[FIR] Properly compute default arguments of java annotations

This commit is contained in:
Dmitriy Novozhilov
2021-03-04 15:01:00 +03:00
parent 8324f499cd
commit bd7689d381
3 changed files with 20 additions and 7 deletions
@@ -454,8 +454,8 @@ class JavaSymbolProvider(
session = this@JavaSymbolProvider.session session = this@JavaSymbolProvider.session
returnTypeRef = firJavaMethod.returnTypeRef returnTypeRef = firJavaMethod.returnTypeRef
name = methodName name = methodName
if (javaMethod.hasAnnotationParameterDefaultValue) { javaMethod.annotationParameterDefaultValue?.let { javaDefaultValue ->
defaultValue = buildExpressionStub() defaultValue = javaDefaultValue.toFirExpression(session, javaTypeParameterStack, returnTypeRef)
} }
isVararg = returnType is JavaArrayType && methodName == VALUE_METHOD_NAME isVararg = returnType is JavaArrayType && methodName == VALUE_METHOD_NAME
annotationBuilder = { emptyList() } annotationBuilder = { emptyList() }
@@ -35,6 +35,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef
import org.jetbrains.kotlin.fir.types.builder.buildImplicitTypeRef
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
@@ -519,7 +520,7 @@ private fun buildArgumentMapping(
val mapping = annotationArguments.associateTo(linkedMapOf()) { argument -> val mapping = annotationArguments.associateTo(linkedMapOf()) { argument ->
val parameter = annotationConstructor.valueParameters.find { it.name == (argument.name ?: JavaSymbolProvider.VALUE_METHOD_NAME) } val parameter = annotationConstructor.valueParameters.find { it.name == (argument.name ?: JavaSymbolProvider.VALUE_METHOD_NAME) }
?: return null ?: return null
argument.toFirExpression(session, javaTypeParameterStack) to parameter argument.toFirExpression(session, javaTypeParameterStack, parameter.returnTypeRef) to parameter
} }
return buildResolvedArgumentList(mapping) return buildResolvedArgumentList(mapping)
} }
@@ -555,7 +556,12 @@ internal fun JavaAnnotation.toFirAnnotationCall(
null -> null null -> null
else -> buildArgumentMapping(session, javaTypeParameterStack, lookupTag!!, arguments) else -> buildArgumentMapping(session, javaTypeParameterStack, lookupTag!!, arguments)
} ?: buildArgumentList { } ?: buildArgumentList {
this@toFirAnnotationCall.arguments.mapTo(arguments) { it.toFirExpression(session, javaTypeParameterStack) } this@toFirAnnotationCall.arguments.mapTo(arguments) {
val expectedArgumentType = buildErrorTypeRef {
diagnostic = ConeSimpleDiagnostic("java annotation argument without expected type")
}
it.toFirExpression(session, javaTypeParameterStack, expectedArgumentType)
}
} }
calleeReference = FirReferencePlaceholderForResolvedAnnotations calleeReference = FirReferencePlaceholderForResolvedAnnotations
} }
@@ -624,14 +630,19 @@ private fun JavaType?.toConeProjectionWithoutEnhancement(
} }
} }
private fun JavaAnnotationArgument.toFirExpression( internal fun JavaAnnotationArgument.toFirExpression(
session: FirSession, javaTypeParameterStack: JavaTypeParameterStack session: FirSession, javaTypeParameterStack: JavaTypeParameterStack, expectedTypeRef: FirTypeRef
): FirExpression { ): FirExpression {
return when (this) { return when (this) {
is JavaLiteralAnnotationArgument -> value.createConstantOrError(session) is JavaLiteralAnnotationArgument -> value.createConstantOrError(session)
is JavaArrayAnnotationArgument -> buildArrayOfCall { is JavaArrayAnnotationArgument -> buildArrayOfCall {
typeRef = expectedTypeRef
val argumentTypeRef = buildResolvedTypeRef {
type = expectedTypeRef.coneTypeSafe<ConeKotlinType>()?.lowerBoundIfFlexible()?.arrayElementType()
?: ConeClassErrorType(ConeSimpleDiagnostic("expected type is not array type"))
}
argumentList = buildArgumentList { argumentList = buildArgumentList {
getElements().mapTo(arguments) { it.toFirExpression(session, javaTypeParameterStack) } getElements().mapTo(arguments) { it.toFirExpression(session, javaTypeParameterStack, argumentTypeRef) }
} }
} }
is JavaEnumValueAnnotationArgument -> buildEnumCall(session, enumClassId, entryName) is JavaEnumValueAnnotationArgument -> buildEnumCall(session, enumClassId, entryName)
@@ -203,6 +203,8 @@ class FirSignatureEnhancement(
} }
val newValueParameters = firMethod.valueParameters.zip(enhancedValueParameterTypes) { valueParameter, enhancedReturnType -> val newValueParameters = firMethod.valueParameters.zip(enhancedValueParameterTypes) { valueParameter, enhancedReturnType ->
valueParameter.defaultValue?.replaceTypeRef(enhancedReturnType)
buildValueParameter { buildValueParameter {
source = valueParameter.source source = valueParameter.source
session = this@FirSignatureEnhancement.session session = this@FirSignatureEnhancement.session