mirror of https://github.com/sbt/sbt.git
Fix SOE with macros in dependencies extraction
In some cases, expanded macros report that their original tree and its expansion are the same, thus creating a cyclic chain. This chain may then produce a SOE during dependencies or used names extraction. This kind of problem was already reported in sbt/sbt#1237 and sbt/sbt#1408. Unfortunately, the fix that was applied to the dependencies extraction part was not sufficient. Mark test 'source-dependencies/macro' as passing Fixes #1544
This commit is contained in:
parent
68602278d5
commit
8542c9b31a
|
|
@ -102,6 +102,16 @@ final class Dependency(val global: CallbackGlobal) extends LocateClassFile {
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ExtractDependenciesByMemberRefTraverser extends ExtractDependenciesTraverser {
|
private class ExtractDependenciesByMemberRefTraverser extends ExtractDependenciesTraverser {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Some macros appear to contain themselves as original tree.
|
||||||
|
* We must check that we don't inspect the same tree over and over.
|
||||||
|
* See https://issues.scala-lang.org/browse/SI-8486
|
||||||
|
* https://github.com/sbt/sbt/issues/1237
|
||||||
|
* https://github.com/sbt/sbt/issues/1544
|
||||||
|
*/
|
||||||
|
private val inspectedOriginalTrees = collection.mutable.Set.empty[Tree]
|
||||||
|
|
||||||
override def traverse(tree: Tree): Unit = {
|
override def traverse(tree: Tree): Unit = {
|
||||||
tree match {
|
tree match {
|
||||||
case Import(expr, selectors) =>
|
case Import(expr, selectors) =>
|
||||||
|
|
@ -118,13 +128,13 @@ final class Dependency(val global: CallbackGlobal) extends LocateClassFile {
|
||||||
case select: Select =>
|
case select: Select =>
|
||||||
addDependency(select.symbol)
|
addDependency(select.symbol)
|
||||||
/*
|
/*
|
||||||
* Idents are used in number of situations:
|
* Idents are used in number of situations:
|
||||||
* - to refer to local variable
|
* - to refer to local variable
|
||||||
* - to refer to a top-level package (other packages are nested selections)
|
* - to refer to a top-level package (other packages are nested selections)
|
||||||
* - to refer to a term defined in the same package as an enclosing class;
|
* - to refer to a term defined in the same package as an enclosing class;
|
||||||
* this looks fishy, see this thread:
|
* this looks fishy, see this thread:
|
||||||
* https://groups.google.com/d/topic/scala-internals/Ms9WUAtokLo/discussion
|
* https://groups.google.com/d/topic/scala-internals/Ms9WUAtokLo/discussion
|
||||||
*/
|
*/
|
||||||
case ident: Ident =>
|
case ident: Ident =>
|
||||||
addDependency(ident.symbol)
|
addDependency(ident.symbol)
|
||||||
case typeTree: TypeTree =>
|
case typeTree: TypeTree =>
|
||||||
|
|
@ -136,13 +146,7 @@ final class Dependency(val global: CallbackGlobal) extends LocateClassFile {
|
||||||
deps.foreach(addDependency)
|
deps.foreach(addDependency)
|
||||||
case Template(parents, self, body) =>
|
case Template(parents, self, body) =>
|
||||||
traverseTrees(body)
|
traverseTrees(body)
|
||||||
/*
|
case MacroExpansionOf(original) if inspectedOriginalTrees.add(original) =>
|
||||||
* Some macros appear to contain themselves as original tree
|
|
||||||
* In this case, we don't need to inspect the original tree because
|
|
||||||
* we already inspected its expansion, which is equal.
|
|
||||||
* See https://issues.scala-lang.org/browse/SI-8486
|
|
||||||
*/
|
|
||||||
case MacroExpansionOf(original) if original != tree =>
|
|
||||||
this.traverse(original)
|
this.traverse(original)
|
||||||
case other => ()
|
case other => ()
|
||||||
}
|
}
|
||||||
|
|
@ -191,4 +195,4 @@ final class Dependency(val global: CallbackGlobal) extends LocateClassFile {
|
||||||
// for Scala 2.8 and 2.9 this method is provided through SymbolCompat
|
// for Scala 2.8 and 2.9 this method is provided through SymbolCompat
|
||||||
sym.enclosingTopLevelClass
|
sym.enclosingTopLevelClass
|
||||||
|
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue