[Analysis API FIR] fix KtSymbol creation for _ destructuring parameter
We need to have a corresponding declaration in the FIR tree, so we can create a symbol for it ^KT-60904 fixed ^KT-60904 fixed
This commit is contained in:
committed by
Space Team
parent
04b9faf9e6
commit
c963eadb44
+8
-2
@@ -5,6 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.analysis.api.descriptors.symbols.psiBased
|
||||
|
||||
import com.intellij.extapi.psi.StubBasedPsiElementBase
|
||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
||||
import org.jetbrains.kotlin.analysis.api.descriptors.Fe10AnalysisContext
|
||||
import org.jetbrains.kotlin.analysis.api.descriptors.Fe10AnalysisFacade.AnalysisMode
|
||||
@@ -23,6 +24,7 @@ import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer
|
||||
import org.jetbrains.kotlin.analysis.api.types.KtType
|
||||
import org.jetbrains.kotlin.descriptors.VariableDescriptor
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.name.SpecialNames
|
||||
import org.jetbrains.kotlin.psi.KtVariableDeclaration
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
|
||||
@@ -36,8 +38,12 @@ internal class KtFe10PsiLocalVariableSymbol(
|
||||
}
|
||||
|
||||
override val name: Name
|
||||
get() = withValidityAssertion { psi.nameAsSafeName }
|
||||
|
||||
get() = withValidityAssertion {
|
||||
when {
|
||||
psi.nameIdentifier?.text == "_" -> SpecialNames.UNDERSCORE_FOR_UNUSED_VAR
|
||||
else -> psi.nameAsSafeName
|
||||
}
|
||||
}
|
||||
override val returnType: KtType
|
||||
get() = withValidityAssertion { descriptor?.type?.toKtType(analysisContext) ?: createErrorType() }
|
||||
|
||||
|
||||
+5
-1
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.descriptors.VariableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.name.SpecialNames
|
||||
import org.jetbrains.kotlin.psi.KtParameter
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
|
||||
@@ -68,7 +69,10 @@ internal class KtFe10PsiValueParameterSymbol(
|
||||
}
|
||||
|
||||
override val name: Name
|
||||
get() = withValidityAssertion { psi.nameAsSafeName }
|
||||
get() = withValidityAssertion {
|
||||
if (psi.destructuringDeclaration != null) SpecialNames.DESTRUCT
|
||||
else psi.nameAsSafeName
|
||||
}
|
||||
|
||||
context(KtAnalysisSession)
|
||||
override fun createPointer(): KtSymbolPointer<KtValueParameterSymbol> = withValidityAssertion {
|
||||
|
||||
+40
@@ -314,6 +314,46 @@ public class Fe10IdeNormalAnalysisSourceModuleSingleSymbolByPsiGenerated extends
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("analysis/analysis-api/testData/symbols/singleSymbolByPsi/destructuring")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class Destructuring {
|
||||
@Test
|
||||
public void testAllFilesPresentInDestructuring() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/symbols/singleSymbolByPsi/destructuring"), Pattern.compile("^(.+)\\.kt$"), null, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("destructuringDeclarationParameterInLambda.kt")
|
||||
public void testDestructuringDeclarationParameterInLambda() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/destructuring/destructuringDeclarationParameterInLambda.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("entryInDestructuringDeclaration.kt")
|
||||
public void testEntryInDestructuringDeclaration() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/destructuring/entryInDestructuringDeclaration.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("entryInDestructuringDeclarationParameterInLambda.kt")
|
||||
public void testEntryInDestructuringDeclarationParameterInLambda() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/destructuring/entryInDestructuringDeclarationParameterInLambda.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("entryUnderscoreInDestructuringDeclaration.kt")
|
||||
public void testEntryUnderscoreInDestructuringDeclaration() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/destructuring/entryUnderscoreInDestructuringDeclaration.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("entryUnderscoreInDestructuringDeclarationParameterInLambda.kt")
|
||||
public void testEntryUnderscoreInDestructuringDeclarationParameterInLambda() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/destructuring/entryUnderscoreInDestructuringDeclarationParameterInLambda.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("analysis/analysis-api/testData/symbols/singleSymbolByPsi/errors")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
|
||||
+6
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getOrBuildFirFile
|
||||
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.FirProperty
|
||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.psi
|
||||
@@ -130,6 +131,11 @@ internal class KtFirImportOptimizer(
|
||||
super.visitImplicitInvokeCall(implicitInvokeCall)
|
||||
}
|
||||
|
||||
override fun visitProperty(property: FirProperty) {
|
||||
if (property.name == SpecialNames.UNDERSCORE_FOR_UNUSED_VAR) return
|
||||
super.visitProperty(property)
|
||||
}
|
||||
|
||||
override fun visitComponentCall(componentCall: FirComponentCall) {
|
||||
processFunctionCall(componentCall)
|
||||
super.visitComponentCall(componentCall)
|
||||
|
||||
+8
-3
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.analysis.api.fir.components.KtFirAnalysisSessionComp
|
||||
import org.jetbrains.kotlin.analysis.api.getModule
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.*
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getOrBuildFirFile
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.resolveToFirSymbol
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.resolveToFirSymbolOfType
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.throwUnexpectedFirElementError
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.errorWithFirSpecificEntries
|
||||
@@ -25,6 +26,7 @@ import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.isObjectLiteral
|
||||
import org.jetbrains.kotlin.resolve.calls.util.isSingleUnderscore
|
||||
|
||||
internal class KtFirSymbolProvider(
|
||||
override val analysisSession: KtFirAnalysisSession,
|
||||
@@ -186,11 +188,14 @@ internal class KtFirSymbolProvider(
|
||||
|
||||
override val ROOT_PACKAGE_SYMBOL: KtPackageSymbol = KtFirPackageSymbol(FqName.ROOT, firResolveSession.project, token)
|
||||
|
||||
override fun getDestructuringDeclarationEntrySymbol(psi: KtDestructuringDeclarationEntry): KtFirLocalOrErrorVariableSymbol<*, *> {
|
||||
return when (val firSymbol = psi.resolveToFirSymbolOfType<FirVariableSymbol<*>>(firResolveSession)) {
|
||||
override fun getDestructuringDeclarationEntrySymbol(psi: KtDestructuringDeclarationEntry): KtLocalVariableSymbol {
|
||||
return when (val firSymbol = psi.resolveToFirSymbol(firResolveSession)) {
|
||||
is FirPropertySymbol -> firSymbolBuilder.variableLikeBuilder.buildLocalVariableSymbol(firSymbol)
|
||||
is FirErrorPropertySymbol -> firSymbolBuilder.variableLikeBuilder.buildErrorVariableSymbol(firSymbol)
|
||||
else -> throwUnexpectedFirElementError(firSymbol, psi, FirPropertySymbol::class, FirErrorPropertySymbol::class)
|
||||
else -> throwUnexpectedFirElementError(
|
||||
firSymbol, psi,
|
||||
FirPropertySymbol::class, FirErrorPropertySymbol::class, FirValueParameterSymbol::class
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+40
@@ -314,6 +314,46 @@ public class FirIdeNormalAnalysisSourceModuleSingleSymbolByPsiGenerated extends
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("analysis/analysis-api/testData/symbols/singleSymbolByPsi/destructuring")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class Destructuring {
|
||||
@Test
|
||||
public void testAllFilesPresentInDestructuring() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/symbols/singleSymbolByPsi/destructuring"), Pattern.compile("^(.+)\\.kt$"), null, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("destructuringDeclarationParameterInLambda.kt")
|
||||
public void testDestructuringDeclarationParameterInLambda() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/destructuring/destructuringDeclarationParameterInLambda.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("entryInDestructuringDeclaration.kt")
|
||||
public void testEntryInDestructuringDeclaration() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/destructuring/entryInDestructuringDeclaration.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("entryInDestructuringDeclarationParameterInLambda.kt")
|
||||
public void testEntryInDestructuringDeclarationParameterInLambda() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/destructuring/entryInDestructuringDeclarationParameterInLambda.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("entryUnderscoreInDestructuringDeclaration.kt")
|
||||
public void testEntryUnderscoreInDestructuringDeclaration() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/destructuring/entryUnderscoreInDestructuringDeclaration.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("entryUnderscoreInDestructuringDeclarationParameterInLambda.kt")
|
||||
public void testEntryUnderscoreInDestructuringDeclarationParameterInLambda() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/destructuring/entryUnderscoreInDestructuringDeclarationParameterInLambda.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("analysis/analysis-api/testData/symbols/singleSymbolByPsi/errors")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
|
||||
+40
@@ -314,6 +314,46 @@ public class FirStandaloneNormalAnalysisSourceModuleSingleSymbolByPsiGenerated e
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("analysis/analysis-api/testData/symbols/singleSymbolByPsi/destructuring")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class Destructuring {
|
||||
@Test
|
||||
public void testAllFilesPresentInDestructuring() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/symbols/singleSymbolByPsi/destructuring"), Pattern.compile("^(.+)\\.kt$"), null, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("destructuringDeclarationParameterInLambda.kt")
|
||||
public void testDestructuringDeclarationParameterInLambda() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/destructuring/destructuringDeclarationParameterInLambda.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("entryInDestructuringDeclaration.kt")
|
||||
public void testEntryInDestructuringDeclaration() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/destructuring/entryInDestructuringDeclaration.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("entryInDestructuringDeclarationParameterInLambda.kt")
|
||||
public void testEntryInDestructuringDeclarationParameterInLambda() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/destructuring/entryInDestructuringDeclarationParameterInLambda.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("entryUnderscoreInDestructuringDeclaration.kt")
|
||||
public void testEntryUnderscoreInDestructuringDeclaration() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/destructuring/entryUnderscoreInDestructuringDeclaration.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("entryUnderscoreInDestructuringDeclarationParameterInLambda.kt")
|
||||
public void testEntryUnderscoreInDestructuringDeclarationParameterInLambda() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/destructuring/entryUnderscoreInDestructuringDeclarationParameterInLambda.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("analysis/analysis-api/testData/symbols/singleSymbolByPsi/errors")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
// LOOK_UP_FOR_ELEMENT_OF_TYPE: KtParameter
|
||||
// DO_NOT_CHECK_NON_PSI_SYMBOL_RESTORE
|
||||
|
||||
data class X(val a: Int, val b: Int)
|
||||
|
||||
fun x(action: (X, Int) -> Unit) {}
|
||||
|
||||
fun main() {
|
||||
x { <expr>(a, b)</expr>, i ->
|
||||
|
||||
}
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
`<destruct>`: X
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
KtValueParameterSymbol:
|
||||
annotationsList: []
|
||||
callableIdIfNonLocal: null
|
||||
contextReceivers: []
|
||||
generatedPrimaryConstructorProperty: null
|
||||
hasDefaultValue: false
|
||||
isCrossinline: false
|
||||
isExtension: false
|
||||
isImplicitLambdaParameter: false
|
||||
isNoinline: false
|
||||
isVararg: false
|
||||
name: <destruct>
|
||||
origin: SOURCE
|
||||
receiverParameter: null
|
||||
returnType: KtUsualClassType:
|
||||
annotationsList: []
|
||||
ownTypeArguments: []
|
||||
type: X
|
||||
symbolKind: LOCAL
|
||||
typeParameters: []
|
||||
getContainingModule: KtSourceModule "Sources of main"
|
||||
deprecationStatus: null
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
// LOOK_UP_FOR_ELEMENT_OF_TYPE: KtDestructuringDeclarationEntry
|
||||
// DO_NOT_CHECK_NON_PSI_SYMBOL_RESTORE
|
||||
|
||||
data class X(val a: Int, val b: Int)
|
||||
|
||||
fun main(x: X) {
|
||||
val (<expr>a</expr>, b) = x
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
val a: kotlin.Int
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
KtLocalVariableSymbol:
|
||||
annotationsList: []
|
||||
callableIdIfNonLocal: null
|
||||
contextReceivers: []
|
||||
isExtension: false
|
||||
isVal: true
|
||||
name: a
|
||||
origin: SOURCE
|
||||
receiverParameter: null
|
||||
returnType: KtUsualClassType:
|
||||
annotationsList: []
|
||||
ownTypeArguments: []
|
||||
type: kotlin/Int
|
||||
symbolKind: LOCAL
|
||||
typeParameters: []
|
||||
getContainingModule: KtSourceModule "Sources of main"
|
||||
deprecationStatus: null
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
// LOOK_UP_FOR_ELEMENT_OF_TYPE: KtDestructuringDeclarationEntry
|
||||
// DO_NOT_CHECK_NON_PSI_SYMBOL_RESTORE
|
||||
|
||||
data class X(val a: Int, val b: Int)
|
||||
|
||||
fun x(action: (X) -> Unit) {}
|
||||
|
||||
fun main() {
|
||||
x { (<expr>a</expr>, b) ->
|
||||
|
||||
}
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
val a: kotlin.Int
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
KtLocalVariableSymbol:
|
||||
annotationsList: []
|
||||
callableIdIfNonLocal: null
|
||||
contextReceivers: []
|
||||
isExtension: false
|
||||
isVal: true
|
||||
name: a
|
||||
origin: SOURCE
|
||||
receiverParameter: null
|
||||
returnType: KtUsualClassType:
|
||||
annotationsList: []
|
||||
ownTypeArguments: []
|
||||
type: kotlin/Int
|
||||
symbolKind: LOCAL
|
||||
typeParameters: []
|
||||
getContainingModule: KtSourceModule "Sources of main"
|
||||
deprecationStatus: null
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
// LOOK_UP_FOR_ELEMENT_OF_TYPE: KtDestructuringDeclarationEntry
|
||||
// DO_NOT_CHECK_NON_PSI_SYMBOL_RESTORE
|
||||
|
||||
data class X(val a: Int, val b: Int)
|
||||
|
||||
fun main(x: X) {
|
||||
val (<expr>_</expr>, b) = x
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
val `<unused var>`: kotlin.Int
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
KtLocalVariableSymbol:
|
||||
annotationsList: []
|
||||
callableIdIfNonLocal: null
|
||||
contextReceivers: []
|
||||
isExtension: false
|
||||
isVal: true
|
||||
name: <unused var>
|
||||
origin: SOURCE
|
||||
receiverParameter: null
|
||||
returnType: KtUsualClassType:
|
||||
annotationsList: []
|
||||
ownTypeArguments: []
|
||||
type: kotlin/Int
|
||||
symbolKind: LOCAL
|
||||
typeParameters: []
|
||||
getContainingModule: KtSourceModule "Sources of main"
|
||||
deprecationStatus: null
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
// LOOK_UP_FOR_ELEMENT_OF_TYPE: KtDestructuringDeclarationEntry
|
||||
// DO_NOT_CHECK_NON_PSI_SYMBOL_RESTORE
|
||||
|
||||
data class X(val a: Int, val b: Int)
|
||||
|
||||
fun x(action: (X) -> Unit) {}
|
||||
|
||||
fun main() {
|
||||
x { (<expr>_</expr>, b) ->
|
||||
|
||||
}
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
val `<unused var>`: kotlin.Int
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
KtLocalVariableSymbol:
|
||||
annotationsList: []
|
||||
callableIdIfNonLocal: null
|
||||
contextReceivers: []
|
||||
isExtension: false
|
||||
isVal: true
|
||||
name: <unused var>
|
||||
origin: SOURCE
|
||||
receiverParameter: null
|
||||
returnType: KtUsualClassType:
|
||||
annotationsList: []
|
||||
ownTypeArguments: []
|
||||
type: kotlin/Int
|
||||
symbolKind: LOCAL
|
||||
typeParameters: []
|
||||
getContainingModule: KtSourceModule "Sources of main"
|
||||
deprecationStatus: null
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
// LOOK_UP_FOR_ELEMENT_OF_TYPE: org.jetbrains.kotlin.psi.KtDestructuringDeclarationEntry
|
||||
|
||||
data class X(val a: Int, val b: Int)
|
||||
|
||||
fun main(x: X) {
|
||||
val (<expr>_</expr>, b) = x
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
KT element: KtDestructuringDeclarationEntry
|
||||
FIR element: FirPropertyImpl
|
||||
FIR source kind: KtRealSourceElementKind
|
||||
|
||||
FIR element rendered:
|
||||
[ResolvedTo(BODY_RESOLVE)] lval <unused var>: R|kotlin/Int| = R|<local>/<destruct>|.R|/X.component1|()
|
||||
|
||||
FIR FILE:
|
||||
FILE: [ResolvedTo(IMPORTS)] entryUnderscoreInDestructuringDeclaration.kt
|
||||
public final data [ResolvedTo(STATUS)] class X : R|kotlin/Any| {
|
||||
public [ResolvedTo(STATUS)] [ContainingClassKey=X] constructor([ResolvedTo(STATUS)] [CorrespondingProperty=/X.a] a: R|kotlin/Int|, [ResolvedTo(STATUS)] [CorrespondingProperty=/X.b] b: R|kotlin/Int|): R|X| {
|
||||
LAZY_super<R|kotlin/Any|>
|
||||
}
|
||||
|
||||
public final [ResolvedTo(STATUS)] [ComponentFunctionSymbolKey=/X.component1, IsFromPrimaryConstructor=true] val a: R|kotlin/Int| = R|<local>/a|
|
||||
public [ResolvedTo(STATUS)] [ContainingClassKey=X] get(): R|kotlin/Int|
|
||||
|
||||
public final [ResolvedTo(STATUS)] [ComponentFunctionSymbolKey=/X.component2, IsFromPrimaryConstructor=true] val b: R|kotlin/Int| = R|<local>/b|
|
||||
public [ResolvedTo(STATUS)] [ContainingClassKey=X] get(): R|kotlin/Int|
|
||||
|
||||
public final operator [ResolvedTo(CONTRACTS)] fun component1(): R|kotlin/Int|
|
||||
|
||||
public final operator [ResolvedTo(CONTRACTS)] fun component2(): R|kotlin/Int|
|
||||
|
||||
public final [ResolvedTo(STATUS)] fun copy([ResolvedTo(STATUS)] a: R|kotlin/Int| = this@R|/X|.R|/X.a|, [ResolvedTo(STATUS)] b: R|kotlin/Int| = this@R|/X|.R|/X.b|): R|X|
|
||||
|
||||
}
|
||||
public final [ResolvedTo(BODY_RESOLVE)] fun main([ResolvedTo(BODY_RESOLVE)] x: R|X|): R|kotlin/Unit| {
|
||||
[ResolvedTo(BODY_RESOLVE)] lval <destruct>: R|X| = R|<local>/x|
|
||||
[ResolvedTo(BODY_RESOLVE)] lval <unused var>: R|kotlin/Int| = R|<local>/<destruct>|.R|/X.component1|()
|
||||
[ResolvedTo(BODY_RESOLVE)] lval b: R|kotlin/Int| = R|<local>/<destruct>|.R|/X.component2|()
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
// LOOK_UP_FOR_ELEMENT_OF_TYPE: org.jetbrains.kotlin.psi.KtDestructuringDeclarationEntry
|
||||
|
||||
data class X(val a: Int, val b: Int)
|
||||
|
||||
fun x(action: (X) -> Unit) {}
|
||||
|
||||
fun main() {
|
||||
x { (<expr>_</expr>, b) ->
|
||||
|
||||
}
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
KT element: KtDestructuringDeclarationEntry
|
||||
FIR element: FirPropertyImpl
|
||||
FIR source kind: KtRealSourceElementKind
|
||||
|
||||
FIR element rendered:
|
||||
[ResolvedTo(BODY_RESOLVE)] lval <unused var>: R|kotlin/Int| = R|<local>/<destruct>|.R|/X.component1|()
|
||||
|
||||
FIR FILE:
|
||||
FILE: [ResolvedTo(IMPORTS)] entryUnderscoreInDestructuringDeclarationParameterInLambda.kt
|
||||
public final data [ResolvedTo(STATUS)] class X : R|kotlin/Any| {
|
||||
public [ResolvedTo(STATUS)] [ContainingClassKey=X] constructor([ResolvedTo(STATUS)] [CorrespondingProperty=/X.a] a: R|kotlin/Int|, [ResolvedTo(STATUS)] [CorrespondingProperty=/X.b] b: R|kotlin/Int|): R|X| {
|
||||
LAZY_super<R|kotlin/Any|>
|
||||
}
|
||||
|
||||
public final [ResolvedTo(STATUS)] [ComponentFunctionSymbolKey=/X.component1, IsFromPrimaryConstructor=true] val a: R|kotlin/Int| = R|<local>/a|
|
||||
public [ResolvedTo(STATUS)] [ContainingClassKey=X] get(): R|kotlin/Int|
|
||||
|
||||
public final [ResolvedTo(STATUS)] [ComponentFunctionSymbolKey=/X.component2, IsFromPrimaryConstructor=true] val b: R|kotlin/Int| = R|<local>/b|
|
||||
public [ResolvedTo(STATUS)] [ContainingClassKey=X] get(): R|kotlin/Int|
|
||||
|
||||
public final operator [ResolvedTo(CONTRACTS)] fun component1(): R|kotlin/Int|
|
||||
|
||||
public final operator [ResolvedTo(CONTRACTS)] fun component2(): R|kotlin/Int|
|
||||
|
||||
public final [ResolvedTo(STATUS)] fun copy([ResolvedTo(STATUS)] a: R|kotlin/Int| = this@R|/X|.R|/X.a|, [ResolvedTo(STATUS)] b: R|kotlin/Int| = this@R|/X|.R|/X.b|): R|X|
|
||||
|
||||
}
|
||||
public final [ResolvedTo(CONTRACTS)] fun x([ResolvedTo(CONTRACTS)] action: R|(X) -> kotlin/Unit|): R|kotlin/Unit| {
|
||||
}
|
||||
public final [ResolvedTo(BODY_RESOLVE)] fun main(): R|kotlin/Unit| {
|
||||
R|/x|(<L> = [ResolvedTo(BODY_RESOLVE)] [MatchingParameterFunctionTypeKey=kotlin/Function1<X, kotlin/Unit>] x@fun <anonymous>([ResolvedTo(BODY_RESOLVE)] <destruct>: R|X|): R|kotlin/Unit| <inline=NoInline> {
|
||||
[ResolvedTo(BODY_RESOLVE)] lval <unused var>: R|kotlin/Int| = R|<local>/<destruct>|.R|/X.component1|()
|
||||
[ResolvedTo(BODY_RESOLVE)] lval b: R|kotlin/Int| = R|<local>/<destruct>|.R|/X.component2|()
|
||||
^@x Unit
|
||||
}
|
||||
)
|
||||
}
|
||||
+12
@@ -606,6 +606,18 @@ public class OutOfContentRootGetOrBuildFirTestGenerated extends AbstractOutOfCon
|
||||
public void testEntryInDestructuringDeclarationParameterInLambda() throws Exception {
|
||||
runTest("analysis/low-level-api-fir/testdata/getOrBuildFir/destructuring/entryInDestructuringDeclarationParameterInLambda.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("entryUnderscoreInDestructuringDeclaration.kt")
|
||||
public void testEntryUnderscoreInDestructuringDeclaration() throws Exception {
|
||||
runTest("analysis/low-level-api-fir/testdata/getOrBuildFir/destructuring/entryUnderscoreInDestructuringDeclaration.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("entryUnderscoreInDestructuringDeclarationParameterInLambda.kt")
|
||||
public void testEntryUnderscoreInDestructuringDeclarationParameterInLambda() throws Exception {
|
||||
runTest("analysis/low-level-api-fir/testdata/getOrBuildFir/destructuring/entryUnderscoreInDestructuringDeclarationParameterInLambda.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
|
||||
+12
@@ -606,6 +606,18 @@ public class SourceGetOrBuildFirTestGenerated extends AbstractSourceGetOrBuildFi
|
||||
public void testEntryInDestructuringDeclarationParameterInLambda() throws Exception {
|
||||
runTest("analysis/low-level-api-fir/testdata/getOrBuildFir/destructuring/entryInDestructuringDeclarationParameterInLambda.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("entryUnderscoreInDestructuringDeclaration.kt")
|
||||
public void testEntryUnderscoreInDestructuringDeclaration() throws Exception {
|
||||
runTest("analysis/low-level-api-fir/testdata/getOrBuildFir/destructuring/entryUnderscoreInDestructuringDeclaration.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("entryUnderscoreInDestructuringDeclarationParameterInLambda.kt")
|
||||
public void testEntryUnderscoreInDestructuringDeclarationParameterInLambda() throws Exception {
|
||||
runTest("analysis/low-level-api-fir/testdata/getOrBuildFir/destructuring/entryUnderscoreInDestructuringDeclarationParameterInLambda.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
|
||||
+2
@@ -26,11 +26,13 @@ import org.jetbrains.kotlin.fir.symbols.SymbolInternals
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.name.SpecialNames
|
||||
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
||||
|
||||
object FirDestructuringDeclarationChecker : FirPropertyChecker() {
|
||||
override fun check(declaration: FirProperty, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
val source = declaration.source ?: return
|
||||
if (declaration.name == SpecialNames.UNDERSCORE_FOR_UNUSED_VAR) return
|
||||
// val (...) = `destructuring_declaration`
|
||||
if (source.elementType == KtNodeTypes.DESTRUCTURING_DECLARATION) {
|
||||
checkInitializer(source, declaration.initializer, reporter, context)
|
||||
|
||||
+5
-1
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.isCatchParameter
|
||||
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.FirUserTypeRef
|
||||
import org.jetbrains.kotlin.name.SpecialNames
|
||||
|
||||
object FirReservedUnderscoreDeclarationChecker : FirBasicDeclarationChecker() {
|
||||
override fun check(declaration: FirDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
@@ -55,7 +56,10 @@ object FirReservedUnderscoreDeclarationChecker : FirBasicDeclarationChecker() {
|
||||
isSingleUnderscoreAllowed: Boolean = false
|
||||
) {
|
||||
val declarationSource = declaration.source
|
||||
if (declarationSource != null && declarationSource.kind !is KtFakeSourceElementKind) {
|
||||
if (declarationSource != null &&
|
||||
declarationSource.kind !is KtFakeSourceElementKind &&
|
||||
(declaration as? FirProperty)?.name != SpecialNames.UNDERSCORE_FOR_UNUSED_VAR
|
||||
) {
|
||||
with(SourceNavigator.forElement(declaration)) {
|
||||
val rawName = declaration.getRawName()
|
||||
if (rawName?.isUnderscore == true && !(isSingleUnderscoreAllowed && rawName == "_")) {
|
||||
|
||||
+2
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
|
||||
import org.jetbrains.kotlin.fir.types.coneType
|
||||
import org.jetbrains.kotlin.fir.types.isBasicFunctionType
|
||||
import org.jetbrains.kotlin.name.SpecialNames
|
||||
|
||||
object UnusedChecker : AbstractFirPropertyInitializationChecker() {
|
||||
override fun analyze(data: PropertyInitializationInfoData, reporter: DiagnosticReporter, context: CheckerContext) {
|
||||
@@ -62,6 +63,7 @@ object UnusedChecker : AbstractFirPropertyInitializationChecker() {
|
||||
val variableSymbol = node.fir.symbol
|
||||
if (node.fir.source == null) return
|
||||
if (variableSymbol.isLoopIterator) return
|
||||
if (variableSymbol.name == SpecialNames.UNDERSCORE_FOR_UNUSED_VAR) return
|
||||
val dataPerNode = data[node] ?: return
|
||||
|
||||
val data = dataPerNode.values.mapNotNull { it[variableSymbol] }.reduceOrNull { acc, it -> acc.merge(it) }
|
||||
|
||||
@@ -251,6 +251,9 @@ class Fir2IrVisitor(
|
||||
for (statement in script.statements) {
|
||||
val irStatement = if (statement is FirDeclaration) {
|
||||
when {
|
||||
statement is FirProperty && statement.name == SpecialNames.UNDERSCORE_FOR_UNUSED_VAR -> {
|
||||
continue
|
||||
}
|
||||
statement is FirProperty && statement.origin == FirDeclarationOrigin.ScriptCustomization.ResultProperty -> {
|
||||
// Generating the result property only for expressions with a meaningful result type
|
||||
// otherwise skip the property and convert the expression into the statement
|
||||
@@ -820,6 +823,7 @@ class Fir2IrVisitor(
|
||||
}
|
||||
if (this is FirContractCallBlock) return null
|
||||
if (this is FirBlock) return convertToIrExpression(this)
|
||||
if (this is FirProperty && name == SpecialNames.UNDERSCORE_FOR_UNUSED_VAR) return null
|
||||
return accept(this@Fir2IrVisitor, null) as IrStatement
|
||||
}
|
||||
|
||||
|
||||
+5
-2
@@ -1390,8 +1390,11 @@ class LightTreeRawFirDeclarationBuilder(
|
||||
}
|
||||
}
|
||||
|
||||
if (identifier == "_") return null
|
||||
val name = identifier.nameAsSafeName()
|
||||
val name = if (identifier == "_") {
|
||||
SpecialNames.UNDERSCORE_FOR_UNUSED_VAR
|
||||
} else {
|
||||
identifier.nameAsSafeName()
|
||||
}
|
||||
return buildProperty {
|
||||
source = entry.toFirSourceElement()
|
||||
moduleData = baseModuleData
|
||||
|
||||
+6
-2
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.impl.FirImplicitTypeRefImplWithoutSource
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.name.SpecialNames
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
|
||||
internal fun KtWhenCondition.toFirWhenCondition(
|
||||
@@ -135,9 +136,12 @@ internal fun generateDestructuringBlock(
|
||||
}
|
||||
val isVar = multiDeclaration.isVar
|
||||
for ((index, entry) in multiDeclaration.entries.withIndex()) {
|
||||
if (entry.nameIdentifier?.text == "_") continue
|
||||
val name = if (entry.nameIdentifier?.text == "_") {
|
||||
SpecialNames.UNDERSCORE_FOR_UNUSED_VAR
|
||||
} else {
|
||||
entry.nameAsSafeName
|
||||
}
|
||||
val entrySource = entry.toKtPsiSourceElement()
|
||||
val name = entry.nameAsSafeName
|
||||
statements += buildProperty {
|
||||
source = entrySource
|
||||
this.moduleData = moduleData
|
||||
|
||||
+1
@@ -34,5 +34,6 @@ FILE: destructuring.kt
|
||||
public? final? fun bar(some: Some): R|kotlin/Unit| {
|
||||
lval <destruct>: <implicit> = some#
|
||||
lval a: <implicit> = R|<local>/<destruct>|.component1#()
|
||||
lval <unused var>: <implicit> = R|<local>/<destruct>|.component2#()
|
||||
lval _: <implicit> = R|<local>/<destruct>|.component3#()
|
||||
}
|
||||
|
||||
+1
@@ -48,4 +48,5 @@ FILE: RedeclaredValsAndVars.fir.kt
|
||||
|
||||
lval <destruct>: R|A| = R|/A.A|()
|
||||
lval _: R|kotlin/Int| = R|<local>/<destruct>|.R|/A.component1|()
|
||||
lval <unused var>: R|kotlin/String| = R|<local>/<destruct>|.R|/A.component2|()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user