[FIR] Split primary constructor parameter scope into two different
In init block or property initializers, for `val x` declared in primary constructor, `x` reference is now resolved to property, not to parameter. So we need two different scopes for primary constructor, one for 'pure' parameters and another one for all parameters, including val/var ones. #KT-42844 Fixed
This commit is contained in:
+3
-3
@@ -20,11 +20,11 @@ FILE: RedundantSingleExpressionStringTemplateChecker.kt
|
|||||||
public get(): R|ProductGroup?|
|
public get(): R|ProductGroup?|
|
||||||
|
|
||||||
public final val name: R|kotlin/String| = when () {
|
public final val name: R|kotlin/String| = when () {
|
||||||
==(R|<local>/parent|, Null(null)) -> {
|
==(this@R|/ProductGroup|.R|/ProductGroup.parent|, Null(null)) -> {
|
||||||
R|<local>/short_name|
|
this@R|/ProductGroup|.R|/ProductGroup.short_name|
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
<strcat>(R|<local>/parent|.R|/ProductGroup.name|.R|kotlin/Any.toString|(), String( ), R|<local>/short_name|.R|kotlin/Any.toString|())
|
<strcat>(this@R|/ProductGroup|.R|/ProductGroup.parent|.R|/ProductGroup.name|.R|kotlin/Any.toString|(), String( ), this@R|/ProductGroup|.R|/ProductGroup.short_name|.R|kotlin/Any.toString|())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Vendored
+5
-5
@@ -47,7 +47,7 @@ FILE: propertyTypeMismatchOnOverride.kt
|
|||||||
public final val value: R|T| = R|<local>/value|
|
public final val value: R|T| = R|<local>/value|
|
||||||
public get(): R|T|
|
public get(): R|T|
|
||||||
|
|
||||||
public final override var test: R|T| = R|<local>/value|
|
public final override var test: R|T| = this@R|/E|.R|/E.value|
|
||||||
public get(): R|T|
|
public get(): R|T|
|
||||||
public set(value: R|T|): R|kotlin/Unit|
|
public set(value: R|T|): R|kotlin/Unit|
|
||||||
|
|
||||||
@@ -60,7 +60,7 @@ FILE: propertyTypeMismatchOnOverride.kt
|
|||||||
public final val value: R|T| = R|<local>/value|
|
public final val value: R|T| = R|<local>/value|
|
||||||
public get(): R|T|
|
public get(): R|T|
|
||||||
|
|
||||||
public open var rest: R|T| = R|<local>/value|
|
public open var rest: R|T| = this@R|/F|.R|/F.value|
|
||||||
public get(): R|T|
|
public get(): R|T|
|
||||||
public set(value: R|T|): R|kotlin/Unit|
|
public set(value: R|T|): R|kotlin/Unit|
|
||||||
|
|
||||||
@@ -73,7 +73,7 @@ FILE: propertyTypeMismatchOnOverride.kt
|
|||||||
public final val balue: R|E| = R|<local>/balue|
|
public final val balue: R|E| = R|<local>/balue|
|
||||||
public get(): R|E|
|
public get(): R|E|
|
||||||
|
|
||||||
public final override var rest: R|E| = R|<local>/balue|
|
public final override var rest: R|E| = this@R|/G|.R|/G.balue|
|
||||||
public get(): R|E|
|
public get(): R|E|
|
||||||
public set(value: R|E|): R|kotlin/Unit|
|
public set(value: R|E|): R|kotlin/Unit|
|
||||||
|
|
||||||
@@ -86,7 +86,7 @@ FILE: propertyTypeMismatchOnOverride.kt
|
|||||||
public final val balue: R|E| = R|<local>/balue|
|
public final val balue: R|E| = R|<local>/balue|
|
||||||
public get(): R|E|
|
public get(): R|E|
|
||||||
|
|
||||||
public final override var rest: R|E| = R|<local>/balue|
|
public final override var rest: R|E| = this@R|/H|.R|/H.balue|
|
||||||
public get(): R|E|
|
public get(): R|E|
|
||||||
public set(value: R|E|): R|kotlin/Unit|
|
public set(value: R|E|): R|kotlin/Unit|
|
||||||
|
|
||||||
@@ -99,7 +99,7 @@ FILE: propertyTypeMismatchOnOverride.kt
|
|||||||
public final val balue: R|E| = R|<local>/balue|
|
public final val balue: R|E| = R|<local>/balue|
|
||||||
public get(): R|E|
|
public get(): R|E|
|
||||||
|
|
||||||
public final override var rest: R|E| = R|<local>/balue|
|
public final override var rest: R|E| = this@R|/M|.R|/M.balue|
|
||||||
public get(): R|E|
|
public get(): R|E|
|
||||||
public set(value: R|E|): R|kotlin/Unit|
|
public set(value: R|E|): R|kotlin/Unit|
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -47,7 +47,7 @@ FILE: repeatedModifier.kt
|
|||||||
private final val int: R|kotlin/Int| = R|<local>/int|
|
private final val int: R|kotlin/Int| = R|<local>/int|
|
||||||
private get(): R|kotlin/Int|
|
private get(): R|kotlin/Int|
|
||||||
|
|
||||||
protected final var double: R|kotlin/Double| = R|<local>/int|.R|kotlin/Int.plus|(Double(8.0))
|
protected final var double: R|kotlin/Double| = this@R|/E|.R|/E.int|.R|kotlin/Int.plus|(Double(8.0))
|
||||||
protected get(): R|kotlin/Double|
|
protected get(): R|kotlin/Double|
|
||||||
protected set(value: R|kotlin/Double|): R|kotlin/Unit|
|
protected set(value: R|kotlin/Double|): R|kotlin/Unit|
|
||||||
|
|
||||||
|
|||||||
Vendored
+1
-1
@@ -29,7 +29,7 @@ FILE: CallBasedInExpressionGenerator.kt
|
|||||||
public final val codegen: R|org/jetbrains/kotlin/codegen/range/inExpression/ExpressionCodegen| = R|<local>/codegen|
|
public final val codegen: R|org/jetbrains/kotlin/codegen/range/inExpression/ExpressionCodegen| = R|<local>/codegen|
|
||||||
public get(): R|org/jetbrains/kotlin/codegen/range/inExpression/ExpressionCodegen|
|
public get(): R|org/jetbrains/kotlin/codegen/range/inExpression/ExpressionCodegen|
|
||||||
|
|
||||||
private final val resolvedCall: R|ERROR CLASS: Unresolved name: getResolvedCallWithAssert| = R|<local>/operatorReference|.<Unresolved name: getResolvedCallWithAssert>#(R|<local>/codegen|.<Unresolved name: bindingContext>#)
|
private final val resolvedCall: R|ERROR CLASS: Unresolved name: getResolvedCallWithAssert| = R|<local>/operatorReference|.<Unresolved name: getResolvedCallWithAssert>#(this@R|org/jetbrains/kotlin/codegen/range/inExpression/CallBasedInExpressionGenerator|.R|org/jetbrains/kotlin/codegen/range/inExpression/CallBasedInExpressionGenerator.codegen|.<Unresolved name: bindingContext>#)
|
||||||
private get(): R|ERROR CLASS: Unresolved name: getResolvedCallWithAssert|
|
private get(): R|ERROR CLASS: Unresolved name: getResolvedCallWithAssert|
|
||||||
|
|
||||||
private final val isInverted: R|kotlin/Boolean| = ==(R|<local>/operatorReference|.<Unresolved name: getReferencedNameElementType>#(), <Unresolved name: KtTokens>#.<Unresolved name: NOT_IN>#)
|
private final val isInverted: R|kotlin/Boolean| = ==(R|<local>/operatorReference|.<Unresolved name: getReferencedNameElementType>#(), <Unresolved name: KtTokens>#.<Unresolved name: NOT_IN>#)
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ FILE: enums.kt
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public final val g: R|kotlin/Double| = this@R|/Planet.Companion|.R|/Planet.Companion.G|.R|kotlin/Double.times|(R|<local>/m|).R|kotlin/Double.div|(R|<local>/r|.R|kotlin/Double.times|(R|<local>/r|))
|
public final val g: R|kotlin/Double| = this@R|/Planet.Companion|.R|/Planet.Companion.G|.R|kotlin/Double.times|(this@R|/Planet|.R|/Planet.m|).R|kotlin/Double.div|(this@R|/Planet|.R|/Planet.r|.R|kotlin/Double.times|(this@R|/Planet|.R|/Planet.r|))
|
||||||
public get(): R|kotlin/Double|
|
public get(): R|kotlin/Double|
|
||||||
|
|
||||||
public abstract fun sayHello(): R|kotlin/Unit|
|
public abstract fun sayHello(): R|kotlin/Unit|
|
||||||
|
|||||||
+4
-4
@@ -46,9 +46,9 @@ FILE: KotlinClass.kt
|
|||||||
public get(): R|JavaClass?|
|
public get(): R|JavaClass?|
|
||||||
|
|
||||||
public final val x: R|(KotlinClass) -> kotlin/Boolean| = when () {
|
public final val x: R|(KotlinClass) -> kotlin/Boolean| = when () {
|
||||||
!=(R|<local>/javaClass|, Null(null)) -> {
|
!=(this@R|/Case1|.R|/Case1.javaClass|, Null(null)) -> {
|
||||||
fun <anonymous>(it: R|KotlinClass|): R|kotlin/Boolean| {
|
fun <anonymous>(it: R|KotlinClass|): R|kotlin/Boolean| {
|
||||||
^ ==(R|<local>/it|, R|<local>/javaClass|)
|
^ ==(R|<local>/it|, this@R|/Case1|.R|/Case1.javaClass|)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -139,9 +139,9 @@ FILE: KotlinClass.kt
|
|||||||
public get(): R|KotlinClass?|
|
public get(): R|KotlinClass?|
|
||||||
|
|
||||||
public final val x: R|(KotlinClass) -> kotlin/Boolean| = when () {
|
public final val x: R|(KotlinClass) -> kotlin/Boolean| = when () {
|
||||||
!=(R|<local>/kotlinClass|, Null(null)) -> {
|
!=(this@R|/Case2|.R|/Case2.kotlinClass|, Null(null)) -> {
|
||||||
fun <anonymous>(it: R|KotlinClass|): R|kotlin/Boolean| {
|
fun <anonymous>(it: R|KotlinClass|): R|kotlin/Boolean| {
|
||||||
^ ==(R|<local>/it|, R|<local>/kotlinClass|)
|
^ ==(R|<local>/it|, this@R|/Case2|.R|/Case2.kotlinClass|)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -7,7 +7,7 @@ FILE: simpleDelegatedToMap.kt
|
|||||||
public final val map: R|kotlin/collections/MutableMap<kotlin/String, kotlin/Any>| = R|<local>/map|
|
public final val map: R|kotlin/collections/MutableMap<kotlin/String, kotlin/Any>| = R|<local>/map|
|
||||||
public get(): R|kotlin/collections/MutableMap<kotlin/String, kotlin/Any>|
|
public get(): R|kotlin/collections/MutableMap<kotlin/String, kotlin/Any>|
|
||||||
|
|
||||||
public final var foo: R|kotlin/Any|by R|<local>/map|
|
public final var foo: R|kotlin/Any|by this@R|/C|.R|/C.map|
|
||||||
public get(): R|kotlin/Any| {
|
public get(): R|kotlin/Any| {
|
||||||
^ this@R|/C|.D|/C.foo|.R|kotlin/collections/getValue|<R|kotlin/Any|, R|kotlin/Any|>(this@R|/C|, ::R|/C.foo|)
|
^ this@R|/C|.D|/C.foo|.R|kotlin/collections/getValue|<R|kotlin/Any|, R|kotlin/Any|>(this@R|/C|, ::R|/C.foo|)
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+16
@@ -0,0 +1,16 @@
|
|||||||
|
class Some(var foo: Int) {
|
||||||
|
init {
|
||||||
|
if (foo < 0) {
|
||||||
|
foo = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val y = run {
|
||||||
|
foo = 1
|
||||||
|
foo
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(): this(-1) {
|
||||||
|
foo = 2
|
||||||
|
}
|
||||||
|
}
|
||||||
Vendored
+32
@@ -0,0 +1,32 @@
|
|||||||
|
FILE: constructorVarWrite.kt
|
||||||
|
public final class Some : R|kotlin/Any| {
|
||||||
|
public constructor(foo: R|kotlin/Int|): R|Some| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
public final var foo: R|kotlin/Int| = R|<local>/foo|
|
||||||
|
public get(): R|kotlin/Int|
|
||||||
|
public set(value: R|kotlin/Int|): R|kotlin/Unit|
|
||||||
|
|
||||||
|
init {
|
||||||
|
when () {
|
||||||
|
CMP(<, this@R|/Some|.R|/Some.foo|.R|kotlin/Int.compareTo|(Int(0))) -> {
|
||||||
|
this@R|/Some|.R|/Some.foo| = Int(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public final val y: R|kotlin/Int| = this@R|/Some|.R|kotlin/run|<R|Some|, R|kotlin/Int|>(<L> = run@fun R|Some|.<anonymous>(): R|kotlin/Int| <kind=EXACTLY_ONCE> {
|
||||||
|
this@R|special/anonymous|.R|/Some.foo| = Int(1)
|
||||||
|
^ this@R|special/anonymous|.R|/Some.foo|
|
||||||
|
}
|
||||||
|
)
|
||||||
|
public get(): R|kotlin/Int|
|
||||||
|
|
||||||
|
public constructor(): R|Some| {
|
||||||
|
this<R|Some|>(Int(-1))
|
||||||
|
this@R|/Some|.R|/Some.foo| = Int(2)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+18
@@ -1235,6 +1235,24 @@ public class FirDiagnosticsWithStdlibTestGenerated extends AbstractFirDiagnostic
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/fir/analysis-tests/testData/resolveWithStdlib/reinitializations")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class Reinitializations extends AbstractFirDiagnosticsWithStdlibTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInReinitializations() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolveWithStdlib/reinitializations"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("constructorVarWrite.kt")
|
||||||
|
public void testConstructorVarWrite() throws Exception {
|
||||||
|
runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/reinitializations/constructorVarWrite.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/fir/analysis-tests/testData/resolveWithStdlib/smartcasts")
|
@TestMetadata("compiler/fir/analysis-tests/testData/resolveWithStdlib/smartcasts")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
|||||||
+5
@@ -1811,6 +1811,11 @@ public class Fir2IrTextTestGenerated extends AbstractFir2IrTextTest {
|
|||||||
public void testV8ArrayToList() throws Exception {
|
public void testV8ArrayToList() throws Exception {
|
||||||
runTest("compiler/testData/ir/irText/firProblems/V8ArrayToList.kt");
|
runTest("compiler/testData/ir/irText/firProblems/V8ArrayToList.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("VarInInit.kt")
|
||||||
|
public void testVarInInit() throws Exception {
|
||||||
|
runTest("compiler/testData/ir/irText/firProblems/VarInInit.kt");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/ir/irText/lambdas")
|
@TestMetadata("compiler/testData/ir/irText/lambdas")
|
||||||
|
|||||||
+7
-4
@@ -5,9 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.lightTree.fir
|
package org.jetbrains.kotlin.fir.lightTree.fir
|
||||||
|
|
||||||
import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
|
import org.jetbrains.kotlin.fir.*
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
|
||||||
import org.jetbrains.kotlin.fir.copyWithNewSourceKind
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
|
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirProperty
|
import org.jetbrains.kotlin.fir.declarations.FirProperty
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
||||||
@@ -45,7 +43,12 @@ class ValueParameter(
|
|||||||
}
|
}
|
||||||
|
|
||||||
return buildProperty {
|
return buildProperty {
|
||||||
source = firValueParameter.source
|
val parameterSource = firValueParameter.source as? FirLightSourceElement
|
||||||
|
val parameterNode = parameterSource?.lightNode
|
||||||
|
source = parameterNode?.toFirLightSourceElement(
|
||||||
|
parameterSource.startOffset, parameterSource.endOffset, parameterSource.tree,
|
||||||
|
FirFakeSourceElementKind.PropertyFromParameter
|
||||||
|
)
|
||||||
this.session = session
|
this.session = session
|
||||||
origin = FirDeclarationOrigin.Source
|
origin = FirDeclarationOrigin.Source
|
||||||
returnTypeRef = type.copyWithNewSourceKind(FirFakeSourceElementKind.PropertyFromParameter)
|
returnTypeRef = type.copyWithNewSourceKind(FirFakeSourceElementKind.PropertyFromParameter)
|
||||||
|
|||||||
@@ -143,7 +143,8 @@ typealias TowerDataContextForAnonymousFunctions = Map<FirAnonymousFunctionSymbol
|
|||||||
class FirTowerDataContextsForClassParts(
|
class FirTowerDataContextsForClassParts(
|
||||||
val forNestedClasses: FirTowerDataContext,
|
val forNestedClasses: FirTowerDataContext,
|
||||||
val forConstructorHeaders: FirTowerDataContext,
|
val forConstructorHeaders: FirTowerDataContext,
|
||||||
val primaryConstructorParametersScope: FirLocalScope?,
|
val primaryConstructorPureParametersScope: FirLocalScope?,
|
||||||
|
val primaryConstructorAllParametersScope: FirLocalScope?,
|
||||||
)
|
)
|
||||||
|
|
||||||
// --------------------------------------- Utils ---------------------------------------
|
// --------------------------------------- Utils ---------------------------------------
|
||||||
|
|||||||
+5
-2
@@ -85,8 +85,11 @@ class BodyResolveContext(
|
|||||||
fun getTowerDataContextForConstructorResolution(): FirTowerDataContext =
|
fun getTowerDataContextForConstructorResolution(): FirTowerDataContext =
|
||||||
firTowerDataContextsForClassParts().forConstructorHeaders
|
firTowerDataContextsForClassParts().forConstructorHeaders
|
||||||
|
|
||||||
fun getPrimaryConstructorParametersScope(): FirLocalScope? =
|
fun getPrimaryConstructorPureParametersScope(): FirLocalScope? =
|
||||||
towerDataContextsForClassParts?.primaryConstructorParametersScope
|
towerDataContextsForClassParts?.primaryConstructorPureParametersScope
|
||||||
|
|
||||||
|
fun getPrimaryConstructorAllParametersScope(): FirLocalScope? =
|
||||||
|
towerDataContextsForClassParts?.primaryConstructorAllParametersScope
|
||||||
|
|
||||||
private fun firTowerDataContextsForClassParts() =
|
private fun firTowerDataContextsForClassParts() =
|
||||||
towerDataContextsForClassParts.sure { "towerDataContextForStaticNestedClasses should not be null" }
|
towerDataContextsForClassParts.sure { "towerDataContextForStaticNestedClasses should not be null" }
|
||||||
|
|||||||
+30
-8
@@ -121,13 +121,14 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
|
|||||||
dataFlowAnalyzer.enterProperty(property)
|
dataFlowAnalyzer.enterProperty(property)
|
||||||
withFullBodyResolve {
|
withFullBodyResolve {
|
||||||
withLocalScopeCleanup {
|
withLocalScopeCleanup {
|
||||||
|
val primaryConstructorParametersScope = context.getPrimaryConstructorPureParametersScope()
|
||||||
context.withContainer(property) {
|
context.withContainer(property) {
|
||||||
if (property.delegate != null) {
|
if (property.delegate != null) {
|
||||||
addLocalScope(context.getPrimaryConstructorParametersScope())
|
addLocalScope(primaryConstructorParametersScope)
|
||||||
transformPropertyWithDelegate(property)
|
transformPropertyWithDelegate(property)
|
||||||
} else {
|
} else {
|
||||||
withLocalScopeCleanup {
|
withLocalScopeCleanup {
|
||||||
addLocalScope(context.getPrimaryConstructorParametersScope())
|
addLocalScope(primaryConstructorParametersScope)
|
||||||
property.transformChildrenWithoutAccessors(returnTypeRef)
|
property.transformChildrenWithoutAccessors(returnTypeRef)
|
||||||
}
|
}
|
||||||
if (property.initializer != null) {
|
if (property.initializer != null) {
|
||||||
@@ -577,7 +578,7 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
|
|||||||
}
|
}
|
||||||
|
|
||||||
val scopeWithValueParameters = if (constructor.isPrimary) {
|
val scopeWithValueParameters = if (constructor.isPrimary) {
|
||||||
context.getPrimaryConstructorParametersScope()
|
context.getPrimaryConstructorAllParametersScope()
|
||||||
} else {
|
} else {
|
||||||
constructor.scopeWithParameters()
|
constructor.scopeWithParameters()
|
||||||
}
|
}
|
||||||
@@ -624,7 +625,9 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
|
|||||||
if (implicitTypeOnly) return anonymousInitializer.compose()
|
if (implicitTypeOnly) return anonymousInitializer.compose()
|
||||||
return withLocalScopeCleanup {
|
return withLocalScopeCleanup {
|
||||||
dataFlowAnalyzer.enterInitBlock(anonymousInitializer)
|
dataFlowAnalyzer.enterInitBlock(anonymousInitializer)
|
||||||
addLocalScope(context.getPrimaryConstructorParametersScope())
|
addLocalScope(
|
||||||
|
context.getPrimaryConstructorPureParametersScope()
|
||||||
|
)
|
||||||
addNewLocalScope()
|
addNewLocalScope()
|
||||||
val result =
|
val result =
|
||||||
transformDeclarationContent(anonymousInitializer, ResolutionMode.ContextIndependent).single as FirAnonymousInitializer
|
transformDeclarationContent(anonymousInitializer, ResolutionMode.ContextIndependent).single as FirAnonymousInitializer
|
||||||
@@ -841,17 +844,20 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
|
|||||||
staticsAndCompanion
|
staticsAndCompanion
|
||||||
|
|
||||||
val constructor = (owner as? FirRegularClass)?.declarations?.firstOrNull { it is FirConstructor } as? FirConstructor
|
val constructor = (owner as? FirRegularClass)?.declarations?.firstOrNull { it is FirConstructor } as? FirConstructor
|
||||||
val primaryConstructorParametersScope =
|
val (primaryConstructorPureParametersScope, primaryConstructorAllParametersScope) =
|
||||||
if (constructor?.isPrimary == true) {
|
if (constructor?.isPrimary == true) {
|
||||||
constructor.scopeWithParameters()
|
constructor.scopesWithPrimaryConstructorParameters(owner)
|
||||||
} else null
|
} else {
|
||||||
|
null to null
|
||||||
|
}
|
||||||
|
|
||||||
components.context.replaceTowerDataContext(forMembersResolution)
|
components.context.replaceTowerDataContext(forMembersResolution)
|
||||||
|
|
||||||
val newContexts = FirTowerDataContextsForClassParts(
|
val newContexts = FirTowerDataContextsForClassParts(
|
||||||
newTowerDataContextForStaticNestedClasses,
|
newTowerDataContextForStaticNestedClasses,
|
||||||
scopeForConstructorHeader,
|
scopeForConstructorHeader,
|
||||||
primaryConstructorParametersScope
|
primaryConstructorPureParametersScope,
|
||||||
|
primaryConstructorAllParametersScope
|
||||||
)
|
)
|
||||||
|
|
||||||
context.withNewTowerDataForClassParts(newContexts) {
|
context.withNewTowerDataForClassParts(newContexts) {
|
||||||
@@ -863,6 +869,22 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
|
|||||||
return valueParameters.fold(FirLocalScope()) { acc, param -> acc.storeVariable(param) }
|
return valueParameters.fold(FirLocalScope()) { acc, param -> acc.storeVariable(param) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun FirConstructor.scopesWithPrimaryConstructorParameters(
|
||||||
|
ownerClass: FirClass<*>
|
||||||
|
): Pair<FirLocalScope, FirLocalScope> {
|
||||||
|
var parameterScope = FirLocalScope()
|
||||||
|
var allScope = FirLocalScope()
|
||||||
|
val properties = ownerClass.declarations.filterIsInstance<FirProperty>().associateBy { it.name }
|
||||||
|
for (parameter in valueParameters) {
|
||||||
|
allScope = allScope.storeVariable(parameter)
|
||||||
|
val property = properties[parameter.name]
|
||||||
|
if (property?.source?.kind != FirFakeSourceElementKind.PropertyFromParameter) {
|
||||||
|
parameterScope = parameterScope.storeVariable(parameter)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return parameterScope to allScope
|
||||||
|
}
|
||||||
|
|
||||||
protected inline fun <T> withLabelAndReceiverType(
|
protected inline fun <T> withLabelAndReceiverType(
|
||||||
labelName: Name?,
|
labelName: Name?,
|
||||||
owner: FirCallableDeclaration<*>,
|
owner: FirCallableDeclaration<*>,
|
||||||
|
|||||||
+1
-1
@@ -760,7 +760,7 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
|
|||||||
context.withTowerDataCleanup {
|
context.withTowerDataCleanup {
|
||||||
if ((context.containerIfAny as? FirConstructor)?.isPrimary == true) {
|
if ((context.containerIfAny as? FirConstructor)?.isPrimary == true) {
|
||||||
context.replaceTowerDataContext(context.getTowerDataContextForConstructorResolution())
|
context.replaceTowerDataContext(context.getTowerDataContextForConstructorResolution())
|
||||||
context.getPrimaryConstructorParametersScope()?.let(context::addLocalScope)
|
context.getPrimaryConstructorAllParametersScope()?.let(context::addLocalScope)
|
||||||
}
|
}
|
||||||
|
|
||||||
// it's just a constructor parameters scope created in
|
// it's just a constructor parameters scope created in
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ sealed class My(open val x: Int?) {
|
|||||||
init {
|
init {
|
||||||
if (x != null) {
|
if (x != null) {
|
||||||
// Should be error: property is open
|
// Should be error: property is open
|
||||||
x.hashCode()
|
x.<!INAPPLICABLE_CANDIDATE!>hashCode<!>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3,15 +3,15 @@ class Foo(var x: Int?) {
|
|||||||
if (x != null) {
|
if (x != null) {
|
||||||
val y = x
|
val y = x
|
||||||
// Error: x is not stable, Type(y) = Int?
|
// Error: x is not stable, Type(y) = Int?
|
||||||
x.hashCode()
|
x.<!INAPPLICABLE_CANDIDATE!>hashCode<!>()
|
||||||
y.hashCode()
|
y.<!INAPPLICABLE_CANDIDATE!>hashCode<!>()
|
||||||
if (y == x) {
|
if (y == x) {
|
||||||
// Still error
|
// Still error
|
||||||
y.hashCode()
|
y.<!INAPPLICABLE_CANDIDATE!>hashCode<!>()
|
||||||
}
|
}
|
||||||
if (x == null && y != x) {
|
if (x == null && y != x) {
|
||||||
// Still error
|
// Still error
|
||||||
y.hashCode()
|
y.<!INAPPLICABLE_CANDIDATE!>hashCode<!>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-4
@@ -7,15 +7,15 @@ class Foo(var x: Any) {
|
|||||||
if (x is Bar) {
|
if (x is Bar) {
|
||||||
val y = x
|
val y = x
|
||||||
// Error: x is not stable, Type(y) = Any
|
// Error: x is not stable, Type(y) = Any
|
||||||
x.bar()
|
x.<!UNRESOLVED_REFERENCE!>bar<!>()
|
||||||
y.bar()
|
y.<!UNRESOLVED_REFERENCE!>bar<!>()
|
||||||
if (y == x) {
|
if (y == x) {
|
||||||
// Still error
|
// Still error
|
||||||
y.bar()
|
y.<!UNRESOLVED_REFERENCE!>bar<!>()
|
||||||
}
|
}
|
||||||
if (x !is Bar && y != x) {
|
if (x !is Bar && y != x) {
|
||||||
// Still error
|
// Still error
|
||||||
y.bar()
|
y.<!UNRESOLVED_REFERENCE!>bar<!>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,7 +60,8 @@ FILE fqName:<root> fileName:/delegatedProperties.kt
|
|||||||
PROPERTY name:test3 visibility:public modality:FINAL [delegated,var]
|
PROPERTY name:test3 visibility:public modality:FINAL [delegated,var]
|
||||||
FIELD PROPERTY_DELEGATE name:test3$delegate type:kotlin.collections.MutableMap<kotlin.String, kotlin.Any> visibility:private [final]
|
FIELD PROPERTY_DELEGATE name:test3$delegate type:kotlin.collections.MutableMap<kotlin.String, kotlin.Any> visibility:private [final]
|
||||||
EXPRESSION_BODY
|
EXPRESSION_BODY
|
||||||
GET_VAR 'map: kotlin.collections.MutableMap<kotlin.String, kotlin.Any> declared in <root>.C.<init>' type=kotlin.collections.MutableMap<kotlin.String, kotlin.Any> origin=null
|
CALL 'public final fun <get-map> (): kotlin.collections.MutableMap<kotlin.String, kotlin.Any> declared in <root>.C' type=kotlin.collections.MutableMap<kotlin.String, kotlin.Any> origin=GET_PROPERTY
|
||||||
|
$this: GET_VAR '<this>: <root>.C declared in <root>.C' type=<root>.C origin=null
|
||||||
FUN DELEGATED_PROPERTY_ACCESSOR name:<get-test3> visibility:public modality:FINAL <> ($this:<root>.C) returnType:kotlin.Any
|
FUN DELEGATED_PROPERTY_ACCESSOR name:<get-test3> visibility:public modality:FINAL <> ($this:<root>.C) returnType:kotlin.Any
|
||||||
correspondingProperty: PROPERTY name:test3 visibility:public modality:FINAL [delegated,var]
|
correspondingProperty: PROPERTY name:test3 visibility:public modality:FINAL [delegated,var]
|
||||||
$this: VALUE_PARAMETER name:<this> type:<root>.C
|
$this: VALUE_PARAMETER name:<this> type:<root>.C
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
|
class Some(var foo: Int) {
|
||||||
|
init {
|
||||||
|
if (foo < 0) {
|
||||||
|
foo = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
FILE fqName:<root> fileName:/VarInInit.kt
|
||||||
|
CLASS CLASS name:Some modality:FINAL visibility:public superTypes:[kotlin.Any]
|
||||||
|
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.Some
|
||||||
|
CONSTRUCTOR visibility:public <> (foo:kotlin.Int) returnType:<root>.Some [primary]
|
||||||
|
VALUE_PARAMETER name:foo index:0 type:kotlin.Int
|
||||||
|
BLOCK_BODY
|
||||||
|
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in kotlin.Any'
|
||||||
|
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:Some modality:FINAL visibility:public superTypes:[kotlin.Any]'
|
||||||
|
PROPERTY name:foo visibility:public modality:FINAL [var]
|
||||||
|
FIELD PROPERTY_BACKING_FIELD name:foo type:kotlin.Int visibility:private
|
||||||
|
EXPRESSION_BODY
|
||||||
|
GET_VAR 'foo: kotlin.Int declared in <root>.Some.<init>' type=kotlin.Int origin=INITIALIZE_PROPERTY_FROM_PARAMETER
|
||||||
|
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-foo> visibility:public modality:FINAL <> ($this:<root>.Some) returnType:kotlin.Int
|
||||||
|
correspondingProperty: PROPERTY name:foo visibility:public modality:FINAL [var]
|
||||||
|
$this: VALUE_PARAMETER name:<this> type:<root>.Some
|
||||||
|
BLOCK_BODY
|
||||||
|
RETURN type=kotlin.Nothing from='public final fun <get-foo> (): kotlin.Int declared in <root>.Some'
|
||||||
|
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:foo type:kotlin.Int visibility:private' type=kotlin.Int origin=null
|
||||||
|
receiver: GET_VAR '<this>: <root>.Some declared in <root>.Some.<get-foo>' type=<root>.Some origin=null
|
||||||
|
FUN DEFAULT_PROPERTY_ACCESSOR name:<set-foo> visibility:public modality:FINAL <> ($this:<root>.Some, <set-?>:kotlin.Int) returnType:kotlin.Unit
|
||||||
|
correspondingProperty: PROPERTY name:foo visibility:public modality:FINAL [var]
|
||||||
|
$this: VALUE_PARAMETER name:<this> type:<root>.Some
|
||||||
|
VALUE_PARAMETER name:<set-?> index:0 type:kotlin.Int
|
||||||
|
BLOCK_BODY
|
||||||
|
SET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:foo type:kotlin.Int visibility:private' type=kotlin.Unit origin=null
|
||||||
|
receiver: GET_VAR '<this>: <root>.Some declared in <root>.Some.<set-foo>' type=<root>.Some origin=null
|
||||||
|
value: GET_VAR '<set-?>: kotlin.Int declared in <root>.Some.<set-foo>' type=kotlin.Int origin=null
|
||||||
|
ANONYMOUS_INITIALIZER isStatic=false
|
||||||
|
BLOCK_BODY
|
||||||
|
WHEN type=kotlin.Unit origin=IF
|
||||||
|
BRANCH
|
||||||
|
if: CALL 'public final fun less (arg0: kotlin.Int, arg1: kotlin.Int): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=LT
|
||||||
|
arg0: CALL 'public final fun <get-foo> (): kotlin.Int declared in <root>.Some' type=kotlin.Int origin=GET_PROPERTY
|
||||||
|
$this: GET_VAR '<this>: <root>.Some declared in <root>.Some' type=<root>.Some origin=null
|
||||||
|
arg1: CONST Int type=kotlin.Int value=0
|
||||||
|
then: BLOCK type=kotlin.Unit origin=null
|
||||||
|
CALL 'public final fun <set-foo> (<set-?>: kotlin.Int): kotlin.Unit declared in <root>.Some' type=kotlin.Unit origin=EQ
|
||||||
|
$this: GET_VAR '<this>: <root>.Some declared in <root>.Some' type=<root>.Some origin=null
|
||||||
|
<set-?>: CONST Int type=kotlin.Int value=0
|
||||||
|
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator]
|
||||||
|
overridden:
|
||||||
|
public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any
|
||||||
|
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
|
||||||
|
VALUE_PARAMETER name:other index:0 type:kotlin.Any?
|
||||||
|
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override]
|
||||||
|
overridden:
|
||||||
|
public open fun hashCode (): kotlin.Int declared in kotlin.Any
|
||||||
|
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
|
||||||
|
FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override]
|
||||||
|
overridden:
|
||||||
|
public open fun toString (): kotlin.String declared in kotlin.Any
|
||||||
|
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
|
||||||
+384
-384
File diff suppressed because it is too large
Load Diff
@@ -1810,6 +1810,11 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase {
|
|||||||
public void testV8ArrayToList() throws Exception {
|
public void testV8ArrayToList() throws Exception {
|
||||||
runTest("compiler/testData/ir/irText/firProblems/V8ArrayToList.kt");
|
runTest("compiler/testData/ir/irText/firProblems/V8ArrayToList.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("VarInInit.kt")
|
||||||
|
public void testVarInInit() throws Exception {
|
||||||
|
runTest("compiler/testData/ir/irText/firProblems/VarInInit.kt");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/ir/irText/lambdas")
|
@TestMetadata("compiler/testData/ir/irText/lambdas")
|
||||||
|
|||||||
Reference in New Issue
Block a user