@@ -76,12 +76,8 @@ class ExtractDependencies extends Phase {
7676 collector.traverse(unit.tpdTree)
7777
7878 if (ctx.settings.YdumpSbtInc .value) {
79- val deps = rec.classDependencies.flatMap((k,vs) =>
80- vs.iterator.flatMap((to, depCtxs) =>
81- depCtxs.asScala.map(depCtx => s " ClassDependency( $k, $to, $depCtx) " )
82- )
83- ).toArray[Object ]
84- val names = rec.usedNames.map { case (clazz, names) => s " $clazz: $names" }.toArray[Object ]
79+ val deps = rec.foundDeps.map { case (clazz, found) => s " $clazz: ${found.classesString}" }.toArray[Object ]
80+ val names = rec.foundDeps.map { case (clazz, found) => s " $clazz: ${found.namesString}" }.toArray[Object ]
8581 Arrays .sort(deps)
8682 Arrays .sort(names)
8783
@@ -168,7 +164,7 @@ private class ExtractDependenciesCollector(rec: DependencyRecorder) extends tpd.
168164
169165
170166 /** Traverse the tree of a source file and record the dependencies and used names which
171- * can be retrieved using `dependencies` and`usedNames `.
167+ * can be retrieved using `foundDeps `.
172168 */
173169 override def traverse (tree : Tree )(using Context ): Unit = try {
174170 tree match {
@@ -315,16 +311,6 @@ private class ExtractDependenciesCollector(rec: DependencyRecorder) extends tpd.
315311 }
316312}
317313
318- class ClassDepsInClass :
319- private val _classes = util.EqHashMap [Symbol , EnumSet [DependencyContext ]]()
320-
321- def addDependency (fromClass : Symbol , context : DependencyContext ): Unit =
322- val set = _classes.getOrElseUpdate(fromClass, EnumSet .noneOf(classOf [DependencyContext ]))
323- set.add(context)
324-
325- def iterator : Iterator [(Symbol , EnumSet [DependencyContext ])] =
326- _classes.iterator
327-
328314/** Record dependencies using `addUsedName`/`addClassDependency` and inform Zinc using `sendToZinc()`.
329315 *
330316 * Note: As an alternative design choice, we could directly call the appropriate
@@ -336,10 +322,10 @@ class ClassDepsInClass:
336322class DependencyRecorder {
337323 import ExtractDependencies .*
338324
339- /** A map from a non-local class to the names it uses, this does not include
325+ /** A map from a non-local class to the names and classes it uses, this does not include
340326 * names which are only defined and not referenced.
341327 */
342- def usedNames : collection.Map [Symbol , UsedNamesInClass ] = _usedNames
328+ def foundDeps : collection.Map [Symbol , FoundDepsInClass ] = _foundDeps
343329
344330 /** Record a reference to the name of `sym` from the current non-local
345331 * enclosing class.
@@ -374,7 +360,7 @@ class DependencyRecorder {
374360 def addUsedRawName (name : Name , includeSealedChildren : Boolean = false )(using Context ): Unit = {
375361 val fromClass = resolveDependencyFromClass
376362 if (fromClass.exists) {
377- lastUsedCache.update (name, includeSealedChildren)
363+ lastFoundCache.recordName (name, includeSealedChildren)
378364 }
379365 }
380366
@@ -383,26 +369,36 @@ class DependencyRecorder {
383369 private val DefaultScopes = EnumSet .of(UseScope .Default )
384370 private val PatMatScopes = EnumSet .of(UseScope .Default , UseScope .PatMatTarget )
385371
386- /** An object that maintain the set of used names from within a class */
387- final class UsedNamesInClass {
372+ /** An object that maintain the set of used names and class dependencies from within a class */
373+ final class FoundDepsInClass {
388374 /** Each key corresponds to a name used in the class. To understand the meaning
389375 * of the associated value, see the documentation of parameter `includeSealedChildren`
390376 * of `addUsedRawName`.
391377 */
392378 private val _names = new util.HashMap [Name , DefaultScopes .type | PatMatScopes .type ]
393379
394- def iterator : Iterator [(Name , EnumSet [UseScope ])] = _names.iterator
380+ /** Each key corresponds to a class dependency used in the class.
381+ */
382+ private val _classes = util.EqHashMap [Symbol , EnumSet [DependencyContext ]]()
383+
384+ def addDependency (fromClass : Symbol , context : DependencyContext ): Unit =
385+ val set = _classes.getOrElseUpdate(fromClass, EnumSet .noneOf(classOf [DependencyContext ]))
386+ set.add(context)
387+
388+ def classes : Iterator [(Symbol , EnumSet [DependencyContext ])] = _classes.iterator
395389
396- private [DependencyRecorder ] def update (name : Name , includeSealedChildren : Boolean ): Unit = {
390+ def names : Iterator [(Name , EnumSet [UseScope ])] = _names.iterator
391+
392+ private [DependencyRecorder ] def recordName (name : Name , includeSealedChildren : Boolean ): Unit = {
397393 if (includeSealedChildren)
398394 _names(name) = PatMatScopes
399395 else
400396 _names.getOrElseUpdate(name, DefaultScopes )
401397 }
402398
403- override def toString () : String = {
399+ def namesString : String = {
404400 val builder = new StringBuilder
405- iterator .foreach { (name, scopes) =>
401+ names .foreach { case (name, scopes) =>
406402 builder.append(name.mangledString)
407403 builder.append(" in [" )
408404 scopes.forEach(scope => builder.append(scope.toString))
@@ -411,46 +407,50 @@ class DependencyRecorder {
411407 }
412408 builder.toString()
413409 }
414- }
415-
416410
417- private val _classDependencies = new mutable.HashMap [Symbol , ClassDepsInClass ]
418-
419- def classDependencies : collection.Map [Symbol , ClassDepsInClass ] = _classDependencies
411+ def classesString : String = {
412+ val builder = new StringBuilder
413+ classes.foreach { case (clazz, scopes) =>
414+ builder.append(clazz.toString)
415+ builder.append(" in [" )
416+ scopes.forEach(scope => builder.append(scope.toString))
417+ builder.append(" ]" )
418+ builder.append(" , " )
419+ }
420+ builder.toString()
421+ }
422+ }
420423
421424 /** Record a dependency to the class `to` in a given `context`
422425 * from the current non-local enclosing class.
423426 */
424427 def addClassDependency (toClass : Symbol , context : DependencyContext )(using Context ): Unit =
425428 val fromClass = resolveDependencyFromClass
426429 if (fromClass.exists)
427- lastDepCache .addDependency(toClass, context)
430+ lastFoundCache .addDependency(toClass, context)
428431
429- private val _usedNames = new mutable.HashMap [Symbol , UsedNamesInClass ]
432+ private val _foundDeps = new mutable.HashMap [Symbol , FoundDepsInClass ]
430433
431434 /** Send the collected dependency information to Zinc and clear the local caches. */
432435 def sendToZinc ()(using Context ): Unit =
433436 ctx.withIncCallback: cb =>
434- usedNames.foreach:
435- case (clazz, usedNames) =>
437+ val siblingClassfiles = new mutable.HashMap [PlainFile , Path ]
438+ foundDeps.foreach:
439+ case (clazz, foundDeps) =>
436440 val className = classNameAsString(clazz)
437- usedNames.iterator .foreach: (usedName, scopes) =>
441+ foundDeps.names .foreach: (usedName, scopes) =>
438442 cb.usedName(className, usedName.toString, scopes)
439- val siblingClassfiles = new mutable.HashMap [PlainFile , Path ]
440- for (fromClass, partialDependencies) <- _classDependencies do
441- for (toClass, deps) <- partialDependencies.iterator do
442- for dep <- deps.asScala do
443- recordClassDependency(cb, fromClass, toClass, dep, siblingClassfiles)
443+ for (toClass, deps) <- foundDeps.classes do
444+ for dep <- deps.asScala do
445+ recordClassDependency(cb, clazz, toClass, dep, siblingClassfiles)
444446 clear()
445447
446448 /** Clear all state. */
447449 def clear (): Unit =
448- _usedNames.clear()
449- _classDependencies.clear()
450+ _foundDeps.clear()
450451 lastOwner = NoSymbol
451452 lastDepSource = NoSymbol
452- lastDepCache = null
453- lastUsedCache = null
453+ lastFoundCache = null
454454 _responsibleForImports = NoSymbol
455455
456456 /** Handles dependency on given symbol by trying to figure out if represents a term
@@ -521,8 +521,7 @@ class DependencyRecorder {
521521
522522 private var lastOwner : Symbol = _
523523 private var lastDepSource : Symbol = _
524- private var lastDepCache : ClassDepsInClass | Null = _
525- private var lastUsedCache : UsedNamesInClass | Null = _
524+ private var lastFoundCache : FoundDepsInClass | Null = _
526525
527526 /** The source of the dependency according to `nonLocalEnclosingClass`
528527 * if it exists, otherwise fall back to `responsibleForImports`.
@@ -537,8 +536,7 @@ class DependencyRecorder {
537536 val fromClass = if (source.is(PackageClass )) responsibleForImports else source
538537 if lastDepSource != fromClass then
539538 lastDepSource = fromClass
540- lastDepCache = _classDependencies.getOrElseUpdate(fromClass, new ClassDepsInClass )
541- lastUsedCache = _usedNames.getOrElseUpdate(fromClass, new UsedNamesInClass )
539+ lastFoundCache = _foundDeps.getOrElseUpdate(fromClass, new FoundDepsInClass )
542540 }
543541
544542 lastDepSource
0 commit comments