Skip to content

Commit 370cfb0

Browse files
committed
Add extractors for different kinds of symbols
1 parent 28ddeac commit 370cfb0

File tree

23 files changed

+344
-167
lines changed

23 files changed

+344
-167
lines changed

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: 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 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,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 (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 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 & 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: 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 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,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: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ 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
1414
* |
1515
* +- Term --------+- Ident
1616
* +- Select
@@ -96,7 +96,12 @@ package scala.tasty.reflect
9696
*
9797
* +- Constant
9898
*
99-
* +- Symbol
99+
* +- Symbol --+- PackageSymbol
100+
* +- ClassSymbol
101+
* +- TypeSymbol
102+
* +- DefSymbol
103+
* +- ValSymbol
104+
* +- NoSymbol
100105
*
101106
* Aliases:
102107
* # Parent = Term | TypeTree
@@ -118,11 +123,11 @@ trait TastyCore {
118123
type Statement <: Tree
119124
type Import <: Statement
120125
type Definition <: Statement
126+
type PackageDef <: Definition
121127
type ClassDef <: Definition
122128
type TypeDef <: Definition
123129
type DefDef <: Definition
124130
type ValDef <: Definition
125-
type PackageDef <: Definition
126131
type Term <: Statement
127132

128133
/** Branch of a pattern match or catch clause */
@@ -167,5 +172,11 @@ trait TastyCore {
167172
* Then can be compared with == to know if the definition is the same.
168173
*/
169174
type Symbol
175+
type PackageSymbol <: Symbol
176+
type ClassSymbol <: Symbol
177+
type TypeSymbol <: Symbol
178+
type DefSymbol <: Symbol
179+
type ValSymbol <: Symbol
180+
type NoSymbol <: Symbol
170181

171182
}

0 commit comments

Comments
 (0)