[FIR] Introduce special phase for resolve of enums and class literals
This commit is contained in:
committed by
TeamCityServer
parent
afb85026c4
commit
71def0666e
+5
@@ -29,6 +29,11 @@ public class LazyBodyIsNotTouchedTilContractsPhaseTestGenerated extends Abstract
|
|||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("annotationOnDeclarationWithDifferentArguments.kt")
|
||||||
|
public void testAnnotationOnDeclarationWithDifferentArguments() throws Exception {
|
||||||
|
runTest("compiler/fir/analysis-tests/testData/resolve/annotationOnDeclarationWithDifferentArguments.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("annotationUsedAsAnnotationArgument.kt")
|
@TestMetadata("annotationUsedAsAnnotationArgument.kt")
|
||||||
public void testAnnotationUsedAsAnnotationArgument() throws Exception {
|
public void testAnnotationUsedAsAnnotationArgument() throws Exception {
|
||||||
runTest("compiler/fir/analysis-tests/testData/resolve/annotationUsedAsAnnotationArgument.kt");
|
runTest("compiler/fir/analysis-tests/testData/resolve/annotationUsedAsAnnotationArgument.kt");
|
||||||
|
|||||||
Vendored
+54
@@ -0,0 +1,54 @@
|
|||||||
|
FILE: annotationOnDeclarationWithDifferentArguments.kt
|
||||||
|
public final enum class SomeEnum : R|kotlin/Enum<SomeEnum>| {
|
||||||
|
private constructor(): R|SomeEnum| {
|
||||||
|
super<R|kotlin/Enum<SomeEnum>|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
public final static enum entry A: R|SomeEnum|
|
||||||
|
public final static enum entry B: R|SomeEnum|
|
||||||
|
public final static fun values(): R|kotlin/Array<SomeEnum>| {
|
||||||
|
}
|
||||||
|
|
||||||
|
public final static fun valueOf(value: R|kotlin/String|): R|SomeEnum| {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public final annotation class MyAnnotation : R|kotlin/Annotation| {
|
||||||
|
public constructor(intValue: R|kotlin/Int|, stringValue: R|kotlin/String|, enumValue: R|SomeEnum|, kClasses: R|kotlin/Array<out kotlin/reflect/KClass<*>>|, annotation: R|MyOtherAnnotation|): R|MyAnnotation| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
public final val intValue: R|kotlin/Int| = R|<local>/intValue|
|
||||||
|
public get(): R|kotlin/Int|
|
||||||
|
|
||||||
|
public final val stringValue: R|kotlin/String| = R|<local>/stringValue|
|
||||||
|
public get(): R|kotlin/String|
|
||||||
|
|
||||||
|
public final val enumValue: R|SomeEnum| = R|<local>/enumValue|
|
||||||
|
public get(): R|SomeEnum|
|
||||||
|
|
||||||
|
public final val kClasses: R|kotlin/Array<out kotlin/reflect/KClass<*>>| = R|<local>/kClasses|
|
||||||
|
public get(): R|kotlin/Array<out kotlin/reflect/KClass<*>>|
|
||||||
|
|
||||||
|
public final val annotation: R|MyOtherAnnotation| = R|<local>/annotation|
|
||||||
|
public get(): R|MyOtherAnnotation|
|
||||||
|
|
||||||
|
}
|
||||||
|
public final annotation class MyOtherAnnotation : R|kotlin/Annotation| {
|
||||||
|
public constructor(intValue: R|kotlin/Int|, stringValue: R|kotlin/String|): R|MyOtherAnnotation| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
public final val intValue: R|kotlin/Int| = R|<local>/intValue|
|
||||||
|
public get(): R|kotlin/Int|
|
||||||
|
|
||||||
|
public final val stringValue: R|kotlin/String| = R|<local>/stringValue|
|
||||||
|
public get(): R|kotlin/String|
|
||||||
|
|
||||||
|
}
|
||||||
|
public final const val constInt: R|kotlin/Int| = Int(10)
|
||||||
|
public get(): R|kotlin/Int|
|
||||||
|
public final const val constString: R|kotlin/String| = String()
|
||||||
|
public get(): R|kotlin/String|
|
||||||
|
@R|MyAnnotation|(intValue = Int(10), stringValue = R|/constString|, enumValue = Q|SomeEnum|.R|/SomeEnum.A|, kClasses = <implicitArrayOf>(<getClass>(Q|kotlin/String|), <getClass>(R|/constString|)), annotation = R|/MyOtherAnnotation.MyOtherAnnotation|(intValue = R|/constInt|, stringValue = String(hello))) public final fun foo(): R|kotlin/Unit| {
|
||||||
|
}
|
||||||
Vendored
+30
@@ -0,0 +1,30 @@
|
|||||||
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
|
enum class SomeEnum {
|
||||||
|
A, B
|
||||||
|
}
|
||||||
|
|
||||||
|
annotation class MyAnnotation(
|
||||||
|
val intValue: Int,
|
||||||
|
val stringValue: String,
|
||||||
|
val enumValue: SomeEnum,
|
||||||
|
val kClasses: Array<out KClass<*>>,
|
||||||
|
val annotation: MyOtherAnnotation
|
||||||
|
)
|
||||||
|
annotation class MyOtherAnnotation(val intValue: Int, val stringValue: String)
|
||||||
|
|
||||||
|
const val constInt = 10
|
||||||
|
const val constString = ""
|
||||||
|
|
||||||
|
@MyAnnotation(
|
||||||
|
intValue = 10,
|
||||||
|
stringValue = constString,
|
||||||
|
enumValue = SomeEnum.A,
|
||||||
|
kClasses = [String::class, <!ANNOTATION_ARGUMENT_MUST_BE_KCLASS_LITERAL!>constString::class<!>],
|
||||||
|
|
||||||
|
annotation = MyOtherAnnotation(
|
||||||
|
intValue = constInt,
|
||||||
|
stringValue = "hello"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
fun foo() {}
|
||||||
+6
@@ -26,6 +26,12 @@ public class FirDiagnosticTestGenerated extends AbstractFirDiagnosticTest {
|
|||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("annotationOnDeclarationWithDifferentArguments.kt")
|
||||||
|
public void testAnnotationOnDeclarationWithDifferentArguments() throws Exception {
|
||||||
|
runTest("compiler/fir/analysis-tests/testData/resolve/annotationOnDeclarationWithDifferentArguments.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("annotationUsedAsAnnotationArgument.kt")
|
@TestMetadata("annotationUsedAsAnnotationArgument.kt")
|
||||||
public void testAnnotationUsedAsAnnotationArgument() throws Exception {
|
public void testAnnotationUsedAsAnnotationArgument() throws Exception {
|
||||||
|
|||||||
+6
@@ -26,6 +26,12 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
|
|||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("annotationOnDeclarationWithDifferentArguments.kt")
|
||||||
|
public void testAnnotationOnDeclarationWithDifferentArguments() throws Exception {
|
||||||
|
runTest("compiler/fir/analysis-tests/testData/resolve/annotationOnDeclarationWithDifferentArguments.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("annotationUsedAsAnnotationArgument.kt")
|
@TestMetadata("annotationUsedAsAnnotationArgument.kt")
|
||||||
public void testAnnotationUsedAsAnnotationArgument() throws Exception {
|
public void testAnnotationUsedAsAnnotationArgument() throws Exception {
|
||||||
|
|||||||
@@ -200,6 +200,20 @@ class FirCallResolver(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun <T : FirQualifiedAccess> resolveVariableAccessAndSelectCandidate(qualifiedAccess: T): FirStatement {
|
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
|
val callee = qualifiedAccess.calleeReference as? FirSimpleNamedReference ?: return qualifiedAccess
|
||||||
|
|
||||||
qualifiedResolver.initProcessingQualifiedAccess(callee, qualifiedAccess.typeArguments)
|
qualifiedResolver.initProcessingQualifiedAccess(callee, qualifiedAccess.typeArguments)
|
||||||
@@ -233,6 +247,8 @@ class FirCallResolver(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val reducedCandidates = result.candidates
|
val reducedCandidates = result.candidates
|
||||||
|
if (!acceptCandidates(reducedCandidates)) return qualifiedAccess
|
||||||
|
|
||||||
val nameReference = createResolvedNamedReference(
|
val nameReference = createResolvedNamedReference(
|
||||||
callee,
|
callee,
|
||||||
callee.name,
|
callee.name,
|
||||||
|
|||||||
+1
-1
@@ -28,7 +28,7 @@ fun FirResolvePhase.createCompilerProcessorByPhase(
|
|||||||
SUPER_TYPES -> FirSupertypeResolverProcessor(session, scopeSession)
|
SUPER_TYPES -> FirSupertypeResolverProcessor(session, scopeSession)
|
||||||
SEALED_CLASS_INHERITORS -> FirSealedClassInheritorsProcessor(session, scopeSession)
|
SEALED_CLASS_INHERITORS -> FirSealedClassInheritorsProcessor(session, scopeSession)
|
||||||
TYPES -> FirTypeResolveProcessor(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)
|
EXTENSION_STATUS_UPDATE -> FirGlobalExtensionStatusProcessor(session, scopeSession)
|
||||||
STATUS -> FirStatusResolveProcessor(session, scopeSession)
|
STATUS -> FirStatusResolveProcessor(session, scopeSession)
|
||||||
CONTRACTS -> FirContractResolveProcessor(session, scopeSession)
|
CONTRACTS -> FirContractResolveProcessor(session, scopeSession)
|
||||||
|
|||||||
+10
-1
@@ -121,7 +121,7 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
|
|||||||
qualifiedAccessExpression
|
qualifiedAccessExpression
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
val transformedCallee = callResolver.resolveVariableAccessAndSelectCandidate(qualifiedAccessExpression)
|
val transformedCallee = resolveQualifiedAccessAndSelectCandidate(qualifiedAccessExpression)
|
||||||
// NB: here we can get raw expression because of dropped qualifiers (see transform callee),
|
// NB: here we can get raw expression because of dropped qualifiers (see transform callee),
|
||||||
// so candidate existence must be checked before calling completion
|
// so candidate existence must be checked before calling completion
|
||||||
if (transformedCallee is FirQualifiedAccessExpression && transformedCallee.candidate() != null) {
|
if (transformedCallee is FirQualifiedAccessExpression && transformedCallee.candidate() != null) {
|
||||||
@@ -147,6 +147,10 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected open fun resolveQualifiedAccessAndSelectCandidate(qualifiedAccessExpression: FirQualifiedAccessExpression): FirStatement {
|
||||||
|
return callResolver.resolveVariableAccessAndSelectCandidate(qualifiedAccessExpression)
|
||||||
|
}
|
||||||
|
|
||||||
fun transformSuperReceiver(
|
fun transformSuperReceiver(
|
||||||
superReference: FirSuperReference,
|
superReference: FirSuperReference,
|
||||||
superReferenceContainer: FirQualifiedAccessExpression,
|
superReferenceContainer: FirQualifiedAccessExpression,
|
||||||
@@ -833,6 +837,7 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
|
|||||||
symbol.constructType(emptyArray(), isNullable = false)
|
symbol.constructType(emptyArray(), isNullable = false)
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
|
if (!shouldComputeTypeOfGetClassCallWithNotQualifierInLhs(getClassCall)) return transformedGetClassCall
|
||||||
val resultType = lhs.resultType
|
val resultType = lhs.resultType
|
||||||
if (resultType is FirErrorTypeRef) {
|
if (resultType is FirErrorTypeRef) {
|
||||||
resultType.coneType
|
resultType.coneType
|
||||||
@@ -850,6 +855,10 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
|
|||||||
return transformedGetClassCall
|
return transformedGetClassCall
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected open fun shouldComputeTypeOfGetClassCallWithNotQualifierInLhs(getClassCall: FirGetClassCall): Boolean {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
override fun <T> transformConstExpression(
|
override fun <T> transformConstExpression(
|
||||||
constExpression: FirConstExpression<T>,
|
constExpression: FirConstExpression<T>,
|
||||||
data: ResolutionMode,
|
data: ResolutionMode,
|
||||||
|
|||||||
-5
@@ -8,8 +8,6 @@ package org.jetbrains.kotlin.fir.resolve.transformers.plugin
|
|||||||
import org.jetbrains.kotlin.fir.FirElement
|
import org.jetbrains.kotlin.fir.FirElement
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
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.ResolutionMode
|
||||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.AdapterForResolveProcessor
|
import org.jetbrains.kotlin.fir.resolve.transformers.AdapterForResolveProcessor
|
||||||
@@ -27,15 +25,12 @@ class FirAnnotationArgumentsResolveProcessor(
|
|||||||
@AdapterForResolveProcessor
|
@AdapterForResolveProcessor
|
||||||
class FirAnnotationArgumentsResolveTransformerAdapter(session: FirSession, scopeSession: ScopeSession) : FirTransformer<Any?>() {
|
class FirAnnotationArgumentsResolveTransformerAdapter(session: FirSession, scopeSession: ScopeSession) : FirTransformer<Any?>() {
|
||||||
private val transformer = FirAnnotationArgumentsResolveTransformer(session, scopeSession)
|
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 {
|
override fun <E : FirElement> transformElement(element: E, data: Any?): E {
|
||||||
return element
|
return element
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun transformFile(file: FirFile, data: Any?): FirFile {
|
override fun transformFile(file: FirFile, data: Any?): FirFile {
|
||||||
if (!hasAnnotations || !predicateBasedProvider.fileHasPluginAnnotations(file)) return file
|
|
||||||
return file.transform(transformer, ResolutionMode.ContextIndependent)
|
return file.transform(transformer, ResolutionMode.ContextIndependent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+83
-42
@@ -8,8 +8,6 @@ package org.jetbrains.kotlin.fir.resolve.transformers.plugin
|
|||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.*
|
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.references.FirErrorNamedReference
|
||||||
import org.jetbrains.kotlin.fir.resolve.ResolutionMode
|
import org.jetbrains.kotlin.fir.resolve.ResolutionMode
|
||||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
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.FirBodyResolveTransformer
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirDeclarationsResolveTransformer
|
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.resolve.transformers.body.resolve.FirExpressionsResolveTransformer
|
||||||
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
|
||||||
import org.jetbrains.kotlin.fir.types.coneTypeSafe
|
|
||||||
|
|
||||||
class FirAnnotationArgumentsResolveTransformer(
|
class FirAnnotationArgumentsResolveTransformer(
|
||||||
session: FirSession,
|
session: FirSession,
|
||||||
@@ -26,15 +22,12 @@ class FirAnnotationArgumentsResolveTransformer(
|
|||||||
outerBodyResolveContext: BodyResolveContext? = null
|
outerBodyResolveContext: BodyResolveContext? = null
|
||||||
) : FirBodyResolveTransformer(
|
) : FirBodyResolveTransformer(
|
||||||
session,
|
session,
|
||||||
FirResolvePhase.ARGUMENTS_OF_PLUGIN_ANNOTATIONS,
|
FirResolvePhase.ARGUMENTS_OF_ANNOTATIONS,
|
||||||
implicitTypeOnly = false,
|
implicitTypeOnly = false,
|
||||||
scopeSession,
|
scopeSession,
|
||||||
outerBodyResolveContext = outerBodyResolveContext
|
outerBodyResolveContext = outerBodyResolveContext
|
||||||
) {
|
) {
|
||||||
override val expressionsTransformer: FirExpressionsResolveTransformer = FirExpressionsResolveTransformerForSpecificAnnotations(
|
override val expressionsTransformer: FirExpressionsResolveTransformer = FirExpressionsResolveTransformerForSpecificAnnotations(this)
|
||||||
this,
|
|
||||||
session.registeredPluginAnnotations.annotations
|
|
||||||
)
|
|
||||||
|
|
||||||
override val declarationsTransformer: FirDeclarationsResolveTransformer = FirDeclarationsResolveTransformerForArgumentAnnotations(this)
|
override val declarationsTransformer: FirDeclarationsResolveTransformer = FirDeclarationsResolveTransformerForArgumentAnnotations(this)
|
||||||
}
|
}
|
||||||
@@ -42,15 +35,16 @@ class FirAnnotationArgumentsResolveTransformer(
|
|||||||
private class FirDeclarationsResolveTransformerForArgumentAnnotations(
|
private class FirDeclarationsResolveTransformerForArgumentAnnotations(
|
||||||
transformer: FirBodyResolveTransformer
|
transformer: FirBodyResolveTransformer
|
||||||
) : FirDeclarationsResolveTransformer(transformer) {
|
) : FirDeclarationsResolveTransformer(transformer) {
|
||||||
override fun transformWrappedDelegateExpression(
|
|
||||||
wrappedDelegateExpression: FirWrappedDelegateExpression,
|
|
||||||
data: ResolutionMode
|
|
||||||
): FirStatement {
|
|
||||||
return wrappedDelegateExpression
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun transformRegularClass(regularClass: FirRegularClass, data: ResolutionMode): FirStatement {
|
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(
|
override fun transformAnonymousInitializer(
|
||||||
@@ -64,21 +58,38 @@ private class FirDeclarationsResolveTransformerForArgumentAnnotations(
|
|||||||
simpleFunction: FirSimpleFunction,
|
simpleFunction: FirSimpleFunction,
|
||||||
data: ResolutionMode
|
data: ResolutionMode
|
||||||
): FirSimpleFunction {
|
): 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 {
|
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 {
|
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 {
|
override fun transformProperty(property: FirProperty, data: ResolutionMode): FirProperty {
|
||||||
property.transformAnnotations(this, data)
|
property
|
||||||
property.transformGetter(this, data)
|
.transformAnnotations(transformer, data)
|
||||||
property.transformSetter(this, data)
|
.transformReceiverTypeRef(transformer, data)
|
||||||
|
.transformReturnTypeRef(transformer, data)
|
||||||
|
.transformGetter(transformer, data)
|
||||||
|
.transformSetter(transformer, data)
|
||||||
|
.transformTypeParameters(transformer, data)
|
||||||
return property
|
return property
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,42 +97,63 @@ private class FirDeclarationsResolveTransformerForArgumentAnnotations(
|
|||||||
propertyAccessor: FirPropertyAccessor,
|
propertyAccessor: FirPropertyAccessor,
|
||||||
data: ResolutionMode
|
data: ResolutionMode
|
||||||
): FirPropertyAccessor {
|
): FirPropertyAccessor {
|
||||||
propertyAccessor.transformAnnotations(this, data)
|
propertyAccessor
|
||||||
|
.transformValueParameters(transformer, data)
|
||||||
|
.transformReturnTypeRef(transformer, data)
|
||||||
|
.transformReceiverTypeRef(transformer, data)
|
||||||
|
.transformReturnTypeRef(transformer, data)
|
||||||
|
.transformAnnotations(transformer, data)
|
||||||
return propertyAccessor
|
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(
|
private class FirExpressionsResolveTransformerForSpecificAnnotations(
|
||||||
transformer: FirBodyResolveTransformer,
|
transformer: FirBodyResolveTransformer
|
||||||
private val annotations: Set<AnnotationFqn>
|
|
||||||
) : FirExpressionsResolveTransformer(transformer) {
|
) : FirExpressionsResolveTransformer(transformer) {
|
||||||
private var annotationArgumentsMode: Boolean = false
|
|
||||||
|
|
||||||
override fun transformAnnotationCall(annotationCall: FirAnnotationCall, data: ResolutionMode): FirStatement {
|
override fun transformAnnotationCall(annotationCall: FirAnnotationCall, data: ResolutionMode): FirStatement {
|
||||||
if (annotationArgumentsMode) {
|
dataFlowAnalyzer.enterAnnotationCall(annotationCall)
|
||||||
return resolveAnnotationCall(annotationCall, FirAnnotationResolveStatus.PartiallyResolved)
|
annotationCall.transformChildren(transformer, ResolutionMode.ContextDependent)
|
||||||
}
|
dataFlowAnalyzer.exitAnnotationCall(annotationCall)
|
||||||
|
return annotationCall
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun transformExpression(expression: FirExpression, data: ResolutionMode): FirStatement {
|
override fun transformExpression(expression: FirExpression, data: ResolutionMode): FirStatement {
|
||||||
return expression
|
return expression.transformChildren(transformer, data) as FirStatement
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun FirQualifiedAccessExpression.isAcceptableResolvedQualifiedAccess(): Boolean {
|
override fun FirQualifiedAccessExpression.isAcceptableResolvedQualifiedAccess(): Boolean {
|
||||||
return calleeReference !is FirErrorNamedReference
|
return calleeReference !is FirErrorNamedReference
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun resolveQualifiedAccessAndSelectCandidate(qualifiedAccessExpression: FirQualifiedAccessExpression): FirStatement {
|
||||||
|
return callResolver.resolveOnlyEnumOrQualifierAccessAndSelectCandidate(qualifiedAccessExpression)
|
||||||
|
}
|
||||||
|
|
||||||
override fun transformFunctionCall(functionCall: FirFunctionCall, data: ResolutionMode): FirStatement {
|
override fun transformFunctionCall(functionCall: FirFunctionCall, data: ResolutionMode): FirStatement {
|
||||||
return functionCall
|
return functionCall
|
||||||
}
|
}
|
||||||
@@ -192,4 +224,13 @@ private class FirExpressionsResolveTransformerForSpecificAnnotations(
|
|||||||
): FirStatement {
|
): FirStatement {
|
||||||
return augmentedArraySetCall
|
return augmentedArraySetCall
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun transformArrayOfCall(arrayOfCall: FirArrayOfCall, data: ResolutionMode): FirStatement {
|
||||||
|
arrayOfCall.transformChildren(transformer, data)
|
||||||
|
return arrayOfCall
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun shouldComputeTypeOfGetClassCallWithNotQualifierInLhs(getClassCall: FirGetClassCall): Boolean {
|
||||||
|
return false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ enum class FirResolvePhase(val pluginPhase: Boolean = false, val noProcessor: Bo
|
|||||||
SUPER_TYPES,
|
SUPER_TYPES,
|
||||||
SEALED_CLASS_INHERITORS,
|
SEALED_CLASS_INHERITORS,
|
||||||
TYPES,
|
TYPES,
|
||||||
ARGUMENTS_OF_PLUGIN_ANNOTATIONS(pluginPhase = true),
|
ARGUMENTS_OF_ANNOTATIONS,
|
||||||
EXTENSION_STATUS_UPDATE(pluginPhase = true),
|
EXTENSION_STATUS_UPDATE(pluginPhase = true),
|
||||||
STATUS,
|
STATUS,
|
||||||
CONTRACTS,
|
CONTRACTS,
|
||||||
|
|||||||
+6
@@ -26,6 +26,12 @@ public class DiagnosisCompilerFirTestdataTestGenerated extends AbstractDiagnosis
|
|||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("annotationOnDeclarationWithDifferentArguments.kt")
|
||||||
|
public void testAnnotationOnDeclarationWithDifferentArguments() throws Exception {
|
||||||
|
runTest("compiler/fir/analysis-tests/testData/resolve/annotationOnDeclarationWithDifferentArguments.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("annotationUsedAsAnnotationArgument.kt")
|
@TestMetadata("annotationUsedAsAnnotationArgument.kt")
|
||||||
public void testAnnotationUsedAsAnnotationArgument() throws Exception {
|
public void testAnnotationUsedAsAnnotationArgument() throws Exception {
|
||||||
|
|||||||
Reference in New Issue
Block a user