FIR: forbid top-level destructuring declarations #KT-50468 Fixed

This commit is contained in:
Mikhail Glukhikh
2022-03-10 16:11:49 +03:00
committed by Space
parent 6ecc97575d
commit 6b53ac8367
10 changed files with 59 additions and 19 deletions
@@ -64,7 +64,7 @@ internal class LLFirDesignatedAnnotationsResolveTransformed(
when (declaration) {
is FirClass, is FirTypeAlias ->
declaration.ensurePhase(FirResolvePhase.COMPILER_REQUIRED_ANNOTATIONS)
is FirFunction, is FirProperty, is FirEnumEntry, is FirField, is FirAnonymousInitializer ->
is FirFunction, is FirProperty, is FirEnumEntry, is FirField, is FirAnonymousInitializer, is FirErrorProperty ->
Unit
else ->
error("Unexpected type: ${declaration::class.simpleName}")
@@ -512,6 +512,12 @@ public class DiagnosisCompilerFirTestdataTestGenerated extends AbstractDiagnosis
runTest("compiler/fir/analysis-tests/testData/resolve/throwableSubclass.kt");
}
@Test
@TestMetadata("topLevelDestruction.kt")
public void testTopLevelDestruction() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/topLevelDestruction.kt");
}
@Test
@TestMetadata("treeSet.kt")
public void testTreeSet() throws Exception {
@@ -434,6 +434,11 @@ public class LazyBodyIsNotTouchedTilContractsPhaseTestGenerated extends Abstract
runTest("compiler/fir/analysis-tests/testData/resolve/throwableSubclass.kt");
}
@TestMetadata("topLevelDestruction.kt")
public void testTopLevelDestruction() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/topLevelDestruction.kt");
}
@TestMetadata("treeSet.kt")
public void testTreeSet() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/treeSet.kt");
@@ -0,0 +1,2 @@
FILE: topLevelDestruction.kt
<ERROR TYPE REF: Destructuring declarations are only allowed for local variables/values>
@@ -0,0 +1 @@
val <!SYNTAX!>(x, y)<!> = Pair(1, 2)
@@ -512,6 +512,12 @@ public class FirDiagnosticTestGenerated extends AbstractFirDiagnosticTest {
runTest("compiler/fir/analysis-tests/testData/resolve/throwableSubclass.kt");
}
@Test
@TestMetadata("topLevelDestruction.kt")
public void testTopLevelDestruction() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/topLevelDestruction.kt");
}
@Test
@TestMetadata("treeSet.kt")
public void testTreeSet() throws Exception {
@@ -512,6 +512,12 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
runTest("compiler/fir/analysis-tests/testData/resolve/throwableSubclass.kt");
}
@Test
@TestMetadata("topLevelDestruction.kt")
public void testTopLevelDestruction() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/topLevelDestruction.kt");
}
@Test
@TestMetadata("treeSet.kt")
public void testTreeSet() throws Exception {
@@ -8,11 +8,8 @@ package org.jetbrains.kotlin.fir.lightTree.converter
import com.intellij.lang.LighterASTNode
import com.intellij.psi.TokenType
import com.intellij.util.diff.FlyweightCapableTreeStructure
import org.jetbrains.kotlin.*
import org.jetbrains.kotlin.ElementTypeUtils.isExpression
import org.jetbrains.kotlin.KtFakeSourceElementKind
import org.jetbrains.kotlin.KtLightSourceElement
import org.jetbrains.kotlin.KtSourceElement
import org.jetbrains.kotlin.KtNodeTypes
import org.jetbrains.kotlin.KtNodeTypes.*
import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.builtins.StandardNames.DEFAULT_VALUE_PARAMETER
@@ -22,7 +19,6 @@ import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget.*
import org.jetbrains.kotlin.fakeElement
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.builder.*
import org.jetbrains.kotlin.fir.contracts.FirContractDescription
@@ -94,18 +90,20 @@ class DeclarationsConverter(
val firDeclarationList = mutableListOf<FirDeclaration>()
context.packageFqName = FqName.ROOT
var packageDirective: FirPackageDirective? = null
file.forEachChildren {
when (it.tokenType) {
FILE_ANNOTATION_LIST -> fileAnnotationList += convertFileAnnotationList(it)
file.forEachChildren { child ->
@Suppress("RemoveRedundantQualifierName")
when (child.tokenType) {
FILE_ANNOTATION_LIST -> fileAnnotationList += convertFileAnnotationList(child)
PACKAGE_DIRECTIVE -> {
packageDirective = convertPackageDirective(it).also { context.packageFqName = it.packageFqName }
packageDirective = convertPackageDirective(child).also { context.packageFqName = it.packageFqName }
}
IMPORT_LIST -> importList += convertImportDirectives(it)
CLASS -> firDeclarationList += convertClass(it)
FUN -> firDeclarationList += convertFunctionDeclaration(it) as FirDeclaration
KtNodeTypes.PROPERTY -> firDeclarationList += convertPropertyDeclaration(it)
TYPEALIAS -> firDeclarationList += convertTypeAlias(it)
OBJECT_DECLARATION -> firDeclarationList += convertClass(it)
IMPORT_LIST -> importList += convertImportDirectives(child)
CLASS -> firDeclarationList += convertClass(child)
FUN -> firDeclarationList += convertFunctionDeclaration(child) as FirDeclaration
KtNodeTypes.PROPERTY -> firDeclarationList += convertPropertyDeclaration(child)
TYPEALIAS -> firDeclarationList += convertTypeAlias(child)
OBJECT_DECLARATION -> firDeclarationList += convertClass(child)
DESTRUCTURING_DECLARATION -> firDeclarationList += buildErrorTopLevelDestructuringDeclaration(child.toFirSourceElement())
SCRIPT -> {
// TODO: scripts aren't supported yet
}
@@ -134,6 +132,7 @@ class DeclarationsConverter(
fun convertBlockExpressionWithoutBuilding(block: LighterASTNode): FirBlockBuilder {
val firStatements = block.forEachChildrenReturnList<FirStatement> { node, container ->
@Suppress("RemoveRedundantQualifierName")
when (node.tokenType) {
CLASS, OBJECT_DECLARATION -> container += convertClass(node) as FirStatement
FUN -> container += convertFunctionDeclaration(node)
@@ -791,6 +790,7 @@ class DeclarationsConverter(
*/
private fun convertClassBody(classBody: LighterASTNode, classWrapper: ClassWrapper): List<FirDeclaration> {
return classBody.forEachChildrenReturnList { node, container ->
@Suppress("RemoveRedundantQualifierName")
when (node.tokenType) {
ENUM_ENTRY -> container += convertEnumEntry(node, classWrapper)
CLASS -> container += convertClass(node)
@@ -929,9 +929,12 @@ open class RawFirBuilder(
}
}
for (declaration in file.declarations) {
// TODO: scripts aren't supported yet
if (declaration is KtScript) continue
declarations += declaration.convert<FirDeclaration>()
declarations += when (declaration) {
// TODO: scripts aren't supported yet
is KtScript -> continue
is KtDestructuringDeclaration -> buildErrorTopLevelDestructuringDeclaration(declaration.toFirSourceElement())
else -> declaration.convert()
}
}
}
}
@@ -1261,6 +1261,17 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
}
}
protected fun buildErrorTopLevelDestructuringDeclaration(source: KtSourceElement) = buildErrorProperty {
this.source = source
moduleData = baseModuleData
origin = FirDeclarationOrigin.Source
name = Name.special("<destructuring>")
diagnostic = ConeSimpleDiagnostic(
"Destructuring declarations are only allowed for local variables/values", DiagnosticKind.Syntax
)
symbol = FirErrorPropertySymbol(diagnostic)
}
enum class ValueParameterDeclaration {
OTHER,
LAMBDA,