From f00e5b199298f0008c0b438421286eb346937425 Mon Sep 17 00:00:00 2001 From: Roman Golyshev Date: Thu, 24 Dec 2020 15:03:54 +0300 Subject: [PATCH] FIR: Check `relativeClassName` of found class in `JavaSymbolProvider` `ClassId` denotes how class is nested; however, you can find `foo/bar/Outer.Nested` class by `ClassId(foo/bar/Outer/Nested)`. This will lead to inconsistencies when working with class symbol later This is also important to `FirQualifierResolverImpl::resolveSymbol` which detects correct `ClassId` by traversing all symbol qualifiers We check only `relativeClassName`, because we want to be able to find classes without package specified Also, fix test data of resolve tests that have been passing because of check absence --- .../kotlin/fir/java/JavaSymbolProvider.kt | 16 +++++++++++++--- .../resoreSymbolFromLibrary/classFromJdk.txt | 8 ++++---- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaSymbolProvider.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaSymbolProvider.kt index 9da1b4d0ca2..78806c5adff 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaSymbolProvider.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaSymbolProvider.kt @@ -134,9 +134,9 @@ class JavaSymbolProvider( classId, { val foundClass = findClass(classId, content) - if (foundClass == null || foundClass.annotations.any { - it.classId?.asSingleFqName() == JvmAnnotationNames.METADATA_FQ_NAME - } + if (foundClass == null || + foundClass.hasDifferentRelativeClassName(classId) || + foundClass.hasMetadataAnnotation() ) { null to null } else { @@ -148,6 +148,16 @@ class JavaSymbolProvider( } } + /** + * We do not check the package because we can look for the class in the same package by class name without package specified. + * In this case, found [JavaClass] may have different `packageFqName`, but not `relativeClassName`. + */ + private fun JavaClass.hasDifferentRelativeClassName(lookupClassId: ClassId): Boolean = + classId?.relativeClassName != lookupClassId.relativeClassName + + private fun JavaClass.hasMetadataAnnotation(): Boolean = + annotations.any { it.classId?.asSingleFqName() == JvmAnnotationNames.METADATA_FQ_NAME } + private class ValueParametersForAnnotationConstructor { val valueParameters: MutableList = mutableListOf() var valueParameterForValue: FirJavaValueParameter? = null diff --git a/idea/idea-frontend-fir/testData/resoreSymbolFromLibrary/classFromJdk.txt b/idea/idea-frontend-fir/testData/resoreSymbolFromLibrary/classFromJdk.txt index fdaadb53a6d..5d7f0a1fc3a 100644 --- a/idea/idea-frontend-fir/testData/resoreSymbolFromLibrary/classFromJdk.txt +++ b/idea/idea-frontend-fir/testData/resoreSymbolFromLibrary/classFromJdk.txt @@ -1,19 +1,19 @@ // RUNTIME -class: java.lang.String +class: java/lang/String // SYMBOLS: KtFirClassOrObjectSymbol: annotations: [] - classIdIfNonLocal: java.lang.String + classIdIfNonLocal: java/lang/String classKind: CLASS companionObject: null - isInner: true + isInner: false modality: FINAL name: String origin: JAVA primaryConstructor: null superTypes: [[] kotlin/Any, [] java/io/Serializable, [] kotlin/Comparable!>, [] kotlin/CharSequence] - symbolKind: MEMBER + symbolKind: TOP_LEVEL typeParameters: [] visibility: PUBLIC