Improved kotlin decompiler range indexes
Fixed #KT-30628
This commit is contained in:
@@ -57,10 +57,7 @@ object MapPsiToAsmDesc {
|
|||||||
append(typeDesc(it.type))
|
append(typeDesc(it.type))
|
||||||
}
|
}
|
||||||
append(")")
|
append(")")
|
||||||
psiMethod.returnType?.let {
|
append(psiMethod.returnType?.let { typeDesc(it) } ?: "V")
|
||||||
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 unknownSignature() = ""
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ import org.jetbrains.kotlin.idea.debugger.test.AbstractFileRankingTest
|
|||||||
import org.jetbrains.kotlin.idea.decompiler.navigation.AbstractNavigateToDecompiledLibraryTest
|
import org.jetbrains.kotlin.idea.decompiler.navigation.AbstractNavigateToDecompiledLibraryTest
|
||||||
import org.jetbrains.kotlin.idea.decompiler.navigation.AbstractNavigateToLibrarySourceTest
|
import org.jetbrains.kotlin.idea.decompiler.navigation.AbstractNavigateToLibrarySourceTest
|
||||||
import org.jetbrains.kotlin.idea.decompiler.navigation.AbstractNavigateToLibrarySourceTestWithJS
|
import org.jetbrains.kotlin.idea.decompiler.navigation.AbstractNavigateToLibrarySourceTestWithJS
|
||||||
|
import org.jetbrains.kotlin.idea.decompiler.navigation.AbstractNavigateJavaToLibrarySourceTest
|
||||||
import org.jetbrains.kotlin.idea.decompiler.stubBuilder.AbstractClsStubBuilderTest
|
import org.jetbrains.kotlin.idea.decompiler.stubBuilder.AbstractClsStubBuilderTest
|
||||||
import org.jetbrains.kotlin.idea.decompiler.stubBuilder.AbstractLoadJavaClsStubTest
|
import org.jetbrains.kotlin.idea.decompiler.stubBuilder.AbstractLoadJavaClsStubTest
|
||||||
import org.jetbrains.kotlin.idea.decompiler.textBuilder.AbstractCommonDecompiledTextFromJsMetadataTest
|
import org.jetbrains.kotlin.idea.decompiler.textBuilder.AbstractCommonDecompiledTextFromJsMetadataTest
|
||||||
@@ -332,6 +333,10 @@ fun main(args: Array<String>) {
|
|||||||
model("decompiler/navigation/usercode")
|
model("decompiler/navigation/usercode")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
testClass<AbstractNavigateJavaToLibrarySourceTest>(annotations = listOf(muteExtraSuffix(".libsrc"))) {
|
||||||
|
model("decompiler/navigation/userJavaCode", pattern = "^(.+)\\.java$")
|
||||||
|
}
|
||||||
|
|
||||||
testClass<AbstractNavigateToLibrarySourceTestWithJS>(annotations = listOf(muteExtraSuffix(".libsrcjs"))) {
|
testClass<AbstractNavigateToLibrarySourceTestWithJS>(annotations = listOf(muteExtraSuffix(".libsrcjs"))) {
|
||||||
model("decompiler/navigation/usercode", testClassName = "UsercodeWithJSModule")
|
model("decompiler/navigation/usercode", testClassName = "UsercodeWithJSModule")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ import org.jetbrains.kotlin.idea.debugger.test.AbstractFileRankingTest
|
|||||||
import org.jetbrains.kotlin.idea.decompiler.navigation.AbstractNavigateToDecompiledLibraryTest
|
import org.jetbrains.kotlin.idea.decompiler.navigation.AbstractNavigateToDecompiledLibraryTest
|
||||||
import org.jetbrains.kotlin.idea.decompiler.navigation.AbstractNavigateToLibrarySourceTest
|
import org.jetbrains.kotlin.idea.decompiler.navigation.AbstractNavigateToLibrarySourceTest
|
||||||
import org.jetbrains.kotlin.idea.decompiler.navigation.AbstractNavigateToLibrarySourceTestWithJS
|
import org.jetbrains.kotlin.idea.decompiler.navigation.AbstractNavigateToLibrarySourceTestWithJS
|
||||||
|
import org.jetbrains.kotlin.idea.decompiler.navigation.AbstractNavigateJavaToLibrarySourceTest
|
||||||
import org.jetbrains.kotlin.idea.decompiler.stubBuilder.AbstractClsStubBuilderTest
|
import org.jetbrains.kotlin.idea.decompiler.stubBuilder.AbstractClsStubBuilderTest
|
||||||
import org.jetbrains.kotlin.idea.decompiler.stubBuilder.AbstractLoadJavaClsStubTest
|
import org.jetbrains.kotlin.idea.decompiler.stubBuilder.AbstractLoadJavaClsStubTest
|
||||||
import org.jetbrains.kotlin.idea.decompiler.textBuilder.AbstractCommonDecompiledTextFromJsMetadataTest
|
import org.jetbrains.kotlin.idea.decompiler.textBuilder.AbstractCommonDecompiledTextFromJsMetadataTest
|
||||||
@@ -318,6 +319,10 @@ fun main(args: Array<String>) {
|
|||||||
model("decompiler/navigation/usercode")
|
model("decompiler/navigation/usercode")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
testClass<AbstractNavigateJavaToLibrarySourceTest>(annotations = listOf(muteExtraSuffix(".libsrc"))) {
|
||||||
|
model("decompiler/navigation/userJavaCode", pattern = "^(.+)\\.java$")
|
||||||
|
}
|
||||||
|
|
||||||
testClass<AbstractNavigateToLibrarySourceTestWithJS>(annotations = listOf(muteExtraSuffix(".libsrcjs"))) {
|
testClass<AbstractNavigateToLibrarySourceTestWithJS>(annotations = listOf(muteExtraSuffix(".libsrcjs"))) {
|
||||||
model("decompiler/navigation/usercode", testClassName ="UsercodeWithJSModule")
|
model("decompiler/navigation/usercode", testClassName ="UsercodeWithJSModule")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ import org.jetbrains.kotlin.idea.debugger.test.AbstractFileRankingTest
|
|||||||
import org.jetbrains.kotlin.idea.decompiler.navigation.AbstractNavigateToDecompiledLibraryTest
|
import org.jetbrains.kotlin.idea.decompiler.navigation.AbstractNavigateToDecompiledLibraryTest
|
||||||
import org.jetbrains.kotlin.idea.decompiler.navigation.AbstractNavigateToLibrarySourceTest
|
import org.jetbrains.kotlin.idea.decompiler.navigation.AbstractNavigateToLibrarySourceTest
|
||||||
import org.jetbrains.kotlin.idea.decompiler.navigation.AbstractNavigateToLibrarySourceTestWithJS
|
import org.jetbrains.kotlin.idea.decompiler.navigation.AbstractNavigateToLibrarySourceTestWithJS
|
||||||
|
import org.jetbrains.kotlin.idea.decompiler.navigation.AbstractNavigateJavaToLibrarySourceTest
|
||||||
import org.jetbrains.kotlin.idea.decompiler.stubBuilder.AbstractClsStubBuilderTest
|
import org.jetbrains.kotlin.idea.decompiler.stubBuilder.AbstractClsStubBuilderTest
|
||||||
import org.jetbrains.kotlin.idea.decompiler.stubBuilder.AbstractLoadJavaClsStubTest
|
import org.jetbrains.kotlin.idea.decompiler.stubBuilder.AbstractLoadJavaClsStubTest
|
||||||
import org.jetbrains.kotlin.idea.decompiler.textBuilder.AbstractCommonDecompiledTextFromJsMetadataTest
|
import org.jetbrains.kotlin.idea.decompiler.textBuilder.AbstractCommonDecompiledTextFromJsMetadataTest
|
||||||
@@ -318,6 +319,10 @@ fun main(args: Array<String>) {
|
|||||||
model("decompiler/navigation/usercode")
|
model("decompiler/navigation/usercode")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
testClass<AbstractNavigateJavaToLibrarySourceTest>(annotations = listOf(muteExtraSuffix(".libsrc"))) {
|
||||||
|
model("decompiler/navigation/userJavaCode", pattern = "^(.+)\\.java$")
|
||||||
|
}
|
||||||
|
|
||||||
testClass<AbstractNavigateToLibrarySourceTestWithJS>(annotations = listOf(muteExtraSuffix(".libsrcjs"))) {
|
testClass<AbstractNavigateToLibrarySourceTestWithJS>(annotations = listOf(muteExtraSuffix(".libsrcjs"))) {
|
||||||
model("decompiler/navigation/usercode", testClassName ="UsercodeWithJSModule")
|
model("decompiler/navigation/usercode", testClassName ="UsercodeWithJSModule")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ import org.jetbrains.kotlin.idea.debugger.test.AbstractFileRankingTest
|
|||||||
import org.jetbrains.kotlin.idea.decompiler.navigation.AbstractNavigateToDecompiledLibraryTest
|
import org.jetbrains.kotlin.idea.decompiler.navigation.AbstractNavigateToDecompiledLibraryTest
|
||||||
import org.jetbrains.kotlin.idea.decompiler.navigation.AbstractNavigateToLibrarySourceTest
|
import org.jetbrains.kotlin.idea.decompiler.navigation.AbstractNavigateToLibrarySourceTest
|
||||||
import org.jetbrains.kotlin.idea.decompiler.navigation.AbstractNavigateToLibrarySourceTestWithJS
|
import org.jetbrains.kotlin.idea.decompiler.navigation.AbstractNavigateToLibrarySourceTestWithJS
|
||||||
|
import org.jetbrains.kotlin.idea.decompiler.navigation.AbstractNavigateJavaToLibrarySourceTest
|
||||||
import org.jetbrains.kotlin.idea.decompiler.stubBuilder.AbstractClsStubBuilderTest
|
import org.jetbrains.kotlin.idea.decompiler.stubBuilder.AbstractClsStubBuilderTest
|
||||||
import org.jetbrains.kotlin.idea.decompiler.stubBuilder.AbstractLoadJavaClsStubTest
|
import org.jetbrains.kotlin.idea.decompiler.stubBuilder.AbstractLoadJavaClsStubTest
|
||||||
import org.jetbrains.kotlin.idea.decompiler.textBuilder.AbstractCommonDecompiledTextFromJsMetadataTest
|
import org.jetbrains.kotlin.idea.decompiler.textBuilder.AbstractCommonDecompiledTextFromJsMetadataTest
|
||||||
@@ -318,6 +319,10 @@ fun main(args: Array<String>) {
|
|||||||
model("decompiler/navigation/usercode")
|
model("decompiler/navigation/usercode")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
testClass<AbstractNavigateJavaToLibrarySourceTest>(annotations = listOf(muteExtraSuffix(".libsrc"))) {
|
||||||
|
model("decompiler/navigation/userJavaCode", pattern = "^(.+)\\.java$")
|
||||||
|
}
|
||||||
|
|
||||||
testClass<AbstractNavigateToLibrarySourceTestWithJS>(annotations = listOf(muteExtraSuffix(".libsrcjs"))) {
|
testClass<AbstractNavigateToLibrarySourceTestWithJS>(annotations = listOf(muteExtraSuffix(".libsrcjs"))) {
|
||||||
model("decompiler/navigation/usercode", testClassName ="UsercodeWithJSModule")
|
model("decompiler/navigation/usercode", testClassName ="UsercodeWithJSModule")
|
||||||
}
|
}
|
||||||
|
|||||||
+115
-37
@@ -1,17 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2017 JetBrains s.r.o.
|
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
*
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
* 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.lightClasses
|
package org.jetbrains.kotlin.idea.caches.lightClasses
|
||||||
@@ -20,6 +9,8 @@ import com.intellij.psi.PsiElement
|
|||||||
import com.intellij.psi.PsiField
|
import com.intellij.psi.PsiField
|
||||||
import com.intellij.psi.PsiMember
|
import com.intellij.psi.PsiMember
|
||||||
import com.intellij.psi.PsiMethod
|
import com.intellij.psi.PsiMethod
|
||||||
|
import com.intellij.psi.impl.compiled.SignatureParsing
|
||||||
|
import com.intellij.util.cls.ClsFormatException
|
||||||
import org.jetbrains.kotlin.asJava.builder.LightMemberOrigin
|
import org.jetbrains.kotlin.asJava.builder.LightMemberOrigin
|
||||||
import org.jetbrains.kotlin.asJava.classes.lazyPub
|
import org.jetbrains.kotlin.asJava.classes.lazyPub
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
@@ -36,12 +27,18 @@ import org.jetbrains.kotlin.name.Name
|
|||||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||||
import org.jetbrains.kotlin.psi.KtDeclarationContainer
|
import org.jetbrains.kotlin.psi.KtDeclarationContainer
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.components.hasDefaultValue
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
|
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
|
||||||
|
import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension
|
||||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
||||||
|
import org.jetbrains.kotlin.resolve.jvm.annotations.findJvmOverloadsAnnotation
|
||||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind
|
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind
|
||||||
|
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassConstructorDescriptor
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPropertyDescriptor
|
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPropertyDescriptor
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedSimpleFunctionDescriptor
|
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedSimpleFunctionDescriptor
|
||||||
import org.jetbrains.kotlin.type.MapPsiToAsmDesc
|
import org.jetbrains.kotlin.type.MapPsiToAsmDesc
|
||||||
|
import java.text.CharacterIterator
|
||||||
|
import java.text.StringCharacterIterator
|
||||||
|
|
||||||
interface LightMemberOriginForCompiledElement<T : PsiMember> : LightMemberOrigin {
|
interface LightMemberOriginForCompiledElement<T : PsiMember> : LightMemberOrigin {
|
||||||
val member: T
|
val member: T
|
||||||
@@ -98,7 +95,8 @@ data class LightMemberOriginForCompiledMethod(val psiMethod: PsiMethod, val file
|
|||||||
|
|
||||||
override val originalElement: KtDeclaration? by lazyPub {
|
override val originalElement: KtDeclaration? by lazyPub {
|
||||||
val desc = MapPsiToAsmDesc.methodDesc(psiMethod)
|
val desc = MapPsiToAsmDesc.methodDesc(psiMethod)
|
||||||
val signature = MemberSignature.fromMethodNameAndDesc(psiMethod.name, desc)
|
val name = if (psiMethod.isConstructor) "<init>" else psiMethod.name
|
||||||
|
val signature = MemberSignature.fromMethodNameAndDesc(name, desc)
|
||||||
findDeclarationInCompiledFile(file, psiMethod, signature)
|
findDeclarationInCompiledFile(file, psiMethod, signature)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -148,58 +146,138 @@ private fun ClassDescriptor.relativeClassName(): List<Name> {
|
|||||||
return classId!!.relativeClassName.pathSegments().drop(1)
|
return classId!!.relativeClassName.pathSegments().drop(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun excludeParametersFromDescriptor(descriptor: String, omittedParameters: List<Int>): String? {
|
||||||
|
|
||||||
|
fun tryParseParametersAndReturnType(): Pair<List<String>, String>? {
|
||||||
|
val iterator = StringCharacterIterator(descriptor)
|
||||||
|
|
||||||
|
fun parseTypeString(): String? {
|
||||||
|
val begin = iterator.index
|
||||||
|
try {
|
||||||
|
SignatureParsing.parseTypeString(iterator) { it }
|
||||||
|
} catch (e: ClsFormatException) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
val end = iterator.index
|
||||||
|
return descriptor.substring(begin, end)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iterator.current() != '(') return null
|
||||||
|
iterator.next()
|
||||||
|
|
||||||
|
if (iterator.current() == ')') {
|
||||||
|
iterator.next()
|
||||||
|
val returnType = parseTypeString() ?: return null
|
||||||
|
return emptyList<String>() to returnType
|
||||||
|
}
|
||||||
|
|
||||||
|
val parameterTypes = mutableListOf<String>()
|
||||||
|
while (iterator.current() != ')' && iterator.current() != CharacterIterator.DONE) {
|
||||||
|
parameterTypes += parseTypeString() ?: return null
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iterator.current() != ')') return null
|
||||||
|
iterator.next()
|
||||||
|
|
||||||
|
val returnType = parseTypeString() ?: return null
|
||||||
|
return parameterTypes to returnType
|
||||||
|
}
|
||||||
|
|
||||||
|
val (parameterTypes, returnType) = tryParseParametersAndReturnType() ?: return null
|
||||||
|
|
||||||
|
val parametersList = parameterTypes
|
||||||
|
.filterIndexed { index, _ -> index !in omittedParameters }
|
||||||
|
.joinToString("")
|
||||||
|
|
||||||
|
return "($parametersList)$returnType"
|
||||||
|
}
|
||||||
|
|
||||||
private fun ClassDescriptor.desc(): String = "L" + JvmClassName.byClassId(classId!!).internalName + ";"
|
private fun ClassDescriptor.desc(): String = "L" + JvmClassName.byClassId(classId!!).internalName + ";"
|
||||||
|
|
||||||
private object ByJvmSignatureIndexer : DecompiledTextIndexer<ClassNameAndSignature> {
|
private object ByJvmSignatureIndexer : DecompiledTextIndexer<ClassNameAndSignature> {
|
||||||
override fun indexDescriptor(descriptor: DeclarationDescriptor): Collection<ClassNameAndSignature> {
|
override fun indexDescriptor(descriptor: DeclarationDescriptor): Collection<ClassNameAndSignature> {
|
||||||
val signatures = arrayListOf<ClassNameAndSignature>()
|
val signatures = arrayListOf<ClassNameAndSignature>()
|
||||||
|
|
||||||
fun save(id: List<Name>, signature: MemberSignature) {
|
fun save(id: List<Name>, signature: MemberSignature) {
|
||||||
signatures.add(ClassNameAndSignature(id, signature))
|
signatures.add(ClassNameAndSignature(id, signature))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (descriptor is ClassDescriptor) {
|
fun ClassDescriptor.apply() {
|
||||||
@Suppress("NON_EXHAUSTIVE_WHEN")
|
when (kind) {
|
||||||
when (descriptor.kind) {
|
|
||||||
ClassKind.ENUM_ENTRY -> {
|
ClassKind.ENUM_ENTRY -> {
|
||||||
val enumClass = descriptor.containingDeclaration as ClassDescriptor
|
val enumClass = containingDeclaration as ClassDescriptor
|
||||||
val signature = MemberSignature.fromFieldNameAndDesc(descriptor.name.asString(), enumClass.desc())
|
val signature = MemberSignature.fromFieldNameAndDesc(name.asString(), enumClass.desc())
|
||||||
save(enumClass.relativeClassName(), signature)
|
save(enumClass.relativeClassName(), signature)
|
||||||
}
|
}
|
||||||
ClassKind.OBJECT -> {
|
ClassKind.OBJECT -> {
|
||||||
val instanceFieldSignature = MemberSignature.fromFieldNameAndDesc(JvmAbi.INSTANCE_FIELD, descriptor.desc())
|
val instanceFieldSignature = MemberSignature.fromFieldNameAndDesc(JvmAbi.INSTANCE_FIELD, desc())
|
||||||
save(descriptor.relativeClassName(), instanceFieldSignature)
|
save(relativeClassName(), instanceFieldSignature)
|
||||||
if (descriptor.isCompanionObject) {
|
if (isCompanionObject) {
|
||||||
val signature = MemberSignature.fromFieldNameAndDesc(descriptor.name.asString(), descriptor.desc())
|
val signature = MemberSignature.fromFieldNameAndDesc(name.asString(), desc())
|
||||||
save((descriptor.containingDeclaration as? ClassDescriptor)?.relativeClassName().orEmpty(), signature)
|
save((containingDeclaration as? ClassDescriptor)?.relativeClassName().orEmpty(), signature)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun DeserializedClassConstructorDescriptor.apply() {
|
||||||
|
JvmProtoBufUtil.getJvmConstructorSignature(proto, nameResolver, typeTable)?.let {
|
||||||
|
val id = (containingDeclaration as? ClassDescriptor)?.relativeClassName().orEmpty()
|
||||||
|
val signature = MemberSignature.fromJvmMemberSignature(it)
|
||||||
|
save(id, signature)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun DeserializedSimpleFunctionDescriptor.apply() {
|
||||||
|
JvmProtoBufUtil.getJvmMethodSignature(proto, nameResolver, typeTable)?.let {
|
||||||
|
val id = (containingDeclaration as? ClassDescriptor)?.relativeClassName().orEmpty()
|
||||||
|
|
||||||
|
val signature = MemberSignature.fromJvmMemberSignature(it)
|
||||||
|
save(id, signature)
|
||||||
|
|
||||||
|
if (findJvmOverloadsAnnotation() == null) return
|
||||||
|
|
||||||
|
val extensionShift = if (isExtension) 1 else 0
|
||||||
|
|
||||||
|
val omittedList = mutableListOf<Int>()
|
||||||
|
valueParameters.asReversed().forEach { parameter ->
|
||||||
|
if (parameter.hasDefaultValue()) {
|
||||||
|
omittedList.add(parameter.index + extensionShift)
|
||||||
|
val newDescriptor = excludeParametersFromDescriptor(it.desc, omittedList)
|
||||||
|
if (newDescriptor != null) {
|
||||||
|
val overloadedSignature = MemberSignature.fromMethodNameAndDesc(it.name, newDescriptor)
|
||||||
|
save(id, overloadedSignature)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (descriptor is DeserializedSimpleFunctionDescriptor) {
|
fun DeserializedPropertyDescriptor.apply() {
|
||||||
JvmProtoBufUtil.getJvmMethodSignature(descriptor.proto, descriptor.nameResolver, descriptor.typeTable)?.let { it ->
|
val className = (containingDeclaration as? ClassDescriptor)?.relativeClassName().orEmpty()
|
||||||
val signature = MemberSignature.fromJvmMemberSignature(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()
|
|
||||||
val signature = proto.getExtensionOrNull(JvmProtoBuf.propertySignature)
|
val signature = proto.getExtensionOrNull(JvmProtoBuf.propertySignature)
|
||||||
if (signature != null) {
|
if (signature != null) {
|
||||||
val fieldSignature = JvmProtoBufUtil.getJvmFieldSignature(proto, descriptor.nameResolver, descriptor.typeTable)
|
val fieldSignature = JvmProtoBufUtil.getJvmFieldSignature(proto, nameResolver, typeTable)
|
||||||
if (fieldSignature != null) {
|
if (fieldSignature != null) {
|
||||||
save(className, MemberSignature.fromJvmMemberSignature(fieldSignature))
|
save(className, MemberSignature.fromJvmMemberSignature(fieldSignature))
|
||||||
}
|
}
|
||||||
if (signature.hasGetter()) {
|
if (signature.hasGetter()) {
|
||||||
save(className, MemberSignature.fromMethod(descriptor.nameResolver, signature.getter))
|
save(className, MemberSignature.fromMethod(nameResolver, signature.getter))
|
||||||
}
|
}
|
||||||
if (signature.hasSetter()) {
|
if (signature.hasSetter()) {
|
||||||
save(className, MemberSignature.fromMethod(descriptor.nameResolver, signature.setter))
|
save(className, MemberSignature.fromMethod(nameResolver, signature.setter))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
when (descriptor) {
|
||||||
|
is ClassDescriptor -> descriptor.apply()
|
||||||
|
is DeserializedClassConstructorDescriptor -> descriptor.apply()
|
||||||
|
is DeserializedSimpleFunctionDescriptor -> descriptor.apply()
|
||||||
|
is DeserializedPropertyDescriptor -> descriptor.apply()
|
||||||
|
}
|
||||||
|
|
||||||
return signatures
|
return signatures
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package testData.libraries
|
||||||
|
|
||||||
|
class SomeClassWithConstructors(private val arg: String) {
|
||||||
|
constructor(x: Int) : this("Hello")
|
||||||
|
fun check() {
|
||||||
|
TODO()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
package testData.libraries
|
||||||
|
|
||||||
|
@JvmOverloads
|
||||||
|
fun <T> String.overloadedFun(vararg specs: String, allowExisting: Boolean = false, x: Int, y: Int = 2, z: T): String {
|
||||||
|
TODO()
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
package testData.libraries
|
||||||
|
|
||||||
|
@JvmName("renamedFun")
|
||||||
|
fun funToRename(x: Int) {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
import testData.libraries.*;
|
||||||
|
|
||||||
|
class TestClassAndConstructors {
|
||||||
|
void foo() {
|
||||||
|
|
||||||
|
SomeClassWithConstructors inst = new SomeClassWithConstructors("arg");
|
||||||
|
|
||||||
|
SomeClassWithConstructors inst2 = new SomeClassWithConstructors(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
Actual data differs from file content: ClassAndConstuctors.source.expected expected:< [SomeClassWithConstructors.class
|
||||||
|
public final class <1><2><3><4>SomeClassWithConstructors public constructor(arg: kotlin.String)] {
|
||||||
|
> but was:< [classAndConstructors.kt
|
||||||
|
class <1><2><3><4>SomeClassWithConstructors(private val arg: String) ] {
|
||||||
|
>
|
||||||
+2
@@ -0,0 +1,2 @@
|
|||||||
|
SomeClassWithConstructors.class
|
||||||
|
public final class <1><2><3><4>SomeClassWithConstructors public constructor(arg: kotlin.String) {
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
import testData.libraries.*;
|
||||||
|
|
||||||
|
class TestOverload {
|
||||||
|
void foo() {
|
||||||
|
OverloadedFunKt.overloadedFun("", null, 2, null);
|
||||||
|
|
||||||
|
OverloadedFunKt.overloadedFun("", null, true, 2, null);
|
||||||
|
|
||||||
|
OverloadedFunKt.overloadedFun("", null, true, 2, 3, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
Actual data differs from file content: OverloadedFun.source.expected expected:<...d from a class file
|
||||||
|
[// Implementation of methods is not available
|
||||||
|
|
||||||
|
package testData.libraries
|
||||||
|
|
||||||
|
@kotlin.jvm.JvmOverloads public fun <T> kotlin.String.<2><4><6>overloadedFun(vararg specs: kotlin.String, allowExisting: kotlin.Boolean /* = compiled code */, x: kotlin.Int, y: kotlin.Int /* = compiled code */, z: T): kotlin.String { /* compiled code */ }]
|
||||||
|
> but was:<...d from a class file
|
||||||
|
[ overloadedFun.kt
|
||||||
|
fun <T> String.<2><4><6>overloadedFun(vararg specs: String, allowExisting: Boolean = false, x: Int, y: Int = 2, z: T): String {]
|
||||||
|
>
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
OverloadedFunKt.class
|
||||||
|
<1><3><5>// IntelliJ API Decompiler stub source generated from a class file
|
||||||
|
// Implementation of methods is not available
|
||||||
|
|
||||||
|
package testData.libraries
|
||||||
|
|
||||||
|
@kotlin.jvm.JvmOverloads public fun <T> kotlin.String.<2><4><6>overloadedFun(vararg specs: kotlin.String, allowExisting: kotlin.Boolean /* = compiled code */, x: kotlin.Int, y: kotlin.Int /* = compiled code */, z: T): kotlin.String { /* compiled code */ }
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
import testData.libraries.*;
|
||||||
|
|
||||||
|
class TestRenamedElements {
|
||||||
|
void foo() {
|
||||||
|
RenamedElementsKt.renamedFun(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
+12
@@ -0,0 +1,12 @@
|
|||||||
|
Actual data differs from file content: RenamedElements.source.expected expected:<[RenamedElementsKt.class
|
||||||
|
<1>// IntelliJ API Decompiler stub source generated from a class file
|
||||||
|
// Implementation of methods is not available
|
||||||
|
|
||||||
|
package testData.libraries
|
||||||
|
|
||||||
|
@kotlin.jvm.JvmName public fun <2>funToRename(x: kotlin.Int): kotlin.Unit { /* compiled code */ }]
|
||||||
|
> but was:<[ RenamedElementsKt.class
|
||||||
|
<1>// IntelliJ API Decompiler stub source generated from a class file
|
||||||
|
renamedElements.kt
|
||||||
|
fun <2>funToRename(x: Int) {]
|
||||||
|
>
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
RenamedElementsKt.class
|
||||||
|
<1>// IntelliJ API Decompiler stub source generated from a class file
|
||||||
|
// Implementation of methods is not available
|
||||||
|
|
||||||
|
package testData.libraries
|
||||||
|
|
||||||
|
@kotlin.jvm.JvmName public fun <2>funToRename(x: kotlin.Int): kotlin.Unit { /* compiled code */ }
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
Actual data differs from file content: LibraryNestedClassSecondaryConstructorUsages.results.txt expected:<...3 class Y(): A.T()
|
||||||
|
[[LibraryNestedClassSecondaryConstructorUsages.1.java] New instance creation 14 A.T a = new A.T();
|
||||||
|
[LibraryNestedClassSecondaryConstructorUsages.1.java] Unclassified usage 10 super();
|
||||||
|
[LibraryNestedClassSecondaryConstructorUsages.1.java] Unclassified usage 6 public J() {
|
||||||
|
[library.kt] New instance creation 64 val tt = A.T()
|
||||||
|
[library.kt] Supertype 40 class VV(): A.T()
|
||||||
|
]> but was:<...3 class Y(): A.T()
|
||||||
|
[[library.kt] New instance creation 64 val tt = A.T()
|
||||||
|
[library.kt] Supertype 40 class VV(): A.T()]>
|
||||||
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
package usages
|
package usages;
|
||||||
|
|
||||||
import library.*
|
import library.*;
|
||||||
|
|
||||||
class J extends A.T {
|
class J extends A.T {
|
||||||
public J() {
|
public J() {
|
||||||
|
|||||||
+3
@@ -1,4 +1,7 @@
|
|||||||
[LibraryNestedClassSecondaryConstructorUsages.0.kt] New instance creation 16 val a: A.T = A.T()
|
[LibraryNestedClassSecondaryConstructorUsages.0.kt] New instance creation 16 val a: A.T = A.T()
|
||||||
[LibraryNestedClassSecondaryConstructorUsages.0.kt] Supertype 13 class Y(): A.T()
|
[LibraryNestedClassSecondaryConstructorUsages.0.kt] Supertype 13 class Y(): A.T()
|
||||||
|
[LibraryNestedClassSecondaryConstructorUsages.1.java] New instance creation 14 A.T a = new A.T();
|
||||||
|
[LibraryNestedClassSecondaryConstructorUsages.1.java] Unclassified usage 10 super();
|
||||||
|
[LibraryNestedClassSecondaryConstructorUsages.1.java] Unclassified usage 6 public J() {
|
||||||
[library.kt] New instance creation 64 val tt = A.T()
|
[library.kt] New instance creation 64 val tt = A.T()
|
||||||
[library.kt] Supertype 40 class VV(): A.T()
|
[library.kt] Supertype 40 class VV(): A.T()
|
||||||
|
|||||||
idea/testData/findUsages/libraryUsages/kotlinLibrary/LibrarySecondaryConstructorUsages.0.kt.fail.192
Vendored
+6
@@ -0,0 +1,6 @@
|
|||||||
|
Actual data differs from file content: LibrarySecondaryConstructorUsages.results.txt expected:<... 13 class Y(): A()
|
||||||
|
[[LibrarySecondaryConstructorUsages.1.java] New instance creation 14 A a = new A();
|
||||||
|
[LibrarySecondaryConstructorUsages.1.java] Unclassified usage 10 super();
|
||||||
|
[LibrarySecondaryConstructorUsages.1.java] Unclassified usage 6 public J() {
|
||||||
|
[]library.kt] New inst...> but was:<... 13 class Y(): A()
|
||||||
|
[[]library.kt] New inst...>
|
||||||
Vendored
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
package usages
|
package usages;
|
||||||
|
|
||||||
import library.*
|
import library.*;
|
||||||
|
|
||||||
class J extends A {
|
class J extends A {
|
||||||
public J() {
|
public J() {
|
||||||
|
|||||||
Vendored
+3
@@ -1,4 +1,7 @@
|
|||||||
[LibrarySecondaryConstructorUsages.0.kt] New instance creation 16 val a: A = A()
|
[LibrarySecondaryConstructorUsages.0.kt] New instance creation 16 val a: A = A()
|
||||||
[LibrarySecondaryConstructorUsages.0.kt] Supertype 13 class Y(): A()
|
[LibrarySecondaryConstructorUsages.0.kt] Supertype 13 class Y(): A()
|
||||||
|
[LibrarySecondaryConstructorUsages.1.java] New instance creation 14 A a = new A();
|
||||||
|
[LibrarySecondaryConstructorUsages.1.java] Unclassified usage 10 super();
|
||||||
|
[LibrarySecondaryConstructorUsages.1.java] Unclassified usage 6 public J() {
|
||||||
[library.kt] New instance creation 58 val aa = A()
|
[library.kt] New instance creation 58 val aa = A()
|
||||||
[library.kt] Supertype 39 class CC(): A() {
|
[library.kt] Supertype 39 class CC(): A() {
|
||||||
+20
-8
@@ -5,8 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.idea.decompiler.navigation
|
package org.jetbrains.kotlin.idea.decompiler.navigation
|
||||||
|
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.*
|
||||||
import com.intellij.psi.PsiFile
|
|
||||||
import com.intellij.psi.impl.source.resolve.reference.impl.PsiMultiReference
|
import com.intellij.psi.impl.source.resolve.reference.impl.PsiMultiReference
|
||||||
import junit.framework.TestCase
|
import junit.framework.TestCase
|
||||||
import org.jetbrains.kotlin.idea.navigation.NavigationTestUtils
|
import org.jetbrains.kotlin.idea.navigation.NavigationTestUtils
|
||||||
@@ -22,7 +21,8 @@ abstract class AbstractNavigateToLibraryTest : KotlinLightCodeInsightFixtureTest
|
|||||||
|
|
||||||
protected fun doTest(path: String) {
|
protected fun doTest(path: String) {
|
||||||
myFixture.configureByFile(fileName())
|
myFixture.configureByFile(fileName())
|
||||||
NavigationChecker.checkAnnotatedCode(file, File(path.replace(".kt", expectedFileExt)))
|
val pathOfExpect = path.replace(Regex("\\.kt|\\.java"), expectedFileExt)
|
||||||
|
NavigationChecker.checkAnnotatedCode(file, File(pathOfExpect))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun tearDown() {
|
override fun tearDown() {
|
||||||
@@ -55,6 +55,18 @@ abstract class AbstractNavigateToLibrarySourceTest : AbstractNavigateToLibraryTe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
abstract class AbstractNavigateJavaToLibrarySourceTest : AbstractNavigateToLibraryTest() {
|
||||||
|
override val expectedFileExt: String get() = ".source.expected"
|
||||||
|
|
||||||
|
override fun getProjectDescriptor(): KotlinLightProjectDescriptor = PROJECT_DESCRIPTOR
|
||||||
|
|
||||||
|
protected companion object {
|
||||||
|
val PROJECT_DESCRIPTOR = SdkAndMockLibraryProjectDescriptor(
|
||||||
|
PluginTestCaseBase.getTestDataPathBase() + "/decompiler/navigation/fromJavaSource", true
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
abstract class AbstractNavigateToLibrarySourceTestWithJS : AbstractNavigateToLibrarySourceTest() {
|
abstract class AbstractNavigateToLibrarySourceTestWithJS : AbstractNavigateToLibrarySourceTest() {
|
||||||
override fun getProjectDescriptor(): KotlinLightProjectDescriptor = KotlinMultiModuleProjectDescriptor(
|
override fun getProjectDescriptor(): KotlinLightProjectDescriptor = KotlinMultiModuleProjectDescriptor(
|
||||||
"AbstractNavigateToLibrarySourceTestWithJS",
|
"AbstractNavigateToLibrarySourceTestWithJS",
|
||||||
@@ -74,13 +86,13 @@ class NavigationChecker(val file: PsiFile, val referenceTargetChecker: (PsiEleme
|
|||||||
target!!.navigationElement
|
target!!.navigationElement
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun collectInterestingReferences(): Collection<KtReference> {
|
private fun collectInterestingReferences(): Collection<PsiReference> {
|
||||||
val referenceContainersToReferences = LinkedHashMap<PsiElement, KtReference>()
|
val referenceContainersToReferences = LinkedHashMap<PsiElement, PsiReference>()
|
||||||
for (offset in 0 until file.textLength) {
|
for (offset in 0 until file.textLength) {
|
||||||
val refs = when (val ref = file.findReferenceAt(offset)) {
|
val refs = when (val ref = file.findReferenceAt(offset)) {
|
||||||
is KtReference -> listOf(ref)
|
is KtReference, is PsiReferenceExpression, is PsiJavaCodeReferenceElement -> listOf(ref)
|
||||||
is PsiMultiReference -> ref.references.filterIsInstance<KtReference>()
|
is PsiMultiReference -> ref.references.filterIsInstance<KtReference>()
|
||||||
else -> emptyList<KtReference>()
|
else -> emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
refs.forEach { referenceContainersToReferences.addReference(it) }
|
refs.forEach { referenceContainersToReferences.addReference(it) }
|
||||||
@@ -88,7 +100,7 @@ class NavigationChecker(val file: PsiFile, val referenceTargetChecker: (PsiEleme
|
|||||||
return referenceContainersToReferences.values
|
return referenceContainersToReferences.values
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun MutableMap<PsiElement, KtReference>.addReference(ref: KtReference) {
|
private fun MutableMap<PsiElement, PsiReference>.addReference(ref: PsiReference) {
|
||||||
if (containsKey(ref.element)) return
|
if (containsKey(ref.element)) return
|
||||||
val target = ref.resolve() ?: return
|
val target = ref.resolve() ?: return
|
||||||
|
|
||||||
|
|||||||
+47
@@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.idea.decompiler.navigation;
|
||||||
|
|
||||||
|
import com.intellij.testFramework.TestDataPath;
|
||||||
|
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
|
||||||
|
import org.jetbrains.kotlin.test.KotlinTestUtils;
|
||||||
|
import org.jetbrains.kotlin.test.MuteExtraSuffix;
|
||||||
|
import org.jetbrains.kotlin.test.TestMetadata;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
@TestMetadata("idea/testData/decompiler/navigation/userJavaCode")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@MuteExtraSuffix(".libsrc")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public class NavigateJavaToLibrarySourceTestGenerated extends AbstractNavigateJavaToLibrarySourceTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInUserJavaCode() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/decompiler/navigation/userJavaCode"), Pattern.compile("^(.+)\\.java$"), null, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("ClassAndConstuctors.java")
|
||||||
|
public void testClassAndConstuctors() throws Exception {
|
||||||
|
runTest("idea/testData/decompiler/navigation/userJavaCode/ClassAndConstuctors.java");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("OverloadedFun.java")
|
||||||
|
public void testOverloadedFun() throws Exception {
|
||||||
|
runTest("idea/testData/decompiler/navigation/userJavaCode/OverloadedFun.java");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("RenamedElements.java")
|
||||||
|
public void testRenamedElements() throws Exception {
|
||||||
|
runTest("idea/testData/decompiler/navigation/userJavaCode/RenamedElements.java");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -20,3 +20,8 @@ org.jetbrains.kotlin.idea.completion.test.JvmBasicCompletionTestGenerated.Java.S
|
|||||||
org.jetbrains.kotlin.idea.completion.test.JvmBasicCompletionTestGenerated.Java.SyntheticExtensions.testSyntheticExtensions1, KT-32919
|
org.jetbrains.kotlin.idea.completion.test.JvmBasicCompletionTestGenerated.Java.SyntheticExtensions.testSyntheticExtensions1, KT-32919
|
||||||
org.jetbrains.kotlin.idea.completion.test.weighers.BasicCompletionWeigherTestGenerated.testPreferFromJdk, KT-35709 Class from JDK is not prioritized
|
org.jetbrains.kotlin.idea.completion.test.weighers.BasicCompletionWeigherTestGenerated.testPreferFromJdk, KT-35709 Class from JDK is not prioritized
|
||||||
org.jetbrains.kotlin.idea.quickfix.QuickFixMultiFileTestGenerated.AutoImports.testAmbiguousNamePreferFromJdk, KT-35709 Class from JDK is not prioritized
|
org.jetbrains.kotlin.idea.quickfix.QuickFixMultiFileTestGenerated.AutoImports.testAmbiguousNamePreferFromJdk, KT-35709 Class from JDK is not prioritized
|
||||||
|
org.jetbrains.kotlin.findUsages.KotlinFindUsagesWithLibraryTestGenerated.KotlinLibrary.testLibrarySecondaryConstructorUsages, KT-34542, FAIL
|
||||||
|
org.jetbrains.kotlin.findUsages.KotlinFindUsagesWithLibraryTestGenerated.KotlinLibrary.testLibraryNestedClassSecondaryConstructorUsages, KT-34542, FAIL
|
||||||
|
org.jetbrains.kotlin.idea.decompiler.navigation.NavigateJavaToLibrarySourceTestGenerated.testClassAndConstuctors, KT-34542, FAIL
|
||||||
|
org.jetbrains.kotlin.idea.decompiler.navigation.NavigateJavaToLibrarySourceTestGenerated.testOverloadedFun, KT-34542, FAIL
|
||||||
|
org.jetbrains.kotlin.idea.decompiler.navigation.NavigateJavaToLibrarySourceTestGenerated.testRenamedElements, KT-34542, FAIL
|
||||||
Reference in New Issue
Block a user