@@ -5,7 +5,7 @@ import scala.language.unsafeNulls
55
66import java .io .File
77import java .nio .file .Path
8- import java .util .{ Arrays , EnumSet }
8+ import java .util .EnumSet
99
1010import dotty .tools .dotc .ast .tpd
1111import dotty .tools .dotc .classpath .FileUtils .{hasClassExtension , hasTastyExtension }
@@ -46,7 +46,6 @@ import scala.compiletime.uninitialized
4646 *
4747 * The following flags affect this phase:
4848 * -Yforce-sbt-phases
49- * -Ydump-sbt-inc
5049 *
5150 * @see ExtractAPI
5251 */
@@ -77,27 +76,6 @@ class ExtractDependencies extends Phase {
7776 val rec = unit.depRecorder
7877 val collector = ExtractDependenciesCollector (rec)
7978 collector.traverse(unit.tpdTree)
80-
81- if (ctx.settings.YdumpSbtInc .value) {
82- val deps = rec.foundDeps.iterator.map { case (clazz, found) => s " $clazz: ${found.classesString}" }.toArray[Object ]
83- val names = rec.foundDeps.iterator.map { case (clazz, found) => s " $clazz: ${found.namesString}" }.toArray[Object ]
84- Arrays .sort(deps)
85- Arrays .sort(names)
86-
87- val pw = io.File (unit.source.file.jpath).changeExtension(FileExtension .Inc ).toFile.printWriter()
88- // val pw = Console.out
89- try {
90- pw.println(" Used Names:" )
91- pw.println(" ===========" )
92- names.foreach(pw.println)
93- pw.println()
94- pw.println(" Dependencies:" )
95- pw.println(" =============" )
96- deps.foreach(pw.println)
97- } finally pw.close()
98- }
99-
100- rec.sendToZinc()
10179 }
10280}
10381
@@ -129,6 +107,47 @@ object ExtractDependencies {
129107 report.error(em " Internal error in the incremental compiler while compiling ${ctx.compilationUnit.source}: $msg" , pos)
130108}
131109
110+ /** Extract the dependency information of a compilation unit.
111+ *
112+ * This extracts the symbol dependencies in the written code.
113+ * There are further extractions performed in the Inlining phase later.
114+ *
115+ * To understand why we track the used names see the section "Name hashing
116+ * algorithm" in http://www.scala-sbt.org/0.13/docs/Understanding-Recompilation.html
117+ * To understand why we need to track dependencies introduced by inheritance
118+ * specially, see the subsection "Dependencies introduced by member reference and
119+ * inheritance" in the "Name hashing algorithm" section.
120+ */
121+ private class ExtractDependenciesCollector (rec : DependencyRecorder ) extends AbstractExtractDependenciesCollector (rec):
122+ import tpd .*
123+
124+ /** Traverse the tree of a source file and record the dependencies and used names which
125+ * can be retrieved using DependencyRecorder.
126+ */
127+ override def traverse (tree : Tree )(using Context ): Unit =
128+ try
129+ recordTree(tree)
130+ tree match
131+ case tree : Inlined if ! tree.inlinedFromOuterScope =>
132+ // The inlined call is normally ignored by TreeTraverser but we need to
133+ // record it as a dependency
134+ traverse(tree.call)
135+ // traverseChildren(tree)
136+ case vd : ValDef if vd.symbol.is(ModuleVal ) =>
137+ // Don't visit module val
138+ case t : Template if t.symbol.owner.is(ModuleClass ) =>
139+ // Don't visit self type of module class
140+ traverse(t.constr)
141+ t.parents.foreach(traverse)
142+ t.body.foreach(traverse)
143+ case _ =>
144+ traverseChildren(tree)
145+ catch
146+ case ex : AssertionError =>
147+ println(i " asserted failed while traversing $tree" )
148+ throw ex
149+ end ExtractDependenciesCollector
150+
132151/** Extract the dependency information of a compilation unit.
133152 *
134153 * To understand why we track the used names see the section "Name hashing
@@ -137,7 +156,7 @@ object ExtractDependencies {
137156 * specially, see the subsection "Dependencies introduced by member reference and
138157 * inheritance" in the "Name hashing algorithm" section.
139158 */
140- private class ExtractDependenciesCollector (rec : DependencyRecorder ) extends tpd.TreeTraverser { thisTreeTraverser =>
159+ trait AbstractExtractDependenciesCollector (rec : DependencyRecorder ) extends tpd.TreeTraverser { thisTreeTraverser =>
141160 import tpd .*
142161
143162 private def addMemberRefDependency (sym : Symbol )(using Context ): Unit =
@@ -181,12 +200,8 @@ private class ExtractDependenciesCollector(rec: DependencyRecorder) extends tpd.
181200 // can happen for constructor proxies. Test case is pos-macros/i13532.
182201 true
183202
184-
185- /** Traverse the tree of a source file and record the dependencies and used names which
186- * can be retrieved using `foundDeps`.
187- */
188- override def traverse (tree : Tree )(using Context ): Unit = try {
189- tree match {
203+ protected def recordTree (tree : Tree )(using Context ): Unit =
204+ tree match
190205 case Match (selector, _) =>
191206 addPatMatDependency(selector.tpe)
192207 case Import (expr, selectors) =>
@@ -223,31 +238,7 @@ private class ExtractDependenciesCollector(rec: DependencyRecorder) extends tpd.
223238 addInheritanceDependencies(t)
224239 case t : Template =>
225240 addInheritanceDependencies(t)
226- case _ =>
227- }
228-
229- tree match {
230- case tree : Inlined =>
231- // The inlined call is normally ignored by TreeTraverser but we need to
232- // record it as a dependency
233- if ! tree.inlinedFromOuterScope then
234- traverse(tree.call)
235- traverseChildren(tree)
236- case vd : ValDef if vd.symbol.is(ModuleVal ) =>
237- // Don't visit module val
238- case t : Template if t.symbol.owner.is(ModuleClass ) =>
239- // Don't visit self type of module class
240- traverse(t.constr)
241- t.parents.foreach(traverse)
242- t.body.foreach(traverse)
243- case _ =>
244- traverseChildren(tree)
245- }
246- } catch {
247- case ex : AssertionError =>
248- println(i " asserted failed while traversing $tree" )
249- throw ex
250- }
241+ case _ => ()
251242
252243 /** Reused EqHashSet, safe to use as each TypeDependencyTraverser is used atomically
253244 * Avoid cycles by remembering both the types (testcase:
0 commit comments