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