javac-wrapper: constant evaluator
This commit is contained in:
committed by
Alexander Baratynskiy
parent
4f180e1292
commit
1b0d7ff5be
+1
-1
@@ -149,7 +149,7 @@ class K2JVMCompilerArguments : CommonCompilerArguments() {
|
|||||||
var useJavac: Boolean by FreezableVar(false)
|
var useJavac: Boolean by FreezableVar(false)
|
||||||
|
|
||||||
@Argument(value = "-Xcompile-java", description = "Reuse javac analysis and compile Java source files")
|
@Argument(value = "-Xcompile-java", description = "Reuse javac analysis and compile Java source files")
|
||||||
public boolean compileJava;
|
var compileJava by FreezableVar(false)
|
||||||
|
|
||||||
@Argument(
|
@Argument(
|
||||||
value = "-Xjavac-arguments",
|
value = "-Xjavac-arguments",
|
||||||
|
|||||||
@@ -253,7 +253,7 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
|
|||||||
|
|
||||||
private fun compileJavaFilesIfNeeded(environment: KotlinCoreEnvironment,
|
private fun compileJavaFilesIfNeeded(environment: KotlinCoreEnvironment,
|
||||||
arguments: K2JVMCompilerArguments): Boolean {
|
arguments: K2JVMCompilerArguments): Boolean {
|
||||||
if (arguments.useJavac) {
|
if (arguments.compileJava) {
|
||||||
return JavacWrapper.getInstance(environment.project).use { it.compile() }
|
return JavacWrapper.getInstance(environment.project).use { it.compile() }
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
|
|||||||
@@ -279,7 +279,7 @@ class KotlinCoreEnvironment private constructor(
|
|||||||
bootClasspath: List<File>? = null,
|
bootClasspath: List<File>? = null,
|
||||||
sourcePath: List<File>? = null
|
sourcePath: List<File>? = null
|
||||||
): Boolean {
|
): Boolean {
|
||||||
return JavacWrapperRegistrar.registerJavac(projectEnvironment.project, configuration, javaFiles, kotlinFiles, arguments, bootClasspath, sourcePath, CliLightClassGenerationSupport(project))
|
return JavacWrapperRegistrar.registerJavac(projectEnvironment.project, configuration, javaFiles, kotlinFiles, arguments, bootClasspath, sourcePath, LightClassGenerationSupport.getInstance(project))
|
||||||
}
|
}
|
||||||
|
|
||||||
private val applicationEnvironment: CoreApplicationEnvironment
|
private val applicationEnvironment: CoreApplicationEnvironment
|
||||||
|
|||||||
+10
-2
@@ -17,8 +17,9 @@
|
|||||||
package org.jetbrains.kotlin.cli.jvm.javac
|
package org.jetbrains.kotlin.cli.jvm.javac
|
||||||
|
|
||||||
import com.intellij.psi.PsiClass
|
import com.intellij.psi.PsiClass
|
||||||
|
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
|
||||||
import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
||||||
import org.jetbrains.kotlin.cli.jvm.compiler.CliLightClassGenerationSupport
|
import org.jetbrains.kotlin.asJava.findFacadeClass
|
||||||
import org.jetbrains.kotlin.javac.JavacWrapperKotlinResolver
|
import org.jetbrains.kotlin.javac.JavacWrapperKotlinResolver
|
||||||
import org.jetbrains.kotlin.javac.resolve.MockKotlinField
|
import org.jetbrains.kotlin.javac.resolve.MockKotlinField
|
||||||
import org.jetbrains.kotlin.load.java.structure.JavaField
|
import org.jetbrains.kotlin.load.java.structure.JavaField
|
||||||
@@ -26,8 +27,9 @@ import org.jetbrains.kotlin.name.ClassId
|
|||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||||
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
|
|
||||||
class JavacWrapperKotlinResolverImpl(private val lightClassGenerationSupport: CliLightClassGenerationSupport) : JavacWrapperKotlinResolver {
|
class JavacWrapperKotlinResolverImpl(private val lightClassGenerationSupport: LightClassGenerationSupport) : JavacWrapperKotlinResolver {
|
||||||
|
|
||||||
private val cache = hashMapOf<KtClassOrObject, KtLightClass>()
|
private val cache = hashMapOf<KtClassOrObject, KtLightClass>()
|
||||||
|
|
||||||
@@ -44,6 +46,12 @@ class JavacWrapperKotlinResolverImpl(private val lightClassGenerationSupport: Cl
|
|||||||
return lightClass.allFields.find { it.name == name}?.let(::MockKotlinField)
|
return lightClass.allFields.find { it.name == name}?.let(::MockKotlinField)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun findField(ktFile: KtFile?, name: String): JavaField? {
|
||||||
|
val lightClass = ktFile?.findFacadeClass() ?: return null
|
||||||
|
|
||||||
|
return lightClass.allFields.find { it.name == name}?.let(::MockKotlinField)
|
||||||
|
}
|
||||||
|
|
||||||
private fun KtClassOrObject.getLightClass(): KtLightClass? =
|
private fun KtClassOrObject.getLightClass(): KtLightClass? =
|
||||||
cache[this] ?: lightClassGenerationSupport.getLightClass(this)?.also { cache[this] = it }
|
cache[this] ?: lightClassGenerationSupport.getLightClass(this)?.also { cache[this] = it }
|
||||||
|
|
||||||
|
|||||||
@@ -18,9 +18,9 @@ package org.jetbrains.kotlin.cli.jvm.javac
|
|||||||
|
|
||||||
import com.intellij.mock.MockProject
|
import com.intellij.mock.MockProject
|
||||||
import com.sun.tools.javac.util.Context
|
import com.sun.tools.javac.util.Context
|
||||||
|
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
|
||||||
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
|
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
|
||||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.STRONG_WARNING
|
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.STRONG_WARNING
|
||||||
import org.jetbrains.kotlin.cli.jvm.compiler.CliLightClassGenerationSupport
|
|
||||||
import org.jetbrains.kotlin.cli.jvm.config.jvmClasspathRoots
|
import org.jetbrains.kotlin.cli.jvm.config.jvmClasspathRoots
|
||||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||||
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
||||||
@@ -40,7 +40,7 @@ object JavacWrapperRegistrar {
|
|||||||
arguments: Array<String>?,
|
arguments: Array<String>?,
|
||||||
bootClasspath: List<File>?,
|
bootClasspath: List<File>?,
|
||||||
sourcePath: List<File>?,
|
sourcePath: List<File>?,
|
||||||
lightClassGenerationSupport: CliLightClassGenerationSupport
|
lightClassGenerationSupport: LightClassGenerationSupport
|
||||||
): Boolean {
|
): Boolean {
|
||||||
val messageCollector = configuration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY)
|
val messageCollector = configuration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY)
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2017 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.javac
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.load.java.structure.impl.VirtualFileBoundJavaClass
|
||||||
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
|
|
||||||
|
interface JavaClassWithClassId : VirtualFileBoundJavaClass {
|
||||||
|
val classId: ClassId?
|
||||||
|
}
|
||||||
@@ -21,7 +21,6 @@ import com.intellij.openapi.project.Project
|
|||||||
import com.intellij.openapi.vfs.StandardFileSystems
|
import com.intellij.openapi.vfs.StandardFileSystems
|
||||||
import com.intellij.openapi.vfs.VirtualFile
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
import com.intellij.openapi.vfs.VirtualFileManager
|
import com.intellij.openapi.vfs.VirtualFileManager
|
||||||
import com.intellij.psi.CommonClassNames
|
|
||||||
import com.intellij.psi.search.EverythingGlobalScope
|
import com.intellij.psi.search.EverythingGlobalScope
|
||||||
import com.intellij.psi.search.GlobalSearchScope
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
import com.sun.source.tree.CompilationUnitTree
|
import com.sun.source.tree.CompilationUnitTree
|
||||||
@@ -80,21 +79,21 @@ class JavacWrapper(
|
|||||||
fun getInstance(project: Project): JavacWrapper = ServiceManager.getService(project, JavacWrapper::class.java)
|
fun getInstance(project: Project): JavacWrapper = ServiceManager.getService(project, JavacWrapper::class.java)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createCommonClassifierType(fqName: String) =
|
private fun createCommonClassifierType(classId: ClassId) =
|
||||||
findClassInSymbols(fqName)?.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(CommonClassNames.JAVA_LANG_OBJECT)
|
createCommonClassifierType(classId("java.lang", "Object"))
|
||||||
}
|
}
|
||||||
|
|
||||||
val JAVA_LANG_ENUM by lazy {
|
val JAVA_LANG_ENUM by lazy {
|
||||||
findClassInSymbols(CommonClassNames.JAVA_LANG_ENUM)
|
findClassInSymbols(classId("java.lang", "Enum"))
|
||||||
}
|
}
|
||||||
|
|
||||||
val JAVA_LANG_ANNOTATION_ANNOTATION by lazy {
|
val JAVA_LANG_ANNOTATION_ANNOTATION by lazy {
|
||||||
createCommonClassifierType(CommonClassNames.JAVA_LANG_ANNOTATION_ANNOTATION)
|
createCommonClassifierType(classId("java.lang.annotation", "Annotation"))
|
||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@@ -133,31 +132,15 @@ class JavacWrapper(
|
|||||||
private val fileObjects = fileManager.getJavaFileObjectsFromFiles(javaFiles).toJavacList()
|
private val fileObjects = fileManager.getJavaFileObjectsFromFiles(javaFiles).toJavacList()
|
||||||
private val compilationUnits: JavacList<JCTree.JCCompilationUnit> = fileObjects.map(javac::parse).toJavacList()
|
private val compilationUnits: JavacList<JCTree.JCCompilationUnit> = fileObjects.map(javac::parse).toJavacList()
|
||||||
|
|
||||||
private val treeBasedJavaClasses = hashMapOf<ClassId, TreeBasedClass>()
|
private val treeBasedJavaClasses = compilationUnits.flatMap { unit ->
|
||||||
|
|
||||||
private val javaClassDeclarations = compilationUnits.flatMap { unit ->
|
|
||||||
unit.typeDecls.map { classDeclaration ->
|
unit.typeDecls.map { classDeclaration ->
|
||||||
val packageName = unit.packageName?.toString() ?: ""
|
val packageName = unit.packageName?.toString() ?: ""
|
||||||
val className = (classDeclaration as JCTree.JCClassDecl).simpleName.toString()
|
val className = (classDeclaration as JCTree.JCClassDecl).simpleName.toString()
|
||||||
val classId = classId(packageName, className)
|
val classId = classId(packageName, className)
|
||||||
classId to Pair(classDeclaration, unit)
|
classId to TreeBasedClass(classDeclaration, trees.getPath(unit, classDeclaration), this, unit.sourceFile, classId)
|
||||||
}
|
}
|
||||||
}.toMap()
|
}.toMap()
|
||||||
|
|
||||||
private fun getTreeBasedClass(classId: ClassId): TreeBasedClass? {
|
|
||||||
if (treeBasedJavaClasses.containsKey(classId)) {
|
|
||||||
return treeBasedJavaClasses[classId]
|
|
||||||
}
|
|
||||||
|
|
||||||
val (classDeclaration, unit) = javaClassDeclarations[classId] ?: return null
|
|
||||||
val treeBasedClass = TreeBasedClass(classDeclaration,
|
|
||||||
trees.getPath(unit, classDeclaration),
|
|
||||||
this,
|
|
||||||
unit.sourceFile)
|
|
||||||
|
|
||||||
return treeBasedClass.apply { treeBasedJavaClasses[classId] = this }
|
|
||||||
}
|
|
||||||
|
|
||||||
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 ->
|
||||||
@@ -176,8 +159,9 @@ class JavacWrapper(
|
|||||||
|
|
||||||
val classifierResolver = ClassifierResolver(this)
|
val classifierResolver = ClassifierResolver(this)
|
||||||
private val identifierResolver = IdentifierResolver(this)
|
private val identifierResolver = IdentifierResolver(this)
|
||||||
private val kotlinClassifiersCache = KotlinClassifiersCache(if (javaFiles.isNotEmpty()) kotlinFiles else emptyList(), this)
|
private val kotlinClassifiersCache by lazy { KotlinClassifiersCache(if (javaFiles.isNotEmpty()) kotlinFiles else emptyList(), this) }
|
||||||
private val symbolBasedPackagesCache = hashMapOf<String, SymbolBasedPackage?>()
|
private val symbolBasedPackagesCache = hashMapOf<String, SymbolBasedPackage?>()
|
||||||
|
private val symbolBasedClassesCache = hashMapOf<ClassId, SymbolBasedClass>()
|
||||||
|
|
||||||
fun compile(outDir: File? = null): Boolean = with(javac) {
|
fun compile(outDir: File? = null): Boolean = with(javac) {
|
||||||
if (!compileJava) return true
|
if (!compileJava) return true
|
||||||
@@ -211,12 +195,19 @@ class JavacWrapper(
|
|||||||
return outerClass
|
return outerClass
|
||||||
}
|
}
|
||||||
|
|
||||||
getTreeBasedClass(classId)?.let { javaClass ->
|
treeBasedJavaClasses[classId]?.let { javaClass ->
|
||||||
javaClass.virtualFile?.let { if (it in scope) return javaClass }
|
javaClass.virtualFile?.let { if (it in scope) return javaClass }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (symbolBasedClassesCache.containsKey(classId)) {
|
||||||
|
val javaClass = symbolBasedClassesCache[classId]
|
||||||
|
javaClass?.virtualFile?.let { file ->
|
||||||
|
if (file in scope) return javaClass
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
findPackageInSymbols(classId.packageFqName.asString())?.let {
|
findPackageInSymbols(classId.packageFqName.asString())?.let {
|
||||||
(it.element as Symbol.PackageSymbol).findClass(classId.relativeClassName.asString())?.let { javaClass ->
|
(it.element as Symbol.PackageSymbol).findClass(classId)?.let { javaClass ->
|
||||||
javaClass.virtualFile?.let { file ->
|
javaClass.virtualFile?.let { file ->
|
||||||
if (file in scope) return javaClass
|
if (file in scope) return javaClass
|
||||||
}
|
}
|
||||||
@@ -249,20 +240,20 @@ class JavacWrapper(
|
|||||||
packageSourceAnnotations[fqName] ?: emptyList()
|
packageSourceAnnotations[fqName] ?: emptyList()
|
||||||
|
|
||||||
fun findClassesFromPackage(fqName: FqName): List<JavaClass> =
|
fun findClassesFromPackage(fqName: FqName): List<JavaClass> =
|
||||||
javaClassDeclarations
|
treeBasedJavaClasses
|
||||||
.filterKeys { it.packageFqName == fqName }
|
.filterKeys { it.packageFqName == fqName }
|
||||||
.map { getTreeBasedClass(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)
|
||||||
?.map { SymbolBasedClass(it, this, it.classfile) }
|
?.map { SymbolBasedClass(it, this, null, it.classfile) }
|
||||||
.orEmpty()
|
.orEmpty()
|
||||||
|
|
||||||
fun knownClassNamesInPackage(fqName: FqName): Set<String> =
|
fun knownClassNamesInPackage(fqName: FqName): Set<String> =
|
||||||
javaClassDeclarations
|
treeBasedJavaClasses
|
||||||
.filterKeys { it.packageFqName == fqName }
|
.filterKeys { it.packageFqName == fqName }
|
||||||
.mapTo(hashSetOf()) { it.key.shortClassName.asString() } +
|
.mapTo(hashSetOf()) { it.value.name.asString() } +
|
||||||
elements.getPackageElement(fqName.asString())
|
elements.getPackageElement(fqName.asString())
|
||||||
?.members_field
|
?.members_field
|
||||||
?.elements
|
?.elements
|
||||||
@@ -309,9 +300,9 @@ class JavacWrapper(
|
|||||||
|
|
||||||
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(fqName: String): SymbolBasedClass? =
|
private fun findClassInSymbols(classId: ClassId): SymbolBasedClass? =
|
||||||
elements.getTypeElement(fqName)?.let { symbol ->
|
elements.getTypeElement(classId.asSingleFqName().asString())?.let { symbol ->
|
||||||
SymbolBasedClass(symbol, this, symbol.classfile)
|
SymbolBasedClass(symbol, this, classId, symbol.classfile)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun findPackageInSymbols(fqName: String): SymbolBasedPackage? {
|
private fun findPackageInSymbols(fqName: String): SymbolBasedPackage? {
|
||||||
@@ -356,7 +347,8 @@ class JavacWrapper(
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Symbol.PackageSymbol.findClass(name: String): SymbolBasedClass? {
|
private fun Symbol.PackageSymbol.findClass(classId: ClassId): SymbolBasedClass? {
|
||||||
|
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
|
||||||
@@ -368,7 +360,8 @@ class JavacWrapper(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return symbol.let { SymbolBasedClass(it, this@JavacWrapper, it.classfile) }
|
return symbol.let { SymbolBasedClass(it, this@JavacWrapper, classId, it.classfile) }
|
||||||
|
.apply { symbolBasedClassesCache[classId] = this }
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -19,9 +19,12 @@ package org.jetbrains.kotlin.javac
|
|||||||
import org.jetbrains.kotlin.load.java.structure.JavaField
|
import org.jetbrains.kotlin.load.java.structure.JavaField
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||||
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
|
|
||||||
interface JavacWrapperKotlinResolver {
|
interface JavacWrapperKotlinResolver {
|
||||||
fun resolveSupertypes(classOrObject: KtClassOrObject): List<ClassId>
|
fun resolveSupertypes(classOrObject: KtClassOrObject): List<ClassId>
|
||||||
|
|
||||||
fun findField(classOrObject: KtClassOrObject, name: String): JavaField?
|
fun findField(classOrObject: KtClassOrObject, name: String): JavaField?
|
||||||
|
|
||||||
|
fun findField(ktFile: KtFile?, name: String): JavaField?
|
||||||
}
|
}
|
||||||
+19
-20
@@ -238,7 +238,7 @@ private class CurrentClassAndInnerScope(javac: JavacWrapper,
|
|||||||
|
|
||||||
override fun findClass(name: String, pathSegments: List<String>): JavaClassifier? {
|
override fun findClass(name: String, pathSegments: List<String>): JavaClassifier? {
|
||||||
val identifier = Name.identifier(name)
|
val identifier = Name.identifier(name)
|
||||||
treePath.enclosingClasses.forEach {
|
treePath.enclosingClasses().forEach {
|
||||||
(it as? TreeBasedClass)?.typeParameters
|
(it as? TreeBasedClass)?.typeParameters
|
||||||
?.find { typeParameter -> typeParameter.name == identifier }
|
?.find { typeParameter -> typeParameter.name == identifier }
|
||||||
?.let { typeParameter -> return typeParameter }
|
?.let { typeParameter -> return typeParameter }
|
||||||
@@ -251,31 +251,30 @@ private class CurrentClassAndInnerScope(javac: JavacWrapper,
|
|||||||
return parent.findClass(name, pathSegments)
|
return parent.findClass(name, pathSegments)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val TreePath.enclosingClasses: List<JavaClass>
|
private fun TreePath.enclosingClasses(): List<JavaClass> {
|
||||||
get() {
|
val outerClasses = filterIsInstance<JCTree.JCClassDecl>()
|
||||||
val outerClasses = filterIsInstance<JCTree.JCClassDecl>()
|
.dropWhile { it.extending == leaf || leaf in it.implementing }
|
||||||
.dropWhile { it.extending == leaf || leaf in it.implementing }
|
.asReversed()
|
||||||
.asReversed()
|
.map { it.simpleName.toString() }
|
||||||
.map { it.simpleName.toString() }
|
|
||||||
|
|
||||||
val packageName = compilationUnit.packageName?.toString() ?: ""
|
val packageName = compilationUnit.packageName?.toString() ?: ""
|
||||||
val outermostClassName = outerClasses.firstOrNull() ?: return emptyList()
|
val outermostClassName = outerClasses.firstOrNull() ?: return emptyList()
|
||||||
|
|
||||||
val outermostClassId = classId(packageName, outermostClassName)
|
val outermostClassId = classId(packageName, outermostClassName)
|
||||||
var outermostClass = javac.findClass(outermostClassId) ?: return emptyList()
|
var outermostClass = javac.findClass(outermostClassId) ?: return emptyList()
|
||||||
|
|
||||||
val classes = arrayListOf<JavaClass>()
|
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)
|
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()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return classes.reversed()
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun classId(packageName: String = "", className: String) = ClassId(FqName(packageName), Name.identifier(className))
|
fun classId(packageName: String = "", className: String) = ClassId(FqName(packageName), Name.identifier(className))
|
||||||
@@ -0,0 +1,286 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2017 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.javac.resolve
|
||||||
|
|
||||||
|
import com.sun.source.util.TreePath
|
||||||
|
import com.sun.tools.javac.code.TypeTag
|
||||||
|
import com.sun.tools.javac.tree.JCTree
|
||||||
|
import org.jetbrains.kotlin.javac.JavacWrapper
|
||||||
|
import org.jetbrains.kotlin.load.java.structure.JavaClass
|
||||||
|
import kotlin.experimental.inv
|
||||||
|
|
||||||
|
class ConstantEvaluator(private val containingClass: JavaClass,
|
||||||
|
private val javac: JavacWrapper,
|
||||||
|
private val treePath: TreePath) {
|
||||||
|
fun getValue(expr: JCTree.JCExpression): Any? {
|
||||||
|
return when (expr) {
|
||||||
|
is JCTree.JCLiteral -> {
|
||||||
|
if (expr.typetag == TypeTag.BOOLEAN) {
|
||||||
|
expr.value != 0
|
||||||
|
}
|
||||||
|
else expr.value
|
||||||
|
}
|
||||||
|
is JCTree.JCIdent,
|
||||||
|
is JCTree.JCFieldAccess -> javac.resolveField(javac.getTreePath(expr, treePath.compilationUnit), containingClass)?.initializerValue
|
||||||
|
is JCTree.JCBinary -> binaryInitializerValue(expr)
|
||||||
|
is JCTree.JCParens -> getValue(expr.expr)
|
||||||
|
is JCTree.JCUnary -> unaryInitializerValue(expr)
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun unaryInitializerValue(value: JCTree.JCUnary): Any? {
|
||||||
|
val argValue = getValue(value.arg)
|
||||||
|
return when (value.tag) {
|
||||||
|
JCTree.Tag.COMPL -> {
|
||||||
|
when (argValue) {
|
||||||
|
is Int -> argValue.inv()
|
||||||
|
is Long -> argValue.inv()
|
||||||
|
is Short -> argValue.inv()
|
||||||
|
is Byte -> argValue.inv()
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JCTree.Tag.NOT -> (argValue as? Boolean)?.let { !it }
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun binaryInitializerValue(value: JCTree.JCBinary): Any? {
|
||||||
|
val lhsValue = getValue(value.lhs) ?: return null
|
||||||
|
val rhsValue = getValue(value.rhs) ?: return null
|
||||||
|
|
||||||
|
return evaluateValue(lhsValue, rhsValue, value.tag)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun evaluateValue(lhsValue: Any?, rhsValue: Any?, opcode: JCTree.Tag): Any? {
|
||||||
|
if (lhsValue is String && opcode == JCTree.Tag.PLUS) return lhsValue + rhsValue
|
||||||
|
else if (lhsValue is Boolean && rhsValue is Boolean) {
|
||||||
|
return when (opcode) {
|
||||||
|
JCTree.Tag.AND -> lhsValue && rhsValue
|
||||||
|
JCTree.Tag.OR -> lhsValue || rhsValue
|
||||||
|
JCTree.Tag.EQ -> lhsValue == rhsValue
|
||||||
|
JCTree.Tag.NE -> lhsValue != rhsValue
|
||||||
|
JCTree.Tag.BITXOR -> lhsValue xor rhsValue
|
||||||
|
JCTree.Tag.BITAND -> lhsValue and rhsValue
|
||||||
|
JCTree.Tag.BITOR -> lhsValue or rhsValue
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (lhsValue is Number && rhsValue is Number) {
|
||||||
|
val isInteger = !(lhsValue is Float || lhsValue is Double || rhsValue is Float || rhsValue is Double)
|
||||||
|
val isWide = if (isInteger) {
|
||||||
|
lhsValue is Long || rhsValue is Long
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lhsValue is Double || rhsValue is Double
|
||||||
|
}
|
||||||
|
|
||||||
|
return when (opcode) {
|
||||||
|
JCTree.Tag.PLUS -> {
|
||||||
|
if (isInteger) {
|
||||||
|
if (isWide) {
|
||||||
|
lhsValue.toLong() + rhsValue.toLong()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lhsValue.toInt() + rhsValue.toInt()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (isWide) {
|
||||||
|
lhsValue.toDouble() + rhsValue.toDouble()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lhsValue.toFloat() + rhsValue.toFloat()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JCTree.Tag.MINUS -> {
|
||||||
|
if (isInteger) {
|
||||||
|
if (isWide) {
|
||||||
|
lhsValue.toLong() - rhsValue.toLong()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lhsValue.toInt() - rhsValue.toInt()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (isWide) {
|
||||||
|
lhsValue.toDouble() - rhsValue.toDouble()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lhsValue.toFloat() - rhsValue.toFloat()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JCTree.Tag.MUL -> {
|
||||||
|
if (isInteger) {
|
||||||
|
if (isWide) {
|
||||||
|
lhsValue.toLong() * rhsValue.toLong()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lhsValue.toInt() * rhsValue.toInt()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (isWide) {
|
||||||
|
lhsValue.toDouble() * rhsValue.toDouble()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lhsValue.toFloat() * rhsValue.toFloat()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JCTree.Tag.DIV -> {
|
||||||
|
if (isInteger) {
|
||||||
|
if (isWide) {
|
||||||
|
lhsValue.toLong() / rhsValue.toLong()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lhsValue.toInt() / rhsValue.toInt()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (isWide) {
|
||||||
|
lhsValue.toDouble() / rhsValue.toDouble()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lhsValue.toFloat() / rhsValue.toFloat()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JCTree.Tag.MOD -> {
|
||||||
|
if (isInteger) {
|
||||||
|
if (isWide) {
|
||||||
|
lhsValue.toLong() % rhsValue.toLong()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lhsValue.toInt() % rhsValue.toInt()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (isWide) {
|
||||||
|
lhsValue.toDouble() % rhsValue.toDouble()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lhsValue.toFloat() % rhsValue.toFloat()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JCTree.Tag.SR -> {
|
||||||
|
if (isWide) {
|
||||||
|
lhsValue.toLong() shr rhsValue.toInt()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lhsValue.toInt() shr rhsValue.toInt()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JCTree.Tag.SL -> {
|
||||||
|
if (isWide) {
|
||||||
|
lhsValue.toLong() shl rhsValue.toInt()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lhsValue.toInt() shl rhsValue.toInt()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JCTree.Tag.BITAND -> {
|
||||||
|
if (isWide) {
|
||||||
|
lhsValue.toLong() and rhsValue.toLong()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lhsValue.toInt() and rhsValue.toInt()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JCTree.Tag.BITOR -> {
|
||||||
|
if (isWide) {
|
||||||
|
lhsValue.toLong() or rhsValue.toLong()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lhsValue.toInt() or rhsValue.toInt()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JCTree.Tag.BITXOR -> {
|
||||||
|
if (isWide) {
|
||||||
|
lhsValue.toLong() xor rhsValue.toLong()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lhsValue.toInt() xor rhsValue.toInt()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JCTree.Tag.USR -> {
|
||||||
|
if (isWide) {
|
||||||
|
lhsValue.toLong() ushr rhsValue.toInt()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lhsValue.toInt() ushr rhsValue.toInt()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JCTree.Tag.EQ -> {
|
||||||
|
if (isInteger) {
|
||||||
|
lhsValue.toLong() == rhsValue.toLong()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lhsValue.toDouble() == rhsValue.toDouble()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JCTree.Tag.NE -> {
|
||||||
|
if (isInteger) {
|
||||||
|
lhsValue.toLong() != rhsValue.toLong()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lhsValue.toDouble() != rhsValue.toDouble()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JCTree.Tag.LT -> {
|
||||||
|
if (isInteger) {
|
||||||
|
lhsValue.toLong() < rhsValue.toLong()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lhsValue.toDouble() < rhsValue.toDouble()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JCTree.Tag.LE -> {
|
||||||
|
if (isInteger) {
|
||||||
|
lhsValue.toLong() <= rhsValue.toLong()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lhsValue.toDouble() <= rhsValue.toDouble()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JCTree.Tag.GT -> {
|
||||||
|
if (isInteger) {
|
||||||
|
lhsValue.toLong() > rhsValue.toLong()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lhsValue.toDouble() > rhsValue.toDouble()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JCTree.Tag.GE -> {
|
||||||
|
if (isInteger) {
|
||||||
|
lhsValue.toLong() >= rhsValue.toLong()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lhsValue.toDouble() >= rhsValue.toDouble()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else return null
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -65,7 +65,12 @@ private abstract class FieldScope(protected val javac: JavacWrapper,
|
|||||||
.mapNotNull {
|
.mapNotNull {
|
||||||
val classifier = it.classifier as? JavaClass
|
val classifier = it.classifier as? JavaClass
|
||||||
if (classifier !in checkedSupertypes) {
|
if (classifier !in checkedSupertypes) {
|
||||||
classifier?.findFieldIncludingSupertypes(name, checkedSupertypes)
|
if (classifier is MockKotlinClassifier) {
|
||||||
|
classifier.findField(name.asString())
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
classifier?.findFieldIncludingSupertypes(name, checkedSupertypes)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else null
|
else null
|
||||||
}.singleOrNull()
|
}.singleOrNull()
|
||||||
|
|||||||
+32
-17
@@ -22,6 +22,8 @@ import com.intellij.psi.PsiLiteralExpression
|
|||||||
import com.intellij.psi.search.SearchScope
|
import com.intellij.psi.search.SearchScope
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
import org.jetbrains.kotlin.descriptors.Visibility
|
import org.jetbrains.kotlin.descriptors.Visibility
|
||||||
|
import org.jetbrains.kotlin.fileClasses.javaFileFacadeFqName
|
||||||
|
import org.jetbrains.kotlin.javac.JavaClassWithClassId
|
||||||
import org.jetbrains.kotlin.javac.JavacWrapper
|
import org.jetbrains.kotlin.javac.JavacWrapper
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.load.java.JavaVisibilities
|
import org.jetbrains.kotlin.load.java.JavaVisibilities
|
||||||
@@ -29,7 +31,6 @@ import org.jetbrains.kotlin.load.java.structure.*
|
|||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
|
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
|
||||||
import org.jetbrains.kotlin.load.java.structure.impl.VirtualFileBoundJavaClass
|
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.visibilityModifierType
|
import org.jetbrains.kotlin.psi.psiUtil.visibilityModifierType
|
||||||
@@ -38,9 +39,12 @@ class KotlinClassifiersCache(sourceFiles: Collection<KtFile>,
|
|||||||
private val javac: JavacWrapper) {
|
private val javac: JavacWrapper) {
|
||||||
|
|
||||||
private val kotlinPackages = hashSetOf<FqName>()
|
private val kotlinPackages = hashSetOf<FqName>()
|
||||||
|
private val kotlinFacadeClasses = hashMapOf<ClassId, KtFile>()
|
||||||
private val kotlinClasses: Map<ClassId?, KtClassOrObject?> =
|
private val kotlinClasses: Map<ClassId?, KtClassOrObject?> =
|
||||||
sourceFiles.flatMap { ktFile ->
|
sourceFiles.flatMap { ktFile ->
|
||||||
kotlinPackages.add(ktFile.packageFqName)
|
kotlinPackages.add(ktFile.packageFqName)
|
||||||
|
val facadeFqName = ktFile.javaFileFacadeFqName
|
||||||
|
kotlinFacadeClasses[ClassId(facadeFqName.parent(), facadeFqName.shortName())] = ktFile
|
||||||
ktFile.declarations
|
ktFile.declarations
|
||||||
.filterIsInstance<KtClassOrObject>()
|
.filterIsInstance<KtClassOrObject>()
|
||||||
.map { it.computeClassId() to it }
|
.map { it.computeClassId() to it }
|
||||||
@@ -50,9 +54,11 @@ class KotlinClassifiersCache(sourceFiles: Collection<KtFile>,
|
|||||||
|
|
||||||
fun getKotlinClassifier(classId: ClassId) = classifiers[classId] ?: createClassifier(classId)
|
fun getKotlinClassifier(classId: ClassId) = classifiers[classId] ?: createClassifier(classId)
|
||||||
|
|
||||||
fun createMockKotlinClassifier(classifier: KtClassOrObject,
|
fun createMockKotlinClassifier(classifier: KtClassOrObject?,
|
||||||
|
ktFile: KtFile?,
|
||||||
classId: ClassId) = MockKotlinClassifier(classId,
|
classId: ClassId) = MockKotlinClassifier(classId,
|
||||||
classifier,
|
classifier,
|
||||||
|
ktFile,
|
||||||
this,
|
this,
|
||||||
javac)
|
javac)
|
||||||
.apply { classifiers[classId] = this }
|
.apply { classifiers[classId] = this }
|
||||||
@@ -60,11 +66,14 @@ class KotlinClassifiersCache(sourceFiles: Collection<KtFile>,
|
|||||||
fun hasPackage(packageFqName: FqName) = kotlinPackages.contains(packageFqName)
|
fun hasPackage(packageFqName: FqName) = kotlinPackages.contains(packageFqName)
|
||||||
|
|
||||||
private fun createClassifier(classId: ClassId): JavaClass? {
|
private fun createClassifier(classId: ClassId): JavaClass? {
|
||||||
|
kotlinFacadeClasses[classId]?.let {
|
||||||
|
return createMockKotlinClassifier(null, it, classId)
|
||||||
|
}
|
||||||
if (classId.isNestedClass) {
|
if (classId.isNestedClass) {
|
||||||
classifiers[classId]?.let { return it }
|
classifiers[classId]?.let { return it }
|
||||||
val pathSegments = classId.relativeClassName.pathSegments().map { it.asString() }
|
val pathSegments = classId.relativeClassName.pathSegments().map { it.asString() }
|
||||||
val outerClassId = ClassId(classId.packageFqName, Name.identifier(pathSegments.first()))
|
val outerClassId = ClassId(classId.packageFqName, Name.identifier(pathSegments.first()))
|
||||||
var outerClass: JavaClass = kotlinClasses[outerClassId]?.let { createMockKotlinClassifier(it, outerClassId) } ?: return null
|
var outerClass: JavaClass = kotlinClasses[outerClassId]?.let { createMockKotlinClassifier(it, null, outerClassId) } ?: return null
|
||||||
|
|
||||||
pathSegments.drop(1).forEach {
|
pathSegments.drop(1).forEach {
|
||||||
outerClass = outerClass.findInnerClass(Name.identifier(it)) ?: return null
|
outerClass = outerClass.findInnerClass(Name.identifier(it)) ?: return null
|
||||||
@@ -75,21 +84,25 @@ class KotlinClassifiersCache(sourceFiles: Collection<KtFile>,
|
|||||||
|
|
||||||
val kotlinClassifier = kotlinClasses[classId] ?: return null
|
val kotlinClassifier = kotlinClasses[classId] ?: return null
|
||||||
|
|
||||||
return createMockKotlinClassifier(kotlinClassifier, classId)
|
return createMockKotlinClassifier(kotlinClassifier, null, classId)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class MockKotlinClassifier(val classId: ClassId,
|
class MockKotlinClassifier(override val classId: ClassId,
|
||||||
private val classOrObject: KtClassOrObject,
|
private val classOrObject: KtClassOrObject?,
|
||||||
|
private val ktFile: KtFile?,
|
||||||
private val cache: KotlinClassifiersCache,
|
private val cache: KotlinClassifiersCache,
|
||||||
private val javac: JavacWrapper) : VirtualFileBoundJavaClass {
|
private val javac: JavacWrapper) : JavaClassWithClassId {
|
||||||
|
|
||||||
override val fqName: FqName
|
override val fqName: FqName
|
||||||
get() = classId.asSingleFqName()
|
get() = classId.asSingleFqName()
|
||||||
|
|
||||||
override val visibility: Visibility
|
override val visibility: Visibility
|
||||||
get() = when (classOrObject.visibilityModifierType()) {
|
get() = if (classOrObject == null) {
|
||||||
|
Visibilities.PUBLIC
|
||||||
|
}
|
||||||
|
else when (classOrObject.visibilityModifierType()) {
|
||||||
null, KtTokens.PUBLIC_KEYWORD -> Visibilities.PUBLIC
|
null, KtTokens.PUBLIC_KEYWORD -> Visibilities.PUBLIC
|
||||||
KtTokens.PRIVATE_KEYWORD -> Visibilities.PRIVATE
|
KtTokens.PRIVATE_KEYWORD -> Visibilities.PRIVATE
|
||||||
KtTokens.PROTECTED_KEYWORD -> Visibilities.PROTECTED
|
KtTokens.PROTECTED_KEYWORD -> Visibilities.PROTECTED
|
||||||
@@ -97,17 +110,19 @@ class MockKotlinClassifier(val classId: ClassId,
|
|||||||
}
|
}
|
||||||
|
|
||||||
override val supertypes: Collection<JavaClassifierType>
|
override val supertypes: Collection<JavaClassifierType>
|
||||||
get() = javac.kotlinResolver.resolveSupertypes(classOrObject)
|
get() = if (classOrObject == null) {
|
||||||
|
emptyList()
|
||||||
|
}
|
||||||
|
else javac.kotlinResolver.resolveSupertypes(classOrObject)
|
||||||
.mapNotNull { javac.getKotlinClassifier(it) ?: javac.findClass(it) }
|
.mapNotNull { javac.getKotlinClassifier(it) ?: javac.findClass(it) }
|
||||||
.map { MockKotlinClassifierType(it) }
|
.map { MockKotlinClassifierType(it) }
|
||||||
|
|
||||||
val innerClasses: Collection<JavaClass>
|
val innerClasses: Collection<JavaClass>
|
||||||
get() = classOrObject.declarations.filterIsInstance<KtClassOrObject>()
|
get() = classOrObject?.declarations
|
||||||
.mapNotNull { nestedClassOrObject ->
|
?.filterIsInstance<KtClassOrObject>()
|
||||||
nestedClassOrObject.computeClassId()?.let {
|
?.mapNotNull { nestedClassOrObject ->
|
||||||
cache.createMockKotlinClassifier(nestedClassOrObject, it)
|
cache.createMockKotlinClassifier(nestedClassOrObject, ktFile, classId.createNestedClassId(nestedClassOrObject.nameAsSafeName))
|
||||||
}
|
} ?: emptyList()
|
||||||
}
|
|
||||||
|
|
||||||
override val lightClassOriginKind
|
override val lightClassOriginKind
|
||||||
get() = LightClassOriginKind.SOURCE
|
get() = LightClassOriginKind.SOURCE
|
||||||
@@ -127,12 +142,12 @@ class MockKotlinClassifier(val classId: ClassId,
|
|||||||
innerClasses.find { it.name == name }
|
innerClasses.find { it.name == name }
|
||||||
|
|
||||||
val typeParametersNumber: Int
|
val typeParametersNumber: Int
|
||||||
get() = classOrObject.typeParameters.size
|
get() = classOrObject?.typeParameters?.size ?: 0
|
||||||
|
|
||||||
val hasTypeParameters: Boolean
|
val hasTypeParameters: Boolean
|
||||||
get() = typeParametersNumber > 0
|
get() = typeParametersNumber > 0
|
||||||
|
|
||||||
fun findField(name: String) = javac.kotlinResolver.findField(classOrObject, name)
|
fun findField(name: String) = classOrObject?.let { javac.kotlinResolver.findField(it, name) } ?: javac.kotlinResolver.findField(ktFile, name)
|
||||||
|
|
||||||
override val isAbstract: Boolean
|
override val isAbstract: Boolean
|
||||||
get() = throw UnsupportedOperationException("Should not be called")
|
get() = throw UnsupportedOperationException("Should not be called")
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ package org.jetbrains.kotlin.javac.resolve
|
|||||||
|
|
||||||
import com.sun.source.util.TreePath
|
import com.sun.source.util.TreePath
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
|
import org.jetbrains.kotlin.javac.JavaClassWithClassId
|
||||||
import org.jetbrains.kotlin.javac.JavacWrapper
|
import org.jetbrains.kotlin.javac.JavacWrapper
|
||||||
import org.jetbrains.kotlin.javac.wrappers.trees.computeClassId
|
|
||||||
import org.jetbrains.kotlin.load.java.JavaVisibilities
|
import org.jetbrains.kotlin.load.java.JavaVisibilities
|
||||||
import org.jetbrains.kotlin.load.java.structure.JavaClass
|
import org.jetbrains.kotlin.load.java.structure.JavaClass
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
@@ -82,7 +82,7 @@ internal class ResolveHelper(private val javac: JavacWrapper,
|
|||||||
when (innerOrNestedClass.visibility) {
|
when (innerOrNestedClass.visibility) {
|
||||||
Visibilities.PRIVATE -> null
|
Visibilities.PRIVATE -> null
|
||||||
JavaVisibilities.PACKAGE_VISIBILITY -> {
|
JavaVisibilities.PACKAGE_VISIBILITY -> {
|
||||||
val classId = (innerOrNestedClass as? MockKotlinClassifier)?.classId ?: innerOrNestedClass.computeClassId()
|
val classId = (innerOrNestedClass as? JavaClassWithClassId)?.classId
|
||||||
if (classId?.packageFqName?.asString() == (treePath.compilationUnit.packageName?.toString() ?: "")) innerOrNestedClass else null
|
if (classId?.packageFqName?.asString() == (treePath.compilationUnit.packageName?.toString() ?: "")) innerOrNestedClass else null
|
||||||
}
|
}
|
||||||
else -> innerOrNestedClass
|
else -> innerOrNestedClass
|
||||||
|
|||||||
+3
-5
@@ -36,11 +36,9 @@ open class SymbolBasedAnnotation(
|
|||||||
SymbolBasedAnnotationArgument.create(value.value, Name.identifier(key.simpleName.toString()), javac)
|
SymbolBasedAnnotationArgument.create(value.value, Name.identifier(key.simpleName.toString()), javac)
|
||||||
}
|
}
|
||||||
|
|
||||||
override val classId: ClassId?
|
override val classId: ClassId
|
||||||
get() = (annotationMirror.annotationType.asElement() as? TypeElement)?.computeClassId()
|
get() = (annotationMirror.annotationType.asElement() as TypeElement).computeClassId()!!
|
||||||
|
|
||||||
override fun resolve() = with(annotationMirror.annotationType.asElement() as Symbol.ClassSymbol) {
|
override fun resolve() = with(annotationMirror.annotationType.asElement() as Symbol.ClassSymbol) { javac.findClass(classId) }
|
||||||
SymbolBasedClass(this, javac, classfile)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
+32
-24
@@ -20,9 +20,10 @@ import com.intellij.openapi.vfs.VirtualFile
|
|||||||
import com.intellij.psi.CommonClassNames
|
import com.intellij.psi.CommonClassNames
|
||||||
import com.intellij.psi.search.SearchScope
|
import com.intellij.psi.search.SearchScope
|
||||||
import org.jetbrains.kotlin.descriptors.Visibility
|
import org.jetbrains.kotlin.descriptors.Visibility
|
||||||
|
import org.jetbrains.kotlin.javac.JavaClassWithClassId
|
||||||
import org.jetbrains.kotlin.javac.JavacWrapper
|
import org.jetbrains.kotlin.javac.JavacWrapper
|
||||||
import org.jetbrains.kotlin.load.java.structure.*
|
import org.jetbrains.kotlin.load.java.structure.*
|
||||||
import org.jetbrains.kotlin.load.java.structure.impl.VirtualFileBoundJavaClass
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import javax.lang.model.element.ElementKind
|
import javax.lang.model.element.ElementKind
|
||||||
@@ -37,8 +38,9 @@ import javax.tools.JavaFileObject
|
|||||||
class SymbolBasedClass(
|
class SymbolBasedClass(
|
||||||
element: TypeElement,
|
element: TypeElement,
|
||||||
javac: JavacWrapper,
|
javac: JavacWrapper,
|
||||||
|
override val classId: ClassId?,
|
||||||
val file: JavaFileObject?
|
val file: JavaFileObject?
|
||||||
) : SymbolBasedClassifier<TypeElement>(element, javac), VirtualFileBoundJavaClass {
|
) : SymbolBasedClassifier<TypeElement>(element, javac), JavaClassWithClassId {
|
||||||
|
|
||||||
override val name: Name
|
override val name: Name
|
||||||
get() = Name.identifier(element.simpleName.toString())
|
get() = Name.identifier(element.simpleName.toString())
|
||||||
@@ -62,28 +64,34 @@ class SymbolBasedClass(
|
|||||||
get() = FqName(element.qualifiedName.toString())
|
get() = FqName(element.qualifiedName.toString())
|
||||||
|
|
||||||
override val supertypes: Collection<JavaClassifierType>
|
override val supertypes: Collection<JavaClassifierType>
|
||||||
get() = arrayListOf<TypeMirror>()
|
by lazy {
|
||||||
.apply {
|
arrayListOf<TypeMirror>()
|
||||||
element.superclass.takeIf { it !is NoType }?.let(this::add)
|
.apply {
|
||||||
}
|
element.superclass.takeIf { it !is NoType }?.let(this::add)
|
||||||
.apply { addAll(element.interfaces) }
|
addAll(element.interfaces)
|
||||||
.mapTo(arrayListOf()) { SymbolBasedClassifierType(it, javac) }
|
}
|
||||||
.apply {
|
.mapTo(arrayListOf()) { SymbolBasedClassifierType(it, javac) }
|
||||||
if (isEmpty() && element.qualifiedName.toString() != CommonClassNames.JAVA_LANG_OBJECT) {
|
.apply {
|
||||||
javac.JAVA_LANG_OBJECT?.let { add(it) }
|
if (isEmpty() && element.qualifiedName.toString() != CommonClassNames.JAVA_LANG_OBJECT) {
|
||||||
}
|
javac.JAVA_LANG_OBJECT?.let { add(it) }
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val innerClasses: Map<Name, JavaClass>
|
val innerClasses: Map<Name, JavaClass>
|
||||||
get() = element.enclosedElements
|
by lazy {
|
||||||
.filterIsInstance(TypeElement::class.java)
|
element.enclosedElements
|
||||||
.map { SymbolBasedClass(it, javac, file) }
|
.filterIsInstance(TypeElement::class.java)
|
||||||
.associateBy(JavaClass::name)
|
.map { SymbolBasedClass(it, javac, classId?.createNestedClassId(Name.identifier(it.simpleName.toString())), file) }
|
||||||
|
.associateBy(JavaClass::name)
|
||||||
|
}
|
||||||
|
|
||||||
override val outerClass: JavaClass?
|
override val outerClass: JavaClass?
|
||||||
get() = element.enclosingElement?.let {
|
by lazy {
|
||||||
if (it.asType().kind != TypeKind.DECLARED) null else SymbolBasedClass(it as TypeElement, javac, file)
|
element.enclosingElement?.let {
|
||||||
}
|
if (it.asType().kind != TypeKind.DECLARED) null else SymbolBasedClass(it as TypeElement, javac, classId?.outerClassId, file)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override val isInterface: Boolean
|
override val isInterface: Boolean
|
||||||
get() = element.kind == ElementKind.INTERFACE
|
get() = element.kind == ElementKind.INTERFACE
|
||||||
@@ -99,8 +107,8 @@ class SymbolBasedClass(
|
|||||||
|
|
||||||
override val methods: Collection<JavaMethod>
|
override val methods: Collection<JavaMethod>
|
||||||
get() = element.enclosedElements
|
get() = element.enclosedElements
|
||||||
.filter { it.kind == ElementKind.METHOD && !isEnumValuesOrValueOf(it as ExecutableElement)}
|
.filter { it.kind == ElementKind.METHOD && !isEnumValuesOrValueOf(it as ExecutableElement) }
|
||||||
.map { SymbolBasedMethod(it as ExecutableElement, javac) }
|
.map { SymbolBasedMethod(it as ExecutableElement, this, javac) }
|
||||||
|
|
||||||
private fun isEnumValuesOrValueOf(method: ExecutableElement): Boolean {
|
private fun isEnumValuesOrValueOf(method: ExecutableElement): Boolean {
|
||||||
return isEnum && when (method.simpleName.toString()) {
|
return isEnum && when (method.simpleName.toString()) {
|
||||||
@@ -113,12 +121,12 @@ class SymbolBasedClass(
|
|||||||
override val fields: Collection<JavaField>
|
override val fields: Collection<JavaField>
|
||||||
get() = element.enclosedElements
|
get() = element.enclosedElements
|
||||||
.filter { it.kind.isField && Name.isValidIdentifier(it.simpleName.toString()) }
|
.filter { it.kind.isField && Name.isValidIdentifier(it.simpleName.toString()) }
|
||||||
.map { SymbolBasedField(it as VariableElement, javac) }
|
.map { SymbolBasedField(it as VariableElement, this, javac) }
|
||||||
|
|
||||||
override val constructors: Collection<JavaConstructor>
|
override val constructors: Collection<JavaConstructor>
|
||||||
get() = element.enclosedElements
|
get() = element.enclosedElements
|
||||||
.filter { it.kind == ElementKind.CONSTRUCTOR }
|
.filter { it.kind == ElementKind.CONSTRUCTOR }
|
||||||
.map { SymbolBasedConstructor(it as ExecutableElement, javac) }
|
.map { SymbolBasedConstructor(it as ExecutableElement, this, javac) }
|
||||||
|
|
||||||
override val innerClassNames: Collection<Name>
|
override val innerClassNames: Collection<Name>
|
||||||
get() = innerClasses.keys
|
get() = innerClasses.keys
|
||||||
|
|||||||
+3
-1
@@ -17,6 +17,7 @@
|
|||||||
package org.jetbrains.kotlin.javac.wrappers.symbols
|
package org.jetbrains.kotlin.javac.wrappers.symbols
|
||||||
|
|
||||||
import org.jetbrains.kotlin.javac.JavacWrapper
|
import org.jetbrains.kotlin.javac.JavacWrapper
|
||||||
|
import org.jetbrains.kotlin.load.java.structure.JavaClass
|
||||||
import org.jetbrains.kotlin.load.java.structure.JavaConstructor
|
import org.jetbrains.kotlin.load.java.structure.JavaConstructor
|
||||||
import org.jetbrains.kotlin.load.java.structure.JavaTypeParameter
|
import org.jetbrains.kotlin.load.java.structure.JavaTypeParameter
|
||||||
import org.jetbrains.kotlin.load.java.structure.JavaValueParameter
|
import org.jetbrains.kotlin.load.java.structure.JavaValueParameter
|
||||||
@@ -24,8 +25,9 @@ import javax.lang.model.element.ExecutableElement
|
|||||||
|
|
||||||
class SymbolBasedConstructor(
|
class SymbolBasedConstructor(
|
||||||
element: ExecutableElement,
|
element: ExecutableElement,
|
||||||
|
containingClass: JavaClass,
|
||||||
javac: JavacWrapper
|
javac: JavacWrapper
|
||||||
) : SymbolBasedMember<ExecutableElement>(element, javac), JavaConstructor {
|
) : SymbolBasedMember<ExecutableElement>(element, containingClass, javac), JavaConstructor {
|
||||||
|
|
||||||
override val typeParameters: List<JavaTypeParameter>
|
override val typeParameters: List<JavaTypeParameter>
|
||||||
get() = element.typeParameters.map { SymbolBasedTypeParameter(it, javac) }
|
get() = element.typeParameters.map { SymbolBasedTypeParameter(it, javac) }
|
||||||
|
|||||||
+5
-8
@@ -17,17 +17,17 @@
|
|||||||
package org.jetbrains.kotlin.javac.wrappers.symbols
|
package org.jetbrains.kotlin.javac.wrappers.symbols
|
||||||
|
|
||||||
import org.jetbrains.kotlin.javac.JavacWrapper
|
import org.jetbrains.kotlin.javac.JavacWrapper
|
||||||
|
import org.jetbrains.kotlin.load.java.structure.JavaClass
|
||||||
import org.jetbrains.kotlin.load.java.structure.JavaField
|
import org.jetbrains.kotlin.load.java.structure.JavaField
|
||||||
import org.jetbrains.kotlin.load.java.structure.JavaType
|
import org.jetbrains.kotlin.load.java.structure.JavaType
|
||||||
import javax.lang.model.element.ElementKind
|
import javax.lang.model.element.ElementKind
|
||||||
import javax.lang.model.element.TypeElement
|
|
||||||
import javax.lang.model.element.VariableElement
|
import javax.lang.model.element.VariableElement
|
||||||
import javax.lang.model.type.DeclaredType
|
|
||||||
|
|
||||||
class SymbolBasedField(
|
class SymbolBasedField(
|
||||||
element: VariableElement,
|
element: VariableElement,
|
||||||
|
containingClass: JavaClass,
|
||||||
javac: JavacWrapper
|
javac: JavacWrapper
|
||||||
) : SymbolBasedMember<VariableElement>(element, javac), JavaField {
|
) : SymbolBasedMember<VariableElement>(element, containingClass, javac), JavaField {
|
||||||
|
|
||||||
override val isEnumEntry: Boolean
|
override val isEnumEntry: Boolean
|
||||||
get() = element.kind == ElementKind.ENUM_CONSTANT
|
get() = element.kind == ElementKind.ENUM_CONSTANT
|
||||||
@@ -36,12 +36,9 @@ class SymbolBasedField(
|
|||||||
get() = SymbolBasedType.create(element.asType(), javac)
|
get() = SymbolBasedType.create(element.asType(), javac)
|
||||||
|
|
||||||
override val initializerValue: Any?
|
override val initializerValue: Any?
|
||||||
get() = element.constantValue
|
by lazy { element.constantValue }
|
||||||
|
|
||||||
override val hasConstantNotNullInitializer: Boolean
|
override val hasConstantNotNullInitializer: Boolean
|
||||||
get() = element.constantValue != null && element.asType().let {
|
get() = initializerValue != null
|
||||||
it.kind.isPrimitive ||
|
|
||||||
((it as? DeclaredType)?.asElement() as? TypeElement)?.qualifiedName?.toString() == "java.lang.String"
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
+1
-6
@@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.javac.wrappers.symbols
|
package org.jetbrains.kotlin.javac.wrappers.symbols
|
||||||
|
|
||||||
import com.sun.tools.javac.code.Symbol
|
|
||||||
import org.jetbrains.kotlin.descriptors.Visibility
|
import org.jetbrains.kotlin.descriptors.Visibility
|
||||||
import org.jetbrains.kotlin.javac.JavacWrapper
|
import org.jetbrains.kotlin.javac.JavacWrapper
|
||||||
import org.jetbrains.kotlin.load.java.structure.JavaAnnotation
|
import org.jetbrains.kotlin.load.java.structure.JavaAnnotation
|
||||||
@@ -28,14 +27,10 @@ import javax.lang.model.element.Element
|
|||||||
|
|
||||||
abstract class SymbolBasedMember<out T : Element>(
|
abstract class SymbolBasedMember<out T : Element>(
|
||||||
element: T,
|
element: T,
|
||||||
|
override val containingClass: JavaClass,
|
||||||
javac: JavacWrapper
|
javac: JavacWrapper
|
||||||
) : SymbolBasedElement<T>(element, javac), JavaMember {
|
) : SymbolBasedElement<T>(element, javac), JavaMember {
|
||||||
|
|
||||||
override val containingClass: JavaClass
|
|
||||||
get() = with(element.enclosingElement as Symbol.ClassSymbol) {
|
|
||||||
SymbolBasedClass(this, javac, classfile)
|
|
||||||
}
|
|
||||||
|
|
||||||
override val annotations: Collection<JavaAnnotation>
|
override val annotations: Collection<JavaAnnotation>
|
||||||
get() = element.annotationMirrors.map { SymbolBasedAnnotation(it, javac) }
|
get() = element.annotationMirrors.map { SymbolBasedAnnotation(it, javac) }
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -22,8 +22,9 @@ import javax.lang.model.element.ExecutableElement
|
|||||||
|
|
||||||
class SymbolBasedMethod(
|
class SymbolBasedMethod(
|
||||||
element: ExecutableElement,
|
element: ExecutableElement,
|
||||||
|
containingClass: JavaClass,
|
||||||
javac: JavacWrapper
|
javac: JavacWrapper
|
||||||
) : SymbolBasedMember<ExecutableElement>(element, javac), JavaMethod {
|
) : SymbolBasedMember<ExecutableElement>(element, containingClass, javac), JavaMethod {
|
||||||
|
|
||||||
override val typeParameters: List<JavaTypeParameter>
|
override val typeParameters: List<JavaTypeParameter>
|
||||||
get() = element.typeParameters.map { SymbolBasedTypeParameter(it, javac) }
|
get() = element.typeParameters.map { SymbolBasedTypeParameter(it, javac) }
|
||||||
|
|||||||
+1
-1
@@ -34,7 +34,7 @@ class SymbolBasedPackage(
|
|||||||
get() = FqName(element.qualifiedName.toString())
|
get() = FqName(element.qualifiedName.toString())
|
||||||
|
|
||||||
override val subPackages: Collection<JavaPackage>
|
override val subPackages: Collection<JavaPackage>
|
||||||
get() = javac.findSubPackages(FqName(element.qualifiedName.toString()))
|
get() = javac.findSubPackages(fqName)
|
||||||
|
|
||||||
|
|
||||||
override val annotations: Collection<JavaAnnotation>
|
override val annotations: Collection<JavaAnnotation>
|
||||||
|
|||||||
+11
-5
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.javac.wrappers.symbols
|
package org.jetbrains.kotlin.javac.wrappers.symbols
|
||||||
|
|
||||||
|
import com.sun.tools.javac.code.Symbol
|
||||||
import org.jetbrains.kotlin.javac.JavacWrapper
|
import org.jetbrains.kotlin.javac.JavacWrapper
|
||||||
import org.jetbrains.kotlin.load.java.structure.*
|
import org.jetbrains.kotlin.load.java.structure.*
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
@@ -26,7 +27,7 @@ import javax.lang.model.type.TypeMirror
|
|||||||
|
|
||||||
sealed class SymbolBasedAnnotationArgument(
|
sealed class SymbolBasedAnnotationArgument(
|
||||||
override val name: Name,
|
override val name: Name,
|
||||||
val javac: JavacWrapper
|
protected val javac: JavacWrapper
|
||||||
) : JavaAnnotationArgument, JavaElement {
|
) : JavaAnnotationArgument, JavaElement {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@@ -40,7 +41,7 @@ sealed class SymbolBasedAnnotationArgument(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun arrayAnnotationArguments(values: Collection<*>, name: Name, javac: JavacWrapper): JavaArrayAnnotationArgument =
|
private fun arrayAnnotationArguments(values: Collection<*>, name: Name, javac: JavacWrapper): JavaArrayAnnotationArgument =
|
||||||
values.map { if (it is Collection<*>) arrayAnnotationArguments(it, name, javac) else create(it!!, name, javac) }
|
values.map { create(it!!, name, javac) }
|
||||||
.let { argumentList -> SymbolBasedArrayAnnotationArgument(argumentList, name, javac) }
|
.let { argumentList -> SymbolBasedArrayAnnotationArgument(argumentList, name, javac) }
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -48,7 +49,7 @@ sealed class SymbolBasedAnnotationArgument(
|
|||||||
}
|
}
|
||||||
|
|
||||||
class SymbolBasedAnnotationAsAnnotationArgument(
|
class SymbolBasedAnnotationAsAnnotationArgument(
|
||||||
val mirror: AnnotationMirror,
|
private val mirror: AnnotationMirror,
|
||||||
name: Name,
|
name: Name,
|
||||||
javac: JavacWrapper
|
javac: JavacWrapper
|
||||||
) : SymbolBasedAnnotationArgument(name, javac), JavaAnnotationAsAnnotationArgument {
|
) : SymbolBasedAnnotationArgument(name, javac), JavaAnnotationAsAnnotationArgument {
|
||||||
@@ -65,12 +66,17 @@ class SymbolBasedReferenceAnnotationArgument(
|
|||||||
override val entryName: Name?
|
override val entryName: Name?
|
||||||
get() = Name.identifier(name)
|
get() = Name.identifier(name)
|
||||||
|
|
||||||
override fun resolve() = SymbolBasedField(element, javac)
|
override fun resolve(): SymbolBasedField {
|
||||||
|
val containingClass = (element.enclosingElement as Symbol.ClassSymbol).let {
|
||||||
|
SymbolBasedClass(it, javac, null, it.classfile)
|
||||||
|
}
|
||||||
|
return SymbolBasedField(element, containingClass, javac)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class SymbolBasedClassObjectAnnotationArgument(
|
class SymbolBasedClassObjectAnnotationArgument(
|
||||||
val type: TypeMirror,
|
private val type: TypeMirror,
|
||||||
name : Name,
|
name : Name,
|
||||||
javac: JavacWrapper
|
javac: JavacWrapper
|
||||||
) : SymbolBasedAnnotationArgument(name, javac), JavaClassObjectAnnotationArgument {
|
) : SymbolBasedAnnotationArgument(name, javac), JavaClassObjectAnnotationArgument {
|
||||||
|
|||||||
+10
-5
@@ -73,12 +73,17 @@ class SymbolBasedClassifierType<out T : TypeMirror>(
|
|||||||
) : SymbolBasedType<T>(typeMirror, javac), JavaClassifierType {
|
) : SymbolBasedType<T>(typeMirror, javac), JavaClassifierType {
|
||||||
|
|
||||||
override val classifier: JavaClassifier?
|
override val classifier: JavaClassifier?
|
||||||
get() = when (typeMirror.kind) {
|
by lazy {
|
||||||
TypeKind.DECLARED -> ((typeMirror as DeclaredType).asElement() as Symbol.ClassSymbol).let { symbol ->
|
when (typeMirror.kind) {
|
||||||
SymbolBasedClass(symbol, javac, symbol.classfile)
|
TypeKind.DECLARED -> ((typeMirror as DeclaredType).asElement() as Symbol.ClassSymbol).let { symbol ->
|
||||||
|
// try to find cached javaClass
|
||||||
|
val classId = symbol.computeClassId()
|
||||||
|
classId?.let { javac.findClass(it) }
|
||||||
|
?: SymbolBasedClass(symbol, javac, classId, symbol.classfile)
|
||||||
|
}
|
||||||
|
TypeKind.TYPEVAR -> SymbolBasedTypeParameter((typeMirror as TypeVariable).asElement() as TypeParameterElement, javac)
|
||||||
|
else -> null
|
||||||
}
|
}
|
||||||
TypeKind.TYPEVAR -> SymbolBasedTypeParameter((typeMirror as TypeVariable).asElement() as TypeParameterElement, javac)
|
|
||||||
else -> null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override val typeArguments: List<JavaType>
|
override val typeArguments: List<JavaType>
|
||||||
|
|||||||
@@ -36,21 +36,24 @@ internal val Element.isStatic: Boolean
|
|||||||
internal val Element.isFinal: Boolean
|
internal val Element.isFinal: Boolean
|
||||||
get() = modifiers.contains(Modifier.FINAL)
|
get() = modifiers.contains(Modifier.FINAL)
|
||||||
|
|
||||||
internal fun Element.getVisibility(): Visibility = when {
|
internal fun Element.getVisibility(): Visibility = modifiers.let { modifiers ->
|
||||||
Modifier.PUBLIC in modifiers -> Visibilities.PUBLIC
|
when {
|
||||||
Modifier.PRIVATE in modifiers -> Visibilities.PRIVATE
|
Modifier.PUBLIC in modifiers -> Visibilities.PUBLIC
|
||||||
Modifier.PROTECTED in modifiers -> {
|
Modifier.PRIVATE in modifiers -> Visibilities.PRIVATE
|
||||||
if (Modifier.STATIC in modifiers) {
|
Modifier.PROTECTED in modifiers -> {
|
||||||
JavaVisibilities.PROTECTED_STATIC_VISIBILITY
|
if (Modifier.STATIC in modifiers) {
|
||||||
}
|
JavaVisibilities.PROTECTED_STATIC_VISIBILITY
|
||||||
else {
|
}
|
||||||
JavaVisibilities.PROTECTED_AND_PACKAGE
|
else {
|
||||||
|
JavaVisibilities.PROTECTED_AND_PACKAGE
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else -> JavaVisibilities.PACKAGE_VISIBILITY
|
||||||
}
|
}
|
||||||
else -> JavaVisibilities.PACKAGE_VISIBILITY
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun TypeElement.computeClassId(): ClassId? {
|
internal fun TypeElement.computeClassId(): ClassId? {
|
||||||
|
val enclosingElement = enclosingElement
|
||||||
if (enclosingElement.kind != ElementKind.PACKAGE) {
|
if (enclosingElement.kind != ElementKind.PACKAGE) {
|
||||||
val parentClassId = (enclosingElement as TypeElement).computeClassId() ?: return null
|
val parentClassId = (enclosingElement as TypeElement).computeClassId() ?: return null
|
||||||
return parentClassId.createNestedClassId(Name.identifier(simpleName.toString()))
|
return parentClassId.createNestedClassId(Name.identifier(simpleName.toString()))
|
||||||
@@ -60,11 +63,16 @@ internal fun TypeElement.computeClassId(): ClassId? {
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal fun ExecutableElement.valueParameters(javac: JavacWrapper): List<JavaValueParameter> =
|
internal fun ExecutableElement.valueParameters(javac: JavacWrapper): List<JavaValueParameter> =
|
||||||
parameters.mapIndexed { index, parameter ->
|
parameters.let { parameters ->
|
||||||
SymbolBasedValueParameter(parameter,
|
val isVarArgs = isVarArgs
|
||||||
if (!parameter.simpleName.contentEquals("arg$index")) parameter.simpleName.toString() else "p$index",
|
val lastIndex = parameters.lastIndex
|
||||||
index == parameters.lastIndex && isVarArgs,
|
parameters.mapIndexed { index, parameter ->
|
||||||
javac)
|
val simpleName = parameter.simpleName.toString()
|
||||||
|
SymbolBasedValueParameter(parameter,
|
||||||
|
if (!simpleName.contentEquals("arg$index")) simpleName else "p$index",
|
||||||
|
index == lastIndex && isVarArgs,
|
||||||
|
javac)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun AnnotatedConstruct.findAnnotation(fqName: FqName,
|
internal fun AnnotatedConstruct.findAnnotation(fqName: FqName,
|
||||||
|
|||||||
+6
-5
@@ -18,7 +18,9 @@ package org.jetbrains.kotlin.javac.wrappers.trees
|
|||||||
|
|
||||||
import com.sun.source.util.TreePath
|
import com.sun.source.util.TreePath
|
||||||
import com.sun.tools.javac.tree.JCTree
|
import com.sun.tools.javac.tree.JCTree
|
||||||
|
import org.jetbrains.kotlin.javac.JavaClassWithClassId
|
||||||
import org.jetbrains.kotlin.javac.JavacWrapper
|
import org.jetbrains.kotlin.javac.JavacWrapper
|
||||||
|
import org.jetbrains.kotlin.javac.resolve.ConstantEvaluator
|
||||||
import org.jetbrains.kotlin.load.java.structure.*
|
import org.jetbrains.kotlin.load.java.structure.*
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
@@ -34,7 +36,7 @@ class TreeBasedAnnotation(
|
|||||||
get() = createAnnotationArguments(this, javac)
|
get() = createAnnotationArguments(this, javac)
|
||||||
|
|
||||||
override val classId: ClassId?
|
override val classId: ClassId?
|
||||||
get() = resolve()?.computeClassId() ?: ClassId.topLevel(FqName(annotation.annotationType.toString().substringAfter("@")))
|
get() = (resolve() as? JavaClassWithClassId)?.classId ?: ClassId.topLevel(FqName(annotation.annotationType.toString().substringAfter("@")))
|
||||||
|
|
||||||
override fun resolve() =
|
override fun resolve() =
|
||||||
javac.resolve(TreePath.getPath(treePath.compilationUnit, annotation.annotationType)) as? JavaClass
|
javac.resolve(TreePath.getPath(treePath.compilationUnit, annotation.annotationType)) as? JavaClass
|
||||||
@@ -130,11 +132,10 @@ private fun resolveArgumentValue(argument: JCTree.JCExpression,
|
|||||||
name: Name,
|
name: Name,
|
||||||
treePath: TreePath,
|
treePath: TreePath,
|
||||||
javac: JavacWrapper): JavaAnnotationArgument? {
|
javac: JavacWrapper): JavaAnnotationArgument? {
|
||||||
val containingAnnotation = annotation.resolve()
|
val containingAnnotation = annotation.resolve() ?: return null
|
||||||
val type = containingAnnotation?.methods?.find { it.name == name }?.returnType ?: return null
|
val evaluator = ConstantEvaluator(containingAnnotation, javac, treePath)
|
||||||
val calculator = ValueCalculator(containingAnnotation, javac, treePath, type)
|
|
||||||
|
|
||||||
return calculator.getValue(argument)?.let { TreeBasedLiteralAnnotationArgument(name, it, javac) }
|
return evaluator.getValue(argument)?.let { TreeBasedLiteralAnnotationArgument(name, it, javac) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun arrayAnnotationArguments(values: List<JCTree.JCExpression>,
|
private fun arrayAnnotationArguments(values: List<JCTree.JCExpression>,
|
||||||
|
|||||||
+32
-30
@@ -25,9 +25,10 @@ import com.sun.tools.javac.tree.JCTree
|
|||||||
import com.sun.tools.javac.tree.TreeInfo
|
import com.sun.tools.javac.tree.TreeInfo
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities.PUBLIC
|
import org.jetbrains.kotlin.descriptors.Visibilities.PUBLIC
|
||||||
import org.jetbrains.kotlin.descriptors.Visibility
|
import org.jetbrains.kotlin.descriptors.Visibility
|
||||||
|
import org.jetbrains.kotlin.javac.JavaClassWithClassId
|
||||||
import org.jetbrains.kotlin.javac.JavacWrapper
|
import org.jetbrains.kotlin.javac.JavacWrapper
|
||||||
import org.jetbrains.kotlin.load.java.structure.*
|
import org.jetbrains.kotlin.load.java.structure.*
|
||||||
import org.jetbrains.kotlin.load.java.structure.impl.VirtualFileBoundJavaClass
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import javax.tools.JavaFileObject
|
import javax.tools.JavaFileObject
|
||||||
@@ -36,8 +37,9 @@ class TreeBasedClass(
|
|||||||
tree: JCTree.JCClassDecl,
|
tree: JCTree.JCClassDecl,
|
||||||
treePath: TreePath,
|
treePath: TreePath,
|
||||||
javac: JavacWrapper,
|
javac: JavacWrapper,
|
||||||
val file: JavaFileObject
|
val file: JavaFileObject,
|
||||||
) : TreeBasedElement<JCTree.JCClassDecl>(tree, treePath, javac), VirtualFileBoundJavaClass {
|
override val classId: ClassId?
|
||||||
|
) : TreeBasedElement<JCTree.JCClassDecl>(tree, treePath, javac), JavaClassWithClassId {
|
||||||
|
|
||||||
override val name: Name
|
override val name: Name
|
||||||
get() = Name.identifier(tree.simpleName.toString())
|
get() = Name.identifier(tree.simpleName.toString())
|
||||||
@@ -70,45 +72,43 @@ class TreeBasedClass(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override val fqName: FqName
|
override val fqName: FqName
|
||||||
get() = treePath.reversed()
|
get() = classId?.asSingleFqName() ?: throw UnsupportedOperationException("classId of $name is null")
|
||||||
.filterIsInstance<JCTree.JCClassDecl>()
|
|
||||||
.joinToString(
|
|
||||||
separator = ".",
|
|
||||||
transform = JCTree.JCClassDecl::name
|
|
||||||
)
|
|
||||||
.let { treePath.compilationUnit.packageName?.let { packageName -> FqName("$packageName.$it") } ?: FqName.topLevel(Name.identifier(it))}
|
|
||||||
|
|
||||||
override val supertypes: Collection<JavaClassifierType>
|
override val supertypes: Collection<JavaClassifierType>
|
||||||
get() = arrayListOf<JavaClassifierType>().also { list ->
|
by lazy {
|
||||||
if (isEnum) {
|
arrayListOf<JavaClassifierType>().also { list ->
|
||||||
createEnumSupertype(this, javac).let { list.add(it) }
|
if (isEnum) {
|
||||||
} else if (isAnnotationType) {
|
createEnumSupertype(this, javac).let { list.add(it) }
|
||||||
javac.JAVA_LANG_ANNOTATION_ANNOTATION?.let { list.add(it) }
|
}
|
||||||
}
|
else if (isAnnotationType) {
|
||||||
|
javac.JAVA_LANG_ANNOTATION_ANNOTATION?.let { list.add(it) }
|
||||||
|
}
|
||||||
|
|
||||||
tree.extending?.let {
|
tree.extending?.let {
|
||||||
(TreeBasedType.create(it, javac.getTreePath(it, treePath.compilationUnit), javac, emptyList()) as? JavaClassifierType)
|
(TreeBasedType.create(it, javac.getTreePath(it, treePath.compilationUnit), javac, emptyList()) as? JavaClassifierType)
|
||||||
?.let { list.add(it) }
|
?.let { list.add(it) }
|
||||||
}
|
}
|
||||||
tree.implementing?.mapNotNull {
|
tree.implementing?.mapNotNull {
|
||||||
TreeBasedType.create(it, javac.getTreePath(it, treePath.compilationUnit), javac, emptyList()) as? JavaClassifierType
|
TreeBasedType.create(it, javac.getTreePath(it, treePath.compilationUnit), javac, emptyList()) as? JavaClassifierType
|
||||||
}?.let { list.addAll(it) }
|
}?.let { list.addAll(it) }
|
||||||
|
|
||||||
if (list.isEmpty()) {
|
if (list.isEmpty()) {
|
||||||
javac.JAVA_LANG_OBJECT?.let { list.add(it) }
|
javac.JAVA_LANG_OBJECT?.let { list.add(it) }
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
val innerClasses: Map<Name, TreeBasedClass> by lazy {
|
val innerClasses: Map<Name, TreeBasedClass> by lazy {
|
||||||
tree.members
|
tree.members
|
||||||
.filterIsInstance(JCTree.JCClassDecl::class.java)
|
.filterIsInstance(JCTree.JCClassDecl::class.java)
|
||||||
.map { TreeBasedClass(it, TreePath(treePath, it), javac, file) }
|
.map { TreeBasedClass(it, TreePath(treePath, it), javac, file, classId?.createNestedClassId(Name.identifier(it.simpleName.toString()))) }
|
||||||
.associateBy(JavaClass::name)
|
.associateBy(JavaClass::name)
|
||||||
}
|
}
|
||||||
|
|
||||||
override val outerClass: JavaClass? by lazy {
|
override val outerClass: JavaClass? by lazy {
|
||||||
(treePath.parentPath.leaf as? JCTree.JCClassDecl)?.let { classDecl ->
|
(treePath.parentPath.leaf as? JCTree.JCClassDecl)?.let { classDecl ->
|
||||||
TreeBasedClass(classDecl, treePath.parentPath, javac, file)
|
javac.findClass(classId!!.outerClassId!!)
|
||||||
|
?: TreeBasedClass(classDecl, treePath.parentPath, javac, file, classId.outerClassId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,7 +156,7 @@ class TreeBasedClass(
|
|||||||
|
|
||||||
private fun createEnumSupertype(javaClass: JavaClass,
|
private fun createEnumSupertype(javaClass: JavaClass,
|
||||||
javac: JavacWrapper) = object : JavaClassifierType {
|
javac: JavacWrapper) = object : JavaClassifierType {
|
||||||
override val classifier: JavaClassifier?
|
override val classifier: JavaClass?
|
||||||
get() = javac.JAVA_LANG_ENUM
|
get() = javac.JAVA_LANG_ENUM
|
||||||
|
|
||||||
override val typeArguments: List<JavaType>
|
override val typeArguments: List<JavaType>
|
||||||
@@ -167,11 +167,12 @@ private fun createEnumSupertype(javaClass: JavaClass,
|
|||||||
override val annotations: Collection<JavaAnnotation>
|
override val annotations: Collection<JavaAnnotation>
|
||||||
get() = emptyList()
|
get() = emptyList()
|
||||||
override val classifierQualifiedName: String
|
override val classifierQualifiedName: String
|
||||||
get() = (classifier as? JavaClass)?.fqName?.asString() ?: ""
|
get() = classifier?.fqName?.asString() ?: ""
|
||||||
override val presentableText: String
|
override val presentableText: String
|
||||||
get() = classifierQualifiedName
|
get() = classifierQualifiedName
|
||||||
override val isDeprecatedInJavaDoc: Boolean
|
override val isDeprecatedInJavaDoc: Boolean
|
||||||
get() = false
|
get() = false
|
||||||
|
|
||||||
override fun findAnnotation(fqName: FqName) = null
|
override fun findAnnotation(fqName: FqName) = null
|
||||||
|
|
||||||
private inner class TypeArgument : JavaClassifierType {
|
private inner class TypeArgument : JavaClassifierType {
|
||||||
@@ -189,6 +190,7 @@ private fun createEnumSupertype(javaClass: JavaClass,
|
|||||||
get() = classifierQualifiedName
|
get() = classifierQualifiedName
|
||||||
override val isDeprecatedInJavaDoc: Boolean
|
override val isDeprecatedInJavaDoc: Boolean
|
||||||
get() = false
|
get() = false
|
||||||
|
|
||||||
override fun findAnnotation(fqName: FqName) = null
|
override fun findAnnotation(fqName: FqName) = null
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-92
@@ -18,15 +18,13 @@ package org.jetbrains.kotlin.javac.wrappers.trees
|
|||||||
|
|
||||||
import com.sun.source.util.TreePath
|
import com.sun.source.util.TreePath
|
||||||
import com.sun.tools.javac.code.Flags
|
import com.sun.tools.javac.code.Flags
|
||||||
import com.sun.tools.javac.code.TypeTag
|
|
||||||
import com.sun.tools.javac.tree.JCTree
|
import com.sun.tools.javac.tree.JCTree
|
||||||
import org.jetbrains.kotlin.builtins.PrimitiveType
|
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
import org.jetbrains.kotlin.descriptors.Visibility
|
import org.jetbrains.kotlin.descriptors.Visibility
|
||||||
import org.jetbrains.kotlin.javac.JavacWrapper
|
import org.jetbrains.kotlin.javac.JavacWrapper
|
||||||
|
import org.jetbrains.kotlin.javac.resolve.ConstantEvaluator
|
||||||
import org.jetbrains.kotlin.load.java.structure.JavaClass
|
import org.jetbrains.kotlin.load.java.structure.JavaClass
|
||||||
import org.jetbrains.kotlin.load.java.structure.JavaField
|
import org.jetbrains.kotlin.load.java.structure.JavaField
|
||||||
import org.jetbrains.kotlin.load.java.structure.JavaPrimitiveType
|
|
||||||
import org.jetbrains.kotlin.load.java.structure.JavaType
|
import org.jetbrains.kotlin.load.java.structure.JavaType
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
|
||||||
@@ -60,7 +58,7 @@ class TreeBasedField(
|
|||||||
|
|
||||||
override val initializerValue: Any?
|
override val initializerValue: Any?
|
||||||
get() = tree.init?.let { initExpr ->
|
get() = tree.init?.let { initExpr ->
|
||||||
if (hasConstantNotNullInitializer) ValueCalculator(containingClass, javac, treePath, type).getValue(initExpr) else null
|
if (hasConstantNotNullInitializer) ConstantEvaluator(containingClass, javac, treePath).getValue(initExpr) else null
|
||||||
}
|
}
|
||||||
|
|
||||||
override val hasConstantNotNullInitializer: Boolean
|
override val hasConstantNotNullInitializer: Boolean
|
||||||
@@ -74,91 +72,3 @@ class TreeBasedField(
|
|||||||
} ?: false
|
} ?: false
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class ValueCalculator(private val containingClass: JavaClass,
|
|
||||||
private val javac: JavacWrapper,
|
|
||||||
private val treePath: TreePath,
|
|
||||||
private val type: JavaType) {
|
|
||||||
fun getValue(expr: JCTree.JCExpression): Any? {
|
|
||||||
return when (expr) {
|
|
||||||
is JCTree.JCLiteral -> {
|
|
||||||
if (expr.typetag == TypeTag.BOOLEAN) {
|
|
||||||
expr.value != 0
|
|
||||||
}
|
|
||||||
else expr.value
|
|
||||||
}
|
|
||||||
is JCTree.JCIdent,
|
|
||||||
is JCTree.JCFieldAccess -> javac.resolveField(javac.getTreePath(expr, treePath.compilationUnit), containingClass)?.initializerValue
|
|
||||||
is JCTree.JCBinary -> binaryInitializerValue(expr)
|
|
||||||
is JCTree.JCParens -> getValue(expr.expr)
|
|
||||||
is JCTree.JCUnary -> unaryInitializerValue(expr)
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun unaryInitializerValue(value: JCTree.JCUnary): Any? {
|
|
||||||
val argValue = getValue(value.arg)
|
|
||||||
return when (value.tag) {
|
|
||||||
JCTree.Tag.COMPL -> (argValue as? Int)?.inv()
|
|
||||||
JCTree.Tag.NOT -> (argValue as? Boolean)?.let { !it }
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun binaryInitializerValue(value: JCTree.JCBinary): Any? {
|
|
||||||
val lhsValue = getValue(value.lhs) ?: return null
|
|
||||||
val rhsValue = getValue(value.rhs) ?: return null
|
|
||||||
|
|
||||||
return calculateValue(lhsValue, rhsValue, value.tag)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun calculateValue(lhsValue: Any?, rhsValue: Any?, opcode: JCTree.Tag): Any? {
|
|
||||||
if (lhsValue is String && opcode == JCTree.Tag.PLUS) return lhsValue + rhsValue
|
|
||||||
|
|
||||||
if (lhsValue is Boolean && rhsValue is Boolean) {
|
|
||||||
return when (opcode) {
|
|
||||||
JCTree.Tag.AND -> lhsValue && rhsValue
|
|
||||||
JCTree.Tag.OR -> lhsValue || rhsValue
|
|
||||||
JCTree.Tag.EQ -> lhsValue == rhsValue
|
|
||||||
JCTree.Tag.NE -> lhsValue != rhsValue
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val l = (lhsValue as? Number)?.toInt() ?: return null
|
|
||||||
val r = (rhsValue as? Number)?.toInt() ?: return null
|
|
||||||
return when (opcode) {
|
|
||||||
JCTree.Tag.PLUS -> getExpressionType(l + r)
|
|
||||||
JCTree.Tag.MINUS -> getExpressionType(l - r)
|
|
||||||
JCTree.Tag.MUL -> getExpressionType(l * r)
|
|
||||||
JCTree.Tag.DIV -> getExpressionType(l / r)
|
|
||||||
JCTree.Tag.MOD -> getExpressionType(l % r)
|
|
||||||
JCTree.Tag.SR -> getExpressionType(l shr r)
|
|
||||||
JCTree.Tag.SL -> getExpressionType(l shl r)
|
|
||||||
JCTree.Tag.BITAND -> getExpressionType(l and r)
|
|
||||||
JCTree.Tag.BITOR -> getExpressionType(l or r)
|
|
||||||
JCTree.Tag.BITXOR -> getExpressionType(l xor r)
|
|
||||||
JCTree.Tag.USR -> getExpressionType(l ushr r)
|
|
||||||
JCTree.Tag.EQ -> l == r
|
|
||||||
JCTree.Tag.NE -> l != r
|
|
||||||
JCTree.Tag.LT -> l < r
|
|
||||||
JCTree.Tag.LE -> l <= r
|
|
||||||
JCTree.Tag.GT -> l > r
|
|
||||||
JCTree.Tag.GE -> l >= r
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getExpressionType(expression: Int): Any? {
|
|
||||||
val type = type as? JavaPrimitiveType ?: return null
|
|
||||||
return when (type.type) {
|
|
||||||
PrimitiveType.DOUBLE -> expression.toDouble()
|
|
||||||
PrimitiveType.INT -> expression
|
|
||||||
PrimitiveType.FLOAT -> expression.toFloat()
|
|
||||||
PrimitiveType.LONG -> expression.toLong()
|
|
||||||
PrimitiveType.SHORT -> expression.toShort()
|
|
||||||
PrimitiveType.BYTE -> expression.toByte()
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+4
-3
@@ -19,7 +19,6 @@ package org.jetbrains.kotlin.javac.wrappers.trees
|
|||||||
import com.sun.source.util.TreePath
|
import com.sun.source.util.TreePath
|
||||||
import com.sun.tools.javac.tree.JCTree
|
import com.sun.tools.javac.tree.JCTree
|
||||||
import org.jetbrains.kotlin.javac.JavacWrapper
|
import org.jetbrains.kotlin.javac.JavacWrapper
|
||||||
import org.jetbrains.kotlin.load.java.structure.JavaAnnotation
|
|
||||||
import org.jetbrains.kotlin.load.java.structure.JavaClass
|
import org.jetbrains.kotlin.load.java.structure.JavaClass
|
||||||
import org.jetbrains.kotlin.load.java.structure.JavaMember
|
import org.jetbrains.kotlin.load.java.structure.JavaMember
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
@@ -34,11 +33,13 @@ abstract class TreeBasedMember<out T : JCTree>(
|
|||||||
override val isDeprecatedInJavaDoc: Boolean
|
override val isDeprecatedInJavaDoc: Boolean
|
||||||
get() = javac.isDeprecatedInJavaDoc(treePath)
|
get() = javac.isDeprecatedInJavaDoc(treePath)
|
||||||
|
|
||||||
override val annotations: Collection<JavaAnnotation> by lazy {
|
override val annotations: Collection<TreeBasedAnnotation> by lazy {
|
||||||
tree.annotations().map { TreeBasedAnnotation(it, treePath, javac) }
|
tree.annotations().map { TreeBasedAnnotation(it, treePath, javac) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun findAnnotation(fqName: FqName) =
|
override fun findAnnotation(fqName: FqName) =
|
||||||
annotations.find { it.classId?.asSingleFqName() == fqName }
|
annotations
|
||||||
|
.filter { it.annotation.annotationType.toString().endsWith(fqName.shortName().asString()) }
|
||||||
|
.find { it.classId?.asSingleFqName() == fqName }
|
||||||
|
|
||||||
}
|
}
|
||||||
+4
-3
@@ -20,7 +20,6 @@ import com.sun.source.util.TreePath
|
|||||||
import com.sun.tools.javac.code.Flags
|
import com.sun.tools.javac.code.Flags
|
||||||
import com.sun.tools.javac.tree.JCTree
|
import com.sun.tools.javac.tree.JCTree
|
||||||
import org.jetbrains.kotlin.javac.JavacWrapper
|
import org.jetbrains.kotlin.javac.JavacWrapper
|
||||||
import org.jetbrains.kotlin.load.java.structure.JavaAnnotation
|
|
||||||
import org.jetbrains.kotlin.load.java.structure.JavaType
|
import org.jetbrains.kotlin.load.java.structure.JavaType
|
||||||
import org.jetbrains.kotlin.load.java.structure.JavaValueParameter
|
import org.jetbrains.kotlin.load.java.structure.JavaValueParameter
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
@@ -32,12 +31,14 @@ class TreeBasedValueParameter(
|
|||||||
javac: JavacWrapper
|
javac: JavacWrapper
|
||||||
) : TreeBasedElement<JCTree.JCVariableDecl>(tree, treePath, javac), JavaValueParameter {
|
) : TreeBasedElement<JCTree.JCVariableDecl>(tree, treePath, javac), JavaValueParameter {
|
||||||
|
|
||||||
override val annotations: Collection<JavaAnnotation> by lazy {
|
override val annotations: Collection<TreeBasedAnnotation> by lazy {
|
||||||
tree.annotations().map { TreeBasedAnnotation(it, treePath, javac) }
|
tree.annotations().map { TreeBasedAnnotation(it, treePath, javac) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun findAnnotation(fqName: FqName) =
|
override fun findAnnotation(fqName: FqName) =
|
||||||
annotations.find { it.classId?.asSingleFqName() == fqName }
|
annotations
|
||||||
|
.filter { it.annotation.annotationType.toString().endsWith(fqName.shortName().asString()) }
|
||||||
|
.find { it.classId?.asSingleFqName() == fqName }
|
||||||
|
|
||||||
override val isDeprecatedInJavaDoc: Boolean
|
override val isDeprecatedInJavaDoc: Boolean
|
||||||
get() = javac.isDeprecatedInJavaDoc(treePath)
|
get() = javac.isDeprecatedInJavaDoc(treePath)
|
||||||
|
|||||||
+31
-29
@@ -31,25 +31,27 @@ abstract class TreeBasedType<out T : JCTree>(
|
|||||||
val tree: T,
|
val tree: T,
|
||||||
val treePath: TreePath,
|
val treePath: TreePath,
|
||||||
val javac: JavacWrapper,
|
val javac: JavacWrapper,
|
||||||
override val annotations: Collection<JavaAnnotation>
|
private val allAnnotations: Collection<JavaAnnotation>
|
||||||
) : JavaType, JavaAnnotationOwner {
|
) : JavaType, JavaAnnotationOwner {
|
||||||
|
|
||||||
|
override val annotations: Collection<JavaAnnotation>
|
||||||
|
get() = allAnnotations.filterTypeAnnotations()
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun create(tree: JCTree, treePath: TreePath,
|
fun create(tree: JCTree, treePath: TreePath,
|
||||||
javac: JavacWrapper, annotations: Collection<JavaAnnotation>): JavaType {
|
javac: JavacWrapper, annotations: Collection<JavaAnnotation>): JavaType {
|
||||||
val applicableAnnotations = annotations.filterTypeAnnotations()
|
|
||||||
return when (tree) {
|
return when (tree) {
|
||||||
is JCTree.JCPrimitiveTypeTree -> TreeBasedPrimitiveType(tree, javac.getTreePath(tree, treePath.compilationUnit), javac, applicableAnnotations)
|
is JCTree.JCPrimitiveTypeTree -> TreeBasedPrimitiveType(tree, javac.getTreePath(tree, treePath.compilationUnit), javac, annotations)
|
||||||
is JCTree.JCArrayTypeTree -> TreeBasedArrayType(tree, javac.getTreePath(tree, treePath.compilationUnit), javac, applicableAnnotations)
|
is JCTree.JCArrayTypeTree -> TreeBasedArrayType(tree, javac.getTreePath(tree, treePath.compilationUnit), javac, annotations)
|
||||||
is JCTree.JCWildcard -> TreeBasedWildcardType(tree, javac.getTreePath(tree, treePath.compilationUnit), javac, applicableAnnotations)
|
is JCTree.JCWildcard -> TreeBasedWildcardType(tree, javac.getTreePath(tree, treePath.compilationUnit), javac, annotations)
|
||||||
is JCTree.JCTypeApply -> TreeBasedGenericClassifierType(tree, javac.getTreePath(tree, treePath.compilationUnit), javac, applicableAnnotations)
|
is JCTree.JCTypeApply -> TreeBasedGenericClassifierType(tree, javac.getTreePath(tree, treePath.compilationUnit), javac, annotations)
|
||||||
is JCTree.JCAnnotatedType -> {
|
is JCTree.JCAnnotatedType -> {
|
||||||
val underlyingType = tree.underlyingType
|
val underlyingType = tree.underlyingType
|
||||||
val newAnnotations = tree.annotations
|
val newAnnotations = tree.annotations
|
||||||
.map { TreeBasedAnnotation(it, javac.getTreePath(it, treePath.compilationUnit), javac) }
|
.map { TreeBasedAnnotation(it, javac.getTreePath(it, treePath.compilationUnit), javac) }
|
||||||
create(underlyingType, javac.getTreePath(underlyingType, treePath.compilationUnit), javac, newAnnotations)
|
create(underlyingType, javac.getTreePath(underlyingType, treePath.compilationUnit), javac, newAnnotations)
|
||||||
}
|
}
|
||||||
is JCTree.JCExpression -> TreeBasedNonGenericClassifierType(tree, javac.getTreePath(tree, treePath.compilationUnit), javac, applicableAnnotations)
|
is JCTree.JCExpression -> TreeBasedNonGenericClassifierType(tree, javac.getTreePath(tree, treePath.compilationUnit), javac, annotations)
|
||||||
else -> throw UnsupportedOperationException("Unsupported type: $tree")
|
else -> throw UnsupportedOperationException("Unsupported type: $tree")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -72,8 +74,8 @@ class TreeBasedPrimitiveType(
|
|||||||
tree: JCTree.JCPrimitiveTypeTree,
|
tree: JCTree.JCPrimitiveTypeTree,
|
||||||
treePath: TreePath,
|
treePath: TreePath,
|
||||||
javac: JavacWrapper,
|
javac: JavacWrapper,
|
||||||
annotations: Collection<JavaAnnotation>
|
allAnnotations: Collection<JavaAnnotation>
|
||||||
) : TreeBasedType<JCTree.JCPrimitiveTypeTree>(tree, treePath, javac, annotations), JavaPrimitiveType {
|
) : TreeBasedType<JCTree.JCPrimitiveTypeTree>(tree, treePath, javac, allAnnotations), JavaPrimitiveType {
|
||||||
|
|
||||||
override val type: PrimitiveType?
|
override val type: PrimitiveType?
|
||||||
get() = if (tree.primitiveTypeKind == TypeKind.VOID) {
|
get() = if (tree.primitiveTypeKind == TypeKind.VOID) {
|
||||||
@@ -89,8 +91,8 @@ class TreeBasedArrayType(
|
|||||||
tree: JCTree.JCArrayTypeTree,
|
tree: JCTree.JCArrayTypeTree,
|
||||||
treePath: TreePath,
|
treePath: TreePath,
|
||||||
javac: JavacWrapper,
|
javac: JavacWrapper,
|
||||||
annotations: Collection<JavaAnnotation>
|
allAnnotations: Collection<JavaAnnotation>
|
||||||
) : TreeBasedType<JCTree.JCArrayTypeTree>(tree, treePath, javac, annotations), JavaArrayType {
|
) : TreeBasedType<JCTree.JCArrayTypeTree>(tree, treePath, javac, allAnnotations), JavaArrayType {
|
||||||
|
|
||||||
override val componentType: JavaType
|
override val componentType: JavaType
|
||||||
get() = create(tree.elemtype, treePath, javac, annotations)
|
get() = create(tree.elemtype, treePath, javac, annotations)
|
||||||
@@ -101,8 +103,8 @@ class TreeBasedWildcardType(
|
|||||||
tree: JCTree.JCWildcard,
|
tree: JCTree.JCWildcard,
|
||||||
treePath: TreePath,
|
treePath: TreePath,
|
||||||
javac: JavacWrapper,
|
javac: JavacWrapper,
|
||||||
annotations: Collection<JavaAnnotation>
|
allAnnotations: Collection<JavaAnnotation>
|
||||||
) : TreeBasedType<JCTree.JCWildcard>(tree, treePath, javac, annotations), JavaWildcardType {
|
) : TreeBasedType<JCTree.JCWildcard>(tree, treePath, javac, allAnnotations), JavaWildcardType {
|
||||||
|
|
||||||
override val bound: JavaType?
|
override val bound: JavaType?
|
||||||
get() = tree.bound?.let { create(it, treePath, javac, annotations) }
|
get() = tree.bound?.let { create(it, treePath, javac, annotations) }
|
||||||
@@ -116,11 +118,11 @@ sealed class TreeBasedClassifierType<out T : JCTree>(
|
|||||||
tree: T,
|
tree: T,
|
||||||
treePath: TreePath,
|
treePath: TreePath,
|
||||||
javac: JavacWrapper,
|
javac: JavacWrapper,
|
||||||
annotations: Collection<JavaAnnotation>
|
allAnnotations: Collection<JavaAnnotation>
|
||||||
) : TreeBasedType<T>(tree, treePath, javac, annotations), JavaClassifierType {
|
) : TreeBasedType<T>(tree, treePath, javac, allAnnotations), JavaClassifierType {
|
||||||
|
|
||||||
override val classifier: JavaClassifier?
|
override val classifier: JavaClassifier?
|
||||||
get() = javac.resolve(treePath)
|
by lazy { javac.resolve(treePath) }
|
||||||
|
|
||||||
override val classifierQualifiedName: String
|
override val classifierQualifiedName: String
|
||||||
get() = (classifier as? JavaClass)?.fqName?.asString() ?: treePath.leaf.toString().substringBefore("<")
|
get() = (classifier as? JavaClass)?.fqName?.asString() ?: treePath.leaf.toString().substringBefore("<")
|
||||||
@@ -132,7 +134,7 @@ sealed class TreeBasedClassifierType<out T : JCTree>(
|
|||||||
get() {
|
get() {
|
||||||
var tree: JCTree = tree
|
var tree: JCTree = tree
|
||||||
if (tree is JCTree.JCTypeApply) {
|
if (tree is JCTree.JCTypeApply) {
|
||||||
tree = tree.clazz
|
tree = tree.clazz
|
||||||
}
|
}
|
||||||
if (tree is JCTree.JCFieldAccess) {
|
if (tree is JCTree.JCFieldAccess) {
|
||||||
val enclosingType = TreeBasedType.create(tree.selected, treePath, javac, annotations)
|
val enclosingType = TreeBasedType.create(tree.selected, treePath, javac, annotations)
|
||||||
@@ -158,12 +160,12 @@ sealed class TreeBasedClassifierType<out T : JCTree>(
|
|||||||
|
|
||||||
private val typeParameter: JCTree.JCTypeParameter?
|
private val typeParameter: JCTree.JCTypeParameter?
|
||||||
get() = treePath.flatMap {
|
get() = treePath.flatMap {
|
||||||
when (it) {
|
when (it) {
|
||||||
is JCTree.JCClassDecl -> it.typarams
|
is JCTree.JCClassDecl -> it.typarams
|
||||||
is JCTree.JCMethodDecl -> it.typarams
|
is JCTree.JCMethodDecl -> it.typarams
|
||||||
else -> emptyList<JCTree.JCTypeParameter>()
|
else -> emptyList<JCTree.JCTypeParameter>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.find { it.toString().substringBefore(" ") == treePath.leaf.toString() }
|
.find { it.toString().substringBefore(" ") == treePath.leaf.toString() }
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -213,13 +215,13 @@ class TreeBasedGenericClassifierType(
|
|||||||
) : TreeBasedClassifierType<JCTree.JCTypeApply>(tree, treePath, javac, annotations) {
|
) : TreeBasedClassifierType<JCTree.JCTypeApply>(tree, treePath, javac, annotations) {
|
||||||
|
|
||||||
override val classifier: JavaClassifier?
|
override val classifier: JavaClassifier?
|
||||||
get() {
|
by lazy {
|
||||||
val newTree = tree.clazz
|
val newTree = tree.clazz
|
||||||
return if (newTree is JCTree.JCAnnotatedType) {
|
if (newTree is JCTree.JCAnnotatedType) {
|
||||||
javac.resolve(javac.getTreePath(newTree.underlyingType, treePath.compilationUnit))
|
javac.resolve(javac.getTreePath(newTree.underlyingType, treePath.compilationUnit))
|
||||||
|
}
|
||||||
|
else super.classifier
|
||||||
}
|
}
|
||||||
else super.classifier
|
|
||||||
}
|
|
||||||
|
|
||||||
override val annotations: Collection<JavaAnnotation>
|
override val annotations: Collection<JavaAnnotation>
|
||||||
get() {
|
get() {
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ import org.jetbrains.kotlin.javac.wrappers.symbols.SymbolBasedField
|
|||||||
import org.jetbrains.kotlin.javac.wrappers.symbols.SymbolBasedReferenceAnnotationArgument
|
import org.jetbrains.kotlin.javac.wrappers.symbols.SymbolBasedReferenceAnnotationArgument
|
||||||
import org.jetbrains.kotlin.load.java.JavaVisibilities
|
import org.jetbrains.kotlin.load.java.JavaVisibilities
|
||||||
import org.jetbrains.kotlin.load.java.structure.JavaAnnotation
|
import org.jetbrains.kotlin.load.java.structure.JavaAnnotation
|
||||||
import org.jetbrains.kotlin.load.java.structure.JavaClass
|
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
@@ -63,14 +62,12 @@ internal fun JCTree.annotations(): Collection<JCTree.JCAnnotation> = when (this)
|
|||||||
else -> null
|
else -> null
|
||||||
} ?: emptyList<JCTree.JCAnnotation>()
|
} ?: emptyList<JCTree.JCAnnotation>()
|
||||||
|
|
||||||
fun JavaClass.computeClassId(): ClassId? =
|
|
||||||
outerClass?.computeClassId()?.createNestedClassId(name) ?: fqName?.let { ClassId.topLevel(it) }
|
|
||||||
|
|
||||||
fun Collection<JavaAnnotation>.filterTypeAnnotations(): Collection<JavaAnnotation> {
|
fun Collection<JavaAnnotation>.filterTypeAnnotations(): Collection<JavaAnnotation> {
|
||||||
val filteredAnnotations = arrayListOf<JavaAnnotation>()
|
val filteredAnnotations = arrayListOf<JavaAnnotation>()
|
||||||
|
val targetClassId = ClassId(FqName("java.lang.annotation"), Name.identifier("Target"))
|
||||||
for (annotation in this) {
|
for (annotation in this) {
|
||||||
val annotationClass = annotation.resolve()
|
val annotationClass = annotation.resolve()
|
||||||
val targetAnnotation = annotationClass?.annotations?.find { it.classId == ClassId(FqName("java.lang.annotation"), Name.identifier("Target")) } ?: continue
|
val targetAnnotation = annotationClass?.annotations?.find { it.classId == targetClassId } ?: continue
|
||||||
val elementTypeArg = targetAnnotation.arguments.firstOrNull() ?: continue
|
val elementTypeArg = targetAnnotation.arguments.firstOrNull() ?: continue
|
||||||
|
|
||||||
when (elementTypeArg) {
|
when (elementTypeArg) {
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
// FILE: a/x.java
|
||||||
|
package a;
|
||||||
|
|
||||||
|
public interface x {
|
||||||
|
|
||||||
|
double D = Double.MAX_VALUE;
|
||||||
|
double D2 = D - 32.12111;
|
||||||
|
|
||||||
|
float F = Float.MAX_VALUE;
|
||||||
|
float F2 = F - 1231.965f;
|
||||||
|
|
||||||
|
int I = Integer.MAX_VALUE;
|
||||||
|
int I2 = I - 42;
|
||||||
|
|
||||||
|
byte B = Byte.MAX_VALUE;
|
||||||
|
byte B2 = B - 3;
|
||||||
|
|
||||||
|
long L = Long.MAX_VALUE;
|
||||||
|
long L2 = L - 5545342;
|
||||||
|
|
||||||
|
short S = Short.MAX_VALUE;
|
||||||
|
short S2 = S - 5;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
package a {
|
||||||
|
|
||||||
|
public interface x {
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
|
||||||
|
// Static members
|
||||||
|
public const final val B: kotlin.Byte = 127.toByte()
|
||||||
|
public const final val B2: kotlin.Byte = 124.toByte()
|
||||||
|
public const final val D: kotlin.Double = 1.7976931348623157E308.toDouble()
|
||||||
|
public const final val D2: kotlin.Double = 1.7976931348623157E308.toDouble()
|
||||||
|
public const final val F: kotlin.Float = 3.4028235E38.toFloat()
|
||||||
|
public const final val F2: kotlin.Float = 3.4028235E38.toFloat()
|
||||||
|
public const final val I: kotlin.Int = 2147483647
|
||||||
|
public const final val I2: kotlin.Int = 2147483605
|
||||||
|
public const final val L: kotlin.Long = 9223372036854775807.toLong()
|
||||||
|
public const final val L2: kotlin.Long = 9223372036849230465.toLong()
|
||||||
|
public const final val S: kotlin.Short = 32767.toShort()
|
||||||
|
public const final val S2: kotlin.Short = 32762.toShort()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
// FILE: a/x.java
|
||||||
|
package a;
|
||||||
|
|
||||||
|
public class x {
|
||||||
|
public static class y {
|
||||||
|
public static final int I = 42;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: b/x.java
|
||||||
|
package b;
|
||||||
|
|
||||||
|
public class x {
|
||||||
|
public static final int I = a.x.y.I;
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
package a {
|
||||||
|
|
||||||
|
public open class x {
|
||||||
|
public constructor x()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
|
||||||
|
public open class y {
|
||||||
|
public constructor y()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
|
||||||
|
// Static members
|
||||||
|
public const final val I: kotlin.Int = 42
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
package b {
|
||||||
|
|
||||||
|
public open class x {
|
||||||
|
public constructor x()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
|
||||||
|
// Static members
|
||||||
|
public const final val I: kotlin.Int = 42
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
// FILE: test.kt
|
||||||
|
package a
|
||||||
|
|
||||||
|
const val CONST = "CONST"
|
||||||
|
|
||||||
|
open class Test {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val CONST = 42
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: a/x.java
|
||||||
|
package a;
|
||||||
|
|
||||||
|
public class x {
|
||||||
|
|
||||||
|
public static final String CONST1 = TestKt.CONST;
|
||||||
|
public static final int CONST2 = Test.CONST;
|
||||||
|
|
||||||
|
public class y extends Test {
|
||||||
|
public static final int I = CONST;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
package a {
|
||||||
|
public const val CONST: kotlin.String = "CONST"
|
||||||
|
|
||||||
|
public open class Test {
|
||||||
|
public constructor Test()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
|
||||||
|
public companion object Companion {
|
||||||
|
private constructor Companion()
|
||||||
|
public const final val CONST: kotlin.Int = 42
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public open class x {
|
||||||
|
public constructor x()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
|
||||||
|
public open inner class y : a.Test {
|
||||||
|
public constructor y()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
|
||||||
|
// Static members
|
||||||
|
public const final val I: kotlin.Int = 42
|
||||||
|
}
|
||||||
|
|
||||||
|
// Static members
|
||||||
|
public const final val CONST1: kotlin.String = "CONST"
|
||||||
|
public const final val CONST2: kotlin.Int = 42
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
// FILE: a/X.java
|
||||||
|
package a;
|
||||||
|
|
||||||
|
public interface X {
|
||||||
|
int I = 42;
|
||||||
|
|
||||||
|
interface Y extends X {
|
||||||
|
int O = I;
|
||||||
|
class XY implements X, Y {
|
||||||
|
public static final int I = O + X.I;
|
||||||
|
public class XYZ extends XY implements Y {
|
||||||
|
int O = I;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class C {
|
||||||
|
public static final double Pi = 3.14;
|
||||||
|
interface I {
|
||||||
|
double Pi = 41.3;
|
||||||
|
class Z {
|
||||||
|
public static final double CONST = Pi;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
package a {
|
||||||
|
|
||||||
|
public interface X {
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
|
||||||
|
public open class C {
|
||||||
|
public constructor C()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
|
||||||
|
public/*package*/ interface I {
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
|
||||||
|
public open class Z {
|
||||||
|
public constructor Z()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
|
||||||
|
// Static members
|
||||||
|
public const final val CONST: kotlin.Double = 41.3.toDouble()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Static members
|
||||||
|
public const final val Pi: kotlin.Double = 41.3.toDouble()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Static members
|
||||||
|
public const final val Pi: kotlin.Double = 3.14.toDouble()
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface Y : a.X {
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
|
||||||
|
public open class XY : a.X, a.X.Y {
|
||||||
|
public constructor XY()
|
||||||
|
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
|
||||||
|
public open inner class XYZ : a.X.Y.XY, a.X.Y {
|
||||||
|
public constructor XYZ()
|
||||||
|
public/*package*/ final var O: kotlin.Int
|
||||||
|
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
|
||||||
|
// Static members
|
||||||
|
public const final override /*1*/ /*fake_override*/ val I: kotlin.Int = 84
|
||||||
|
public const final override /*1*/ /*fake_override*/ val I: kotlin.Int = 42
|
||||||
|
public const final override /*2*/ /*fake_override*/ val O: kotlin.Int = 42
|
||||||
|
}
|
||||||
|
|
||||||
|
// Static members
|
||||||
|
public const final val I: kotlin.Int = 84
|
||||||
|
public const final override /*1*/ /*fake_override*/ val O: kotlin.Int = 42
|
||||||
|
}
|
||||||
|
|
||||||
|
// Static members
|
||||||
|
public const final override /*1*/ /*fake_override*/ val I: kotlin.Int = 42
|
||||||
|
public const final val O: kotlin.Int = 42
|
||||||
|
}
|
||||||
|
|
||||||
|
// Static members
|
||||||
|
public const final val I: kotlin.Int = 42
|
||||||
|
}
|
||||||
|
}
|
||||||
+6
@@ -886,6 +886,12 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("annotatedExpressionInsideAnnotation.kt")
|
||||||
|
public void testAnnotatedExpressionInsideAnnotation() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/annotations/annotatedExpressionInsideAnnotation.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("AnnotatedLocalObjectFun.kt")
|
@TestMetadata("AnnotatedLocalObjectFun.kt")
|
||||||
public void testAnnotatedLocalObjectFun() throws Exception {
|
public void testAnnotatedLocalObjectFun() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/annotations/AnnotatedLocalObjectFun.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/annotations/AnnotatedLocalObjectFun.kt");
|
||||||
|
|||||||
+48
@@ -44,12 +44,30 @@ public class JavacFieldResolutionTestGenerated extends AbstractJavacFieldResolut
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("BinaryInitializers.kt")
|
||||||
|
public void testBinaryInitializers() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/javac/fieldsResolution/tests/BinaryInitializers.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("ConstantByFqName.kt")
|
||||||
|
public void testConstantByFqName() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/javac/fieldsResolution/tests/ConstantByFqName.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("ConstantValues.kt")
|
@TestMetadata("ConstantValues.kt")
|
||||||
public void testConstantValues() throws Exception {
|
public void testConstantValues() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/javac/fieldsResolution/tests/ConstantValues.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/javac/fieldsResolution/tests/ConstantValues.kt");
|
||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("ConstantValuesFromKtFile.kt")
|
||||||
|
public void testConstantValuesFromKtFile() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/javac/fieldsResolution/tests/ConstantValuesFromKtFile.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("FieldFromOuterClass.kt")
|
@TestMetadata("FieldFromOuterClass.kt")
|
||||||
public void testFieldFromOuterClass() throws Exception {
|
public void testFieldFromOuterClass() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/javac/fieldsResolution/tests/FieldFromOuterClass.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/javac/fieldsResolution/tests/FieldFromOuterClass.kt");
|
||||||
@@ -62,6 +80,12 @@ public class JavacFieldResolutionTestGenerated extends AbstractJavacFieldResolut
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("MultipleOuters.kt")
|
||||||
|
public void testMultipleOuters() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/javac/fieldsResolution/tests/MultipleOuters.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("ResolutionPriority.kt")
|
@TestMetadata("ResolutionPriority.kt")
|
||||||
public void testResolutionPriority() throws Exception {
|
public void testResolutionPriority() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/javac/fieldsResolution/tests/ResolutionPriority.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/javac/fieldsResolution/tests/ResolutionPriority.kt");
|
||||||
@@ -101,12 +125,30 @@ public class JavacFieldResolutionTestGenerated extends AbstractJavacFieldResolut
|
|||||||
doTestWithoutJavacWrapper(fileName);
|
doTestWithoutJavacWrapper(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("BinaryInitializers.kt")
|
||||||
|
public void testBinaryInitializers() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/javac/fieldsResolution/tests/BinaryInitializers.kt");
|
||||||
|
doTestWithoutJavacWrapper(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("ConstantByFqName.kt")
|
||||||
|
public void testConstantByFqName() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/javac/fieldsResolution/tests/ConstantByFqName.kt");
|
||||||
|
doTestWithoutJavacWrapper(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("ConstantValues.kt")
|
@TestMetadata("ConstantValues.kt")
|
||||||
public void testConstantValues() throws Exception {
|
public void testConstantValues() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/javac/fieldsResolution/tests/ConstantValues.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/javac/fieldsResolution/tests/ConstantValues.kt");
|
||||||
doTestWithoutJavacWrapper(fileName);
|
doTestWithoutJavacWrapper(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("ConstantValuesFromKtFile.kt")
|
||||||
|
public void testConstantValuesFromKtFile() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/javac/fieldsResolution/tests/ConstantValuesFromKtFile.kt");
|
||||||
|
doTestWithoutJavacWrapper(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("FieldFromOuterClass.kt")
|
@TestMetadata("FieldFromOuterClass.kt")
|
||||||
public void testFieldFromOuterClass() throws Exception {
|
public void testFieldFromOuterClass() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/javac/fieldsResolution/tests/FieldFromOuterClass.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/javac/fieldsResolution/tests/FieldFromOuterClass.kt");
|
||||||
@@ -119,6 +161,12 @@ public class JavacFieldResolutionTestGenerated extends AbstractJavacFieldResolut
|
|||||||
doTestWithoutJavacWrapper(fileName);
|
doTestWithoutJavacWrapper(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("MultipleOuters.kt")
|
||||||
|
public void testMultipleOuters() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/javac/fieldsResolution/tests/MultipleOuters.kt");
|
||||||
|
doTestWithoutJavacWrapper(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("ResolutionPriority.kt")
|
@TestMetadata("ResolutionPriority.kt")
|
||||||
public void testResolutionPriority() throws Exception {
|
public void testResolutionPriority() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/javac/fieldsResolution/tests/ResolutionPriority.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/javac/fieldsResolution/tests/ResolutionPriority.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user