Skip to content

Commit 660fab6

Browse files
Merge pull request #3027 from dotty-staging/fix-ide-crash-on-java-annotations
Fix IDE crash on @afterclass
2 parents 74c835d + 5b88356 commit 660fab6

File tree

1 file changed

+20
-6
lines changed

1 file changed

+20
-6
lines changed

compiler/src/dotty/tools/dotc/interactive/InteractiveDriver.scala

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -182,14 +182,28 @@ class InteractiveDriver(settings: List[String]) extends Driver {
182182
* of a previous run. Note that typed trees can have untyped or partially
183183
* typed children if the source contains errors.
184184
*/
185-
private def cleanup(tree: tpd.Tree)(implicit ctx: Context): Unit = tree.foreachSubTree { t =>
186-
if (t.hasType) {
187-
if (t.symbol.exists) {
188-
if (!t.symbol.isCompleted) t.symbol.info = UnspecifiedErrorType
189-
t.symbol.annotations.foreach(annot => cleanup(annot.tree))
185+
private def cleanup(tree: tpd.Tree)(implicit ctx: Context): Unit = {
186+
val seen = mutable.Set.empty[tpd.Tree]
187+
def cleanupTree(tree: tpd.Tree): Unit = {
188+
seen += tree
189+
tree.foreachSubTree { t =>
190+
if (t.symbol.exists && t.hasType) {
191+
if (!t.symbol.isCompleted) t.symbol.info = UnspecifiedErrorType
192+
t.symbol.annotations.foreach { annot =>
193+
/* In some cases annotations are are used on themself (possibly larger cycles).
194+
* This is the case with the java.lang.annotation.Target annotation, would end
195+
* in an infinite loop while cleaning. The `seen` is added to ensure that those
196+
* trees are not cleand twice.
197+
* TODO: Find a less expensive way to check for those cycles.
198+
*/
199+
if (!seen(annot.tree))
200+
cleanupTree(annot.tree)
201+
}
202+
}
203+
t.removeAllAttachments()
190204
}
191205
}
192-
t.removeAllAttachments()
206+
cleanupTree(tree)
193207
}
194208

195209
def run(uri: URI, sourceCode: String): List[MessageContainer] = {

0 commit comments

Comments
 (0)