Skip to content

Commit 4412edb

Browse files
yanexSpace Team
authored andcommitted
[Analysis API] Use SELF contexts for code fragment context expressions
Expressions can contribute smart casts, and those should normally be ignored (a context element should be interpreted like the code fragment prepends it). ^KT-70860 Fixed
1 parent 5964115 commit 4412edb

File tree

6 files changed

+29
-13
lines changed

6 files changed

+29
-13
lines changed

analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/resultNothingBeforeSmartCast.ir.txt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@ MODULE_FRAGMENT
55
CONSTRUCTOR visibility:public returnType:<root>.CodeFragment [primary]
66
BLOCK_BODY
77
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in kotlin.Any'
8-
FUN name:run visibility:public modality:FINAL returnType:kotlin.Any?
8+
FUN name:run visibility:public modality:FINAL returnType:kotlin.String
99
VALUE_PARAMETER kind:Regular name:p0 index:0 type:kotlin.String?
1010
EXPRESSION_BODY
11-
BLOCK type=kotlin.Nothing? origin=null
12-
GET_VAR 'p0: kotlin.String? declared in <root>.CodeFragment.run' type=kotlin.String? origin=null
11+
BLOCK type=kotlin.String origin=null
12+
TYPE_OP type=kotlin.String origin=IMPLICIT_CAST typeOperand=kotlin.String
13+
GET_VAR 'p0: kotlin.String? declared in <root>.CodeFragment.run' type=kotlin.String? origin=null

analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/resultNothingBeforeSmartCast.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ public final class CodeFragment {
1818
MAXLOCALS = 1
1919

2020
// access flags 0x19
21-
public final static run(Ljava/lang/String;)Ljava/lang/Object;
22-
@Lorg/jetbrains/annotations/Nullable;() // invisible
21+
public final static run(Ljava/lang/String;)Ljava/lang/String;
22+
@Lorg/jetbrains/annotations/NotNull;() // invisible
2323
// annotable parameter count: 1 (invisible)
2424
@Lorg/jetbrains/annotations/Nullable;() // invisible, parameter 0
2525
L0

analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/resultNothingSmartCast.ir.txt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@ MODULE_FRAGMENT
55
CONSTRUCTOR visibility:public returnType:<root>.CodeFragment [primary]
66
BLOCK_BODY
77
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in kotlin.Any'
8-
FUN name:run visibility:public modality:FINAL returnType:kotlin.Any?
8+
FUN name:run visibility:public modality:FINAL returnType:kotlin.String
99
VALUE_PARAMETER kind:Regular name:p0 index:0 type:kotlin.String?
1010
EXPRESSION_BODY
11-
BLOCK type=kotlin.Nothing? origin=null
12-
GET_VAR 'p0: kotlin.String? declared in <root>.CodeFragment.run' type=kotlin.String? origin=null
11+
BLOCK type=kotlin.String origin=null
12+
TYPE_OP type=kotlin.String origin=IMPLICIT_CAST typeOperand=kotlin.String
13+
GET_VAR 'p0: kotlin.String? declared in <root>.CodeFragment.run' type=kotlin.String? origin=null

analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/resultNothingSmartCast.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ fun main() {
77
var str: String? = null
88
str = "not null"
99
println(str)
10-
str = null
11-
<caret_context>println(str)
10+
<caret_context>str = null
11+
println(str)
1212
}
1313

1414

analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/resultNothingSmartCast.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ public final class CodeFragment {
1818
MAXLOCALS = 1
1919

2020
// access flags 0x19
21-
public final static run(Ljava/lang/String;)Ljava/lang/Object;
22-
@Lorg/jetbrains/annotations/Nullable;() // invisible
21+
public final static run(Ljava/lang/String;)Ljava/lang/String;
22+
@Lorg/jetbrains/annotations/NotNull;() // invisible
2323
// annotable parameter count: 1 (invisible)
2424
@Lorg/jetbrains/annotations/Nullable;() // invisible, parameter 0
2525
L0

analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirBodyLazyResolver.kt

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,14 @@ import org.jetbrains.kotlin.fir.types.isResolved
5454
import org.jetbrains.kotlin.fir.utils.exceptions.withFirEntry
5555
import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
5656
import org.jetbrains.kotlin.psi
57+
import org.jetbrains.kotlin.psi.KtBlockExpression
5758
import org.jetbrains.kotlin.psi.KtCodeFragment
59+
import org.jetbrains.kotlin.psi.KtDeclaration
5860
import org.jetbrains.kotlin.psi.KtElement
5961
import org.jetbrains.kotlin.psi.KtFile
62+
import org.jetbrains.kotlin.psi.KtProperty
63+
import org.jetbrains.kotlin.psi.KtStatementExpression
64+
import org.jetbrains.kotlin.psi.KtVariableDeclaration
6065
import org.jetbrains.kotlin.utils.exceptions.checkWithAttachment
6166
import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment
6267
import org.jetbrains.kotlin.utils.exceptions.requireWithAttachment
@@ -778,7 +783,16 @@ private class LLFirBodyTargetResolver(target: LLFirResolveTarget) : LLFirAbstrac
778783

779784
return if (contextKtFile != null) {
780785
val contextFirFile = resolutionFacade.getOrBuildFirFile(contextKtFile)
781-
val elementContext = ContextCollector.process(resolutionFacade, contextFirFile, contextPsiElement)
786+
787+
// Avoid using body context of expressions/statements, as those can contribute additional smart casts.
788+
// Still use body contexts for declarations (e.g., to be able to address parameters of a primary constructor).
789+
val preferBodyContext = when (contextPsiElement) {
790+
is KtDeclaration -> contextPsiElement !is KtProperty || !contextPsiElement.isLocal
791+
is KtBlockExpression -> true
792+
else -> false
793+
}
794+
795+
val elementContext = ContextCollector.process(resolutionFacade, contextFirFile, contextPsiElement, preferBodyContext)
782796
?: errorWithAttachment("Cannot find enclosing context for ${contextPsiElement::class}") {
783797
withPsiEntry("contextPsiElement", contextPsiElement)
784798
}

0 commit comments

Comments
 (0)