Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 6468bd6

Browse files
authored
Merge pull request #11080 from som-snytt/issue/10313-macro-usages
Improve unused check of macro expansion
2 parents 2472638 + 2124b09 commit 6468bd6

File tree

2 files changed

+61
-43
lines changed

2 files changed

+61
-43
lines changed

src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala

Lines changed: 47 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -551,6 +551,49 @@ trait TypeDiagnostics extends splain.SplainDiagnostics {
551551
case _ => isConstantType(rhs.tpe) || isSingleType(rhs.tpe) || rhs.isInstanceOf[This]
552552
})
553553

554+
def handleRefTree(t: RefTree): Unit = {
555+
val sym = t.symbol
556+
if (isExisting(sym) && !currentOwner.hasTransOwner(sym) && !t.hasAttachment[ForAttachment.type])
557+
recordReference(sym)
558+
}
559+
560+
def handleTreeType(t: Tree): Unit =
561+
if ((t.tpe ne null) && t.tpe != NoType) {
562+
for (tp <- t.tpe if tp != NoType && !treeTypes(tp)) {
563+
// Include references to private/local aliases (which might otherwise refer to an enclosing class)
564+
val isAlias = {
565+
val td = tp.typeSymbolDirect
566+
td.isAliasType && (td.isLocalToBlock || td.isPrivate)
567+
}
568+
// Ignore type references to an enclosing class. A reference to C must be outside C to avoid warning.
569+
if (isAlias || !currentOwner.hasTransOwner(tp.typeSymbol)) tp match {
570+
case NoType | NoPrefix =>
571+
case NullaryMethodType(_) =>
572+
case MethodType(_, _) =>
573+
case SingleType(_, _) =>
574+
case ConstantType(Constant(k: Type)) =>
575+
log(s"classOf $k referenced from $currentOwner")
576+
treeTypes += k
577+
case _ =>
578+
log(s"${if (isAlias) "alias " else ""}$tp referenced from $currentOwner")
579+
treeTypes += tp
580+
}
581+
for (annot <- tp.annotations)
582+
descend(annot)
583+
}
584+
// e.g. val a = new Foo ; new a.Bar ; don't let a be reported as unused.
585+
t.tpe.prefix foreach {
586+
case SingleType(_, sym) => recordReference(sym)
587+
case _ => ()
588+
}
589+
}
590+
591+
def descend(annot: AnnotationInfo): Unit =
592+
if (!annots(annot)) {
593+
annots.addOne(annot)
594+
traverse(annot.original)
595+
}
596+
554597
override def traverse(t: Tree): Unit = {
555598
t match {
556599
case t: ValDef if wasPatVarDef(t) => // include field excluded by qualifies test
@@ -616,10 +659,7 @@ trait TypeDiagnostics extends splain.SplainDiagnostics {
616659
case b @ Bind(n, _) if n != nme.DEFAULT_CASE => addPatVar(b)
617660
case _ =>
618661
}
619-
case t: RefTree =>
620-
val sym = t.symbol
621-
if (isExisting(sym) && !currentOwner.hasTransOwner(sym) && !t.hasAttachment[ForAttachment.type])
622-
recordReference(sym)
662+
case t: RefTree => handleRefTree(t)
623663
case Assign(lhs, _) if isExisting(lhs.symbol) => setVars += lhs.symbol
624664
case Function(ps, _) if !t.isErrorTyped =>
625665
for (p <- ps) {
@@ -648,40 +688,7 @@ trait TypeDiagnostics extends splain.SplainDiagnostics {
648688
case _ =>
649689
}
650690

651-
def descend(annot: AnnotationInfo): Unit =
652-
if (!annots(annot)) {
653-
annots.addOne(annot)
654-
traverse(annot.original)
655-
}
656-
if ((t.tpe ne null) && t.tpe != NoType) {
657-
for (tp <- t.tpe if tp != NoType) if (!treeTypes(tp)) {
658-
// Include references to private/local aliases (which might otherwise refer to an enclosing class)
659-
val isAlias = {
660-
val td = tp.typeSymbolDirect
661-
td.isAliasType && (td.isLocalToBlock || td.isPrivate)
662-
}
663-
// Ignore type references to an enclosing class. A reference to C must be outside C to avoid warning.
664-
if (isAlias || !currentOwner.hasTransOwner(tp.typeSymbol)) tp match {
665-
case NoType | NoPrefix =>
666-
case NullaryMethodType(_) =>
667-
case MethodType(_, _) =>
668-
case SingleType(_, _) =>
669-
case ConstantType(Constant(k: Type)) =>
670-
log(s"classOf $k referenced from $currentOwner")
671-
treeTypes += k
672-
case _ =>
673-
log(s"${if (isAlias) "alias " else ""}$tp referenced from $currentOwner")
674-
treeTypes += tp
675-
}
676-
for (annot <- tp.annotations)
677-
descend(annot)
678-
}
679-
// e.g. val a = new Foo ; new a.Bar ; don't let a be reported as unused.
680-
t.tpe.prefix foreach {
681-
case SingleType(_, sym) => recordReference(sym)
682-
case _ => ()
683-
}
684-
}
691+
handleTreeType(t)
685692

686693
if (t.symbol != null && t.symbol.exists)
687694
for (annot <- t.symbol.annotations)
@@ -804,13 +811,10 @@ trait TypeDiagnostics extends splain.SplainDiagnostics {
804811
object refCollector extends Traverser {
805812
override def traverse(tree: Tree): Unit = {
806813
tree match {
807-
case _: RefTree if isExisting(tree.symbol) => recordReference(tree.symbol)
808-
case _ =>
809-
}
810-
if (tree.tpe != null) tree.tpe.prefix.foreach {
811-
case SingleType(_, sym) => recordReference(sym)
814+
case tree: RefTree => handleRefTree(tree)
812815
case _ =>
813816
}
817+
handleTreeType(tree)
814818
super.traverse(tree)
815819
}
816820
}

test/files/pos/t10313a.scala

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
//> using options -Werror -Xlint:unused
2+
//-Vprint:typer -Vmacro
3+
4+
import scala.util.matching.Regex
5+
6+
// guard against regression in reporting constant `esc` unused
7+
object Naming {
8+
private final val esc = "\u001b"
9+
private val csi = raw"$esc\[[0-9;]*([\x40-\x7E])"
10+
private lazy val cleaner = raw"$csi|([\p{Cntrl}&&[^\p{Space}]]+)|$linePattern".r
11+
private def linePattern: String = ""
12+
private def clean(m: Regex.Match): Option[String] = None
13+
def unmangle(str: String): String = cleaner.replaceSomeIn(str, clean)
14+
}

0 commit comments

Comments
 (0)