From 9f470e2a4de3211c96ac290981d48bf049fbf35b Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Thu, 10 Nov 2022 15:07:39 +0100 Subject: [PATCH] [LL API] return FirErrorProperty for top level destructuring declaration KTIJ-23552 --- ...AnalysisSourceModuleHLExpressionTypeTestGenerated.java | 6 ++++++ ...AnalysisSourceModuleHLExpressionTypeTestGenerated.java | 6 ++++++ ...AnalysisSourceModuleHLExpressionTypeTestGenerated.java | 6 ++++++ ...AnalysisSourceModuleHLExpressionTypeTestGenerated.java | 6 ++++++ .../expressionType/nameReference.kt | 5 +++++ .../expressionType/nameReference.txt | 2 ++ .../low/level/api/fir/api/FirDeclarationDesignation.kt | 8 ++++++++ .../level/api/fir/element/builder/FirElementBuilder.kt | 7 +++++-- .../analysis/low/level/api/fir/util/declarationUtils.kt | 4 ++++ .../testdata/getOrBuildFir/declarations/destructuring.kt | 6 ++++++ .../testdata/getOrBuildFir/declarations/destructuring.txt | 6 ++++++ .../low/level/api/fir/GetOrBuildFirTestGenerated.java | 6 ++++++ .../declaration/FirDestructuringDeclarationChecker.kt | 5 +---- .../analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt | 1 + .../org/jetbrains/kotlin/fir/builder/BaseFirBuilder.kt | 5 ++--- .../kotlin/fir/resolve/diagnostics/ConeDiagnostics.kt | 2 +- .../kotlin/fir/diagnostics/ConeSimpleDiagnostic.kt | 7 +++++-- 17 files changed, 76 insertions(+), 12 deletions(-) create mode 100644 analysis/analysis-api/testData/components/expressionTypeProvider/expressionType/nameReference.kt create mode 100644 analysis/analysis-api/testData/components/expressionTypeProvider/expressionType/nameReference.txt create mode 100644 analysis/low-level-api-fir/testdata/getOrBuildFir/declarations/destructuring.kt create mode 100644 analysis/low-level-api-fir/testdata/getOrBuildFir/declarations/destructuring.txt diff --git a/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/components/expressionTypeProvider/Fe10IdeNormalAnalysisSourceModuleHLExpressionTypeTestGenerated.java b/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/components/expressionTypeProvider/Fe10IdeNormalAnalysisSourceModuleHLExpressionTypeTestGenerated.java index e71aab4ad2d..f895c636717 100644 --- a/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/components/expressionTypeProvider/Fe10IdeNormalAnalysisSourceModuleHLExpressionTypeTestGenerated.java +++ b/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/components/expressionTypeProvider/Fe10IdeNormalAnalysisSourceModuleHLExpressionTypeTestGenerated.java @@ -142,6 +142,12 @@ public class Fe10IdeNormalAnalysisSourceModuleHLExpressionTypeTestGenerated exte runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expressionType/list_mutableListOf.kt"); } + @Test + @TestMetadata("nameReference.kt") + public void testNameReference() throws Exception { + runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expressionType/nameReference.kt"); + } + @Test @TestMetadata("nonExpression.kt") public void testNonExpression() throws Exception { diff --git a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/expressionTypeProvider/FirIdeDependentAnalysisSourceModuleHLExpressionTypeTestGenerated.java b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/expressionTypeProvider/FirIdeDependentAnalysisSourceModuleHLExpressionTypeTestGenerated.java index 61e51c96204..6676e62e66e 100644 --- a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/expressionTypeProvider/FirIdeDependentAnalysisSourceModuleHLExpressionTypeTestGenerated.java +++ b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/expressionTypeProvider/FirIdeDependentAnalysisSourceModuleHLExpressionTypeTestGenerated.java @@ -142,6 +142,12 @@ public class FirIdeDependentAnalysisSourceModuleHLExpressionTypeTestGenerated ex runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expressionType/list_mutableListOf.kt"); } + @Test + @TestMetadata("nameReference.kt") + public void testNameReference() throws Exception { + runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expressionType/nameReference.kt"); + } + @Test @TestMetadata("nonExpression.kt") public void testNonExpression() throws Exception { diff --git a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/expressionTypeProvider/FirIdeNormalAnalysisSourceModuleHLExpressionTypeTestGenerated.java b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/expressionTypeProvider/FirIdeNormalAnalysisSourceModuleHLExpressionTypeTestGenerated.java index fcdfd274911..d675fc50996 100644 --- a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/expressionTypeProvider/FirIdeNormalAnalysisSourceModuleHLExpressionTypeTestGenerated.java +++ b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/expressionTypeProvider/FirIdeNormalAnalysisSourceModuleHLExpressionTypeTestGenerated.java @@ -142,6 +142,12 @@ public class FirIdeNormalAnalysisSourceModuleHLExpressionTypeTestGenerated exten runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expressionType/list_mutableListOf.kt"); } + @Test + @TestMetadata("nameReference.kt") + public void testNameReference() throws Exception { + runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expressionType/nameReference.kt"); + } + @Test @TestMetadata("nonExpression.kt") public void testNonExpression() throws Exception { diff --git a/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/components/expressionTypeProvider/FirStandaloneNormalAnalysisSourceModuleHLExpressionTypeTestGenerated.java b/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/components/expressionTypeProvider/FirStandaloneNormalAnalysisSourceModuleHLExpressionTypeTestGenerated.java index d154b072e8c..3fc3556689c 100644 --- a/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/components/expressionTypeProvider/FirStandaloneNormalAnalysisSourceModuleHLExpressionTypeTestGenerated.java +++ b/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/components/expressionTypeProvider/FirStandaloneNormalAnalysisSourceModuleHLExpressionTypeTestGenerated.java @@ -142,6 +142,12 @@ public class FirStandaloneNormalAnalysisSourceModuleHLExpressionTypeTestGenerate runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expressionType/list_mutableListOf.kt"); } + @Test + @TestMetadata("nameReference.kt") + public void testNameReference() throws Exception { + runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expressionType/nameReference.kt"); + } + @Test @TestMetadata("nonExpression.kt") public void testNonExpression() throws Exception { diff --git a/analysis/analysis-api/testData/components/expressionTypeProvider/expressionType/nameReference.kt b/analysis/analysis-api/testData/components/expressionTypeProvider/expressionType/nameReference.kt new file mode 100644 index 00000000000..0a5dfdfca53 --- /dev/null +++ b/analysis/analysis-api/testData/components/expressionTypeProvider/expressionType/nameReference.kt @@ -0,0 +1,5 @@ +var first = -1 +var last = -1 +val pair = Pair(first, last) + +val (first, last) = pair \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/expressionTypeProvider/expressionType/nameReference.txt b/analysis/analysis-api/testData/components/expressionTypeProvider/expressionType/nameReference.txt new file mode 100644 index 00000000000..63b88eb2175 --- /dev/null +++ b/analysis/analysis-api/testData/components/expressionTypeProvider/expressionType/nameReference.txt @@ -0,0 +1,2 @@ +expression: pair +type: kotlin.Unit diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/api/FirDeclarationDesignation.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/api/FirDeclarationDesignation.kt index 42f64473cf0..058c8f7bff7 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/api/FirDeclarationDesignation.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/api/FirDeclarationDesignation.kt @@ -18,6 +18,7 @@ import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLookupTagWithFixedSymbol import org.jetbrains.kotlin.analysis.utils.errors.buildErrorWithAttachment import org.jetbrains.kotlin.analysis.utils.errors.checkWithAttachmentBuilder +import org.jetbrains.kotlin.fir.diagnostics.ConeDestructuringDeclarationsOnTopLevel import org.jetbrains.kotlin.fir.java.javaSymbolProvider class FirDeclarationDesignationWithFile( @@ -69,6 +70,13 @@ private fun collectDesignationPath(declaration: FirDeclaration): List { + return if (declaration.diagnostic == ConeDestructuringDeclarationsOnTopLevel) { + emptyList() + } else { + null + } + } else -> return null } } diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/element/builder/FirElementBuilder.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/element/builder/FirElementBuilder.kt index 1eb83488185..7c98ef754a9 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/element/builder/FirElementBuilder.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/element/builder/FirElementBuilder.kt @@ -103,7 +103,7 @@ internal class FirElementBuilder( } // TODO: simplify -internal inline fun PsiElement.getNonLocalContainingOrThisDeclaration(predicate: (KtDeclaration) -> Boolean = { true }): KtNamedDeclaration? { +internal inline fun PsiElement.getNonLocalContainingOrThisDeclaration(predicate: (KtDeclaration) -> Boolean = { true }): KtDeclaration? { var container: PsiElement? = this while (container != null && container !is KtFile) { if (container is KtNamedDeclaration @@ -116,12 +116,15 @@ internal inline fun PsiElement.getNonLocalContainingOrThisDeclaration(predicate: ) { return container } + if (container is KtDestructuringDeclaration && container.parent is KtFile) { + return container + } container = container.parent } return null } -fun PsiElement.getNonLocalContainingInBodyDeclarationWith(): KtNamedDeclaration? = +fun PsiElement.getNonLocalContainingInBodyDeclarationWith(): KtDeclaration? = getNonLocalContainingOrThisDeclaration { declaration -> when (declaration) { is KtNamedFunction -> declaration.bodyExpression?.isAncestor(this) == true diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/util/declarationUtils.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/util/declarationUtils.kt index d17c585899b..33be04e81f1 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/util/declarationUtils.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/util/declarationUtils.kt @@ -99,6 +99,10 @@ private fun KtDeclaration.findSourceNonLocalFirDeclarationByProvider( containerClassFir.declarations.firstOrNull { it.psi === this } } this is KtTypeAlias -> findFir(provider) + this is KtDestructuringDeclaration -> { + val firFile = containerFirFile ?: firFileBuilder.buildRawFirFileWithCaching(containingKtFile) + firFile.declarations.firstOrNull { it.psi == this } + } else -> errorWithFirSpecificEntries("Invalid container", psi = this) } return candidate?.takeIf { it.realPsi == this } diff --git a/analysis/low-level-api-fir/testdata/getOrBuildFir/declarations/destructuring.kt b/analysis/low-level-api-fir/testdata/getOrBuildFir/declarations/destructuring.kt new file mode 100644 index 00000000000..d9a17a1d639 --- /dev/null +++ b/analysis/low-level-api-fir/testdata/getOrBuildFir/declarations/destructuring.kt @@ -0,0 +1,6 @@ +// WITH_STDLIB +var a = -1 +var b = 0 +val pair = Pair(a, b) + +val (first, last) = pair \ No newline at end of file diff --git a/analysis/low-level-api-fir/testdata/getOrBuildFir/declarations/destructuring.txt b/analysis/low-level-api-fir/testdata/getOrBuildFir/declarations/destructuring.txt new file mode 100644 index 00000000000..35d64299176 --- /dev/null +++ b/analysis/low-level-api-fir/testdata/getOrBuildFir/declarations/destructuring.txt @@ -0,0 +1,6 @@ +KT element: KtNameReferenceExpression +FIR element: FirErrorPropertyImpl +FIR source kind: KtRealSourceElementKind + +FIR element rendered: + \ No newline at end of file diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/GetOrBuildFirTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/GetOrBuildFirTestGenerated.java index ebadbcd07a9..eff086667d3 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/GetOrBuildFirTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/GetOrBuildFirTestGenerated.java @@ -215,6 +215,12 @@ public class GetOrBuildFirTestGenerated extends AbstractGetOrBuildFirTest { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/low-level-api-fir/testdata/getOrBuildFir/declarations"), Pattern.compile("^(.+)\\.kt$"), null, true); } + @Test + @TestMetadata("destructuring.kt") + public void testDestructuring() throws Exception { + runTest("analysis/low-level-api-fir/testdata/getOrBuildFir/declarations/destructuring.kt"); + } + @Test @TestMetadata("objectLiteral.kt") public void testObjectLiteral() throws Exception { diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirDestructuringDeclarationChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirDestructuringDeclarationChecker.kt index 9b2c0954b88..b75c7c943aa 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirDestructuringDeclarationChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirDestructuringDeclarationChecker.kt @@ -19,10 +19,7 @@ import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.references.FirErrorNamedReference -import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeAmbiguityError -import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeConstraintSystemHasContradiction -import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeInapplicableCandidateError -import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnresolvedNameError +import org.jetbrains.kotlin.fir.resolve.diagnostics.* import org.jetbrains.kotlin.fir.resolvedSymbol import org.jetbrains.kotlin.fir.symbols.SymbolInternals import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt index dc751bc6937..da14e4495cd 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt @@ -113,6 +113,7 @@ private fun ConeDiagnostic.toKtDiagnostic( else -> this.getFactory(source).createOn(qualifiedAccessSource ?: source) } + is ConeDestructuringDeclarationsOnTopLevel -> FirSyntaxErrors.SYNTAX.createOn(source) is ConeCannotInferParameterType -> FirErrors.CANNOT_INFER_PARAMETER_TYPE.createOn(source) is ConeInstanceAccessBeforeSuperCall -> FirErrors.INSTANCE_ACCESS_BEFORE_SUPER_CALL.createOn(source, this.target) is ConeStubDiagnostic -> null diff --git a/compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/BaseFirBuilder.kt b/compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/BaseFirBuilder.kt index d9df4488367..f3036e809a1 100644 --- a/compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/BaseFirBuilder.kt +++ b/compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/BaseFirBuilder.kt @@ -18,6 +18,7 @@ import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl import org.jetbrains.kotlin.fir.declarations.utils.addDeclaration import org.jetbrains.kotlin.fir.declarations.utils.isCompanion import org.jetbrains.kotlin.fir.declarations.utils.isLocal +import org.jetbrains.kotlin.fir.diagnostics.ConeDestructuringDeclarationsOnTopLevel import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic import org.jetbrains.kotlin.fir.diagnostics.ConeUnderscoreIsReserved import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind @@ -1276,9 +1277,7 @@ abstract class BaseFirBuilder(val baseSession: FirSession, val context: Conte moduleData = baseModuleData origin = FirDeclarationOrigin.Source name = Name.special("") - diagnostic = ConeSimpleDiagnostic( - "Destructuring declarations are only allowed for local variables/values", DiagnosticKind.Syntax - ) + diagnostic = ConeDestructuringDeclarationsOnTopLevel symbol = FirErrorPropertySymbol(diagnostic) } diff --git a/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/diagnostics/ConeDiagnostics.kt b/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/diagnostics/ConeDiagnostics.kt index 39c8aae0b38..008559028d6 100644 --- a/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/diagnostics/ConeDiagnostics.kt +++ b/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/diagnostics/ConeDiagnostics.kt @@ -242,4 +242,4 @@ class ConeAmbiguousAlteredAssign(val altererNames: List) : ConeDiagnost object ConeForbiddenIntersection : ConeDiagnostic { override val reason: String get() = "Such an intersection type is not allowed" -} +} \ No newline at end of file diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/diagnostics/ConeSimpleDiagnostic.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/diagnostics/ConeSimpleDiagnostic.kt index 21b8d53087d..e048cc6566b 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/diagnostics/ConeSimpleDiagnostic.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/diagnostics/ConeSimpleDiagnostic.kt @@ -6,9 +6,7 @@ package org.jetbrains.kotlin.fir.diagnostics import org.jetbrains.kotlin.KtSourceElement -import org.jetbrains.kotlin.fir.declarations.FirTypeParameter import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol -import org.jetbrains.kotlin.fir.symbols.impl.FirValueParameterSymbol import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.name.Name @@ -43,6 +41,11 @@ class ConeRecursiveTypeParameterDuringErasureError(val typeParameterName: Name) get() = "self-recursive type parameter $typeParameterName" } +object ConeDestructuringDeclarationsOnTopLevel : ConeDiagnostic { + override val reason: String + get() = "Destructuring declarations are only allowed for local variables/values" +} + enum class DiagnosticKind { Syntax, ExpressionExpected,