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 package org.jetbrains.kotlin.cli.jvm.javac
import com.intellij.psi.PsiClass import com.intellij.psi.PsiClass
import org.jetbrains.kotlin.asJava.classes.KtLightClass
import org.jetbrains.kotlin.cli.jvm.compiler.CliLightClassGenerationSupport 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.ClassId
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.psi.KtClassOrObject
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> { override fun resolveSupertypes(classOrObject: KtClassOrObject): List<ClassId> {
val lightClass = lightClassGenerationSupport.getLightClass(classOrObject) ?: return emptyList() val lightClass = classOrObject.getLightClass() ?: return emptyList()
return lightClass.superTypes return lightClass.superTypes
.mapNotNull { it.resolve()?.computeClassId() } .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? = private fun PsiClass.computeClassId(): ClassId? =
containingClass?.computeClassId()?.createNestedClassId(Name.identifier(name!!)) ?: qualifiedName?.let { ClassId.topLevel(FqName(it)) } containingClass?.computeClassId()?.createNestedClassId(Name.identifier(name!!)) ?: qualifiedName?.let { ClassId.topLevel(FqName(it)) }
@@ -58,7 +58,7 @@ object JavacWrapperRegistrar {
val jvmClasspathRoots = configuration.jvmClasspathRoots val jvmClasspathRoots = configuration.jvmClasspathRoots
val outputDirectory = configuration.get(JVMConfigurationKeys.OUTPUT_DIRECTORY) val outputDirectory = configuration.get(JVMConfigurationKeys.OUTPUT_DIRECTORY)
val compileJava = configuration.getBoolean(JVMConfigurationKeys.COMPILE_JAVA) val compileJava = configuration.getBoolean(JVMConfigurationKeys.COMPILE_JAVA)
val kotlinSupertypesResolver = KotlinSupertypeResolverImpl(lightClassGenerationSupport) val kotlinSupertypesResolver = JavacWrapperKotlinResolverImpl(lightClassGenerationSupport)
val javacWrapper = JavacWrapper(javaFiles, kotlinFiles, arguments, jvmClasspathRoots, bootClasspath, sourcePath, val javacWrapper = JavacWrapper(javaFiles, kotlinFiles, arguments, jvmClasspathRoots, bootClasspath, sourcePath,
kotlinSupertypesResolver, compileJava, outputDirectory, context) 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.Log
import com.sun.tools.javac.util.Names import com.sun.tools.javac.util.Names
import com.sun.tools.javac.util.Options 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.SymbolBasedClass
import org.jetbrains.kotlin.javac.wrappers.symbols.SymbolBasedClassifierType import org.jetbrains.kotlin.javac.wrappers.symbols.SymbolBasedClassifierType
import org.jetbrains.kotlin.javac.wrappers.symbols.SymbolBasedPackage import org.jetbrains.kotlin.javac.wrappers.symbols.SymbolBasedPackage
import org.jetbrains.kotlin.javac.wrappers.trees.* import org.jetbrains.kotlin.javac.wrappers.trees.*
import org.jetbrains.kotlin.load.java.structure.JavaAnnotation import org.jetbrains.kotlin.load.java.structure.*
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.name.* import org.jetbrains.kotlin.name.*
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
import java.io.Closeable import java.io.Closeable
@@ -67,7 +68,7 @@ class JavacWrapper(
jvmClasspathRoots: List<File>, jvmClasspathRoots: List<File>,
bootClasspath: List<File>?, bootClasspath: List<File>?,
sourcePath: List<File>?, sourcePath: List<File>?,
val kotlinSupertypeResolver: KotlinSupertypeResolver, val kotlinResolver: JavacWrapperKotlinResolver,
private val compileJava: Boolean, private val compileJava: Boolean,
private val outputDirectory: File?, private val outputDirectory: File?,
private val context: Context private val context: Context
@@ -174,6 +175,7 @@ class JavacWrapper(
} }
val classifierResolver = ClassifierResolver(this) val classifierResolver = ClassifierResolver(this)
private val identifierResolver = IdentifierResolver(this)
private val kotlinClassifiersCache = KotlinClassifiersCache(if (javaFiles.isNotEmpty()) kotlinFiles else emptyList(), this) private val kotlinClassifiersCache = KotlinClassifiersCache(if (javaFiles.isNotEmpty()) kotlinFiles else emptyList(), this)
private val symbolBasedPackagesCache = hashMapOf<String, SymbolBasedPackage?>() private val symbolBasedPackagesCache = hashMapOf<String, SymbolBasedPackage?>()
@@ -281,6 +283,9 @@ class JavacWrapper(
fun resolve(treePath: TreePath): JavaClassifier? = fun resolve(treePath: TreePath): JavaClassifier? =
classifierResolver.resolve(treePath) classifierResolver.resolve(treePath)
fun resolveField(treePath: TreePath, containingClass: JavaClass): JavaField? =
identifierResolver.resolve(treePath, containingClass)
fun toVirtualFile(javaFileObject: JavaFileObject): VirtualFile? = fun toVirtualFile(javaFileObject: JavaFileObject): VirtualFile? =
javaFileObject.toUri().let { uri -> javaFileObject.toUri().let { uri ->
if (uri.scheme == "jar") { if (uri.scheme == "jar") {
@@ -16,9 +16,12 @@
package org.jetbrains.kotlin.javac package org.jetbrains.kotlin.javac
import org.jetbrains.kotlin.load.java.structure.JavaField
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.psi.KtClassOrObject
interface KotlinSupertypeResolver { interface JavacWrapperKotlinResolver {
fun resolveSupertypes(classOrObject: KtClassOrObject): List<ClassId> fun resolveSupertypes(classOrObject: KtClassOrObject): List<ClassId>
fun findField(classOrObject: KtClassOrObject, name: String): JavaField?
} }
@@ -14,15 +14,14 @@
* limitations under the License. * 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.tree.Tree
import com.sun.source.util.TreePath import com.sun.source.util.TreePath
import com.sun.tools.javac.tree.JCTree import com.sun.tools.javac.tree.JCTree
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.javac.JavacWrapper import org.jetbrains.kotlin.javac.JavacWrapper
import org.jetbrains.kotlin.javac.MockKotlinClassifier import org.jetbrains.kotlin.javac.wrappers.trees.TreeBasedClass
import org.jetbrains.kotlin.load.java.JavaVisibilities import org.jetbrains.kotlin.javac.wrappers.trees.TreeBasedTypeParameter
import org.jetbrains.kotlin.load.java.structure.JavaClass import org.jetbrains.kotlin.load.java.structure.JavaClass
import org.jetbrains.kotlin.load.java.structure.JavaClassifier import org.jetbrains.kotlin.load.java.structure.JavaClassifier
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
@@ -111,80 +110,14 @@ class ClassifierResolver(private val javac: JavacWrapper) {
} }
private abstract class Scope(protected 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 val parent: Scope?
abstract fun findClass(name: String, pathSegments: List<String>): JavaClassifier? 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) { 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? { override fun findClass(name: String, pathSegments: List<String>): JavaClass? {
findByFqName(pathSegments)?.let { return it } findByFqName(pathSegments)?.let { return it }
return findJavaOrKotlinClass(classId("java.lang", name))?.let { javaClass -> return helper.findJavaOrKotlinClass(classId("java.lang", name))?.let { javaClass ->
getJavaClassFromPathSegments(javaClass, pathSegments) helper.getJavaClassFromPathSegments(javaClass, pathSegments)
} }
} }
@@ -204,18 +137,18 @@ private class GlobalScope(javac: JavacWrapper, treePath: TreePath) : Scope(javac
pathSegments.forEachIndexed { index, _ -> pathSegments.forEachIndexed { index, _ ->
if (index != 0) { if (index != 0) {
val packageFqName = pathSegments.take(index).joinToString(separator = ".") val packageFqName = pathSegments.take(index).joinToString(separator = ".")
findPackage(packageFqName)?.let { pack -> helper.findPackage(packageFqName)?.let { pack ->
val className = pathSegments.drop(index) val className = pathSegments.drop(index)
findJavaOrKotlinClass(ClassId(pack, Name.identifier(className.first())))?.let { javaClass -> helper.findJavaOrKotlinClass(ClassId(pack, Name.identifier(className.first())))?.let { javaClass ->
return getJavaClassFromPathSegments(javaClass, className) return helper.getJavaClassFromPathSegments(javaClass, className)
} }
} }
} }
} }
// try to find in <root> // try to find in <root>
return findJavaOrKotlinClass(classId("", pathSegments.first()))?.let { javaClass -> return helper.findJavaOrKotlinClass(classId("", pathSegments.first()))?.let { javaClass ->
getJavaClassFromPathSegments(javaClass, pathSegments) helper.getJavaClassFromPathSegments(javaClass, pathSegments)
} }
} }
@@ -229,11 +162,11 @@ private class ImportOnDemandScope(javac: JavacWrapper,
override fun findClass(name: String, pathSegments: List<String>): JavaClassifier? { override fun findClass(name: String, pathSegments: List<String>): JavaClassifier? {
asteriskImports() asteriskImports()
.mapNotNullTo(hashSetOf()) { findImport("$it$name".split(".")) } .mapNotNullTo(hashSetOf()) { helper.findImport("$it$name".split(".")) }
.takeIf { it.isNotEmpty() } .takeIf { it.isNotEmpty() }
?.let { ?.let {
return it.singleOrNull()?.let { javaClass -> 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) get() = ImportOnDemandScope(javac, treePath)
override fun findClass(name: String, pathSegments: List<String>): JavaClassifier? { 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 -> ?.let { javaClass ->
return getJavaClassFromPathSegments(javaClass, pathSegments) return helper.getJavaClassFromPathSegments(javaClass, pathSegments)
} }
return parent.findClass(name, pathSegments) return parent.findClass(name, pathSegments)
@@ -281,8 +214,8 @@ private class SingleTypeImportScope(javac: JavacWrapper,
imports.singleOrNull() ?: return null imports.singleOrNull() ?: return null
return findImport(imports.first().split(".")) return helper.findImport(imports.first().split("."))
?.let { javaClass -> getJavaClassFromPathSegments(javaClass, pathSegments) } ?.let { javaClass -> helper.getJavaClassFromPathSegments(javaClass, pathSegments) }
} }
private fun imports(firstSegment: String) = private fun imports(firstSegment: String) =
@@ -310,7 +243,7 @@ private class CurrentClassAndInnerScope(javac: JavacWrapper,
?.find { typeParameter -> typeParameter.name == identifier } ?.find { typeParameter -> typeParameter.name == identifier }
?.let { typeParameter -> return typeParameter } ?.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 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. * limitations under the License.
*/ */
package org.jetbrains.kotlin.javac package org.jetbrains.kotlin.javac.resolve
import com.intellij.openapi.vfs.VirtualFile import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiField
import com.intellij.psi.PsiLiteralExpression
import com.intellij.psi.search.SearchScope import com.intellij.psi.search.SearchScope
import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.descriptors.Visibility import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.javac.JavacWrapper
import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.load.java.JavaVisibilities import org.jetbrains.kotlin.load.java.JavaVisibilities
import org.jetbrains.kotlin.load.java.structure.* import org.jetbrains.kotlin.load.java.structure.*
@@ -85,15 +88,6 @@ class MockKotlinClassifier(val classId: ClassId,
override val fqName: FqName override val fqName: FqName
get() = classId.asSingleFqName() 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 override val visibility: Visibility
get() = when (classOrObject.visibilityModifierType()) { get() = when (classOrObject.visibilityModifierType()) {
null, KtTokens.PUBLIC_KEYWORD -> Visibilities.PUBLIC null, KtTokens.PUBLIC_KEYWORD -> Visibilities.PUBLIC
@@ -102,11 +96,8 @@ class MockKotlinClassifier(val classId: ClassId,
else -> JavaVisibilities.PACKAGE_VISIBILITY else -> JavaVisibilities.PACKAGE_VISIBILITY
} }
override val typeParameters: List<JavaTypeParameter>
get() = throw UnsupportedOperationException("Should not be called")
override val supertypes: Collection<JavaClassifierType> override val supertypes: Collection<JavaClassifierType>
get() = javac.kotlinSupertypeResolver.resolveSupertypes(classOrObject) get() = javac.kotlinResolver.resolveSupertypes(classOrObject)
.mapNotNull { javac.getKotlinClassifier(it) ?: javac.findClass(it) } .mapNotNull { javac.getKotlinClassifier(it) ?: javac.findClass(it) }
.map { MockKotlinClassifierType(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 override val lightClassOriginKind
get() = LightClassOriginKind.SOURCE get() = LightClassOriginKind.SOURCE
override val virtualFile: VirtualFile? override val virtualFile: VirtualFile?
get() = null 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 override val name
get() = fqName.shortNameOrSpecial() 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 isFromSourceCodeInScope(scope: SearchScope) = true
override fun findAnnotation(fqName: FqName) =
throw UnsupportedOperationException("Should not be called")
override val innerClassNames override val innerClassNames
get() = innerClasses.map(JavaClass::name) get() = innerClasses.map(JavaClass::name)
@@ -177,36 +132,62 @@ class MockKotlinClassifier(val classId: ClassId,
val hasTypeParameters: Boolean val hasTypeParameters: Boolean
get() = typeParametersNumber > 0 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 { class MockKotlinClassifierType(override val classifier: JavaClassifier) : JavaClassifierType {
override val typeArguments: List<JavaType> override val typeArguments: List<JavaType>
get() = throw UnsupportedOperationException("Should not be called") get() = throw UnsupportedOperationException("Should not be called")
override val isRaw: Boolean override val isRaw: Boolean
get() = throw UnsupportedOperationException("Should not be called") get() = throw UnsupportedOperationException("Should not be called")
override val annotations: Collection<JavaAnnotation> override val annotations: Collection<JavaAnnotation>
get() = throw UnsupportedOperationException("Should not be called") get() = throw UnsupportedOperationException("Should not be called")
override val classifierQualifiedName: String override val classifierQualifiedName: String
get() = throw UnsupportedOperationException("Should not be called") get() = throw UnsupportedOperationException("Should not be called")
override val presentableText: String override val presentableText: String
get() = throw UnsupportedOperationException("Should not be called") get() = throw UnsupportedOperationException("Should not be called")
override fun findAnnotation(fqName: FqName) = override fun findAnnotation(fqName: FqName) =
throw UnsupportedOperationException("Should not be called") throw UnsupportedOperationException("Should not be called")
override val isDeprecatedInJavaDoc: Boolean override val isDeprecatedInJavaDoc: Boolean
get() = throw UnsupportedOperationException("Should not be called") 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 override val name: Name
get() = property.nameAsSafeName get() = throw UnsupportedOperationException("Should not be called")
override val annotations: Collection<JavaAnnotation> override val annotations: Collection<JavaAnnotation>
get() = throw UnsupportedOperationException("Should not be called") get() = throw UnsupportedOperationException("Should not be called")
override val isDeprecatedInJavaDoc: Boolean override val isDeprecatedInJavaDoc: Boolean
@@ -225,16 +206,8 @@ class MockKotlinField(private val property: KtProperty) : JavaField {
get() = throw UnsupportedOperationException("Should not be called") get() = throw UnsupportedOperationException("Should not be called")
override val type: JavaType override val type: JavaType
get() = throw UnsupportedOperationException("Should not be called") 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 override val hasConstantNotNullInitializer: Boolean
get() = throw UnsupportedOperationException("Should not be called") get() = throw UnsupportedOperationException("Should not be called")
override fun findAnnotation(fqName: FqName) = 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 else expr.value
} }
is JCTree.JCIdent -> containingClass.fields is JCTree.JCIdent,
.find { it.name == expr.name.toString().let { Name.identifier(it) } } is JCTree.JCFieldAccess -> javac.resolveField(javac.getTreePath(expr, treePath.compilationUnit), containingClass)?.initializerValue
?.initializerValue
is JCTree.JCFieldAccess -> fieldAccessValue(expr)
is JCTree.JCBinary -> binaryInitializerValue(expr) is JCTree.JCBinary -> binaryInitializerValue(expr)
is JCTree.JCParens -> getValue(expr.expr) is JCTree.JCParens -> getValue(expr.expr)
is JCTree.JCUnary -> unaryInitializerValue(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? { private fun unaryInitializerValue(value: JCTree.JCUnary): Any? {
val argValue = getValue(value.arg) val argValue = getValue(value.arg)
return when (value.tag) { return when (value.tag) {
@@ -21,7 +21,7 @@ import com.sun.tools.javac.code.BoundKind
import com.sun.tools.javac.tree.JCTree import com.sun.tools.javac.tree.JCTree
import org.jetbrains.kotlin.builtins.PrimitiveType import org.jetbrains.kotlin.builtins.PrimitiveType
import org.jetbrains.kotlin.javac.JavacWrapper 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.load.java.structure.*
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType 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); 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") @TestMetadata("compiler/testData/javac/diagnostics/tests/imports")
@TestDataPath("$PROJECT_ROOT") @TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class) @RunWith(JUnit3RunnerWithInners.class)
@@ -440,12 +434,6 @@ public class JavacDiagnosticsTestGenerated extends AbstractJavacDiagnosticsTest
doTestWithoutJavacWrapper(fileName); 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") @TestMetadata("compiler/testData/javac/diagnostics/tests/imports")
@TestDataPath("$PROJECT_ROOT") @TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class) @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") model("javac/diagnostics/tests", testClassName = "TestsWithoutJavac", testMethod = "doTestWithoutJavacWrapper")
} }
testClass<AbstractJavacFieldResolutionTest> {
model("javac/fieldsResolution/tests")
model("javac/fieldsResolution/tests", testClassName = "TestsWithoutJavac", testMethod = "doTestWithoutJavacWrapper")
}
testClass<AbstractDiagnosticsTestWithStdLib> { testClass<AbstractDiagnosticsTestWithStdLib> {
model("diagnostics/testsWithStdLib") model("diagnostics/testsWithStdLib")
} }