aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dotty/tools/dotc/core/SymDenotations.scala19
-rw-r--r--src/dotty/tools/dotc/core/Symbols.scala51
-rw-r--r--src/dotty/tools/dotc/core/TypedTrees.scala20
3 files changed, 49 insertions, 41 deletions
diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala
index 5213e9314..0fb099bdb 100644
--- a/src/dotty/tools/dotc/core/SymDenotations.scala
+++ b/src/dotty/tools/dotc/core/SymDenotations.scala
@@ -427,10 +427,14 @@ object SymDenotations {
/** The top-level class containing this denotation,
* except for a toplevel module, where its module class is returned.
*/
- final def topLevelClass(implicit ctx: Context): Symbol =
- if (!(owner.isPackageClass)) owner.topLevelClass
- else if (isClass) symbol
- else moduleClass
+ final def topLevelClass(implicit ctx: Context): Symbol = {
+ val sym = topLevelSym
+ if (sym.isClass) sym else sym.moduleClass
+ }
+
+ /** The top-level symbol containing this denotation. */
+ final def topLevelSym(implicit ctx: Context): Symbol =
+ if (owner.isPackageClass) symbol else owner.topLevelSym
/** The package containing this denotation */
final def enclosingPackage(implicit ctx: Context): Symbol =
@@ -707,7 +711,7 @@ object SymDenotations {
* gets invalidated.
*/
def memberFingerPrint(implicit ctx: Context): FingerPrint = {
- assert(hasChildren)
+ assert(classSymbol.hasChildren)
if (_memberFingerPrint == FingerPrint.empty) _memberFingerPrint = computeMemberFingerPrint
_memberFingerPrint
}
@@ -745,9 +749,6 @@ object SymDenotations {
memberCache invalidate sym.name
}
- /** Have we seen a subclass of this class? */
- def hasChildren = symbol.superId >= 0
-
/** All members of this class that have the given name.
* The elements of the returned pre-denotation all
* have existing symbols.
@@ -755,7 +756,7 @@ object SymDenotations {
final def membersNamed(name: Name)(implicit ctx: Context): PreDenotation = {
var denots: PreDenotation = memberCache lookup name
if (denots == null) {
- if (!hasChildren || (memberFingerPrint contains name)) {
+ if (!classSymbol.hasChildren || (memberFingerPrint contains name)) {
val ownDenots = info.decls.denotsNamed(name)
denots = ownDenots
var ps = classInfo.classParents
diff --git a/src/dotty/tools/dotc/core/Symbols.scala b/src/dotty/tools/dotc/core/Symbols.scala
index 90b9837ca..e307328e1 100644
--- a/src/dotty/tools/dotc/core/Symbols.scala
+++ b/src/dotty/tools/dotc/core/Symbols.scala
@@ -65,7 +65,7 @@ trait Symbols { this: Context =>
}
/** Create a class symbol from its non-info fields and a function
- * producing its info (the info may be lazy).
+ * producing its info (the produced info may be lazy).
*/
def newClassSymbol(
owner: Symbol,
@@ -77,7 +77,7 @@ trait Symbols { this: Context =>
assocFile: AbstractFile = null): ClassSymbol
= {
val cls = newNakedClassSymbol(coord, assocFile)
- val denot = SymDenotation(cls, owner, name, flags, infoFn(cls))
+ val denot = SymDenotation(cls, owner, name, flags, infoFn(cls), privateWithin)
cls.denot = denot
cls
}
@@ -160,7 +160,7 @@ trait Symbols { this: Context =>
newModuleSymbol(owner, name, PackageCreationFlags, info)
/** Create a package symbol with associated package class
- * from its non-info fields and the fields of the package class info.
+ * from its non-info fields its member scope.
*/
def newCompletePackageSymbol(
owner: Symbol,
@@ -222,9 +222,9 @@ trait Symbols { this: Context =>
type OwnerMap = Symbol => Symbol
- /** Map given symbols, subjecting all types to given type map and owner map. Cross symbol
- * references are brought over from originals to copies.
- * Do not copy any symbols if all their attributes stay the same.
+ /** Map given symbols, subjecting all types to given type map and owner map.
+ * Cross symbol references are brought over from originals to copies.
+ * Do not copy any symbols if all attributes of all symbols stay the same.
*/
def mapSymbols(
originals: List[Symbol],
@@ -237,16 +237,16 @@ trait Symbols { this: Context =>
else {
val copies: List[Symbol] = for (original <- originals) yield
newNakedSymbol[original.ThisName](original.coord)
- val copyTypeMap = typeMap andThen ((tp: Type) => tp.substSym(originals, copies))
- val copyTreeMap = new TypedTrees.TreeMapper(copyTypeMap, ownerMap)
+ val treeMap = new TypedTrees.TreeMapper(typeMap, ownerMap)
+ .withSubstitution(originals, copies)
(originals, copies).zipped foreach {(original, copy) =>
val odenot = original.denot
copy.denot = odenot.copySymDenotation(
symbol = copy,
- owner = ownerMap(odenot.owner),
- info = copyTypeMap(odenot.info),
+ owner = treeMap.ownerMap(odenot.owner),
+ info = treeMap.typeMap(odenot.info),
privateWithin = ownerMap(odenot.privateWithin),
- annotations = odenot.annotations.mapConserve(copyTreeMap.apply))
+ annotations = odenot.annotations.mapConserve(treeMap.apply))
}
copies
}
@@ -271,15 +271,6 @@ object Symbols {
type ThisName <: Name
- /** Is symbol different from NoSymbol? */
- def exists = true
-
- /** This symbol, if it exists, otherwise the result of evaluating `that` */
- def orElse(that: => Symbol) = if (exists) this else that
-
- /** If this symbol satisfies predicate `p` this symbol, otherwise `NoSymbol` */
- def filter(p: Symbol => Boolean): Symbol = if (p(this)) this else NoSymbol
-
private[this] var _id: Int = _
/** The unique id of this symbol */
@@ -298,7 +289,8 @@ object Symbols {
/** The current denotation of this symbol */
final def denot(implicit ctx: Context): SymDenotation = {
var denot = lastDenot
- if (!(denot.validFor contains ctx.period)) denot = denot.current.asInstanceOf[SymDenotation]
+ if (!(denot.validFor contains ctx.period))
+ denot = denot.current.asInstanceOf[SymDenotation]
denot
}
@@ -317,11 +309,19 @@ object Symbols {
*/
def superId: Int = -1
+ /** This symbol entered into owner's scope (owner must be a class). */
final def entered(implicit ctx: Context): this.type = {
this.owner.asClass.enter(this)
this
}
+ /** This symbol, if it exists, otherwise the result of evaluating `that` */
+ def orElse(that: => Symbol)(implicit ctx: Context) =
+ if (this.exists) this else that
+
+ /** If this symbol satisfies predicate `p` this symbol, otherwise `NoSymbol` */
+ def filter(p: Symbol => Boolean): Symbol = if (p(this)) this else NoSymbol
+
/** Is symbol a primitive value class? */
def isPrimitiveValueClass(implicit ctx: Context) = defn.ScalaValueClasses contains this
@@ -335,7 +335,7 @@ object Symbols {
* the class containing this symbol was generated, null if not applicable.
*/
def associatedFile(implicit ctx: Context): AbstractFile =
- this.denot.topLevelClass.symbol.associatedFile
+ denot.topLevelClass.symbol.associatedFile
/** The class file from which this class was generated, null if not applicable. */
final def binaryFile(implicit ctx: Context): AbstractFile =
@@ -359,7 +359,6 @@ object Symbols {
def showKind(implicit ctx: Context): String = ctx.showKind(this)
def showName(implicit ctx: Context): String = ctx.showName(this)
def showFullName(implicit ctx: Context): String = ctx.showFullName(this)
-
}
type TermSymbol = Symbol { type ThisName = TermName }
@@ -399,6 +398,9 @@ object Symbols {
id
}
}
+
+ /** Have we seen a subclass of this class? */
+ def hasChildren = superIdHint >= 0
}
class ErrorSymbol(val underlying: Symbol, msg: => String)(implicit ctx: Context) extends Symbol(NoCoord) {
@@ -407,7 +409,6 @@ object Symbols {
}
object NoSymbol extends Symbol(NoCoord) {
- override def exists = false
denot = NoDenotation
}
@@ -429,7 +430,9 @@ object Symbols {
implicit def defn(implicit ctx: Context): Definitions = ctx.definitions
+ /** Makes all denotation operations available on symbols */
implicit def toDenot(sym: Symbol)(implicit ctx: Context): SymDenotation = sym.denot
+ /** Makes all class denotations available on class symbols */
implicit def toClassDenot(cls: ClassSymbol)(implicit ctx: Context): ClassDenotation = cls.classDenot
}
diff --git a/src/dotty/tools/dotc/core/TypedTrees.scala b/src/dotty/tools/dotc/core/TypedTrees.scala
index 7f2838c66..b9708efe6 100644
--- a/src/dotty/tools/dotc/core/TypedTrees.scala
+++ b/src/dotty/tools/dotc/core/TypedTrees.scala
@@ -505,6 +505,8 @@ object TypedTrees {
check(expr.isValue); check(from.isTerm)
check(from.tpe.termSymbol.isSourceMethod)
case Try(block, catches, finalizer) =>
+ check(block.isTerm)
+ check(finalizer.isTerm)
for (ctch <- catches)
check(ctch.pat.tpe <:< defn.ThrowableType)
case Throw(expr) =>
@@ -656,7 +658,7 @@ object TypedTrees {
new TreeMapper(ownerMap = (sym => if (sym == from) to else sym)).apply(tree)
}
- class TreeMapper(typeMap: TypeMap = IdentityTypeMap, ownerMap: Symbol => Symbol = identity)(implicit ctx: Context) extends TreeTransformer[Type, Unit] {
+ class TreeMapper(val typeMap: TypeMap = IdentityTypeMap, val ownerMap: Symbol => Symbol = identity)(implicit ctx: Context) extends TreeTransformer[Type, Unit] {
override def transform(tree: tpd.Tree, c: Unit): tpd.Tree = {
val tree1 = tree.withType(typeMap(tree.tpe))
val tree2 = tree1 match {
@@ -676,13 +678,9 @@ object TypedTrees {
override def transform(trees: List[tpd.Tree], c: Unit) = {
val locals = localSyms(trees)
val mapped = ctx.mapSymbols(locals, typeMap, ownerMap)
- if (locals eq mapped)
- super.transform(trees, c)
- else
- new TreeMapper(
- typeMap andThen ((tp: Type) => tp.substSym(locals, mapped)),
- ownerMap andThen (locals zip mapped).toMap).transform(trees, c)
- }
+ if (locals eq mapped) super.transform(trees, c)
+ else withSubstitution(locals, mapped).transform(trees, c)
+ }
def apply[ThisTree <: tpd.Tree](tree: ThisTree): ThisTree = transform(tree, ()).asInstanceOf[ThisTree]
@@ -690,6 +688,12 @@ object TypedTrees {
val tree1 = apply(annot.tree)
if (tree1 eq annot.tree) annot else ConcreteAnnotation(tree1)
}
+
+ /** The current tree map composed with a substitution [from -> to] */
+ def withSubstitution(from: List[Symbol], to: List[Symbol]) =
+ new TreeMapper(
+ typeMap andThen ((tp: Type) => tp.substSym(from, to)),
+ ownerMap andThen (from zip to).toMap)
}
// ensure that constructors are fully applied?