diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.kt b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.kt index 20483fde804..fd79b40e081 100644 --- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.kt +++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.kt @@ -149,7 +149,7 @@ class K2JVMCompilerArguments : CommonCompilerArguments() { var useJavac: Boolean by FreezableVar(false) @Argument(value = "-Xcompile-java", description = "Reuse javac analysis and compile Java source files") - public boolean compileJava; + var compileJava by FreezableVar(false) @Argument( value = "-Xjavac-arguments", diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.kt index bbb6464efd5..3adb2d34c16 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.kt @@ -253,7 +253,7 @@ class K2JVMCompiler : CLICompiler() { private fun compileJavaFilesIfNeeded(environment: KotlinCoreEnvironment, arguments: K2JVMCompilerArguments): Boolean { - if (arguments.useJavac) { + if (arguments.compileJava) { return JavacWrapper.getInstance(environment.project).use { it.compile() } } return true diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt index 295ae1cc3e7..2089cc3eebb 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt @@ -279,7 +279,7 @@ class KotlinCoreEnvironment private constructor( bootClasspath: List? = null, sourcePath: List? = null ): 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 diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/javac/JavacWrapperKotlinResolverImpl.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/javac/JavacWrapperKotlinResolverImpl.kt index 7cd332316c3..1841cd901bc 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/javac/JavacWrapperKotlinResolverImpl.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/javac/JavacWrapperKotlinResolverImpl.kt @@ -17,8 +17,9 @@ package org.jetbrains.kotlin.cli.jvm.javac import com.intellij.psi.PsiClass +import org.jetbrains.kotlin.asJava.LightClassGenerationSupport 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.resolve.MockKotlinField 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.Name 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() @@ -44,6 +46,12 @@ class JavacWrapperKotlinResolverImpl(private val lightClassGenerationSupport: Cl 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? = cache[this] ?: lightClassGenerationSupport.getLightClass(this)?.also { cache[this] = it } diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/javac/JavacWrapperRegistrar.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/javac/JavacWrapperRegistrar.kt index 09a969e0855..7aee6d7cf4e 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/javac/JavacWrapperRegistrar.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/javac/JavacWrapperRegistrar.kt @@ -18,9 +18,9 @@ package org.jetbrains.kotlin.cli.jvm.javac import com.intellij.mock.MockProject 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.messages.CompilerMessageSeverity.STRONG_WARNING -import org.jetbrains.kotlin.cli.jvm.compiler.CliLightClassGenerationSupport import org.jetbrains.kotlin.cli.jvm.config.jvmClasspathRoots import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.config.JVMConfigurationKeys @@ -40,7 +40,7 @@ object JavacWrapperRegistrar { arguments: Array?, bootClasspath: List?, sourcePath: List?, - lightClassGenerationSupport: CliLightClassGenerationSupport + lightClassGenerationSupport: LightClassGenerationSupport ): Boolean { val messageCollector = configuration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY) diff --git a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/JavaClassWithClassId.kt b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/JavaClassWithClassId.kt new file mode 100644 index 00000000000..d83808b2121 --- /dev/null +++ b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/JavaClassWithClassId.kt @@ -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? +} \ No newline at end of file diff --git a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/JavacWrapper.kt b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/JavacWrapper.kt index c578c1e00ea..9baec024782 100644 --- a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/JavacWrapper.kt +++ b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/JavacWrapper.kt @@ -21,7 +21,6 @@ import com.intellij.openapi.project.Project import com.intellij.openapi.vfs.StandardFileSystems import com.intellij.openapi.vfs.VirtualFile import com.intellij.openapi.vfs.VirtualFileManager -import com.intellij.psi.CommonClassNames import com.intellij.psi.search.EverythingGlobalScope import com.intellij.psi.search.GlobalSearchScope import com.sun.source.tree.CompilationUnitTree @@ -80,21 +79,21 @@ class JavacWrapper( fun getInstance(project: Project): JavacWrapper = ServiceManager.getService(project, JavacWrapper::class.java) } - private fun createCommonClassifierType(fqName: String) = - findClassInSymbols(fqName)?.let { + private fun createCommonClassifierType(classId: ClassId) = + findClassInSymbols(classId)?.let { SymbolBasedClassifierType(it.element.asType(), this) } val JAVA_LANG_OBJECT by lazy { - createCommonClassifierType(CommonClassNames.JAVA_LANG_OBJECT) + createCommonClassifierType(classId("java.lang", "Object")) } val JAVA_LANG_ENUM by lazy { - findClassInSymbols(CommonClassNames.JAVA_LANG_ENUM) + findClassInSymbols(classId("java.lang", "Enum")) } val JAVA_LANG_ANNOTATION_ANNOTATION by lazy { - createCommonClassifierType(CommonClassNames.JAVA_LANG_ANNOTATION_ANNOTATION) + createCommonClassifierType(classId("java.lang.annotation", "Annotation")) } init { @@ -133,31 +132,15 @@ class JavacWrapper( private val fileObjects = fileManager.getJavaFileObjectsFromFiles(javaFiles).toJavacList() private val compilationUnits: JavacList = fileObjects.map(javac::parse).toJavacList() - private val treeBasedJavaClasses = hashMapOf() - - private val javaClassDeclarations = compilationUnits.flatMap { unit -> + private val treeBasedJavaClasses = compilationUnits.flatMap { unit -> unit.typeDecls.map { classDeclaration -> val packageName = unit.packageName?.toString() ?: "" val className = (classDeclaration as JCTree.JCClassDecl).simpleName.toString() val classId = classId(packageName, className) - classId to Pair(classDeclaration, unit) + classId to TreeBasedClass(classDeclaration, trees.getPath(unit, classDeclaration), this, unit.sourceFile, classId) } }.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 .mapTo(hashSetOf()) { unit -> unit.packageName?.toString()?.let { packageName -> @@ -176,8 +159,9 @@ class JavacWrapper( val classifierResolver = ClassifierResolver(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() + private val symbolBasedClassesCache = hashMapOf() fun compile(outDir: File? = null): Boolean = with(javac) { if (!compileJava) return true @@ -211,12 +195,19 @@ class JavacWrapper( return outerClass } - getTreeBasedClass(classId)?.let { javaClass -> + treeBasedJavaClasses[classId]?.let { 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 { - (it.element as Symbol.PackageSymbol).findClass(classId.relativeClassName.asString())?.let { javaClass -> + (it.element as Symbol.PackageSymbol).findClass(classId)?.let { javaClass -> javaClass.virtualFile?.let { file -> if (file in scope) return javaClass } @@ -249,20 +240,20 @@ class JavacWrapper( packageSourceAnnotations[fqName] ?: emptyList() fun findClassesFromPackage(fqName: FqName): List = - javaClassDeclarations + treeBasedJavaClasses .filterKeys { it.packageFqName == fqName } - .map { getTreeBasedClass(it.key)!! } + + .map { treeBasedJavaClasses[it.key]!! } + elements.getPackageElement(fqName.asString()) ?.members() ?.elements ?.filterIsInstance(Symbol.ClassSymbol::class.java) - ?.map { SymbolBasedClass(it, this, it.classfile) } + ?.map { SymbolBasedClass(it, this, null, it.classfile) } .orEmpty() fun knownClassNamesInPackage(fqName: FqName): Set = - javaClassDeclarations + treeBasedJavaClasses .filterKeys { it.packageFqName == fqName } - .mapTo(hashSetOf()) { it.key.shortClassName.asString() } + + .mapTo(hashSetOf()) { it.value.name.asString() } + elements.getPackageElement(fqName.asString()) ?.members_field ?.elements @@ -309,9 +300,9 @@ class JavacWrapper( private inline fun Iterable.toJavacList() = JavacList.from(this) - private fun findClassInSymbols(fqName: String): SymbolBasedClass? = - elements.getTypeElement(fqName)?.let { symbol -> - SymbolBasedClass(symbol, this, symbol.classfile) + private fun findClassInSymbols(classId: ClassId): SymbolBasedClass? = + elements.getTypeElement(classId.asSingleFqName().asString())?.let { symbol -> + SymbolBasedClass(symbol, this, classId, symbol.classfile) } 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(".") var symbol = members_field?.getElementsByName(names.fromString(nameParts.first())) ?.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 } } } \ No newline at end of file diff --git a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/JavacWrapperKotlinResolver.kt b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/JavacWrapperKotlinResolver.kt index 8a7743db49d..9f0d019ddbd 100644 --- a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/JavacWrapperKotlinResolver.kt +++ b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/JavacWrapperKotlinResolver.kt @@ -19,9 +19,12 @@ package org.jetbrains.kotlin.javac import org.jetbrains.kotlin.load.java.structure.JavaField import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.psi.KtClassOrObject +import org.jetbrains.kotlin.psi.KtFile interface JavacWrapperKotlinResolver { fun resolveSupertypes(classOrObject: KtClassOrObject): List fun findField(classOrObject: KtClassOrObject, name: String): JavaField? + + fun findField(ktFile: KtFile?, name: String): JavaField? } \ No newline at end of file diff --git a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/resolve/ClassifierResolver.kt b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/resolve/ClassifierResolver.kt index c97c13e0262..8870c5e56ef 100644 --- a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/resolve/ClassifierResolver.kt +++ b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/resolve/ClassifierResolver.kt @@ -238,7 +238,7 @@ private class CurrentClassAndInnerScope(javac: JavacWrapper, override fun findClass(name: String, pathSegments: List): JavaClassifier? { val identifier = Name.identifier(name) - treePath.enclosingClasses.forEach { + treePath.enclosingClasses().forEach { (it as? TreeBasedClass)?.typeParameters ?.find { typeParameter -> typeParameter.name == identifier } ?.let { typeParameter -> return typeParameter } @@ -251,31 +251,30 @@ private class CurrentClassAndInnerScope(javac: JavacWrapper, return parent.findClass(name, pathSegments) } - private val TreePath.enclosingClasses: List - get() { - val outerClasses = filterIsInstance() - .dropWhile { it.extending == leaf || leaf in it.implementing } - .asReversed() - .map { it.simpleName.toString() } + private fun TreePath.enclosingClasses(): List { + val outerClasses = filterIsInstance() + .dropWhile { it.extending == leaf || leaf in it.implementing } + .asReversed() + .map { it.simpleName.toString() } - val packageName = compilationUnit.packageName?.toString() ?: "" - val outermostClassName = outerClasses.firstOrNull() ?: return emptyList() + val packageName = compilationUnit.packageName?.toString() ?: "" + val outermostClassName = outerClasses.firstOrNull() ?: return emptyList() - val outermostClassId = classId(packageName, outermostClassName) - var outermostClass = javac.findClass(outermostClassId) ?: return emptyList() + val outermostClassId = classId(packageName, outermostClassName) + var outermostClass = javac.findClass(outermostClassId) ?: return emptyList() - val classes = arrayListOf() + val classes = arrayListOf() + 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) - - 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)) \ No newline at end of file diff --git a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/resolve/ConstantEvaluator.kt b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/resolve/ConstantEvaluator.kt new file mode 100644 index 00000000000..b85510ed496 --- /dev/null +++ b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/resolve/ConstantEvaluator.kt @@ -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 + } + +} \ No newline at end of file diff --git a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/resolve/IdentifierResolver.kt b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/resolve/IdentifierResolver.kt index 5cadc4f8c94..8494d9ce266 100644 --- a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/resolve/IdentifierResolver.kt +++ b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/resolve/IdentifierResolver.kt @@ -65,7 +65,12 @@ private abstract class FieldScope(protected val javac: JavacWrapper, .mapNotNull { val classifier = it.classifier as? JavaClass if (classifier !in checkedSupertypes) { - classifier?.findFieldIncludingSupertypes(name, checkedSupertypes) + if (classifier is MockKotlinClassifier) { + classifier.findField(name.asString()) + } + else { + classifier?.findFieldIncludingSupertypes(name, checkedSupertypes) + } } else null }.singleOrNull() diff --git a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/resolve/KotlinClassifiersCache.kt b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/resolve/KotlinClassifiersCache.kt index b4be8a9a705..cd14c1a755e 100644 --- a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/resolve/KotlinClassifiersCache.kt +++ b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/resolve/KotlinClassifiersCache.kt @@ -22,6 +22,8 @@ import com.intellij.psi.PsiLiteralExpression import com.intellij.psi.search.SearchScope import org.jetbrains.kotlin.descriptors.Visibilities 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.lexer.KtTokens 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.Name 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.psi.* import org.jetbrains.kotlin.psi.psiUtil.visibilityModifierType @@ -38,9 +39,12 @@ class KotlinClassifiersCache(sourceFiles: Collection, private val javac: JavacWrapper) { private val kotlinPackages = hashSetOf() + private val kotlinFacadeClasses = hashMapOf() private val kotlinClasses: Map = sourceFiles.flatMap { ktFile -> kotlinPackages.add(ktFile.packageFqName) + val facadeFqName = ktFile.javaFileFacadeFqName + kotlinFacadeClasses[ClassId(facadeFqName.parent(), facadeFqName.shortName())] = ktFile ktFile.declarations .filterIsInstance() .map { it.computeClassId() to it } @@ -50,9 +54,11 @@ class KotlinClassifiersCache(sourceFiles: Collection, fun getKotlinClassifier(classId: ClassId) = classifiers[classId] ?: createClassifier(classId) - fun createMockKotlinClassifier(classifier: KtClassOrObject, + fun createMockKotlinClassifier(classifier: KtClassOrObject?, + ktFile: KtFile?, classId: ClassId) = MockKotlinClassifier(classId, classifier, + ktFile, this, javac) .apply { classifiers[classId] = this } @@ -60,11 +66,14 @@ class KotlinClassifiersCache(sourceFiles: Collection, fun hasPackage(packageFqName: FqName) = kotlinPackages.contains(packageFqName) private fun createClassifier(classId: ClassId): JavaClass? { + kotlinFacadeClasses[classId]?.let { + return createMockKotlinClassifier(null, it, classId) + } if (classId.isNestedClass) { classifiers[classId]?.let { return it } val pathSegments = classId.relativeClassName.pathSegments().map { it.asString() } 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 { outerClass = outerClass.findInnerClass(Name.identifier(it)) ?: return null @@ -75,21 +84,25 @@ class KotlinClassifiersCache(sourceFiles: Collection, val kotlinClassifier = kotlinClasses[classId] ?: return null - return createMockKotlinClassifier(kotlinClassifier, classId) + return createMockKotlinClassifier(kotlinClassifier, null, classId) } } -class MockKotlinClassifier(val classId: ClassId, - private val classOrObject: KtClassOrObject, +class MockKotlinClassifier(override val classId: ClassId, + private val classOrObject: KtClassOrObject?, + private val ktFile: KtFile?, private val cache: KotlinClassifiersCache, - private val javac: JavacWrapper) : VirtualFileBoundJavaClass { + private val javac: JavacWrapper) : JavaClassWithClassId { override val fqName: FqName get() = classId.asSingleFqName() override val visibility: Visibility - get() = when (classOrObject.visibilityModifierType()) { + get() = if (classOrObject == null) { + Visibilities.PUBLIC + } + else when (classOrObject.visibilityModifierType()) { null, KtTokens.PUBLIC_KEYWORD -> Visibilities.PUBLIC KtTokens.PRIVATE_KEYWORD -> Visibilities.PRIVATE KtTokens.PROTECTED_KEYWORD -> Visibilities.PROTECTED @@ -97,17 +110,19 @@ class MockKotlinClassifier(val classId: ClassId, } override val supertypes: Collection - get() = javac.kotlinResolver.resolveSupertypes(classOrObject) + get() = if (classOrObject == null) { + emptyList() + } + else javac.kotlinResolver.resolveSupertypes(classOrObject) .mapNotNull { javac.getKotlinClassifier(it) ?: javac.findClass(it) } .map { MockKotlinClassifierType(it) } val innerClasses: Collection - get() = classOrObject.declarations.filterIsInstance() - .mapNotNull { nestedClassOrObject -> - nestedClassOrObject.computeClassId()?.let { - cache.createMockKotlinClassifier(nestedClassOrObject, it) - } - } + get() = classOrObject?.declarations + ?.filterIsInstance() + ?.mapNotNull { nestedClassOrObject -> + cache.createMockKotlinClassifier(nestedClassOrObject, ktFile, classId.createNestedClassId(nestedClassOrObject.nameAsSafeName)) + } ?: emptyList() override val lightClassOriginKind get() = LightClassOriginKind.SOURCE @@ -127,12 +142,12 @@ class MockKotlinClassifier(val classId: ClassId, innerClasses.find { it.name == name } val typeParametersNumber: Int - get() = classOrObject.typeParameters.size + get() = classOrObject?.typeParameters?.size ?: 0 val hasTypeParameters: Boolean 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 get() = throw UnsupportedOperationException("Should not be called") diff --git a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/resolve/ResolveHelper.kt b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/resolve/ResolveHelper.kt index 050c7c7d968..b0ef04b88e8 100644 --- a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/resolve/ResolveHelper.kt +++ b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/resolve/ResolveHelper.kt @@ -18,8 +18,8 @@ package org.jetbrains.kotlin.javac.resolve import com.sun.source.util.TreePath import org.jetbrains.kotlin.descriptors.Visibilities +import org.jetbrains.kotlin.javac.JavaClassWithClassId 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.structure.JavaClass import org.jetbrains.kotlin.name.ClassId @@ -82,7 +82,7 @@ internal class ResolveHelper(private val javac: JavacWrapper, when (innerOrNestedClass.visibility) { Visibilities.PRIVATE -> null 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 } else -> innerOrNestedClass diff --git a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/symbols/SymbolBasedAnnotation.kt b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/symbols/SymbolBasedAnnotation.kt index 33df7123d44..b6a595526ae 100644 --- a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/symbols/SymbolBasedAnnotation.kt +++ b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/symbols/SymbolBasedAnnotation.kt @@ -36,11 +36,9 @@ open class SymbolBasedAnnotation( SymbolBasedAnnotationArgument.create(value.value, Name.identifier(key.simpleName.toString()), javac) } - override val classId: ClassId? - get() = (annotationMirror.annotationType.asElement() as? TypeElement)?.computeClassId() + override val classId: ClassId + get() = (annotationMirror.annotationType.asElement() as TypeElement).computeClassId()!! - override fun resolve() = with(annotationMirror.annotationType.asElement() as Symbol.ClassSymbol) { - SymbolBasedClass(this, javac, classfile) - } + override fun resolve() = with(annotationMirror.annotationType.asElement() as Symbol.ClassSymbol) { javac.findClass(classId) } } \ No newline at end of file diff --git a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/symbols/SymbolBasedClass.kt b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/symbols/SymbolBasedClass.kt index 5ee89ed8752..5dfb9c1cb67 100644 --- a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/symbols/SymbolBasedClass.kt +++ b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/symbols/SymbolBasedClass.kt @@ -20,9 +20,10 @@ import com.intellij.openapi.vfs.VirtualFile import com.intellij.psi.CommonClassNames import com.intellij.psi.search.SearchScope import org.jetbrains.kotlin.descriptors.Visibility +import org.jetbrains.kotlin.javac.JavaClassWithClassId import org.jetbrains.kotlin.javac.JavacWrapper 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.Name import javax.lang.model.element.ElementKind @@ -37,8 +38,9 @@ import javax.tools.JavaFileObject class SymbolBasedClass( element: TypeElement, javac: JavacWrapper, + override val classId: ClassId?, val file: JavaFileObject? -) : SymbolBasedClassifier(element, javac), VirtualFileBoundJavaClass { +) : SymbolBasedClassifier(element, javac), JavaClassWithClassId { override val name: Name get() = Name.identifier(element.simpleName.toString()) @@ -62,28 +64,34 @@ class SymbolBasedClass( get() = FqName(element.qualifiedName.toString()) override val supertypes: Collection - get() = arrayListOf() - .apply { - element.superclass.takeIf { it !is NoType }?.let(this::add) - } - .apply { addAll(element.interfaces) } - .mapTo(arrayListOf()) { SymbolBasedClassifierType(it, javac) } - .apply { - if (isEmpty() && element.qualifiedName.toString() != CommonClassNames.JAVA_LANG_OBJECT) { - javac.JAVA_LANG_OBJECT?.let { add(it) } - } - } + by lazy { + arrayListOf() + .apply { + element.superclass.takeIf { it !is NoType }?.let(this::add) + addAll(element.interfaces) + } + .mapTo(arrayListOf()) { SymbolBasedClassifierType(it, javac) } + .apply { + if (isEmpty() && element.qualifiedName.toString() != CommonClassNames.JAVA_LANG_OBJECT) { + javac.JAVA_LANG_OBJECT?.let { add(it) } + } + } + } val innerClasses: Map - get() = element.enclosedElements - .filterIsInstance(TypeElement::class.java) - .map { SymbolBasedClass(it, javac, file) } - .associateBy(JavaClass::name) + by lazy { + element.enclosedElements + .filterIsInstance(TypeElement::class.java) + .map { SymbolBasedClass(it, javac, classId?.createNestedClassId(Name.identifier(it.simpleName.toString())), file) } + .associateBy(JavaClass::name) + } override val outerClass: JavaClass? - get() = element.enclosingElement?.let { - if (it.asType().kind != TypeKind.DECLARED) null else SymbolBasedClass(it as TypeElement, javac, file) - } + by lazy { + element.enclosingElement?.let { + if (it.asType().kind != TypeKind.DECLARED) null else SymbolBasedClass(it as TypeElement, javac, classId?.outerClassId, file) + } + } override val isInterface: Boolean get() = element.kind == ElementKind.INTERFACE @@ -99,8 +107,8 @@ class SymbolBasedClass( override val methods: Collection get() = element.enclosedElements - .filter { it.kind == ElementKind.METHOD && !isEnumValuesOrValueOf(it as ExecutableElement)} - .map { SymbolBasedMethod(it as ExecutableElement, javac) } + .filter { it.kind == ElementKind.METHOD && !isEnumValuesOrValueOf(it as ExecutableElement) } + .map { SymbolBasedMethod(it as ExecutableElement, this, javac) } private fun isEnumValuesOrValueOf(method: ExecutableElement): Boolean { return isEnum && when (method.simpleName.toString()) { @@ -113,12 +121,12 @@ class SymbolBasedClass( override val fields: Collection get() = element.enclosedElements .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 get() = element.enclosedElements .filter { it.kind == ElementKind.CONSTRUCTOR } - .map { SymbolBasedConstructor(it as ExecutableElement, javac) } + .map { SymbolBasedConstructor(it as ExecutableElement, this, javac) } override val innerClassNames: Collection get() = innerClasses.keys diff --git a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/symbols/SymbolBasedConstructor.kt b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/symbols/SymbolBasedConstructor.kt index 1c500bbe2f1..3aeb896b634 100644 --- a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/symbols/SymbolBasedConstructor.kt +++ b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/symbols/SymbolBasedConstructor.kt @@ -17,6 +17,7 @@ package org.jetbrains.kotlin.javac.wrappers.symbols 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.JavaTypeParameter import org.jetbrains.kotlin.load.java.structure.JavaValueParameter @@ -24,8 +25,9 @@ import javax.lang.model.element.ExecutableElement class SymbolBasedConstructor( element: ExecutableElement, + containingClass: JavaClass, javac: JavacWrapper -) : SymbolBasedMember(element, javac), JavaConstructor { +) : SymbolBasedMember(element, containingClass, javac), JavaConstructor { override val typeParameters: List get() = element.typeParameters.map { SymbolBasedTypeParameter(it, javac) } diff --git a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/symbols/SymbolBasedField.kt b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/symbols/SymbolBasedField.kt index 7b4f080faf4..5d9ee2285c7 100644 --- a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/symbols/SymbolBasedField.kt +++ b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/symbols/SymbolBasedField.kt @@ -17,17 +17,17 @@ package org.jetbrains.kotlin.javac.wrappers.symbols 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.JavaType import javax.lang.model.element.ElementKind -import javax.lang.model.element.TypeElement import javax.lang.model.element.VariableElement -import javax.lang.model.type.DeclaredType class SymbolBasedField( element: VariableElement, + containingClass: JavaClass, javac: JavacWrapper -) : SymbolBasedMember(element, javac), JavaField { +) : SymbolBasedMember(element, containingClass, javac), JavaField { override val isEnumEntry: Boolean get() = element.kind == ElementKind.ENUM_CONSTANT @@ -36,12 +36,9 @@ class SymbolBasedField( get() = SymbolBasedType.create(element.asType(), javac) override val initializerValue: Any? - get() = element.constantValue + by lazy { element.constantValue } override val hasConstantNotNullInitializer: Boolean - get() = element.constantValue != null && element.asType().let { - it.kind.isPrimitive || - ((it as? DeclaredType)?.asElement() as? TypeElement)?.qualifiedName?.toString() == "java.lang.String" - } + get() = initializerValue != null } \ No newline at end of file diff --git a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/symbols/SymbolBasedMember.kt b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/symbols/SymbolBasedMember.kt index b70d3d6ebce..9b5183b5c35 100644 --- a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/symbols/SymbolBasedMember.kt +++ b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/symbols/SymbolBasedMember.kt @@ -16,7 +16,6 @@ package org.jetbrains.kotlin.javac.wrappers.symbols -import com.sun.tools.javac.code.Symbol import org.jetbrains.kotlin.descriptors.Visibility import org.jetbrains.kotlin.javac.JavacWrapper import org.jetbrains.kotlin.load.java.structure.JavaAnnotation @@ -28,14 +27,10 @@ import javax.lang.model.element.Element abstract class SymbolBasedMember( element: T, + override val containingClass: JavaClass, javac: JavacWrapper ) : SymbolBasedElement(element, javac), JavaMember { - override val containingClass: JavaClass - get() = with(element.enclosingElement as Symbol.ClassSymbol) { - SymbolBasedClass(this, javac, classfile) - } - override val annotations: Collection get() = element.annotationMirrors.map { SymbolBasedAnnotation(it, javac) } diff --git a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/symbols/SymbolBasedMethod.kt b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/symbols/SymbolBasedMethod.kt index cdfcc4ec6b7..cfcae045f8f 100644 --- a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/symbols/SymbolBasedMethod.kt +++ b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/symbols/SymbolBasedMethod.kt @@ -22,8 +22,9 @@ import javax.lang.model.element.ExecutableElement class SymbolBasedMethod( element: ExecutableElement, + containingClass: JavaClass, javac: JavacWrapper -) : SymbolBasedMember(element, javac), JavaMethod { +) : SymbolBasedMember(element, containingClass, javac), JavaMethod { override val typeParameters: List get() = element.typeParameters.map { SymbolBasedTypeParameter(it, javac) } diff --git a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/symbols/SymbolBasedPackage.kt b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/symbols/SymbolBasedPackage.kt index 023da82099f..a758ecdbc7b 100644 --- a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/symbols/SymbolBasedPackage.kt +++ b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/symbols/SymbolBasedPackage.kt @@ -34,7 +34,7 @@ class SymbolBasedPackage( get() = FqName(element.qualifiedName.toString()) override val subPackages: Collection - get() = javac.findSubPackages(FqName(element.qualifiedName.toString())) + get() = javac.findSubPackages(fqName) override val annotations: Collection diff --git a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/symbols/symbolBasedAnnotationArguments.kt b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/symbols/symbolBasedAnnotationArguments.kt index 83230627023..271a221d22d 100644 --- a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/symbols/symbolBasedAnnotationArguments.kt +++ b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/symbols/symbolBasedAnnotationArguments.kt @@ -16,6 +16,7 @@ package org.jetbrains.kotlin.javac.wrappers.symbols +import com.sun.tools.javac.code.Symbol import org.jetbrains.kotlin.javac.JavacWrapper import org.jetbrains.kotlin.load.java.structure.* import org.jetbrains.kotlin.name.Name @@ -26,7 +27,7 @@ import javax.lang.model.type.TypeMirror sealed class SymbolBasedAnnotationArgument( override val name: Name, - val javac: JavacWrapper + protected val javac: JavacWrapper ) : JavaAnnotationArgument, JavaElement { companion object { @@ -40,7 +41,7 @@ sealed class SymbolBasedAnnotationArgument( } 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) } } @@ -48,7 +49,7 @@ sealed class SymbolBasedAnnotationArgument( } class SymbolBasedAnnotationAsAnnotationArgument( - val mirror: AnnotationMirror, + private val mirror: AnnotationMirror, name: Name, javac: JavacWrapper ) : SymbolBasedAnnotationArgument(name, javac), JavaAnnotationAsAnnotationArgument { @@ -65,12 +66,17 @@ class SymbolBasedReferenceAnnotationArgument( override val entryName: 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( - val type: TypeMirror, + private val type: TypeMirror, name : Name, javac: JavacWrapper ) : SymbolBasedAnnotationArgument(name, javac), JavaClassObjectAnnotationArgument { diff --git a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/symbols/symbolBasedTypes.kt b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/symbols/symbolBasedTypes.kt index 0361b5d9324..f047fc781d2 100644 --- a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/symbols/symbolBasedTypes.kt +++ b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/symbols/symbolBasedTypes.kt @@ -73,12 +73,17 @@ class SymbolBasedClassifierType( ) : SymbolBasedType(typeMirror, javac), JavaClassifierType { override val classifier: JavaClassifier? - get() = when (typeMirror.kind) { - TypeKind.DECLARED -> ((typeMirror as DeclaredType).asElement() as Symbol.ClassSymbol).let { symbol -> - SymbolBasedClass(symbol, javac, symbol.classfile) + by lazy { + when (typeMirror.kind) { + 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 diff --git a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/symbols/utils.kt b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/symbols/utils.kt index 8203cf4a933..823817a7a47 100644 --- a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/symbols/utils.kt +++ b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/symbols/utils.kt @@ -36,21 +36,24 @@ internal val Element.isStatic: Boolean internal val Element.isFinal: Boolean get() = modifiers.contains(Modifier.FINAL) -internal fun Element.getVisibility(): Visibility = when { - Modifier.PUBLIC in modifiers -> Visibilities.PUBLIC - Modifier.PRIVATE in modifiers -> Visibilities.PRIVATE - Modifier.PROTECTED in modifiers -> { - if (Modifier.STATIC in modifiers) { - JavaVisibilities.PROTECTED_STATIC_VISIBILITY - } - else { - JavaVisibilities.PROTECTED_AND_PACKAGE +internal fun Element.getVisibility(): Visibility = modifiers.let { modifiers -> + when { + Modifier.PUBLIC in modifiers -> Visibilities.PUBLIC + Modifier.PRIVATE in modifiers -> Visibilities.PRIVATE + Modifier.PROTECTED in modifiers -> { + if (Modifier.STATIC in modifiers) { + JavaVisibilities.PROTECTED_STATIC_VISIBILITY + } + else { + JavaVisibilities.PROTECTED_AND_PACKAGE + } } + else -> JavaVisibilities.PACKAGE_VISIBILITY } - else -> JavaVisibilities.PACKAGE_VISIBILITY } internal fun TypeElement.computeClassId(): ClassId? { + val enclosingElement = enclosingElement if (enclosingElement.kind != ElementKind.PACKAGE) { val parentClassId = (enclosingElement as TypeElement).computeClassId() ?: return null return parentClassId.createNestedClassId(Name.identifier(simpleName.toString())) @@ -60,11 +63,16 @@ internal fun TypeElement.computeClassId(): ClassId? { } internal fun ExecutableElement.valueParameters(javac: JavacWrapper): List = - parameters.mapIndexed { index, parameter -> - SymbolBasedValueParameter(parameter, - if (!parameter.simpleName.contentEquals("arg$index")) parameter.simpleName.toString() else "p$index", - index == parameters.lastIndex && isVarArgs, - javac) + parameters.let { parameters -> + val isVarArgs = isVarArgs + val lastIndex = parameters.lastIndex + parameters.mapIndexed { index, parameter -> + 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, diff --git a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/trees/TreeBasedAnnotation.kt b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/trees/TreeBasedAnnotation.kt index 40538c8ef9d..32a1d4bac63 100644 --- a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/trees/TreeBasedAnnotation.kt +++ b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/trees/TreeBasedAnnotation.kt @@ -18,7 +18,9 @@ package org.jetbrains.kotlin.javac.wrappers.trees import com.sun.source.util.TreePath import com.sun.tools.javac.tree.JCTree +import org.jetbrains.kotlin.javac.JavaClassWithClassId import org.jetbrains.kotlin.javac.JavacWrapper +import org.jetbrains.kotlin.javac.resolve.ConstantEvaluator import org.jetbrains.kotlin.load.java.structure.* import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName @@ -34,7 +36,7 @@ class TreeBasedAnnotation( get() = createAnnotationArguments(this, javac) 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() = javac.resolve(TreePath.getPath(treePath.compilationUnit, annotation.annotationType)) as? JavaClass @@ -130,11 +132,10 @@ private fun resolveArgumentValue(argument: JCTree.JCExpression, name: Name, treePath: TreePath, javac: JavacWrapper): JavaAnnotationArgument? { - val containingAnnotation = annotation.resolve() - val type = containingAnnotation?.methods?.find { it.name == name }?.returnType ?: return null - val calculator = ValueCalculator(containingAnnotation, javac, treePath, type) + val containingAnnotation = annotation.resolve() ?: return null + val evaluator = ConstantEvaluator(containingAnnotation, javac, treePath) - return calculator.getValue(argument)?.let { TreeBasedLiteralAnnotationArgument(name, it, javac) } + return evaluator.getValue(argument)?.let { TreeBasedLiteralAnnotationArgument(name, it, javac) } } private fun arrayAnnotationArguments(values: List, diff --git a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/trees/TreeBasedClass.kt b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/trees/TreeBasedClass.kt index 17b363bb103..64636e05c47 100644 --- a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/trees/TreeBasedClass.kt +++ b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/trees/TreeBasedClass.kt @@ -25,9 +25,10 @@ import com.sun.tools.javac.tree.JCTree import com.sun.tools.javac.tree.TreeInfo import org.jetbrains.kotlin.descriptors.Visibilities.PUBLIC import org.jetbrains.kotlin.descriptors.Visibility +import org.jetbrains.kotlin.javac.JavaClassWithClassId import org.jetbrains.kotlin.javac.JavacWrapper 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.Name import javax.tools.JavaFileObject @@ -36,8 +37,9 @@ class TreeBasedClass( tree: JCTree.JCClassDecl, treePath: TreePath, javac: JavacWrapper, - val file: JavaFileObject -) : TreeBasedElement(tree, treePath, javac), VirtualFileBoundJavaClass { + val file: JavaFileObject, + override val classId: ClassId? +) : TreeBasedElement(tree, treePath, javac), JavaClassWithClassId { override val name: Name get() = Name.identifier(tree.simpleName.toString()) @@ -70,45 +72,43 @@ class TreeBasedClass( } override val fqName: FqName - get() = treePath.reversed() - .filterIsInstance() - .joinToString( - separator = ".", - transform = JCTree.JCClassDecl::name - ) - .let { treePath.compilationUnit.packageName?.let { packageName -> FqName("$packageName.$it") } ?: FqName.topLevel(Name.identifier(it))} + get() = classId?.asSingleFqName() ?: throw UnsupportedOperationException("classId of $name is null") override val supertypes: Collection - get() = arrayListOf().also { list -> - if (isEnum) { - createEnumSupertype(this, javac).let { list.add(it) } - } else if (isAnnotationType) { - javac.JAVA_LANG_ANNOTATION_ANNOTATION?.let { list.add(it) } - } + by lazy { + arrayListOf().also { list -> + if (isEnum) { + createEnumSupertype(this, javac).let { list.add(it) } + } + else if (isAnnotationType) { + javac.JAVA_LANG_ANNOTATION_ANNOTATION?.let { list.add(it) } + } - tree.extending?.let { - (TreeBasedType.create(it, javac.getTreePath(it, treePath.compilationUnit), javac, emptyList()) as? JavaClassifierType) - ?.let { list.add(it) } - } - tree.implementing?.mapNotNull { - TreeBasedType.create(it, javac.getTreePath(it, treePath.compilationUnit), javac, emptyList()) as? JavaClassifierType - }?.let { list.addAll(it) } + tree.extending?.let { + (TreeBasedType.create(it, javac.getTreePath(it, treePath.compilationUnit), javac, emptyList()) as? JavaClassifierType) + ?.let { list.add(it) } + } + tree.implementing?.mapNotNull { + TreeBasedType.create(it, javac.getTreePath(it, treePath.compilationUnit), javac, emptyList()) as? JavaClassifierType + }?.let { list.addAll(it) } - if (list.isEmpty()) { - javac.JAVA_LANG_OBJECT?.let { list.add(it) } + if (list.isEmpty()) { + javac.JAVA_LANG_OBJECT?.let { list.add(it) } + } + } } - } val innerClasses: Map by lazy { tree.members .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) } override val outerClass: JavaClass? by lazy { (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, javac: JavacWrapper) = object : JavaClassifierType { - override val classifier: JavaClassifier? + override val classifier: JavaClass? get() = javac.JAVA_LANG_ENUM override val typeArguments: List @@ -167,11 +167,12 @@ private fun createEnumSupertype(javaClass: JavaClass, override val annotations: Collection get() = emptyList() override val classifierQualifiedName: String - get() = (classifier as? JavaClass)?.fqName?.asString() ?: "" + get() = classifier?.fqName?.asString() ?: "" override val presentableText: String get() = classifierQualifiedName override val isDeprecatedInJavaDoc: Boolean get() = false + override fun findAnnotation(fqName: FqName) = null private inner class TypeArgument : JavaClassifierType { @@ -189,6 +190,7 @@ private fun createEnumSupertype(javaClass: JavaClass, get() = classifierQualifiedName override val isDeprecatedInJavaDoc: Boolean get() = false + override fun findAnnotation(fqName: FqName) = null } diff --git a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/trees/TreeBasedField.kt b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/trees/TreeBasedField.kt index 366799b805e..3045a8414b9 100644 --- a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/trees/TreeBasedField.kt +++ b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/trees/TreeBasedField.kt @@ -18,15 +18,13 @@ package org.jetbrains.kotlin.javac.wrappers.trees import com.sun.source.util.TreePath import com.sun.tools.javac.code.Flags -import com.sun.tools.javac.code.TypeTag import com.sun.tools.javac.tree.JCTree -import org.jetbrains.kotlin.builtins.PrimitiveType import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.Visibility 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.JavaField -import org.jetbrains.kotlin.load.java.structure.JavaPrimitiveType import org.jetbrains.kotlin.load.java.structure.JavaType import org.jetbrains.kotlin.name.Name @@ -60,7 +58,7 @@ class TreeBasedField( override val initializerValue: Any? 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 @@ -73,92 +71,4 @@ class TreeBasedField( type.classifierQualifiedName == "java.lang.String")) } ?: 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 - } - } } \ No newline at end of file diff --git a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/trees/TreeBasedMember.kt b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/trees/TreeBasedMember.kt index 8107dcff33d..479de46f085 100644 --- a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/trees/TreeBasedMember.kt +++ b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/trees/TreeBasedMember.kt @@ -19,7 +19,6 @@ package org.jetbrains.kotlin.javac.wrappers.trees import com.sun.source.util.TreePath import com.sun.tools.javac.tree.JCTree import org.jetbrains.kotlin.javac.JavacWrapper -import org.jetbrains.kotlin.load.java.structure.JavaAnnotation import org.jetbrains.kotlin.load.java.structure.JavaClass import org.jetbrains.kotlin.load.java.structure.JavaMember import org.jetbrains.kotlin.name.FqName @@ -34,11 +33,13 @@ abstract class TreeBasedMember( override val isDeprecatedInJavaDoc: Boolean get() = javac.isDeprecatedInJavaDoc(treePath) - override val annotations: Collection by lazy { + override val annotations: Collection by lazy { tree.annotations().map { TreeBasedAnnotation(it, treePath, javac) } } 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 } } \ No newline at end of file diff --git a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/trees/TreeBasedValueParameter.kt b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/trees/TreeBasedValueParameter.kt index 647f1fb364e..c1b65c86062 100644 --- a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/trees/TreeBasedValueParameter.kt +++ b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/trees/TreeBasedValueParameter.kt @@ -20,7 +20,6 @@ import com.sun.source.util.TreePath import com.sun.tools.javac.code.Flags import com.sun.tools.javac.tree.JCTree import org.jetbrains.kotlin.javac.JavacWrapper -import org.jetbrains.kotlin.load.java.structure.JavaAnnotation import org.jetbrains.kotlin.load.java.structure.JavaType import org.jetbrains.kotlin.load.java.structure.JavaValueParameter import org.jetbrains.kotlin.name.FqName @@ -32,12 +31,14 @@ class TreeBasedValueParameter( javac: JavacWrapper ) : TreeBasedElement(tree, treePath, javac), JavaValueParameter { - override val annotations: Collection by lazy { + override val annotations: Collection by lazy { tree.annotations().map { TreeBasedAnnotation(it, treePath, javac) } } 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 get() = javac.isDeprecatedInJavaDoc(treePath) diff --git a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/trees/treeBasedTypes.kt b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/trees/treeBasedTypes.kt index 51a01e14518..58871f346ab 100644 --- a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/trees/treeBasedTypes.kt +++ b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/trees/treeBasedTypes.kt @@ -31,25 +31,27 @@ abstract class TreeBasedType( val tree: T, val treePath: TreePath, val javac: JavacWrapper, - override val annotations: Collection + private val allAnnotations: Collection ) : JavaType, JavaAnnotationOwner { + override val annotations: Collection + get() = allAnnotations.filterTypeAnnotations() + companion object { fun create(tree: JCTree, treePath: TreePath, javac: JavacWrapper, annotations: Collection): JavaType { - val applicableAnnotations = annotations.filterTypeAnnotations() return when (tree) { - is JCTree.JCPrimitiveTypeTree -> TreeBasedPrimitiveType(tree, javac.getTreePath(tree, treePath.compilationUnit), javac, applicableAnnotations) - is JCTree.JCArrayTypeTree -> TreeBasedArrayType(tree, javac.getTreePath(tree, treePath.compilationUnit), javac, applicableAnnotations) - is JCTree.JCWildcard -> TreeBasedWildcardType(tree, javac.getTreePath(tree, treePath.compilationUnit), javac, applicableAnnotations) - is JCTree.JCTypeApply -> TreeBasedGenericClassifierType(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, annotations) + is JCTree.JCWildcard -> TreeBasedWildcardType(tree, javac.getTreePath(tree, treePath.compilationUnit), javac, annotations) + is JCTree.JCTypeApply -> TreeBasedGenericClassifierType(tree, javac.getTreePath(tree, treePath.compilationUnit), javac, annotations) is JCTree.JCAnnotatedType -> { val underlyingType = tree.underlyingType val newAnnotations = tree.annotations .map { TreeBasedAnnotation(it, javac.getTreePath(it, treePath.compilationUnit), javac) } create(underlyingType, javac.getTreePath(underlyingType, treePath.compilationUnit), javac, newAnnotations) } - 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") } } @@ -72,8 +74,8 @@ class TreeBasedPrimitiveType( tree: JCTree.JCPrimitiveTypeTree, treePath: TreePath, javac: JavacWrapper, - annotations: Collection -) : TreeBasedType(tree, treePath, javac, annotations), JavaPrimitiveType { + allAnnotations: Collection +) : TreeBasedType(tree, treePath, javac, allAnnotations), JavaPrimitiveType { override val type: PrimitiveType? get() = if (tree.primitiveTypeKind == TypeKind.VOID) { @@ -89,8 +91,8 @@ class TreeBasedArrayType( tree: JCTree.JCArrayTypeTree, treePath: TreePath, javac: JavacWrapper, - annotations: Collection -) : TreeBasedType(tree, treePath, javac, annotations), JavaArrayType { + allAnnotations: Collection +) : TreeBasedType(tree, treePath, javac, allAnnotations), JavaArrayType { override val componentType: JavaType get() = create(tree.elemtype, treePath, javac, annotations) @@ -101,8 +103,8 @@ class TreeBasedWildcardType( tree: JCTree.JCWildcard, treePath: TreePath, javac: JavacWrapper, - annotations: Collection -) : TreeBasedType(tree, treePath, javac, annotations), JavaWildcardType { + allAnnotations: Collection +) : TreeBasedType(tree, treePath, javac, allAnnotations), JavaWildcardType { override val bound: JavaType? get() = tree.bound?.let { create(it, treePath, javac, annotations) } @@ -116,11 +118,11 @@ sealed class TreeBasedClassifierType( tree: T, treePath: TreePath, javac: JavacWrapper, - annotations: Collection -) : TreeBasedType(tree, treePath, javac, annotations), JavaClassifierType { + allAnnotations: Collection +) : TreeBasedType(tree, treePath, javac, allAnnotations), JavaClassifierType { override val classifier: JavaClassifier? - get() = javac.resolve(treePath) + by lazy { javac.resolve(treePath) } override val classifierQualifiedName: String get() = (classifier as? JavaClass)?.fqName?.asString() ?: treePath.leaf.toString().substringBefore("<") @@ -132,7 +134,7 @@ sealed class TreeBasedClassifierType( get() { var tree: JCTree = tree if (tree is JCTree.JCTypeApply) { - tree = tree.clazz + tree = tree.clazz } if (tree is JCTree.JCFieldAccess) { val enclosingType = TreeBasedType.create(tree.selected, treePath, javac, annotations) @@ -158,12 +160,12 @@ sealed class TreeBasedClassifierType( private val typeParameter: JCTree.JCTypeParameter? get() = treePath.flatMap { - when (it) { - is JCTree.JCClassDecl -> it.typarams - is JCTree.JCMethodDecl -> it.typarams - else -> emptyList() - } - } + when (it) { + is JCTree.JCClassDecl -> it.typarams + is JCTree.JCMethodDecl -> it.typarams + else -> emptyList() + } + } .find { it.toString().substringBefore(" ") == treePath.leaf.toString() } } @@ -213,13 +215,13 @@ class TreeBasedGenericClassifierType( ) : TreeBasedClassifierType(tree, treePath, javac, annotations) { override val classifier: JavaClassifier? - get() { - val newTree = tree.clazz - return if (newTree is JCTree.JCAnnotatedType) { - javac.resolve(javac.getTreePath(newTree.underlyingType, treePath.compilationUnit)) + by lazy { + val newTree = tree.clazz + if (newTree is JCTree.JCAnnotatedType) { + javac.resolve(javac.getTreePath(newTree.underlyingType, treePath.compilationUnit)) + } + else super.classifier } - else super.classifier - } override val annotations: Collection get() { diff --git a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/trees/utils.kt b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/trees/utils.kt index b61b4a30665..55fa2ca219e 100644 --- a/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/trees/utils.kt +++ b/compiler/javac-wrapper/src/org/jetbrains/kotlin/javac/wrappers/trees/utils.kt @@ -24,7 +24,6 @@ import org.jetbrains.kotlin.javac.wrappers.symbols.SymbolBasedField import org.jetbrains.kotlin.javac.wrappers.symbols.SymbolBasedReferenceAnnotationArgument import org.jetbrains.kotlin.load.java.JavaVisibilities 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.FqName import org.jetbrains.kotlin.name.Name @@ -63,14 +62,12 @@ internal fun JCTree.annotations(): Collection = when (this) else -> null } ?: emptyList() -fun JavaClass.computeClassId(): ClassId? = - outerClass?.computeClassId()?.createNestedClassId(name) ?: fqName?.let { ClassId.topLevel(it) } - fun Collection.filterTypeAnnotations(): Collection { val filteredAnnotations = arrayListOf() + val targetClassId = ClassId(FqName("java.lang.annotation"), Name.identifier("Target")) for (annotation in this) { 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 when (elementTypeArg) { diff --git a/compiler/testData/javac/fieldsResolution/tests/BinaryInitializers.kt b/compiler/testData/javac/fieldsResolution/tests/BinaryInitializers.kt new file mode 100644 index 00000000000..a0c16441bc7 --- /dev/null +++ b/compiler/testData/javac/fieldsResolution/tests/BinaryInitializers.kt @@ -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; + +} \ No newline at end of file diff --git a/compiler/testData/javac/fieldsResolution/tests/BinaryInitializers.txt b/compiler/testData/javac/fieldsResolution/tests/BinaryInitializers.txt new file mode 100644 index 00000000000..dc0a28e7515 --- /dev/null +++ b/compiler/testData/javac/fieldsResolution/tests/BinaryInitializers.txt @@ -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() + } +} diff --git a/compiler/testData/javac/fieldsResolution/tests/ConstantByFqName.kt b/compiler/testData/javac/fieldsResolution/tests/ConstantByFqName.kt new file mode 100644 index 00000000000..909a1536180 --- /dev/null +++ b/compiler/testData/javac/fieldsResolution/tests/ConstantByFqName.kt @@ -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; +} \ No newline at end of file diff --git a/compiler/testData/javac/fieldsResolution/tests/ConstantByFqName.txt b/compiler/testData/javac/fieldsResolution/tests/ConstantByFqName.txt new file mode 100644 index 00000000000..c43e75ab353 --- /dev/null +++ b/compiler/testData/javac/fieldsResolution/tests/ConstantByFqName.txt @@ -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 + } +} diff --git a/compiler/testData/javac/fieldsResolution/tests/ConstantValuesFromKtFile.kt b/compiler/testData/javac/fieldsResolution/tests/ConstantValuesFromKtFile.kt new file mode 100644 index 00000000000..a8a910d9d5c --- /dev/null +++ b/compiler/testData/javac/fieldsResolution/tests/ConstantValuesFromKtFile.kt @@ -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; + } + +} \ No newline at end of file diff --git a/compiler/testData/javac/fieldsResolution/tests/ConstantValuesFromKtFile.txt b/compiler/testData/javac/fieldsResolution/tests/ConstantValuesFromKtFile.txt new file mode 100644 index 00000000000..82616a943b3 --- /dev/null +++ b/compiler/testData/javac/fieldsResolution/tests/ConstantValuesFromKtFile.txt @@ -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 + } +} diff --git a/compiler/testData/javac/fieldsResolution/tests/MultipleOuters.kt b/compiler/testData/javac/fieldsResolution/tests/MultipleOuters.kt new file mode 100644 index 00000000000..442da9dc487 --- /dev/null +++ b/compiler/testData/javac/fieldsResolution/tests/MultipleOuters.kt @@ -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; + } + + } + } +} diff --git a/compiler/testData/javac/fieldsResolution/tests/MultipleOuters.txt b/compiler/testData/javac/fieldsResolution/tests/MultipleOuters.txt new file mode 100644 index 00000000000..53cbadb85aa --- /dev/null +++ b/compiler/testData/javac/fieldsResolution/tests/MultipleOuters.txt @@ -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 + } +} diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java index 1b2c2d43142..3ce26bec81d 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java @@ -886,6 +886,12 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing 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") public void testAnnotatedLocalObjectFun() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/annotations/AnnotatedLocalObjectFun.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/javac/JavacFieldResolutionTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/javac/JavacFieldResolutionTestGenerated.java index 7bb47baa742..c268819d141 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/javac/JavacFieldResolutionTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/javac/JavacFieldResolutionTestGenerated.java @@ -44,12 +44,30 @@ public class JavacFieldResolutionTestGenerated extends AbstractJavacFieldResolut 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") public void testConstantValues() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/javac/fieldsResolution/tests/ConstantValues.kt"); 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") public void testFieldFromOuterClass() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/javac/fieldsResolution/tests/FieldFromOuterClass.kt"); @@ -62,6 +80,12 @@ public class JavacFieldResolutionTestGenerated extends AbstractJavacFieldResolut 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") public void testResolutionPriority() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/javac/fieldsResolution/tests/ResolutionPriority.kt"); @@ -101,12 +125,30 @@ public class JavacFieldResolutionTestGenerated extends AbstractJavacFieldResolut 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") public void testConstantValues() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/javac/fieldsResolution/tests/ConstantValues.kt"); 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") public void testFieldFromOuterClass() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/javac/fieldsResolution/tests/FieldFromOuterClass.kt"); @@ -119,6 +161,12 @@ public class JavacFieldResolutionTestGenerated extends AbstractJavacFieldResolut 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") public void testResolutionPriority() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/javac/fieldsResolution/tests/ResolutionPriority.kt");