summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2011-11-11 01:35:40 +0000
committerPaul Phillips <paulp@improving.org>2011-11-11 01:35:40 +0000
commit042fdbc42a632e4b3b8510ff7638295e7aa3e981 (patch)
treef5aeabfe4e3fcdc729c3879ffdb0163e6a1e16b7 /src/compiler
parent7f4fa0ec6f303c4ec535865a6cc5f117df221980 (diff)
downloadscala-042fdbc42a632e4b3b8510ff7638295e7aa3e981.tar.gz
scala-042fdbc42a632e4b3b8510ff7638295e7aa3e981.tar.bz2
scala-042fdbc42a632e4b3b8510ff7638295e7aa3e981.zip
Cleanup around typeref creation and rebinding.
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/reflect/internal/Symbols.scala13
-rw-r--r--src/compiler/scala/reflect/internal/Types.scala85
2 files changed, 39 insertions, 59 deletions
diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala
index fc3fea0fd4..a49a5ebd1e 100644
--- a/src/compiler/scala/reflect/internal/Symbols.scala
+++ b/src/compiler/scala/reflect/internal/Symbols.scala
@@ -338,6 +338,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
final def isModuleClass = isClass && hasFlag(MODULE)
final def isNumericValueClass = definitions.isNumericValueClass(this)
final def isOverloaded = hasFlag(OVERLOADED)
+ final def isOverridableMember = !(isClass || isEffectivelyFinal) && owner.isClass
final def isRefinementClass = isClass && name == tpnme.REFINE_CLASS_NAME
final def isSourceMethod = isMethod && !hasFlag(STABLE) // exclude all accessors!!!
final def isTypeParameter = isType && isParameter && !isSkolem
@@ -362,9 +363,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
*/
def isEffectiveRoot = isRoot || isEmptyPackageClass
- final def isPossibleInRefinement = !isConstructor && !isOverridingSymbol
- final def isStructuralRefinementMember = owner.isStructuralRefinement && isPossibleInRefinement && isPublic
-
/** Term symbols with the exception of static parts of Java classes and packages.
*/
final def isValue = isTerm && !(isModule && hasFlag(PACKAGE | JAVA))
@@ -402,9 +400,9 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
// class C extends D( { class E { ... } ... } ). Here, E is a class local to a constructor
final def isClassLocalToConstructor = isClass && hasFlag(INCONSTRUCTOR)
- final def isAnonymousClass = isClass && (name containsName tpnme.ANON_CLASS_NAME)
- final def isAnonymousFunction = isSynthetic && (name containsName tpnme.ANON_FUN_NAME)
- final def isAnonOrRefinementClass = isAnonymousClass || isRefinementClass
+ final def isAnonymousClass = isClass && (name containsName tpnme.ANON_CLASS_NAME)
+ final def isAnonymousFunction = isSynthetic && (name containsName tpnme.ANON_FUN_NAME)
+ final def isAnonOrRefinementClass = isAnonymousClass || isRefinementClass
// A package object or its module class
final def isPackageObjectOrClass = name == nme.PACKAGE || name == tpnme.PACKAGE
@@ -595,6 +593,9 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
final def isStructuralRefinement: Boolean =
(isClass || isType || isModule) && info.normalize/*.underlying*/.isStructuralRefinement
+ final def isStructuralRefinementMember = owner.isStructuralRefinement && isPossibleInRefinement && isPublic
+ final def isPossibleInRefinement = !isConstructor && !isOverridingSymbol
+
/** Is this symbol a member of class `clazz`? */
def isMemberOf(clazz: Symbol) =
clazz.info.member(name).alternatives contains this
diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala
index 6fef545602..46b95e6b8c 100644
--- a/src/compiler/scala/reflect/internal/Types.scala
+++ b/src/compiler/scala/reflect/internal/Types.scala
@@ -2811,16 +2811,8 @@ A type's typeSymbol should never be inspected directly.
/** Rebind symbol `sym` to an overriding member in type `pre`. */
private def rebind(pre: Type, sym: Symbol): Symbol = {
- val owner = sym.owner
- if (owner.isClass && owner != pre.typeSymbol && !sym.isEffectivelyFinal && !sym.isClass) {
- //Console.println("rebind "+pre+" "+sym)//DEBUG
- val rebind = pre.nonPrivateMember(sym.name).suchThat(sym => sym.isType || sym.isStable)
- if (rebind == NoSymbol) sym
- else {
- // Console.println("rebound "+pre+" "+sym+" to "+rebind)//DEBUG
- rebind
- }
- } else sym
+ if (!sym.isOverridableMember || sym.owner == pre.typeSymbol) sym
+ else pre.nonPrivateMember(sym.name).suchThat(sym => sym.isType || sym.isStable) orElse sym
}
/** Convert a `super` prefix to a this-type if `sym` is abstract or final. */
@@ -2886,57 +2878,44 @@ A type's typeSymbol should never be inspected directly.
* todo: see how we can clean this up a bit
*/
def typeRef(pre: Type, sym: Symbol, args: List[Type]): Type = {
- // type alias selections are rebound in TypeMap ("coevolved", actually -- see #3731)
- // e.g., when type parameters that are referenced by the alias are instantiated in
- // the prefix. See pos/depmet_rebind_typealias.
- def rebindTR(pre: Type, sym: Symbol) =
- if (sym.isAbstractType) rebind(pre, sym) else sym
-
- val sym1 = rebindTR(pre, sym)
+ // type alias selections are rebound in TypeMap ("coevolved",
+ // actually -- see #3731) e.g., when type parameters that are
+ // referenced by the alias are instantiated in the prefix. See
+ // pos/depmet_rebind_typealias.
+ val sym1 = if (sym.isAbstractType) rebind(pre, sym) else sym
+ // don't expand cyclical type alias
// we require that object is initialized, thus info.typeParams instead of typeParams.
- if (sym1.isAliasType && sameLength(sym1.info.typeParams, args)) {
- if (sym1.lockOK) TypeRef(pre, sym1, args) // don't expand type alias (cycles checked by lockOK)
- else throw new TypeError("illegal cyclic reference involving " + sym1)
- }
- else {
- val pre1 = removeSuper(pre, sym1)
- if (pre1 ne pre)
- typeRef(pre1, rebindTR(pre1, sym1), args)
- else pre match {
- case _: CompoundType if sym1.isClass =>
- // sharpen prefix so that it is maximal and still contains the class.
- pre.parents.reverse dropWhile (_.member(sym1.name) != sym1) match {
- case Nil => TypeRef(pre, sym1, args)
- case parent :: _ => typeRef(parent, sym1, args)
- }
- case _ =>
- TypeRef(pre, sym1, args)
- }
+ if (sym1.isAliasType && sameLength(sym1.info.typeParams, args) && !sym1.lockOK)
+ throw new TypeError("illegal cyclic reference involving " + sym1)
+
+ val pre1 = pre match {
+ case x: SuperType if sym1.isEffectivelyFinal || sym1.isDeferred =>
+ x.thistpe
+ case _: CompoundType if sym1.isClass =>
+ // sharpen prefix so that it is maximal and still contains the class.
+ pre.parents.reverse dropWhile (_.member(sym1.name) != sym1) match {
+ case Nil => pre
+ case parent :: _ => parent
+ }
+ case _ => pre
}
+ if (pre eq pre1) TypeRef(pre, sym1, args)
+ else if (sym1.isAbstractType && !sym1.isClass) typeRef(pre1, rebind(pre1, sym1), args)
+ else typeRef(pre1, sym1, args)
}
+ // Optimization to avoid creating unnecessary new typerefs.
def copyTypeRef(tp: Type, pre: Type, sym: Symbol, args: List[Type]): Type = tp match {
- case TypeRef(pre0, sym0, args0) =>
- if ((pre == pre0) && (sym.name == sym0.name)) {
-
- val sym1 = sym
- // we require that object is initialized, thus info.typeParams instead of typeParams.
- if (sym1.isAliasType && sameLength(sym1.info.typeParams, args)) {
- if (sym1.lockOK) TypeRef(pre, sym1, args) // don't expand type alias (cycles checked by lockOK)
- else throw new TypeError("illegal cyclic reference involving " + sym1)
- }
- else {
- TypeRef(pre, sym1, args)
- }
+ case TypeRef(pre0, sym0, _) if (pre0 eq sym0) && sym0.name == sym.name =>
+ if (sym.isAliasType && sameLength(sym.info.typeParams, args) && !sym.lockOK)
+ throw new TypeError("illegal cyclic reference involving " + sym)
- } else
- typeRef(pre, sym, args)
+ TypeRef(pre, sym, args)
+ case _ =>
+ typeRef(pre, sym, args)
}
-
-
-
/** The canonical creator for implicit method types */
def JavaMethodType(params: List[Symbol], resultType: Type): JavaMethodType =
new JavaMethodType(params, resultType) // don't unique this!
@@ -2944,7 +2923,7 @@ A type's typeSymbol should never be inspected directly.
/** Create a new MethodType of the same class as tp, i.e. keep JavaMethodType */
def copyMethodType(tp: Type, params: List[Symbol], restpe: Type): Type = tp match {
case _: JavaMethodType => JavaMethodType(params, restpe)
- case _ => MethodType(params, restpe)
+ case _ => MethodType(params, restpe)
}
/** A creator for intersection type where intersections of a single type are