[LL API] return FirErrorProperty for top level destructuring declaration

KTIJ-23552
This commit is contained in:
Anna Kozlova
2022-11-10 15:07:39 +01:00
parent 3590c4ea35
commit 9f470e2a4d
17 changed files with 76 additions and 12 deletions
@@ -142,6 +142,12 @@ public class Fe10IdeNormalAnalysisSourceModuleHLExpressionTypeTestGenerated exte
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expressionType/list_mutableListOf.kt"); 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 @Test
@TestMetadata("nonExpression.kt") @TestMetadata("nonExpression.kt")
public void testNonExpression() throws Exception { public void testNonExpression() throws Exception {
@@ -142,6 +142,12 @@ public class FirIdeDependentAnalysisSourceModuleHLExpressionTypeTestGenerated ex
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expressionType/list_mutableListOf.kt"); 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 @Test
@TestMetadata("nonExpression.kt") @TestMetadata("nonExpression.kt")
public void testNonExpression() throws Exception { public void testNonExpression() throws Exception {
@@ -142,6 +142,12 @@ public class FirIdeNormalAnalysisSourceModuleHLExpressionTypeTestGenerated exten
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expressionType/list_mutableListOf.kt"); 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 @Test
@TestMetadata("nonExpression.kt") @TestMetadata("nonExpression.kt")
public void testNonExpression() throws Exception { public void testNonExpression() throws Exception {
@@ -142,6 +142,12 @@ public class FirStandaloneNormalAnalysisSourceModuleHLExpressionTypeTestGenerate
runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expressionType/list_mutableListOf.kt"); 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 @Test
@TestMetadata("nonExpression.kt") @TestMetadata("nonExpression.kt")
public void testNonExpression() throws Exception { public void testNonExpression() throws Exception {
@@ -0,0 +1,5 @@
var first = -1
var last = -1
val pair = Pair(first, last)
val (first, last) = <expr>pair</expr>
@@ -0,0 +1,2 @@
expression: pair
type: kotlin.Unit
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLookupTagWithFixedSymbol import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLookupTagWithFixedSymbol
import org.jetbrains.kotlin.analysis.utils.errors.buildErrorWithAttachment import org.jetbrains.kotlin.analysis.utils.errors.buildErrorWithAttachment
import org.jetbrains.kotlin.analysis.utils.errors.checkWithAttachmentBuilder import org.jetbrains.kotlin.analysis.utils.errors.checkWithAttachmentBuilder
import org.jetbrains.kotlin.fir.diagnostics.ConeDestructuringDeclarationsOnTopLevel
import org.jetbrains.kotlin.fir.java.javaSymbolProvider import org.jetbrains.kotlin.fir.java.javaSymbolProvider
class FirDeclarationDesignationWithFile( class FirDeclarationDesignationWithFile(
@@ -69,6 +70,13 @@ private fun collectDesignationPath(declaration: FirDeclaration): List<FirDeclara
if (klass.classId.isLocal) return null if (klass.classId.isLocal) return null
klass.toFirRegularClassFromSameSession(declaration.moduleData.session) klass.toFirRegularClassFromSameSession(declaration.moduleData.session)
} }
is FirErrorProperty -> {
return if (declaration.diagnostic == ConeDestructuringDeclarationsOnTopLevel) {
emptyList()
} else {
null
}
}
else -> return null else -> return null
} }
} }
@@ -103,7 +103,7 @@ internal class FirElementBuilder(
} }
// TODO: simplify // 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 var container: PsiElement? = this
while (container != null && container !is KtFile) { while (container != null && container !is KtFile) {
if (container is KtNamedDeclaration if (container is KtNamedDeclaration
@@ -116,12 +116,15 @@ internal inline fun PsiElement.getNonLocalContainingOrThisDeclaration(predicate:
) { ) {
return container return container
} }
if (container is KtDestructuringDeclaration && container.parent is KtFile) {
return container
}
container = container.parent container = container.parent
} }
return null return null
} }
fun PsiElement.getNonLocalContainingInBodyDeclarationWith(): KtNamedDeclaration? = fun PsiElement.getNonLocalContainingInBodyDeclarationWith(): KtDeclaration? =
getNonLocalContainingOrThisDeclaration { declaration -> getNonLocalContainingOrThisDeclaration { declaration ->
when (declaration) { when (declaration) {
is KtNamedFunction -> declaration.bodyExpression?.isAncestor(this) == true is KtNamedFunction -> declaration.bodyExpression?.isAncestor(this) == true
@@ -99,6 +99,10 @@ private fun KtDeclaration.findSourceNonLocalFirDeclarationByProvider(
containerClassFir.declarations.firstOrNull { it.psi === this } containerClassFir.declarations.firstOrNull { it.psi === this }
} }
this is KtTypeAlias -> findFir(provider) 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) else -> errorWithFirSpecificEntries("Invalid container", psi = this)
} }
return candidate?.takeIf { it.realPsi == this } return candidate?.takeIf { it.realPsi == this }
@@ -0,0 +1,6 @@
// WITH_STDLIB
var a = -1
var b = 0
val pair = Pair(a, b)
val (first, last) = <expr>pair</expr>
@@ -0,0 +1,6 @@
KT element: KtNameReferenceExpression
FIR element: FirErrorPropertyImpl
FIR source kind: KtRealSourceElementKind
FIR element rendered:
<ERROR TYPE REF: Destructuring declarations are only allowed for local variables/values>
@@ -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); 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 @Test
@TestMetadata("objectLiteral.kt") @TestMetadata("objectLiteral.kt")
public void testObjectLiteral() throws Exception { public void testObjectLiteral() throws Exception {
@@ -19,10 +19,7 @@ import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeAmbiguityError import org.jetbrains.kotlin.fir.resolve.diagnostics.*
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.resolvedSymbol import org.jetbrains.kotlin.fir.resolvedSymbol
import org.jetbrains.kotlin.fir.symbols.SymbolInternals import org.jetbrains.kotlin.fir.symbols.SymbolInternals
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
@@ -113,6 +113,7 @@ private fun ConeDiagnostic.toKtDiagnostic(
else -> this.getFactory(source).createOn(qualifiedAccessSource ?: source) else -> this.getFactory(source).createOn(qualifiedAccessSource ?: source)
} }
is ConeDestructuringDeclarationsOnTopLevel -> FirSyntaxErrors.SYNTAX.createOn(source)
is ConeCannotInferParameterType -> FirErrors.CANNOT_INFER_PARAMETER_TYPE.createOn(source) is ConeCannotInferParameterType -> FirErrors.CANNOT_INFER_PARAMETER_TYPE.createOn(source)
is ConeInstanceAccessBeforeSuperCall -> FirErrors.INSTANCE_ACCESS_BEFORE_SUPER_CALL.createOn(source, this.target) is ConeInstanceAccessBeforeSuperCall -> FirErrors.INSTANCE_ACCESS_BEFORE_SUPER_CALL.createOn(source, this.target)
is ConeStubDiagnostic -> null is ConeStubDiagnostic -> null
@@ -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.addDeclaration
import org.jetbrains.kotlin.fir.declarations.utils.isCompanion import org.jetbrains.kotlin.fir.declarations.utils.isCompanion
import org.jetbrains.kotlin.fir.declarations.utils.isLocal 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.ConeSimpleDiagnostic
import org.jetbrains.kotlin.fir.diagnostics.ConeUnderscoreIsReserved import org.jetbrains.kotlin.fir.diagnostics.ConeUnderscoreIsReserved
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
@@ -1276,9 +1277,7 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
moduleData = baseModuleData moduleData = baseModuleData
origin = FirDeclarationOrigin.Source origin = FirDeclarationOrigin.Source
name = Name.special("<destructuring>") name = Name.special("<destructuring>")
diagnostic = ConeSimpleDiagnostic( diagnostic = ConeDestructuringDeclarationsOnTopLevel
"Destructuring declarations are only allowed for local variables/values", DiagnosticKind.Syntax
)
symbol = FirErrorPropertySymbol(diagnostic) symbol = FirErrorPropertySymbol(diagnostic)
} }
@@ -242,4 +242,4 @@ class ConeAmbiguousAlteredAssign(val altererNames: List<String?>) : ConeDiagnost
object ConeForbiddenIntersection : ConeDiagnostic { object ConeForbiddenIntersection : ConeDiagnostic {
override val reason: String get() = "Such an intersection type is not allowed" override val reason: String get() = "Such an intersection type is not allowed"
} }
@@ -6,9 +6,7 @@
package org.jetbrains.kotlin.fir.diagnostics package org.jetbrains.kotlin.fir.diagnostics
import org.jetbrains.kotlin.KtSourceElement 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.FirTypeParameterSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirValueParameterSymbol
import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
@@ -43,6 +41,11 @@ class ConeRecursiveTypeParameterDuringErasureError(val typeParameterName: Name)
get() = "self-recursive type parameter $typeParameterName" 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 { enum class DiagnosticKind {
Syntax, Syntax,
ExpressionExpected, ExpressionExpected,