KT-11678 Support navigation from Java source to Kotlin binaries
Introduce LightMemberOriginForCompiledElement which holds logic for finding corresponding decompiled declaration ByJvmSignatureIndexer stores the required information while building decompiled text Some are unsolved in this commit: - constructors - @Jvm* and other unregular generated members - annotation methods #KT-11678 Fixed
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
* Copyright 2010-2016 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.
|
||||
@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf
|
||||
|
||||
// The purpose of this class is to hold a unique signature of either a method or a field, so that annotations on a member can be put
|
||||
// into a map indexed by these signatures
|
||||
internal data class MemberSignature private constructor(internal val signature: String) {
|
||||
data class MemberSignature private constructor(internal val signature: String) {
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun fromMethod(nameResolver: NameResolver, signature: JvmProtoBuf.JvmMethodSignature): MemberSignature {
|
||||
|
||||
+12
@@ -17,7 +17,11 @@
|
||||
package org.jetbrains.kotlin.idea.caches.resolve
|
||||
|
||||
import com.intellij.psi.PsiClass
|
||||
import com.intellij.psi.PsiField
|
||||
import com.intellij.psi.PsiMethod
|
||||
import com.intellij.psi.impl.compiled.ClsClassImpl
|
||||
import org.jetbrains.kotlin.asJava.KtLightFieldImpl
|
||||
import org.jetbrains.kotlin.asJava.KtLightMethodImpl
|
||||
import org.jetbrains.kotlin.asJava.KtWrappingLightClass
|
||||
import org.jetbrains.kotlin.idea.decompiler.classFile.KtClsFile
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
@@ -40,6 +44,14 @@ class KtLightClassForDecompiledDeclaration(
|
||||
}
|
||||
}
|
||||
|
||||
override fun getOwnFields(): List<PsiField> {
|
||||
return clsDelegate.ownFields.map { KtLightFieldImpl.create(LightMemberOriginForCompiledField(it, file), it, this) }
|
||||
}
|
||||
|
||||
override fun getOwnMethods(): List<PsiMethod> {
|
||||
return clsDelegate.ownMethods.map { KtLightMethodImpl.create(it, LightMemberOriginForCompiledMethod(it, file), this) }
|
||||
}
|
||||
|
||||
override fun getNavigationElement() = kotlinOrigin?.navigationElement ?: file
|
||||
|
||||
override fun getFqName() = fqName
|
||||
|
||||
+144
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
* Copyright 2010-2016 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.idea.caches.resolve
|
||||
|
||||
import com.intellij.psi.PsiField
|
||||
import com.intellij.psi.PsiMember
|
||||
import com.intellij.psi.PsiMethod
|
||||
import org.jetbrains.kotlin.asJava.LightMemberOrigin
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.idea.decompiler.classFile.KtClsFile
|
||||
import org.jetbrains.kotlin.idea.decompiler.textBuilder.DecompiledTextIndexer
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.load.kotlin.MemberSignature
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPropertyDescriptor
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedSimpleFunctionDescriptor
|
||||
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf
|
||||
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBufUtil
|
||||
|
||||
interface LightMemberOriginForCompiledElement : LightMemberOrigin {
|
||||
override val originKind: JvmDeclarationOriginKind
|
||||
get() = JvmDeclarationOriginKind.OTHER
|
||||
}
|
||||
|
||||
|
||||
data class LightMemberOriginForCompiledField(val psiField: PsiField, val file: KtClsFile) : LightMemberOriginForCompiledElement {
|
||||
override fun copy(): LightMemberOrigin {
|
||||
return LightMemberOriginForCompiledField(psiField.copy() as PsiField, file)
|
||||
}
|
||||
|
||||
override val originalElement: KtDeclaration? by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
||||
val desc = MapPsiToAsmDesc.typeDesc(psiField.type)
|
||||
val signature = MemberSignature.fromFieldNameAndDesc(psiField.name!!, desc)
|
||||
file.getDeclaration(ByJvmSignatureIndexer, ClassNameAndSignature(psiField.relativeClassName(), signature))
|
||||
}
|
||||
}
|
||||
|
||||
data class LightMemberOriginForCompiledMethod(val psiMethod: PsiMethod, val file: KtClsFile) : LightMemberOriginForCompiledElement {
|
||||
override fun copy(): LightMemberOrigin {
|
||||
return LightMemberOriginForCompiledMethod(psiMethod.copy() as PsiMethod, file)
|
||||
}
|
||||
|
||||
override val originalElement: KtDeclaration? by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
||||
val desc = MapPsiToAsmDesc.methodDesc(psiMethod)
|
||||
val signature = MemberSignature.fromMethodNameAndDesc(psiMethod.name, desc)
|
||||
file.getDeclaration(ByJvmSignatureIndexer, ClassNameAndSignature(psiMethod.relativeClassName(), signature))
|
||||
}
|
||||
}
|
||||
|
||||
// this is convenient data structure for this purpose and is not supposed to be used outside this file
|
||||
// every member is represented by its jvm signature and relative class name (which is easy to obtain from descriptors or cls psi)
|
||||
|
||||
// relative class name is a path containing inner/nested class names from top level class to the class containing this member (excluding top level class name)
|
||||
// Examples: for top level function or function in a top level class relativeClassName is empty
|
||||
// For: class TopLevel { class A { class B { fun f() } } }
|
||||
// relativeClassName for function 'f' will be [A, B]
|
||||
private data class ClassNameAndSignature(val relativeClassName: List<Name>, val memberSignature: MemberSignature)
|
||||
|
||||
private fun PsiMember.relativeClassName(): List<Name> {
|
||||
return generateSequence(this.containingClass) { it.containingClass }.toList().dropLast(1).reversed().map { Name.identifier(it.name!!) }
|
||||
}
|
||||
|
||||
private fun ClassDescriptor.relativeClassName(): List<Name> {
|
||||
return classId.relativeClassName.pathSegments().drop(1).orEmpty()
|
||||
}
|
||||
|
||||
private fun ClassDescriptor.desc(): String = "L" + JvmClassName.byClassId(classId).internalName + ";"
|
||||
|
||||
private object ByJvmSignatureIndexer : DecompiledTextIndexer<ClassNameAndSignature> {
|
||||
override fun indexDescriptor(descriptor: DeclarationDescriptor): Collection<ClassNameAndSignature> {
|
||||
val signatures = arrayListOf<ClassNameAndSignature>()
|
||||
|
||||
fun save(id: List<Name>, signature: MemberSignature) {
|
||||
signatures.add(ClassNameAndSignature(id, signature))
|
||||
}
|
||||
|
||||
if (descriptor is ClassDescriptor) {
|
||||
@Suppress("NON_EXHAUSTIVE_WHEN")
|
||||
when (descriptor.kind) {
|
||||
ClassKind.ENUM_ENTRY -> {
|
||||
val enumClass = descriptor.containingDeclaration as ClassDescriptor
|
||||
val signature = MemberSignature.fromFieldNameAndDesc(descriptor.name.asString(), enumClass.desc())
|
||||
save(enumClass.relativeClassName(), signature)
|
||||
}
|
||||
ClassKind.OBJECT -> {
|
||||
val instanceFieldSignature = MemberSignature.fromFieldNameAndDesc(JvmAbi.INSTANCE_FIELD, descriptor.desc())
|
||||
save(descriptor.relativeClassName(), instanceFieldSignature)
|
||||
if (descriptor.isCompanionObject) {
|
||||
val signature = MemberSignature.fromFieldNameAndDesc(descriptor.name.asString(), descriptor.desc())
|
||||
save((descriptor.containingDeclaration as? ClassDescriptor)?.relativeClassName().orEmpty(), signature)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (descriptor is DeserializedSimpleFunctionDescriptor) {
|
||||
JvmProtoBufUtil.getJvmMethodSignature(descriptor.proto, descriptor.nameResolver, descriptor.typeTable)?.let {
|
||||
val signature = MemberSignature.fromMethodNameAndDesc(it)
|
||||
save((descriptor.containingDeclaration as? ClassDescriptor)?.relativeClassName().orEmpty(), signature)
|
||||
}
|
||||
}
|
||||
if (descriptor is DeserializedPropertyDescriptor) {
|
||||
val proto = descriptor.proto
|
||||
val className = (descriptor.containingDeclaration as? ClassDescriptor)?.relativeClassName().orEmpty()
|
||||
if (proto.hasExtension(JvmProtoBuf.propertySignature)) {
|
||||
val signature = proto.getExtension(JvmProtoBuf.propertySignature)
|
||||
val fieldSignature = JvmProtoBufUtil.getJvmFieldSignature(proto, descriptor.nameResolver, descriptor.typeTable)
|
||||
if (fieldSignature != null) {
|
||||
save(className, MemberSignature.fromFieldNameAndDesc(fieldSignature.name, fieldSignature.desc))
|
||||
}
|
||||
if (signature.hasGetter()) {
|
||||
save(className, MemberSignature.fromMethod(descriptor.nameResolver, signature.getter))
|
||||
}
|
||||
if (signature.hasSetter()) {
|
||||
save(className, MemberSignature.fromMethod(descriptor.nameResolver, signature.setter))
|
||||
}
|
||||
}
|
||||
}
|
||||
return signatures
|
||||
}
|
||||
}
|
||||
|
||||
// expose with different type
|
||||
val BySignatureIndexer: DecompiledTextIndexer<*> = ByJvmSignatureIndexer
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright 2010-2016 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.idea.caches.resolve
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.psi.*
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.Type.*
|
||||
|
||||
object MapPsiToAsmDesc {
|
||||
fun typeDesc(type: PsiType): String = when (type) {
|
||||
PsiType.VOID -> primitive(VOID_TYPE)
|
||||
|
||||
PsiType.BOOLEAN -> primitive(BOOLEAN_TYPE)
|
||||
|
||||
PsiType.CHAR -> primitive(CHAR_TYPE)
|
||||
PsiType.INT -> primitive(INT_TYPE)
|
||||
PsiType.BYTE -> primitive(BYTE_TYPE)
|
||||
PsiType.SHORT -> primitive(SHORT_TYPE)
|
||||
PsiType.LONG -> primitive(LONG_TYPE)
|
||||
|
||||
PsiType.FLOAT -> primitive(FLOAT_TYPE)
|
||||
PsiType.DOUBLE -> primitive(DOUBLE_TYPE)
|
||||
|
||||
is PsiArrayType -> "[" + typeDesc(type.componentType)
|
||||
|
||||
is PsiClassType -> {
|
||||
val resolved = type.resolve()
|
||||
when (resolved) {
|
||||
is PsiTypeParameter -> resolved.superTypes.firstOrNull()?.let { typeDesc(it) } ?: "Ljava/lang/Object;"
|
||||
is PsiClass -> classDesc(resolved)
|
||||
null -> unknownSignature()
|
||||
else -> error("Resolved to unexpected $resolved of class ${resolved.javaClass}" )
|
||||
}
|
||||
|
||||
}
|
||||
else -> error("Unexpected type $type of class ${type.javaClass}")
|
||||
}
|
||||
|
||||
private fun classDesc(psiClass: PsiClass) = buildString {
|
||||
append("L")
|
||||
val classes = generateSequence(psiClass) { it.containingClass }.toList().reversed()
|
||||
append(classes.first().qualifiedName!!.replace(".", "/"))
|
||||
classes.drop(1).forEach {
|
||||
append("$")
|
||||
append(it.name!!)
|
||||
}
|
||||
append(";")
|
||||
}
|
||||
|
||||
fun methodDesc(psiMethod: PsiMethod): String = buildString {
|
||||
append("(")
|
||||
psiMethod.parameterList.parameters.forEach {
|
||||
append(typeDesc(it.type))
|
||||
}
|
||||
append(")")
|
||||
psiMethod.returnType?.let {
|
||||
append(typeDesc(it))
|
||||
}
|
||||
?: return unknownSignature() // TODO: support constructors, there seems to be additional logic in java that doesn't work correctly for compiled kotlin
|
||||
}
|
||||
|
||||
private fun unknownSignature() = ""
|
||||
private fun error(message: String): String {
|
||||
LOG.error(message)
|
||||
return unknownSignature()
|
||||
}
|
||||
private fun primitive(asmType: Type) = asmType.descriptor
|
||||
|
||||
private val LOG = Logger.getInstance(javaClass)
|
||||
}
|
||||
+12
-8
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
* Copyright 2010-2016 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.
|
||||
@@ -21,10 +21,13 @@ import com.intellij.openapi.roots.FileIndexFacade
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.psi.PsiManager
|
||||
import com.intellij.psi.compiled.ClassFileDecompilers
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.idea.caches.IDEKotlinBinaryClassCache
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.BySignatureIndexer
|
||||
import org.jetbrains.kotlin.idea.decompiler.KotlinDecompiledFileViewProvider
|
||||
import org.jetbrains.kotlin.idea.decompiler.KtDecompiledFile
|
||||
import org.jetbrains.kotlin.idea.decompiler.common.createIncompatibleAbiVersionDecompiledText
|
||||
import org.jetbrains.kotlin.idea.decompiler.navigation.ByDescriptorIndexer
|
||||
import org.jetbrains.kotlin.idea.decompiler.textBuilder.DecompiledText
|
||||
import org.jetbrains.kotlin.idea.decompiler.textBuilder.ResolverForDecompiler
|
||||
import org.jetbrains.kotlin.idea.decompiler.textBuilder.buildDecompiledText
|
||||
@@ -34,7 +37,6 @@ import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
|
||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
||||
import org.jetbrains.kotlin.types.flexibility
|
||||
import org.jetbrains.kotlin.types.isFlexible
|
||||
import java.util.*
|
||||
|
||||
class KotlinClassFileDecompiler : ClassFileDecompilers.Full() {
|
||||
private val stubBuilder = KotlinClsStubBuilder()
|
||||
@@ -75,19 +77,21 @@ fun buildDecompiledTextForClassFile(
|
||||
return createIncompatibleAbiVersionDecompiledText(JvmMetadataVersion.INSTANCE, classHeader.metadataVersion)
|
||||
}
|
||||
|
||||
fun buildText(declarations: List<DeclarationDescriptor>) =
|
||||
buildDecompiledText(classId.packageFqName, declarations, decompilerRendererForClassFiles, listOf(ByDescriptorIndexer, BySignatureIndexer))
|
||||
|
||||
return when (classHeader.kind) {
|
||||
KotlinClassHeader.Kind.FILE_FACADE ->
|
||||
buildDecompiledText(classId.packageFqName, ArrayList(resolver.resolveDeclarationsInFacade(classId.asSingleFqName())),
|
||||
decompilerRendererForClassFiles)
|
||||
KotlinClassHeader.Kind.CLASS ->
|
||||
buildDecompiledText(classId.packageFqName, listOfNotNull(resolver.resolveTopLevelClass(classId)),
|
||||
decompilerRendererForClassFiles)
|
||||
buildText(resolver.resolveDeclarationsInFacade(classId.asSingleFqName()))
|
||||
KotlinClassHeader.Kind.CLASS -> {
|
||||
buildText(listOfNotNull(resolver.resolveTopLevelClass(classId)))
|
||||
}
|
||||
KotlinClassHeader.Kind.MULTIFILE_CLASS -> {
|
||||
val partClasses = findMultifileClassParts(classFile, classId, classHeader)
|
||||
val partMembers = partClasses.flatMap { partClass ->
|
||||
resolver.resolveDeclarationsInFacade(partClass.classId.asSingleFqName())
|
||||
}
|
||||
buildDecompiledText(classId.packageFqName, partMembers, decompilerRendererForClassFiles)
|
||||
buildText(partMembers)
|
||||
}
|
||||
else ->
|
||||
throw UnsupportedOperationException("Unknown header kind: $classHeader, class $classId")
|
||||
|
||||
Vendored
+2
-1
@@ -1,2 +1,3 @@
|
||||
[LibraryCompanionObjectUsages.0.kt] Companion object (10: 15) val a = A.Companion
|
||||
[LibraryCompanionObjectUsages.1.java] Local variable declaration (7: 11) A.Companion o = A.Companion;
|
||||
[LibraryCompanionObjectUsages.1.java] Local variable declaration (7: 11) A.Companion o = A.Companion;
|
||||
[LibraryCompanionObjectUsages.1.java] Unclassified usage (7: 27) A.Companion o = A.Companion;
|
||||
Vendored
+1
@@ -1,4 +1,5 @@
|
||||
[LibraryMemberFunctionUsages.0.kt] Callable reference (10: 16) val f = A::foo
|
||||
[LibraryMemberFunctionUsages.0.kt] Function call (11: 9) A().foo(1)
|
||||
[LibraryMemberFunctionUsages.1.java] Unclassified usage (11: 17) new A().foo(1);
|
||||
[library.kt] Callable reference (61: 17) val ff = A::foo
|
||||
[library.kt] Function call (60: 7) a.foo(2)
|
||||
@@ -0,0 +1,8 @@
|
||||
public class Field {
|
||||
public static void foo() {
|
||||
(new k.Class()).p<caret>rop;
|
||||
}
|
||||
}
|
||||
|
||||
// REF: (in k.Class).prop
|
||||
// CLS_REF: (in k.Class).prop
|
||||
@@ -5,4 +5,4 @@ public class PackageFacade {
|
||||
}
|
||||
|
||||
// REF: /src/<test dir>/resolve/referenceInJava/dependency.dependencies.kt
|
||||
// CLS_REF: (k).DependenciesKt
|
||||
// CLS_REF: <jar>!/k.DependenciesKt.class
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
public class MethodOfDeeplyNested {
|
||||
public static void foo() {
|
||||
(new k.Class.F.F()).f<caret>unction();
|
||||
}
|
||||
}
|
||||
|
||||
// REF: (in k.Class.F.F).function()
|
||||
// CLS_REF: (in k.Class.F.F).function()
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
public class MethodWithParameters {
|
||||
public static void foo() {
|
||||
(new k.Class()).f<caret>unction2();
|
||||
}
|
||||
}
|
||||
|
||||
// REF: (in k.Class).function2(Byte, Char, Short, Int, Long, Boolean, Float, Double, ByteArray, CharArray, IntArray, LongArray, BooleanArray, FloatArray, DoubleArray, Array<String>, Array<ByteArray>, Array<Array<String>>, T, G, String, Class.F, Class.G, Class.F.F)
|
||||
// CLS_REF: (in k.Class).function2(kotlin.Byte, kotlin.Char, kotlin.Short, kotlin.Int, kotlin.Long, kotlin.Boolean, kotlin.Float, kotlin.Double, kotlin.ByteArray, kotlin.CharArray, kotlin.IntArray, kotlin.LongArray, kotlin.BooleanArray, kotlin.FloatArray, kotlin.DoubleArray, kotlin.Array<kotlin.String>, kotlin.Array<kotlin.ByteArray>, kotlin.Array<kotlin.Array<kotlin.String>>, T, G, kotlin.String, k.Class.F, k.Class.G, k.Class.F.F)
|
||||
@@ -3,6 +3,26 @@ package k
|
||||
public class Class() {
|
||||
public val prop: Int = 0
|
||||
fun function() = 1
|
||||
|
||||
fun <T : Number, G> function2(
|
||||
b: Byte, c: Char, s: Short, i: Int, l: Long, bool: Boolean, f: Float, d: Double,
|
||||
ba: ByteArray, ca: CharArray, ia: IntArray, la: LongArray, boola: BooleanArray, fa: FloatArray, da: DoubleArray, sa: Array<String>,
|
||||
baa: Array<ByteArray>, saa: Array<Array<String>>,
|
||||
t: T, g: G, str: String, nestedClass: Class.F, innerClass: Class.G, nestedNested: Class.F.F
|
||||
) {
|
||||
}
|
||||
|
||||
class F {
|
||||
fun function() = 1
|
||||
|
||||
class F {
|
||||
fun function() = 1
|
||||
}
|
||||
}
|
||||
|
||||
inner class G {
|
||||
fun function() = 5
|
||||
}
|
||||
}
|
||||
|
||||
public enum class EnumClass {
|
||||
|
||||
@@ -61,6 +61,12 @@ public class ReferenceResolveInJavaTestGenerated extends AbstractReferenceResolv
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("Field.java")
|
||||
public void testField() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/resolve/referenceInJava/binaryAndSource/Field.java");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("FileFacade.java")
|
||||
public void testFileFacade() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/resolve/referenceInJava/binaryAndSource/FileFacade.java");
|
||||
@@ -79,6 +85,18 @@ public class ReferenceResolveInJavaTestGenerated extends AbstractReferenceResolv
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("MethodOfDeeplyNested.java")
|
||||
public void testMethodOfDeeplyNested() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/resolve/referenceInJava/binaryAndSource/MethodOfDeeplyNested.java");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("MethodWithParameters.java")
|
||||
public void testMethodWithParameters() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/resolve/referenceInJava/binaryAndSource/MethodWithParameters.java");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("ObjectInstance.java")
|
||||
public void testObjectInstance() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/resolve/referenceInJava/binaryAndSource/ObjectInstance.java");
|
||||
|
||||
+18
@@ -59,6 +59,12 @@ public class ReferenceToCompiledKotlinResolveInJavaTestGenerated extends Abstrac
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("Field.java")
|
||||
public void testField() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/resolve/referenceInJava/binaryAndSource/Field.java");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("FileFacade.java")
|
||||
public void testFileFacade() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/resolve/referenceInJava/binaryAndSource/FileFacade.java");
|
||||
@@ -77,6 +83,18 @@ public class ReferenceToCompiledKotlinResolveInJavaTestGenerated extends Abstrac
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("MethodOfDeeplyNested.java")
|
||||
public void testMethodOfDeeplyNested() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/resolve/referenceInJava/binaryAndSource/MethodOfDeeplyNested.java");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("MethodWithParameters.java")
|
||||
public void testMethodWithParameters() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/resolve/referenceInJava/binaryAndSource/MethodWithParameters.java");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("ObjectInstance.java")
|
||||
public void testObjectInstance() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/resolve/referenceInJava/binaryAndSource/ObjectInstance.java");
|
||||
|
||||
Reference in New Issue
Block a user