FIR Java: support read of field constant initializers

This commit is contained in:
Mikhail Glukhikh
2020-09-29 12:31:24 +03:00
parent fafb4a7914
commit 44ebec05bb
10 changed files with 34 additions and 20 deletions
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.builder.* import org.jetbrains.kotlin.fir.declarations.builder.*
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl
import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.expressions.builder.* import org.jetbrains.kotlin.fir.expressions.builder.*
import org.jetbrains.kotlin.fir.java.declarations.* import org.jetbrains.kotlin.fir.java.declarations.*
import org.jetbrains.kotlin.fir.resolve.constructType import org.jetbrains.kotlin.fir.resolve.constructType
@@ -309,10 +310,16 @@ class JavaSymbolProvider(
isVar = !javaField.isFinal isVar = !javaField.isFinal
isStatic = javaField.isStatic isStatic = javaField.isStatic
addAnnotationsFrom(this@JavaSymbolProvider.session, javaField, javaTypeParameterStack) addAnnotationsFrom(this@JavaSymbolProvider.session, javaField, javaTypeParameterStack)
initializer = convertJavaInitializerToFir(javaField.initializerValue)
} }
} }
} }
private fun convertJavaInitializerToFir(value: Any?): FirExpression? {
// NB: null should be converted to null
return value?.createConstantIfAny(session)
}
private fun convertJavaMethodToFir( private fun convertJavaMethodToFir(
javaMethod: JavaMethod, javaMethod: JavaMethod,
classId: ClassId, classId: ClassId,
@@ -451,7 +451,7 @@ private fun JavaAnnotationArgument.toFirExpression(
// TODO: this.name // TODO: this.name
return when (this) { return when (this) {
is JavaLiteralAnnotationArgument -> { is JavaLiteralAnnotationArgument -> {
value.createConstant(session) value.createConstantOrError(session)
} }
is JavaArrayAnnotationArgument -> buildArrayOfCall { is JavaArrayAnnotationArgument -> buildArrayOfCall {
argumentList = buildArgumentList { argumentList = buildArgumentList {
@@ -503,13 +503,19 @@ private fun <T> List<T>.createArrayOfCall(session: FirSession, @Suppress("UNUSED
return buildArrayOfCall { return buildArrayOfCall {
argumentList = buildArgumentList { argumentList = buildArgumentList {
for (element in this@createArrayOfCall) { for (element in this@createArrayOfCall) {
arguments += element.createConstant(session) arguments += element.createConstantOrError(session)
} }
} }
} }
} }
internal fun Any?.createConstant(session: FirSession): FirExpression { internal fun Any?.createConstantOrError(session: FirSession): FirExpression {
return createConstantIfAny(session) ?: buildErrorExpression {
diagnostic = ConeSimpleDiagnostic("Unknown value in JavaLiteralAnnotationArgument: $this", DiagnosticKind.Java)
}
}
internal fun Any?.createConstantIfAny(session: FirSession): FirExpression? {
return when (this) { return when (this) {
is Byte -> buildConstExpression(null, FirConstKind.Byte, this) is Byte -> buildConstExpression(null, FirConstKind.Byte, this)
is Short -> buildConstExpression(null, FirConstKind.Short, this) is Short -> buildConstExpression(null, FirConstKind.Short, this)
@@ -530,9 +536,7 @@ internal fun Any?.createConstant(session: FirSession): FirExpression {
is BooleanArray -> toList().createArrayOfCall(session, FirConstKind.Boolean) is BooleanArray -> toList().createArrayOfCall(session, FirConstKind.Boolean)
null -> buildConstExpression(null, FirConstKind.Null, null) null -> buildConstExpression(null, FirConstKind.Null, null)
else -> buildErrorExpression { else -> null
diagnostic = ConeSimpleDiagnostic("Unknown value in JavaLiteralAnnotationArgument: $this", DiagnosticKind.Java)
}
} }
} }
@@ -41,6 +41,7 @@ class FirJavaField @FirImplementationDetail constructor(
override val isVar: Boolean, override val isVar: Boolean,
override val annotations: MutableList<FirAnnotationCall>, override val annotations: MutableList<FirAnnotationCall>,
override val typeParameters: MutableList<FirTypeParameter>, override val typeParameters: MutableList<FirTypeParameter>,
override var initializer: FirExpression?,
) : FirField() { ) : FirField() {
init { init {
symbol.bind(this) symbol.bind(this)
@@ -71,6 +72,7 @@ class FirJavaField @FirImplementationDetail constructor(
override fun <D> transformOtherChildren(transformer: FirTransformer<D>, data: D): FirField { override fun <D> transformOtherChildren(transformer: FirTransformer<D>, data: D): FirField {
transformAnnotations(transformer, data) transformAnnotations(transformer, data)
initializer = initializer?.transformSingle(transformer, data)
return this return this
} }
@@ -86,6 +88,7 @@ class FirJavaField @FirImplementationDetail constructor(
returnTypeRef.accept(visitor, data) returnTypeRef.accept(visitor, data)
annotations.forEach { it.accept(visitor, data) } annotations.forEach { it.accept(visitor, data) }
typeParameters.forEach { it.accept(visitor, data) } typeParameters.forEach { it.accept(visitor, data) }
initializer?.accept(visitor, data)
} }
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirJavaField { override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirJavaField {
@@ -117,9 +120,6 @@ class FirJavaField @FirImplementationDetail constructor(
override val delegate: FirExpression? override val delegate: FirExpression?
get() = null get() = null
override val initializer: FirExpression?
get() = null
override val delegateFieldSymbol: FirDelegateFieldSymbol<FirField>? override val delegateFieldSymbol: FirDelegateFieldSymbol<FirField>?
get() = null get() = null
@@ -141,6 +141,7 @@ internal class FirJavaFieldBuilder : FirFieldBuilder() {
var modality: Modality? = null var modality: Modality? = null
lateinit var visibility: Visibility lateinit var visibility: Visibility
var isStatic: Boolean by Delegates.notNull() var isStatic: Boolean by Delegates.notNull()
var initializer: FirExpression? = null
override var resolvePhase: FirResolvePhase = FirResolvePhase.ANALYZED_DEPENDENCIES override var resolvePhase: FirResolvePhase = FirResolvePhase.ANALYZED_DEPENDENCIES
@@ -157,6 +158,7 @@ internal class FirJavaFieldBuilder : FirFieldBuilder() {
isVar, isVar,
annotations, annotations,
typeParameters, typeParameters,
initializer,
) )
} }
@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.expressions.builder.* import org.jetbrains.kotlin.fir.expressions.builder.*
import org.jetbrains.kotlin.fir.java.JavaSymbolProvider import org.jetbrains.kotlin.fir.java.JavaSymbolProvider
import org.jetbrains.kotlin.fir.java.createConstant import org.jetbrains.kotlin.fir.java.createConstantOrError
import org.jetbrains.kotlin.fir.java.topLevelName import org.jetbrains.kotlin.fir.java.topLevelName
import org.jetbrains.kotlin.fir.references.builder.buildErrorNamedReference import org.jetbrains.kotlin.fir.references.builder.buildErrorNamedReference
import org.jetbrains.kotlin.fir.references.builder.buildResolvedNamedReference import org.jetbrains.kotlin.fir.references.builder.buildResolvedNamedReference
@@ -288,7 +288,7 @@ class KotlinDeserializedJvmSymbolsProvider(
} }
private fun createConstant(value: Any?): FirExpression { private fun createConstant(value: Any?): FirExpression {
return value.createConstant(session) return value.createConstantOrError(session)
} }
} }
} }
@@ -102,6 +102,7 @@ class FirSignatureEnhancement(
isStatic = firElement.isStatic isStatic = firElement.isStatic
annotations += firElement.annotations annotations += firElement.annotations
status = firElement.status status = firElement.status
initializer = firElement.initializer
} }
return symbol return symbol
} }
@@ -1,7 +1,7 @@
public final class ClassWithConstVal : R|kotlin/Any| { public final class ClassWithConstVal : R|kotlin/Any| {
public final field f: R|kotlin/Int| public final field f: R|kotlin/Int| = Int(1)
public final field f2: R|kotlin/Int| public final field f2: R|kotlin/Int| = Int(1)
public constructor(): R|test/ClassWithConstVal| public constructor(): R|test/ClassWithConstVal|
@@ -1,5 +1,5 @@
public final class FinalFieldAsVal : R|kotlin/Any| { public final class FinalFieldAsVal : R|kotlin/Any| {
public final field f: R|kotlin/Int| public final field f: R|kotlin/Int| = Int(1)
public constructor(): R|test/FinalFieldAsVal| public constructor(): R|test/FinalFieldAsVal|
@@ -1,7 +1,7 @@
public open class AnnotatedField : R|kotlin/Any| { public open class AnnotatedField : R|kotlin/Any| {
@R|test/AnnotatedField.Anno|(String(static)) public final static field x: R|kotlin/Int| @R|test/AnnotatedField.Anno|(String(static)) public final static field x: R|kotlin/Int| = Int(0)
@R|test/AnnotatedField.Anno|(String(member)) public final field y: R|kotlin/Int| @R|test/AnnotatedField.Anno|(String(member)) public final field y: R|kotlin/Int| = Int(0)
public constructor(): R|test/AnnotatedField| public constructor(): R|test/AnnotatedField|
@@ -1,4 +1,4 @@
public abstract interface StringConstantInParam : R|kotlin/Any| { public abstract interface StringConstantInParam : R|kotlin/Any| {
public final static field HEL: R|ft<kotlin/String, kotlin/String?>!| public final static field HEL: R|ft<kotlin/String, kotlin/String?>!| = String(hel)
} }
@@ -1,13 +1,13 @@
public open class StaticFinal : R|kotlin/Any| { public open class StaticFinal : R|kotlin/Any| {
public final static field publicNonNull: R|ft<kotlin/String, kotlin/String?>!| public final static field publicNonNull: R|ft<kotlin/String, kotlin/String?>!| = String(aaa)
public final static field publicNull: R|ft<kotlin/String, kotlin/String?>!| public final static field publicNull: R|ft<kotlin/String, kotlin/String?>!|
public/*package*/ final static field packageNonNull: R|ft<kotlin/String, kotlin/String?>!| public/*package*/ final static field packageNonNull: R|ft<kotlin/String, kotlin/String?>!| = String(bbb)
public/*package*/ final static field packageNull: R|ft<kotlin/String, kotlin/String?>!| public/*package*/ final static field packageNull: R|ft<kotlin/String, kotlin/String?>!|
private final static field privateNonNull: R|ft<kotlin/String, kotlin/String?>!| private final static field privateNonNull: R|ft<kotlin/String, kotlin/String?>!| = String(bbb)
private final static field privateNull: R|ft<kotlin/String, kotlin/String?>!| private final static field privateNull: R|ft<kotlin/String, kotlin/String?>!|