Cleanup code: JavacWrapper
This commit is contained in:
@@ -58,16 +58,16 @@ import javax.tools.StandardLocation
|
|||||||
import com.sun.tools.javac.util.List as JavacList
|
import com.sun.tools.javac.util.List as JavacList
|
||||||
|
|
||||||
class JavacWrapper(
|
class JavacWrapper(
|
||||||
javaFiles: Collection<File>,
|
javaFiles: Collection<File>,
|
||||||
kotlinFiles: Collection<KtFile>,
|
kotlinFiles: Collection<KtFile>,
|
||||||
arguments: Array<String>?,
|
arguments: Array<String>?,
|
||||||
jvmClasspathRoots: List<File>,
|
jvmClasspathRoots: List<File>,
|
||||||
bootClasspath: List<File>?,
|
bootClasspath: List<File>?,
|
||||||
sourcePath: List<File>?,
|
sourcePath: List<File>?,
|
||||||
val kotlinResolver: JavacWrapperKotlinResolver,
|
val kotlinResolver: JavacWrapperKotlinResolver,
|
||||||
private val compileJava: Boolean,
|
private val compileJava: Boolean,
|
||||||
private val outputDirectory: File?,
|
private val outputDirectory: File?,
|
||||||
private val context: Context
|
private val context: Context
|
||||||
) : Closeable {
|
) : Closeable {
|
||||||
private val localFileSystem = VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.FILE_PROTOCOL)!!
|
private val localFileSystem = VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.FILE_PROTOCOL)!!
|
||||||
private val jarFileSystem = VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.JAR_PROTOCOL)!!
|
private val jarFileSystem = VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.JAR_PROTOCOL)!!
|
||||||
@@ -77,9 +77,9 @@ class JavacWrapper(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun createCommonClassifierType(classId: ClassId) =
|
private fun createCommonClassifierType(classId: ClassId) =
|
||||||
findClassInSymbols(classId)?.let {
|
findClassInSymbols(classId)?.let {
|
||||||
SymbolBasedClassifierType(it.element.asType(), this)
|
SymbolBasedClassifierType(it.element.asType(), this)
|
||||||
}
|
}
|
||||||
|
|
||||||
val JAVA_LANG_OBJECT by lazy {
|
val JAVA_LANG_OBJECT by lazy {
|
||||||
createCommonClassifierType(classId("java.lang", "Object"))
|
createCommonClassifierType(classId("java.lang", "Object"))
|
||||||
@@ -138,20 +138,20 @@ class JavacWrapper(
|
|||||||
}.toMap()
|
}.toMap()
|
||||||
|
|
||||||
private val javaPackages = compilationUnits
|
private val javaPackages = compilationUnits
|
||||||
.mapTo(hashSetOf<TreeBasedPackage>()) { unit ->
|
.mapTo(hashSetOf<TreeBasedPackage>()) { unit ->
|
||||||
unit.packageName?.toString()?.let { packageName ->
|
unit.packageName?.toString()?.let { packageName ->
|
||||||
TreeBasedPackage(packageName, this, unit)
|
TreeBasedPackage(packageName, this, unit)
|
||||||
} ?: TreeBasedPackage("<root>", this, unit)
|
} ?: TreeBasedPackage("<root>", this, unit)
|
||||||
}
|
}
|
||||||
.associateBy(TreeBasedPackage::fqName)
|
.associateBy(TreeBasedPackage::fqName)
|
||||||
|
|
||||||
private val packageSourceAnnotations = compilationUnits
|
private val packageSourceAnnotations = compilationUnits
|
||||||
.filter {
|
.filter {
|
||||||
it.sourceFile.isNameCompatible("package-info", JavaFileObject.Kind.SOURCE) &&
|
it.sourceFile.isNameCompatible("package-info", JavaFileObject.Kind.SOURCE) &&
|
||||||
it.packageName != null
|
it.packageName != null
|
||||||
}.associateBy({ FqName(it.packageName!!.toString()) }) { compilationUnit ->
|
}.associateBy({ FqName(it.packageName!!.toString()) }) { compilationUnit ->
|
||||||
compilationUnit.packageAnnotations
|
compilationUnit.packageAnnotations
|
||||||
}
|
}
|
||||||
|
|
||||||
private val classifierResolver = ClassifierResolver(this)
|
private val classifierResolver = ClassifierResolver(this)
|
||||||
private val identifierResolver = IdentifierResolver(this)
|
private val identifierResolver = IdentifierResolver(this)
|
||||||
@@ -167,8 +167,10 @@ class JavacWrapper(
|
|||||||
if (javaFilesNumber == 0) return true
|
if (javaFilesNumber == 0) return true
|
||||||
|
|
||||||
fileManager.setClassPathForCompilation(outDir)
|
fileManager.setClassPathForCompilation(outDir)
|
||||||
context.get(Log.outKey)?.println("Compiling $javaFilesNumber Java source files" +
|
context.get(Log.outKey)?.println(
|
||||||
" to [${fileManager.getLocation(StandardLocation.CLASS_OUTPUT)?.firstOrNull()?.path}]")
|
"Compiling $javaFilesNumber Java source files" +
|
||||||
|
" to [${fileManager.getLocation(StandardLocation.CLASS_OUTPUT)?.firstOrNull()?.path}]"
|
||||||
|
)
|
||||||
compile(fileObjects)
|
compile(fileObjects)
|
||||||
errorCount() == 0
|
errorCount() == 0
|
||||||
}
|
}
|
||||||
@@ -225,21 +227,21 @@ class JavacWrapper(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun findSubPackages(fqName: FqName): List<JavaPackage> =
|
fun findSubPackages(fqName: FqName): List<JavaPackage> =
|
||||||
symbols.packages
|
symbols.packages
|
||||||
.filterKeys { it.toString().startsWith("$fqName.") }
|
.filterKeys { it.toString().startsWith("$fqName.") }
|
||||||
.map { SymbolBasedPackage(it.value, this) } +
|
.map { SymbolBasedPackage(it.value, this) } +
|
||||||
javaPackages
|
javaPackages
|
||||||
.filterKeys { it.isSubpackageOf(fqName) && it != fqName }
|
.filterKeys { it.isSubpackageOf(fqName) && it != fqName }
|
||||||
.map { it.value }
|
.map { it.value }
|
||||||
|
|
||||||
fun getPackageAnnotationsFromSources(fqName: FqName): List<JCTree.JCAnnotation> =
|
fun getPackageAnnotationsFromSources(fqName: FqName): List<JCTree.JCAnnotation> =
|
||||||
packageSourceAnnotations[fqName] ?: emptyList()
|
packageSourceAnnotations[fqName] ?: emptyList()
|
||||||
|
|
||||||
fun findClassesFromPackage(fqName: FqName): List<JavaClass> =
|
fun findClassesFromPackage(fqName: FqName): List<JavaClass> =
|
||||||
treeBasedJavaClasses
|
treeBasedJavaClasses
|
||||||
.filterKeys { it.packageFqName == fqName }
|
.filterKeys { it.packageFqName == fqName }
|
||||||
.map { treeBasedJavaClasses[it.key]!! } +
|
.map { treeBasedJavaClasses[it.key]!! } +
|
||||||
elements.getPackageElement(fqName.asString())
|
elements.getPackageElement(fqName.asString())
|
||||||
?.members()
|
?.members()
|
||||||
?.elements
|
?.elements
|
||||||
?.filterIsInstance(Symbol.ClassSymbol::class.java)
|
?.filterIsInstance(Symbol.ClassSymbol::class.java)
|
||||||
@@ -247,10 +249,10 @@ class JavacWrapper(
|
|||||||
.orEmpty()
|
.orEmpty()
|
||||||
|
|
||||||
fun knownClassNamesInPackage(fqName: FqName): Set<String> =
|
fun knownClassNamesInPackage(fqName: FqName): Set<String> =
|
||||||
treeBasedJavaClasses
|
treeBasedJavaClasses
|
||||||
.filterKeys { it.packageFqName == fqName }
|
.filterKeys { it.packageFqName == fqName }
|
||||||
.mapTo(hashSetOf()) { it.value.name.asString() } +
|
.mapTo(hashSetOf()) { it.value.name.asString() } +
|
||||||
elements.getPackageElement(fqName.asString())
|
elements.getPackageElement(fqName.asString())
|
||||||
?.members_field
|
?.members_field
|
||||||
?.elements
|
?.elements
|
||||||
?.filterIsInstance<Symbol.ClassSymbol>()
|
?.filterIsInstance<Symbol.ClassSymbol>()
|
||||||
@@ -258,45 +260,43 @@ class JavacWrapper(
|
|||||||
.orEmpty()
|
.orEmpty()
|
||||||
|
|
||||||
fun getKotlinClassifier(classId: ClassId): JavaClass? =
|
fun getKotlinClassifier(classId: ClassId): JavaClass? =
|
||||||
kotlinClassifiersCache.getKotlinClassifier(classId)
|
kotlinClassifiersCache.getKotlinClassifier(classId)
|
||||||
|
|
||||||
fun isDeprecated(element: Element) = elements.isDeprecated(element)
|
fun isDeprecated(element: Element) = elements.isDeprecated(element)
|
||||||
|
|
||||||
fun isDeprecated(typeMirror: TypeMirror) = isDeprecated(types.asElement(typeMirror))
|
fun isDeprecated(typeMirror: TypeMirror) = isDeprecated(types.asElement(typeMirror))
|
||||||
|
|
||||||
fun resolve(tree: JCTree, compilationUnit: CompilationUnitTree, containingElement: JavaElement): JavaClassifier? =
|
fun resolve(tree: JCTree, compilationUnit: CompilationUnitTree, containingElement: JavaElement): JavaClassifier? =
|
||||||
classifierResolver.resolve(tree, compilationUnit, containingElement)
|
classifierResolver.resolve(tree, compilationUnit, containingElement)
|
||||||
|
|
||||||
fun resolveField(tree: JCTree, compilationUnit: CompilationUnitTree, containingClass: JavaClass): JavaField? =
|
fun resolveField(tree: JCTree, compilationUnit: CompilationUnitTree, containingClass: JavaClass): JavaField? =
|
||||||
identifierResolver.resolve(tree, compilationUnit, containingClass)
|
identifierResolver.resolve(tree, compilationUnit, containingClass)
|
||||||
|
|
||||||
fun toVirtualFile(javaFileObject: JavaFileObject): VirtualFile? =
|
fun toVirtualFile(javaFileObject: JavaFileObject): VirtualFile? =
|
||||||
javaFileObject.toUri().let { uri ->
|
javaFileObject.toUri().let { uri ->
|
||||||
if (uri.scheme == "jar") {
|
if (uri.scheme == "jar") {
|
||||||
jarFileSystem.findFileByPath(uri.schemeSpecificPart.substring("file:".length))
|
jarFileSystem.findFileByPath(uri.schemeSpecificPart.substring("file:".length))
|
||||||
}
|
} else {
|
||||||
else {
|
localFileSystem.findFileByPath(uri.schemeSpecificPart)
|
||||||
localFileSystem.findFileByPath(uri.schemeSpecificPart)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun hasKotlinPackage(fqName: FqName) =
|
fun hasKotlinPackage(fqName: FqName) =
|
||||||
if (kotlinClassifiersCache.hasPackage(fqName)) {
|
if (kotlinClassifiersCache.hasPackage(fqName)) {
|
||||||
fqName
|
fqName
|
||||||
}
|
} else {
|
||||||
else {
|
null
|
||||||
null
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fun isDeprecatedInJavaDoc(tree: JCTree, compilationUnit: CompilationUnitTree) =
|
fun isDeprecatedInJavaDoc(tree: JCTree, compilationUnit: CompilationUnitTree) =
|
||||||
(compilationUnit as JCTree.JCCompilationUnit).docComments?.getCommentTree(tree)?.comment?.isDeprecated == true
|
(compilationUnit as JCTree.JCCompilationUnit).docComments?.getCommentTree(tree)?.comment?.isDeprecated == true
|
||||||
|
|
||||||
private inline fun <reified T> Iterable<T>.toJavacList() = JavacList.from(this)
|
private inline fun <reified T> Iterable<T>.toJavacList() = JavacList.from(this)
|
||||||
|
|
||||||
private fun findClassInSymbols(classId: ClassId): SymbolBasedClass? =
|
private fun findClassInSymbols(classId: ClassId): SymbolBasedClass? =
|
||||||
elements.getTypeElement(classId.asSingleFqName().asString())?.let { symbol ->
|
elements.getTypeElement(classId.asSingleFqName().asString())?.let { symbol ->
|
||||||
SymbolBasedClass(symbol, this, classId, symbol.classfile)
|
SymbolBasedClass(symbol, this, classId, symbol.classfile)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun findPackageInSymbols(fqName: String): SymbolBasedPackage? {
|
private fun findPackageInSymbols(fqName: String): SymbolBasedPackage? {
|
||||||
if (symbolBasedPackagesCache.containsKey(fqName)) return symbolBasedPackagesCache[fqName]
|
if (symbolBasedPackagesCache.containsKey(fqName)) return symbolBasedPackagesCache[fqName]
|
||||||
@@ -320,23 +320,23 @@ class JavacWrapper(
|
|||||||
val outDirName = getLocation(StandardLocation.CLASS_OUTPUT)?.firstOrNull()?.path ?: ""
|
val outDirName = getLocation(StandardLocation.CLASS_OUTPUT)?.firstOrNull()?.path ?: ""
|
||||||
|
|
||||||
list(StandardLocation.CLASS_OUTPUT, "", setOf(JavaFileObject.Kind.CLASS), true)
|
list(StandardLocation.CLASS_OUTPUT, "", setOf(JavaFileObject.Kind.CLASS), true)
|
||||||
.forEach { fileObject ->
|
.forEach { fileObject ->
|
||||||
val fqName = fileObject.name
|
val fqName = fileObject.name
|
||||||
.substringAfter(outDirName)
|
.substringAfter(outDirName)
|
||||||
.substringBefore(".class")
|
.substringBefore(".class")
|
||||||
.replace(File.separator, ".")
|
.replace(File.separator, ".")
|
||||||
.let { className ->
|
.let { className ->
|
||||||
if (className.startsWith(".")) className.substring(1) else className
|
if (className.startsWith(".")) className.substring(1) else className
|
||||||
}.let(names::fromString)
|
}.let(names::fromString)
|
||||||
|
|
||||||
symbols.classes[fqName]?.let { symbols.classes[fqName] = null }
|
symbols.classes[fqName]?.let { symbols.classes[fqName] = null }
|
||||||
val symbol = reader.enterClass(fqName, fileObject)
|
val symbol = reader.enterClass(fqName, fileObject)
|
||||||
|
|
||||||
(elements.getPackageOf(symbol) as? Symbol.PackageSymbol)?.let { packageSymbol ->
|
(elements.getPackageOf(symbol) as? Symbol.PackageSymbol)?.let { packageSymbol ->
|
||||||
packageSymbol.members_field?.enter(symbol)
|
packageSymbol.members_field?.enter(symbol)
|
||||||
packageSymbol.flags_field = packageSymbol.flags_field or Flags.EXISTS.toLong()
|
packageSymbol.flags_field = packageSymbol.flags_field or Flags.EXISTS.toLong()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -344,7 +344,7 @@ class JavacWrapper(
|
|||||||
val name = classId.relativeClassName.asString()
|
val name = classId.relativeClassName.asString()
|
||||||
val nameParts = name.replace("$", ".").split(".")
|
val nameParts = name.replace("$", ".").split(".")
|
||||||
var symbol = members_field?.getElementsByName(names.fromString(nameParts.first()))
|
var symbol = members_field?.getElementsByName(names.fromString(nameParts.first()))
|
||||||
?.firstOrNull() as? Symbol.ClassSymbol ?: return null
|
?.firstOrNull() as? Symbol.ClassSymbol ?: return null
|
||||||
if (nameParts.size > 1) {
|
if (nameParts.size > 1) {
|
||||||
symbol.complete()
|
symbol.complete()
|
||||||
for (it in nameParts.drop(1)) {
|
for (it in nameParts.drop(1)) {
|
||||||
@@ -354,7 +354,7 @@ class JavacWrapper(
|
|||||||
}
|
}
|
||||||
|
|
||||||
return symbol.let { SymbolBasedClass(it, this@JavacWrapper, classId, it.classfile) }
|
return symbol.let { SymbolBasedClass(it, this@JavacWrapper, classId, it.classfile) }
|
||||||
.apply { symbolBasedClassesCache[classId] = this }
|
.apply { symbolBasedClassesCache[classId] = this }
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user