@@ -340,7 +340,7 @@ object CheckUnused:
340
340
341
341
/* IMPORTS */
342
342
private val impInScope = Stack (ListBuffer .empty[ImportSelectorData ])
343
- private val usedInScope = Stack (mut.Set .empty[Usage ])
343
+ private val usedInScope = Stack (mut.Map .empty[Symbol , ListBuffer [ Usage ] ])
344
344
private val usedInPosition = mut.Map .empty[Name , mut.Set [Symbol ]]
345
345
/* unused import collected during traversal */
346
346
private val unusedImport = ListBuffer .empty[ImportSelectorData ]
@@ -397,14 +397,19 @@ object CheckUnused:
397
397
if sym.exists then
398
398
usedDef += sym
399
399
if includeForImport1 then
400
- usedInScope.top += Usage (sym, name, prefix, isDerived)
400
+ addUsage( Usage (sym, name, prefix, isDerived) )
401
401
addIfExists(sym)
402
402
addIfExists(sym.companionModule)
403
403
addIfExists(sym.companionClass)
404
404
if sym.sourcePos.exists then
405
405
for n <- name do
406
406
usedInPosition.getOrElseUpdate(n, mut.Set .empty) += sym
407
407
408
+ def addUsage (usage : Usage )(using Context ): Unit =
409
+ val usages = usedInScope.top.getOrElseUpdate(usage.symbol, ListBuffer .empty)
410
+ if ! usages.exists(x => x.name == usage.name && x.isDerived == usage.isDerived && x.prefix =:= usage.prefix)
411
+ then usages += usage
412
+
408
413
/** Register a symbol that should be ignored */
409
414
def addIgnoredUsage (sym : Symbol )(using Context ): Unit =
410
415
doNotRegister ++= sym.everySymbol
@@ -465,7 +470,7 @@ object CheckUnused:
465
470
// unused imports :
466
471
currScopeType.push(newScopeType)
467
472
impInScope.push(ListBuffer .empty)
468
- usedInScope.push(mut.Set .empty)
473
+ usedInScope.push(mut.Map .empty)
469
474
470
475
def registerSetVar (sym : Symbol ): Unit =
471
476
setVars += sym
@@ -477,18 +482,17 @@ object CheckUnused:
477
482
*/
478
483
def popScope (scopeType : ScopeType )(using Context ): Unit =
479
484
assert(currScopeType.pop() == scopeType)
480
- val usedInfos = usedInScope.pop()
481
485
val selDatas = impInScope.pop()
482
486
483
- for usedInfo <- usedInfos do
484
- val Usage (sym, optName, prefix, isDerived) = usedInfo
485
- selDatas.find(sym .isInImport(_, optName , prefix, isDerived)) match
487
+ for usedInfos <- usedInScope.pop().valuesIterator; usedInfo <- usedInfos do
488
+ import usedInfo . *
489
+ selDatas.find(symbol .isInImport(_, name , prefix, isDerived)) match
486
490
case Some (sel) =>
487
491
sel.markUsed()
488
492
case None =>
489
493
// Propagate the symbol one level up
490
494
if usedInScope.nonEmpty then
491
- usedInScope.top += usedInfo
495
+ addUsage( usedInfo)
492
496
end for // each in usedInfos
493
497
494
498
for selData <- selDatas do
@@ -802,7 +806,7 @@ object CheckUnused:
802
806
/** A symbol usage includes the name under which it was observed,
803
807
* the prefix from which it was selected, and whether it is in a derived element.
804
808
*/
805
- case class Usage (symbol : Symbol , name : Option [Name ], prefix : Type , isDerived : Boolean )
809
+ class Usage (val symbol : Symbol , val name : Option [Name ], val prefix : Type , val isDerived : Boolean )
806
810
end UnusedData
807
811
extension (sym : Symbol )
808
812
/** is accessible without import in current context */
0 commit comments