diff options
-rw-r--r-- | .travis.yml | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/DenotTransformers.scala | 20 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Types.scala | 13 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/pickling/ClassfileParser.scala | 12 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/ElimByName.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/ElimRepeated.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/ExplicitOuter.scala | 2 |
7 files changed, 39 insertions, 14 deletions
diff --git a/.travis.yml b/.travis.yml index 0e31b0dbe..110cae400 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,7 @@ language: scala script: - sbt -Ddotty.travis.build=yes update compile test jdk: - - oraclejdk7 + - oraclejdk8 notifications: email: - dotty-reports@googlegroups.com diff --git a/src/dotty/tools/dotc/core/DenotTransformers.scala b/src/dotty/tools/dotc/core/DenotTransformers.scala index 0e31d87e6..02d27ea33 100644 --- a/src/dotty/tools/dotc/core/DenotTransformers.scala +++ b/src/dotty/tools/dotc/core/DenotTransformers.scala @@ -38,13 +38,23 @@ object DenotTransformers { def transformInfo(tp: Type, sym: Symbol)(implicit ctx: Context): Type def transform(ref: SingleDenotation)(implicit ctx: Context): SingleDenotation = { - val info1 = transformInfo(ref.info, ref.symbol) - if (info1 eq ref.info) ref - else ref match { - case ref: SymDenotation => ref.copySymDenotation(info = info1) - case _ => ref.derivedSingleDenotation(ref.symbol, info1) + val sym = ref.symbol + if (sym.exists && !mayChange(sym)) ref + else { + val info1 = transformInfo(ref.info, ref.symbol) + if (info1 eq ref.info) ref + else ref match { + case ref: SymDenotation => ref.copySymDenotation(info = info1) + case _ => ref.derivedSingleDenotation(ref.symbol, info1) + } } } + + /** Denotations with a symbol where `mayChange` is false are guaranteed to be + * unaffected by this transform, so `transformInfo` need not be run. This + * can save time, and more importantly, can help avoid forcing symbol completers. + */ + protected def mayChange(sym: Symbol)(implicit ctx: Context): Boolean = true } /** A transformer that only transforms SymDenotations */ diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala index 5228c077e..335e72e3f 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -105,6 +105,15 @@ object Types { false } + /** Is this type a (neither aliased nor applied) reference to class `sym`? */ + def isDirectRef(sym: Symbol)(implicit ctx: Context): Boolean = stripTypeVar match { + case this1: TypeRef => + this1.name == sym.name && // avoid forcing info if names differ + (this1.symbol eq sym) + case _ => + false + } + /** Is this type an instance of a non-bottom subclass of the given class `cls`? */ final def derivesFrom(cls: Symbol)(implicit ctx: Context): Boolean = this match { case tp: TypeRef => @@ -663,10 +672,6 @@ object Types { case _ => this } - /** Map references to Object to references to Any; needed for Java interop */ - final def objToAny(implicit ctx: Context) = - if ((this isRef defn.ObjectClass) && !ctx.phase.erasedTypes) defn.AnyType else this - /** If this is a (possibly aliased, annotated, and/or parameterized) reference to * a class, the class type ref, otherwise NoType. */ diff --git a/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala b/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala index f2a5e4171..8dd9314ee 100644 --- a/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala +++ b/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala @@ -214,6 +214,10 @@ class ClassfileParser( } } + /** Map direct references to Object to references to Any */ + final def objToAny(tp: Type)(implicit ctx: Context) = + if (tp.isDirectRef(defn.ObjectClass) && !ctx.phase.erasedTypes) defn.AnyType else tp + private def sigToType(sig: TermName, owner: Symbol = null)(implicit ctx: Context): Type = { var index = 0 val end = sig.length @@ -258,12 +262,12 @@ class ClassfileParser( case variance @ ('+' | '-' | '*') => index += 1 val bounds = variance match { - case '+' => TypeBounds.upper(sig2type(tparams, skiptvs).objToAny) + case '+' => objToAny(TypeBounds.upper(sig2type(tparams, skiptvs))) case '-' => val tp = sig2type(tparams, skiptvs) // sig2type seems to return AnyClass regardless of the situation: // we don't want Any as a LOWER bound. - if (tp isRef defn.AnyClass) TypeBounds.empty + if (tp.isDirectRef(defn.AnyClass)) TypeBounds.empty else TypeBounds.lower(tp) case '*' => TypeBounds.empty } @@ -310,7 +314,7 @@ class ClassfileParser( var paramnames = new ListBuffer[TermName]() while (sig(index) != ')') { paramnames += nme.syntheticParamName(paramtypes.length) - paramtypes += sig2type(tparams, skiptvs).objToAny + paramtypes += objToAny(sig2type(tparams, skiptvs)) } index += 1 val restype = sig2type(tparams, skiptvs) @@ -328,7 +332,7 @@ class ClassfileParser( while (sig(index) == ':') { index += 1 if (sig(index) != ':') // guard against empty class bound - ts += sig2type(tparams, skiptvs).objToAny + ts += objToAny(sig2type(tparams, skiptvs)) } TypeBounds.upper(((NoType: Type) /: ts)(_ & _) orElse defn.AnyType) } diff --git a/src/dotty/tools/dotc/transform/ElimByName.scala b/src/dotty/tools/dotc/transform/ElimByName.scala index 40fd48327..7adee3a8a 100644 --- a/src/dotty/tools/dotc/transform/ElimByName.scala +++ b/src/dotty/tools/dotc/transform/ElimByName.scala @@ -116,4 +116,6 @@ class ElimByName extends MiniPhaseTransform with InfoTransformer { thisTransform case ExprType(rt) if exprBecomesFunction(sym) => defn.FunctionType(Nil, rt) case _ => tp } + + override def mayChange(sym: Symbol)(implicit ctx: Context): Boolean = sym.isTerm } diff --git a/src/dotty/tools/dotc/transform/ElimRepeated.scala b/src/dotty/tools/dotc/transform/ElimRepeated.scala index eb44c3e2c..03fd28a26 100644 --- a/src/dotty/tools/dotc/transform/ElimRepeated.scala +++ b/src/dotty/tools/dotc/transform/ElimRepeated.scala @@ -28,6 +28,8 @@ class ElimRepeated extends MiniPhaseTransform with InfoTransformer { thisTransfo def transformInfo(tp: Type, sym: Symbol)(implicit ctx: Context): Type = elimRepeated(tp) + override def mayChange(sym: Symbol)(implicit ctx: Context): Boolean = sym is Method + private def elimRepeated(tp: Type)(implicit ctx: Context): Type = tp.stripTypeVar match { case tp @ MethodType(paramNames, paramTypes) => val resultType1 = elimRepeated(tp.resultType) diff --git a/src/dotty/tools/dotc/transform/ExplicitOuter.scala b/src/dotty/tools/dotc/transform/ExplicitOuter.scala index 436d9bcf7..0810f7d9c 100644 --- a/src/dotty/tools/dotc/transform/ExplicitOuter.scala +++ b/src/dotty/tools/dotc/transform/ExplicitOuter.scala @@ -55,6 +55,8 @@ class ExplicitOuter extends MiniPhaseTransform with InfoTransformer { thisTransf tp } + override def mayChange(sym: Symbol)(implicit ctx: Context): Boolean = sym.isClass + /** First, add outer accessors if a class does not have them yet and it references an outer this. * If the class has outer accessors, implement them. * Furthermore, if a parent trait might have an outer accessor, |