From ada47eb1108d2bcf894630718229658ace5e4d19 Mon Sep 17 00:00:00 2001 From: Ivan Kylchik Date: Thu, 29 Feb 2024 13:25:43 +0100 Subject: [PATCH] [K2] Add new resolve phase `CONSTANT_EVALUATION` During this phase, the compiler will evaluate initializers of const properties and defaults of annotation's constructor. Evaluation results will be stored in corresponding attributes. #KT-64151 --- .../LLFirConstantEvaluationLazyResolver.kt | 32 ++++++++++++++++++ .../LLFirLazyPhaseResolverByPhase.kt | 1 + .../fir/transformers/LLFirTargetResolver.kt | 1 + .../FirConstantEvaluationProcessor.kt | 33 +++++++++++++++++++ .../transformers/FirTotalResolveProcessor.kt | 1 + .../fir/declarations/FirResolvePhase.kt | 5 +++ docs/fir/fir-basics.md | 1 + 7 files changed, 74 insertions(+) create mode 100644 analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirConstantEvaluationLazyResolver.kt create mode 100644 compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirConstantEvaluationProcessor.kt diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirConstantEvaluationLazyResolver.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirConstantEvaluationLazyResolver.kt new file mode 100644 index 00000000000..533620d586f --- /dev/null +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirConstantEvaluationLazyResolver.kt @@ -0,0 +1,32 @@ +/* + * Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.analysis.low.level.api.fir.transformers + +import org.jetbrains.kotlin.analysis.low.level.api.fir.api.targets.LLFirResolveTarget +import org.jetbrains.kotlin.fir.FirElementWithResolveState +import org.jetbrains.kotlin.fir.declarations.FirResolvePhase + +internal object LLFirConstantEvaluationLazyResolver : LLFirLazyResolver(FirResolvePhase.CONSTANT_EVALUATION) { + override fun createTargetResolver(target: LLFirResolveTarget): LLFirTargetResolver = LLFirConstantEvaluationTargetResolver(target) + + override fun phaseSpecificCheckIsResolved(target: FirElementWithResolveState) {} +} + +/** + * This resolver is responsible for [CONSTANT_EVALUATION][FirResolvePhase.CONSTANT_EVALUATION] phase. + * + * This resolver doesn't do anything yet (see KT-64151). + * + * @see FirResolvePhase.CONSTANT_EVALUATION + */ +private class LLFirConstantEvaluationTargetResolver(resolveTarget: LLFirResolveTarget) : LLFirTargetResolver( + resolveTarget, + FirResolvePhase.CONSTANT_EVALUATION, +) { + override fun doLazyResolveUnderLock(target: FirElementWithResolveState) { + // Will be finished later on + } +} diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirLazyPhaseResolverByPhase.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirLazyPhaseResolverByPhase.kt index d2c2ca39109..5e741c85936 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirLazyPhaseResolverByPhase.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirLazyPhaseResolverByPhase.kt @@ -22,6 +22,7 @@ internal object LLFirLazyPhaseResolverByPhase { this[FirResolvePhase.EXPECT_ACTUAL_MATCHING] = LLFirExpectActualMatcherLazyResolver this[FirResolvePhase.CONTRACTS] = LLFirContractsLazyResolver this[FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE] = LLFirImplicitTypesLazyResolver + this[FirResolvePhase.CONSTANT_EVALUATION] = LLFirConstantEvaluationLazyResolver this[FirResolvePhase.ANNOTATION_ARGUMENTS] = LLFirAnnotationArgumentsLazyResolver this[FirResolvePhase.BODY_RESOLVE] = LLFirBodyLazyResolver } diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirTargetResolver.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirTargetResolver.kt index ab4da792ac8..383d3e7a1fd 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirTargetResolver.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirTargetResolver.kt @@ -65,6 +65,7 @@ import org.jetbrains.kotlin.utils.exceptions.requireWithAttachment * - [EXPECT_ACTUAL_MATCHING][FirResolvePhase.EXPECT_ACTUAL_MATCHING] – [LLFirExpectActualMatchingTargetResolver] * - [CONTRACTS][FirResolvePhase.CONTRACTS] – [LLFirContractsTargetResolver] * - [IMPLICIT_TYPES_BODY_RESOLVE][FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE] – [LLFirImplicitBodyTargetResolver] + * - [CONSTANT_EVALUATION][FirResolvePhase.CONSTANT_EVALUATION] - [LLFirConstantEvaluationTargetResolver] * - [ANNOTATION_ARGUMENTS][FirResolvePhase.ANNOTATION_ARGUMENTS] – [LLFirAnnotationArgumentsTargetResolver] * - [BODY_RESOLVE][FirResolvePhase.BODY_RESOLVE] – [LLFirBodyTargetResolver] * diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirConstantEvaluationProcessor.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirConstantEvaluationProcessor.kt new file mode 100644 index 00000000000..9b39fca145f --- /dev/null +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirConstantEvaluationProcessor.kt @@ -0,0 +1,33 @@ +/* + * Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.fir.resolve.transformers + +import org.jetbrains.kotlin.fir.FirElement +import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.declarations.FirFile +import org.jetbrains.kotlin.fir.declarations.FirResolvePhase +import org.jetbrains.kotlin.fir.resolve.ScopeSession +import org.jetbrains.kotlin.fir.visitors.FirTransformer + +@OptIn(AdapterForResolveProcessor::class) +class FirConstantEvaluationProcessor( + session: FirSession, + scopeSession: ScopeSession +) : FirTransformerBasedResolveProcessor(session, scopeSession, FirResolvePhase.CONSTANT_EVALUATION) { + override val transformer = FirConstantEvaluationTransformerAdapter(session, scopeSession) +} + +@Suppress("UNUSED_PARAMETER") +@AdapterForResolveProcessor +class FirConstantEvaluationTransformerAdapter(session: FirSession, scopeSession: ScopeSession) : FirTransformer() { + override fun transformElement(element: E, data: Any?): E { + error("Should only be called via transformFile()") + } + + override fun transformFile(file: FirFile, data: Any?): FirFile { + return file + } +} diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTotalResolveProcessor.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTotalResolveProcessor.kt index b54b83d4fb4..dd14b274aaa 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTotalResolveProcessor.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTotalResolveProcessor.kt @@ -85,6 +85,7 @@ fun FirResolvePhase.createCompilerProcessorByPhase( STATUS -> FirStatusResolveProcessor(session, scopeSession) CONTRACTS -> FirContractResolveProcessor(session, scopeSession) IMPLICIT_TYPES_BODY_RESOLVE -> FirImplicitTypeBodyResolveProcessor(session, scopeSession) + CONSTANT_EVALUATION -> FirConstantEvaluationProcessor(session, scopeSession) ANNOTATION_ARGUMENTS -> FirAnnotationArgumentsProcessor(session, scopeSession) BODY_RESOLVE -> FirBodyResolveProcessor(session, scopeSession) EXPECT_ACTUAL_MATCHING -> FirExpectActualMatcherProcessor(session, scopeSession) diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/FirResolvePhase.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/FirResolvePhase.kt index 2d617c808a5..db468059383 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/FirResolvePhase.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/FirResolvePhase.kt @@ -178,6 +178,11 @@ enum class FirResolvePhase(val noProcessor: Boolean = false) { */ IMPLICIT_TYPES_BODY_RESOLVE, + /** + * The compiler evaluates expressions that are used as initializers for const properties and defaults of annotation's constructor. + */ + CONSTANT_EVALUATION, + /** * The compiler resolves arguments of annotations in declaration headers. */ diff --git a/docs/fir/fir-basics.md b/docs/fir/fir-basics.md index fcc551184b1..f4d6ff3f972 100644 --- a/docs/fir/fir-basics.md +++ b/docs/fir/fir-basics.md @@ -24,6 +24,7 @@ List of all FIR phases that exist in the compiler right now with a short descrip - **EXPECT_ACTUAL_MATCHING**: The compiler matches and records an `expect` member declaration for `actual` member declarations. - **CONTRACTS**: The compiler resolves a contract definition in property accessors, functions, and constructors. - **IMPLICIT_TYPES_BODY_RESOLVE**: The compiler resolves types for callable declarations without an explicit return type. +- **CONSTANT_EVALUATION**: The compiler evaluates values of const properties and defaults of annotations' constructors. - **ANNOTATION_ARGUMENTS**: The compiler resolves arguments of annotations in declaration headers. - **BODY_RESOLVE**: The compiler resolves bodies for declarations. - **CHECKERS**: At this point, all FIR tree is already resolved, and it's time to check it and report diagnostics for the user.