aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2014-11-12 17:12:44 +0100
committerMartin Odersky <odersky@gmail.com>2014-11-12 17:12:44 +0100
commitc4aa3c058904912ba1b5696b2aaa4d9234dc5c79 (patch)
tree88202fd564fabaa60bc135ded32d9216e83029a7
parent7978a5f6a1be13ca9c482c3f2e9c2102018cfcf0 (diff)
downloaddotty-c4aa3c058904912ba1b5696b2aaa4d9234dc5c79.tar.gz
dotty-c4aa3c058904912ba1b5696b2aaa4d9234dc5c79.tar.bz2
dotty-c4aa3c058904912ba1b5696b2aaa4d9234dc5c79.zip
Avoid forcing infos of some symbols in InfoTransforms
Provides the "mayChange" hook to exclude symbols from being completed prior to a transformInfo.
-rw-r--r--src/dotty/tools/dotc/core/DenotTransformers.scala20
-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
4 files changed, 21 insertions, 5 deletions
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/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,