Fix ultra light structure for @JvmRecord classes

This commit is contained in:
Denis.Zharkov
2021-01-11 18:04:21 +03:00
parent 43b61a618d
commit 0e3aaceb16
8 changed files with 70 additions and 19 deletions
@@ -40,6 +40,7 @@ import org.jetbrains.kotlin.resolve.annotations.JVM_STATIC_ANNOTATION_FQ_NAME
import org.jetbrains.kotlin.resolve.annotations.argumentValue
import org.jetbrains.kotlin.resolve.constants.EnumValue
import org.jetbrains.kotlin.resolve.jvm.annotations.JVM_OVERLOADS_FQ_NAME
import org.jetbrains.kotlin.resolve.jvm.annotations.JVM_RECORD_ANNOTATION_FQ_NAME
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.typeUtil.isAnyOrNullableAny
@@ -282,7 +283,8 @@ open class KtUltraLightClass(classOrObject: KtClassOrObject, internal val suppor
parameter.isMutable,
forceStatic = false,
onlyJvmStatic = false,
createAsAnnotationMethod = isAnnotationType
createAsAnnotationMethod = isAnnotationType,
isJvmRecord = classOrObject.hasAnnotation(JVM_RECORD_ANNOTATION_FQ_NAME),
)
)
}
@@ -509,4 +511,4 @@ open class KtUltraLightClass(classOrObject: KtClassOrObject, internal val suppor
return super.getTextRange()
}
}
}
@@ -405,7 +405,8 @@ internal class UltraLightMembersCreator(
mutable: Boolean,
forceStatic: Boolean,
onlyJvmStatic: Boolean,
createAsAnnotationMethod: Boolean = false
createAsAnnotationMethod: Boolean = false,
isJvmRecord: Boolean = false,
): List<KtLightMethod> {
val propertyName = declaration.name ?: return emptyList()
@@ -454,7 +455,7 @@ internal class UltraLightMembersCreator(
auxiliaryOriginalElement = auxiliaryOrigin
)
val defaultGetterName = if (createAsAnnotationMethod) propertyName else JvmAbi.getterName(propertyName)
val defaultGetterName = if (createAsAnnotationMethod || isJvmRecord) propertyName else JvmAbi.getterName(propertyName)
val getterName = computeMethodName(auxiliaryOrigin, defaultGetterName, MethodType.GETTER)
val getterPrototype = lightMethod(getterName, auxiliaryOrigin, forceStatic = onlyJvmStatic || forceStatic)
val getterWrapper = KtUltraLightMethodForSourceDeclaration(
@@ -0,0 +1,24 @@
@kotlin.jvm.JvmRecord()
public final class MyRec /* pkg.MyRec*/ {
@org.jetbrains.annotations.NotNull()
private final java.lang.String name;
@org.jetbrains.annotations.NotNull()
public final java.lang.String component1();// component1()
@org.jetbrains.annotations.NotNull()
public final java.lang.String name();// name()
@org.jetbrains.annotations.NotNull()
public final pkg.MyRec copy(@org.jetbrains.annotations.NotNull() java.lang.String);// copy(java.lang.String)
@org.jetbrains.annotations.NotNull()
public java.lang.String toString();// toString()
public MyRec(@org.jetbrains.annotations.NotNull() java.lang.String);// .ctor(java.lang.String)
public boolean equals(@org.jetbrains.annotations.Nullable() java.lang.Object);// equals(java.lang.Object)
public int hashCode();// hashCode()
}
@@ -0,0 +1,8 @@
// CHECK_BY_JAVA_FILE
// API_VERSION: 1.5
// JVM_TARGET: 15
// COMPILER_ARGUMENTS: -XXLanguage:+JvmRecordSupport -Xjvm-enable-preview
package pkg
@JvmRecord
data class MyRec(val name: String)
@@ -134,6 +134,11 @@ public class FirClassLoadingTestGenerated extends AbstractFirClassLoadingTest {
runTest("compiler/testData/asJava/ultraLightClasses/jvmOverloads.kt");
}
@TestMetadata("jvmRecord.kt")
public void testJvmRecord() throws Exception {
runTest("compiler/testData/asJava/ultraLightClasses/jvmRecord.kt");
}
@TestMetadata("jvmSynthetic.kt")
public void testJvmSynthetic() throws Exception {
runTest("compiler/testData/asJava/ultraLightClasses/jvmSynthetic.kt");
@@ -46,6 +46,7 @@ import org.jetbrains.kotlin.idea.inspections.UnusedSymbolInspection
import org.jetbrains.kotlin.idea.test.CompilerTestDirectives.COMPILER_ARGUMENTS_DIRECTIVE
import org.jetbrains.kotlin.idea.test.CompilerTestDirectives.JVM_TARGET_DIRECTIVE
import org.jetbrains.kotlin.idea.test.CompilerTestDirectives.LANGUAGE_VERSION_DIRECTIVE
import org.jetbrains.kotlin.idea.test.CompilerTestDirectives.API_VERSION_DIRECTIVE
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.test.InTextDirectivesUtils
import org.jetbrains.kotlin.test.KotlinTestUtils
@@ -245,6 +246,7 @@ abstract class KotlinLightCodeInsightFixtureTestCase : KotlinLightCodeInsightFix
object CompilerTestDirectives {
const val LANGUAGE_VERSION_DIRECTIVE = "LANGUAGE_VERSION:"
const val API_VERSION_DIRECTIVE = "API_VERSION:"
const val JVM_TARGET_DIRECTIVE = "JVM_TARGET:"
const val COMPILER_ARGUMENTS_DIRECTIVE = "COMPILER_ARGUMENTS:"
@@ -265,6 +267,7 @@ fun <T> withCustomCompilerOptions(fileText: String, project: Project, module: Mo
private fun configureCompilerOptions(fileText: String, project: Project, module: Module): Boolean {
val version = InTextDirectivesUtils.findStringWithPrefixes(fileText, "// $LANGUAGE_VERSION_DIRECTIVE ")
val apiVersion = InTextDirectivesUtils.findStringWithPrefixes(fileText, "// $API_VERSION_DIRECTIVE ")
val jvmTarget = InTextDirectivesUtils.findStringWithPrefixes(fileText, "// $JVM_TARGET_DIRECTIVE ")
// We can have several such directives in quickFixMultiFile tests
// TODO: refactor such tests or add sophisticated check for the directive
@@ -274,7 +277,7 @@ private fun configureCompilerOptions(fileText: String, project: Project, module:
configureLanguageAndApiVersion(
project, module,
version ?: LanguageVersion.LATEST_STABLE.versionString,
null
apiVersion
)
val facetSettings = KotlinFacet.get(module)!!.configuration.settings
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.idea.perf.UltraLightChecker.checkByJavaFile
import org.jetbrains.kotlin.idea.perf.UltraLightChecker.checkDescriptorsLeak
import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase
import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor
import org.jetbrains.kotlin.idea.test.withCustomCompilerOptions
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.test.InTextDirectivesUtils
import org.jetbrains.kotlin.test.KotlinTestUtils
@@ -24,24 +25,26 @@ abstract class AbstractUltraLightClassLoadingTest : KotlinLightCodeInsightFixtur
open fun doTest(testDataPath: String) {
val sourceText = File(testDataPath).readText()
val file = myFixture.addFileToProject(testDataPath, sourceText) as KtFile
withCustomCompilerOptions(sourceText, project, module) {
val file = myFixture.addFileToProject(testDataPath, sourceText) as KtFile
UltraLightChecker.checkForReleaseCoroutine(sourceText, module)
UltraLightChecker.checkForReleaseCoroutine(sourceText, module)
val checkByJavaFile = InTextDirectivesUtils.isDirectiveDefined(sourceText, "CHECK_BY_JAVA_FILE")
val checkByJavaFile = InTextDirectivesUtils.isDirectiveDefined(sourceText, "CHECK_BY_JAVA_FILE")
val ktClassOrObjects = UltraLightChecker.allClasses(file)
val ktClassOrObjects = UltraLightChecker.allClasses(file)
if (checkByJavaFile) {
val classFabric = LightClassGenerationSupport.getInstance(project)
val classList = ktClassOrObjects.mapNotNull { classFabric.createUltraLightClass(it) }
checkByJavaFile(testDataPath, classList)
classList.forEach { checkDescriptorsLeak(it) }
} else {
for (ktClass in ktClassOrObjects) {
val ultraLightClass = UltraLightChecker.checkClassEquivalence(ktClass)
if (ultraLightClass != null) {
checkDescriptorsLeak(ultraLightClass)
if (checkByJavaFile) {
val classFabric = LightClassGenerationSupport.getInstance(project)
val classList = ktClassOrObjects.mapNotNull { classFabric.createUltraLightClass(it) }
checkByJavaFile(testDataPath, classList)
classList.forEach { checkDescriptorsLeak(it) }
} else {
for (ktClass in ktClassOrObjects) {
val ultraLightClass = UltraLightChecker.checkClassEquivalence(ktClass)
if (ultraLightClass != null) {
checkDescriptorsLeak(ultraLightClass)
}
}
}
}
@@ -134,6 +134,11 @@ public class UltraLightClassLoadingTestGenerated extends AbstractUltraLightClass
runTest("compiler/testData/asJava/ultraLightClasses/jvmOverloads.kt");
}
@TestMetadata("jvmRecord.kt")
public void testJvmRecord() throws Exception {
runTest("compiler/testData/asJava/ultraLightClasses/jvmRecord.kt");
}
@TestMetadata("jvmSynthetic.kt")
public void testJvmSynthetic() throws Exception {
runTest("compiler/testData/asJava/ultraLightClasses/jvmSynthetic.kt");