From 7cde8b6d78022aadb00d3f82fb9019da39a62b49 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sat, 23 Feb 2013 13:36:05 +0100 Subject: Moving associatedFile from SymDenotation to Symbol Motivation: This is something that stays invariant over all periods. but _can_ change between compilation runs. Therefore it matches the lifetime of a Symbol. --- src/dotty/tools/dotc/core/Definitions.scala | 2 +- src/dotty/tools/dotc/core/SymDenotations.scala | 56 ++++++++-------------- src/dotty/tools/dotc/core/Symbols.scala | 31 ++++++++++-- src/dotty/tools/dotc/core/pickling/UnPickler.scala | 4 +- 4 files changed, 50 insertions(+), 43 deletions(-) diff --git a/src/dotty/tools/dotc/core/Definitions.scala b/src/dotty/tools/dotc/core/Definitions.scala index 935369091..ef9f3d70d 100644 --- a/src/dotty/tools/dotc/core/Definitions.scala +++ b/src/dotty/tools/dotc/core/Definitions.scala @@ -41,7 +41,7 @@ class Definitions(implicit ctx: Context) { val parentRefs: List[TypeRef] = ctx.normalizeToRefs(parents, cls, paramDecls) CompleteClassDenotation(cls, ScalaPackageClass, name, flags, parentRefs, decls = paramDecls)(ctx) } - new ClassSymbol(NoCoord, classDenot) + new ClassSymbol(NoCoord, classDenot, null) } private def mkArityArray(name: String, arity: Int, countFrom: Int): Array[ClassSymbol] = { diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala index e179a11a7..c976bbf0d 100644 --- a/src/dotty/tools/dotc/core/SymDenotations.scala +++ b/src/dotty/tools/dotc/core/SymDenotations.scala @@ -55,23 +55,6 @@ object SymDenotations { /** `fullName` where `.' is the separator character */ def fullName(implicit ctx: Context): Name = fullName('.') - /** The source or class file from which this denotation was generated, null if not applicable. */ - def associatedFile(implicit ctx: Context): AbstractFile = topLevelClass.associatedFile - - /** The class file from which this denotation was generated, null if not applicable. */ - final def binaryFile(implicit ctx: Context): AbstractFile = pickFile(associatedFile, classFile = true) - - /** The source file from which this denotation was generated, null if not applicable. */ - final def sourceFile(implicit ctx: Context): AbstractFile = pickFile(associatedFile, classFile = false) - - /** Desire to re-use the field in ClassSymbol which stores the source - * file to also store the classfile, but without changing the behavior - * of sourceFile (which is expected at least in the IDE only to - * return actual source code.) So sourceFile has classfiles filtered out. - */ - private def pickFile(file: AbstractFile, classFile: Boolean): AbstractFile = - if ((file eq null) || classFile != (file.path endsWith ".class")) null else file - private[this] var _flags: FlagSet = initFlags /** The flag set */ @@ -197,11 +180,15 @@ object SymDenotations { /** Is this denotation defined in the same scope and compilation unit as that symbol? */ def isCoDefinedWith(that: Symbol)(implicit ctx: Context) = (this.effectiveOwner == that.effectiveOwner) && - ( !(this.effectiveOwner.isPackageClass) - || (this.sourceFile == null) - || (that.sourceFile == null) - || (this.sourceFile.path == that.sourceFile.path) // Cheap possibly wrong check, then expensive normalization - || (this.sourceFile.canonicalPath == that.sourceFile.canonicalPath) + ( !this.effectiveOwner.isPackageClass + || { val thisFile = this.symbol.associatedFile + val thatFile = that.symbol.associatedFile + ( thisFile == null + || thatFile == null + || thisFile.path == thatFile.path // Cheap possibly wrong check, then expensive normalization + || thisFile.canonicalPath == thatFile.canonicalPath + ) + } ) /** Is this a denotation of a stable term (or an arbitrary type)? */ @@ -514,7 +501,7 @@ object SymDenotations { * Note: important to leave initctx non-implicit, and to check that it is not * retained after object construction. */ - abstract class ClassDenotation(initFlags: FlagSet, assocFile: AbstractFile)(initctx: Context) + abstract class ClassDenotation(initFlags: FlagSet)(initctx: Context) extends SymDenotation(initFlags) { import NameFilter._ import util.LRU8Cache @@ -541,8 +528,6 @@ object SymDenotations { ClassInfo(owner.thisType, this) } - override def associatedFile(implicit ctx: Context): AbstractFile = assocFile - private[this] var _typeParams: List[TypeSymbol] = _ /** The type parameters of this class */ @@ -814,9 +799,8 @@ object SymDenotations { privateWithin: Symbol = this.privateWithin, parents: List[TypeRef] = this.parents, selfType: Type = this.selfType, - decls: Scope = this.decls, - assocFile: AbstractFile = this.assocFile)(implicit ctx: Context) = - new CompleteClassDenotation(sym, owner, name, initFlags, parents, privateWithin, selfType, decls, assocFile)(ctx) + decls: Scope = this.decls)(implicit ctx: Context) = + new CompleteClassDenotation(sym, owner, name, initFlags, parents, privateWithin, selfType, decls)(ctx) } // -------- Concrete classes for instantiating denotations -------------------------- @@ -862,9 +846,8 @@ object SymDenotations { val parents: List[TypeRef], val privateWithin: Symbol, optSelfType: Type, - val decls: Scope, - assocFile: AbstractFile)(initctx: Context) - extends ClassDenotation(initFlags, assocFile)(initctx) { + val decls: Scope)(initctx: Context) + extends ClassDenotation(initFlags)(initctx) { val selfType = if (optSelfType == NoType) typeConstructor(initctx) else optSelfType final def preCompleteDecls = decls } @@ -876,16 +859,15 @@ object SymDenotations { decls: Scope = newScope, assocFile: AbstractFile = null)(implicit ctx: Context) = new CompleteClassDenotation(symbol, owner, name, initFlags, parents, - privateWithin, optSelfType, decls, assocFile)(ctx) + privateWithin, optSelfType, decls)(ctx) class LazyClassDenotation( val symbol: ClassSymbol, val owner: Symbol, val name: TypeName, initFlags: FlagSet, - var completer: ClassCompleter, - assocFile: AbstractFile - )(initctx: Context) extends ClassDenotation(initFlags, assocFile)(initctx) with isLazy[LazyClassDenotation] { + var completer: ClassCompleter + )(initctx: Context) extends ClassDenotation(initFlags)(initctx) with isLazy[LazyClassDenotation] { private[this] var _parents: List[TypeRef] = null private[this] var _selfType: Type = null @@ -907,7 +889,7 @@ object SymDenotations { def LazyClassDenotation( symbol: ClassSymbol, owner: Symbol, name: TypeName, initFlags: FlagSet, completer: ClassCompleter, assocFile: AbstractFile = null)(implicit ctx: Context) = - new LazyClassDenotation(symbol, owner, name, initFlags, completer, assocFile)(ctx) + new LazyClassDenotation(symbol, owner, name, initFlags, completer)(ctx) object NoDenotation extends SymDenotation(EmptyFlags) { override def isTerm = false @@ -976,7 +958,7 @@ object SymDenotations { def apply(denot: LazyClassDenotation): Unit = { val sym = denot.symbol - val file = denot.associatedFile + val file = sym.associatedFile val (location, src) = if (file != null) (s" in $file", file.toString) else ("", "the signature") diff --git a/src/dotty/tools/dotc/core/Symbols.scala b/src/dotty/tools/dotc/core/Symbols.scala index edd610bca..2aec15894 100644 --- a/src/dotty/tools/dotc/core/Symbols.scala +++ b/src/dotty/tools/dotc/core/Symbols.scala @@ -27,7 +27,7 @@ trait Symbols { this: Context => } def newLazyClassSymbol(owner: Symbol, name: TypeName, initFlags: FlagSet, completer: ClassCompleter, assocFile: AbstractFile = null, coord: Coord = NoCoord) = - new ClassSymbol(coord, new LazyClassDenotation(_, owner, name, initFlags, completer, assocFile)(this)) + new ClassSymbol(coord, new LazyClassDenotation(_, owner, name, initFlags, completer)(this), assocFile) def newLazyModuleSymbols(owner: Symbol, name: TermName, @@ -64,7 +64,7 @@ trait Symbols { this: Context => coord: Coord = NoCoord) = new ClassSymbol(coord, new CompleteClassDenotation( - _, owner, name, flags, parents, privateWithin, optSelfType, decls, assocFile)(this)) + _, owner, name, flags, parents, privateWithin, optSelfType, decls)(this), assocFile) def newModuleSymbols( owner: Symbol, @@ -257,6 +257,26 @@ object Symbols { /** The current name of this symbol */ final def name(implicit ctx: Context): ThisName = denot.name.asInstanceOf[ThisName] + /** The source or class file from which this class was generated, null if not applicable. */ + def associatedFile(implicit ctx: Context): AbstractFile = + this.denot.topLevelClass.symbol.associatedFile + + /** The class file from which this class was generated, null if not applicable. */ + final def binaryFile(implicit ctx: Context): AbstractFile = + pickFile(associatedFile, classFile = true) + + /** The source file from which this class was generated, null if not applicable. */ + final def sourceFile(implicit ctx: Context): AbstractFile = + pickFile(associatedFile, classFile = false) + + /** Desire to re-use the field in ClassSymbol which stores the source + * file to also store the classfile, but without changing the behavior + * of sourceFile (which is expected at least in the IDE only to + * return actual source code.) So sourceFile has classfiles filtered out. + */ + private def pickFile(file: AbstractFile, classFile: Boolean): AbstractFile = + if ((file eq null) || classFile != (file.path endsWith ".class")) null else file + def show(implicit ctx: Context): String = ctx.show(this) def showLocated(implicit ctx: Context): String = ctx.showLocated(this) def showDcl(implicit ctx: Context): String = ctx.showDcl(this) @@ -269,10 +289,15 @@ object Symbols { type TermSymbol = Symbol { type ThisName = TermName } type TypeSymbol = Symbol { type ThisName = TypeName } - class ClassSymbol(coord: Coord, denotf: ClassSymbol => ClassDenotation) extends Symbol(coord, s => denotf(s.asClass)) { + class ClassSymbol(coord: Coord, denotf: ClassSymbol => ClassDenotation, assocFile: AbstractFile) extends Symbol(coord, s => denotf(s.asClass)) { type ThisName = TypeName + /** The source or class file from which this class was generated, null if not applicable. */ + override def associatedFile(implicit ctx: Context): AbstractFile = + if (this.owner.isPackageClass) assocFile + else super.associatedFile + final def classDenot(implicit ctx: Context): ClassDenotation = denot.asInstanceOf[ClassDenotation] diff --git a/src/dotty/tools/dotc/core/pickling/UnPickler.scala b/src/dotty/tools/dotc/core/pickling/UnPickler.scala index 7c3e6ca43..35ef5dece 100644 --- a/src/dotty/tools/dotc/core/pickling/UnPickler.scala +++ b/src/dotty/tools/dotc/core/pickling/UnPickler.scala @@ -142,8 +142,8 @@ class UnPickler(bytes: Array[Byte], classRoot: LazyClassDenotation, moduleRoot: } def source: AbstractFile = { - val f = classRoot.associatedFile - if (f != null) f else moduleRoot.associatedFile + val f = classRoot.symbol.associatedFile + if (f != null) f else moduleRoot.symbol.associatedFile } private def checkVersion() { -- cgit v1.2.3