@@ -61,7 +61,6 @@ class CheckUnused extends MiniPhase:
61
61
// ========== SETUP ============
62
62
63
63
override def prepareForUnit (tree : tpd.Tree )(using Context ): Context =
64
- val tree = ctx.compilationUnit.tpdTree
65
64
val data = UnusedData ()
66
65
val fresh = ctx.fresh.setProperty(_key, data)
67
66
fresh
@@ -94,7 +93,11 @@ class CheckUnused extends MiniPhase:
94
93
pushInBlockTemplatePackageDef(tree)
95
94
96
95
override def prepareForValDef (tree : tpd.ValDef )(using Context ): Context =
97
- _key.unusedDataApply(_.registerDef(tree))
96
+ _key.unusedDataApply{ud =>
97
+ ud.registerDef(tree)
98
+ if tree.symbol.is(Flags .Module ) then
99
+ ud.addIgnoredUsage(tree.symbol)
100
+ }
98
101
99
102
override def prepareForDefDef (tree : tpd.DefDef )(using Context ): Context =
100
103
_key.unusedDataApply{ ud =>
@@ -103,6 +106,12 @@ class CheckUnused extends MiniPhase:
103
106
ud.registerDef(tree)
104
107
}
105
108
109
+ override def prepareForTypeDef (tree : tpd.TypeDef )(using Context ): Context =
110
+ _key.unusedDataApply{ ud =>
111
+ ud.registerDef(tree)
112
+ ud.addIgnoredUsage(tree.symbol)
113
+ }
114
+
106
115
override def prepareForBind (tree : tpd.Bind )(using Context ): Context =
107
116
_key.unusedDataApply(_.registerPatVar(tree))
108
117
@@ -112,6 +121,11 @@ class CheckUnused extends MiniPhase:
112
121
113
122
// ========== MiniPhase Transform ==========
114
123
124
+ override def transformValDef (tree : tpd.ValDef )(using Context ): tpd.Tree =
125
+ if tree.symbol.is(Flags .Module ) then
126
+ _key.unusedDataApply(_.removeIgnoredUsage(tree.symbol))
127
+ tree
128
+
115
129
override def transformBlock (tree : tpd.Block )(using Context ): tpd.Tree =
116
130
popOutBlockTemplatePackageDef()
117
131
tree
@@ -124,6 +138,10 @@ class CheckUnused extends MiniPhase:
124
138
popOutBlockTemplatePackageDef()
125
139
tree
126
140
141
+ override def transformTypeDef (tree : tpd.TypeDef )(using Context ): tpd.Tree =
142
+ _key.unusedDataApply(_.removeIgnoredUsage(tree.symbol))
143
+ tree
144
+
127
145
// ---------- MiniPhase HELPERS -----------
128
146
129
147
private def pushInBlockTemplatePackageDef (tree : tpd.Block | tpd.Template | tpd.PackageDef )(using Context ): Context =
@@ -175,6 +193,9 @@ class CheckUnused extends MiniPhase:
175
193
case t: tpd.DefDef =>
176
194
prepareForDefDef(t)
177
195
traverseChildren(tree)(using newCtx)
196
+ case t: tpd.TypeDef =>
197
+ prepareForTypeDef(t)
198
+ traverseChildren(tree)(using newCtx)
178
199
case t : tpd.Bind =>
179
200
prepareForBind(t)
180
201
traverseChildren(tree)(using newCtx)
@@ -255,21 +276,23 @@ object CheckUnused:
255
276
private val unusedImport = MutSet [ImportSelector ]()
256
277
257
278
/* LOCAL DEF OR VAL / Private Def or Val / Pattern variables */
258
- private val localDefInScope = MutSet [tpd.ValOrDefDef ]()
259
- private val privateDefInScope = MutSet [tpd.ValOrDefDef ]()
260
- private val explicitParamInScope = MutSet [tpd.ValOrDefDef ]()
261
- private val implicitParamInScope = MutSet [tpd.ValOrDefDef ]()
279
+ private val localDefInScope = MutSet [tpd.MemberDef ]()
280
+ private val privateDefInScope = MutSet [tpd.MemberDef ]()
281
+ private val explicitParamInScope = MutSet [tpd.MemberDef ]()
282
+ private val implicitParamInScope = MutSet [tpd.MemberDef ]()
262
283
private val patVarsInScope = MutSet [tpd.Bind ]()
263
284
264
285
/* Unused collection collected at the end */
265
- private val unusedLocalDef = MutSet [tpd.ValOrDefDef ]()
266
- private val unusedPrivateDef = MutSet [tpd.ValOrDefDef ]()
267
- private val unusedExplicitParams = MutSet [tpd.ValOrDefDef ]()
268
- private val unusedImplicitParams = MutSet [tpd.ValOrDefDef ]()
286
+ private val unusedLocalDef = MutSet [tpd.MemberDef ]()
287
+ private val unusedPrivateDef = MutSet [tpd.MemberDef ]()
288
+ private val unusedExplicitParams = MutSet [tpd.MemberDef ]()
289
+ private val unusedImplicitParams = MutSet [tpd.MemberDef ]()
269
290
private val unusedPatVars = MutSet [tpd.Bind ]()
270
291
271
292
/** All used symbols */
272
293
private val usedDef = MutSet [Symbol ]()
294
+ /** Do not register as used */
295
+ private val doNotRegister = MutSet [Symbol ]()
273
296
274
297
/** Trivial definitions, avoid registering params */
275
298
private val trivialDefs = MutSet [Symbol ]()
@@ -296,14 +319,30 @@ object CheckUnused:
296
319
* as the same element can be imported with different renaming
297
320
*/
298
321
def registerUsed (sym : Symbol , name : Option [Name ])(using Context ): Unit =
299
- if ! isConstructorOfSynth(sym) then
322
+ if ! isConstructorOfSynth(sym) && ! doNotRegister(sym) then
300
323
usedInScope.top += ((sym, sym.isAccessibleAsIdent, name))
301
324
if sym.isConstructor && sym.exists then
302
325
registerUsed(sym.owner, None ) // constructor are "implicitly" imported with the class
303
326
304
327
/** Register a list of found (used) symbols */
305
328
def registerUsed (syms : Seq [Symbol ])(using Context ): Unit =
306
- usedInScope.top ++= syms.filterNot(isConstructorOfSynth).map(s => (s, s.isAccessibleAsIdent, None ))
329
+ usedInScope.top ++=
330
+ syms
331
+ .filterNot(s => isConstructorOfSynth(s) || doNotRegister(s))
332
+ .map(s => (s, s.isAccessibleAsIdent, None ))
333
+
334
+ /** Register a symbol that should be ignored */
335
+ def addIgnoredUsage (sym : Symbol )(using Context ): Unit =
336
+ doNotRegister += sym
337
+ if sym.is(Flags .Module ) then
338
+ doNotRegister += sym.moduleClass
339
+
340
+ /** Remove a symbol that shouldn't be ignored anymore */
341
+ def removeIgnoredUsage (sym : Symbol )(using Context ): Unit =
342
+ doNotRegister -= sym
343
+ if sym.is(Flags .Module ) then
344
+ doNotRegister -= sym.moduleClass
345
+
307
346
308
347
/** Register an import */
309
348
def registerImport (imp : tpd.Import )(using Context ): Unit =
@@ -314,19 +353,19 @@ object CheckUnused:
314
353
}
315
354
316
355
/** Register (or not) some `val` or `def` according to the context, scope and flags */
317
- def registerDef (valOrDef : tpd.ValOrDefDef )(using Context ): Unit =
356
+ def registerDef (memDef : tpd.MemberDef )(using Context ): Unit =
318
357
// register the annotations for usage
319
- registerUsedAnnotation(valOrDef .symbol)
320
- if ! valOrDef .symbol.isUnusedAnnot then
321
- if valOrDef .symbol.is(Param ) && ! isSyntheticMainParam(valOrDef .symbol) && ! valOrDef .symbol.ownerIsTrivial then
322
- if valOrDef .symbol.isOneOf(GivenOrImplicit ) then
323
- implicitParamInScope += valOrDef
358
+ registerUsedAnnotation(memDef .symbol)
359
+ if ! memDef .symbol.isUnusedAnnot then
360
+ if memDef .symbol.is(Param ) && ! isSyntheticMainParam(memDef .symbol) && ! memDef .symbol.ownerIsTrivial then
361
+ if memDef .symbol.isOneOf(GivenOrImplicit ) then
362
+ implicitParamInScope += memDef
324
363
else
325
- explicitParamInScope += valOrDef
364
+ explicitParamInScope += memDef
326
365
else if currScopeType.top == ScopeType .Local then
327
- localDefInScope += valOrDef
328
- else if currScopeType.top == ScopeType .Template && valOrDef .symbol.is(Private , butNot = SelfName ) then
329
- privateDefInScope += valOrDef
366
+ localDefInScope += memDef
367
+ else if currScopeType.top == ScopeType .Template && memDef .symbol.is(Private , butNot = SelfName ) then
368
+ privateDefInScope += memDef
330
369
331
370
/** Register pattern variable */
332
371
def registerPatVar (patvar : tpd.Bind )(using Context ): Unit =
0 commit comments