FIR: Add separate local scopes for blocks
This commit is contained in:
+16
@@ -0,0 +1,16 @@
|
|||||||
|
class B {
|
||||||
|
fun append() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
class A {
|
||||||
|
val message = B()
|
||||||
|
|
||||||
|
fun foo(w: Boolean) {
|
||||||
|
if (w) {
|
||||||
|
val message = ""
|
||||||
|
message.toString()
|
||||||
|
} else {
|
||||||
|
message.append() // message here should relate to the class-level property
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+32
@@ -0,0 +1,32 @@
|
|||||||
|
FILE: blockLocalScopes.kt
|
||||||
|
public final class B : R|kotlin/Any| {
|
||||||
|
public constructor(): R|B| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
public final fun append(): R|kotlin/Unit| {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public final class A : R|kotlin/Any| {
|
||||||
|
public constructor(): R|A| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
public final val message: R|B| = R|/B.B|()
|
||||||
|
public get(): R|B|
|
||||||
|
|
||||||
|
public final fun foo(w: R|kotlin/Boolean|): R|kotlin/Unit| {
|
||||||
|
when () {
|
||||||
|
R|<local>/w| -> {
|
||||||
|
lval message: R|kotlin/String| = String()
|
||||||
|
R|<local>/message|.R|kotlin/Any.toString|()
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
this@R|/A|.R|/A.message|.R|/B.append|()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Generated
+5
@@ -909,6 +909,11 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest {
|
|||||||
runTest("compiler/fir/analysis-tests/testData/resolve/expresssions/baseQualifier.kt");
|
runTest("compiler/fir/analysis-tests/testData/resolve/expresssions/baseQualifier.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("blockLocalScopes.kt")
|
||||||
|
public void testBlockLocalScopes() throws Exception {
|
||||||
|
runTest("compiler/fir/analysis-tests/testData/resolve/expresssions/blockLocalScopes.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("CallBasedInExpressionGenerator.kt")
|
@TestMetadata("CallBasedInExpressionGenerator.kt")
|
||||||
public void testCallBasedInExpressionGenerator() throws Exception {
|
public void testCallBasedInExpressionGenerator() throws Exception {
|
||||||
runTest("compiler/fir/analysis-tests/testData/resolve/expresssions/CallBasedInExpressionGenerator.kt");
|
runTest("compiler/fir/analysis-tests/testData/resolve/expresssions/CallBasedInExpressionGenerator.kt");
|
||||||
|
|||||||
+5
@@ -909,6 +909,11 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
|
|||||||
runTest("compiler/fir/analysis-tests/testData/resolve/expresssions/baseQualifier.kt");
|
runTest("compiler/fir/analysis-tests/testData/resolve/expresssions/baseQualifier.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("blockLocalScopes.kt")
|
||||||
|
public void testBlockLocalScopes() throws Exception {
|
||||||
|
runTest("compiler/fir/analysis-tests/testData/resolve/expresssions/blockLocalScopes.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("CallBasedInExpressionGenerator.kt")
|
@TestMetadata("CallBasedInExpressionGenerator.kt")
|
||||||
public void testCallBasedInExpressionGenerator() throws Exception {
|
public void testCallBasedInExpressionGenerator() throws Exception {
|
||||||
runTest("compiler/fir/analysis-tests/testData/resolve/expresssions/CallBasedInExpressionGenerator.kt");
|
runTest("compiler/fir/analysis-tests/testData/resolve/expresssions/CallBasedInExpressionGenerator.kt");
|
||||||
|
|||||||
+1
-1
@@ -39,7 +39,7 @@ open class FirBodyResolveTransformer(
|
|||||||
final override val components: BodyResolveTransformerComponents =
|
final override val components: BodyResolveTransformerComponents =
|
||||||
BodyResolveTransformerComponents(session, scopeSession, this, context)
|
BodyResolveTransformerComponents(session, scopeSession, this, context)
|
||||||
|
|
||||||
private val expressionsTransformer = FirExpressionsResolveTransformer(this)
|
internal val expressionsTransformer = FirExpressionsResolveTransformer(this)
|
||||||
protected open val declarationsTransformer = FirDeclarationsResolveTransformer(this)
|
protected open val declarationsTransformer = FirDeclarationsResolveTransformer(this)
|
||||||
private val controlFlowStatementsTransformer = FirControlFlowStatementsResolveTransformer(this)
|
private val controlFlowStatementsTransformer = FirControlFlowStatementsResolveTransformer(this)
|
||||||
|
|
||||||
|
|||||||
+11
-4
@@ -40,10 +40,17 @@ class FirControlFlowStatementsResolveTransformer(transformer: FirBodyResolveTran
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun transformDoWhileLoop(doWhileLoop: FirDoWhileLoop, data: ResolutionMode): CompositeTransformResult<FirStatement> {
|
override fun transformDoWhileLoop(doWhileLoop: FirDoWhileLoop, data: ResolutionMode): CompositeTransformResult<FirStatement> {
|
||||||
return doWhileLoop.also(dataFlowAnalyzer::enterDoWhileLoop)
|
// Do-while has a specific scope structure (its block and condition effectively share the scope)
|
||||||
.transformBlock(transformer, data).also(dataFlowAnalyzer::enterDoWhileLoopCondition)
|
return withNewLocalScope {
|
||||||
.transformCondition(transformer, data).also(dataFlowAnalyzer::exitDoWhileLoop)
|
doWhileLoop.also(dataFlowAnalyzer::enterDoWhileLoop)
|
||||||
.transformOtherChildren(transformer, data).compose()
|
.apply {
|
||||||
|
transformer.expressionsTransformer.transformBlockInCurrentScope(block, data)
|
||||||
|
dataFlowAnalyzer
|
||||||
|
}
|
||||||
|
.also(dataFlowAnalyzer::enterDoWhileLoopCondition).transformCondition(transformer, data)
|
||||||
|
.also(dataFlowAnalyzer::exitDoWhileLoop)
|
||||||
|
.transformOtherChildren(transformer, data).compose()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------- When expressions -------------------------------
|
// ------------------------------- When expressions -------------------------------
|
||||||
|
|||||||
+9
-1
@@ -191,6 +191,14 @@ class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransformer) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun transformBlock(block: FirBlock, data: ResolutionMode): CompositeTransformResult<FirStatement> {
|
override fun transformBlock(block: FirBlock, data: ResolutionMode): CompositeTransformResult<FirStatement> {
|
||||||
|
withNewLocalScope {
|
||||||
|
transformBlockInCurrentScope(block, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
return block.compose()
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun transformBlockInCurrentScope(block: FirBlock, data: ResolutionMode) {
|
||||||
dataFlowAnalyzer.enterBlock(block)
|
dataFlowAnalyzer.enterBlock(block)
|
||||||
val numberOfStatements = block.statements.size
|
val numberOfStatements = block.statements.size
|
||||||
|
|
||||||
@@ -220,8 +228,8 @@ class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransformer) :
|
|||||||
diagnostic = ConeSimpleDiagnostic("No type for block", DiagnosticKind.InferenceError)
|
diagnostic = ConeSimpleDiagnostic("No type for block", DiagnosticKind.InferenceError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dataFlowAnalyzer.exitBlock(block)
|
dataFlowAnalyzer.exitBlock(block)
|
||||||
return block.compose()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun transformThisReceiverExpression(
|
override fun transformThisReceiverExpression(
|
||||||
|
|||||||
Vendored
-2
@@ -1,5 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
|
|
||||||
var result = ""
|
var result = ""
|
||||||
|
|
||||||
fun overload() {
|
fun overload() {
|
||||||
|
|||||||
+2
-2
@@ -70,8 +70,8 @@ class Your {
|
|||||||
val z = if (true) {
|
val z = if (true) {
|
||||||
val xx: Int
|
val xx: Int
|
||||||
exec {
|
exec {
|
||||||
<!UNRESOLVED_REFERENCE!>xx<!> = 24
|
xx = 24
|
||||||
}
|
}
|
||||||
42
|
42
|
||||||
}
|
}
|
||||||
else 0
|
else 0
|
||||||
|
|||||||
Reference in New Issue
Block a user