javac-wrapper: get rid of TreePath because it is slow

This commit is contained in:
baratynskiy
2017-08-09 11:07:23 +03:00
committed by Alexander Baratynskiy
parent 1b0d7ff5be
commit 2dc0c55e76
20 changed files with 300 additions and 356 deletions
@@ -24,8 +24,6 @@ import com.intellij.openapi.vfs.VirtualFileManager
import com.intellij.psi.search.EverythingGlobalScope
import com.intellij.psi.search.GlobalSearchScope
import com.sun.source.tree.CompilationUnitTree
import com.sun.source.util.TreePath
import com.sun.tools.javac.api.JavacTrees
import com.sun.tools.javac.code.Flags
import com.sun.tools.javac.code.Symbol
import com.sun.tools.javac.code.Symtab
@@ -34,7 +32,6 @@ import com.sun.tools.javac.jvm.ClassReader
import com.sun.tools.javac.main.JavaCompiler
import com.sun.tools.javac.model.JavacElements
import com.sun.tools.javac.model.JavacTypes
import com.sun.tools.javac.tree.DCTree
import com.sun.tools.javac.tree.JCTree
import com.sun.tools.javac.util.Context
import com.sun.tools.javac.util.Log
@@ -126,7 +123,6 @@ class JavacWrapper(
private val names = Names.instance(context)
private val symbols = Symtab.instance(context)
private val trees = JavacTrees.instance(context)
private val elements = JavacElements.instance(context)
private val types = JavacTypes.instance(context)
private val fileObjects = fileManager.getJavaFileObjectsFromFiles(javaFiles).toJavacList()
@@ -137,15 +133,15 @@ class JavacWrapper(
val packageName = unit.packageName?.toString() ?: ""
val className = (classDeclaration as JCTree.JCClassDecl).simpleName.toString()
val classId = classId(packageName, className)
classId to TreeBasedClass(classDeclaration, trees.getPath(unit, classDeclaration), this, unit.sourceFile, classId)
classId to TreeBasedClass(classDeclaration, unit, this, classId, null)
}
}.toMap()
private val javaPackages = compilationUnits
.mapTo(hashSetOf<TreeBasedPackage>()) { unit ->
unit.packageName?.toString()?.let { packageName ->
TreeBasedPackage(packageName, this, unit.sourcefile)
} ?: TreeBasedPackage("<root>", this, unit.sourcefile)
TreeBasedPackage(packageName, this, unit)
} ?: TreeBasedPackage("<root>", this, unit)
}
.associateBy(TreeBasedPackage::fqName)
@@ -154,7 +150,7 @@ class JavacWrapper(
it.sourceFile.isNameCompatible("package-info", JavaFileObject.Kind.SOURCE) &&
it.packageName != null
}.associateBy({ FqName(it.packageName!!.toString()) }) { compilationUnit ->
compilationUnit.packageAnnotations.map { TreeBasedAnnotation(it, getTreePath(it, compilationUnit), this) }
compilationUnit.packageAnnotations/*.map { TreeBasedAnnotation(it, compilationUnit, this) }*/
}
val classifierResolver = ClassifierResolver(this)
@@ -236,7 +232,7 @@ class JavacWrapper(
.filterKeys { it.isSubpackageOf(fqName) && it != fqName }
.map { it.value }
fun getPackageAnnotationsFromSources(fqName: FqName): List<JavaAnnotation> =
fun getPackageAnnotationsFromSources(fqName: FqName): List<JCTree.JCAnnotation> =
packageSourceAnnotations[fqName] ?: emptyList()
fun findClassesFromPackage(fqName: FqName): List<JavaClass> =
@@ -261,9 +257,6 @@ class JavacWrapper(
?.map { it.name.toString() }
.orEmpty()
fun getTreePath(tree: JCTree, compilationUnit: CompilationUnitTree): TreePath =
trees.getPath(compilationUnit, tree)
fun getKotlinClassifier(classId: ClassId): JavaClass? =
kotlinClassifiersCache.getKotlinClassifier(classId)
@@ -271,11 +264,11 @@ class JavacWrapper(
fun isDeprecated(typeMirror: TypeMirror) = isDeprecated(types.asElement(typeMirror))
fun resolve(treePath: TreePath): JavaClassifier? =
classifierResolver.resolve(treePath)
fun resolve(tree: JCTree, compilationUnit: CompilationUnitTree, containingElement: JavaElement): JavaClassifier? =
classifierResolver.resolve(tree, compilationUnit, containingElement)
fun resolveField(treePath: TreePath, containingClass: JavaClass): JavaField? =
identifierResolver.resolve(treePath, containingClass)
fun resolveField(tree: JCTree, compilationUnit: CompilationUnitTree, containingClass: JavaClass): JavaField? =
identifierResolver.resolve(tree, compilationUnit, containingClass)
fun toVirtualFile(javaFileObject: JavaFileObject): VirtualFile? =
javaFileObject.toUri().let { uri ->
@@ -295,8 +288,8 @@ class JavacWrapper(
null
}
fun isDeprecatedInJavaDoc(treePath: TreePath) =
(trees.getDocCommentTree(treePath) as? DCTree.DCDocComment)?.comment?.isDeprecated ?: false
fun isDeprecatedInJavaDoc(tree: JCTree, compilationUnit: CompilationUnitTree) =
(compilationUnit as JCTree.JCCompilationUnit).docComments?.getCommentTree(tree)?.comment?.isDeprecated == true
private inline fun <reified T> Iterable<T>.toJavacList() = JavacList.from(this)
@@ -16,14 +16,11 @@
package org.jetbrains.kotlin.javac.resolve
import com.sun.source.tree.CompilationUnitTree
import com.sun.source.tree.Tree
import com.sun.source.util.TreePath
import com.sun.tools.javac.tree.JCTree
import org.jetbrains.kotlin.javac.JavacWrapper
import org.jetbrains.kotlin.javac.wrappers.trees.TreeBasedClass
import org.jetbrains.kotlin.javac.wrappers.trees.TreeBasedTypeParameter
import org.jetbrains.kotlin.load.java.structure.JavaClass
import org.jetbrains.kotlin.load.java.structure.JavaClassifier
import org.jetbrains.kotlin.load.java.structure.*
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
@@ -33,14 +30,14 @@ class ClassifierResolver(private val javac: JavacWrapper) {
private val cache = hashMapOf<Tree, JavaClassifier?>()
private val beingResolved = hashSetOf<Tree>()
fun resolve(treePath: TreePath): JavaClassifier? = with (treePath) {
if (cache.containsKey(leaf)) return cache[leaf]
if (treePath.leaf in beingResolved) return null
beingResolved(treePath.leaf)
fun resolve(tree: Tree, unit: CompilationUnitTree, containingElement: JavaElement): JavaClassifier? {
if (cache.containsKey(tree)) return cache[tree]
if (tree in beingResolved) return null
beingResolved(tree)
return tryToResolve().apply {
cache[leaf] = this
removeBeingResolved(treePath.leaf)
return tryToResolve2(tree, unit, containingElement).apply {
cache[tree] = this
removeBeingResolved(tree)
}
}
@@ -89,30 +86,27 @@ class ClassifierResolver(private val javac: JavacWrapper) {
return pathSegments.apply { add(builder.toString()) }
}
private fun TreePath.tryToResolve(): JavaClassifier? {
val pathSegments = pathSegments(leaf.toString())
private fun tryToResolve2(tree: Tree, unit: CompilationUnitTree, containingElement: JavaElement): JavaClassifier? {
val pathSegments = pathSegments(tree.toString())
val containingClass = when (containingElement) {
is JavaClass -> containingElement
is JavaTypeParameterListOwner -> {
val identifier = Name.identifier(pathSegments.first())
containingElement.typeParameters.find { it.name == identifier }?.let { return it }
(containingElement as JavaMember).containingClass
}
else -> throw UnsupportedOperationException()
}
return tryToGetTypeParameterFromMethod()?.let { return it } ?:
createResolutionScope(this).findClass(pathSegments.first(), pathSegments)
return CurrentClassAndInnerScope(javac, unit, containingClass).findClass(pathSegments.first(), pathSegments)
}
private fun TreePath.tryToGetTypeParameterFromMethod(): TreeBasedTypeParameter? =
(find { it is JCTree.JCMethodDecl } as? JCTree.JCMethodDecl)
?.typarams?.find { it.name.toString() == leaf.toString() }
?.let {
TreeBasedTypeParameter(it,
javac.getTreePath(it, compilationUnit),
javac)
}
private fun createResolutionScope(treePath: TreePath): Scope = CurrentClassAndInnerScope(javac, treePath)
}
private abstract class Scope(protected val javac: JavacWrapper,
protected val treePath: TreePath) {
protected val compilationUnit: CompilationUnitTree) {
protected val helper = ResolveHelper(javac, treePath)
protected val helper = ResolveHelper(javac, compilationUnit)
abstract val parent: Scope?
@@ -120,7 +114,8 @@ private abstract class Scope(protected val javac: JavacWrapper,
}
private class GlobalScope(javac: JavacWrapper, treePath: TreePath) : Scope(javac, treePath) {
private class GlobalScope(javac: JavacWrapper,
compilationUnit: CompilationUnitTree) : Scope(javac, compilationUnit) {
override val parent: Scope?
get() = null
@@ -155,10 +150,10 @@ private class GlobalScope(javac: JavacWrapper, treePath: TreePath) : Scope(javac
}
private class ImportOnDemandScope(javac: JavacWrapper,
treePath: TreePath) : Scope(javac, treePath) {
compilationUnit: CompilationUnitTree) : Scope(javac, compilationUnit) {
override val parent: Scope
get() = GlobalScope(javac, treePath)
get() = GlobalScope(javac, compilationUnit)
override fun findClass(name: String, pathSegments: List<String>): JavaClassifier? {
asteriskImports()
@@ -174,7 +169,7 @@ private class ImportOnDemandScope(javac: JavacWrapper,
}
private fun asteriskImports() =
treePath.compilationUnit.imports
compilationUnit.imports
.mapNotNull {
val fqName = it.qualifiedIdentifier.toString()
if (fqName.endsWith("*")) {
@@ -186,13 +181,13 @@ private class ImportOnDemandScope(javac: JavacWrapper,
}
private class PackageScope(javac: JavacWrapper,
treePath: TreePath) : Scope(javac, treePath) {
compilationUnit: CompilationUnitTree) : Scope(javac, compilationUnit) {
override val parent: Scope
get() = ImportOnDemandScope(javac, treePath)
get() = ImportOnDemandScope(javac, compilationUnit)
override fun findClass(name: String, pathSegments: List<String>): JavaClassifier? {
helper.findJavaOrKotlinClass(classId(treePath.compilationUnit.packageName?.toString() ?: "", name))
helper.findJavaOrKotlinClass(classId(compilationUnit.packageName?.toString() ?: "", name))
?.let { javaClass ->
return helper.getJavaClassFromPathSegments(javaClass, pathSegments)
}
@@ -203,10 +198,10 @@ private class PackageScope(javac: JavacWrapper,
}
private class SingleTypeImportScope(javac: JavacWrapper,
treePath: TreePath) : Scope(javac, treePath) {
compilationUnit: CompilationUnitTree) : Scope(javac, compilationUnit) {
override val parent: Scope
get() = PackageScope(javac, treePath)
get() = PackageScope(javac, compilationUnit)
override fun findClass(name: String, pathSegments: List<String>): JavaClassifier? {
val imports = imports(name).toSet().takeIf { it.isNotEmpty() }
@@ -219,7 +214,7 @@ private class SingleTypeImportScope(javac: JavacWrapper,
}
private fun imports(firstSegment: String) =
(treePath.compilationUnit as JCTree.JCCompilationUnit).imports
(compilationUnit as JCTree.JCCompilationUnit).imports
.mapNotNull {
val fqName = it.qualifiedIdentifier.toString()
if (fqName.endsWith(".$firstSegment")) {
@@ -227,54 +222,34 @@ private class SingleTypeImportScope(javac: JavacWrapper,
}
else null
}
}
private class CurrentClassAndInnerScope(javac: JavacWrapper,
treePath: TreePath) : Scope(javac, treePath) {
compilationUnit: CompilationUnitTree,
private val containingElement: JavaClass) : Scope(javac, compilationUnit) {
override val parent: Scope
get() = SingleTypeImportScope(javac, treePath)
get() = SingleTypeImportScope(javac, compilationUnit)
override fun findClass(name: String, pathSegments: List<String>): JavaClassifier? {
val identifier = Name.identifier(name)
treePath.enclosingClasses().forEach {
(it as? TreeBasedClass)?.typeParameters
?.find { typeParameter -> typeParameter.name == identifier }
var enclosingClass: JavaClass? = containingElement
while (enclosingClass != null) {
enclosingClass.typeParameters
.find { typeParameter -> typeParameter.name == identifier }
?.let { typeParameter -> return typeParameter }
helper.findInnerOrNested(it, identifier)?.let { javaClass -> return helper.getJavaClassFromPathSegments(javaClass, pathSegments) }
helper.findInnerOrNested(enclosingClass, identifier)?.let { javaClass -> return helper.getJavaClassFromPathSegments(javaClass, pathSegments) }
if (it.name == identifier && pathSegments.size == 1) return it
if (enclosingClass.name == identifier && pathSegments.size == 1) return enclosingClass
enclosingClass = enclosingClass.outerClass
}
return parent.findClass(name, pathSegments)
}
private fun TreePath.enclosingClasses(): List<JavaClass> {
val outerClasses = filterIsInstance<JCTree.JCClassDecl>()
.dropWhile { it.extending == leaf || leaf in it.implementing }
.asReversed()
.map { it.simpleName.toString() }
val packageName = compilationUnit.packageName?.toString() ?: ""
val outermostClassName = outerClasses.firstOrNull() ?: return emptyList()
val outermostClassId = classId(packageName, outermostClassName)
var outermostClass = javac.findClass(outermostClassId) ?: return emptyList()
val classes = arrayListOf<JavaClass>()
classes.add(outermostClass)
for (it in outerClasses.drop(1)) {
outermostClass = outermostClass.findInnerClass(Name.identifier(it))
?: throw AssertionError("Couldn't find a class ($it) that is surely defined in ${outermostClass.fqName?.asString()}")
classes.add(outermostClass)
}
return classes.reversed()
}
}
fun classId(packageName: String = "", className: String) = ClassId(FqName(packageName), Name.identifier(className))
@@ -16,7 +16,7 @@
package org.jetbrains.kotlin.javac.resolve
import com.sun.source.util.TreePath
import com.sun.source.tree.CompilationUnitTree
import com.sun.tools.javac.code.TypeTag
import com.sun.tools.javac.tree.JCTree
import org.jetbrains.kotlin.javac.JavacWrapper
@@ -25,7 +25,7 @@ import kotlin.experimental.inv
class ConstantEvaluator(private val containingClass: JavaClass,
private val javac: JavacWrapper,
private val treePath: TreePath) {
private val compilationUnit: CompilationUnitTree) {
fun getValue(expr: JCTree.JCExpression): Any? {
return when (expr) {
is JCTree.JCLiteral -> {
@@ -35,7 +35,7 @@ class ConstantEvaluator(private val containingClass: JavaClass,
else expr.value
}
is JCTree.JCIdent,
is JCTree.JCFieldAccess -> javac.resolveField(javac.getTreePath(expr, treePath.compilationUnit), containingClass)?.initializerValue
is JCTree.JCFieldAccess -> javac.resolveField(expr, compilationUnit, containingClass)?.initializerValue
is JCTree.JCBinary -> binaryInitializerValue(expr)
is JCTree.JCParens -> getValue(expr.expr)
is JCTree.JCUnary -> unaryInitializerValue(expr)
@@ -16,7 +16,8 @@
package org.jetbrains.kotlin.javac.resolve
import com.sun.source.util.TreePath
import com.sun.source.tree.CompilationUnitTree
import com.sun.source.tree.Tree
import com.sun.tools.javac.tree.JCTree
import org.jetbrains.kotlin.javac.JavacWrapper
import org.jetbrains.kotlin.load.java.structure.JavaClass
@@ -25,21 +26,19 @@ import org.jetbrains.kotlin.name.Name
class IdentifierResolver(private val javac: JavacWrapper) {
fun resolve(treePath: TreePath, containingClass: JavaClass): JavaField? {
val leaf = treePath.leaf
if (leaf is JCTree.JCIdent) {
val fieldName = Name.identifier(leaf.name.toString())
return CurrentClassAndInnerFieldScope(javac, treePath).findField(containingClass, fieldName)
fun resolve(tree: Tree, compilationUnit: CompilationUnitTree, containingClass: JavaClass): JavaField? {
if (tree is JCTree.JCIdent) {
val fieldName = Name.identifier(tree.name.toString())
return CurrentClassAndInnerFieldScope(javac, compilationUnit).findField(containingClass, fieldName)
}
else if (leaf is JCTree.JCFieldAccess) {
val javaClassTreePath = javac.getTreePath(leaf.selected, treePath.compilationUnit)
val javaClass = javac.resolve(javaClassTreePath) as? JavaClass ?: return null
else if (tree is JCTree.JCFieldAccess) {
val javaClass = javac.resolve(tree.selected, compilationUnit, containingClass) as? JavaClass ?: return null
if (javaClass is MockKotlinClassifier) {
return javaClass.findField(leaf.name.toString())
return javaClass.findField(tree.name.toString())
}
val fieldName = Name.identifier(leaf.name.toString())
return CurrentClassAndInnerFieldScope(javac, treePath, null).findField(javaClass, fieldName)
val fieldName = Name.identifier(tree.name.toString())
return CurrentClassAndInnerFieldScope(javac, compilationUnit, null).findField(javaClass, fieldName)
}
return null
@@ -48,9 +47,9 @@ class IdentifierResolver(private val javac: JavacWrapper) {
}
private abstract class FieldScope(protected val javac: JavacWrapper,
protected val treePath: TreePath) {
protected val compilationUnit: CompilationUnitTree) {
protected val helper = ResolveHelper(javac, treePath)
protected val helper = ResolveHelper(javac, compilationUnit)
abstract val parent: FieldScope?
@@ -79,7 +78,7 @@ private abstract class FieldScope(protected val javac: JavacWrapper,
}
private class StaticImportOnDemandFieldScope(javac: JavacWrapper,
treePath: TreePath) : FieldScope(javac, treePath) {
compilationUnit: CompilationUnitTree) : FieldScope(javac, compilationUnit) {
override val parent: FieldScope?
get() = null
@@ -100,7 +99,7 @@ private class StaticImportOnDemandFieldScope(javac: JavacWrapper,
}
private fun staticAsteriskImports() =
(treePath.compilationUnit as JCTree.JCCompilationUnit).imports
(compilationUnit as JCTree.JCCompilationUnit).imports
.filter { it.staticImport }
.mapNotNull {
val fqName = it.qualifiedIdentifier.toString()
@@ -113,10 +112,10 @@ private class StaticImportOnDemandFieldScope(javac: JavacWrapper,
}
private class StaticImportFieldScope(javac: JavacWrapper,
treePath: TreePath) : FieldScope(javac, treePath) {
compilationUnit: CompilationUnitTree) : FieldScope(javac, compilationUnit) {
override val parent: FieldScope
get() = StaticImportOnDemandFieldScope(javac, treePath)
get() = StaticImportOnDemandFieldScope(javac, compilationUnit)
override fun findField(javaClass: JavaClass, name: Name): JavaField? {
val staticImports = staticImports(name.asString()).toSet().takeIf { it.isNotEmpty() }
@@ -134,7 +133,7 @@ private class StaticImportFieldScope(javac: JavacWrapper,
}
private fun staticImports(fieldName: String) =
(treePath.compilationUnit as JCTree.JCCompilationUnit).imports
(compilationUnit as JCTree.JCCompilationUnit).imports
.filter { it.staticImport }
.mapNotNull {
val import = it.qualifiedIdentifier as? JCTree.JCFieldAccess
@@ -148,8 +147,8 @@ private class StaticImportFieldScope(javac: JavacWrapper,
}
private class CurrentClassAndInnerFieldScope(javac: JavacWrapper,
treePath: TreePath,
override val parent: FieldScope? = StaticImportFieldScope(javac, treePath)) : FieldScope(javac, treePath) {
compilationUnit: CompilationUnitTree,
override val parent: FieldScope? = StaticImportFieldScope(javac, compilationUnit)) : FieldScope(javac, compilationUnit) {
override fun findField(javaClass: JavaClass, name: Name): JavaField? {
javaClass.enclosingClasses().forEach {
@@ -138,8 +138,7 @@ class MockKotlinClassifier(override val classId: ClassId,
override val innerClassNames
get() = innerClasses.map(JavaClass::name)
override fun findInnerClass(name: Name) =
innerClasses.find { it.name == name }
override fun findInnerClass(name: Name) = innerClasses.find { it.name == name }
val typeParametersNumber: Int
get() = classOrObject?.typeParameters?.size ?: 0
@@ -149,51 +148,30 @@ class MockKotlinClassifier(override val classId: ClassId,
fun findField(name: String) = classOrObject?.let { javac.kotlinResolver.findField(it, name) } ?: javac.kotlinResolver.findField(ktFile, name)
override val isAbstract: Boolean
get() = throw UnsupportedOperationException("Should not be called")
override val isStatic: Boolean
get() = throw UnsupportedOperationException("Should not be called")
override val isFinal: Boolean
get() = throw UnsupportedOperationException("Should not be called")
override val typeParameters: List<JavaTypeParameter>
get() = throw UnsupportedOperationException("Should not be called")
override val outerClass: JavaClass?
get() = throw UnsupportedOperationException("Should not be called")
override val isInterface: Boolean
get() = throw UnsupportedOperationException("Should not be called")
override val isAnnotationType: Boolean
get() = throw UnsupportedOperationException("Should not be called")
override val isEnum: Boolean
get() = throw UnsupportedOperationException("Should not be called")
override val methods: Collection<JavaMethod>
get() = throw UnsupportedOperationException("Should not be called")
override val fields: Collection<JavaField>
get() = throw UnsupportedOperationException("Should not be called")
override val constructors: Collection<JavaConstructor>
get() = throw UnsupportedOperationException("Should not be called")
override val annotations
get() = throw UnsupportedOperationException("Should not be called")
override val isDeprecatedInJavaDoc: Boolean
get() = throw UnsupportedOperationException("Should not be called")
override fun findAnnotation(fqName: FqName) =
throw UnsupportedOperationException("Should not be called")
override val isAbstract get() = shouldNotBeCalled()
override val isStatic get() = shouldNotBeCalled()
override val isFinal get() = shouldNotBeCalled()
override val typeParameters get() = shouldNotBeCalled()
override val outerClass get() = shouldNotBeCalled()
override val isInterface get() = shouldNotBeCalled()
override val isAnnotationType get() = shouldNotBeCalled()
override val isEnum get() = shouldNotBeCalled()
override val methods get() = shouldNotBeCalled()
override val fields get() = shouldNotBeCalled()
override val constructors get() = shouldNotBeCalled()
override val annotations get() = shouldNotBeCalled()
override val isDeprecatedInJavaDoc get() = shouldNotBeCalled()
override fun findAnnotation(fqName: FqName) = shouldNotBeCalled()
}
class MockKotlinClassifierType(override val classifier: JavaClassifier) : JavaClassifierType {
override val typeArguments: List<JavaType>
get() = throw UnsupportedOperationException("Should not be called")
override val isRaw: Boolean
get() = throw UnsupportedOperationException("Should not be called")
override val annotations: Collection<JavaAnnotation>
get() = throw UnsupportedOperationException("Should not be called")
override val classifierQualifiedName: String
get() = throw UnsupportedOperationException("Should not be called")
override val presentableText: String
get() = throw UnsupportedOperationException("Should not be called")
override fun findAnnotation(fqName: FqName) =
throw UnsupportedOperationException("Should not be called")
override val isDeprecatedInJavaDoc: Boolean
get() = throw UnsupportedOperationException("Should not be called")
override val typeArguments get() = shouldNotBeCalled()
override val isRaw get() = shouldNotBeCalled()
override val annotations get() = shouldNotBeCalled()
override val classifierQualifiedName get() = shouldNotBeCalled()
override val presentableText get() = shouldNotBeCalled()
override fun findAnnotation(fqName: FqName) = shouldNotBeCalled()
override val isDeprecatedInJavaDoc get() = shouldNotBeCalled()
}
class MockKotlinField(private val psiField: PsiField) : JavaField {
@@ -201,30 +179,21 @@ class MockKotlinField(private val psiField: PsiField) : JavaField {
override val initializerValue: Any?
get() = (psiField.initializer as? PsiLiteralExpression)?.value
override val name: Name
get() = throw UnsupportedOperationException("Should not be called")
override val annotations: Collection<JavaAnnotation>
get() = throw UnsupportedOperationException("Should not be called")
override val isDeprecatedInJavaDoc: Boolean
get() = throw UnsupportedOperationException("Should not be called")
override val isAbstract: Boolean
get() = throw UnsupportedOperationException("Should not be called")
override val isStatic: Boolean
get() = throw UnsupportedOperationException("Should not be called")
override val isFinal: Boolean
get() = throw UnsupportedOperationException("Should not be called")
override val visibility: Visibility
get() = throw UnsupportedOperationException("Should not be called")
override val containingClass: JavaClass
get() = throw UnsupportedOperationException("Should not be called")
override val isEnumEntry: Boolean
get() = throw UnsupportedOperationException("Should not be called")
override val type: JavaType
get() = throw UnsupportedOperationException("Should not be called")
override val hasConstantNotNullInitializer: Boolean
get() = throw UnsupportedOperationException("Should not be called")
override fun findAnnotation(fqName: FqName) = throw UnsupportedOperationException("Should not be called")
override val name get() = shouldNotBeCalled()
override val annotations get() = shouldNotBeCalled()
override val isDeprecatedInJavaDoc get() = shouldNotBeCalled()
override val isAbstract get() = shouldNotBeCalled()
override val isStatic get() = shouldNotBeCalled()
override val isFinal get() = shouldNotBeCalled()
override val visibility get() = shouldNotBeCalled()
override val containingClass get() = shouldNotBeCalled()
override val isEnumEntry get() = shouldNotBeCalled()
override val type get() = shouldNotBeCalled()
override val hasConstantNotNullInitializer get() = shouldNotBeCalled()
override fun findAnnotation(fqName: FqName) = shouldNotBeCalled()
}
private fun KtClassOrObject.computeClassId(): ClassId? =
containingClassOrObject?.computeClassId()?.createNestedClassId(nameAsSafeName) ?: fqName?.let { ClassId.topLevel(it) }
containingClassOrObject?.computeClassId()?.createNestedClassId(nameAsSafeName) ?: fqName?.let { ClassId.topLevel(it) }
private fun shouldNotBeCalled(): Nothing = throw UnsupportedOperationException("Should not be called")
@@ -16,7 +16,7 @@
package org.jetbrains.kotlin.javac.resolve
import com.sun.source.util.TreePath
import com.sun.source.tree.CompilationUnitTree
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.javac.JavaClassWithClassId
import org.jetbrains.kotlin.javac.JavacWrapper
@@ -27,7 +27,7 @@ import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
internal class ResolveHelper(private val javac: JavacWrapper,
private val treePath: TreePath) {
private val compilationUnit: CompilationUnitTree) {
fun getJavaClassFromPathSegments(javaClass: JavaClass,
pathSegments: List<String>) =
@@ -83,7 +83,7 @@ internal class ResolveHelper(private val javac: JavacWrapper,
Visibilities.PRIVATE -> null
JavaVisibilities.PACKAGE_VISIBILITY -> {
val classId = (innerOrNestedClass as? JavaClassWithClassId)?.classId
if (classId?.packageFqName?.asString() == (treePath.compilationUnit.packageName?.toString() ?: "")) innerOrNestedClass else null
if (classId?.packageFqName?.asString() == (compilationUnit.packageName?.toString() ?: "")) innerOrNestedClass else null
}
else -> innerOrNestedClass
}
@@ -58,7 +58,7 @@ class SymbolBasedClass(
get() = element.getVisibility()
override val typeParameters: List<JavaTypeParameter>
get() = element.typeParameters.map { SymbolBasedTypeParameter(it, javac) }
by lazy { element.typeParameters.map { SymbolBasedTypeParameter(it, javac) } }
override val fqName: FqName
get() = FqName(element.qualifiedName.toString())
@@ -22,7 +22,6 @@ import org.jetbrains.kotlin.javac.JavacWrapper
import org.jetbrains.kotlin.load.java.structure.*
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType
import javax.lang.model.element.TypeElement
import javax.lang.model.element.TypeParameterElement
import javax.lang.model.type.*
@@ -108,8 +107,8 @@ class SymbolBasedClassifierType<out T : TypeMirror>(
override val isRaw: Boolean
get() = when {
typeMirror !is DeclaredType -> false
(typeMirror.asElement() as TypeElement).typeParameters.isEmpty() -> false
else -> typeMirror.typeArguments.isEmpty() || (typeMirror.asElement() as TypeElement).typeParameters.size != typeMirror.typeArguments.size
(classifier as? JavaClass)?.typeParameters?.isEmpty() == true -> false
else -> typeMirror.typeArguments.isEmpty() || (classifier as? JavaClass)?.typeParameters?.size != typeMirror.typeArguments.size
}
override val classifierQualifiedName: String
@@ -16,7 +16,7 @@
package org.jetbrains.kotlin.javac.wrappers.trees
import com.sun.source.util.TreePath
import com.sun.source.tree.CompilationUnitTree
import com.sun.tools.javac.tree.JCTree
import org.jetbrains.kotlin.javac.JavaClassWithClassId
import org.jetbrains.kotlin.javac.JavacWrapper
@@ -28,18 +28,18 @@ import org.jetbrains.kotlin.name.Name
class TreeBasedAnnotation(
val annotation: JCTree.JCAnnotation,
val treePath: TreePath,
val javac: JavacWrapper
val compilationUnit: CompilationUnitTree,
val javac: JavacWrapper,
val onElement: JavaElement
) : JavaElement, JavaAnnotation {
override val arguments: Collection<JavaAnnotationArgument>
get() = createAnnotationArguments(this, javac)
get() = createAnnotationArguments(this, javac, onElement)
override val classId: ClassId?
get() = (resolve() as? JavaClassWithClassId)?.classId ?: ClassId.topLevel(FqName(annotation.annotationType.toString().substringAfter("@")))
override fun resolve() =
javac.resolve(TreePath.getPath(treePath.compilationUnit, annotation.annotationType)) as? JavaClass
override fun resolve() = javac.resolve(annotation.annotationType, compilationUnit, onElement) as? JavaClass
}
@@ -51,13 +51,13 @@ class TreeBasedLiteralAnnotationArgument(name: Name,
javac: JavacWrapper) : TreeBasedAnnotationArgument(name, javac), JavaLiteralAnnotationArgument
class TreeBasedReferenceAnnotationArgument(name: Name,
private val treePath: TreePath,
private val compilationUnit: CompilationUnitTree,
private val field: JCTree.JCFieldAccess,
javac: JavacWrapper) : TreeBasedAnnotationArgument(name, javac), JavaEnumValueAnnotationArgument {
javac: JavacWrapper,
private val onElement: JavaElement) : TreeBasedAnnotationArgument(name, javac), JavaEnumValueAnnotationArgument {
override fun resolve(): JavaField? {
val newTreePath = javac.getTreePath(field.selected, treePath.compilationUnit)
val javaClass = javac.resolve(newTreePath) as? JavaClass ?: return null
val javaClass = javac.resolve(field.selected, compilationUnit, onElement) as? JavaClass ?: return null
val fieldName = field.name.toString().let { Name.identifier(it) }
return javaClass.fields.find { it.name == fieldName }
@@ -74,25 +74,28 @@ class TreeBasedArrayAnnotationArgument(val args: List<JavaAnnotationArgument>,
class TreeBasedJavaClassObjectAnnotationArgument(private val type: JCTree.JCExpression,
name: Name,
private val treePath: TreePath,
javac: JavacWrapper): TreeBasedAnnotationArgument(name, javac), JavaClassObjectAnnotationArgument {
private val compilationUnit: CompilationUnitTree,
javac: JavacWrapper,
private val onElement: JavaElement): TreeBasedAnnotationArgument(name, javac), JavaClassObjectAnnotationArgument {
override fun getReferencedType(): JavaType =
TreeBasedType.create(type, javac.getTreePath(type, treePath.compilationUnit), javac, emptyList())
TreeBasedType.create(type, compilationUnit, javac, emptyList(), onElement)
}
class TreeBasedAnnotationAsAnnotationArgument(private val annotation: JCTree.JCAnnotation,
name: Name,
private val treePath: TreePath,
javac: JavacWrapper): TreeBasedAnnotationArgument(name, javac), JavaAnnotationAsAnnotationArgument {
private val compilationUnit: CompilationUnitTree,
javac: JavacWrapper,
private val onElement: JavaElement): TreeBasedAnnotationArgument(name, javac), JavaAnnotationAsAnnotationArgument {
override fun getAnnotation(): JavaAnnotation =
TreeBasedAnnotation(annotation, javac.getTreePath(annotation, treePath.compilationUnit), javac )
TreeBasedAnnotation(annotation, compilationUnit, javac, onElement)
}
private fun createAnnotationArguments(annotation: TreeBasedAnnotation,
javac: JavacWrapper): Collection<JavaAnnotationArgument> {
javac: JavacWrapper,
onElement: JavaElement): Collection<JavaAnnotationArgument> {
val arguments = annotation.annotation.arguments
val javaClass = annotation.resolve() ?: return emptyList()
val methods = javaClass.methods
@@ -100,54 +103,56 @@ private fun createAnnotationArguments(annotation: TreeBasedAnnotation,
if (arguments.size != methods.size) return emptyList()
return methods.mapIndexedNotNull { index, it ->
createAnnotationArgument(arguments[index], it.name, annotation.treePath, javac, annotation)
createAnnotationArgument(arguments[index], it.name, annotation.compilationUnit, javac, annotation, onElement)
}
}
private fun createAnnotationArgument(argument: JCTree.JCExpression,
name: Name,
treePath: TreePath,
compilationUnit: CompilationUnitTree,
javac: JavacWrapper,
annotation: TreeBasedAnnotation): JavaAnnotationArgument? =
annotation: TreeBasedAnnotation,
onElement: JavaElement): JavaAnnotationArgument? =
when (argument) {
is JCTree.JCLiteral -> TreeBasedLiteralAnnotationArgument(name, argument.value, javac)
is JCTree.JCFieldAccess -> {
if (argument.name.contentEquals("class")) {
TreeBasedJavaClassObjectAnnotationArgument(argument.selected, name, treePath, javac)
TreeBasedJavaClassObjectAnnotationArgument(argument.selected, name, compilationUnit, javac, onElement)
} else {
TreeBasedReferenceAnnotationArgument(name, treePath, argument, javac)
TreeBasedReferenceAnnotationArgument(name, compilationUnit, argument, javac, onElement)
}
}
is JCTree.JCAssign -> createAnnotationArgument(argument.rhs, name, treePath, javac, annotation)
is JCTree.JCNewArray -> arrayAnnotationArguments(argument.elems, name, treePath, javac, annotation)
is JCTree.JCAnnotation -> TreeBasedAnnotationAsAnnotationArgument(argument, name, treePath, javac)
is JCTree.JCParens -> createAnnotationArgument(argument.expr, name, treePath, javac, annotation)
is JCTree.JCBinary -> resolveArgumentValue(argument, annotation, name, treePath, javac)
is JCTree.JCUnary -> resolveArgumentValue(argument, annotation, name, treePath, javac)
is JCTree.JCAssign -> createAnnotationArgument(argument.rhs, name, compilationUnit, javac, annotation, onElement)
is JCTree.JCNewArray -> arrayAnnotationArguments(argument.elems, name, compilationUnit, javac, annotation, onElement)
is JCTree.JCAnnotation -> TreeBasedAnnotationAsAnnotationArgument(argument, name, compilationUnit, javac, onElement)
is JCTree.JCParens -> createAnnotationArgument(argument.expr, name, compilationUnit, javac, annotation, onElement)
is JCTree.JCBinary -> resolveArgumentValue(argument, annotation, name, compilationUnit, javac)
is JCTree.JCUnary -> resolveArgumentValue(argument, annotation, name, compilationUnit, javac)
else -> null
}
private fun resolveArgumentValue(argument: JCTree.JCExpression,
annotation: TreeBasedAnnotation,
name: Name,
treePath: TreePath,
compilationUnit: CompilationUnitTree,
javac: JavacWrapper): JavaAnnotationArgument? {
val containingAnnotation = annotation.resolve() ?: return null
val evaluator = ConstantEvaluator(containingAnnotation, javac, treePath)
val evaluator = ConstantEvaluator(containingAnnotation, javac, compilationUnit)
return evaluator.getValue(argument)?.let { TreeBasedLiteralAnnotationArgument(name, it, javac) }
}
private fun arrayAnnotationArguments(values: List<JCTree.JCExpression>,
name: Name,
treePath: TreePath,
compilationUnit: CompilationUnitTree,
javac: JavacWrapper,
annotation: TreeBasedAnnotation): JavaArrayAnnotationArgument =
annotation: TreeBasedAnnotation,
onElement: JavaElement): JavaArrayAnnotationArgument =
values.mapNotNull {
if (it is JCTree.JCNewArray) {
arrayAnnotationArguments(it.elems, name, treePath, javac, annotation)
arrayAnnotationArguments(it.elems, name, compilationUnit, javac, annotation, onElement)
}
else {
createAnnotationArgument(it, name, treePath, javac, annotation)
createAnnotationArgument(it, name, compilationUnit, javac, annotation, onElement)
}
}.let { TreeBasedArrayAnnotationArgument(it, name, javac) }
@@ -18,8 +18,8 @@ package org.jetbrains.kotlin.javac.wrappers.trees
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.search.SearchScope
import com.sun.source.tree.CompilationUnitTree
import com.sun.source.tree.Tree
import com.sun.source.util.TreePath
import com.sun.tools.javac.code.Flags
import com.sun.tools.javac.tree.JCTree
import com.sun.tools.javac.tree.TreeInfo
@@ -31,28 +31,27 @@ import org.jetbrains.kotlin.load.java.structure.*
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import javax.tools.JavaFileObject
class TreeBasedClass(
tree: JCTree.JCClassDecl,
treePath: TreePath,
compilationUnit: CompilationUnitTree,
javac: JavacWrapper,
val file: JavaFileObject,
override val classId: ClassId?
) : TreeBasedElement<JCTree.JCClassDecl>(tree, treePath, javac), JavaClassWithClassId {
override val classId: ClassId?,
override val outerClass: JavaClass?
) : TreeBasedElement<JCTree.JCClassDecl>(tree, compilationUnit, javac), JavaClassWithClassId {
override val name: Name
get() = Name.identifier(tree.simpleName.toString())
override val annotations: Collection<JavaAnnotation> by lazy {
tree.annotations().map { annotation -> TreeBasedAnnotation(annotation, treePath, javac) }
tree.annotations().map { annotation -> TreeBasedAnnotation(annotation, compilationUnit, javac, this) }
}
override fun findAnnotation(fqName: FqName) =
annotations.find { it.classId?.asSingleFqName() == fqName }
override val isDeprecatedInJavaDoc: Boolean
get() = javac.isDeprecatedInJavaDoc(treePath)
get() = javac.isDeprecatedInJavaDoc(tree, compilationUnit)
override val isAbstract: Boolean
get() = tree.modifiers.isAbstract || ((isAnnotationType || isEnum) && methods.any { it.isAbstract })
@@ -68,7 +67,7 @@ class TreeBasedClass(
override val typeParameters: List<JavaTypeParameter>
get() = tree.typeParameters.map { parameter ->
TreeBasedTypeParameter(parameter, TreePath(treePath, parameter), javac)
TreeBasedTypeParameter(parameter, compilationUnit, javac, this)
}
override val fqName: FqName
@@ -78,40 +77,34 @@ class TreeBasedClass(
by lazy {
arrayListOf<JavaClassifierType>().also { list ->
if (isEnum) {
createEnumSupertype(this, javac).let { list.add(it) }
EnumSupertype(this, javac).let { list.add(it) }
}
else if (isAnnotationType) {
javac.JAVA_LANG_ANNOTATION_ANNOTATION?.let { list.add(it) }
}
tree.extending?.let {
(TreeBasedType.create(it, javac.getTreePath(it, treePath.compilationUnit), javac, emptyList()) as? JavaClassifierType)
(TreeBasedType.create(it, compilationUnit, javac, emptyList(), this) as? JavaClassifierType)
?.let { list.add(it) }
}
tree.implementing?.mapNotNull {
TreeBasedType.create(it, javac.getTreePath(it, treePath.compilationUnit), javac, emptyList()) as? JavaClassifierType
}?.let { list.addAll(it) }
if (list.isEmpty()) {
if (list.isEmpty() && !isInterface) {
javac.JAVA_LANG_OBJECT?.let { list.add(it) }
}
tree.implementing?.mapNotNullTo(list) {
TreeBasedType.create(it, compilationUnit, javac, emptyList(), this) as? JavaClassifierType
}
}
}
val innerClasses: Map<Name, TreeBasedClass> by lazy {
tree.members
.filterIsInstance(JCTree.JCClassDecl::class.java)
.map { TreeBasedClass(it, TreePath(treePath, it), javac, file, classId?.createNestedClassId(Name.identifier(it.simpleName.toString()))) }
.map { TreeBasedClass(it, compilationUnit, javac, classId?.createNestedClassId(Name.identifier(it.simpleName.toString())), this) }
.associateBy(JavaClass::name)
}
override val outerClass: JavaClass? by lazy {
(treePath.parentPath.leaf as? JCTree.JCClassDecl)?.let { classDecl ->
javac.findClass(classId!!.outerClassId!!)
?: TreeBasedClass(classDecl, treePath.parentPath, javac, file, classId.outerClassId)
}
}
override val isInterface: Boolean
get() = tree.modifiers.flags and Flags.INTERFACE.toLong() != 0L
@@ -127,25 +120,25 @@ class TreeBasedClass(
override val methods: Collection<JavaMethod>
get() = tree.members
.filter { it.kind == Tree.Kind.METHOD && !TreeInfo.isConstructor(it) }
.map { TreeBasedMethod(it as JCTree.JCMethodDecl, TreePath(treePath, it), this, javac) }
.map { TreeBasedMethod(it as JCTree.JCMethodDecl, compilationUnit,this, javac) }
override val fields: Collection<JavaField>
get() = tree.members
.filterIsInstance(JCTree.JCVariableDecl::class.java)
.map { TreeBasedField(it, TreePath(treePath, it), this, javac) }
.map { TreeBasedField(it, compilationUnit, this, javac) }
override val constructors: Collection<JavaConstructor>
get() = tree.members
.filter { member -> TreeInfo.isConstructor(member) }
.map { constructor ->
TreeBasedConstructor(constructor as JCTree.JCMethodDecl, TreePath(treePath, constructor), this, javac)
TreeBasedConstructor(constructor as JCTree.JCMethodDecl, compilationUnit, this, javac)
}
override val innerClassNames: Collection<Name>
get() = innerClasses.keys
override val virtualFile: VirtualFile? by lazy {
javac.toVirtualFile(file)
javac.toVirtualFile(compilationUnit.sourceFile)
}
override fun isFromSourceCodeInScope(scope: SearchScope): Boolean = true
@@ -154,8 +147,9 @@ class TreeBasedClass(
}
private fun createEnumSupertype(javaClass: JavaClass,
javac: JavacWrapper) = object : JavaClassifierType {
private class EnumSupertype(private val javaClass: JavaClass,
private val javac: JavacWrapper) : JavaClassifierType {
override val classifier: JavaClass?
get() = javac.JAVA_LANG_ENUM
@@ -177,7 +171,7 @@ private fun createEnumSupertype(javaClass: JavaClass,
private inner class TypeArgument : JavaClassifierType {
override val classifier: JavaClassifier?
get() = javaClass
get() = this@EnumSupertype.javaClass
override val typeArguments: List<JavaType>
get() = emptyList()
override val isRaw: Boolean
@@ -185,7 +179,7 @@ private fun createEnumSupertype(javaClass: JavaClass,
override val annotations: Collection<JavaAnnotation>
get() = emptyList()
override val classifierQualifiedName: String
get() = javaClass.fqName!!.asString()
get() = this@EnumSupertype.javaClass.fqName!!.asString()
override val presentableText: String
get() = classifierQualifiedName
override val isDeprecatedInJavaDoc: Boolean
@@ -194,5 +188,4 @@ private fun createEnumSupertype(javaClass: JavaClass,
override fun findAnnotation(fqName: FqName) = null
}
}
@@ -16,7 +16,7 @@
package org.jetbrains.kotlin.javac.wrappers.trees
import com.sun.source.util.TreePath
import com.sun.source.tree.CompilationUnitTree
import com.sun.tools.javac.tree.JCTree
import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.javac.JavacWrapper
@@ -28,10 +28,10 @@ import org.jetbrains.kotlin.name.Name
class TreeBasedConstructor(
tree: JCTree.JCMethodDecl,
treePath: TreePath,
compilationUnit: CompilationUnitTree,
containingClass: JavaClass,
javac: JavacWrapper
) : TreeBasedMember<JCTree.JCMethodDecl>(tree, treePath, containingClass, javac), JavaConstructor {
) : TreeBasedMember<JCTree.JCMethodDecl>(tree, compilationUnit, containingClass, javac), JavaConstructor {
override val name: Name
get() = Name.identifier(tree.name.toString())
@@ -49,9 +49,9 @@ class TreeBasedConstructor(
get() = tree.modifiers.visibility
override val typeParameters: List<JavaTypeParameter>
get() = tree.typeParameters.map { TreeBasedTypeParameter(it, TreePath(treePath, it), javac) }
get() = tree.typeParameters.map { TreeBasedTypeParameter(it, compilationUnit, javac, this) }
override val valueParameters: List<JavaValueParameter>
get() = tree.parameters.map { TreeBasedValueParameter(it, TreePath(treePath, it), javac) }
get() = tree.parameters.map { TreeBasedValueParameter(it, compilationUnit, javac, this) }
}
@@ -16,14 +16,14 @@
package org.jetbrains.kotlin.javac.wrappers.trees
import com.sun.source.util.TreePath
import com.sun.source.tree.CompilationUnitTree
import com.sun.tools.javac.tree.JCTree
import org.jetbrains.kotlin.javac.JavacWrapper
import org.jetbrains.kotlin.load.java.structure.JavaElement
abstract class TreeBasedElement<out T : JCTree>(
val tree: T,
val treePath: TreePath,
val compilationUnit: CompilationUnitTree,
val javac: JavacWrapper
) : JavaElement {
@@ -16,7 +16,7 @@
package org.jetbrains.kotlin.javac.wrappers.trees
import com.sun.source.util.TreePath
import com.sun.source.tree.CompilationUnitTree
import com.sun.tools.javac.code.Flags
import com.sun.tools.javac.tree.JCTree
import org.jetbrains.kotlin.descriptors.Visibilities
@@ -30,10 +30,10 @@ import org.jetbrains.kotlin.name.Name
class TreeBasedField(
tree: JCTree.JCVariableDecl,
treePath: TreePath,
compilationUnit: CompilationUnitTree,
containingClass: JavaClass,
javac: JavacWrapper
) : TreeBasedMember<JCTree.JCVariableDecl>(tree, treePath, containingClass, javac), JavaField {
) : TreeBasedMember<JCTree.JCVariableDecl>(tree, compilationUnit, containingClass, javac), JavaField {
override val name: Name
get() = Name.identifier(tree.name.toString())
@@ -54,11 +54,11 @@ class TreeBasedField(
get() = tree.modifiers.flags and Flags.ENUM.toLong() != 0L
override val type: JavaType
get() = TreeBasedType.create(tree.getType(), treePath, javac, annotations)
get() = TreeBasedType.create(tree.getType(), compilationUnit, javac, annotations, containingClass)
override val initializerValue: Any?
get() = tree.init?.let { initExpr ->
if (hasConstantNotNullInitializer) ConstantEvaluator(containingClass, javac, treePath).getValue(initExpr) else null
if (hasConstantNotNullInitializer) ConstantEvaluator(containingClass, javac, compilationUnit).getValue(initExpr) else null
}
override val hasConstantNotNullInitializer: Boolean
@@ -16,7 +16,7 @@
package org.jetbrains.kotlin.javac.wrappers.trees
import com.sun.source.util.TreePath
import com.sun.source.tree.CompilationUnitTree
import com.sun.tools.javac.tree.JCTree
import org.jetbrains.kotlin.javac.JavacWrapper
import org.jetbrains.kotlin.load.java.structure.JavaClass
@@ -25,17 +25,16 @@ import org.jetbrains.kotlin.name.FqName
abstract class TreeBasedMember<out T : JCTree>(
tree: T,
treePath: TreePath,
compilationUnit: CompilationUnitTree,
override val containingClass: JavaClass,
javac: JavacWrapper
) : TreeBasedElement<T>(tree, treePath, javac), JavaMember {
) : TreeBasedElement<T>(tree, compilationUnit, javac), JavaMember {
override val isDeprecatedInJavaDoc: Boolean
get() = javac.isDeprecatedInJavaDoc(treePath)
get() = javac.isDeprecatedInJavaDoc(tree, compilationUnit)
override val annotations: Collection<TreeBasedAnnotation> by lazy {
tree.annotations().map { TreeBasedAnnotation(it, treePath, javac) }
}
tree.annotations().map { TreeBasedAnnotation(it, compilationUnit, javac, containingClass) } }
override fun findAnnotation(fqName: FqName) =
annotations
@@ -16,7 +16,7 @@
package org.jetbrains.kotlin.javac.wrappers.trees
import com.sun.source.util.TreePath
import com.sun.source.tree.CompilationUnitTree
import com.sun.tools.javac.tree.JCTree
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.descriptors.Visibility
@@ -26,10 +26,10 @@ import org.jetbrains.kotlin.name.Name
class TreeBasedMethod(
tree: JCTree.JCMethodDecl,
treePath: TreePath,
compilationUnit: CompilationUnitTree,
containingClass: JavaClass,
javac: JavacWrapper
) : TreeBasedMember<JCTree.JCMethodDecl>(tree, treePath, containingClass, javac), JavaMethod {
) : TreeBasedMember<JCTree.JCMethodDecl>(tree, compilationUnit, containingClass, javac), JavaMethod {
override val name: Name
get() = Name.identifier(tree.name.toString())
@@ -47,13 +47,13 @@ class TreeBasedMethod(
get() = if (containingClass.isInterface) Visibilities.PUBLIC else tree.modifiers.visibility
override val typeParameters: List<JavaTypeParameter>
get() = tree.typeParameters.map { TreeBasedTypeParameter(it, TreePath(treePath, it), javac) }
get() = tree.typeParameters.map { TreeBasedTypeParameter(it, compilationUnit, javac, this) }
override val valueParameters: List<JavaValueParameter>
get() = tree.parameters.map { TreeBasedValueParameter(it, TreePath(treePath, it), javac) }
get() = tree.parameters.map { TreeBasedValueParameter(it, compilationUnit, javac, this) }
override val returnType: JavaType
get() = TreeBasedType.create(tree.returnType, treePath, javac, annotations)
get() = TreeBasedType.create(tree.returnType, compilationUnit, javac, annotations, this)
override val hasAnnotationParameterDefaultValue: Boolean
get() = tree.defaultValue != null
@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.javac.wrappers.trees
import com.intellij.openapi.vfs.VirtualFile
import com.sun.tools.javac.tree.JCTree
import org.jetbrains.kotlin.javac.JavacWrapper
import org.jetbrains.kotlin.load.java.structure.JavaAnnotation
import org.jetbrains.kotlin.load.java.structure.JavaPackage
@@ -26,7 +27,7 @@ import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import javax.tools.JavaFileObject
class TreeBasedPackage(val name: String, val javac: JavacWrapper, val file: JavaFileObject) : JavaPackage, MapBasedJavaAnnotationOwner {
class TreeBasedPackage(val name: String, val javac: JavacWrapper, val unit: JCTree.JCCompilationUnit) : JavaPackage, MapBasedJavaAnnotationOwner {
override val fqName: FqName
get() = FqName(name)
@@ -35,14 +36,14 @@ class TreeBasedPackage(val name: String, val javac: JavacWrapper, val file: Java
get() = javac.findSubPackages(fqName)
val virtualFile: VirtualFile? by lazy {
javac.toVirtualFile(file)
javac.toVirtualFile(unit.sourceFile)
}
override fun getClasses(nameFilter: (Name) -> Boolean) =
javac.findClassesFromPackage(fqName).filter { nameFilter(it.fqName!!.shortName()) }
override val annotations
get() = javac.getPackageAnnotationsFromSources(fqName)
override val annotations: Collection<JavaAnnotation>
get() = javac.getPackageAnnotationsFromSources(fqName).map { TreeBasedAnnotation(it, unit, javac, this) }
override val annotationsByFqName: Map<FqName?, JavaAnnotation> by buildLazyValueForMap()
@@ -16,37 +16,39 @@
package org.jetbrains.kotlin.javac.wrappers.trees
import com.sun.source.util.TreePath
import com.sun.source.tree.CompilationUnitTree
import com.sun.tools.javac.tree.JCTree
import org.jetbrains.kotlin.javac.JavacWrapper
import org.jetbrains.kotlin.load.java.structure.JavaAnnotation
import org.jetbrains.kotlin.load.java.structure.JavaClassifierType
import org.jetbrains.kotlin.load.java.structure.JavaElement
import org.jetbrains.kotlin.load.java.structure.JavaTypeParameter
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
class TreeBasedTypeParameter(
tree: JCTree.JCTypeParameter,
treePath: TreePath,
javac: JavacWrapper
) : TreeBasedElement<JCTree.JCTypeParameter>(tree, treePath, javac), JavaTypeParameter {
compilationUnit: CompilationUnitTree,
javac: JavacWrapper,
private val containingElement: JavaElement
) : TreeBasedElement<JCTree.JCTypeParameter>(tree, compilationUnit, javac), JavaTypeParameter {
override val name: Name
get() = Name.identifier(tree.name.toString())
override val annotations: Collection<JavaAnnotation> by lazy {
tree.annotations().map { TreeBasedAnnotation(it, treePath, javac) }
tree.annotations().map { TreeBasedAnnotation(it, compilationUnit, javac, containingElement) }
}
override fun findAnnotation(fqName: FqName) =
annotations.firstOrNull { it.classId?.asSingleFqName() == fqName }
override val isDeprecatedInJavaDoc: Boolean
get() = javac.isDeprecatedInJavaDoc(treePath)
get() = javac.isDeprecatedInJavaDoc(tree, compilationUnit)
override val upperBounds: Collection<JavaClassifierType>
get() = tree.bounds.mapNotNull {
TreeBasedType.create(it, TreePath(treePath, it), javac, emptyList()) as? JavaClassifierType
TreeBasedType.create(it, compilationUnit, javac, emptyList(), containingElement) as? JavaClassifierType
}
override fun equals(other: Any?): Boolean {
@@ -16,10 +16,11 @@
package org.jetbrains.kotlin.javac.wrappers.trees
import com.sun.source.util.TreePath
import com.sun.source.tree.CompilationUnitTree
import com.sun.tools.javac.code.Flags
import com.sun.tools.javac.tree.JCTree
import org.jetbrains.kotlin.javac.JavacWrapper
import org.jetbrains.kotlin.load.java.structure.JavaElement
import org.jetbrains.kotlin.load.java.structure.JavaType
import org.jetbrains.kotlin.load.java.structure.JavaValueParameter
import org.jetbrains.kotlin.name.FqName
@@ -27,12 +28,13 @@ import org.jetbrains.kotlin.name.Name
class TreeBasedValueParameter(
tree: JCTree.JCVariableDecl,
treePath: TreePath,
javac: JavacWrapper
) : TreeBasedElement<JCTree.JCVariableDecl>(tree, treePath, javac), JavaValueParameter {
compilationUnit: CompilationUnitTree,
javac: JavacWrapper,
private val containingElement: JavaElement
) : TreeBasedElement<JCTree.JCVariableDecl>(tree, compilationUnit, javac), JavaValueParameter {
override val annotations: Collection<TreeBasedAnnotation> by lazy {
tree.annotations().map { TreeBasedAnnotation(it, treePath, javac) }
tree.annotations().map { TreeBasedAnnotation(it, compilationUnit, javac, containingElement) }
}
override fun findAnnotation(fqName: FqName) =
@@ -41,13 +43,13 @@ class TreeBasedValueParameter(
.find { it.classId?.asSingleFqName() == fqName }
override val isDeprecatedInJavaDoc: Boolean
get() = javac.isDeprecatedInJavaDoc(treePath)
get() = javac.isDeprecatedInJavaDoc(tree, compilationUnit)
override val name: Name
get() = Name.identifier(tree.name.toString())
override val type: JavaType
get() = TreeBasedType.create(tree.getType(), treePath, javac, annotations)
get() = TreeBasedType.create(tree.getType(), compilationUnit, javac, annotations, containingElement)
override val isVararg: Boolean
get() = tree.modifiers.flags and Flags.VARARGS != 0L
@@ -16,7 +16,7 @@
package org.jetbrains.kotlin.javac.wrappers.trees
import com.sun.source.util.TreePath
import com.sun.source.tree.CompilationUnitTree
import com.sun.tools.javac.code.BoundKind
import com.sun.tools.javac.tree.JCTree
import org.jetbrains.kotlin.builtins.PrimitiveType
@@ -29,29 +29,31 @@ import javax.lang.model.type.TypeKind
abstract class TreeBasedType<out T : JCTree>(
val tree: T,
val treePath: TreePath,
val compilationUnit: CompilationUnitTree,
val javac: JavacWrapper,
private val allAnnotations: Collection<JavaAnnotation>
private val allAnnotations: Collection<JavaAnnotation>,
protected val containingElement: JavaElement
) : JavaType, JavaAnnotationOwner {
override val annotations: Collection<JavaAnnotation>
get() = allAnnotations.filterTypeAnnotations()
companion object {
fun create(tree: JCTree, treePath: TreePath,
javac: JavacWrapper, annotations: Collection<JavaAnnotation>): JavaType {
fun create(tree: JCTree, compilationUnit: CompilationUnitTree,
javac: JavacWrapper, annotations: Collection<JavaAnnotation>,
containingElement: JavaElement): JavaType {
return when (tree) {
is JCTree.JCPrimitiveTypeTree -> TreeBasedPrimitiveType(tree, javac.getTreePath(tree, treePath.compilationUnit), javac, annotations)
is JCTree.JCArrayTypeTree -> TreeBasedArrayType(tree, javac.getTreePath(tree, treePath.compilationUnit), javac, annotations)
is JCTree.JCWildcard -> TreeBasedWildcardType(tree, javac.getTreePath(tree, treePath.compilationUnit), javac, annotations)
is JCTree.JCTypeApply -> TreeBasedGenericClassifierType(tree, javac.getTreePath(tree, treePath.compilationUnit), javac, annotations)
is JCTree.JCPrimitiveTypeTree -> TreeBasedPrimitiveType(tree, compilationUnit, javac, annotations, containingElement)
is JCTree.JCArrayTypeTree -> TreeBasedArrayType(tree, compilationUnit, javac, annotations, containingElement)
is JCTree.JCWildcard -> TreeBasedWildcardType(tree, compilationUnit, javac, annotations, containingElement)
is JCTree.JCTypeApply -> TreeBasedGenericClassifierType(tree, compilationUnit, javac, annotations, containingElement)
is JCTree.JCAnnotatedType -> {
val underlyingType = tree.underlyingType
val newAnnotations = tree.annotations
.map { TreeBasedAnnotation(it, javac.getTreePath(it, treePath.compilationUnit), javac) }
create(underlyingType, javac.getTreePath(underlyingType, treePath.compilationUnit), javac, newAnnotations)
.map { TreeBasedAnnotation(it, compilationUnit, javac, containingElement) }
create(underlyingType, compilationUnit, javac, newAnnotations, containingElement)
}
is JCTree.JCExpression -> TreeBasedNonGenericClassifierType(tree, javac.getTreePath(tree, treePath.compilationUnit), javac, annotations)
is JCTree.JCExpression -> TreeBasedNonGenericClassifierType(tree, compilationUnit, javac, annotations, containingElement)
else -> throw UnsupportedOperationException("Unsupported type: $tree")
}
}
@@ -72,10 +74,11 @@ abstract class TreeBasedType<out T : JCTree>(
class TreeBasedPrimitiveType(
tree: JCTree.JCPrimitiveTypeTree,
treePath: TreePath,
compilationUnit: CompilationUnitTree,
javac: JavacWrapper,
allAnnotations: Collection<JavaAnnotation>
) : TreeBasedType<JCTree.JCPrimitiveTypeTree>(tree, treePath, javac, allAnnotations), JavaPrimitiveType {
allAnnotations: Collection<JavaAnnotation>,
containingElement: JavaElement
) : TreeBasedType<JCTree.JCPrimitiveTypeTree>(tree, compilationUnit, javac, allAnnotations, containingElement), JavaPrimitiveType {
override val type: PrimitiveType?
get() = if (tree.primitiveTypeKind == TypeKind.VOID) {
@@ -89,25 +92,27 @@ class TreeBasedPrimitiveType(
class TreeBasedArrayType(
tree: JCTree.JCArrayTypeTree,
treePath: TreePath,
compilationUnit: CompilationUnitTree,
javac: JavacWrapper,
allAnnotations: Collection<JavaAnnotation>
) : TreeBasedType<JCTree.JCArrayTypeTree>(tree, treePath, javac, allAnnotations), JavaArrayType {
allAnnotations: Collection<JavaAnnotation>,
containingElement: JavaElement
) : TreeBasedType<JCTree.JCArrayTypeTree>(tree, compilationUnit, javac, allAnnotations, containingElement), JavaArrayType {
override val componentType: JavaType
get() = create(tree.elemtype, treePath, javac, annotations)
get() = create(tree.elemtype, compilationUnit, javac, annotations, containingElement)
}
class TreeBasedWildcardType(
tree: JCTree.JCWildcard,
treePath: TreePath,
compilationUnit: CompilationUnitTree,
javac: JavacWrapper,
allAnnotations: Collection<JavaAnnotation>
) : TreeBasedType<JCTree.JCWildcard>(tree, treePath, javac, allAnnotations), JavaWildcardType {
allAnnotations: Collection<JavaAnnotation>,
containingElement: JavaElement
) : TreeBasedType<JCTree.JCWildcard>(tree, compilationUnit, javac, allAnnotations, containingElement), JavaWildcardType {
override val bound: JavaType?
get() = tree.bound?.let { create(it, treePath, javac, annotations) }
get() = tree.bound?.let { create(it, compilationUnit, javac, annotations, containingElement) }
override val isExtends: Boolean
get() = tree.kind.kind == BoundKind.EXTENDS
@@ -116,16 +121,17 @@ class TreeBasedWildcardType(
sealed class TreeBasedClassifierType<out T : JCTree>(
tree: T,
treePath: TreePath,
compilationUnit: CompilationUnitTree,
javac: JavacWrapper,
allAnnotations: Collection<JavaAnnotation>
) : TreeBasedType<T>(tree, treePath, javac, allAnnotations), JavaClassifierType {
allAnnotations: Collection<JavaAnnotation>,
containingElement: JavaElement
) : TreeBasedType<T>(tree, compilationUnit, javac, allAnnotations, containingElement), JavaClassifierType {
override val classifier: JavaClassifier?
by lazy { javac.resolve(treePath) }
by lazy { javac.resolve(tree, compilationUnit, containingElement) }
override val classifierQualifiedName: String
get() = (classifier as? JavaClass)?.fqName?.asString() ?: treePath.leaf.toString().substringBefore("<")
get() = (classifier as? JavaClass)?.fqName?.asString() ?: tree.toString().substringBefore("<")
override val presentableText: String
get() = classifierQualifiedName
@@ -137,7 +143,7 @@ sealed class TreeBasedClassifierType<out T : JCTree>(
tree = tree.clazz
}
if (tree is JCTree.JCFieldAccess) {
val enclosingType = TreeBasedType.create(tree.selected, treePath, javac, annotations)
val enclosingType = TreeBasedType.create(tree.selected, compilationUnit, javac, annotations, containingElement)
return (enclosingType as? JavaClassifierType)?.typeArguments ?: emptyList()
}
else {
@@ -158,16 +164,6 @@ sealed class TreeBasedClassifierType<out T : JCTree>(
}
}
private val typeParameter: JCTree.JCTypeParameter?
get() = treePath.flatMap {
when (it) {
is JCTree.JCClassDecl -> it.typarams
is JCTree.JCMethodDecl -> it.typarams
else -> emptyList<JCTree.JCTypeParameter>()
}
}
.find { it.toString().substringBefore(" ") == treePath.leaf.toString() }
}
class TreeBasedTypeParameterType(override val classifier: JavaTypeParameter) : JavaClassifierType {
@@ -195,10 +191,11 @@ class TreeBasedTypeParameterType(override val classifier: JavaTypeParameter) : J
class TreeBasedNonGenericClassifierType(
tree: JCTree.JCExpression,
treePath: TreePath,
compilationUnit: CompilationUnitTree,
javac: JavacWrapper,
annotations: Collection<JavaAnnotation>
) : TreeBasedClassifierType<JCTree.JCExpression>(tree, treePath, javac, annotations) {
annotations: Collection<JavaAnnotation>,
containingElement: JavaElement
) : TreeBasedClassifierType<JCTree.JCExpression>(tree, compilationUnit, javac, annotations, containingElement) {
override val isRaw: Boolean
get() = (classifier as? MockKotlinClassifier)?.hasTypeParameters
@@ -209,16 +206,17 @@ class TreeBasedNonGenericClassifierType(
class TreeBasedGenericClassifierType(
tree: JCTree.JCTypeApply,
treePath: TreePath,
compilationUnit: CompilationUnitTree,
javac: JavacWrapper,
annotations: Collection<JavaAnnotation>
) : TreeBasedClassifierType<JCTree.JCTypeApply>(tree, treePath, javac, annotations) {
annotations: Collection<JavaAnnotation>,
containingElement: JavaElement
) : TreeBasedClassifierType<JCTree.JCTypeApply>(tree, compilationUnit, javac, annotations, containingElement) {
override val classifier: JavaClassifier?
by lazy {
val newTree = tree.clazz
if (newTree is JCTree.JCAnnotatedType) {
javac.resolve(javac.getTreePath(newTree.underlyingType, treePath.compilationUnit))
javac.resolve(newTree.underlyingType, compilationUnit, containingElement)
}
else super.classifier
}
@@ -226,14 +224,14 @@ class TreeBasedGenericClassifierType(
override val annotations: Collection<JavaAnnotation>
get() {
val newTree = tree.clazz
return (newTree as? JCTree.JCAnnotatedType)?.annotations?.map { TreeBasedAnnotation(it, javac.getTreePath(it, treePath.compilationUnit), javac) }
return (newTree as? JCTree.JCAnnotatedType)?.annotations?.map { TreeBasedAnnotation(it, compilationUnit, javac, containingElement) }
?.toMutableList<JavaAnnotation>()
?.apply { addAll(super.annotations) }
?: super.annotations
}
override val typeArguments: List<JavaType>
get() = tree.arguments.map { create(it, treePath, javac, emptyList()) }
get() = tree.arguments.map { create(it, compilationUnit, javac, emptyList(), containingElement) }
.toMutableList()
.apply { addAll(super.typeArguments) }