diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2016-09-19 11:51:58 +1000 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2016-09-21 12:02:07 +1000 |
commit | c0450f0c12f265674bc657cfb469778cd35d1c40 (patch) | |
tree | 78633e6a19e08cfab43628b6fb160a0bb600f3aa /src | |
parent | 6df14e57a4980897d5517f002c04584b82e05b15 (diff) | |
download | scala-c0450f0c12f265674bc657cfb469778cd35d1c40.tar.gz scala-c0450f0c12f265674bc657cfb469778cd35d1c40.tar.bz2 scala-c0450f0c12f265674bc657cfb469778cd35d1c40.zip |
SD-226 Be lazier in Fields info transform for better performance
Only mixin fields + accessors into class infos of classes that are
either in the current run, or appear in a superclass chain of a class
in the current run.
This is analagous to what happens in the mixin phase.
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/Fields.scala | 9 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/RefChecks.scala | 5 |
2 files changed, 13 insertions, 1 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/Fields.scala b/src/compiler/scala/tools/nsc/transform/Fields.scala index 894d0a1701..c39491cf9e 100644 --- a/src/compiler/scala/tools/nsc/transform/Fields.scala +++ b/src/compiler/scala/tools/nsc/transform/Fields.scala @@ -305,6 +305,10 @@ abstract class Fields extends InfoTransform with ast.TreeDSL with TypingTransfor lazyCallingSuper setInfo tp } + private def needsMixin(cls: Symbol): Boolean = { + !(cls.isPackageClass || cls.isJavaDefined) && (currentRun.compiles(cls) || refChecks.isSeparatelyCompiledScalaSuperclass(cls)) + } + def apply(tp0: Type): Type = tp0 match { // TODO: make less destructive (name changes, decl additions, flag setting -- // none of this is actually undone when travelling back in time using atPhase) @@ -360,9 +364,12 @@ abstract class Fields extends InfoTransform with ast.TreeDSL with TypingTransfor ClassInfoType(parents, allDecls, clazz) } else tp + + case tp@ClassInfoType(parents, oldDecls, clazz) if !needsMixin(clazz) => tp + // mix in fields & accessors for all mixed in traits + case tp@ClassInfoType(parents, oldDecls, clazz) => - case tp@ClassInfoType(parents, oldDecls, clazz) if !clazz.isPackageClass => val site = clazz.thisType // setter conflicts cannot arise independently from a getter conflict, since a setter without a getter does not a val definition make diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index 8034d056d7..24b4334ec4 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -95,6 +95,9 @@ abstract class RefChecks extends Transform { ) } + private val separatelyCompiledScalaSuperclass = perRunCaches.newAnyRefMap[Symbol, Unit]() + final def isSeparatelyCompiledScalaSuperclass(sym: Symbol) = separatelyCompiledScalaSuperclass.contains(sym) + class RefCheckTransformer(unit: CompilationUnit) extends Transformer { var localTyper: analyzer.Typer = typer @@ -854,6 +857,8 @@ abstract class RefChecks extends Transform { // println("validate base type "+tp) val baseClass = tp.typeSymbol if (baseClass.isClass) { + if (!baseClass.isTrait && !baseClass.isJavaDefined && !currentRun.compiles(baseClass) && !separatelyCompiledScalaSuperclass.contains(baseClass)) + separatelyCompiledScalaSuperclass.update(baseClass, ()) val index = clazz.info.baseTypeIndex(baseClass) if (index >= 0) { if (seenTypes(index) forall (tp1 => !(tp1 <:< tp))) |