aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml2
-rw-r--r--src/dotty/tools/dotc/core/DenotTransformers.scala20
-rw-r--r--src/dotty/tools/dotc/core/Types.scala13
-rw-r--r--src/dotty/tools/dotc/core/pickling/ClassfileParser.scala12
-rw-r--r--src/dotty/tools/dotc/transform/ElimByName.scala2
-rw-r--r--src/dotty/tools/dotc/transform/ElimRepeated.scala2
-rw-r--r--src/dotty/tools/dotc/transform/ExplicitOuter.scala2
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,