Skip to content

Commit ed22473

Browse files
committed
Add extractors for different kinds of symbols
1 parent 18bb14c commit ed22473

File tree

20 files changed

+328
-169
lines changed

20 files changed

+328
-169
lines changed

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

Lines changed: 77 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 isEmpty(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,34 @@ trait SymbolOpsImpl extends scala.tasty.reflect.SymbolOps with TastyCoreImpl {
3432
else ctx
3533
}
3634

37-
def tree(implicit ctx: Context): Option[Definition] =
38-
if (isEmpty) 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 asType(implicit ctx: Context): TypeSymbol = symbol match {
56+
case IsTypeSymbol(symbol) => symbol.asType
57+
case _ => throw new Exception("not a TypeSymbol")
58+
}
59+
60+
def treeOpt(implicit ctx: Context): Option[Definition] =
61+
if (symbol eq core.Symbols.NoSymbol) None
62+
else Some(FromSymbol.definitionFromSym(symbol))
3963

4064
def annots(implicit ctx: Context): List[Term] = {
4165
symbol.annotations.flatMap {
@@ -46,4 +70,52 @@ trait SymbolOpsImpl extends scala.tasty.reflect.SymbolOps with TastyCoreImpl {
4670

4771
}
4872

73+
object IsClassSymbol extends IsClassSymbolExtractor {
74+
def unapply(symbol: Symbol)(implicit ctx: Context): Option[ClassSymbol] =
75+
if (symbol.isClass) Some(symbol.asClass) else None
76+
}
77+
78+
def ClassSymbolDeco(symbol: ClassSymbol): ClassSymbolAPI = new ClassSymbolAPI {
79+
def tree(implicit ctx: Context): ClassDef = FromSymbol.classDef(symbol)
80+
}
81+
82+
object IsDefSymbol extends IsDefSymbolExtractor {
83+
def unapply(symbol: Symbol)(implicit ctx: Context): Option[DefSymbol] =
84+
if (symbol.isTerm && symbol.is(Flags.Method)) Some(symbol.asTerm) else None
85+
}
86+
87+
def DefSymbolDeco(symbol: DefSymbol): DefSymbolAPI = new DefSymbolAPI {
88+
def tree(implicit ctx: Context): DefDef = FromSymbol.defDefFromSym(symbol)
89+
}
90+
91+
object IsValSymbol extends IsValSymbolExtractor {
92+
def unapply(symbol: Symbol)(implicit ctx: Context): Option[ValSymbol] =
93+
if (symbol.isTerm && !symbol.is(Flags.Method)) Some(symbol.asTerm) else None
94+
}
95+
96+
def ValSymbolDeco(symbol: ValSymbol): ValSymbolAPI = new ValSymbolAPI {
97+
def tree(implicit ctx: Context): ValDef = FromSymbol.valDefFromSym(symbol)
98+
}
99+
100+
object IsTypeSymbol extends IsTypeSymbolExtractor {
101+
def unapply(symbol: Symbol)(implicit ctx: Context): Option[TypeSymbol] =
102+
if (symbol.isType) Some(symbol.asType) else None
103+
}
104+
105+
def TypeSymbolDeco(symbol: TypeSymbol): TypeSymbolAPI = new TypeSymbolAPI {
106+
def tree(implicit ctx: Context): TypeDef = FromSymbol.typeDefFromSym(symbol)
107+
}
108+
109+
object IsPackageSymbol extends IsPackageSymbolExtractor {
110+
def unapply(symbol: Symbol)(implicit ctx: Context): Option[PackageSymbol] =
111+
if (symbol.is(Flags.Package)) Some(symbol) else None
112+
}
113+
114+
def PackageSymbolDeco(symbol: PackageSymbol): PackageSymbolAPI = new PackageSymbolAPI {
115+
def tree(implicit ctx: Context): PackageDef = FromSymbol.packageDefFromSym(symbol)
116+
}
117+
118+
object NoSymbol extends NoSymbolExtractor {
119+
def unapply(symbol: Symbol)(implicit ctx: Context): Boolean = symbol ne core.Symbols.NoSymbol
120+
}
49121
}

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@ 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
@@ -52,5 +52,9 @@ trait TastyCoreImpl extends scala.tasty.reflect.TastyCore {
5252
type Constant = Constants.Constant
5353

5454
type Symbol = core.Symbols.Symbol
55-
55+
type PackageSymbol = core.Symbols.Symbol
56+
type ClassSymbol = core.Symbols.ClassSymbol
57+
type TypeSymbol = core.Symbols.TypeSymbol
58+
type DefSymbol = core.Symbols.TermSymbol
59+
type ValSymbol = core.Symbols.TermSymbol
5660
}

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

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,17 @@
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
77
import dotty.tools.dotc.core._
8-
import dotty.tools.dotc.reporting.Reporter
9-
import dotty.tools.dotc.reporting.diagnostic.MessageContainer
108
import dotty.tools.dotc.tastyreflect.FromSymbol.{definitionFromSym, packageDefFromSym}
119

1210
trait TreeOpsImpl extends scala.tasty.reflect.TreeOps with TastyCoreImpl with Helpers {
1311

1412
def TreeDeco(tree: Tree): TreeAPI = new TreeAPI {
1513
def pos(implicit ctx: Context): Position = tree.pos
1614
def symbol(implicit ctx: Context): Symbol = tree.symbol
17-
1815
}
1916

2017
object IsPackageClause extends IsPackageClauseExtractor {
@@ -86,6 +83,7 @@ trait TreeOpsImpl extends scala.tasty.reflect.TreeOps with TastyCoreImpl with He
8683
def parents(implicit ctx: Context): List[tpd.Tree] = rhs.parents
8784
def self(implicit ctx: Context): Option[tpd.ValDef] = optional(rhs.self)
8885
def body(implicit ctx: Context): List[tpd.Tree] = rhs.body
86+
def symbol(implicit ctx: Context): ClassSymbol = cdef.symbol.asClass
8987
}
9088

9189
// DefDef
@@ -110,6 +108,7 @@ trait TreeOpsImpl extends scala.tasty.reflect.TreeOps with TastyCoreImpl with He
110108
def paramss(implicit ctx: Context): List[List[ValDef]] = ddef.vparamss
111109
def returnTpt(implicit ctx: Context): TypeTree = ddef.tpt
112110
def rhs(implicit ctx: Context): Option[Tree] = optional(ddef.rhs)
111+
def symbol(implicit ctx: Context): DefSymbol = ddef.symbol.asTerm
113112
}
114113

115114
// ValDef
@@ -132,6 +131,7 @@ trait TreeOpsImpl extends scala.tasty.reflect.TreeOps with TastyCoreImpl with He
132131
def ValDefDeco(vdef: ValDef): ValDefAPI = new ValDefAPI {
133132
def tpt(implicit ctx: Context): TypeTree = vdef.tpt
134133
def rhs(implicit ctx: Context): Option[Tree] = optional(vdef.rhs)
134+
def symbol(implicit ctx: Context): ValSymbol = vdef.symbol.asTerm
135135
}
136136

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

153153
def TypeDefDeco(tdef: TypeDef): TypeDefAPI = new TypeDefAPI {
154154
def rhs(implicit ctx: Context): TypeOrBoundsTree = tdef.rhs
155+
def symbol(implicit ctx: Context): TypeSymbol = tdef.symbol.asType
155156
}
156157

157158
// PackageDef
@@ -164,6 +165,8 @@ trait TreeOpsImpl extends scala.tasty.reflect.TreeOps with TastyCoreImpl with He
164165
if (pdef.symbol.is(core.Flags.JavaDefined)) Nil // FIXME should also support java packages
165166
else pdef.symbol.info.decls.iterator.map(definitionFromSym).toList
166167
}
168+
169+
def symbol(implicit ctx: Context): PackageSymbol = pdef.symbol
167170
}
168171

169172
object IsPackageDef extends IsPackageDefExtractor {

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

Lines changed: 75 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 isEmpty(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,83 @@ 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+
29+
def treeOpt(implicit ctx: Context): Option[Definition]
2530

2631
def annots(implicit ctx: Context): List[Term]
2732

2833
}
2934
implicit def SymbolDeco(symbol: Symbol): SymbolAPI
3035

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

library/src/scala/tasty/reflect/TastyCore.scala

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,12 @@ package scala.tasty.reflect
66
*
77
* +- Tree -+- PackageClause
88
* +- Import
9-
* +- Statement -+- Definition --+- ClassDef
9+
* +- Statement -+- Definition --+- PackageDef
10+
* | +- ClassDef
1011
* | +- TypeDef
1112
* | +- DefDef
1213
* | +- ValDef
13-
* | +- PackageDef
14+
* |
1415
* |
1516
* +- Term --------+- Ident
1617
* / +- Select
@@ -96,7 +97,12 @@ package scala.tasty.reflect
9697
*
9798
* +- Constant
9899
*
99-
* +- Symbol
100+
* +- Symbol --+- PackageSymbol
101+
* +- ClassSymbol
102+
* +- TypeSymbol
103+
* +- DefSymbol
104+
* +- ValSymbol
105+
* +- NoSymbol
100106
*
101107
* ```
102108
*/
@@ -115,11 +121,11 @@ trait TastyCore {
115121
type Statement <: Tree
116122
type Import <: Statement
117123
type Definition <: Statement
124+
type PackageDef <: Definition
118125
type ClassDef <: Definition
119126
type TypeDef <: Definition
120127
type DefDef <: Definition
121128
type ValDef <: Definition
122-
type PackageDef <: Definition
123129
type Term <: Statement with Parent // TODO: When bootstrapped, remove `Parent`
124130

125131
/** Branch of a pattern match or catch clause */
@@ -164,5 +170,11 @@ trait TastyCore {
164170
* Then can be compared with == to know if the definition is the same.
165171
*/
166172
type Symbol
173+
type PackageSymbol <: Symbol
174+
type ClassSymbol <: Symbol
175+
type TypeSymbol <: Symbol
176+
type DefSymbol <: Symbol
177+
type ValSymbol <: Symbol
178+
type NoSymbol <: Symbol
167179

168180
}

library/src/scala/tasty/reflect/TreeOps.scala

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ trait TreeOps extends TastyCore {
6666
def parents(implicit ctx: Context): List[Parent]
6767
def self(implicit ctx: Context): Option[ValDef]
6868
def body(implicit ctx: Context): List[Statement]
69+
70+
def symbol(implicit ctx: Context): ClassSymbol
6971
}
7072
implicit def ClassDefDeco(cdef: ClassDef): ClassDefAPI
7173

@@ -86,6 +88,8 @@ trait TreeOps extends TastyCore {
8688
def paramss(implicit ctx: Context): List[List[ValDef]]
8789
def returnTpt(implicit ctx: Context): TypeTree
8890
def rhs(implicit ctx: Context): Option[Term]
91+
92+
def symbol(implicit ctx: Context): DefSymbol
8993
}
9094
implicit def DefDefDeco(ddef: DefDef): DefDefAPI
9195

@@ -104,6 +108,8 @@ trait TreeOps extends TastyCore {
104108
trait ValDefAPI {
105109
def tpt(implicit ctx: Context): TypeTree
106110
def rhs(implicit ctx: Context): Option[Term]
111+
112+
def symbol(implicit ctx: Context): ValSymbol
107113
}
108114
implicit def ValDefDeco(vdef: ValDef): ValDefAPI
109115

@@ -121,6 +127,7 @@ trait TreeOps extends TastyCore {
121127

122128
trait TypeDefAPI {
123129
def rhs(implicit ctx: Context): TypeOrBoundsTree
130+
def symbol(implicit ctx: Context): TypeSymbol
124131
}
125132
implicit def TypeDefDeco(tdef: TypeDef): TypeDefAPI
126133

@@ -134,6 +141,7 @@ trait TreeOps extends TastyCore {
134141
trait PackageDefAPI {
135142
def owner(implicit ctx: Context): PackageDef
136143
def members(implicit ctx: Context): List[Statement]
144+
def symbol(implicit ctx: Context): PackageSymbol
137145
}
138146
implicit def PackageDefDeco(pdef: PackageDef): PackageDefAPI
139147

0 commit comments

Comments
 (0)