diff --git a/compiler/fir/analysis-tests/testData/resolve/cast.fir.txt b/compiler/fir/analysis-tests/testData/resolve/cast.fir.txt index bfab229080b..b9d5a5b6fce 100644 --- a/compiler/fir/analysis-tests/testData/resolve/cast.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolve/cast.fir.txt @@ -13,12 +13,12 @@ FILE: cast.kt } public get(): R|() -> kotlin/Unit| - public final val h: R|(kotlin/String) -> kotlin/Boolean| = fun (_: R|kotlin/String|): R|kotlin/Boolean| { + public final val h: R|(kotlin/String) -> kotlin/Boolean| = fun (: R|kotlin/String|): R|kotlin/Boolean| { ^ Boolean(false) } public get(): R|(kotlin/String) -> kotlin/Boolean| - public final val hError: R|(ERROR CLASS: No type for parameter) -> kotlin/Boolean| = fun (_: ): R|kotlin/Boolean| { + public final val hError: R|(ERROR CLASS: No type for parameter) -> kotlin/Boolean| = fun (: ): R|kotlin/Boolean| { ^ Boolean(true) } diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/delegates/delegateTypeMismatch.fir.txt b/compiler/fir/analysis-tests/testData/resolveWithStdlib/delegates/delegateTypeMismatch.fir.txt index c5ad7b1e290..008919b021f 100644 --- a/compiler/fir/analysis-tests/testData/resolveWithStdlib/delegates/delegateTypeMismatch.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/delegates/delegateTypeMismatch.fir.txt @@ -19,7 +19,7 @@ FILE: delegateTypeMismatch.kt public get(): R|kotlin/Boolean| private final fun property(initialValue: R|T|): R|kotlin/properties/ReadWriteProperty| { - ^property Q|kotlin/properties/Delegates|.R|kotlin/properties/Delegates.vetoable|(R|/initialValue|, = vetoable@fun (_: R|@R|kotlin/ParameterName|(name = String(property)) kotlin/reflect/KProperty<*>|, _: R|T|, _: R|T|): R|kotlin/Boolean| { + ^property Q|kotlin/properties/Delegates|.R|kotlin/properties/Delegates.vetoable|(R|/initialValue|, = vetoable@fun (: R|@R|kotlin/ParameterName|(name = String(property)) kotlin/reflect/KProperty<*>|, : R|T|, : R|T|): R|kotlin/Boolean| { ^ when () { this@R|/A|.R|/A.isLocked| -> { throw R|java/lang/IllegalStateException.IllegalStateException|(String(Cannot modify readonly DescriptorRendererOptions)) diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/j+k/MapCompute.fir.txt b/compiler/fir/analysis-tests/testData/resolveWithStdlib/j+k/MapCompute.fir.txt index 7a9f965f799..aa05ac37ed7 100644 --- a/compiler/fir/analysis-tests/testData/resolveWithStdlib/j+k/MapCompute.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/j+k/MapCompute.fir.txt @@ -1,6 +1,6 @@ FILE: MapCompute.kt public final fun R|kotlin/collections/MutableMap>|.initAndAdd(key: R|kotlin/String|, value: R|D|): R|kotlin/Unit| { - this@R|/initAndAdd|.R|SubstitutionOverride?|>|(R|/key|, = compute@fun (_: R|ft|, maybeValues: R|ft, kotlin/collections/MutableSet?>|): R|ft, kotlin/collections/MutableSet?>| { + this@R|/initAndAdd|.R|SubstitutionOverride?|>|(R|/key|, = compute@fun (: R|ft|, maybeValues: R|ft, kotlin/collections/MutableSet?>|): R|ft, kotlin/collections/MutableSet?>| { lval setOfValues: R|kotlin/collections/MutableSet| = R|/maybeValues| ?: R|kotlin/collections/mutableSetOf|() R|/setOfValues|.R|SubstitutionOverride|(R|/value|) ^ R|/setOfValues| diff --git a/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt b/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt index 375ab8403e8..727d215e6e6 100644 --- a/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt +++ b/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt @@ -2009,10 +2009,13 @@ class DeclarationsConverter( /** * @see org.jetbrains.kotlin.parsing.KotlinParsing.parseValueParameterList */ - fun convertValueParameters(valueParameters: LighterASTNode): List { + fun convertValueParameters( + valueParameters: LighterASTNode, + valueParameterDeclaration: ValueParameterDeclaration = ValueParameterDeclaration.OTHER + ): List { return valueParameters.forEachChildrenReturnList { node, container -> when (node.tokenType) { - VALUE_PARAMETER -> container += convertValueParameter(node) + VALUE_PARAMETER -> container += convertValueParameter(node, valueParameterDeclaration) } } } @@ -2020,7 +2023,10 @@ class DeclarationsConverter( /** * @see org.jetbrains.kotlin.parsing.KotlinParsing.parseValueParameter */ - fun convertValueParameter(valueParameter: LighterASTNode): ValueParameter { + fun convertValueParameter( + valueParameter: LighterASTNode, + valueParameterDeclaration: ValueParameterDeclaration = ValueParameterDeclaration.OTHER + ): ValueParameter { var modifiers = Modifier() var isVal = false var isVar = false @@ -2040,7 +2046,7 @@ class DeclarationsConverter( } } - val name = identifier.nameAsSafeName() + val name = convertValueParameterName(identifier.nameAsSafeName(), identifier, valueParameterDeclaration) val firValueParameter = buildValueParameter { source = valueParameter.toFirSourceElement() moduleData = baseModuleData diff --git a/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/ExpressionsConverter.kt b/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/ExpressionsConverter.kt index 786586b0f11..311803b0b9c 100644 --- a/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/ExpressionsConverter.kt +++ b/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/ExpressionsConverter.kt @@ -125,7 +125,7 @@ class ExpressionsConverter( var block: LighterASTNode? = null lambdaExpression.getChildNodesByType(FUNCTION_LITERAL).first().forEachChildren { when (it.tokenType) { - VALUE_PARAMETER_LIST -> valueParameterList += declarationsConverter.convertValueParameters(it) + VALUE_PARAMETER_LIST -> valueParameterList += declarationsConverter.convertValueParameters(it, ValueParameterDeclaration.LAMBDA) BLOCK -> block = it } } @@ -1174,7 +1174,8 @@ class ExpressionsConverter( var blockNode: LighterASTNode? = null catchClause.forEachChildren { when (it.tokenType) { - VALUE_PARAMETER_LIST -> valueParameter = declarationsConverter.convertValueParameters(it).firstOrNull() ?: return null + VALUE_PARAMETER_LIST -> valueParameter = declarationsConverter.convertValueParameters(it, ValueParameterDeclaration.CATCH) + .firstOrNull() ?: return null BLOCK -> blockNode = it } } diff --git a/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt b/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt index 0809802d27a..3be2b208d36 100644 --- a/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt +++ b/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt @@ -32,7 +32,10 @@ import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.builder.* -import org.jetbrains.kotlin.fir.types.impl.* +import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl +import org.jetbrains.kotlin.fir.types.impl.FirQualifierPartImpl +import org.jetbrains.kotlin.fir.types.impl.FirTypeArgumentListImpl +import org.jetbrains.kotlin.fir.types.impl.FirTypePlaceholderProjection import org.jetbrains.kotlin.lexer.KtTokens.* import org.jetbrains.kotlin.name.CallableId import org.jetbrains.kotlin.name.Name @@ -173,8 +176,11 @@ open class RawFirBuilder( ownerRegularClassTypeParametersCount: Int?, ): FirProperty = property.toFirProperty(ownerRegularOrAnonymousObjectSymbol, ownerRegularClassTypeParametersCount) - open fun convertValueParameter(valueParameter: KtParameter, defaultTypeRef: FirTypeRef? = null): FirValueParameter = - valueParameter.toFirValueParameter(defaultTypeRef) + open fun convertValueParameter( + valueParameter: KtParameter, + defaultTypeRef: FirTypeRef? = null, + valueParameterDeclaration: ValueParameterDeclaration = ValueParameterDeclaration.OTHER + ): FirValueParameter = valueParameter.toFirValueParameter(defaultTypeRef, valueParameterDeclaration) private fun KtTypeReference?.toFirOrImplicitType(): FirTypeRef = convertSafe() ?: buildImplicitTypeRef { @@ -444,8 +450,11 @@ open class RawFirBuilder( } } - private fun KtParameter.toFirValueParameter(defaultTypeRef: FirTypeRef? = null): FirValueParameter { - val name = nameAsSafeName + private fun KtParameter.toFirValueParameter( + defaultTypeRef: FirTypeRef? = null, + valueParameterDeclaration: ValueParameterDeclaration = ValueParameterDeclaration.OTHER + ): FirValueParameter { + val name = convertValueParameterName(nameAsSafeName, nameIdentifier?.node?.text, valueParameterDeclaration) return buildValueParameter { source = toFirSourceElement() moduleData = baseModuleData @@ -1248,7 +1257,7 @@ open class RawFirBuilder( val typeRef = valueParameter.typeReference?.convertSafe() ?: buildImplicitTypeRef { source = implicitTypeRefSource } - convertValueParameter(valueParameter, typeRef) + convertValueParameter(valueParameter, typeRef, ValueParameterDeclaration.LAMBDA) } } val expressionSource = expression.toFirSourceElement() @@ -1717,7 +1726,12 @@ open class RawFirBuilder( tryBlock = expression.tryBlock.toFirBlock() finallyBlock = expression.finallyBlock?.finalExpression?.toFirBlock() for (clause in expression.catchClauses) { - val parameter = clause.catchParameter?.let { convertValueParameter(it) } ?: continue + val parameter = clause.catchParameter?.let { + convertValueParameter( + it, + valueParameterDeclaration = ValueParameterDeclaration.CATCH + ) + } ?: continue catches += buildCatch { source = clause.toFirSourceElement() this.parameter = parameter @@ -2376,3 +2390,4 @@ enum class PsiHandlingMode { */ IDE; } + 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 b102fd41bbe..81632f9e62e 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 @@ -7,6 +7,7 @@ package org.jetbrains.kotlin.fir.builder import com.intellij.psi.tree.IElementType import org.jetbrains.kotlin.KtNodeTypes.* +import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.fir.* @@ -35,6 +36,7 @@ import org.jetbrains.kotlin.lexer.KtTokens.OPEN_QUOTE import org.jetbrains.kotlin.name.CallableId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.name.SpecialNames import org.jetbrains.kotlin.parsing.* import org.jetbrains.kotlin.psi.KtPsiUtil import org.jetbrains.kotlin.types.ConstantValueKind @@ -1234,9 +1236,8 @@ abstract class BaseFirBuilder(val baseSession: FirSession, val context: Conte return if (valueParameterDeclaration == ValueParameterDeclaration.LAMBDA && rawName == "_" || valueParameterDeclaration == ValueParameterDeclaration.CATCH && - baseSession.sessionProvider != null && - baseSession.languageVersionSettings.supportsFeature(LanguageFeature.ForbidReferencingToUnderscoreNamedParameterOfCatchBlock) && - safeName.asString() == "_" + safeName.asString() == "_" && + baseSession.safeLanguageVersionSettings?.supportsFeature(LanguageFeature.ForbidReferencingToUnderscoreNamedParameterOfCatchBlock) == true ) { SpecialNames.UNDERSCORE_FOR_UNUSED_VAR } else { @@ -1252,4 +1253,10 @@ abstract class BaseFirBuilder(val baseSession: FirSession, val context: Conte val ITERATOR_NAME = Name.special("") } + + enum class ValueParameterDeclaration { + OTHER, + LAMBDA, + CATCH + } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveContext.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveContext.kt index 15512d5ffae..3b962833ef7 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveContext.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveContext.kt @@ -39,6 +39,7 @@ import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.fir.types.FirImplicitTypeRef import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.name.SpecialNames.UNDERSCORE_FOR_UNUSED_VAR class BodyResolveContext( val returnTypeCalculator: ReturnTypeCalculator, @@ -612,7 +613,9 @@ class BodyResolveContext( valueParameter: FirValueParameter, f: () -> T ): T { - storeVariable(valueParameter) + if (!valueParameter.name.isSpecial || valueParameter.name != UNDERSCORE_FOR_UNUSED_VAR) { + storeVariable(valueParameter) + } return withContainer(valueParameter, f) } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirLanguageSettingsComponent.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirLanguageSettingsComponent.kt similarity index 64% rename from compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirLanguageSettingsComponent.kt rename to compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirLanguageSettingsComponent.kt index 9c4b065526b..bd75455f463 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirLanguageSettingsComponent.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirLanguageSettingsComponent.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2021 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. */ @@ -12,5 +12,10 @@ class FirLanguageSettingsComponent(val languageVersionSettings: LanguageVersionS private val FirSession.languageSettingsComponent: FirLanguageSettingsComponent by FirSession.sessionComponentAccessor() +private val FirSession.safeLanguageSettingsComponent: FirLanguageSettingsComponent? by FirSession.nullableSessionComponentAccessor() + val FirSession.languageVersionSettings: LanguageVersionSettings get() = languageSettingsComponent.languageVersionSettings + +val FirSession.safeLanguageVersionSettings: LanguageVersionSettings? + get() = safeLanguageSettingsComponent?.languageVersionSettings \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/functionLiterals/underscopeParameters.fir.kt b/compiler/testData/diagnostics/tests/functionLiterals/underscopeParameters.fir.kt index 89475115666..40308fbcc76 100644 --- a/compiler/testData/diagnostics/tests/functionLiterals/underscopeParameters.fir.kt +++ b/compiler/testData/diagnostics/tests/functionLiterals/underscopeParameters.fir.kt @@ -5,35 +5,35 @@ fun foobar(block: (Double) -> Unit) { } fun bar() { foo { _, b -> - _.hashCode() + _.hashCode() b checkType { _() } } foo { a, _ -> a checkType { _() } - _.hashCode() + _.hashCode() } foo { _, _ -> - _.hashCode() + _.hashCode() } foo { _: Int, b: String -> - _.hashCode() + _.hashCode() b checkType { _() } } foo { a: Int, _: String -> a checkType { _() } - _.hashCode() + _.hashCode() } foo { _: Int, _: String -> - _.hashCode() + _.hashCode() } foo { `_`, _ -> - _ checkType { _() } + _ checkType { _() } } foo { _, `_` -> diff --git a/compiler/testData/diagnostics/tests/resolve/underscoreInCatchBlock.fir.kt b/compiler/testData/diagnostics/tests/resolve/underscoreInCatchBlock.fir.kt index 6006c50a72c..c8feb1ac302 100644 --- a/compiler/testData/diagnostics/tests/resolve/underscoreInCatchBlock.fir.kt +++ b/compiler/testData/diagnostics/tests/resolve/underscoreInCatchBlock.fir.kt @@ -15,7 +15,7 @@ fun foo() { val x2 = { val x3 = { y: Int -> val x4 = { _: Int -> - `_` + `_` } `_` } @@ -52,7 +52,7 @@ fun foo() { try { TODO() } catch (x: Exception) { - `_`.stackTrace + `_`.stackTrace } } } diff --git a/compiler/testData/diagnostics/tests/resolve/underscoreInCatchBlockWithEnabledFeature.fir.kt b/compiler/testData/diagnostics/tests/resolve/underscoreInCatchBlockWithEnabledFeature.fir.kt index 45d84f8a50d..99b614be4ea 100644 --- a/compiler/testData/diagnostics/tests/resolve/underscoreInCatchBlockWithEnabledFeature.fir.kt +++ b/compiler/testData/diagnostics/tests/resolve/underscoreInCatchBlockWithEnabledFeature.fir.kt @@ -6,7 +6,7 @@ fun foo() { try { TODO() } catch (_: Exception) { - `_`.stackTrace + `_`.stackTrace } try { TODO() @@ -15,22 +15,22 @@ fun foo() { val x2 = { val x3 = { y: Int -> val x4 = { _: Int -> - `_` + `_` } - `_` + `_` } - `_` + `_` 10 } - fun bar(x: Exception = `_`) {} + fun bar(x: Exception = `_`) {} class Bar(`_`: Exception = `_`) { - inner class Bar2(x: Exception = `_`) { } + inner class Bar2(x: Exception = `_`) { } } } } catch (_: Exception) { - `_`.stackTrace - val y1 = _ - val y2 = (`_`) + `_`.stackTrace + val y1 = _ + val y2 = (`_`) } try { TODO() @@ -38,7 +38,7 @@ fun foo() { try { TODO() } catch (x: Exception) { - `_`.stackTrace + `_`.stackTrace } } val boo1 = { `_`: Exception -> @@ -52,7 +52,7 @@ fun foo() { try { TODO() } catch (x: Exception) { - `_`.stackTrace + `_`.stackTrace } } } diff --git a/core/compiler.common/src/org/jetbrains/kotlin/name/SpecialNames.java b/core/compiler.common/src/org/jetbrains/kotlin/name/SpecialNames.java index 7336b7f7ac4..31f7a3060bd 100644 --- a/core/compiler.common/src/org/jetbrains/kotlin/name/SpecialNames.java +++ b/core/compiler.common/src/org/jetbrains/kotlin/name/SpecialNames.java @@ -22,6 +22,7 @@ import org.jetbrains.annotations.Nullable; public class SpecialNames { public static final Name NO_NAME_PROVIDED = Name.special(""); public static final Name ROOT_PACKAGE = Name.special(""); + public static final Name UNDERSCORE_FOR_UNUSED_VAR = Name.special(""); public static final Name DEFAULT_NAME_FOR_COMPANION_OBJECT = Name.identifier("Companion"); diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/lazy/resolve/RawFirNonLocalDeclarationBuilder.kt b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/lazy/resolve/RawFirNonLocalDeclarationBuilder.kt index 97f1b41f51c..2f5460927c8 100644 --- a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/lazy/resolve/RawFirNonLocalDeclarationBuilder.kt +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/lazy/resolve/RawFirNonLocalDeclarationBuilder.kt @@ -95,12 +95,17 @@ internal class RawFirNonLocalDeclarationBuilder private constructor( ) } - override fun convertValueParameter(valueParameter: KtParameter, defaultTypeRef: FirTypeRef?): FirValueParameter { + override fun convertValueParameter( + valueParameter: KtParameter, + defaultTypeRef: FirTypeRef?, + valueParameterDeclaration: ValueParameterDeclaration + ): FirValueParameter { val replacementParameter = replacementApplier?.tryReplace(valueParameter) ?: valueParameter check(replacementParameter is KtParameter) return super.convertValueParameter( valueParameter = replacementParameter, - defaultTypeRef = defaultTypeRef + defaultTypeRef = defaultTypeRef, + valueParameterDeclaration = valueParameterDeclaration ) } }