Skip to content

Commit 32d00a0

Browse files
Kotlin extractor: satisfy internal lint on convergence helpers
The Kotlin internal queries job (odasa-buildutils/kotlin_internal_queries) flagged two code-quality issues introduced by the K1/K2 convergence helpers. Both are pure source refactors with no effect on extractor output, so no .expected files change. 1. possiblyThrowingExpressions.ql / notNullExpr: extractVariableExpr used a `!!` not-null assertion (`currentDesugarTemp!!.second`) guarded by a separate `currentDesugarTemp?.first === v` check. The extractor must avoid `!!` (it can throw and lose a source file). Bind `currentDesugarTemp` to a local val and null-check it in the `when`, which smart-casts the subsequent `.first`/`.second` accesses. Behaviour is identical. 2. separated_overloads.ql: two overload groups were split by newly added helpers, which the lint reports as harder-to-read code: - `getPsiBasedConstructorBodyLocation` sat between the two `extractBlockBody` overloads; moved it below both. - the destructuring helpers (`destructuringContainerK1NameRegex`, `isDestructuringContainerVariable`, `getPsiBasedDestructuringContainerLocation`) sat between the `getPsiBasedLocation(IrVariable)` and `getPsiBasedLocation(IrProperty)` overloads; moved them below the third overload so all three `getPsiBasedLocation` overloads are adjacent. Verified the standalone extractor still compiles under both K2 (2.4.0) and K1 (1.9.20-Beta). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent a1ae9f7 commit 32d00a0

1 file changed

Lines changed: 40 additions & 39 deletions

File tree

java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt

Lines changed: 40 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -2947,6 +2947,16 @@ open class KotlinFileExtractor(
29472947
tw.writeHasLocation(it, locId)
29482948
}
29492949

2950+
private fun extractBlockBody(b: IrBlockBody, callable: Label<out DbCallable>) {
2951+
with("block body", b) {
2952+
extractBlockBody(callable, getPsiBasedConstructorBodyLocation(b) ?: tw.getLocation(b)).also {
2953+
for ((sIdx, stmt) in b.statements.withIndex()) {
2954+
extractStatement(stmt, callable, it, sIdx)
2955+
}
2956+
}
2957+
}
2958+
}
2959+
29502960
/**
29512961
* Returns a PSI-based location for a constructor body block that starts at the
29522962
* `constructor` keyword rather than at any leading modifiers.
@@ -2975,16 +2985,6 @@ open class KotlinFileExtractor(
29752985
return tw.getLocation(keyword.startOffset, b.endOffset)
29762986
}
29772987

2978-
private fun extractBlockBody(b: IrBlockBody, callable: Label<out DbCallable>) {
2979-
with("block body", b) {
2980-
extractBlockBody(callable, getPsiBasedConstructorBodyLocation(b) ?: tw.getLocation(b)).also {
2981-
for ((sIdx, stmt) in b.statements.withIndex()) {
2982-
extractStatement(stmt, callable, it, sIdx)
2983-
}
2984-
}
2985-
}
2986-
}
2987-
29882988
private fun extractSyntheticBody(b: IrSyntheticBody, callable: Label<out DbCallable>) {
29892989
with("synthetic body", b) {
29902990
val kind = b.kind
@@ -3066,6 +3066,34 @@ open class KotlinFileExtractor(
30663066
return tw.getLocation(declStart, declaration.endOffset)
30673067
}
30683068

3069+
/**
3070+
* Returns the PSI-based location for a property declaration, spanning from
3071+
* the `val`/`var` keyword to the end of the full property declaration (including
3072+
* any explicit getter/setter body).
3073+
*
3074+
* IR offsets are inconsistent across K1 and K2:
3075+
* - K1 [IrProperty.startOffset] includes leading modifiers (private, abstract,
3076+
* lateinit, @Annotation) in the span start. K2 starts at `val`/`var`.
3077+
* - K1 [IrProperty.endOffset] stops at the end of the declaration line and
3078+
* does not include an explicit getter/setter body on a subsequent line. K2
3079+
* includes the getter/setter body.
3080+
*
3081+
* Both are resolved by walking the PSI tree: the [KtProperty] node covers the
3082+
* full declaration including getter/setter, and [KtProperty.valOrVarKeyword]
3083+
* gives the correct start, excluding modifiers.
3084+
*/
3085+
private fun getPsiBasedLocation(p: IrProperty): Label<DbLocation>? {
3086+
if (p.startOffset < 0 || p.endOffset < 0) return null
3087+
val file = currentIrFile ?: return null
3088+
val ktFile = getPsi2Ir()?.getKtFile(file) ?: return null
3089+
val ktProperty = ktFile.findElementAt(p.startOffset)
3090+
?.let { leaf -> generateSequence(leaf) { it.parent }.filterIsInstance<KtProperty>().firstOrNull() }
3091+
?: return null
3092+
val declStart = ktProperty.valOrVarKeyword.startOffset
3093+
val declEnd = ktProperty.endOffset
3094+
return tw.getLocation(declStart, declEnd)
3095+
}
3096+
30693097
// Matches the K1 frontend's synthetic name for the temporary holding the subject of a
30703098
// destructuring declaration (`val (a, b) = subject`), which is `tmp<N>_container`. K2 names
30713099
// the same temporary with the special name `<destruct>`.
@@ -3104,34 +3132,6 @@ open class KotlinFileExtractor(
31043132
return tw.getLocation(destructuring.startOffset, destructuring.endOffset)
31053133
}
31063134

3107-
/**
3108-
* Returns the PSI-based location for a property declaration, spanning from
3109-
* the `val`/`var` keyword to the end of the full property declaration (including
3110-
* any explicit getter/setter body).
3111-
*
3112-
* IR offsets are inconsistent across K1 and K2:
3113-
* - K1 [IrProperty.startOffset] includes leading modifiers (private, abstract,
3114-
* lateinit, @Annotation) in the span start. K2 starts at `val`/`var`.
3115-
* - K1 [IrProperty.endOffset] stops at the end of the declaration line and
3116-
* does not include an explicit getter/setter body on a subsequent line. K2
3117-
* includes the getter/setter body.
3118-
*
3119-
* Both are resolved by walking the PSI tree: the [KtProperty] node covers the
3120-
* full declaration including getter/setter, and [KtProperty.valOrVarKeyword]
3121-
* gives the correct start, excluding modifiers.
3122-
*/
3123-
private fun getPsiBasedLocation(p: IrProperty): Label<DbLocation>? {
3124-
if (p.startOffset < 0 || p.endOffset < 0) return null
3125-
val file = currentIrFile ?: return null
3126-
val ktFile = getPsi2Ir()?.getKtFile(file) ?: return null
3127-
val ktProperty = ktFile.findElementAt(p.startOffset)
3128-
?.let { leaf -> generateSequence(leaf) { it.parent }.filterIsInstance<KtProperty>().firstOrNull() }
3129-
?: return null
3130-
val declStart = ktProperty.valOrVarKeyword.startOffset
3131-
val declEnd = ktProperty.endOffset
3132-
return tw.getLocation(declStart, declEnd)
3133-
}
3134-
31353135
/**
31363136
* Returns the PSI-based location for a synthesised (`DEFAULT_PROPERTY_ACCESSOR`)
31373137
* getter or setter, matching the span the K2 frontend emits natively.
@@ -3545,9 +3545,10 @@ open class KotlinFileExtractor(
35453545
// source spelling `_`. Emit `_` so both frontends produce the same, source-faithful
35463546
// name (D15). The desugar temporaries for increment/decrement (`<unary>`) and
35473547
// destructuring (`<destruct>`) are likewise normalised onto the uniform K2 names.
3548+
val desugarTemp = currentDesugarTemp
35483549
val varName =
35493550
when {
3550-
currentDesugarTemp?.first === v -> currentDesugarTemp!!.second
3551+
desugarTemp != null && desugarTemp.first === v -> desugarTemp.second
35513552
isDestructContainer -> "<destruct>"
35523553
v.name == SpecialNames.UNDERSCORE_FOR_UNUSED_VAR -> "_"
35533554
else -> v.name.asString()

0 commit comments

Comments
 (0)