diff options
Diffstat (limited to 'src/dotty/tools')
-rw-r--r-- | src/dotty/tools/dotc/core/Annotations.scala | 1 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Definitions.scala | 1 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Denotations.scala | 118 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Flags.scala | 280 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Referenceds.scala | 7 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/SubTypers.scala | 41 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Symbols.scala | 46 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Types.scala | 53 |
8 files changed, 490 insertions, 57 deletions
diff --git a/src/dotty/tools/dotc/core/Annotations.scala b/src/dotty/tools/dotc/core/Annotations.scala index 48165f488..756430fb3 100644 --- a/src/dotty/tools/dotc/core/Annotations.scala +++ b/src/dotty/tools/dotc/core/Annotations.scala @@ -2,6 +2,7 @@ package dotty.tools.dotc.core object Annotations { + abstract class Annotation abstract class AnnotationInfo }
\ No newline at end of file diff --git a/src/dotty/tools/dotc/core/Definitions.scala b/src/dotty/tools/dotc/core/Definitions.scala index 8e76282a3..40f12a1b6 100644 --- a/src/dotty/tools/dotc/core/Definitions.scala +++ b/src/dotty/tools/dotc/core/Definitions.scala @@ -18,6 +18,7 @@ class Definitions(implicit ctx: Context) { lazy val SingletonClass: ClassSymbol = ??? lazy val SingletonType = SingletonClass.typeConstructor lazy val ArrayClass: ClassSymbol = ??? + lazy val uncheckedStableClass: ClassSymbol = ??? def init() = if (!isInitialized) { diff --git a/src/dotty/tools/dotc/core/Denotations.scala b/src/dotty/tools/dotc/core/Denotations.scala index bbbbaa74b..72a55944d 100644 --- a/src/dotty/tools/dotc/core/Denotations.scala +++ b/src/dotty/tools/dotc/core/Denotations.scala @@ -14,20 +14,23 @@ object Denotations { */ abstract class Denotation(initFlags: FlagSet) extends SymRefd { - def symbol: Symbol - def owner: Symbol def name: Name + def symbol: Symbol + private[this] var currentFlags: FlagSet = initFlags def flags: FlagSet = currentFlags def info: Type - def setFlag(flag: FlagSet): Unit = - currentFlags = initFlags + def setFlags(flags: FlagSet): Unit = + currentFlags |= flags + + def resetFlags(flags: FlagSet): Unit = + currentFlags &~= flags /** is this symbol a class? */ def isClass: Boolean = false @@ -43,25 +46,50 @@ object Denotations { override protected def copy(s: Symbol, i: Type): SymRefd = new UniqueSymRefd(s, i, validFor) } - class NonClassDenotation( - override val symbol: Symbol, - override val owner: Symbol, - override val name: Name, - val initFlags: FlagSet, - override val info: Type + class CompleteDenotation( + val symbol: Symbol, + val owner: Symbol, + val name: Name, + initFlags: FlagSet, + val info: Type ) extends Denotation(initFlags) - class ClassDenotation( - override val symbol: ClassSymbol, - override val owner: Symbol, - override val name: Name, - val initFlags: FlagSet, - val parents: List[Type], - val decls: Scope)(implicit ctx: Context) extends Denotation(initFlags) { + abstract class LazyDenotation( + val symbol: Symbol, + val owner: Symbol, + val name: Name, + initFlags: FlagSet + ) extends Denotation(initFlags) { + + private var currentInfo: Type = null + + override def flags = { + val fs = super.flags + if (fs is Unloaded) { load(); super.flags } + else fs + } + + override def info = { + if (currentInfo == null) complete() + currentInfo + } + + def load(): Unit + def complete(): Unit + } + + abstract class ClassDenotation(initFlags: FlagSet)(implicit ctx: Context) + extends Denotation(initFlags) { import NameFilter._ import util.LRU8Cache - def typeParams: List[TypeSymbol] = ??? + val symbol: ClassSymbol + + def typeParams: List[TypeSymbol] + + def parents: List[Type] + + def decls: Scope val info = ClassInfo(owner.thisType, this) @@ -157,7 +185,7 @@ object Denotations { parent.deref match { case classd: ClassDenotation => includeFingerPrint(bits, classd.definedFingerPrint) - parent.deref setFlag Frozen + parent.deref setFlags Frozen case _ => } ps = ps.tail @@ -171,7 +199,7 @@ object Denotations { * someone does a findMember on a subclass. */ def enter(sym: Symbol)(implicit ctx: Context) = { - require(!(flags intersects Frozen)) + require(!(this is Frozen)) decls enter sym if (definedFingerPrintCache != null) includeName(definedFingerPrintCache, sym.name) @@ -184,7 +212,7 @@ object Denotations { * someone does a findMember on a subclass. */ def delete(sym: Symbol)(implicit ctx: Context) = { - require(!(flags intersects Frozen)) + require(!(this is Frozen)) decls unlink sym if (definedFingerPrintCache != null) computeDefinedFingerPrint @@ -284,6 +312,51 @@ object Denotations { } } + class CompleteClassDenotation( + val symbol: ClassSymbol, + val owner: Symbol, + val name: Name, + initFlags: FlagSet, + val typeParams: List[TypeSymbol], + val parents: List[Type], + val decls: Scope + )(implicit ctx: Context) extends ClassDenotation(initFlags) + + abstract class LazyClassDenotation( + val symbol: ClassSymbol, + val owner: Symbol, + val name: Name, + initFlags: FlagSet + )(implicit ctx: Context) extends ClassDenotation(initFlags) { + + protected var _typeParams: List[TypeSymbol] = null + protected var _parents: List[Type] = null + protected var _decls: Scope = null + + override def flags = { + val fs = super.flags + if (fs is Unloaded) { load(); flags } else fs + } + + def typeParams: List[TypeSymbol] = { + val tparams = _typeParams + if (tparams == null) { load(); typeParams } else tparams + } + + def parents: List[Type] = { + val ps = _parents + if (ps == null) { complete(); parents } else ps + } + + def decls: Scope = { + val ds = _decls + if (ds == null) { complete(); decls } else ds + } + + def load(): Unit + def complete(): Unit + } + object NoDenotation extends Denotation(Flags.Empty) { override def symbol: Symbol = NoSymbol override def owner: Symbol = throw new AssertionError("NoDenotation.owner") @@ -314,4 +387,7 @@ object Denotations { def newNameFilter: FingerPrint = new Array[Long](DefinedNamesWords) } + + implicit def toFlagSet(denot: Denotation): FlagSet = denot.flags + }
\ No newline at end of file diff --git a/src/dotty/tools/dotc/core/Flags.scala b/src/dotty/tools/dotc/core/Flags.scala index f4a111632..1b1f2c618 100644 --- a/src/dotty/tools/dotc/core/Flags.scala +++ b/src/dotty/tools/dotc/core/Flags.scala @@ -12,7 +12,9 @@ object Flags { */ case class FlagSet(val bits: Long) extends AnyVal { - def | (that: FlagSet) = + /** The union of this flag set and the given flag set + */ + def | (that: FlagSet): FlagSet = if (bits == 0) that else if (that.bits == 0) this else { @@ -21,28 +23,55 @@ object Flags { FlagSet(tbits | ((this.bits | that.bits) & ~TYPEFLAGS)) } + /** The union of this flag set and the given flag conjunction seen as + * a flag set. + */ + def | (that: FlagConjunction): FlagSet = this | FlagSet(that.bits) + + /** The intersection of this flag set and the given flag set */ def & (that: FlagSet) = FlagSet(bits & that.bits) - def intersects(flags: FlagSet) = { + /** The intersection of this flag set with the complement of the given flag set */ + def &~ (that: FlagSet) = { + val tbits = bits & that.bits & TYPEFLAGS + assert(tbits != 0, s"illegal flagset combination: $this and $that") + FlagSet(tbits | ((this.bits & ~that.bits) & ~TYPEFLAGS)) + } + + /** Does this flag set have a non-empty intersection with the given flag set? + * Pre: The intersection of the typeflags of both sets must be non-empty. + */ + def is(flags: FlagSet) = { val fs = bits & flags.bits (fs & TYPEFLAGS) != 0 && fs > TYPEFLAGS } - def intersects(flags: FlagSet, butNot: FlagSet) = { + /** Does this flag set have a non-empty intersection with the given flag set, + * and at the same time contain none of the flags in the `butNot` set? + * Pre: The intersection of the typeflags of both sets must be non-empty. + */ + def is(flags: FlagSet, butNot: FlagSet) = { val fs = bits & flags.bits (fs & TYPEFLAGS) != 0 && fs > TYPEFLAGS && (bits & butNot.bits) == 0 } - def contains(flags: FlagSet) = { + /** Does this flag set have all of the flags in given flag conjunction? + * Pre: The intersection of the typeflags of both sets must be non-empty. + */ + def is(flags: FlagConjunction) = { val fs = bits & flags.bits (fs & TYPEFLAGS) != 0 && (fs >> TYPESHIFT) == (flags.bits >> TYPESHIFT) } - def contains(flags: FlagSet, butNot: FlagSet) = { + /** Does this flag set have all of the flags in given flag conjunction? + * and at the same time contain none of the flags in the `butNot` set? + * Pre: The intersection of the typeflags of both sets must be non-empty. + */ + def is(flags: FlagConjunction, butNot: FlagSet) = { val fs = bits & (flags.bits | butNot.bits) (fs & TYPEFLAGS) != 0 && (fs >> TYPESHIFT) == (flags.bits >> TYPESHIFT) @@ -54,48 +83,253 @@ object Flags { private def flagString(idx: Int): Set[String] = kindIndices.map(flagName(idx)).filterNot(_.isEmpty) + /** The string representation of this flag set */ override def toString = (2 to MaxFlag).flatMap(flagString).mkString(" ") } - final val TYPEFLAGS = 3L - final val TYPESHIFT = 2 - final val TERMindex = 0 - final val TYPEindex = 1 - final val TERMS = 1 << TERMindex - final val TYPES = 1 << TYPEindex + /** A class representing flag sets that should be tested + * conjunctively. I.e. for a flag conjunction `fc`, + * `x is fc` tests whether `x` contains all flags in `fc`. + */ + case class FlagConjunction(bits: Long) + + private final val TYPEFLAGS = 3L + private final val TYPESHIFT = 2 + private final val TERMindex = 0 + private final val TYPEindex = 1 + private final val TERMS = 1 << TERMindex + private final val TYPES = 1 << TYPEindex - final val MaxFlag = 63 + private final val MaxFlag = 63 private var flagName = Array.fill(64, 2)("") private val kindIndices = Set(TERMindex, TYPEindex) - /** The flag with given index between 2 and 63 which applies to terms */ + /** The flag with given index between 2 and 63 which applies to terms. + * Installs given name as the name of the flag. */ def termFlag(index: Int, name: String): FlagSet = { flagName(index)(TERMindex) = name - FlagSet(TERMS | (1L << index)) + termFlag(index) } - /** The flag with given index between 2 and 63 which applies to types */ + /** The flag with given index between 2 and 63 which applies to terms. */ + def termFlag(index: Int) = FlagSet(TERMS | (1L << index)) + + /** The flag with given index between 2 and 63 which applies to types. + * Installs given name as the name of the flag. */ def typeFlag(index: Int, name: String): FlagSet = { flagName(index)(TYPEindex) = name - FlagSet(TYPES | (1L << index)) + typeFlag(index) } + /** The flag with given index between 2 and 63 which applies to terms. */ + def typeFlag(index: Int) = FlagSet(TYPES | (1L << index)) + /** The flag with given index between 2 and 63 which applies to both terms and types */ def commonFlag(index: Int, name: String): FlagSet = - termFlag(index, name) | typeFlag(index, name) + termFlag(index, name) | typeFlag(index) - // Available flags: + /** The conjunction of all flags in given flag set */ + def allOf(flags: FlagSet) = FlagConjunction(flags.bits) + /** The empty flag set */ final val Empty = FlagSet(0) - final val Private = commonFlag(3, "private") - final val Accessor = termFlag(4, "<accessor>") + // Available flags: + + /** Labeled with `private` modifier */ + final val Private = commonFlag(2, "private") + + /** Labeled with `protected` modifier */ + final val Protected = commonFlag(3, "protected") + + /** Labeled with `override` modifier */ + final val Override = commonFlag(4, "override") + + /** A declared, but not defined member */ + final val Deferred = commonFlag(5, "<deferred>") + + /** Labeled with `final` modifier */ + final val Final = commonFlag(6, "final") + + /** A method. !!! needed? */ + final val Method = termFlag(7, "<method>") + + /** An abstract class */ + final val Abstract = typeFlag(8, "abstract") + + /** A trait that has only abstract methods as members + * (and therefore can be represented by a Java interface + */ + final val Interface = typeFlag(9, "interface") + + /** A value or class implementing a module */ + final val Module = commonFlag(10, "module") + final val ModuleObj = termFlag(10) + final val ModuleClass = typeFlag(10) + + /** Labeled with `implicit` modifier */ + final val Implicit = termFlag(11, "implicit") + + /** Labeled with `sealed` modifier */ + final val Sealed = typeFlag(12, "sealed") + + /** A case class or its companion object */ + final val Case = commonFlag(13, "case") + final val CaseClass = typeFlag(13) + final val CaseObj = termFlag(13) + + /** A lazy val */ + final val Lazy = termFlag(14, "lazy") + + /** A mutable var */ + final val Mutable = termFlag(14, "mutable") + + /** A (term or type) parameter to a class or method */ + final val Param = commonFlag(15, "<param>") + final val TermParam = termFlag(15) + final val TypeParam = typeFlag(15) + + /** A value or class representing a package */ + final val Package = commonFlag(16, "<package>") + final val PackageObj = termFlag(16) + final val PackageClass = typeFlag(16) + + /** A by-name parameter !!! needed? */ + final val ByNameParam = termFlag(17, "<by-name>") + + /** A covariant type variable */ + final val Covariant = typeFlag(17, "<covariant>") + + /** Method is a label. */ + final val Label = termFlag(18, "<label>") + + /** Symbol is a macro */ + final val Macro = commonFlag(???, "<macro>") + + /** A contravariant type variable */ + final val Contravariant = typeFlag(18, "<contravariant>") + + /** combination of abstract & override */ + final val AbsOverride = termFlag(19, "abstract override") + + /** Symbol is local to current class (i.e. private[this] or protected[this] + * pre: Private or Protected are also set + */ + final val Local = commonFlag(20, "<local>") + + /** Symbol is defined by a Java class */ + final val Java = commonFlag(21, "<java>") + + /** A compiler-generated symbol. which is visible for type-checking + * (compare with artifact) + */ + final val Synthetic = commonFlag(22, "<synthetic>") + + /** Method is assumed to be stable */ + final val Stable = termFlag(23, "<stable>") + + final val Static = commonFlag(24, "<static>") + + /** A value or variable accessor (getter or setter) */ + final val Accessor = termFlag(25, "<accessor>") + + /** A case parameter (or its accessor, or a GADT skolem) */ + final val CaseAccessor = termFlag(26, "<caseaccessor>") + + /** A super accessor */ + final val SuperAccessor = termFlag(27, "<superaccessor>") + + /** A field generated for a primary constructor parameter (no matter if it's a 'val' or not), + * or an accessor of such a field. + */ + final val ParamAccessor = termFlag(28, "<paramaccessor>") + + /** A parameter with a default value */ + final val DefaultParam = termFlag(27, "<defaultparam>") + + /** A trait */ + final val Trait = typeFlag(27, "<trait>") + + /** A bridge method. Set by Erasure */ + final val Bridge = termFlag(28, "<bridge>") + + /** Symbol is initialized to the default value, e.g. var x: T = _ */ + final val DefaultInit = termFlag(29, "<defaultinit>") + + /** An error symbol */ + final val Erroneous = commonFlag(???, "<is-error>") + + /** Denotation has not yet been loaded */ + final val Unloaded = commonFlag(32, "??") + + /** Denotation is in train of being loaded and completed, flag to catch cyclic dependencies */ + final val Locked = commonFlag(???, "<locked>") + + /** Variable is accessed from nested function. */ + final val Captured = termFlag(???, "<captured>") - final val Error = FlagSet(1 << 32) - final val Frozen = FlagSet(???) - final val Package = FlagSet(???) + /** Class symbol is defined in this/superclass constructor. */ + final val Inconstructor = typeFlag(???, "<in-constructor>") + /** Class is not allowed to accept new members because fingerprint of subclass has been taken */ + final val Frozen = typeFlag(???, "<frozen>") + + /** Class has been lifted out to package level, local value has been lifted out to class level */ + final val Lifted = termFlag(???, "<lifted>") + + /** Term member has been mixed in */ + final val MixedIn = termFlag(???, "<mixedin>") + + /** Symbol is a generated specialized member */ + final val Specialized = commonFlag(???, "<specialized>") + + /** Symbol is a Java-style varargs method */ + final val JavaVarargs = termFlag(???, "<varargs>") + + /** Symbol is a Java varargs bridge */ + final val VBridge = termFlag(???, "<vbridge>") + + /** Symbol is a method which should be marked ACC_SYNCHRONIZED */ + final val Synchronized = termFlag(???, "<synchronized>") + + /** Symbol should be ignored when typechecking; will be marked ACC_SYNTHETIC in bytecode */ + final val Artifact = commonFlag(???, "<artifact>") + + /** Symbol is an implementation class */ + final val ImplClass = typeFlag(???, "<implclass>") + +// --------- Combined Flag Sets and Conjunctions ---------------------- + + /** Flags representing source modifiers */ + final val ModifierFlags = + Private | Protected | Abstract | Final | Sealed | + Override | Case | Implicit | AbsOverride | Lazy + + /** Flags representing access rights */ + final val AccessFlags = Private | Protected | Local + + /** These flags are not pickled */ + final val FlagsNotPickled = + Erroneous | Lifted | Unloaded | Frozen + + /** These flags are pickled */ + //final val PickledFlags = InitialFlags & ~FlagsNotPickled + + + /** A value that's unstable unless complemented with a Stable flag */ + final val UnstableValue = Mutable | Method | ByNameParam + + /** Labeled private[this] */ + final val PrivateLocal = allOf(Private | Local) + + /** Labeled `protected[this]` */ + final val ProtectedLocal = allOf(Protected | Local) + + /** Labeled `abstract` and `override`; only used in Parser, + * symbols are labeled AbsOverride instead + */ + final val AbstractOverride = allOf(Abstract | Override) }
\ No newline at end of file diff --git a/src/dotty/tools/dotc/core/Referenceds.scala b/src/dotty/tools/dotc/core/Referenceds.scala index f0db3ff6c..7ec862be2 100644 --- a/src/dotty/tools/dotc/core/Referenceds.scala +++ b/src/dotty/tools/dotc/core/Referenceds.scala @@ -77,6 +77,12 @@ object Referenceds { /** Is this a reference to a type symbol? */ def isType: Boolean = false + /** Is this a reference to a term symbol? */ + def isTerm: Boolean = !isType + + /** Is this reference overloaded? */ + def isOverloaded = isInstanceOf[OverloadedRef] + /** The signature of the reference */ def signature: Signature @@ -328,6 +334,7 @@ object Referenceds { val info = NoType validFor = Nowhere override def exists = false + override def isTerm = false } // --------------- ReferencedSets ------------------------------------------------- diff --git a/src/dotty/tools/dotc/core/SubTypers.scala b/src/dotty/tools/dotc/core/SubTypers.scala index 602b380f4..29c7b7388 100644 --- a/src/dotty/tools/dotc/core/SubTypers.scala +++ b/src/dotty/tools/dotc/core/SubTypers.scala @@ -203,6 +203,47 @@ object SubTypers { true } + /** A function implementing `tp1` matches `tp2`. */ + final def matchesType(tp1: Type, tp2: Type, alwaysMatchSimple: Boolean): Boolean = tp1 match { + case tp1: MethodType => + tp2 match { + case tp2: MethodType => + tp1.isImplicit == tp2.isImplicit && + matchingParams(tp1.paramTypes, tp2.paramTypes, tp1.isJava, tp2.isJava) && + matchesType(tp1.resultType, tp2.resultType.subst(tp2, tp1), alwaysMatchSimple) + case tp2: ExprType => + tp1.paramNames.isEmpty && + matchesType(tp1.resultType, tp2.resultType, alwaysMatchSimple) + case _ => + false + } + case tp1: ExprType => + tp2 match { + case tp2: MethodType => + tp2.paramNames.isEmpty && + matchesType(tp1.resultType, tp2.resultType, alwaysMatchSimple) + case tp2: ExprType => + matchesType(tp1.resultType, tp2.resultType, alwaysMatchSimple) + case _ => + matchesType(tp1.resultType, tp2, alwaysMatchSimple) + } + case tp1: PolyType => + tp2 match { + case tp2: PolyType => + sameLength(tp1.paramNames, tp2.paramNames) && + matchesType(tp1.resultType, tp2.resultType.subst(tp2, tp1), alwaysMatchSimple) + case _ => + false + } + case _ => + tp2 match { + case _: MethodType | _: PolyType => + false + case _ => + alwaysMatchSimple || isSameType(tp1, tp2) + } + } + /** Are `syms1` and `syms2` parameter lists with pairwise equivalent types? */ private def matchingParams(formals1: List[Type], formals2: List[Type], isJava1: Boolean, isJava2: Boolean): Boolean = formals1 match { case Nil => diff --git a/src/dotty/tools/dotc/core/Symbols.scala b/src/dotty/tools/dotc/core/Symbols.scala index 331c168a8..bd3ab18f9 100644 --- a/src/dotty/tools/dotc/core/Symbols.scala +++ b/src/dotty/tools/dotc/core/Symbols.scala @@ -10,30 +10,46 @@ import Decorators._ import Symbols._ import Contexts._ import Denotations._ -import Types._ +import Types._, Annotations._ import Referenceds.{Referenced, SymRefd, OverloadedRef} import collection.mutable object Symbols { - /** - * A SymRef is a period-dependent reference to a denotation. - * Given a period, its `deref` method resolves to a Symbol. + /** A Symbol represents a Scala definition/declaration or a package. */ abstract class Symbol { - def overriddenSymbol(inclass: ClassSymbol)(implicit ctx: Context): Symbol = - if (owner isSubClass inclass) ??? + /** The non-private symbol whose type matches the type of this symbol + * in in given class. + * + * @param ofClass The class containing the symbol's definition + * @param site The base type from which member types are computed + */ + final def matchingSymbol(inClass: Symbol, site: Type)(implicit ctx: Context): Symbol = { + var ref = inClass.info.nonPrivateDecl(name) + if (ref.isTerm) { + val targetType = site.memberInfo(this) + if (ref.isOverloaded) ref = ref.atSignature(targetType.signature) + val candidate = ref.symbol + if (site.memberInfo(candidate) matches targetType) candidate + else NoSymbol + } else ref.symbol + } + + def overriddenSymbol(inClass: ClassSymbol)(implicit ctx: Context): Symbol = + if (owner isSubClass inClass) matchingSymbol(inClass, owner.thisType) else NoSymbol def isProtected: Boolean = ??? - def isStable: Boolean = ??? + def isStable(implicit ctx: Context): Boolean = false def accessBoundary: ClassSymbol = ??? def isContainedIn(boundary: ClassSymbol) = ??? def baseClasses: List[ClassSymbol] = ??? def exists = true - + def hasAnnotation(ann: Annotation): Boolean = ??? + def hasAnnotation(ann: ClassSymbol): Boolean = ??? def orElse(that: => Symbol) = if (exists) this else that @@ -50,11 +66,10 @@ object Symbols { (this isAsAccessible that) def isAsAccessible(that: Symbol)(implicit ctx: Context): Boolean = - !this.isProtected && !that.isProtected && // protected members are incomparable + !(this is Protected) && !(that is Protected) && // protected members are incomparable (that.accessBoundary isContainedIn this.accessBoundary) && this.isStable || !that.isStable - /** Set the denotation of this symbol. */ def setDenotation(denot: Denotation) = @@ -161,8 +176,15 @@ object Symbols { abstract class TermSymbol extends Symbol { def name: TermName def isType = true + + override def isStable(implicit ctx: Context) = !( + this.is(UnstableValue, butNot = Stable) || + info.isVolatile && !hasAnnotation(defn.uncheckedStableClass) + ) } + final val MutableMethodByNameParam = Mutable | Method | ByNameParam + trait RefinementSymbol extends Symbol { override def deref(implicit ctx: Context) = lastDenot } @@ -220,7 +242,11 @@ object Symbols { def loadDenot(implicit ctx: Context): Denotation = NoDenotation override def exists = false def isType = false + override def isTerm = false } implicit def defn(implicit ctx: Context): Definitions = ctx.root.definitions + + implicit def toFlagSet(sym: Symbol)(implicit ctx: Context): FlagSet = sym.flags + }
\ No newline at end of file diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala index be627faf4..d48526fdb 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -157,7 +157,8 @@ object Types { final def isNotNull: Boolean = false /** Is this type produced as a repair for an error? */ - final def isError(implicit ctx: Context): Boolean = (typeSymbol hasFlag Error) || (termSymbol hasFlag Error) + final def isError(implicit ctx: Context): Boolean = + (typeSymbol is Erroneous) || (termSymbol is Erroneous) /** Is some part of this type produced as a repair for an error? */ final def isErroneous(implicit ctx: Context): Boolean = exists(_.isError) @@ -256,7 +257,26 @@ object Types { /** The declaration of this type with given name */ final def decl(name: Name)(implicit ctx: Context): Referenced = - decls.refsNamed(name).toRef + findDecl(name, this, Flags.Empty) + + /** The non-private declaration of this type with given name */ + final def nonPrivateDecl(name: Name)(implicit ctx: Context): Referenced = + findDecl(name, this, Flags.Private) + + /** The non-private declaration of this type with given name */ + final def findDecl(name: Name, pre: Type, excluded: FlagSet)(implicit ctx: Context): Referenced = this match { + case tp: RefinedType => + tp.findDecl(name, pre) + case tp: ClassInfo => + tp.classd.decls + .refsNamed(name) + .filterAccessibleFrom(pre) + .filterExcluded(excluded) + .asSeenFrom(pre, tp.classd.symbol) + .toRef + case tp: TypeProxy => + tp.underlying.findDecl(name, pre, excluded) + } /** The member of this type with given name */ final def member(name: Name)(implicit ctx: Context): Referenced = @@ -302,6 +322,30 @@ object Types { final def =:=(that: Type)(implicit ctx: Context): Boolean = ctx.subTyper.isSameType(this, that) + /** Is this type close enough to that type so that members + * with the two type would override each other? + * This means: + * - Either both types are polytypes with the same number of + * type parameters and their result types match after renaming + * corresponding type parameters + * - Or both types are (possibly nullary) method types with equivalent type parameter types + * and matching result types + * - Or both types are equivalent + * - Or phase.erasedTypes is false and both types are neither method nor + * poly types. + */ + def matches(that: Type)(implicit ctx: Context): Boolean = + ctx.subTyper.matchesType(this, that, !ctx.phase.erasedTypes) + + /** Does this type match that type + * + */ + + /** The info of `sym`, seen as a member of this type. */ + final def memberInfo(sym: Symbol)(implicit ctx: Context): Type = { + sym.info.asSeenFrom(this, sym.owner) + } + /** Widen from singleton type to its underlying non-singleton * base type by applying one or more `underlying` dereferences, * identity for all other types. Example: @@ -338,7 +382,9 @@ object Types { } final def asSeenFrom(pre: Type, clazz: Symbol)(implicit ctx: Context): Type = - if (clazz.isStaticMono || ctx.erasedTypes && clazz != defn.ArrayClass) this + if (clazz.isStaticMono || + ctx.erasedTypes && clazz != defn.ArrayClass || + (pre eq clazz.thisType)) this else ctx.asSeenFrom(this, pre, clazz, null) /** The signature of this type. This is by default NullSignature, @@ -803,6 +849,7 @@ object Types { abstract case class ExprType(resultType: Type) extends CachedProxyType { override def underlying(implicit ctx: Context): Type = resultType + override def signature: Signature = Nil def derivedExprType(rt: Type)(implicit ctx: Context) = if (rt eq resultType) this else ExprType(rt) override def computeHash = doHash(resultType) |