diff options
Diffstat (limited to 'src/dotty/tools/dotc/core')
-rw-r--r-- | src/dotty/tools/dotc/core/Annotations.scala | 12 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Contexts.scala | 1 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Definitions.scala | 6 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Flags.scala | 22 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/NameOps.scala | 5 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Printers.scala | 15 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/StdNames.scala | 1 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/SymDenotations.scala | 53 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/SymbolLoaders.scala | 143 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Symbols.scala | 50 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Types.scala | 87 |
11 files changed, 287 insertions, 108 deletions
diff --git a/src/dotty/tools/dotc/core/Annotations.scala b/src/dotty/tools/dotc/core/Annotations.scala index 71e747598..8aead084d 100644 --- a/src/dotty/tools/dotc/core/Annotations.scala +++ b/src/dotty/tools/dotc/core/Annotations.scala @@ -9,4 +9,16 @@ object Annotations { def appliesToModule: Boolean = ??? } + abstract class InternalAnnotation extends Annotation { + + } + + case class Alias(sym: Symbol) extends InternalAnnotation { + + } + + case class Child(child: ClassSymbol) extends InternalAnnotation { + + } + }
\ No newline at end of file diff --git a/src/dotty/tools/dotc/core/Contexts.scala b/src/dotty/tools/dotc/core/Contexts.scala index 1dc7ff2c1..b1b047847 100644 --- a/src/dotty/tools/dotc/core/Contexts.scala +++ b/src/dotty/tools/dotc/core/Contexts.scala @@ -66,6 +66,7 @@ object Contexts { def debug: Boolean = ??? def error(msg: String) = ??? def warning(msg: String) = ??? + def log(msg: String) = ??? def inform(msg: String) = ??? def informTime(msg: String, start: Long): Unit = ??? diff --git a/src/dotty/tools/dotc/core/Definitions.scala b/src/dotty/tools/dotc/core/Definitions.scala index 73c874422..35527573f 100644 --- a/src/dotty/tools/dotc/core/Definitions.scala +++ b/src/dotty/tools/dotc/core/Definitions.scala @@ -20,8 +20,10 @@ class Definitions(implicit ctx: Context) { def requiredClass(str: String): ClassSymbol = ??? def requiredModule(str: String): TermSymbol = ??? - lazy val RootClass: ClassSymbol = ctx.newLazyClassSymbol( - NoSymbol, tpnme.ROOT, PackageCreationFlags, ctx.rootLoader) + lazy val RootClass: ClassSymbol = ctx.newLazyPackageSymbols( + NoSymbol, nme.ROOT, ctx.rootLoader)._2 + lazy val RootPackage: TermSymbol = ctx.newTermSymbol( + NoSymbol, nme.ROOTPKG, PackageCreationFlags, TypeRef(NoPrefix, RootClass)) lazy val ScalaPackageVal = requiredPackage("scala") lazy val ScalaPackageClass = ScalaPackageVal.moduleClass.asClass diff --git a/src/dotty/tools/dotc/core/Flags.scala b/src/dotty/tools/dotc/core/Flags.scala index 13392a1c9..a2158a46a 100644 --- a/src/dotty/tools/dotc/core/Flags.scala +++ b/src/dotty/tools/dotc/core/Flags.scala @@ -322,6 +322,9 @@ object Flags { /** Symbol is an implementation class */ final val ImplClass = typeFlag(???, "<implclass>") + /** An existentially bound symbol (Scala 2.x only) */ + final val Scala2Existential = typeFlag(???, "<existential>") + // --------- Combined Flag Sets and Conjunctions ---------------------- /** Flags representing source modifiers */ @@ -345,23 +348,32 @@ object Flags { /** These flags are pickled */ final val PickledFlags = InitialFlags &~ FlagsNotPickled - /** Packages always have these flags set */ + /** Modules always have these flags set */ + final val ModuleCreationFlags = Module + + /** Module classes always have these flags set */ + final val ModuleClassCreationFlags = Module | Final + + /** Packages and package classes always have these flags set */ final val PackageCreationFlags = commonFlags( Module, Package, Final, JavaDefined, Static) /** A value that's unstable unless complemented with a Stable flag */ final val UnstableValue = oneOf(Mutable, Method, ByNameParam) + /** Flags that are passed from a type parameter of a class to a refinement symbol + * that sets the type parameter */ + final val RetainedTypeArgFlags = Covariant | Contravariant | Protected | Local + /** Labeled private[this] */ final val PrivateLocal = allOf(Private, Local) + /** Labeled protected[this] */ + final val ProtectedLocal = allOf(Protected, Local) + /** Labeled `private` or `protected[local]` */ final val PrivateOrLocal = oneOf(Private, Local) /** Java symbol which is `protected` and `static` */ final val StaticProtected = allOf(JavaDefined, Protected, Static) - - /** Labeled `protected[this]` */ - final val ProtectedLocal = allOf(Protected, Local) - }
\ No newline at end of file diff --git a/src/dotty/tools/dotc/core/NameOps.scala b/src/dotty/tools/dotc/core/NameOps.scala index 334d3a908..c422c4ec5 100644 --- a/src/dotty/tools/dotc/core/NameOps.scala +++ b/src/dotty/tools/dotc/core/NameOps.scala @@ -154,6 +154,11 @@ object NameOps { implicit class TypeNameDecorator(val name: TypeName) extends AnyVal { def isUnboxedName = Boxed contains name def boxedName: TypeName = Boxed(name) + + /** The expanded name of `name` relative to this class `base` with given `separator` + */ + def expandedName(base: Symbol, separator: Name = nme.EXPAND_SEPARATOR)(implicit ctx: Context): TypeName = + (base.fullName('$') ++ separator ++ name).toTypeName } implicit class TermNameDecorator(val name: TermName) extends AnyVal { diff --git a/src/dotty/tools/dotc/core/Printers.scala b/src/dotty/tools/dotc/core/Printers.scala index 354790e97..a35b0b797 100644 --- a/src/dotty/tools/dotc/core/Printers.scala +++ b/src/dotty/tools/dotc/core/Printers.scala @@ -1,7 +1,7 @@ package dotty.tools.dotc package core -import Types._, Symbols._, Contexts._, Scopes._ +import Types._, Symbols._, Contexts._, Scopes._, Names._ trait Printers { this: Context => @@ -10,6 +10,8 @@ trait Printers { this: Context => def showLocated(sym: Symbol): String = printer(this).showLocated(sym) def showDef(sym: Symbol): String = printer(this).showDef(sym) def show(sc: Scope): String = printer(this).show(sc) + def show(syms: List[Symbol], sep: String): String = printer(this).show(syms, sep) + def showNameDetailed(name: Name) = printer(this).showNameDetailed(name) private var _diagnostics: Option[StringBuilder] = _ @@ -36,6 +38,8 @@ object Printers { def showLocated(sym: Symbol): String def showDef(sym: Symbol): String def show(sc: Scope): String + def show(syms: List[Symbol], sep: String): String + def showNameDetailed(name: Name): String } class StdPrinter(implicit ctx: Context) extends Printer { @@ -101,7 +105,14 @@ object Printers { def showLocated(sym: Symbol): String = ??? def showDef(sym: Symbol): String = ??? def show(sc: Scope): String = - sc.toList.map(_.showDef).mkString("Scope{\n ", ";\n ", "\n}") + "Scope{\n" + show(sc.toList, ";\n ") + "\n}" + + def show(syms: List[Symbol], sep: String): String = + syms map (_.showDef) mkString sep + + def showNameDetailed(name: Name): String = + (if (name.isTypeName) "type " else "term ") + name + } final val maxShowRecursions = 50 diff --git a/src/dotty/tools/dotc/core/StdNames.scala b/src/dotty/tools/dotc/core/StdNames.scala index a89b970fe..d77ab8c56 100644 --- a/src/dotty/tools/dotc/core/StdNames.scala +++ b/src/dotty/tools/dotc/core/StdNames.scala @@ -233,6 +233,7 @@ object StdNames { val OUTER: N = "$outer" val OUTER_LOCAL: N = "$outer " val OUTER_SYNTH: N = "<outer>" // emitted by virtual pattern matcher, replaced by outer accessor in explicitouter + val REFINE_CLASS: N = "<refinement>" val ROOTPKG: N = "_root_" val SELECTOR_DUMMY: N = "<unapply-selector>" val SELF: N = "$this" diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala index f103e14d4..5e2ff4dfa 100644 --- a/src/dotty/tools/dotc/core/SymDenotations.scala +++ b/src/dotty/tools/dotc/core/SymDenotations.scala @@ -2,7 +2,7 @@ package dotty.tools.dotc package core import Periods._, Contexts._, Symbols._, Denotations._, Names._, Annotations._ -import Types._, Flags._, Decorators._, Transformers._, StdNames._ +import Types._, Flags._, Decorators._, Transformers._, StdNames._, Scopes._ import Scopes.Scope import collection.mutable import collection.immutable.BitSet @@ -41,8 +41,8 @@ object SymDenotations { def flags: FlagSet = { ensureLoaded(); _flags } def flags_=(flags: FlagSet): Unit = { _flags = flags } - def setFlags(flags: FlagSet): Unit = { _flags |= flags } - def resetFlags(flags: FlagSet): Unit = { _flags &~= flags } + def setFlag(flags: FlagSet): Unit = { _flags |= flags } + def resetFlag(flags: FlagSet): Unit = { _flags &~= flags } private[this] var _annotations: List[Annotation] = Nil def annotations: List[Annotation] = { ensureCompleted(); _annotations } @@ -50,6 +50,12 @@ object SymDenotations { def hasAnnotation(cls: Symbol) = dropOtherAnnotations(annotations, cls).nonEmpty + final def addAnnotation(annot: Annotation): Unit = annotations = + annot :: annotations + + final def setAlias(alias: Symbol)(implicit ctx: Context): Unit = + addAnnotation(Alias(alias)) + @tailrec private def dropOtherAnnotations(anns: List[Annotation], cls: Symbol): List[Annotation] = anns match { case ann :: rest => if (ann matches cls) anns else dropOtherAnnotations(rest, cls) @@ -165,10 +171,10 @@ object SymDenotations { final def matchingSymbol(inClass: Symbol, site: Type)(implicit ctx: Context): Symbol = { var denot = inClass.info.nonPrivateDecl(name) if (denot.isTerm) { - val targetType = site.memberInfo(this) + val targetType = site.memberInfo(symbol) if (denot.isOverloaded) denot = denot.atSignature(targetType.signature) - if (!(site.memberInfo(denot.asInstanceOf[SymDenotation]) matches targetType)) + if (!(site.memberInfo(denot.symbol) matches targetType)) denot = NoDenotation } denot.symbol @@ -455,7 +461,7 @@ object SymDenotations { parent.denot match { case classd: ClassDenotation => includeFingerPrint(bits, classd.definedFingerPrint) - parent.denot.setFlags(Frozen) + parent.denot.setFlag(Frozen) case _ => } ps = ps.tail @@ -692,7 +698,7 @@ object SymDenotations { override protected[core] def tryLoad(): Unit = try { if (flags is Locked) throw new CyclicReference(symbol) - setFlags(Locked) + setFlag(Locked) completer.load(this) } finally { flags &~= Locked @@ -701,7 +707,7 @@ object SymDenotations { override protected[core] def tryComplete(): Unit = try { if (flags is Locked) throw new CyclicReference(symbol) - setFlags(Locked) + setFlag(Locked) val c = completer completer = null // set completer to null to avoid space leaks // and to make any subsequent completion attempt a CompletionError @@ -731,11 +737,11 @@ object SymDenotations { type ClassCompleter = Completer[LazyClassDenotation] class ModuleCompleter(cctx: CondensedContext) extends Completer[LazySymDenotation] { - implicit def ctx: Context = cctx + implicit protected def ctx: Context = cctx def classDenot(denot: LazySymDenotation) = denot.moduleClass.denot.asInstanceOf[LazyClassDenotation] def copyLoadedFields(denot: LazySymDenotation, from: LazyClassDenotation) = { - denot.setFlags(from.flags.toTermFlags & RetainedModuleFlags) + denot.setFlag(from.flags.toTermFlags & RetainedModuleFlags) denot.privateWithin = from.privateWithin } def copyCompletedFields(denot: LazySymDenotation, from: LazyClassDenotation) = { @@ -748,6 +754,33 @@ object SymDenotations { copyCompletedFields(denot, classDenot(denot)) } + /** A completer for missing references */ + class StubCompleter[Denot <: SymDenotation](cctx: CondensedContext) extends Completer[Denot] { + implicit protected def ctx: Context = cctx + + def initializeToDefaults(denot: Denot) = denot match { // todo: initialize to errors instead? + case denot: LazySymDenotation => + denot.privateWithin = NoSymbol + denot.info = NoType + case denot: LazyClassDenotation => + denot.privateWithin = NoSymbol + denot.parents = Nil + denot.selfType = denot.thisType + denot.decls = EmptyScope + } + + def complete(denot: Denot): Unit = { + val from = + if (denot.associatedFile == null) "" + else s" - referenced from ${denot.associatedFile.canonicalPath}" + val sym = denot.symbol + val symStr = s"${sym.showKind} ${sym.showName}${sym.showLocated}" + ctx.error(s"bad symbolic reference to $symStr$from (a classfile may be missing)") + if (ctx.settings.debug.value) (new Throwable).printStackTrace + initializeToDefaults(denot) + } + } + class CompletionError(denot: SymDenotation) extends Error("Trying to access missing symbol ${denot.symbol.fullName}") // ---- Name filter -------------------------------------------------------- diff --git a/src/dotty/tools/dotc/core/SymbolLoaders.scala b/src/dotty/tools/dotc/core/SymbolLoaders.scala index 671c4ea65..fa888ae12 100644 --- a/src/dotty/tools/dotc/core/SymbolLoaders.scala +++ b/src/dotty/tools/dotc/core/SymbolLoaders.scala @@ -9,12 +9,11 @@ package core import java.io.IOException import scala.compat.Platform.currentTime -import dotty.tools.io.{ClassPath, AbstractFile} -import Contexts._, Symbols._, Flags._, SymDenotations._, Types._ +import dotty.tools.io.{ ClassPath, AbstractFile } +import Contexts._, Symbols._, Flags._, SymDenotations._, Types._, Scopes._ import Decorators.StringDecorator //import classfile.ClassfileParser - /** A base class for Symbol loaders with some overridable behavior */ class SymbolLoaders { @@ -34,7 +33,7 @@ class SymbolLoaders { /** Enter module with given `name` into scope of `owner`. */ def enterModule(owner: Symbol, name: String, completer: SymbolLoader)(implicit ctx: Context): Symbol = { - val module = ctx.newLazyModuleSymbol(owner, name.toTermName, EmptyFlags, completer, assocFile = completer.sourceFileOrNull) + val module = ctx.newLazyModuleSymbols(owner, name.toTermName, EmptyFlags, completer, assocFile = completer.sourceFileOrNull)._1 enterIfNew(owner, module, completer) } @@ -64,7 +63,7 @@ class SymbolLoaders { return NoSymbol } } - ctx.newLazyModuleSymbol(owner, pname, PackageCreationFlags, completer).entered + ctx.newLazyModuleSymbols(owner, pname, PackageCreationFlags, completer)._1.entered } /** Enter class and module with given `name` into scope of `owner` @@ -98,14 +97,13 @@ class SymbolLoaders { */ def binaryOnly(owner: Symbol, name: String)(implicit ctx: Context): Boolean = name == "package" && - (owner.fullName == "scala" || owner.fullName == "scala.reflect") + (owner.fullName == "scala" || owner.fullName == "scala.reflect") /** Initialize toplevel class and module symbols in `owner` from class path representation `classRep` */ def initializeFromClassPath(owner: Symbol, classRep: ClassPath#ClassRep)(implicit ctx: Context) { - ((classRep.binary, classRep.source) : @unchecked) match { - case (Some(bin), Some(src)) - if needCompile(bin, src) && !binaryOnly(owner, classRep.name) => + ((classRep.binary, classRep.source): @unchecked) match { + case (Some(bin), Some(src)) if needCompile(bin, src) && !binaryOnly(owner, classRep.name) => if (ctx.settings.verbose.value) ctx.inform("[symloader] picked up newer source file for " + src.path) enterToplevelsFromSource(owner, classRep.name, src) case (None, Some(src)) => @@ -118,82 +116,85 @@ class SymbolLoaders { def needCompile(bin: AbstractFile, src: AbstractFile) = src.lastModified >= bin.lastModified -} - /** - * A lazy type that completes itself by calling parameter doComplete. - * Any linked modules/classes or module classes are also initialized. - * Todo: consider factoring out behavior from TopClassCompleter/SymbolLoader into - * supertrait SymLoader - */ - abstract class SymbolLoader(cctx: CondensedContext) extends ClassCompleter { - implicit def ctx: Context = cctx - - /** Load source or class file for `root`, return */ - protected def doComplete(root: LazyClassDenotation): Unit - - def sourceFileOrNull: AbstractFile = null - /** - * Description of the resource (ClassPath, AbstractFile, MsilFile) - * being processed by this loader - */ - protected def description: String - - private var ok = false - - override def complete(root: LazyClassDenotation) { - def signalError(ex: Exception) { - ok = false - if (ctx.settings.debug.value) ex.printStackTrace() - val msg = ex.getMessage() - ctx.error( - if (msg eq null) "i/o error while loading " + root.name - else "error while loading " + root.name + ", " + msg); - } - try { - val start = currentTime - doComplete(root) - ctx.informTime("loaded " + description, start) - ok = true - } catch { - case ex: IOException => - signalError(ex) - case ex: MissingRequirementError => - signalError(ex) - } - root.linkedClass.denot match { - case companion: LazyClassDenotation => companion.completer = null - } - } - } - - /* - /** - * Load contents of a package + /** Load contents of a package */ - class PackageLoader(classpath: ClassPath[platform.BinaryRepr]) extends SymbolLoader with FlagAgnosticCompleter { - protected def description = "package loader "+ classpath.name + class PackageLoader(classpath: ClassPath)(cctx: CondensedContext) extends SymbolLoader { + implicit val ctx: Context = cctx + protected def description = "package loader " + classpath.name - protected def doComplete(root: Symbol) { + protected def doComplete(root: LazyClassDenotation) { assert(root.isPackageClass, root) - root.setInfo(new PackageClassInfoType(newScope, root)) - - val sourcepaths = classpath.sourcepaths + root.parents = Nil + root.decls = newScope if (!root.isRoot) { - for (classRep <- classpath.classes if platform.doLoad(classRep)) { - initializeFromClassPath(root, classRep) + for (classRep <- classpath.classes) { + initializeFromClassPath(root.symbol, classRep) } } - if (!root.isEmptyPackageClass) { + if (!root.isEmptyPackage) { for (pkg <- classpath.packages) { - enterPackage(root, pkg.name, new PackageLoader(pkg)) + enterPackage(root.symbol, pkg.name, new PackageLoader(pkg)(cctx)) } - openPackageModule(root) + openPackageModule(root.symbol) } } } + def openPackageModule(pkgClass: Symbol): Unit = ??? + +} +/** A lazy type that completes itself by calling parameter doComplete. + * Any linked modules/classes or module classes are also initialized. + * Todo: consider factoring out behavior from TopClassCompleter/SymbolLoader into + * supertrait SymLoader + */ +abstract class SymbolLoader extends ClassCompleter { + implicit val ctx: Context + + /** Load source or class file for `root`, return */ + protected def doComplete(root: LazyClassDenotation): Unit + + def sourceFileOrNull: AbstractFile = null + /** Description of the resource (ClassPath, AbstractFile, MsilFile) + * being processed by this loader + */ + protected def description: String + + private var ok = false + + override def complete(root: LazyClassDenotation) { + def signalError(ex: Exception) { + ok = false + if (ctx.settings.debug.value) ex.printStackTrace() + val msg = ex.getMessage() + ctx.error( + if (msg eq null) "i/o error while loading " + root.name + else "error while loading " + root.name + ", " + msg); + } + try { + val start = currentTime + doComplete(root) + ctx.informTime("loaded " + description, start) + ok = true + } catch { + case ex: IOException => + signalError(ex) + case ex: MissingRequirementError => + signalError(ex) + } + // also mark linked class as completed if it exists + root.linkedClass.denot match { + case companion: LazyClassDenotation => companion.completer = null + } + } +} + + + /* + + class ClassfileLoader(val classfile: AbstractFile) extends SymbolLoader with FlagAssigningCompleter { private object classfileParser extends ClassfileParser { val global: SymbolLoaders.this.global.type = SymbolLoaders.this.global diff --git a/src/dotty/tools/dotc/core/Symbols.scala b/src/dotty/tools/dotc/core/Symbols.scala index ecb3d5554..e77959132 100644 --- a/src/dotty/tools/dotc/core/Symbols.scala +++ b/src/dotty/tools/dotc/core/Symbols.scala @@ -27,23 +27,26 @@ trait Symbols { this: Context => def newLazyClassSymbol(owner: Symbol, name: TypeName, initFlags: FlagSet, completer: ClassCompleter, assocFile: AbstractFile = null) = new ClassSymbol(new LazyClassDenotation(_, owner, name, initFlags, completer, assocFile)(this)) - def newLazyModuleSymbol(owner: Symbol, + def newLazyModuleSymbols(owner: Symbol, name: TermName, flags: FlagSet, completer: ClassCompleter, assocFile: AbstractFile = null) = { val module = newLazyTermSymbol( - owner, name, flags | Module, new ModuleCompleter(condensed)) + owner, name, flags | ModuleCreationFlags, new ModuleCompleter(condensed)) val modcls = newLazyClassSymbol( - owner, name.toTypeName, flags | Module | Final, completer, assocFile) + owner, name.toTypeName, flags | ModuleClassCreationFlags, completer, assocFile) module.denot.asInstanceOf[LazySymDenotation].info = - TypeRef(owner.thisType, modcls) + TypeRef(owner.thisType(ctx), modcls) modcls.denot.asInstanceOf[LazyClassDenotation].selfType = TermRef(owner.thisType, module) - module + (module, modcls) } + def newLazyPackageSymbols(owner: Symbol, name: TermName, completer: ClassCompleter) = + newLazyModuleSymbols(owner, name, PackageCreationFlags, completer) + def newTermSymbol( owner: Symbol, name: TermName, @@ -78,7 +81,7 @@ trait Symbols { this: Context => new ClassSymbol(new CompleteClassDenotation( _, owner, name, flags, privateWithin, parents, optSelfType, decls, assocFile)(this)) - def newModuleSymbol( + def newModuleSymbols( owner: Symbol, name: TermName, flags: FlagSet, @@ -88,14 +91,29 @@ trait Symbols { this: Context => decls: Scope = newScope, assocFile: AbstractFile = null)(implicit ctx: Context) = { - val module = newLazyTermSymbol(owner, name, flags, new ModuleCompleter(condensed)) + val module = newLazyTermSymbol(owner, name, flags | ModuleCreationFlags, new ModuleCompleter(condensed)) val modcls = newClassSymbol( - owner, name.toTypeName, classFlags, parents, privateWithin, + owner, name.toTypeName, classFlags | ModuleClassCreationFlags, parents, privateWithin, optSelfType = TermRef(owner.thisType, module), decls, assocFile) module.denot.asInstanceOf[LazySymDenotation].info = TypeRef(owner.thisType, modcls) - module + (module, modcls) + } + + def newPackageSymbols( + owner: Symbol, + name: TermName, + decls: Scope = newScope)(implicit ctx: Context) = + newModuleSymbols( + owner, name, PackageCreationFlags, PackageCreationFlags, Nil, NoSymbol, decls) + + def newStubSymbol(owner: Symbol, name: Name)(implicit ctx: Context): Symbol = { + def stub[Denot <: SymDenotation] = new StubCompleter[Denot](ctx.condensed) + name match { + case name: TermName => ctx.newLazyTermSymbol(owner, name, EmptyFlags, stub) + case name: TypeName => ctx.newLazyClassSymbol(owner, name, EmptyFlags, stub) + } } } @@ -181,9 +199,21 @@ object Symbols { /** The current annotations of this symbol */ final def annotations(implicit ctx: Context): List[Annotation] = denot.annotations + /** Set given flags(s) of this symbol */ + def setFlag(flags: FlagSet)(implicit ctx: Context): Unit = denot.setFlag(flags) + + /** Unset given flag(s) of this symbol */ + def resetFlag(flags: FlagSet)(implicit ctx: Context): Unit = denot.resetFlag(flags) + /** Does this symbol have an annotation matching the given class symbol? */ final def hasAnnotation(cls: Symbol)(implicit ctx: Context): Boolean = denot.hasAnnotation(cls) + /** Add given annotation to this symbol */ + final def addAnnotation(annot: Annotation)(implicit ctx: Context): Unit = denot.addAnnotation(annot) + + /** Record that this symbol is an alias of given `alias` symbol */ + final def setAlias(alias: Symbol)(implicit ctx: Context): Unit = denot.setAlias(alias) + /** The chain of owners of this symbol, starting with the symbol itself */ final def ownersIterator(implicit ctx: Context): Iterator[Symbol] = denot.ownersIterator @@ -307,6 +337,8 @@ object Symbols { def show(implicit ctx: Context): String = ctx.show(this) def showLocated(implicit ctx: Context): String = ctx.showLocated(this) def showDef(implicit ctx: Context): String = ctx.showDef(this) + def showKind(implicit tcx: Context): String = ??? + def showName(implicit ctx: Context): String = ??? /** The type parameters of a class symbol, Nil for all other symbols */ def typeParams(implicit ctx: Context): List[TypeSymbol] = denot.typeParams diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala index 256ab7721..5a8d5b05d 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -233,6 +233,18 @@ object Types { case _ => List() } + /** Map function over elements of an AndType, rebuilding with & */ + def mapAnd(f: Type => Type)(implicit ctx: Context): Type = this match { + case AndType(tp1, tp2) => tp1.mapAnd(f) & tp2.mapAnd(f) + case _ => f(this) + } + + /** Map function over elements of an OrType, rebuilding with | */ + def mapOr(f: Type => Type)(implicit ctx: Context): Type = this match { + case OrType(tp1, tp2) => tp1.mapAnd(f) | tp2.mapAnd(f) + case _ => f(this) + } + /** The normalized prefix of this type is: * For an alias type, the normalized prefix of its alias * For all other named type and class infos: the prefix. @@ -350,9 +362,14 @@ object Types { * */ + /** The info of `denot`, seen as a member of this type. */ +// final def memberInfo(denot: SymDenotation)(implicit ctx: Context): Type = { +// denot.info.asSeenFrom(this, denot.owner) +// } + /** The info of `sym`, seen as a member of this type. */ - final def memberInfo(denot: SymDenotation)(implicit ctx: Context): Type = { - denot.info.asSeenFrom(this, denot.owner) + final def memberInfo(sym: Symbol)(implicit ctx: Context): Type = { + sym.info.asSeenFrom(this, sym.owner) } /** Widen from singleton type to its underlying non-singleton @@ -422,6 +439,24 @@ object Types { case _ => Nil } + final def applyToArgs(args: List[Type])(implicit ctx: Context) = { + def loop(tp: Type, tparams: List[TypeSymbol], args: List[Type]): Type = args match { + case arg :: args1 => + val tparam = tparams.head + val tp1 = RefinedType(tp, tparam.name, tp.toAlias(tparam)) + loop(tp1, tparams.tail, args1) + case nil => tp + } + if (args.isEmpty) this else loop(this, typeParams, args) + } + + final def toAlias(tparam: Symbol)(implicit ctx: Context): TypeBounds = { + val flags = tparam.flags + if (flags is Covariant) TypeBounds(defn.NothingType, this) + else if (flags is Contravariant) TypeBounds(this, defn.AnyType) + else TypeBounds(this, this) + } + final def isWrong: Boolean = !exists // !!! needed? final def exists: Boolean = true @@ -623,7 +658,7 @@ object Types { } } - final class TermRefBySym(prefix: Type, val fixedSym: TermSymbol)(initctx: Context) + final class TermRefBySym(prefix: Type, val fixedSym: TermSymbol)(implicit initctx: Context) extends TermRef(prefix, fixedSym.name(initctx)) with HasFixedSym { } @@ -633,7 +668,7 @@ object Types { super.loadDenot.atSignature(signature) } - final class TypeRefBySym(prefix: Type, val fixedSym: TypeSymbol)(initctx: Context) + final class TypeRefBySym(prefix: Type, val fixedSym: TypeSymbol)(implicit initctx: Context) extends TypeRef(prefix, fixedSym.name(initctx)) with HasFixedSym { } @@ -729,6 +764,9 @@ object Types { def apply(parent: Type, name: Name, infof: RefinedType => Type)(implicit ctx: Context): RefinedType = unique(new CachedRefinedType(parent, name, infof)) + + def apply(parent: Type, name: Name, info: Type)(implicit ctx: Context): RefinedType = + apply(parent, name, Function const info: (RefinedType => Type)) } // --- AndType/OrType --------------------------------------------------------------- @@ -822,16 +860,29 @@ object Types { override def isImplicit = true } - object MethodType { + abstract class GenericMethodType { + def apply(paramNames: List[TermName], paramTypes: List[Type])(resultTypeExp: MethodType => Type)(implicit ctx: Context): MethodType + def fromSymbols(params: List[Symbol], resultType: Type)(implicit ctx: Context) = { + def transResult(mt: MethodType) = + resultType.subst(params, (0 until params.length).toList map (MethodParam(mt, _))) + apply(params map (_.name.asTermName), params map (_.info))(transResult _) + } + } + + object MethodType extends GenericMethodType { def apply(paramNames: List[TermName], paramTypes: List[Type])(resultTypeExp: MethodType => Type)(implicit ctx: Context) = unique(new CachedMethodType(paramNames, paramTypes)(resultTypeExp)) } - def JavaMethodType(paramNames: List[TermName], paramTypes: List[Type])(resultTypeExp: MethodType => Type)(implicit ctx: Context) = - unique(new JavaMethodType(paramNames, paramTypes)(resultTypeExp)) + object JavaMethodType extends GenericMethodType { + def apply(paramNames: List[TermName], paramTypes: List[Type])(resultTypeExp: MethodType => Type)(implicit ctx: Context) = + unique(new JavaMethodType(paramNames, paramTypes)(resultTypeExp)) + } - def ImplicitMethodType(paramNames: List[TermName], paramTypes: List[Type])(resultTypeExp: MethodType => Type)(implicit ctx: Context) = - unique(new ImplicitMethodType(paramNames, paramTypes)(resultTypeExp)) + object ImplicitMethodType extends GenericMethodType { + def apply(paramNames: List[TermName], paramTypes: List[Type])(resultTypeExp: MethodType => Type)(implicit ctx: Context) = + unique(new ImplicitMethodType(paramNames, paramTypes)(resultTypeExp)) + } abstract case class ExprType(resultType: Type) extends CachedProxyType { override def underlying(implicit ctx: Context): Type = resultType @@ -874,6 +925,16 @@ object Types { } } + object PolyType { + def fromSymbols(tparams: List[Symbol], resultType: Type)(implicit ctx: Context) = { + def transform(pt: PolyType, tp: Type) = + tp.subst(tparams, (0 until tparams.length).toList map (PolyParam(pt, _))) + apply(tparams map (_.name.asTypeName))( + pt => tparams map (tparam => transform(pt, tparam.info).bounds), + pt => transform(pt, resultType)) + } + } + abstract class BoundType extends UncachedProxyType { type BT <: BindingType def binder: BT @@ -957,6 +1018,14 @@ object Types { unique(new CachedTypeBounds(lo, hi)) } + object TypeAlias { + def apply(tp: Type)(implicit ctx: Context) = TypeBounds(tp, tp) + def unapply(tp: Type): Option[Type] = tp match { + case TypeBounds(lo, hi) if lo eq hi => Some(lo) + case _ => None + } + } + // ----- AnnotatedTypes ----------------------------------------------------------- case class AnnotatedType(annots: List[Annotation], tpe: Type) extends UncachedProxyType { |