From 729adc58ca13254782d4ce686b08dc192c7d04c6 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Tue, 18 Dec 2018 17:22:12 +0100 Subject: [PATCH 1/2] Memoize sourceFile creation --- compiler/src/dotty/tools/dotc/Run.scala | 8 ++++---- compiler/src/dotty/tools/dotc/ast/tpd.scala | 3 +-- compiler/src/dotty/tools/dotc/core/Contexts.scala | 10 ++++++++++ .../src/dotty/tools/dotc/interactive/SourceTree.scala | 2 +- 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/Run.scala b/compiler/src/dotty/tools/dotc/Run.scala index e295e68548c5..9067693e1168 100644 --- a/compiler/src/dotty/tools/dotc/Run.scala +++ b/compiler/src/dotty/tools/dotc/Run.scala @@ -104,10 +104,10 @@ class Run(comp: Compiler, ictx: Context) extends ImplicitRunInfo with Constraint if (f.isDirectory) { ctx.error(s"expected file, received directory '$fileName'") NoSource - } else if (f.exists) { - val encoding = ctx.settings.encoding.value - new SourceFile(f, Codec(encoding)) - } else { + } + else if (f.exists) + ctx.getSource(f) + else { ctx.error(s"not found: $fileName") NoSource } diff --git a/compiler/src/dotty/tools/dotc/ast/tpd.scala b/compiler/src/dotty/tools/dotc/ast/tpd.scala index 052cd26b96ec..3fce069dd475 100644 --- a/compiler/src/dotty/tools/dotc/ast/tpd.scala +++ b/compiler/src/dotty/tools/dotc/ast/tpd.scala @@ -1136,8 +1136,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo { */ def sourceFile(call: Tree)(implicit ctx: Context): SourceFile = { val file = call.symbol.sourceFile - val encoding = ctx.settings.encoding.value - if (file != null && file.exists) new SourceFile(file, Codec(encoding)) else NoSource + if (file != null && file.exists) ctx.getSource(file) else NoSource } /** Desugar identifier into a select node. Return the tree itself if not possible */ diff --git a/compiler/src/dotty/tools/dotc/core/Contexts.scala b/compiler/src/dotty/tools/dotc/core/Contexts.scala index 8cb6a894ba5d..fb21695a1b07 100644 --- a/compiler/src/dotty/tools/dotc/core/Contexts.scala +++ b/compiler/src/dotty/tools/dotc/core/Contexts.scala @@ -20,6 +20,8 @@ import config.Settings._ import config.Config import reporting._ import reporting.diagnostic.Message +import io.AbstractFile +import scala.io.Codec import collection.mutable import printing._ import config.{JavaPlatform, SJSPlatform, Platform, ScalaSettings} @@ -224,6 +226,10 @@ object Contexts { implicitsCache } + /** Sourcefile corresponding to given abstract file, memoized */ + def getSource(file: AbstractFile, codec: => Codec = Codec(settings.encoding.value)) = + base.sources.getOrElseUpdate(file, new SourceFile(file, codec)) + /** Those fields are used to cache phases created in withPhase. * phasedCtx is first phase with altered phase ever requested. * phasedCtxs is array that uses phaseId's as indexes, @@ -624,6 +630,9 @@ object Contexts { def nextId: Int = { _nextId += 1; _nextId } + /** Sources that were loaded */ + val sources: mutable.HashMap[AbstractFile, SourceFile] = new mutable.HashMap[AbstractFile, SourceFile] + // Types state /** A table for hash consing unique types */ private[core] val uniques: util.HashSet[Type] = new util.HashSet[Type](Config.initialUniquesCapacity) { @@ -696,6 +705,7 @@ object Contexts { def reset(): Unit = { for ((_, set) <- uniqueSets) set.clear() errorTypeMsg.clear() + sources.clear() } // Test that access is single threaded diff --git a/compiler/src/dotty/tools/dotc/interactive/SourceTree.scala b/compiler/src/dotty/tools/dotc/interactive/SourceTree.scala index 2ceda42acf5f..3c8a51617723 100644 --- a/compiler/src/dotty/tools/dotc/interactive/SourceTree.scala +++ b/compiler/src/dotty/tools/dotc/interactive/SourceTree.scala @@ -61,7 +61,7 @@ object SourceTree { case PackageDef(_, stats) => stats.flatMap(sourceTreeOfClass).headOption case tree: tpd.TypeDef if tree.symbol == sym => - val sourceFile = new SourceFile(sym.sourceFile, Codec.UTF8) + val sourceFile = ctx.getSource(sym.sourceFile, Codec.UTF8) Some(SourceTree(tree, sourceFile)) case _ => None From 2ce11d99cff7cb5b140ea35876a586223a2050a3 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Tue, 18 Dec 2018 21:42:50 +0100 Subject: [PATCH 2/2] Memoize another sourceFile creation site --- doc-tool/src/dotty/tools/dottydoc/util/syntax.scala | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/doc-tool/src/dotty/tools/dottydoc/util/syntax.scala b/doc-tool/src/dotty/tools/dottydoc/util/syntax.scala index 005545d670b3..4edb71b387dd 100644 --- a/doc-tool/src/dotty/tools/dottydoc/util/syntax.scala +++ b/doc-tool/src/dotty/tools/dottydoc/util/syntax.scala @@ -21,7 +21,6 @@ object syntax { implicit class SymbolExtensions(val sym: Symbol) extends AnyVal { def sourcePosition(pos: Position)(implicit ctx: Context): SourcePosition = - new SourceFile(sym.sourceFile, Codec(ctx.settings.encoding.value)) atPos pos - + ctx.getSource(sym.sourceFile).atPos(pos) } }