diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/dotty/tools/dotc/core/Denotations.scala | 38 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/SymDenotations.scala | 7 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Types.scala | 91 |
3 files changed, 52 insertions, 84 deletions
diff --git a/src/dotty/tools/dotc/core/Denotations.scala b/src/dotty/tools/dotc/core/Denotations.scala index dda9e11c9..d7a559d53 100644 --- a/src/dotty/tools/dotc/core/Denotations.scala +++ b/src/dotty/tools/dotc/core/Denotations.scala @@ -474,12 +474,13 @@ object Denotations { signature == sig def filterDisjoint(denots: PreDenotation)(implicit ctx: Context): PreDenotation = if (denots.containsSig(signature)) NoDenotation else this - def filterExcluded(flags: FlagSet)(implicit ctx: Context): PreDenotation = - if (symbol is flags) NoDenotation else this - def filterAccessibleFrom(pre: Type)(implicit ctx: Context): PreDenotation = - if (symbol.isAccessibleFrom(pre)) this else NoDenotation - def asSeenFrom(pre: Type)(implicit ctx: Context): PreDenotation = - derivedSingleDenotation(symbol, info.asSeenFrom(pre, symbol.owner)) + def filterAsSeenFrom(pre: Type, excluded: FlagSet)(implicit ctx: Context): PreDenotation = { + val sym = symbol + if (!(sym is excluded) && sym.isAccessibleFrom(pre)) + derivedSingleDenotation(symbol, info.asSeenFrom(pre, symbol.owner)) + else + NoDenotation + } } class UniqueRefDenotation( @@ -529,21 +530,12 @@ object Denotations { def filterDisjoint(denots: PreDenotation)(implicit ctx: Context): PreDenotation /** Keep only those denotations in this group whose flags do not intersect - * with given `flags`. - */ - def filterExcluded(flags: FlagSet)(implicit ctx: Context): PreDenotation - - /** Keep only those denotations in this group which are accessible from - * type `pre`. - */ - def filterAccessibleFrom(pre: Type)(implicit ctx: Context): PreDenotation - - /** The denotations as seen from given prefix type `pre`. - * @pre All denotations need to have an existing symbol. + * with given `excluded` and that are accessible from prefix `pre`. + * Rewrite the infos to be as seen from `pre`. */ - def asSeenFrom(pre: Type)(implicit ctx: Context): PreDenotation + def filterAsSeenFrom(pre: Type, excluded: FlagSet)(implicit ctx: Context): PreDenotation - /** The union of two groups. */ + /** The union of two groups. */ def union(that: PreDenotation) = if (!this.exists) that else if (that.exists) this @@ -559,12 +551,8 @@ object Denotations { (denots1 containsSig sig) || (denots2 containsSig sig) def filterDisjoint(denots: PreDenotation)(implicit ctx: Context): PreDenotation = derivedUnion(denots1 filterDisjoint denots, denots2 filterDisjoint denots) - def filterExcluded(flags: FlagSet)(implicit ctx: Context): PreDenotation = - derivedUnion(denots1 filterExcluded flags, denots2 filterExcluded flags) - def filterAccessibleFrom(pre: Type)(implicit ctx: Context): PreDenotation = - derivedUnion(denots1 filterAccessibleFrom pre, denots2 filterAccessibleFrom pre) - def asSeenFrom(pre: Type)(implicit ctx: Context): PreDenotation = - derivedUnion(denots1.asSeenFrom(pre), denots2.asSeenFrom(pre)) + def filterAsSeenFrom(pre: Type, excluded: FlagSet)(implicit ctx: Context): PreDenotation = + derivedUnion(denots1.filterAsSeenFrom(pre, excluded), denots2.filterAsSeenFrom(pre, excluded)) private def derivedUnion(denots1: PreDenotation, denots2: PreDenotation) = if ((denots1 eq this.denots1) && (denots2 eq this.denots2)) this else denots1 union denots2 diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala index 260cf8bb2..5f8cc1ffe 100644 --- a/src/dotty/tools/dotc/core/SymDenotations.scala +++ b/src/dotty/tools/dotc/core/SymDenotations.scala @@ -520,6 +520,10 @@ object SymDenotations { // ----- type-related ------------------------------------------------ + /** The denotation as seen from prefix type */ + def asSeenFrom(pre: Type)(implicit ctx: Context): SingleDenotation = + derivedSingleDenotation(symbol, info.asSeenFrom(pre, owner)) + /** The type parameters of a class symbol, Nil for all other symbols */ def typeParams(implicit ctx: Context): List[TypeSymbol] = Nil @@ -766,8 +770,7 @@ object SymDenotations { case parentd: ClassDenotation => denots = denots union parentd.membersNamed(name) - .filterExcluded(Flags.Private) - .asSeenFrom(thisType) + .filterAsSeenFrom(thisType, Flags.Private) .filterDisjoint(ownDenots) case _ => } diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala index 1c339540d..e6faad37c 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -164,7 +164,7 @@ object Types { * The set of refinement names in each alternative * are the set of names in refinement types encountered during the collection. */ - def DNF(implicit ctx: Context): Set[(Set[TypeRef], Set[Name])] = this match { + final def DNF(implicit ctx: Context): Set[(Set[TypeRef], Set[Name])] = this match { case tp: TypeRef => if (tp.info.isAliasTypeBounds) tp.info.bounds.hi.DNF else Set((Set(tp), Set())) @@ -199,8 +199,12 @@ object Types { final def isVolatile(implicit ctx: Context): Boolean = ctx.isVolatile(this) - /** Is this type guaranteed not to have `null` as a value? */ - final def isNotNull: Boolean = false + /** Is this type guaranteed not to have `null` as a value? + * For the moment this is only true for modules, but it could + * be refined later. + */ + final def isNotNull(implicit ctx: Context): Boolean = + widen.typeSymbol.isModuleClass /** Is this type produced as a repair for an error? */ final def isError(implicit ctx: Context): Boolean = @@ -214,6 +218,8 @@ object Types { final def exists(p: Type => Boolean): Boolean = new ExistsAccumulator(p)(false, this) + /** Returns true if all parts of this type that satisfy predicate `p`. + */ final def forall(p: Type => Boolean): Boolean = !exists(!p(_)) /** Substitute all types that refer in their symbol attribute to @@ -245,7 +251,7 @@ object Types { final def substThis(rt: RefinedType, tp: Type)(implicit ctx: Context): Type = ctx.substThis(this, rt, tp, null) - /** Substitute all occurrences symbols in `from` by references to corresponding symbols in `to` + /** Substitute all occurrences of symbols in `from` by references to corresponding symbols in `to` */ final def substSym(from: List[Symbol], to: List[Symbol])(implicit ctx: Context): Type = ctx.substSym(this, from, to, null) @@ -255,51 +261,30 @@ object Types { * Overwritten in ClassInfo, where parents is cached. */ def parents(implicit ctx: Context): List[TypeRef] = this match { - case tp: TypeProxy => - tp.underlying.parents - case _ => List() - } - - /** The elements of an AndType or OrType */ - def factors(implicit ctx: Context): List[Type] = this match { - case tp: AndType => - def components(tp: Type): List[Type] = tp match { - case AndType(tp1, tp2) => components(tp1) ++ components(tp2) - case _ => List(tp) - } - components(tp) - case tp: OrType => - def components(tp: Type): List[Type] = tp match { - case OrType(tp1, tp2) => components(tp1) ++ components(tp2) - case _ => List(tp) - } - components(tp) + case tp: TypeProxy => tp.underlying.parents case _ => List() } /** If this is an alias type, its alias, otherwise the type itself */ - def dealias(implicit ctx: Context): Type = this match { + final def dealias(implicit ctx: Context): Type = this match { case tp: TypeRef => - val info = tp.info - if (info.isAliasTypeBounds) info.dealias else this + tp.info match { + case TypeBounds(lo, hi) if lo eq hi => hi.dealias + case _ => this + } case _ => this } /** The parameter types of a PolyType or MethodType, Empty list for others */ - def paramTypess: List[List[Type]] = this match { + final def paramTypess: List[List[Type]] = this match { case mt: MethodType => mt.paramTypes :: mt.resultType.paramTypess case pt: PolyType => pt.paramTypess case _ => Nil } /** The resultType of a PolyType, MethodType, or ExprType, the type itself for others */ - def resultType: Type = this match { - case et: ExprType => et.resultType - case mt: MethodType => mt.resultType - case pt: PolyType => pt.resultType - case _ => this - } + def resultType: Type = this /** Map function over elements of an AndType, rebuilding with & */ def mapAnd(f: Type => Type)(implicit ctx: Context): Type = this match { @@ -308,7 +293,7 @@ object Types { } /** Map function over elements of an OrType, rebuilding with | */ - def mapOr(f: Type => Type)(implicit ctx: Context): Type = this match { + final def mapOr(f: Type => Type)(implicit ctx: Context): Type = this match { case OrType(tp1, tp2) => tp1.mapOr(f) | tp2.mapOr(f) case _ => f(this) } @@ -321,7 +306,7 @@ object Types { */ final def normalizedPrefix(implicit ctx: Context): Type = this match { case tp: NamedType => - if (tp.symbol.isAliasType) tp.info.normalizedPrefix else tp.prefix + if (tp.info.isAliasTypeBounds) tp.info.normalizedPrefix else tp.prefix case tp: ClassInfo => tp.prefix case tp: TypeProxy => @@ -343,39 +328,37 @@ object Types { EmptyScope } - /** The declaration of this type with given name */ + /** A denotation containing the declaration(s) in this type with the given name */ final def decl(name: Name)(implicit ctx: Context): Denotation = findDecl(name, this, EmptyFlags) - /** The non-private declaration of this type with given name */ + /** A denotation containing the non-private declaration(s) in this type with the given name */ final def nonPrivateDecl(name: Name)(implicit ctx: Context): Denotation = findDecl(name, this, Flags.Private) - /** The non-private class member declaration of this type with given name */ + /** A denotation containing the declaration(s) in this type with the given + * name, as seen from prefix type `pre`. Declarations that have a flag + * in `excluded` are omitted. + */ final def findDecl(name: Name, pre: Type, excluded: FlagSet)(implicit ctx: Context): Denotation = this match { case tp: ClassInfo => - tp.decls - .denotsNamed(name) - .filterAccessibleFrom(pre) - .filterExcluded(excluded) - .asSeenFrom(pre) - .toDenot + tp.decls.denotsNamed(name).filterAsSeenFrom(pre, excluded).toDenot case tp: TypeProxy => tp.underlying.findDecl(name, pre, excluded) } - /** The member of this type with given name */ + /** The member of this type with the given name */ final def member(name: Name)(implicit ctx: Context): Denotation = findMember(name, this, EmptyFlags) - /** The non-private member of this type with given name */ + /** The non-private member of this type with the given name. */ final def nonPrivateMember(name: Name)(implicit ctx: Context): Denotation = findMember(name, this, Flags.Private) /** Find member of this type with given name and * produce a denotation that contains the type of the member - * as seen from given prefix `pre`. Exclude all members with one - * of the flags in `excluded` from consideration. + * as seen from given prefix `pre`. Exclude all members that have + * flags in `excluded` from consideration. */ final def findMember(name: Name, pre: Type, excluded: FlagSet)(implicit ctx: Context): Denotation = this match { case tp: RefinedType => @@ -387,14 +370,8 @@ object Types { case tp: TypeProxy => tp.underlying.findMember(name, pre, excluded) case tp: ClassInfo => - val cls = tp.cls - val candidates = cls.membersNamed(name) - val results = candidates - .filterAccessibleFrom(pre) - .filterExcluded(excluded) - .asSeenFrom(pre) - if (results.exists) results.toDenot - else new ErrorDenotation // todo: refine + val candidates = tp.cls.membersNamed(name) + candidates.filterAsSeenFrom(pre, excluded).toDenot case tp: AndType => tp.tp1.findMember(name, pre, excluded) & tp.tp2.findMember(name, pre, excluded) case tp: OrType => @@ -828,7 +805,7 @@ object Types { override def loadDenot(implicit ctx: Context) = { val denot = fixedSym.denot val owner = denot.owner - if (owner.isTerm) denot else denot.asSeenFrom(prefix).toDenot + if (owner.isTerm) denot else denot.asSeenFrom(prefix) } } |