Support @JvmField annotation in light classes

This commit is contained in:
Denis Zharkov
2018-11-19 17:52:12 +03:00
parent dcc47fd8ef
commit 41997769e3
4 changed files with 44 additions and 10 deletions
@@ -161,16 +161,19 @@ class KtUltraLightClass(classOrObject: KtClassOrObject, private val support: Ult
)
for (property in companion.declarations.filterIsInstance<KtProperty>()) {
if (isInterface && !property.hasModifier(CONST_KEYWORD)) continue
if (isInterface && !property.isConstOrJvmField()) continue
propertyField(property, ::generateUniqueName, true)?.let(result::add)
}
}
if (!isInterface &&
!(this.classOrObject is KtObjectDeclaration && this.classOrObject.isCompanion() && containingClass?.isInterface == false)
) {
if (!isInterface) {
val isCompanion = this.classOrObject is KtObjectDeclaration && this.classOrObject.isCompanion()
for (property in this.classOrObject.declarations.filterIsInstance<KtProperty>()) {
// All fields for companion object of classes are generated to the containing class
// For interfaces, only @JvmField-annotated properties are generated to the containing class
// Probably, the same should work for const vals but it doesn't at the moment (see KT-28294)
if (isCompanion && (containingClass?.isInterface == false || property.isJvmField())) continue
propertyField(property, ::generateUniqueName, forceStatic = this.classOrObject is KtObjectDeclaration)?.let(result::add)
}
}
@@ -200,11 +203,10 @@ class KtUltraLightClass(classOrObject: KtClassOrObject, private val support: Ult
val visibility = when {
property.hasModifier(PRIVATE_KEYWORD) -> PsiModifier.PRIVATE
property.hasModifier(LATEINIT_KEYWORD) -> {
property.hasModifier(LATEINIT_KEYWORD) || property.isConstOrJvmField() -> {
val declaration = property.setter ?: property
simpleVisibility(declaration)
}
property.hasModifier(CONST_KEYWORD) -> PsiModifier.PUBLIC
else -> PsiModifier.PRIVATE
}
val modifiers = hashSetOf(visibility)
@@ -433,8 +435,8 @@ class KtUltraLightClass(classOrObject: KtClassOrObject, private val support: Ult
}
private fun propertyAccessors(declaration: KtCallableDeclaration, mutable: Boolean, onlyJvmStatic: Boolean): List<KtLightMethod> {
val propertyName = declaration.name
if (declaration.hasModifier(CONST_KEYWORD) || propertyName == null) return emptyList()
val propertyName = declaration.name ?: return emptyList()
if (declaration.isConstOrJvmField()) return emptyList()
val ktGetter = (declaration as? KtProperty)?.getter
val ktSetter = (declaration as? KtProperty)?.setter
@@ -484,6 +486,11 @@ class KtUltraLightClass(classOrObject: KtClassOrObject, private val support: Ult
return result
}
private fun KtCallableDeclaration.isConstOrJvmField() =
hasModifier(CONST_KEYWORD) || isJvmField()
private fun KtCallableDeclaration.isJvmField() = hasAnnotation(JvmAbi.JVM_FIELD_ANNOTATION_FQ_NAME)
private fun isFinal(declaration: KtDeclaration): Boolean {
if (declaration.hasModifier(FINAL_KEYWORD)) return true
return declaration !is KtPropertyAccessor &&
+20
View File
@@ -0,0 +1,20 @@
class A {
@JvmField
val a: Collection<*> = emptyList()
@JvmField
var b: Int = 1
companion object {
@JvmField
val c: Collection<*> = emptyList()
@JvmField
var d: Int = 1
}
}
interface B {
companion object {
@JvmField
val a: Collection<*> = emptyList()
}
}
@@ -115,6 +115,7 @@ class IDELightClassGenerationSupport(private val project: Project) : LightClassG
if (name == JVM_STATIC_ANNOTATION_FQ_NAME.shortName()) return false
if (name == JVM_SUPPRESS_WILDCARDS_ANNOTATION_FQ_NAME.shortName()) return false
if (name == JVM_WILDCARD_ANNOTATION_FQ_NAME.shortName()) return false
if (name == JvmAbi.JVM_FIELD_ANNOTATION_FQ_NAME.shortName()) return false
return true
}
@@ -129,7 +130,8 @@ class IDELightClassGenerationSupport(private val project: Project) : LightClassG
declaration.hasModifier(KtTokens.INLINE_KEYWORD) && declaration is KtClassOrObject ||
declaration.hasModifier(KtTokens.DATA_KEYWORD) ||
declaration.hasModifier(KtTokens.ENUM_KEYWORD) ||
declaration.hasModifier(KtTokens.SUSPEND_KEYWORD)) {
declaration.hasModifier(KtTokens.SUSPEND_KEYWORD)
) {
return declaration
}
@@ -99,6 +99,11 @@ public class UltraLightClassLoadingTestGenerated extends AbstractUltraLightClass
runTest("compiler/testData/asJava/ultraLightClasses/inlineOnly.kt");
}
@TestMetadata("jvmField.kt")
public void testJvmField() throws Exception {
runTest("compiler/testData/asJava/ultraLightClasses/jvmField.kt");
}
@TestMetadata("jvmName.kt")
public void testJvmName() throws Exception {
runTest("compiler/testData/asJava/ultraLightClasses/jvmName.kt");