diff options
author | Martin Odersky <odersky@gmail.com> | 2013-03-04 10:33:21 +0100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2013-03-04 10:33:21 +0100 |
commit | c7a58aaa0a8c459f99daa23590cd343402559c42 (patch) | |
tree | 2358e4e6c94484dc6abbb13a76d1ecca5f3bba7d /src | |
parent | f2cd8ba0f899c6da94a3dae8efc6cafa75f4aa0b (diff) | |
download | dotty-c7a58aaa0a8c459f99daa23590cd343402559c42.tar.gz dotty-c7a58aaa0a8c459f99daa23590cd343402559c42.tar.bz2 dotty-c7a58aaa0a8c459f99daa23590cd343402559c42.zip |
Polishing of Symbols.
Diffstat (limited to 'src')
-rw-r--r-- | src/dotty/tools/dotc/core/SymDenotations.scala | 19 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Symbols.scala | 51 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/TypedTrees.scala | 20 |
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? |