Skip to content

Split TASTy symbol #4993

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 5, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions compiler/src/dotty/tools/dotc/tastyreflect/FromSymbol.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package dotty.tools.dotc.tastyreflect

import dotty.tools.dotc.ast.tpd
import dotty.tools.dotc.ast.untpd
import dotty.tools.dotc.core.Contexts.Context
import dotty.tools.dotc.core.Flags._
import dotty.tools.dotc.core.StdNames._
Expand All @@ -15,6 +16,7 @@ object FromSymbol {
else if (sym.isClass) classDef(sym.asClass)
else if (sym.isType) typeDefFromSym(sym.asType)
else if (sym.is(Method)) defDefFromSym(sym.asTerm)
else if (sym.is(Case)) bindFromSym(sym.asTerm)
else valDefFromSym(sym.asTerm)
}

Expand Down Expand Up @@ -48,4 +50,8 @@ object FromSymbol {
case tpd.EmptyTree => tpd.ValDef(sym)
}

def bindFromSym(sym: TermSymbol)(implicit ctx: Context): tpd.Bind = sym.defTree match {
case tree: tpd.Bind => tree
case tpd.EmptyTree => tpd.Bind(sym, untpd.Ident(nme.WILDCARD).withType(sym.typeRef))
}
}
5 changes: 5 additions & 0 deletions compiler/src/dotty/tools/dotc/tastyreflect/PrintersImpl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,9 @@ trait PrintersImpl extends scala.tasty.reflect.Printers with scala.tasty.reflect
def show(implicit ctx: Contexts.Context, s: Show[tasty.type]): String = s.showConstant(const)
}

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

}
96 changes: 91 additions & 5 deletions compiler/src/dotty/tools/dotc/tastyreflect/SymbolOpsImpl.scala
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
package dotty.tools.dotc
package tastyreflect

import dotty.tools.dotc.core.Flags
import dotty.tools.dotc.core.Symbols._

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

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

def exists(implicit ctx: Context): Boolean = symbol eq NoSymbol
def isClass(implicit ctx: Context): Boolean = symbol.isClass

def flags(implicit ctx: Context): FlagSet = new FlagSet(symbol.flags)

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

def tree(implicit ctx: Context): Option[Definition] =
if (exists) None else Some(FromSymbol.definitionFromSym(symbol))
def asPackage(implicit ctx: Context): PackageSymbol = symbol match {
case IsPackageSymbol(symbol) => symbol
case _ => throw new Exception("not a PackageSymbol")
}

def asClass(implicit ctx: Context): ClassSymbol = symbol match {
case IsClassSymbol(symbol) => symbol.asClass
case _ => throw new Exception("not a ClassSymbol")
}

def asDef(implicit ctx: Context): DefSymbol = symbol match {
case IsDefSymbol(symbol) => symbol.asTerm
case _ => throw new Exception("not a DefSymbol")
}

def asVal(implicit ctx: Context): ValSymbol = symbol match {
case IsValSymbol(symbol) => symbol
case _ => throw new Exception("not a ValSymbol")
}

def asBind(implicit ctx: Context): BindSymbol = symbol match {
case IsBindSymbol(symbol) => symbol
case _ => throw new Exception("not a BindSymbol")
}

def asType(implicit ctx: Context): TypeSymbol = symbol match {
case IsTypeSymbol(symbol) => symbol.asType
case _ => throw new Exception("not a TypeSymbol")
}

def treeOpt(implicit ctx: Context): Option[Definition] =
if (symbol eq core.Symbols.NoSymbol) None
else Some(FromSymbol.definitionFromSym(symbol))

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

}

object IsPackageSymbol extends IsPackageSymbolExtractor {
def unapply(symbol: Symbol)(implicit ctx: Context): Option[PackageSymbol] =
if (symbol.is(Flags.Package)) Some(symbol) else None
}

def PackageSymbolDeco(symbol: PackageSymbol): PackageSymbolAPI = new PackageSymbolAPI {
def tree(implicit ctx: Context): PackageDef = FromSymbol.packageDefFromSym(symbol)
}

object IsTypeSymbol extends IsTypeSymbolExtractor {
def unapply(symbol: Symbol)(implicit ctx: Context): Option[TypeSymbol] =
if (symbol.isType) Some(symbol.asType) else None
}

def TypeSymbolDeco(symbol: TypeSymbol): TypeSymbolAPI = new TypeSymbolAPI {
def tree(implicit ctx: Context): TypeDef = FromSymbol.typeDefFromSym(symbol)
}

object IsClassSymbol extends IsClassSymbolExtractor {
def unapply(symbol: Symbol)(implicit ctx: Context): Option[ClassSymbol] =
if (symbol.isClass) Some(symbol.asClass) else None
}

def ClassSymbolDeco(symbol: ClassSymbol): ClassSymbolAPI = new ClassSymbolAPI {
def tree(implicit ctx: Context): ClassDef = FromSymbol.classDef(symbol)
}

object IsDefSymbol extends IsDefSymbolExtractor {
def unapply(symbol: Symbol)(implicit ctx: Context): Option[DefSymbol] =
if (symbol.isTerm && symbol.is(Flags.Method)) Some(symbol.asTerm) else None
}

def DefSymbolDeco(symbol: DefSymbol): DefSymbolAPI = new DefSymbolAPI {
def tree(implicit ctx: Context): DefDef = FromSymbol.defDefFromSym(symbol)
}

object IsValSymbol extends IsValSymbolExtractor {
def unapply(symbol: Symbol)(implicit ctx: Context): Option[ValSymbol] =
if (symbol.isTerm && !symbol.is(Flags.Method) && !symbol.is(Flags.Case)) Some(symbol.asTerm) else None
}

def ValSymbolDeco(symbol: ValSymbol): ValSymbolAPI = new ValSymbolAPI {
def tree(implicit ctx: Context): ValDef = FromSymbol.valDefFromSym(symbol)
}

object IsBindSymbol extends IsBindSymbolExtractor {
def unapply(symbol: Symbol)(implicit ctx: Context): Option[BindSymbol] =
if (symbol.isTerm && symbol.is(Flags.Case)) Some(symbol.asTerm) else None // TODO
}

def BindSymbolDeco(symbol: BindSymbol): BindSymbolAPI = new BindSymbolAPI {
def tree(implicit ctx: Context): Bind = FromSymbol.bindFromSym(symbol)
}

object NoSymbol extends NoSymbolExtractor {
def unapply(symbol: Symbol)(implicit ctx: Context): Boolean = symbol ne core.Symbols.NoSymbol
}
}
15 changes: 13 additions & 2 deletions compiler/src/dotty/tools/dotc/tastyreflect/TastyCoreImpl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,21 @@ trait TastyCoreImpl extends scala.tasty.reflect.TastyCore {
type Statement = tpd.Tree
type Import = tpd.Import
type Definition = tpd.Tree
type PackageDef = PackageDefinition
type ClassDef = tpd.TypeDef
type TypeDef = tpd.TypeDef
type DefDef = tpd.DefDef
type ValDef = tpd.ValDef
type PackageDef = PackageDefinition
type Term = tpd.Tree

type CaseDef = tpd.CaseDef

type Pattern = tpd.Tree
type Value = tpd.Tree
type Bind = tpd.Bind
type Unapply = tpd.Tree
type Alternative = tpd.Alternative
type TypeTest = tpd.Typed

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

type Symbol = core.Symbols.Symbol

type PackageSymbol = core.Symbols.Symbol
type ClassSymbol = core.Symbols.ClassSymbol
type TypeSymbol = core.Symbols.TypeSymbol
type DefSymbol = core.Symbols.TermSymbol
type BindSymbol = core.Symbols.TermSymbol
type ValSymbol = core.Symbols.TermSymbol
type NoSymbol = core.Symbols.NoSymbol.type
}
9 changes: 7 additions & 2 deletions compiler/src/dotty/tools/dotc/tastyreflect/TreeOpsImpl.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package dotty.tools.dotc.tastyreflect

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

}

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

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

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

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

def TypeDefDeco(tdef: TypeDef): TypeDefAPI = new TypeDefAPI {
def rhs(implicit ctx: Context): TypeOrBoundsTree = tdef.rhs
def symbol(implicit ctx: Context): TypeSymbol = tdef.symbol.asType
}

// PackageDef
Expand All @@ -162,6 +165,8 @@ trait TreeOpsImpl extends scala.tasty.reflect.TreeOps with TastyCoreImpl with He
if (pdef.symbol.is(core.Flags.JavaDefined)) Nil // FIXME should also support java packages
else pdef.symbol.info.decls.iterator.map(definitionFromSym).toList
}

def symbol(implicit ctx: Context): PackageSymbol = pdef.symbol
}

object IsPackageDef extends IsPackageDefExtractor {
Expand Down
3 changes: 3 additions & 0 deletions library/src/scala/tasty/reflect/Printers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ trait Printers { tasty: Tasty =>
/** Adds `show` as an extension method of a `Constant` */
implicit def ConstantShowDeco(const: Constant): ShowAPI

/** Adds `show` as an extension method of a `Symbol` */
implicit def SymbolShowDeco(symbol: Symbol): ShowAPI

/** Define `show` as method */
trait ShowAPI {
/** Shows the string representation based on an implicit instance of `Show[tasty.type]`
Expand Down
90 changes: 86 additions & 4 deletions library/src/scala/tasty/reflect/SymbolOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,12 @@ package reflect
/** Tasty reflect symbol */
trait SymbolOps extends TastyCore {

// Symbol

trait SymbolAPI {

def owner(implicit ctx: Context): Symbol

def exists(implicit ctx: Context): Boolean
def isClass(implicit ctx: Context): Boolean

def flags(implicit ctx: Context): FlagSet

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

def localContext(implicit ctx: Context): Context

def tree(implicit ctx: Context): Option[Definition]
def asPackage(implicit ctx: Context): PackageSymbol
def asClass(implicit ctx: Context): ClassSymbol
def asDef(implicit ctx: Context): DefSymbol
def asVal(implicit ctx: Context): ValSymbol
def asType(implicit ctx: Context): TypeSymbol
def asBind(implicit ctx: Context): BindSymbol

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

}
implicit def SymbolDeco(symbol: Symbol): SymbolAPI

// PackageSymbol

val IsPackageSymbol: IsPackageSymbolExtractor
abstract class IsPackageSymbolExtractor {
def unapply(symbol: Symbol)(implicit ctx: Context): Option[PackageSymbol]
}

trait PackageSymbolAPI {
def tree(implicit ctx: Context): PackageDef
}
implicit def PackageSymbolDeco(symbol: PackageSymbol): PackageSymbolAPI

// ClassSymbol

val IsClassSymbol: IsClassSymbolExtractor
abstract class IsClassSymbolExtractor {
def unapply(symbol: Symbol)(implicit ctx: Context): Option[ClassSymbol]
}

trait ClassSymbolAPI {
def tree(implicit ctx: Context): ClassDef
}
implicit def ClassSymbolDeco(symbol: ClassSymbol): ClassSymbolAPI

// TypeSymbol

val IsTypeSymbol: IsTypeSymbolExtractor
abstract class IsTypeSymbolExtractor {
def unapply(symbol: Symbol)(implicit ctx: Context): Option[TypeSymbol]
}

trait TypeSymbolAPI {
def tree(implicit ctx: Context): TypeDef
}
implicit def TypeSymbolDeco(symbol: TypeSymbol): TypeSymbolAPI

// DefSymbol

val IsDefSymbol: IsDefSymbolExtractor
abstract class IsDefSymbolExtractor {
def unapply(symbol: Symbol)(implicit ctx: Context): Option[DefSymbol]
}

trait DefSymbolAPI {
def tree(implicit ctx: Context): DefDef
}
implicit def DefSymbolDeco(symbol: DefSymbol): DefSymbolAPI

// ValSymbol

val IsValSymbol: IsValSymbolExtractor
abstract class IsValSymbolExtractor {
def unapply(symbol: Symbol)(implicit ctx: Context): Option[ValSymbol]
}

trait ValSymbolAPI {
def tree(implicit ctx: Context): ValDef
}
implicit def ValSymbolDeco(symbol: ValSymbol): ValSymbolAPI

// BindSymbol

val IsBindSymbol: IsBindSymbolExtractor
abstract class IsBindSymbolExtractor {
def unapply(symbol: Symbol)(implicit ctx: Context): Option[BindSymbol]
}

trait BindSymbolAPI {
def tree(implicit ctx: Context): Bind
}
implicit def BindSymbolDeco(symbol: BindSymbol): BindSymbolAPI

// NoSymbol

val NoSymbol: NoSymbolExtractor
abstract class NoSymbolExtractor {
def unapply(symbol: Symbol)(implicit ctx: Context): Boolean
}
}
Loading