-
Notifications
You must be signed in to change notification settings - Fork 118
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Move Analyze and ClassToAPI specifications
The b0a8a91 merge commit didn't resolve merge conflicts for AnalyzeSpecification.scala and for ClassToAPISpecifaction.scala. This commit oves them to the right subprojects and adapts them to Scalatest APIs. Both specifications depend on TestCallback so it had to be moved to a subproject commonly referenced. I've moved it to the compiler-interface subproject. As a consequence, I had to add a dependency on scala-library in `test` configuration to compile TestCallback written in Scala.
- Loading branch information
1 parent
8df9757
commit ae5d0fe
Showing
6 changed files
with
112 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
86 changes: 86 additions & 0 deletions
86
...incrementalcompiler-apiinfo/src/test/scala/sbt/internal/inc/ClassToAPISpecification.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
package sbt | ||
package internal | ||
package inc | ||
|
||
import java.io.File | ||
|
||
import sbt.internal.inc.classfile.JavaCompilerForUnitTesting | ||
import sbt.internal.util.UnitSpec | ||
import xsbti.AnalysisCallback | ||
import xsbti.api.{ ClassLike, DefinitionType } | ||
|
||
class ClassToAPISpecification extends UnitSpec { | ||
|
||
"ClassToAPI" should "extract api of inner classes" in { | ||
val src = | ||
"""|class A { | ||
| class B {} | ||
|} | ||
""".stripMargin | ||
val apis = extractApisFromSrc("A.java" -> src).map(c => c.name -> c).toMap | ||
assert(apis.keySet === Set("A", "A.B")) | ||
|
||
val companionsA = apis("A") | ||
assert(companionsA.classApi.topLevel === true) | ||
assert(companionsA.objectApi.topLevel === true) | ||
|
||
val innerClassApiB = findDeclaredInnerClass(companionsA.classApi, "A.B", DefinitionType.ClassDef).get | ||
assert(innerClassApiB.structure.declared === Array.empty) | ||
assert(innerClassApiB.structure.inherited === Array.empty) | ||
|
||
val companionsB = apis("A.B") | ||
assert(companionsB.classApi.topLevel === false) | ||
assert(companionsB.objectApi.topLevel === false) | ||
assert(companionsB.classApi.structure.declared.isEmpty === false) | ||
} | ||
|
||
it should "extract a private inner class" in { | ||
val src = | ||
"""|class A { | ||
| private class B {} | ||
|} | ||
""".stripMargin | ||
val apis = extractApisFromSrc("A.java" -> src).map(c => c.name -> c).toMap | ||
assert(apis.keySet === Set("A", "A.B")) | ||
} | ||
|
||
/** | ||
* Compiles given source code using Java compiler and returns API representation | ||
* extracted by ClassToAPI class. | ||
*/ | ||
private def extractApisFromSrc(src: (String, String)): Set[Companions] = { | ||
val (Seq(tempSrcFile), analysisCallback) = JavaCompilerForUnitTesting.compileJavaSrcs(src)(readAPI) | ||
val apis = analysisCallback.apis(tempSrcFile) | ||
apis.groupBy(_.name).map((companions _).tupled).toSet | ||
} | ||
|
||
private def companions(className: String, classes: Set[ClassLike]): Companions = { | ||
assert(classes.size <= 2, s"Too many classes named $className: $classes") | ||
def isClass(c: ClassLike) = | ||
(c.definitionType == DefinitionType.Trait) || (c.definitionType == DefinitionType.ClassDef) | ||
def isModule(c: ClassLike) = | ||
(c.definitionType == DefinitionType.Module) || (c.definitionType == DefinitionType.PackageModule) | ||
// the ClassToAPI always create both class and object APIs | ||
val classApi = classes.find(isClass).get | ||
val objectApi = classes.find(isModule).get | ||
Companions(className, classApi, objectApi) | ||
} | ||
|
||
private case class Companions(name: String, classApi: ClassLike, objectApi: ClassLike) | ||
|
||
private def findDeclaredInnerClass(classApi: ClassLike, innerClassName: String, | ||
defType: DefinitionType): Option[ClassLike] = { | ||
classApi.structure.declared.collectFirst({ | ||
case c: ClassLike if c.name == innerClassName && c.definitionType == defType => c | ||
}) | ||
} | ||
|
||
def readAPI(callback: AnalysisCallback, source: File, classes: Seq[Class[_]]): Set[(String, String)] = { | ||
val (apis, inherits) = ClassToAPI.process(classes) | ||
apis.foreach(callback.api(source, _)) | ||
inherits.map { | ||
case (from: Class[_], to: Class[_]) => (from.getName, to.getName) | ||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters