Skip to content

Commit b80271a

Browse files
committed
Add extractors for different kinds of symbols
Also fix bind symbol tree
1 parent 42de57a commit b80271a

30 files changed

+427
-172
lines changed

compiler/src/dotty/tools/dotc/tastyreflect/FromSymbol.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package dotty.tools.dotc.tastyreflect
22

33
import dotty.tools.dotc.ast.tpd
4+
import dotty.tools.dotc.ast.untpd
45
import dotty.tools.dotc.core.Contexts.Context
56
import dotty.tools.dotc.core.Flags._
67
import dotty.tools.dotc.core.StdNames._
@@ -15,6 +16,7 @@ object FromSymbol {
1516
else if (sym.isClass) classDef(sym.asClass)
1617
else if (sym.isType) typeDefFromSym(sym.asType)
1718
else if (sym.is(Method)) defDefFromSym(sym.asTerm)
19+
else if (sym.is(Case)) bindFromSym(sym.asTerm)
1820
else valDefFromSym(sym.asTerm)
1921
}
2022

@@ -48,4 +50,8 @@ object FromSymbol {
4850
case tpd.EmptyTree => tpd.ValDef(sym)
4951
}
5052

53+
def bindFromSym(sym: TermSymbol)(implicit ctx: Context): tpd.Bind = sym.defTree match {
54+
case tree: tpd.Bind => tree
55+
case tpd.EmptyTree => tpd.Bind(sym, untpd.Ident(nme.WILDCARD).withType(sym.typeRef))
56+
}
5157
}

compiler/src/dotty/tools/dotc/tastyreflect/PrintersImpl.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,9 @@ trait PrintersImpl extends scala.tasty.reflect.Printers with scala.tasty.reflect
4040
def show(implicit ctx: Contexts.Context, s: Show[tasty.type]): String = s.showConstant(const)
4141
}
4242

43+
/** Adds `show` as an extension method of a `Symbol` */
44+
def SymbolShowDeco(symbol: Symbol): ShowAPI = new ShowAPI {
45+
def show(implicit ctx: Contexts.Context, s: Show[tasty.type]): String = s.showSymbol(symbol)
46+
}
47+
4348
}

compiler/src/dotty/tools/dotc/tastyreflect/SymbolOpsImpl.scala

Lines changed: 91 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
package dotty.tools.dotc
22
package tastyreflect
33

4+
import dotty.tools.dotc.core.Flags
45
import dotty.tools.dotc.core.Symbols._
56

67
trait SymbolOpsImpl extends scala.tasty.reflect.SymbolOps with TastyCoreImpl {
78

89
def SymbolDeco(symbol: Symbol): SymbolAPI = new SymbolAPI {
910

10-
def exists(implicit ctx: Context): Boolean = symbol eq NoSymbol
11-
def isClass(implicit ctx: Context): Boolean = symbol.isClass
12-
1311
def flags(implicit ctx: Context): FlagSet = new FlagSet(symbol.flags)
1412

1513
def privateWithin(implicit ctx: Context): Option[Type] = {
@@ -34,8 +32,39 @@ trait SymbolOpsImpl extends scala.tasty.reflect.SymbolOps with TastyCoreImpl {
3432
else ctx
3533
}
3634

37-
def tree(implicit ctx: Context): Option[Definition] =
38-
if (exists) None else Some(FromSymbol.definitionFromSym(symbol))
35+
def asPackage(implicit ctx: Context): PackageSymbol = symbol match {
36+
case IsPackageSymbol(symbol) => symbol
37+
case _ => throw new Exception("not a PackageSymbol")
38+
}
39+
40+
def asClass(implicit ctx: Context): ClassSymbol = symbol match {
41+
case IsClassSymbol(symbol) => symbol.asClass
42+
case _ => throw new Exception("not a ClassSymbol")
43+
}
44+
45+
def asDef(implicit ctx: Context): DefSymbol = symbol match {
46+
case IsDefSymbol(symbol) => symbol.asTerm
47+
case _ => throw new Exception("not a DefSymbol")
48+
}
49+
50+
def asVal(implicit ctx: Context): ValSymbol = symbol match {
51+
case IsValSymbol(symbol) => symbol
52+
case _ => throw new Exception("not a ValSymbol")
53+
}
54+
55+
def asBind(implicit ctx: Context): BindSymbol = symbol match {
56+
case IsBindSymbol(symbol) => symbol
57+
case _ => throw new Exception("not a BindSymbol")
58+
}
59+
60+
def asType(implicit ctx: Context): TypeSymbol = symbol match {
61+
case IsTypeSymbol(symbol) => symbol.asType
62+
case _ => throw new Exception("not a TypeSymbol")
63+
}
64+
65+
def treeOpt(implicit ctx: Context): Option[Definition] =
66+
if (symbol eq core.Symbols.NoSymbol) None
67+
else Some(FromSymbol.definitionFromSym(symbol))
3968

4069
def annots(implicit ctx: Context): List[Term] = {
4170
symbol.annotations.flatMap {
@@ -46,4 +75,61 @@ trait SymbolOpsImpl extends scala.tasty.reflect.SymbolOps with TastyCoreImpl {
4675

4776
}
4877

78+
object IsPackageSymbol extends IsPackageSymbolExtractor {
79+
def unapply(symbol: Symbol)(implicit ctx: Context): Option[PackageSymbol] =
80+
if (symbol.is(Flags.Package)) Some(symbol) else None
81+
}
82+
83+
def PackageSymbolDeco(symbol: PackageSymbol): PackageSymbolAPI = new PackageSymbolAPI {
84+
def tree(implicit ctx: Context): PackageDef = FromSymbol.packageDefFromSym(symbol)
85+
}
86+
87+
object IsTypeSymbol extends IsTypeSymbolExtractor {
88+
def unapply(symbol: Symbol)(implicit ctx: Context): Option[TypeSymbol] =
89+
if (symbol.isType) Some(symbol.asType) else None
90+
}
91+
92+
def TypeSymbolDeco(symbol: TypeSymbol): TypeSymbolAPI = new TypeSymbolAPI {
93+
def tree(implicit ctx: Context): TypeDef = FromSymbol.typeDefFromSym(symbol)
94+
}
95+
96+
object IsClassSymbol extends IsClassSymbolExtractor {
97+
def unapply(symbol: Symbol)(implicit ctx: Context): Option[ClassSymbol] =
98+
if (symbol.isClass) Some(symbol.asClass) else None
99+
}
100+
101+
def ClassSymbolDeco(symbol: ClassSymbol): ClassSymbolAPI = new ClassSymbolAPI {
102+
def tree(implicit ctx: Context): ClassDef = FromSymbol.classDef(symbol)
103+
}
104+
105+
object IsDefSymbol extends IsDefSymbolExtractor {
106+
def unapply(symbol: Symbol)(implicit ctx: Context): Option[DefSymbol] =
107+
if (symbol.isTerm && symbol.is(Flags.Method)) Some(symbol.asTerm) else None
108+
}
109+
110+
def DefSymbolDeco(symbol: DefSymbol): DefSymbolAPI = new DefSymbolAPI {
111+
def tree(implicit ctx: Context): DefDef = FromSymbol.defDefFromSym(symbol)
112+
}
113+
114+
object IsValSymbol extends IsValSymbolExtractor {
115+
def unapply(symbol: Symbol)(implicit ctx: Context): Option[ValSymbol] =
116+
if (symbol.isTerm && !symbol.is(Flags.Method) && !symbol.is(Flags.Case)) Some(symbol.asTerm) else None
117+
}
118+
119+
def ValSymbolDeco(symbol: ValSymbol): ValSymbolAPI = new ValSymbolAPI {
120+
def tree(implicit ctx: Context): ValDef = FromSymbol.valDefFromSym(symbol)
121+
}
122+
123+
object IsBindSymbol extends IsBindSymbolExtractor {
124+
def unapply(symbol: Symbol)(implicit ctx: Context): Option[BindSymbol] =
125+
if (symbol.isTerm && symbol.is(Flags.Case)) Some(symbol.asTerm) else None // TODO
126+
}
127+
128+
def BindSymbolDeco(symbol: BindSymbol): BindSymbolAPI = new BindSymbolAPI {
129+
def tree(implicit ctx: Context): Bind = FromSymbol.bindFromSym(symbol)
130+
}
131+
132+
object NoSymbol extends NoSymbolExtractor {
133+
def unapply(symbol: Symbol)(implicit ctx: Context): Boolean = symbol ne core.Symbols.NoSymbol
134+
}
49135
}

compiler/src/dotty/tools/dotc/tastyreflect/TastyCoreImpl.scala

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,21 @@ trait TastyCoreImpl extends scala.tasty.reflect.TastyCore {
1616
type Statement = tpd.Tree
1717
type Import = tpd.Import
1818
type Definition = tpd.Tree
19+
type PackageDef = PackageDefinition
1920
type ClassDef = tpd.TypeDef
2021
type TypeDef = tpd.TypeDef
2122
type DefDef = tpd.DefDef
2223
type ValDef = tpd.ValDef
23-
type PackageDef = PackageDefinition
2424
type Term = tpd.Tree
2525

2626
type CaseDef = tpd.CaseDef
2727

2828
type Pattern = tpd.Tree
29+
type Value = tpd.Tree
30+
type Bind = tpd.Bind
31+
type Unapply = tpd.Tree
32+
type Alternative = tpd.Alternative
33+
type TypeTest = tpd.Typed
2934

3035
type TypeOrBoundsTree = tpd.Tree
3136
type TypeTree = tpd.Tree
@@ -52,5 +57,11 @@ trait TastyCoreImpl extends scala.tasty.reflect.TastyCore {
5257
type Constant = Constants.Constant
5358

5459
type Symbol = core.Symbols.Symbol
55-
60+
type PackageSymbol = core.Symbols.Symbol
61+
type ClassSymbol = core.Symbols.ClassSymbol
62+
type TypeSymbol = core.Symbols.TypeSymbol
63+
type DefSymbol = core.Symbols.TermSymbol
64+
type BindSymbol = core.Symbols.TermSymbol
65+
type ValSymbol = core.Symbols.TermSymbol
66+
type NoSymbol = core.Symbols.NoSymbol.type
5667
}

compiler/src/dotty/tools/dotc/tastyreflect/TreeOpsImpl.scala

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package dotty.tools.dotc.tastyreflect
22

3-
import dotty.tools.dotc.ast.{Trees, tpd, untpd}
3+
import dotty.tools.dotc.ast.{Trees, tpd}
44
import dotty.tools.dotc.core
55
import dotty.tools.dotc.core.Decorators._
66
import dotty.tools.dotc.core.StdNames.nme
@@ -12,7 +12,6 @@ trait TreeOpsImpl extends scala.tasty.reflect.TreeOps with TastyCoreImpl with He
1212
def TreeDeco(tree: Tree): TreeAPI = new TreeAPI {
1313
def pos(implicit ctx: Context): Position = tree.pos
1414
def symbol(implicit ctx: Context): Symbol = tree.symbol
15-
1615
}
1716

1817
object IsPackageClause extends IsPackageClauseExtractor {
@@ -84,6 +83,7 @@ trait TreeOpsImpl extends scala.tasty.reflect.TreeOps with TastyCoreImpl with He
8483
def parents(implicit ctx: Context): List[tpd.Tree] = rhs.parents
8584
def self(implicit ctx: Context): Option[tpd.ValDef] = optional(rhs.self)
8685
def body(implicit ctx: Context): List[tpd.Tree] = rhs.body
86+
def symbol(implicit ctx: Context): ClassSymbol = cdef.symbol.asClass
8787
}
8888

8989
// DefDef
@@ -108,6 +108,7 @@ trait TreeOpsImpl extends scala.tasty.reflect.TreeOps with TastyCoreImpl with He
108108
def paramss(implicit ctx: Context): List[List[ValDef]] = ddef.vparamss
109109
def returnTpt(implicit ctx: Context): TypeTree = ddef.tpt
110110
def rhs(implicit ctx: Context): Option[Tree] = optional(ddef.rhs)
111+
def symbol(implicit ctx: Context): DefSymbol = ddef.symbol.asTerm
111112
}
112113

113114
// ValDef
@@ -130,6 +131,7 @@ trait TreeOpsImpl extends scala.tasty.reflect.TreeOps with TastyCoreImpl with He
130131
def ValDefDeco(vdef: ValDef): ValDefAPI = new ValDefAPI {
131132
def tpt(implicit ctx: Context): TypeTree = vdef.tpt
132133
def rhs(implicit ctx: Context): Option[Tree] = optional(vdef.rhs)
134+
def symbol(implicit ctx: Context): ValSymbol = vdef.symbol.asTerm
133135
}
134136

135137
// TypeDef
@@ -150,6 +152,7 @@ trait TreeOpsImpl extends scala.tasty.reflect.TreeOps with TastyCoreImpl with He
150152

151153
def TypeDefDeco(tdef: TypeDef): TypeDefAPI = new TypeDefAPI {
152154
def rhs(implicit ctx: Context): TypeOrBoundsTree = tdef.rhs
155+
def symbol(implicit ctx: Context): TypeSymbol = tdef.symbol.asType
153156
}
154157

155158
// PackageDef
@@ -162,6 +165,8 @@ trait TreeOpsImpl extends scala.tasty.reflect.TreeOps with TastyCoreImpl with He
162165
if (pdef.symbol.is(core.Flags.JavaDefined)) Nil // FIXME should also support java packages
163166
else pdef.symbol.info.decls.iterator.map(definitionFromSym).toList
164167
}
168+
169+
def symbol(implicit ctx: Context): PackageSymbol = pdef.symbol
165170
}
166171

167172
object IsPackageDef extends IsPackageDefExtractor {

library/src/scala/tasty/reflect/Printers.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ trait Printers { tasty: Tasty =>
3131
/** Adds `show` as an extension method of a `Constant` */
3232
implicit def ConstantShowDeco(const: Constant): ShowAPI
3333

34+
/** Adds `show` as an extension method of a `Symbol` */
35+
implicit def SymbolShowDeco(symbol: Symbol): ShowAPI
36+
3437
/** Define `show` as method */
3538
trait ShowAPI {
3639
/** Shows the string representation based on an implicit instance of `Show[tasty.type]`

library/src/scala/tasty/reflect/SymbolOps.scala

Lines changed: 86 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,12 @@ package reflect
44
/** Tasty reflect symbol */
55
trait SymbolOps extends TastyCore {
66

7+
// Symbol
8+
79
trait SymbolAPI {
810

911
def owner(implicit ctx: Context): Symbol
1012

11-
def exists(implicit ctx: Context): Boolean
12-
def isClass(implicit ctx: Context): Boolean
13-
1413
def flags(implicit ctx: Context): FlagSet
1514

1615
def privateWithin(implicit ctx: Context): Option[Type]
@@ -21,11 +20,94 @@ trait SymbolOps extends TastyCore {
2120

2221
def localContext(implicit ctx: Context): Context
2322

24-
def tree(implicit ctx: Context): Option[Definition]
23+
def asPackage(implicit ctx: Context): PackageSymbol
24+
def asClass(implicit ctx: Context): ClassSymbol
25+
def asDef(implicit ctx: Context): DefSymbol
26+
def asVal(implicit ctx: Context): ValSymbol
27+
def asType(implicit ctx: Context): TypeSymbol
28+
def asBind(implicit ctx: Context): BindSymbol
2529

2630
def annots(implicit ctx: Context): List[Term]
2731

2832
}
2933
implicit def SymbolDeco(symbol: Symbol): SymbolAPI
3034

35+
// PackageSymbol
36+
37+
val IsPackageSymbol: IsPackageSymbolExtractor
38+
abstract class IsPackageSymbolExtractor {
39+
def unapply(symbol: Symbol)(implicit ctx: Context): Option[PackageSymbol]
40+
}
41+
42+
trait PackageSymbolAPI {
43+
def tree(implicit ctx: Context): PackageDef
44+
}
45+
implicit def PackageSymbolDeco(symbol: PackageSymbol): PackageSymbolAPI
46+
47+
// ClassSymbol
48+
49+
val IsClassSymbol: IsClassSymbolExtractor
50+
abstract class IsClassSymbolExtractor {
51+
def unapply(symbol: Symbol)(implicit ctx: Context): Option[ClassSymbol]
52+
}
53+
54+
trait ClassSymbolAPI {
55+
def tree(implicit ctx: Context): ClassDef
56+
}
57+
implicit def ClassSymbolDeco(symbol: ClassSymbol): ClassSymbolAPI
58+
59+
// TypeSymbol
60+
61+
val IsTypeSymbol: IsTypeSymbolExtractor
62+
abstract class IsTypeSymbolExtractor {
63+
def unapply(symbol: Symbol)(implicit ctx: Context): Option[TypeSymbol]
64+
}
65+
66+
trait TypeSymbolAPI {
67+
def tree(implicit ctx: Context): TypeDef
68+
}
69+
implicit def TypeSymbolDeco(symbol: TypeSymbol): TypeSymbolAPI
70+
71+
// DefSymbol
72+
73+
val IsDefSymbol: IsDefSymbolExtractor
74+
abstract class IsDefSymbolExtractor {
75+
def unapply(symbol: Symbol)(implicit ctx: Context): Option[DefSymbol]
76+
}
77+
78+
trait DefSymbolAPI {
79+
def tree(implicit ctx: Context): DefDef
80+
}
81+
implicit def DefSymbolDeco(symbol: DefSymbol): DefSymbolAPI
82+
83+
// ValSymbol
84+
85+
val IsValSymbol: IsValSymbolExtractor
86+
abstract class IsValSymbolExtractor {
87+
def unapply(symbol: Symbol)(implicit ctx: Context): Option[ValSymbol]
88+
}
89+
90+
trait ValSymbolAPI {
91+
def tree(implicit ctx: Context): ValDef
92+
}
93+
implicit def ValSymbolDeco(symbol: ValSymbol): ValSymbolAPI
94+
95+
// BindSymbol
96+
97+
val IsBindSymbol: IsBindSymbolExtractor
98+
abstract class IsBindSymbolExtractor {
99+
def unapply(symbol: Symbol)(implicit ctx: Context): Option[BindSymbol]
100+
}
101+
102+
trait BindSymbolAPI {
103+
def tree(implicit ctx: Context): Bind
104+
}
105+
implicit def BindSymbolDeco(symbol: BindSymbol): BindSymbolAPI
106+
107+
// NoSymbol
108+
109+
val NoSymbol: NoSymbolExtractor
110+
abstract class NoSymbolExtractor {
111+
def unapply(symbol: Symbol)(implicit ctx: Context): Boolean
112+
}
31113
}

0 commit comments

Comments
 (0)