Kapt: Generate constant value initializers for mutable properties (KT-30164)
This commit is contained in:
+17
-1
@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.base.kapt3.KaptFlag
|
|||||||
import org.jetbrains.kotlin.codegen.coroutines.CONTINUATION_PARAMETER_NAME
|
import org.jetbrains.kotlin.codegen.coroutines.CONTINUATION_PARAMETER_NAME
|
||||||
import org.jetbrains.kotlin.codegen.needsExperimentalCoroutinesWrapper
|
import org.jetbrains.kotlin.codegen.needsExperimentalCoroutinesWrapper
|
||||||
import org.jetbrains.kotlin.config.LanguageFeature
|
import org.jetbrains.kotlin.config.LanguageFeature
|
||||||
|
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||||
@@ -49,11 +50,13 @@ import org.jetbrains.kotlin.load.java.sources.JavaSourceElement
|
|||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
|
import org.jetbrains.kotlin.resolve.DelegatingBindingTrace
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.DefaultValueArgument
|
import org.jetbrains.kotlin.resolve.calls.model.DefaultValueArgument
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument
|
||||||
import org.jetbrains.kotlin.resolve.constants.*
|
import org.jetbrains.kotlin.resolve.constants.*
|
||||||
|
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameOrNull
|
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameOrNull
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassOrAny
|
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassOrAny
|
||||||
@@ -644,8 +647,10 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContextForStubGenerati
|
|||||||
private fun convertPropertyInitializer(field: FieldNode): JCExpression? {
|
private fun convertPropertyInitializer(field: FieldNode): JCExpression? {
|
||||||
val value = field.value
|
val value = field.value
|
||||||
|
|
||||||
|
val origin = kaptContext.origins[field]
|
||||||
|
val propertyInitializer = (origin?.element as? KtProperty)?.initializer
|
||||||
|
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
val propertyInitializer = (kaptContext.origins[field]?.element as? KtProperty)?.initializer
|
|
||||||
if (propertyInitializer != null) {
|
if (propertyInitializer != null) {
|
||||||
return convertConstantValueArguments(value, listOf(propertyInitializer))
|
return convertConstantValueArguments(value, listOf(propertyInitializer))
|
||||||
}
|
}
|
||||||
@@ -653,6 +658,17 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContextForStubGenerati
|
|||||||
return convertValueOfPrimitiveTypeOrString(value)
|
return convertValueOfPrimitiveTypeOrString(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val propertyType = (origin?.descriptor as? PropertyDescriptor)?.returnType
|
||||||
|
if (propertyInitializer != null && propertyType != null) {
|
||||||
|
val moduleDescriptor = kaptContext.generationState.module
|
||||||
|
val evaluator = ConstantExpressionEvaluator(moduleDescriptor, LanguageVersionSettingsImpl.DEFAULT, kaptContext.project)
|
||||||
|
val trace = DelegatingBindingTrace(kaptContext.bindingContext, "Kapt")
|
||||||
|
val const = evaluator.evaluateExpression(propertyInitializer, trace, propertyType)
|
||||||
|
if (const != null && !const.isError && const.canBeUsedInAnnotations && !const.usesNonConstValAsConstant) {
|
||||||
|
return convertConstantValueArguments(const.getValue(propertyType), listOf(propertyInitializer))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (isFinal(field.access)) {
|
if (isFinal(field.access)) {
|
||||||
val type = Type.getType(field.desc)
|
val type = Type.getType(field.desc)
|
||||||
return convertLiteralExpression(getDefaultValue(type))
|
return convertLiteralExpression(getDefaultValue(type))
|
||||||
|
|||||||
+5
@@ -408,4 +408,9 @@ public class ClassFileToSourceStubConverterTestGenerated extends AbstractClassFi
|
|||||||
public void testTopLevel() throws Exception {
|
public void testTopLevel() throws Exception {
|
||||||
runTest("plugins/kapt3/kapt3-compiler/testData/converter/topLevel.kt");
|
runTest("plugins/kapt3/kapt3-compiler/testData/converter/topLevel.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("unsafePropertyInitializers.kt")
|
||||||
|
public void testUnsafePropertyInitializers() throws Exception {
|
||||||
|
runTest("plugins/kapt3/kapt3-compiler/testData/converter/unsafePropertyInitializers.kt");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ import java.lang.System;
|
|||||||
public final class TestAnno2 {
|
public final class TestAnno2 {
|
||||||
@org.jetbrains.annotations.NotNull()
|
@org.jetbrains.annotations.NotNull()
|
||||||
@Anno3(value = "field")
|
@Anno3(value = "field")
|
||||||
private java.lang.String b;
|
private java.lang.String b = "property initializer";
|
||||||
|
|
||||||
@Anno1()
|
@Anno1()
|
||||||
public final void a(@org.jetbrains.annotations.NotNull()
|
public final void a(@org.jetbrains.annotations.NotNull()
|
||||||
|
|||||||
@@ -130,9 +130,9 @@ public final class MyActivity {
|
|||||||
private final int f = 0;
|
private final int f = 0;
|
||||||
public final int propA = app.B.id.textView;
|
public final int propA = app.B.id.textView;
|
||||||
private final int propB = app.B.id.textView;
|
private final int propB = app.B.id.textView;
|
||||||
private int propC;
|
private int propC = app.B.id.textView;
|
||||||
public final int propD = app.B.id.textView;
|
public final int propD = app.B.id.textView;
|
||||||
public int propE;
|
public int propE = app.B.id.textView;
|
||||||
private final int propF = 0;
|
private final int propF = 0;
|
||||||
|
|
||||||
@Bind(id = lib.R.id.textView)
|
@Bind(id = lib.R.id.textView)
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ public final class Modifiers {
|
|||||||
@org.jetbrains.annotations.NotNull()
|
@org.jetbrains.annotations.NotNull()
|
||||||
private final transient java.lang.String transientField = "";
|
private final transient java.lang.String transientField = "";
|
||||||
@org.jetbrains.annotations.NotNull()
|
@org.jetbrains.annotations.NotNull()
|
||||||
private volatile java.lang.String volatileField;
|
private volatile java.lang.String volatileField = "";
|
||||||
|
|
||||||
@org.jetbrains.annotations.NotNull()
|
@org.jetbrains.annotations.NotNull()
|
||||||
public final java.lang.String getTransientField() {
|
public final java.lang.String getTransientField() {
|
||||||
|
|||||||
+24
@@ -0,0 +1,24 @@
|
|||||||
|
object Foo {
|
||||||
|
const val aString: String = "foo"
|
||||||
|
const val aInt: Int = 3
|
||||||
|
|
||||||
|
val bString: String = "bar"
|
||||||
|
val bInt: Int = 5
|
||||||
|
|
||||||
|
var cString: String = "baz"
|
||||||
|
var cInt: Int = 7
|
||||||
|
|
||||||
|
val d = Boo.z
|
||||||
|
val e = Boo.z.length
|
||||||
|
val f = 5 + 3
|
||||||
|
val g = "a" + "b"
|
||||||
|
val h = -4
|
||||||
|
val i = Int.MAX_VALUE
|
||||||
|
val j = "$e$g"
|
||||||
|
val k = g + j
|
||||||
|
}
|
||||||
|
|
||||||
|
object Boo {
|
||||||
|
val z = foo()
|
||||||
|
fun foo() = "abc"
|
||||||
|
}
|
||||||
+118
@@ -0,0 +1,118 @@
|
|||||||
|
import java.lang.System;
|
||||||
|
|
||||||
|
@kotlin.Metadata()
|
||||||
|
public final class Boo {
|
||||||
|
@org.jetbrains.annotations.NotNull()
|
||||||
|
private static final java.lang.String z = null;
|
||||||
|
public static final Boo INSTANCE = null;
|
||||||
|
|
||||||
|
@org.jetbrains.annotations.NotNull()
|
||||||
|
public final java.lang.String getZ() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@org.jetbrains.annotations.NotNull()
|
||||||
|
public final java.lang.String foo() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Boo() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
import java.lang.System;
|
||||||
|
|
||||||
|
@kotlin.Metadata()
|
||||||
|
public final class Foo {
|
||||||
|
@org.jetbrains.annotations.NotNull()
|
||||||
|
public static final java.lang.String aString = "foo";
|
||||||
|
public static final int aInt = 3;
|
||||||
|
@org.jetbrains.annotations.NotNull()
|
||||||
|
private static final java.lang.String bString = "bar";
|
||||||
|
private static final int bInt = 5;
|
||||||
|
@org.jetbrains.annotations.NotNull()
|
||||||
|
private static java.lang.String cString = "baz";
|
||||||
|
private static int cInt = 7;
|
||||||
|
@org.jetbrains.annotations.NotNull()
|
||||||
|
private static final java.lang.String d = null;
|
||||||
|
private static final int e = 0;
|
||||||
|
private static final int f = 8;
|
||||||
|
@org.jetbrains.annotations.NotNull()
|
||||||
|
private static final java.lang.String g = "ab";
|
||||||
|
private static final int h = -4;
|
||||||
|
private static final int i = 2147483647;
|
||||||
|
@org.jetbrains.annotations.NotNull()
|
||||||
|
private static final java.lang.String j = null;
|
||||||
|
@org.jetbrains.annotations.NotNull()
|
||||||
|
private static final java.lang.String k = null;
|
||||||
|
public static final Foo INSTANCE = null;
|
||||||
|
|
||||||
|
@org.jetbrains.annotations.NotNull()
|
||||||
|
public final java.lang.String getBString() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final int getBInt() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@org.jetbrains.annotations.NotNull()
|
||||||
|
public final java.lang.String getCString() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void setCString(@org.jetbrains.annotations.NotNull()
|
||||||
|
java.lang.String p0) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public final int getCInt() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void setCInt(int p0) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@org.jetbrains.annotations.NotNull()
|
||||||
|
public final java.lang.String getD() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final int getE() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final int getF() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@org.jetbrains.annotations.NotNull()
|
||||||
|
public final java.lang.String getG() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final int getH() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final int getI() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@org.jetbrains.annotations.NotNull()
|
||||||
|
public final java.lang.String getJ() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@org.jetbrains.annotations.NotNull()
|
||||||
|
public final java.lang.String getK() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Foo() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user