javac-wrapper: identifier resolver

This commit is contained in:
baratynskiy
2017-08-03 11:22:32 +03:00
committed by Alexander Baratynskiy
parent 01883a41cb
commit 4f180e1292
30 changed files with 1256 additions and 192 deletions
@@ -17,22 +17,36 @@
package org.jetbrains.kotlin.cli.jvm.javac
import com.intellij.psi.PsiClass
import org.jetbrains.kotlin.asJava.classes.KtLightClass
import org.jetbrains.kotlin.cli.jvm.compiler.CliLightClassGenerationSupport
import org.jetbrains.kotlin.javac.KotlinSupertypeResolver
import org.jetbrains.kotlin.javac.JavacWrapperKotlinResolver
import org.jetbrains.kotlin.javac.resolve.MockKotlinField
import org.jetbrains.kotlin.load.java.structure.JavaField
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtClassOrObject
class KotlinSupertypeResolverImpl(private val lightClassGenerationSupport: CliLightClassGenerationSupport) : KotlinSupertypeResolver {
class JavacWrapperKotlinResolverImpl(private val lightClassGenerationSupport: CliLightClassGenerationSupport) : JavacWrapperKotlinResolver {
private val cache = hashMapOf<KtClassOrObject, KtLightClass>()
override fun resolveSupertypes(classOrObject: KtClassOrObject): List<ClassId> {
val lightClass = lightClassGenerationSupport.getLightClass(classOrObject) ?: return emptyList()
val lightClass = classOrObject.getLightClass() ?: return emptyList()
return lightClass.superTypes
.mapNotNull { it.resolve()?.computeClassId() }
}
override fun findField(classOrObject: KtClassOrObject, name: String): JavaField? {
val lightClass = classOrObject.getLightClass() ?: 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 }
private fun PsiClass.computeClassId(): ClassId? =
containingClass?.computeClassId()?.createNestedClassId(Name.identifier(name!!)) ?: qualifiedName?.let { ClassId.topLevel(FqName(it)) }
@@ -58,7 +58,7 @@ object JavacWrapperRegistrar {
val jvmClasspathRoots = configuration.jvmClasspathRoots
val outputDirectory = configuration.get(JVMConfigurationKeys.OUTPUT_DIRECTORY)
val compileJava = configuration.getBoolean(JVMConfigurationKeys.COMPILE_JAVA)
val kotlinSupertypesResolver = KotlinSupertypeResolverImpl(lightClassGenerationSupport)
val kotlinSupertypesResolver = JavacWrapperKotlinResolverImpl(lightClassGenerationSupport)
val javacWrapper = JavacWrapper(javaFiles, kotlinFiles, arguments, jvmClasspathRoots, bootClasspath, sourcePath,
kotlinSupertypesResolver, compileJava, outputDirectory, context)
@@ -41,14 +41,15 @@ import com.sun.tools.javac.util.Context
import com.sun.tools.javac.util.Log
import com.sun.tools.javac.util.Names
import com.sun.tools.javac.util.Options
import org.jetbrains.kotlin.javac.resolve.ClassifierResolver
import org.jetbrains.kotlin.javac.resolve.IdentifierResolver
import org.jetbrains.kotlin.javac.resolve.KotlinClassifiersCache
import org.jetbrains.kotlin.javac.resolve.classId
import org.jetbrains.kotlin.javac.wrappers.symbols.SymbolBasedClass
import org.jetbrains.kotlin.javac.wrappers.symbols.SymbolBasedClassifierType
import org.jetbrains.kotlin.javac.wrappers.symbols.SymbolBasedPackage
import org.jetbrains.kotlin.javac.wrappers.trees.*
import org.jetbrains.kotlin.load.java.structure.JavaAnnotation
import org.jetbrains.kotlin.load.java.structure.JavaClass
import org.jetbrains.kotlin.load.java.structure.JavaClassifier
import org.jetbrains.kotlin.load.java.structure.JavaPackage
import org.jetbrains.kotlin.load.java.structure.*
import org.jetbrains.kotlin.name.*
import org.jetbrains.kotlin.psi.KtFile
import java.io.Closeable
@@ -67,7 +68,7 @@ class JavacWrapper(
jvmClasspathRoots: List<File>,
bootClasspath: List<File>?,
sourcePath: List<File>?,
val kotlinSupertypeResolver: KotlinSupertypeResolver,
val kotlinResolver: JavacWrapperKotlinResolver,
private val compileJava: Boolean,
private val outputDirectory: File?,
private val context: Context
@@ -174,6 +175,7 @@ class JavacWrapper(
}
val classifierResolver = ClassifierResolver(this)
private val identifierResolver = IdentifierResolver(this)
private val kotlinClassifiersCache = KotlinClassifiersCache(if (javaFiles.isNotEmpty()) kotlinFiles else emptyList(), this)
private val symbolBasedPackagesCache = hashMapOf<String, SymbolBasedPackage?>()
@@ -281,6 +283,9 @@ class JavacWrapper(
fun resolve(treePath: TreePath): JavaClassifier? =
classifierResolver.resolve(treePath)
fun resolveField(treePath: TreePath, containingClass: JavaClass): JavaField? =
identifierResolver.resolve(treePath, containingClass)
fun toVirtualFile(javaFileObject: JavaFileObject): VirtualFile? =
javaFileObject.toUri().let { uri ->
if (uri.scheme == "jar") {
@@ -16,9 +16,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
interface KotlinSupertypeResolver {
interface JavacWrapperKotlinResolver {
fun resolveSupertypes(classOrObject: KtClassOrObject): List<ClassId>
fun findField(classOrObject: KtClassOrObject, name: String): JavaField?
}
@@ -14,15 +14,14 @@
* limitations under the License.
*/
package org.jetbrains.kotlin.javac.wrappers.trees
package org.jetbrains.kotlin.javac.resolve
import com.sun.source.tree.Tree
import com.sun.source.util.TreePath
import com.sun.tools.javac.tree.JCTree
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.javac.JavacWrapper
import org.jetbrains.kotlin.javac.MockKotlinClassifier
import org.jetbrains.kotlin.load.java.JavaVisibilities
import org.jetbrains.kotlin.javac.wrappers.trees.TreeBasedClass
import org.jetbrains.kotlin.javac.wrappers.trees.TreeBasedTypeParameter
import org.jetbrains.kotlin.load.java.structure.JavaClass
import org.jetbrains.kotlin.load.java.structure.JavaClassifier
import org.jetbrains.kotlin.name.ClassId
@@ -111,80 +110,14 @@ class ClassifierResolver(private val javac: JavacWrapper) {
}
private abstract class Scope(protected val javac: JavacWrapper,
protected val treePath: TreePath) {
protected val treePath: TreePath) {
protected val helper = ResolveHelper(javac, treePath)
abstract val parent: Scope?
abstract fun findClass(name: String, pathSegments: List<String>): JavaClassifier?
protected fun getJavaClassFromPathSegments(javaClass: JavaClass,
pathSegments: List<String>) =
if (pathSegments.size == 1) {
javaClass
}
else {
javaClass.findInnerOrNested(pathSegments.drop(1))
}
protected fun findImport(pathSegments: List<String>): JavaClass? {
pathSegments.forEachIndexed { index, _ ->
if (index == pathSegments.lastIndex) return null
val packageFqName = pathSegments.dropLast(index + 1).joinToString(separator = ".")
findPackage(packageFqName)?.let { pack ->
val className = pathSegments.takeLast(index + 1)
return findJavaOrKotlinClass(ClassId(pack, Name.identifier(className.first())))?.let { javaClass ->
getJavaClassFromPathSegments(javaClass, className)
}
}
}
return null
}
protected fun findJavaOrKotlinClass(classId: ClassId) = javac.findClass(classId) ?: javac.getKotlinClassifier(classId)
protected fun JavaClass.findInnerOrNested(name: Name, checkedSupertypes: HashSet<JavaClass> = hashSetOf()): JavaClass? {
findVisibleInnerOrNestedClass(name)?.let {
checkedSupertypes.addAll(collectAllSupertypes())
return it
}
return supertypes
.mapNotNull {
(it.classifier as? JavaClass)?.let { supertype ->
if (supertype !in checkedSupertypes) {
supertype.findInnerOrNested(name, checkedSupertypes)
} else null
}
}.singleOrNull()
}
protected fun findPackage(packageName: String): FqName? {
val fqName = if (packageName.isNotBlank()) FqName(packageName) else FqName.ROOT
javac.hasKotlinPackage(fqName)?.let { return it }
return javac.findPackage(fqName)?.fqName
}
private fun JavaClass.findVisibleInnerOrNestedClass(name: Name) = findInnerClass(name)?.let { innerOrNestedClass ->
when (innerOrNestedClass.visibility) {
Visibilities.PRIVATE -> null
JavaVisibilities.PACKAGE_VISIBILITY -> {
val classId = (innerOrNestedClass as? MockKotlinClassifier)?.classId ?: innerOrNestedClass.computeClassId()
if (classId?.packageFqName?.asString() == (treePath.compilationUnit.packageName?.toString() ?: "")) innerOrNestedClass else null
}
else -> innerOrNestedClass
}
}
private fun JavaClass.collectAllSupertypes(): Set<JavaClass> =
hashSetOf(this).apply {
supertypes.mapNotNull { it.classifier as? JavaClass }.forEach { addAll(it.collectAllSupertypes()) }
}
private fun JavaClass.findInnerOrNested(pathSegments: List<String>): JavaClass? =
pathSegments.fold(this) { javaClass, it -> javaClass.findInnerOrNested(Name.identifier(it)) ?: return null }
}
private class GlobalScope(javac: JavacWrapper, treePath: TreePath) : Scope(javac, treePath) {
@@ -195,8 +128,8 @@ private class GlobalScope(javac: JavacWrapper, treePath: TreePath) : Scope(javac
override fun findClass(name: String, pathSegments: List<String>): JavaClass? {
findByFqName(pathSegments)?.let { return it }
return findJavaOrKotlinClass(classId("java.lang", name))?.let { javaClass ->
getJavaClassFromPathSegments(javaClass, pathSegments)
return helper.findJavaOrKotlinClass(classId("java.lang", name))?.let { javaClass ->
helper.getJavaClassFromPathSegments(javaClass, pathSegments)
}
}
@@ -204,18 +137,18 @@ private class GlobalScope(javac: JavacWrapper, treePath: TreePath) : Scope(javac
pathSegments.forEachIndexed { index, _ ->
if (index != 0) {
val packageFqName = pathSegments.take(index).joinToString(separator = ".")
findPackage(packageFqName)?.let { pack ->
helper.findPackage(packageFqName)?.let { pack ->
val className = pathSegments.drop(index)
findJavaOrKotlinClass(ClassId(pack, Name.identifier(className.first())))?.let { javaClass ->
return getJavaClassFromPathSegments(javaClass, className)
helper.findJavaOrKotlinClass(ClassId(pack, Name.identifier(className.first())))?.let { javaClass ->
return helper.getJavaClassFromPathSegments(javaClass, className)
}
}
}
}
// try to find in <root>
return findJavaOrKotlinClass(classId("", pathSegments.first()))?.let { javaClass ->
getJavaClassFromPathSegments(javaClass, pathSegments)
return helper.findJavaOrKotlinClass(classId("", pathSegments.first()))?.let { javaClass ->
helper.getJavaClassFromPathSegments(javaClass, pathSegments)
}
}
@@ -229,11 +162,11 @@ private class ImportOnDemandScope(javac: JavacWrapper,
override fun findClass(name: String, pathSegments: List<String>): JavaClassifier? {
asteriskImports()
.mapNotNullTo(hashSetOf()) { findImport("$it$name".split(".")) }
.mapNotNullTo(hashSetOf()) { helper.findImport("$it$name".split(".")) }
.takeIf { it.isNotEmpty() }
?.let {
return it.singleOrNull()?.let { javaClass ->
getJavaClassFromPathSegments(javaClass, pathSegments)
helper.getJavaClassFromPathSegments(javaClass, pathSegments)
}
}
@@ -259,9 +192,9 @@ private class PackageScope(javac: JavacWrapper,
get() = ImportOnDemandScope(javac, treePath)
override fun findClass(name: String, pathSegments: List<String>): JavaClassifier? {
findJavaOrKotlinClass(classId(treePath.compilationUnit.packageName?.toString() ?: "", name))
helper.findJavaOrKotlinClass(classId(treePath.compilationUnit.packageName?.toString() ?: "", name))
?.let { javaClass ->
return getJavaClassFromPathSegments(javaClass, pathSegments)
return helper.getJavaClassFromPathSegments(javaClass, pathSegments)
}
return parent.findClass(name, pathSegments)
@@ -281,8 +214,8 @@ private class SingleTypeImportScope(javac: JavacWrapper,
imports.singleOrNull() ?: return null
return findImport(imports.first().split("."))
?.let { javaClass -> getJavaClassFromPathSegments(javaClass, pathSegments) }
return helper.findImport(imports.first().split("."))
?.let { javaClass -> helper.getJavaClassFromPathSegments(javaClass, pathSegments) }
}
private fun imports(firstSegment: String) =
@@ -310,7 +243,7 @@ private class CurrentClassAndInnerScope(javac: JavacWrapper,
?.find { typeParameter -> typeParameter.name == identifier }
?.let { typeParameter -> return typeParameter }
it.findInnerOrNested(identifier)?.let { javaClass -> return getJavaClassFromPathSegments(javaClass, pathSegments) }
helper.findInnerOrNested(it, identifier)?.let { javaClass -> return helper.getJavaClassFromPathSegments(javaClass, pathSegments) }
if (it.name == identifier && pathSegments.size == 1) return it
}
@@ -0,0 +1,162 @@
/*
* 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.tree.JCTree
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.name.Name
class IdentifierResolver(private val javac: JavacWrapper) {
fun resolve(treePath: TreePath, containingClass: JavaClass): JavaField? {
val leaf = treePath.leaf
if (leaf is JCTree.JCIdent) {
val fieldName = Name.identifier(leaf.name.toString())
return CurrentClassAndInnerFieldScope(javac, treePath).findField(containingClass, fieldName)
}
else if (leaf is JCTree.JCFieldAccess) {
val javaClassTreePath = javac.getTreePath(leaf.selected, treePath.compilationUnit)
val javaClass = javac.resolve(javaClassTreePath) as? JavaClass ?: return null
if (javaClass is MockKotlinClassifier) {
return javaClass.findField(leaf.name.toString())
}
val fieldName = Name.identifier(leaf.name.toString())
return CurrentClassAndInnerFieldScope(javac, treePath, null).findField(javaClass, fieldName)
}
return null
}
}
private abstract class FieldScope(protected val javac: JavacWrapper,
protected val treePath: TreePath) {
protected val helper = ResolveHelper(javac, treePath)
abstract val parent: FieldScope?
abstract fun findField(javaClass: JavaClass, name: Name): JavaField?
protected fun JavaClass.findFieldIncludingSupertypes(name: Name, checkedSupertypes: HashSet<JavaClass> = hashSetOf()): JavaField? {
fields.find { it.name == name }?.let {
checkedSupertypes.addAll(collectAllSupertypes())
return it
}
return supertypes
.mapNotNull {
val classifier = it.classifier as? JavaClass
if (classifier !in checkedSupertypes) {
classifier?.findFieldIncludingSupertypes(name, checkedSupertypes)
}
else null
}.singleOrNull()
}
}
private class StaticImportOnDemandFieldScope(javac: JavacWrapper,
treePath: TreePath) : FieldScope(javac, treePath) {
override val parent: FieldScope?
get() = null
override fun findField(javaClass: JavaClass, name: Name): JavaField? {
val foundFields = hashSetOf<JavaField>()
staticAsteriskImports().forEach { import ->
val pathSegments = import.split(".")
val importedClass = helper.findImport(pathSegments)
if (importedClass is MockKotlinClassifier) {
return importedClass.findField(name.asString())
}
importedClass?.findFieldIncludingSupertypes(name)?.let { foundFields.add(it) }
}
return foundFields.singleOrNull()
}
private fun staticAsteriskImports() =
(treePath.compilationUnit as JCTree.JCCompilationUnit).imports
.filter { it.staticImport }
.mapNotNull {
val fqName = it.qualifiedIdentifier.toString()
if (fqName.endsWith("*")) {
fqName.dropLast(2)
}
else null
}
}
private class StaticImportFieldScope(javac: JavacWrapper,
treePath: TreePath) : FieldScope(javac, treePath) {
override val parent: FieldScope
get() = StaticImportOnDemandFieldScope(javac, treePath)
override fun findField(javaClass: JavaClass, name: Name): JavaField? {
val staticImports = staticImports(name.asString()).toSet().takeIf { it.isNotEmpty() }
?: return parent.findField(javaClass, name)
val import = staticImports.singleOrNull() ?: return null
val pathSegments = import.split(".").dropLast(1)
val importedClass = helper.findImport(pathSegments)
if (importedClass is MockKotlinClassifier) {
return importedClass.findField(name.asString())
}
return importedClass?.findFieldIncludingSupertypes(name)
}
private fun staticImports(fieldName: String) =
(treePath.compilationUnit as JCTree.JCCompilationUnit).imports
.filter { it.staticImport }
.mapNotNull {
val import = it.qualifiedIdentifier as? JCTree.JCFieldAccess
val importedField = import?.name?.toString()
if (importedField == fieldName) {
import.toString()
}
else null
}
}
private class CurrentClassAndInnerFieldScope(javac: JavacWrapper,
treePath: TreePath,
override val parent: FieldScope? = StaticImportFieldScope(javac, treePath)) : FieldScope(javac, treePath) {
override fun findField(javaClass: JavaClass, name: Name): JavaField? {
javaClass.enclosingClasses().forEach {
it.findFieldIncludingSupertypes(name)?.let { return it }
}
return parent?.findField(javaClass, name)
}
private fun JavaClass.enclosingClasses(): List<JavaClass> = arrayListOf<JavaClass>().also { classes ->
classes.add(this)
outerClass?.let { classes.addAll(it.enclosingClasses()) }
}
}
@@ -14,12 +14,15 @@
* limitations under the License.
*/
package org.jetbrains.kotlin.javac
package org.jetbrains.kotlin.javac.resolve
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiField
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.javac.JavacWrapper
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.load.java.JavaVisibilities
import org.jetbrains.kotlin.load.java.structure.*
@@ -85,15 +88,6 @@ class MockKotlinClassifier(val classId: ClassId,
override val fqName: FqName
get() = classId.asSingleFqName()
override val isAbstract: Boolean
get() = throw UnsupportedOperationException("Should not be called")
override val isStatic: Boolean
get() = throw UnsupportedOperationException("Should not be called")
override val isFinal: Boolean
get() = throw UnsupportedOperationException("Should not be called")
override val visibility: Visibility
get() = when (classOrObject.visibilityModifierType()) {
null, KtTokens.PUBLIC_KEYWORD -> Visibilities.PUBLIC
@@ -102,11 +96,8 @@ class MockKotlinClassifier(val classId: ClassId,
else -> JavaVisibilities.PACKAGE_VISIBILITY
}
override val typeParameters: List<JavaTypeParameter>
get() = throw UnsupportedOperationException("Should not be called")
override val supertypes: Collection<JavaClassifierType>
get() = javac.kotlinSupertypeResolver.resolveSupertypes(classOrObject)
get() = javac.kotlinResolver.resolveSupertypes(classOrObject)
.mapNotNull { javac.getKotlinClassifier(it) ?: javac.findClass(it) }
.map { MockKotlinClassifierType(it) }
@@ -118,53 +109,17 @@ class MockKotlinClassifier(val classId: ClassId,
}
}
override val outerClass: JavaClass?
get() = throw UnsupportedOperationException("Should not be called")
override val isInterface: Boolean
get() = throw UnsupportedOperationException("Should not be called")
override val isAnnotationType: Boolean
get() = throw UnsupportedOperationException("Should not be called")
override val isEnum: Boolean
get() = throw UnsupportedOperationException("Should not be called")
override val lightClassOriginKind
get() = LightClassOriginKind.SOURCE
override val virtualFile: VirtualFile?
get() = null
override val methods: Collection<JavaMethod>
get() = throw UnsupportedOperationException("Should not be called")
override val fields: Collection<JavaField>
get() = classOrObject.declarations
.filterIsInstance<KtProperty>()
.map(::MockKotlinField) + classOrObject.companionObjects.flatMap {
it.declarations
.filterIsInstance<KtProperty>()
.map(::MockKotlinField)
}
override val constructors: Collection<JavaConstructor>
get() = throw UnsupportedOperationException("Should not be called")
override val name
get() = fqName.shortNameOrSpecial()
override val annotations
get() = throw UnsupportedOperationException("Should not be called")
override val isDeprecatedInJavaDoc: Boolean
get() = throw UnsupportedOperationException("Should not be called")
override fun isFromSourceCodeInScope(scope: SearchScope) = true
override fun findAnnotation(fqName: FqName) =
throw UnsupportedOperationException("Should not be called")
override val innerClassNames
get() = innerClasses.map(JavaClass::name)
@@ -177,36 +132,62 @@ class MockKotlinClassifier(val classId: ClassId,
val hasTypeParameters: Boolean
get() = typeParametersNumber > 0
fun findField(name: String) = javac.kotlinResolver.findField(classOrObject, name)
override val isAbstract: Boolean
get() = throw UnsupportedOperationException("Should not be called")
override val isStatic: Boolean
get() = throw UnsupportedOperationException("Should not be called")
override val isFinal: Boolean
get() = throw UnsupportedOperationException("Should not be called")
override val typeParameters: List<JavaTypeParameter>
get() = throw UnsupportedOperationException("Should not be called")
override val outerClass: JavaClass?
get() = throw UnsupportedOperationException("Should not be called")
override val isInterface: Boolean
get() = throw UnsupportedOperationException("Should not be called")
override val isAnnotationType: Boolean
get() = throw UnsupportedOperationException("Should not be called")
override val isEnum: Boolean
get() = throw UnsupportedOperationException("Should not be called")
override val methods: Collection<JavaMethod>
get() = throw UnsupportedOperationException("Should not be called")
override val fields: Collection<JavaField>
get() = throw UnsupportedOperationException("Should not be called")
override val constructors: Collection<JavaConstructor>
get() = throw UnsupportedOperationException("Should not be called")
override val annotations
get() = throw UnsupportedOperationException("Should not be called")
override val isDeprecatedInJavaDoc: Boolean
get() = throw UnsupportedOperationException("Should not be called")
override fun findAnnotation(fqName: FqName) =
throw UnsupportedOperationException("Should not be called")
}
class MockKotlinClassifierType(override val classifier: JavaClassifier) : JavaClassifierType {
override val typeArguments: List<JavaType>
get() = throw UnsupportedOperationException("Should not be called")
override val isRaw: Boolean
get() = throw UnsupportedOperationException("Should not be called")
override val annotations: Collection<JavaAnnotation>
get() = throw UnsupportedOperationException("Should not be called")
override val classifierQualifiedName: String
get() = throw UnsupportedOperationException("Should not be called")
override val presentableText: String
get() = throw UnsupportedOperationException("Should not be called")
override fun findAnnotation(fqName: FqName) =
throw UnsupportedOperationException("Should not be called")
override val isDeprecatedInJavaDoc: Boolean
get() = throw UnsupportedOperationException("Should not be called")
}
class MockKotlinField(private val property: KtProperty) : JavaField {
class MockKotlinField(private val psiField: PsiField) : JavaField {
override val initializerValue: Any?
get() = (psiField.initializer as? PsiLiteralExpression)?.value
override val name: Name
get() = property.nameAsSafeName
get() = throw UnsupportedOperationException("Should not be called")
override val annotations: Collection<JavaAnnotation>
get() = throw UnsupportedOperationException("Should not be called")
override val isDeprecatedInJavaDoc: Boolean
@@ -225,16 +206,8 @@ class MockKotlinField(private val property: KtProperty) : JavaField {
get() = throw UnsupportedOperationException("Should not be called")
override val type: JavaType
get() = throw UnsupportedOperationException("Should not be called")
override val initializerValue: Any?
get() {
if (!property.hasModifier(KtTokens.CONST_KEYWORD)) return null
val initializer = property.initializer ?: return null
return initializer.text.toIntOrNull() ?: initializer.text
}
override val hasConstantNotNullInitializer: Boolean
get() = throw UnsupportedOperationException("Should not be called")
override fun findAnnotation(fqName: FqName) = throw UnsupportedOperationException("Should not be called")
}
@@ -0,0 +1,101 @@
/*
* 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 org.jetbrains.kotlin.descriptors.Visibilities
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
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
internal class ResolveHelper(private val javac: JavacWrapper,
private val treePath: TreePath) {
fun getJavaClassFromPathSegments(javaClass: JavaClass,
pathSegments: List<String>) =
if (pathSegments.size == 1) {
javaClass
}
else {
javaClass.findInnerOrNested(pathSegments.drop(1))
}
fun findImport(pathSegments: List<String>): JavaClass? {
pathSegments.forEachIndexed { index, _ ->
if (index == pathSegments.lastIndex) return null
val packageFqName = pathSegments.dropLast(index + 1).joinToString(separator = ".")
findPackage(packageFqName)?.let { pack ->
val className = pathSegments.takeLast(index + 1)
return findJavaOrKotlinClass(ClassId(pack, Name.identifier(className.first())))?.let { javaClass ->
getJavaClassFromPathSegments(javaClass, className)
}
}
}
return null
}
fun findJavaOrKotlinClass(classId: ClassId) = javac.findClass(classId) ?: javac.getKotlinClassifier(classId)
fun findInnerOrNested(javaClass: JavaClass, name: Name, checkedSupertypes: HashSet<JavaClass> = hashSetOf()): JavaClass? {
javaClass.findVisibleInnerOrNestedClass(name)?.let {
checkedSupertypes.addAll(javaClass.collectAllSupertypes())
return it
}
return javaClass.supertypes
.mapNotNull {
(it.classifier as? JavaClass)?.let { supertype ->
if (supertype !in checkedSupertypes) {
findInnerOrNested(supertype, name, checkedSupertypes)
} else null
}
}.singleOrNull()
}
fun findPackage(packageName: String): FqName? {
val fqName = if (packageName.isNotBlank()) FqName(packageName) else FqName.ROOT
javac.hasKotlinPackage(fqName)?.let { return it }
return javac.findPackage(fqName)?.fqName
}
private fun JavaClass.findVisibleInnerOrNestedClass(name: Name) = findInnerClass(name)?.let { innerOrNestedClass ->
when (innerOrNestedClass.visibility) {
Visibilities.PRIVATE -> null
JavaVisibilities.PACKAGE_VISIBILITY -> {
val classId = (innerOrNestedClass as? MockKotlinClassifier)?.classId ?: innerOrNestedClass.computeClassId()
if (classId?.packageFqName?.asString() == (treePath.compilationUnit.packageName?.toString() ?: "")) innerOrNestedClass else null
}
else -> innerOrNestedClass
}
}
private fun JavaClass.findInnerOrNested(pathSegments: List<String>): JavaClass? =
pathSegments.fold(this) { javaClass, it -> findInnerOrNested(javaClass, Name.identifier(it)) ?: return null }
}
fun JavaClass.collectAllSupertypes(): Set<JavaClass> =
hashSetOf(this).apply {
supertypes.mapNotNull { it.classifier as? JavaClass }.forEach { addAll(it.collectAllSupertypes()) }
}
@@ -87,10 +87,8 @@ class ValueCalculator(private val containingClass: JavaClass,
}
else expr.value
}
is JCTree.JCIdent -> containingClass.fields
.find { it.name == expr.name.toString().let { Name.identifier(it) } }
?.initializerValue
is JCTree.JCFieldAccess -> fieldAccessValue(expr)
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)
@@ -98,16 +96,6 @@ class ValueCalculator(private val containingClass: JavaClass,
}
}
private fun fieldAccessValue(value: JCTree.JCFieldAccess): Any? {
val newTreePath = javac.getTreePath(value.selected, treePath.compilationUnit)
val javaClass = javac.resolve(newTreePath) as? JavaClass ?: return null
val fieldName = value.name.toString().let { Name.identifier(it) }
return javaClass.fields
.find { it.name == fieldName }
?.initializerValue
}
private fun unaryInitializerValue(value: JCTree.JCUnary): Any? {
val argValue = getValue(value.arg)
return when (value.tag) {
@@ -21,7 +21,7 @@ import com.sun.tools.javac.code.BoundKind
import com.sun.tools.javac.tree.JCTree
import org.jetbrains.kotlin.builtins.PrimitiveType
import org.jetbrains.kotlin.javac.JavacWrapper
import org.jetbrains.kotlin.javac.MockKotlinClassifier
import org.jetbrains.kotlin.javac.resolve.MockKotlinClassifier
import org.jetbrains.kotlin.load.java.structure.*
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType
@@ -0,0 +1,33 @@
// FILE: a/x.java
package a;
public class x {
public static final int I = 42;
}
// FILE: a/y.java
package a;
public class y {
public static final int I = 42;
}
// FILE: b/t.java
package b;
import static a.x.*;
import static a.y.*;
public class t {
public static final int CONST = I;
}
// FILE: b/t1.java
package b;
import static a.x.*;
import static a.x.*;
public class t1 {
public static final int CONST = I;
}
@@ -0,0 +1,47 @@
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
// Static members
public const final val I: kotlin.Int = 42
}
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 t {
public constructor t()
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.Int
}
public open class t1 {
public constructor t1()
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.Int = 42
}
}
@@ -0,0 +1,38 @@
// FILE: a/x.java
package a;
public class x {
public static final int I = 42;
public class Inner {
public static final int I2 = I;
public class Inner2 {
public static final int I = x.I + I2;
public class Inner3 extends Inner {
public static final int CONST = I;
}
}
}
public static class Nested {
public static final int I2 = I;
public static class Nested2 {
public static final int I3 = I2;
public static final int I4 = 42;
public class Inner {
public static final int I5 = I4;
}
}
}
}
@@ -0,0 +1,76 @@
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 inner class Inner {
public constructor Inner()
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 Inner2 {
public constructor Inner2()
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 Inner3 : a.x.Inner {
public constructor Inner3()
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.Int = 84
public const final override /*1*/ /*fake_override*/ val I2: kotlin.Int = 42
}
// Static members
public const final val I: kotlin.Int = 84
}
// Static members
public const final val I2: kotlin.Int = 42
}
public open class Nested {
public constructor Nested()
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 Nested2 {
public constructor Nested2()
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 Inner {
public constructor Inner()
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 I5: kotlin.Int = 42
}
// Static members
public const final val I3: kotlin.Int = 42
public const final val I4: kotlin.Int = 42
}
// Static members
public const final val I2: kotlin.Int = 42
}
// Static members
public const final val I: kotlin.Int = 42
}
}
@@ -0,0 +1,23 @@
// FILE: a/x.java
package a;
public class x {
public static final int CONST = 42;
}
// FILE: a/y.java
package a;
public class y extends x {
public static final int O = CONST;
}
// FILE: a/z.java
package a;
public class z {
public static final int I = y.CONST;
public static final int O = y.O;
}
@@ -0,0 +1,36 @@
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
// Static members
public const final val CONST: kotlin.Int = 42
}
public open class y : a.x {
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 override /*1*/ /*fake_override*/ val CONST: kotlin.Int = 42
public const final val O: kotlin.Int = 42
}
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 I: kotlin.Int = 42
public const final val O: kotlin.Int = 42
}
}
@@ -0,0 +1,76 @@
// FILE: a/x.java
package a;
public class x {
public static final int I = 42;
}
// FILE: a/y.java
package a;
public class y extends x {
public static final int I = x.I * 2;
public class Inner {
public static final int Y = I;
}
public class Inner2 extends x {
public static final int Y = I;
}
}
// FILE: b/b.java
package b;
public class b {
public static final int I = 84;
}
// FILE: c/c.java
package c;
import static a.x.I;
import static b.b.*;
public class c extends a.x {
public static final int O = I;
public class Inner {
public static final int O = I;
}
}
// FILE: c/e.java
package c;
import static a.x.I;
public class e extends a.x {
public static final int O = I;
public class Inner {
public static final int O = I;
}
}
// FILE: c/d.java
package c;
import static b.b.*;
public class d extends a.x {
public static final int O = I;
public class Inner {
public static final int O = I;
}
}
@@ -0,0 +1,124 @@
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
// Static members
public const final val I: kotlin.Int = 42
}
public open class y : a.x {
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
public open inner class Inner {
public constructor Inner()
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 Y: kotlin.Int = 84
}
public open inner class Inner2 : a.x {
public constructor Inner2()
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 override /*1*/ /*fake_override*/ val I: kotlin.Int = 42
public const final val Y: kotlin.Int = 42
}
// Static members
public const final val I: kotlin.Int = 84
}
}
package b {
public open class b {
public constructor b()
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 = 84
}
}
package c {
public open class c : a.x {
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 open inner class Inner {
public constructor Inner()
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 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
}
public open class d : a.x {
public constructor d()
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 Inner {
public constructor Inner()
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 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
}
public open class e : a.x {
public constructor e()
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 Inner {
public constructor Inner()
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 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
}
}
@@ -0,0 +1,38 @@
// FILE: a/x.java
package a;
public class x {
public static final int I = 42;
}
// FILE: a/y.java
package a;
public interface y {
int I = 84;
}
// FILE: a/y2.java
package a;
public class y2 implements y {
public static final int I = 168;
}
// FILE: a/z.java
package a;
public class z extends x implements y {}
// FILE: a/z1.java
package a;
public class z1 extends y2 implements y {}
// FILE: a/a.java
package a;
public class a {
public static final int I = z.I;
public static final int I2 = z1.I;
}
@@ -0,0 +1,66 @@
package
package a {
public open class a {
public constructor a()
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
public const final val I2: kotlin.Int = 168
}
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
}
public interface 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 = 84
}
public open class y2 : a.y {
public constructor y2()
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 = 168
}
public open class z : a.x, a.y {
public constructor z()
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 = 42
public const final override /*1*/ /*fake_override*/ val I: kotlin.Int = 84
}
public open class z1 : a.y2, a.y {
public constructor z1()
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 = 168
public const final override /*1*/ /*fake_override*/ val I: kotlin.Int = 84
}
}
@@ -0,0 +1,28 @@
// FILE: a/x.java
package a;
public class x {
public static final int I = 42;
public static final int I1 = 42;
public static final int I2 = I + I1;
}
// FILE: b/y.java
package b;
import static a.x.I;
public class y {
public static final int O = I;
}
// FILE: b/z.java
package b;
import static a.x.*;
public class z {
public static final int CONST = I + I1 + I2;
}
@@ -0,0 +1,39 @@
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
// Static members
public const final val I: kotlin.Int = 42
public const final val I1: kotlin.Int = 42
public const final val I2: kotlin.Int = 84
}
}
package b {
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 O: kotlin.Int = 42
}
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.Int = 168
}
}
@@ -0,0 +1,33 @@
// FILE: a/x.java
package a;
public class x {
public static final int I = 42;
}
// FILE: a/y.java
package a;
public class y {
public static final int I = 42;
}
// FILE: b/t.java
package b;
import static a.x.I;
import static a.y.I;
public class t {
public static final int CONST = I;
}
// FILE: b/t1.java
package b;
import static a.x.I;
import static a.x.I;
public class t1 {
public static final int CONST = I;
}
@@ -0,0 +1,47 @@
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
// Static members
public const final val I: kotlin.Int = 42
}
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 t {
public constructor t()
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.Int
}
public open class t1 {
public constructor t1()
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.Int = 42
}
}
@@ -0,0 +1,42 @@
/*
* 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.checkers.javac
import org.jetbrains.kotlin.checkers.AbstractDiagnosticsTest
import org.jetbrains.kotlin.config.JVMConfigurationKeys
import java.io.File
abstract class AbstractJavacFieldResolutionTest : AbstractDiagnosticsTest() {
private var useJavac = true
override fun analyzeAndCheck(testDataFile: File, files: List<TestFile>) {
if (useJavac) {
val groupedByModule = files.groupBy(TestFile::module)
val allKtFiles = groupedByModule.values.flatMap { getKtFiles(it, true) }
environment.registerJavac(kotlinFiles = allKtFiles)
environment.configuration.put(JVMConfigurationKeys.USE_JAVAC, true)
}
super.analyzeAndCheck(testDataFile, files)
}
fun doTestWithoutJavacWrapper(path: String) {
useJavac = false
super.doTest(path)
}
}
@@ -44,12 +44,6 @@ public class JavacDiagnosticsTestGenerated extends AbstractJavacDiagnosticsTest
doTest(fileName);
}
@TestMetadata("ConstantValues.kt")
public void testConstantValues() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/javac/diagnostics/tests/ConstantValues.kt");
doTest(fileName);
}
@TestMetadata("compiler/testData/javac/diagnostics/tests/imports")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -440,12 +434,6 @@ public class JavacDiagnosticsTestGenerated extends AbstractJavacDiagnosticsTest
doTestWithoutJavacWrapper(fileName);
}
@TestMetadata("ConstantValues.kt")
public void testConstantValues() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/javac/diagnostics/tests/ConstantValues.kt");
doTestWithoutJavacWrapper(fileName);
}
@TestMetadata("compiler/testData/javac/diagnostics/tests/imports")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -0,0 +1,146 @@
/*
* 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.checkers.javac;
import com.intellij.testFramework.TestDataPath;
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
import org.jetbrains.kotlin.test.KotlinTestUtils;
import org.jetbrains.kotlin.test.TargetBackend;
import org.jetbrains.kotlin.test.TestMetadata;
import org.junit.runner.RunWith;
import java.io.File;
import java.util.regex.Pattern;
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
@SuppressWarnings("all")
@RunWith(JUnit3RunnerWithInners.class)
public class JavacFieldResolutionTestGenerated extends AbstractJavacFieldResolutionTest {
@TestMetadata("compiler/testData/javac/fieldsResolution/tests")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Tests extends AbstractJavacFieldResolutionTest {
public void testAllFilesPresentInTests() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/javac/fieldsResolution/tests"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
}
@TestMetadata("AsteriskStaticImportsAmbiguity.kt")
public void testAsteriskStaticImportsAmbiguity() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/javac/fieldsResolution/tests/AsteriskStaticImportsAmbiguity.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("FieldFromOuterClass.kt")
public void testFieldFromOuterClass() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/javac/fieldsResolution/tests/FieldFromOuterClass.kt");
doTest(fileName);
}
@TestMetadata("InheritedField.kt")
public void testInheritedField() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/javac/fieldsResolution/tests/InheritedField.kt");
doTest(fileName);
}
@TestMetadata("ResolutionPriority.kt")
public void testResolutionPriority() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/javac/fieldsResolution/tests/ResolutionPriority.kt");
doTest(fileName);
}
@TestMetadata("SameFieldInSupertypes.kt")
public void testSameFieldInSupertypes() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/javac/fieldsResolution/tests/SameFieldInSupertypes.kt");
doTest(fileName);
}
@TestMetadata("StaticImport.kt")
public void testStaticImport() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/javac/fieldsResolution/tests/StaticImport.kt");
doTest(fileName);
}
@TestMetadata("StaticImportsAmbiguity.kt")
public void testStaticImportsAmbiguity() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/javac/fieldsResolution/tests/StaticImportsAmbiguity.kt");
doTest(fileName);
}
}
@TestMetadata("compiler/testData/javac/fieldsResolution/tests")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class TestsWithoutJavac extends AbstractJavacFieldResolutionTest {
public void testAllFilesPresentInTestsWithoutJavac() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/javac/fieldsResolution/tests"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
}
@TestMetadata("AsteriskStaticImportsAmbiguity.kt")
public void testAsteriskStaticImportsAmbiguity() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/javac/fieldsResolution/tests/AsteriskStaticImportsAmbiguity.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("FieldFromOuterClass.kt")
public void testFieldFromOuterClass() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/javac/fieldsResolution/tests/FieldFromOuterClass.kt");
doTestWithoutJavacWrapper(fileName);
}
@TestMetadata("InheritedField.kt")
public void testInheritedField() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/javac/fieldsResolution/tests/InheritedField.kt");
doTestWithoutJavacWrapper(fileName);
}
@TestMetadata("ResolutionPriority.kt")
public void testResolutionPriority() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/javac/fieldsResolution/tests/ResolutionPriority.kt");
doTestWithoutJavacWrapper(fileName);
}
@TestMetadata("SameFieldInSupertypes.kt")
public void testSameFieldInSupertypes() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/javac/fieldsResolution/tests/SameFieldInSupertypes.kt");
doTestWithoutJavacWrapper(fileName);
}
@TestMetadata("StaticImport.kt")
public void testStaticImport() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/javac/fieldsResolution/tests/StaticImport.kt");
doTestWithoutJavacWrapper(fileName);
}
@TestMetadata("StaticImportsAmbiguity.kt")
public void testStaticImportsAmbiguity() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/javac/fieldsResolution/tests/StaticImportsAmbiguity.kt");
doTestWithoutJavacWrapper(fileName);
}
}
}
@@ -220,6 +220,11 @@ fun main(args: Array<String>) {
model("javac/diagnostics/tests", testClassName = "TestsWithoutJavac", testMethod = "doTestWithoutJavacWrapper")
}
testClass<AbstractJavacFieldResolutionTest> {
model("javac/fieldsResolution/tests")
model("javac/fieldsResolution/tests", testClassName = "TestsWithoutJavac", testMethod = "doTestWithoutJavacWrapper")
}
testClass<AbstractDiagnosticsTestWithStdLib> {
model("diagnostics/testsWithStdLib")
}