[FIR] Introduce special phase for resolve of enums and class literals

This commit is contained in:
Dmitriy Novozhilov
2021-07-28 15:17:17 +03:00
committed by TeamCityServer
parent afb85026c4
commit 71def0666e
12 changed files with 218 additions and 50 deletions
@@ -200,6 +200,20 @@ class FirCallResolver(
}
fun <T : FirQualifiedAccess> resolveVariableAccessAndSelectCandidate(qualifiedAccess: T): FirStatement {
return resolveVariableAccessAndSelectCandidateImpl(qualifiedAccess) { true }
}
fun resolveOnlyEnumOrQualifierAccessAndSelectCandidate(qualifiedAccess: FirQualifiedAccessExpression): FirStatement {
return resolveVariableAccessAndSelectCandidateImpl(qualifiedAccess) accept@{ candidates ->
val symbol = candidates.singleOrNull()?.symbol ?: return@accept false
symbol is FirEnumEntrySymbol || symbol is FirRegularClassSymbol
}
}
private fun <T : FirQualifiedAccess> resolveVariableAccessAndSelectCandidateImpl(
qualifiedAccess: T,
acceptCandidates: (Collection<Candidate>) -> Boolean
): FirStatement {
val callee = qualifiedAccess.calleeReference as? FirSimpleNamedReference ?: return qualifiedAccess
qualifiedResolver.initProcessingQualifiedAccess(callee, qualifiedAccess.typeArguments)
@@ -233,6 +247,8 @@ class FirCallResolver(
}
val reducedCandidates = result.candidates
if (!acceptCandidates(reducedCandidates)) return qualifiedAccess
val nameReference = createResolvedNamedReference(
callee,
callee.name,
@@ -28,7 +28,7 @@ fun FirResolvePhase.createCompilerProcessorByPhase(
SUPER_TYPES -> FirSupertypeResolverProcessor(session, scopeSession)
SEALED_CLASS_INHERITORS -> FirSealedClassInheritorsProcessor(session, scopeSession)
TYPES -> FirTypeResolveProcessor(session, scopeSession)
ARGUMENTS_OF_PLUGIN_ANNOTATIONS -> FirAnnotationArgumentsResolveProcessor(session, scopeSession)
ARGUMENTS_OF_ANNOTATIONS -> FirAnnotationArgumentsResolveProcessor(session, scopeSession)
EXTENSION_STATUS_UPDATE -> FirGlobalExtensionStatusProcessor(session, scopeSession)
STATUS -> FirStatusResolveProcessor(session, scopeSession)
CONTRACTS -> FirContractResolveProcessor(session, scopeSession)
@@ -121,7 +121,7 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
qualifiedAccessExpression
}
else -> {
val transformedCallee = callResolver.resolveVariableAccessAndSelectCandidate(qualifiedAccessExpression)
val transformedCallee = resolveQualifiedAccessAndSelectCandidate(qualifiedAccessExpression)
// NB: here we can get raw expression because of dropped qualifiers (see transform callee),
// so candidate existence must be checked before calling completion
if (transformedCallee is FirQualifiedAccessExpression && transformedCallee.candidate() != null) {
@@ -147,6 +147,10 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
return result
}
protected open fun resolveQualifiedAccessAndSelectCandidate(qualifiedAccessExpression: FirQualifiedAccessExpression): FirStatement {
return callResolver.resolveVariableAccessAndSelectCandidate(qualifiedAccessExpression)
}
fun transformSuperReceiver(
superReference: FirSuperReference,
superReferenceContainer: FirQualifiedAccessExpression,
@@ -833,6 +837,7 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
symbol.constructType(emptyArray(), isNullable = false)
}
else -> {
if (!shouldComputeTypeOfGetClassCallWithNotQualifierInLhs(getClassCall)) return transformedGetClassCall
val resultType = lhs.resultType
if (resultType is FirErrorTypeRef) {
resultType.coneType
@@ -850,6 +855,10 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
return transformedGetClassCall
}
protected open fun shouldComputeTypeOfGetClassCallWithNotQualifierInLhs(getClassCall: FirGetClassCall): Boolean {
return true
}
override fun <T> transformConstExpression(
constExpression: FirConstExpression<T>,
data: ResolutionMode,
@@ -8,8 +8,6 @@ package org.jetbrains.kotlin.fir.resolve.transformers.plugin
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.extensions.predicateBasedProvider
import org.jetbrains.kotlin.fir.extensions.registeredPluginAnnotations
import org.jetbrains.kotlin.fir.resolve.ResolutionMode
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.transformers.AdapterForResolveProcessor
@@ -27,15 +25,12 @@ class FirAnnotationArgumentsResolveProcessor(
@AdapterForResolveProcessor
class FirAnnotationArgumentsResolveTransformerAdapter(session: FirSession, scopeSession: ScopeSession) : FirTransformer<Any?>() {
private val transformer = FirAnnotationArgumentsResolveTransformer(session, scopeSession)
private val hasAnnotations = session.registeredPluginAnnotations.annotations.isNotEmpty()
private val predicateBasedProvider = session.predicateBasedProvider
override fun <E : FirElement> transformElement(element: E, data: Any?): E {
return element
}
override fun transformFile(file: FirFile, data: Any?): FirFile {
if (!hasAnnotations || !predicateBasedProvider.fileHasPluginAnnotations(file)) return file
return file.transform(transformer, ResolutionMode.ContextIndependent)
}
}
@@ -8,8 +8,6 @@ package org.jetbrains.kotlin.fir.resolve.transformers.plugin
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.extensions.AnnotationFqn
import org.jetbrains.kotlin.fir.extensions.registeredPluginAnnotations
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
import org.jetbrains.kotlin.fir.resolve.ResolutionMode
import org.jetbrains.kotlin.fir.resolve.ScopeSession
@@ -17,8 +15,6 @@ import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.BodyResolveCon
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirBodyResolveTransformer
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirDeclarationsResolveTransformer
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirExpressionsResolveTransformer
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
import org.jetbrains.kotlin.fir.types.coneTypeSafe
class FirAnnotationArgumentsResolveTransformer(
session: FirSession,
@@ -26,15 +22,12 @@ class FirAnnotationArgumentsResolveTransformer(
outerBodyResolveContext: BodyResolveContext? = null
) : FirBodyResolveTransformer(
session,
FirResolvePhase.ARGUMENTS_OF_PLUGIN_ANNOTATIONS,
FirResolvePhase.ARGUMENTS_OF_ANNOTATIONS,
implicitTypeOnly = false,
scopeSession,
outerBodyResolveContext = outerBodyResolveContext
) {
override val expressionsTransformer: FirExpressionsResolveTransformer = FirExpressionsResolveTransformerForSpecificAnnotations(
this,
session.registeredPluginAnnotations.annotations
)
override val expressionsTransformer: FirExpressionsResolveTransformer = FirExpressionsResolveTransformerForSpecificAnnotations(this)
override val declarationsTransformer: FirDeclarationsResolveTransformer = FirDeclarationsResolveTransformerForArgumentAnnotations(this)
}
@@ -42,15 +35,16 @@ class FirAnnotationArgumentsResolveTransformer(
private class FirDeclarationsResolveTransformerForArgumentAnnotations(
transformer: FirBodyResolveTransformer
) : FirDeclarationsResolveTransformer(transformer) {
override fun transformWrappedDelegateExpression(
wrappedDelegateExpression: FirWrappedDelegateExpression,
data: ResolutionMode
): FirStatement {
return wrappedDelegateExpression
}
override fun transformRegularClass(regularClass: FirRegularClass, data: ResolutionMode): FirStatement {
return regularClass.transformAnnotations(this, data).transformDeclarations(this, data)
regularClass.transformAnnotations(this, data)
context.withContainingClass(regularClass) {
regularClass
.transformTypeParameters(transformer, data)
.transformSuperTypeRefs(transformer, data)
.transformDeclarations(transformer, data)
.transformCompanionObject(transformer, data)
}
return regularClass
}
override fun transformAnonymousInitializer(
@@ -64,21 +58,38 @@ private class FirDeclarationsResolveTransformerForArgumentAnnotations(
simpleFunction: FirSimpleFunction,
data: ResolutionMode
): FirSimpleFunction {
return simpleFunction.transformAnnotations(this, data)
simpleFunction
.transformReturnTypeRef(transformer, data)
.transformReceiverTypeRef(transformer, data)
.transformValueParameters(transformer, data)
.transformAnnotations(transformer, data)
return simpleFunction
}
override fun transformConstructor(constructor: FirConstructor, data: ResolutionMode): FirConstructor {
return constructor.transformAnnotations(this, data)
constructor
.transformReturnTypeRef(transformer, data)
.transformReceiverTypeRef(transformer, data)
.transformValueParameters(transformer, data)
.transformAnnotations(transformer, data)
return constructor
}
override fun transformValueParameter(valueParameter: FirValueParameter, data: ResolutionMode): FirStatement {
return valueParameter.transformAnnotations(this, data)
valueParameter
.transformAnnotations(transformer, data)
.transformReturnTypeRef(transformer, data)
return valueParameter
}
override fun transformProperty(property: FirProperty, data: ResolutionMode): FirProperty {
property.transformAnnotations(this, data)
property.transformGetter(this, data)
property.transformSetter(this, data)
property
.transformAnnotations(transformer, data)
.transformReceiverTypeRef(transformer, data)
.transformReturnTypeRef(transformer, data)
.transformGetter(transformer, data)
.transformSetter(transformer, data)
.transformTypeParameters(transformer, data)
return property
}
@@ -86,42 +97,63 @@ private class FirDeclarationsResolveTransformerForArgumentAnnotations(
propertyAccessor: FirPropertyAccessor,
data: ResolutionMode
): FirPropertyAccessor {
propertyAccessor.transformAnnotations(this, data)
propertyAccessor
.transformValueParameters(transformer, data)
.transformReturnTypeRef(transformer, data)
.transformReceiverTypeRef(transformer, data)
.transformReturnTypeRef(transformer, data)
.transformAnnotations(transformer, data)
return propertyAccessor
}
override fun transformDeclarationStatus(declarationStatus: FirDeclarationStatus, data: ResolutionMode): FirDeclarationStatus {
return declarationStatus
}
override fun transformEnumEntry(enumEntry: FirEnumEntry, data: ResolutionMode): FirEnumEntry {
context.forEnumEntry {
enumEntry
.transformAnnotations(transformer, data)
.transformReceiverTypeRef(transformer, data)
.transformReturnTypeRef(transformer, data)
.transformTypeParameters(transformer, data)
}
return enumEntry
}
override fun transformField(field: FirField, data: ResolutionMode): FirField {
return field.transformAnnotations(transformer, data)
}
override fun transformTypeAlias(typeAlias: FirTypeAlias, data: ResolutionMode): FirTypeAlias {
typeAlias.transformAnnotations(transformer, data)
return typeAlias
}
}
private class FirExpressionsResolveTransformerForSpecificAnnotations(
transformer: FirBodyResolveTransformer,
private val annotations: Set<AnnotationFqn>
transformer: FirBodyResolveTransformer
) : FirExpressionsResolveTransformer(transformer) {
private var annotationArgumentsMode: Boolean = false
override fun transformAnnotationCall(annotationCall: FirAnnotationCall, data: ResolutionMode): FirStatement {
if (annotationArgumentsMode) {
return resolveAnnotationCall(annotationCall, FirAnnotationResolveStatus.PartiallyResolved)
}
annotationCall.transformAnnotationTypeRef(transformer, data)
val classId = annotationCall.annotationTypeRef.coneTypeSafe<ConeClassLikeType>()?.lookupTag?.classId
?: return annotationCall
if (classId.asSingleFqName() !in annotations) {
return annotationCall
}
annotationArgumentsMode = true
return resolveAnnotationCall(annotationCall, FirAnnotationResolveStatus.PartiallyResolved).also {
annotationArgumentsMode = false
}
dataFlowAnalyzer.enterAnnotationCall(annotationCall)
annotationCall.transformChildren(transformer, ResolutionMode.ContextDependent)
dataFlowAnalyzer.exitAnnotationCall(annotationCall)
return annotationCall
}
override fun transformExpression(expression: FirExpression, data: ResolutionMode): FirStatement {
return expression
return expression.transformChildren(transformer, data) as FirStatement
}
override fun FirQualifiedAccessExpression.isAcceptableResolvedQualifiedAccess(): Boolean {
return calleeReference !is FirErrorNamedReference
}
override fun resolveQualifiedAccessAndSelectCandidate(qualifiedAccessExpression: FirQualifiedAccessExpression): FirStatement {
return callResolver.resolveOnlyEnumOrQualifierAccessAndSelectCandidate(qualifiedAccessExpression)
}
override fun transformFunctionCall(functionCall: FirFunctionCall, data: ResolutionMode): FirStatement {
return functionCall
}
@@ -192,4 +224,13 @@ private class FirExpressionsResolveTransformerForSpecificAnnotations(
): FirStatement {
return augmentedArraySetCall
}
override fun transformArrayOfCall(arrayOfCall: FirArrayOfCall, data: ResolutionMode): FirStatement {
arrayOfCall.transformChildren(transformer, data)
return arrayOfCall
}
override fun shouldComputeTypeOfGetClassCallWithNotQualifierInLhs(getClassCall: FirGetClassCall): Boolean {
return false
}
}