mirror of
https://github.com/github/codeql.git
synced 2026-07-15 08:18:18 +02:00
Kotlin: converge delegated-setter value-parameter name to <set-?>
The synthetic setter of a *delegated* property has one implicit value
parameter. The K2 frontend names it `<set-?>`
(`SpecialNames.IMPLICIT_SETTER_PARAMETER`), matching what it does for an
ordinary member property's setter. The K1 frontend instead names a
delegated property's setter parameter `value`, diverging from both K2 and
from its own naming of member-property setters.
This produced two divergent rows per delegated `var` between
test-kotlin1 and test-kotlin2 (the `[Parameter]` declaration and the
`[VarAccess]` that reads it back inside the generated setter body):
- [Parameter] value -> [Parameter] <set-?>
- [VarAccess] value -> [VarAccess] <set-?>
Decision: adopt the K2 name. `<set-?>` is the canonical implicit
setter-parameter name the frontend already uses everywhere else, so it is
the more consistent and less surprising choice; a bare `value` is
indistinguishable from a user-written parameter of that name.
`getConvergedValueParameterName` renames the parameter only when its
enclosing function has origin `DELEGATED_PROPERTY_ACCESSOR` *and* its K1
source name is `value`. The origin guard restricts the rename to the fully
synthetic delegated accessors (a hand-written `ReadWriteProperty.setValue`
has origin `DEFINED`, so its `value` parameter is untouched); the name
guard restricts it to the setter value parameter, leaving the accessor's
receiver parameters (`<this>` for an extension property,
`<dispatchReceiver>` for a member property) unchanged. Under K2 the setter
parameter is already `<set-?>` and receivers are `<this>`, so nothing
matches and the canonical K2 output is byte-for-byte unchanged (only the
three K1 setters in test-kotlin1 relearn).
The literal `<set-?>` is used because `SpecialNames.IMPLICIT_SETTER_PARAMETER`
is not resolvable in every compiler version the extractor is built against.
Relearned both suites (all 3333 tests pass); only the three delegated
setters in test-kotlin1 (delegatedProperties.kt lines 19, 34, 82) change.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -1439,7 +1439,7 @@ open class KotlinFileExtractor(
|
||||
return extractValueParameter(
|
||||
id,
|
||||
substitutedType,
|
||||
vp.name.asString(),
|
||||
getConvergedValueParameterName(vp),
|
||||
location,
|
||||
parent,
|
||||
idx,
|
||||
@@ -3168,6 +3168,36 @@ open class KotlinFileExtractor(
|
||||
return tw.getLocation(keyword.startOffset, vp.endOffset)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name to record for a value parameter, converging the two frontends where they
|
||||
* disagree.
|
||||
*
|
||||
* A property's synthetic setter has a single implicit value parameter. The K2 frontend names
|
||||
* it `<set-?>`; the K1 frontend does the same for a
|
||||
* member property's setter but names a *delegated* property's setter parameter `value`. That
|
||||
* parameter is always compiler-synthesised (a delegated-property accessor carries no
|
||||
* source-written parameters), so renaming it can never affect a user-written `value` parameter
|
||||
* (for example the `value` parameter of a hand-written `ReadWriteProperty.setValue`, whose
|
||||
* function has origin `DEFINED`). We therefore converge the delegated-setter parameter onto the
|
||||
* canonical `<set-?>` name (the `SpecialNames.IMPLICIT_SETTER_PARAMETER` constant is not present
|
||||
* in every supported compiler version, so the literal is used directly).
|
||||
*
|
||||
* The rename is guarded on the K1 source name `value` so it targets *only* the setter value
|
||||
* parameter: a delegated accessor's other parameters are receivers (`<this>` for an extension
|
||||
* property, `<dispatchReceiver>` for a member property), which must keep their names. Under K2
|
||||
* the setter parameter is already `<set-?>` and the receivers are `<this>`, so none match and
|
||||
* the canonical K2 output is left untouched.
|
||||
*/
|
||||
private fun getConvergedValueParameterName(vp: IrValueParameter): String {
|
||||
if (
|
||||
(vp.parent as? IrFunction)?.origin == IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR &&
|
||||
vp.name.asString() == "value"
|
||||
) {
|
||||
return "<set-?>"
|
||||
}
|
||||
return vp.name.asString()
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the PSI-based location for a *synthesised* value parameter that has no source
|
||||
* token of its own, matching the span the K2 frontend emits natively, or null to leave the
|
||||
|
||||
@@ -294,7 +294,7 @@ delegatedProperties.kt:
|
||||
# 19| 2: [Method] <set-varResource1>
|
||||
# 19| 3: [TypeAccess] Unit
|
||||
#-----| 4: (Parameters)
|
||||
# 19| 0: [Parameter] value
|
||||
# 19| 0: [Parameter] <set-?>
|
||||
# 19| 0: [TypeAccess] int
|
||||
# 19| 5: [BlockStmt] { ... }
|
||||
# 19| 0: [ReturnStmt] return ...
|
||||
@@ -328,7 +328,7 @@ delegatedProperties.kt:
|
||||
# 19| 0: [VarAccess] a0
|
||||
# 19| -3: [TypeAccess] KMutableProperty0<Integer>
|
||||
# 19| 0: [TypeAccess] Integer
|
||||
# 19| 2: [VarAccess] value
|
||||
# 19| 2: [VarAccess] <set-?>
|
||||
# 20| 1: [ExprStmt] <Expr>;
|
||||
# 20| 0: [MethodCall] println(...)
|
||||
# 20| -1: [TypeAccess] ConsoleKt
|
||||
@@ -538,7 +538,7 @@ delegatedProperties.kt:
|
||||
# 34| 2: [Method] <set-readWrite>
|
||||
# 34| 3: [TypeAccess] Unit
|
||||
#-----| 4: (Parameters)
|
||||
# 34| 0: [Parameter] value
|
||||
# 34| 0: [Parameter] <set-?>
|
||||
# 34| 0: [TypeAccess] int
|
||||
# 34| 5: [BlockStmt] { ... }
|
||||
# 34| 0: [ReturnStmt] return ...
|
||||
@@ -572,7 +572,7 @@ delegatedProperties.kt:
|
||||
# 34| 0: [VarAccess] a0
|
||||
# 34| -3: [TypeAccess] KMutableProperty0<Integer>
|
||||
# 34| 0: [TypeAccess] Integer
|
||||
# 34| 2: [VarAccess] value
|
||||
# 34| 2: [VarAccess] <set-?>
|
||||
# 36| 7: [ExprStmt] <Expr>;
|
||||
# 36| 0: [MethodCall] println(...)
|
||||
# 36| -1: [TypeAccess] ConsoleKt
|
||||
@@ -1848,7 +1848,7 @@ delegatedProperties.kt:
|
||||
# 82| 2: [Method] <set-delegatedToMember3>
|
||||
# 82| 3: [TypeAccess] Unit
|
||||
#-----| 4: (Parameters)
|
||||
# 82| 0: [Parameter] value
|
||||
# 82| 0: [Parameter] <set-?>
|
||||
# 82| 0: [TypeAccess] int
|
||||
# 82| 5: [BlockStmt] { ... }
|
||||
# 82| 0: [ReturnStmt] return ...
|
||||
@@ -1884,7 +1884,7 @@ delegatedProperties.kt:
|
||||
# 82| 0: [VarAccess] a0
|
||||
# 82| -3: [TypeAccess] KMutableProperty0<Integer>
|
||||
# 82| 0: [TypeAccess] Integer
|
||||
# 82| 3: [VarAccess] value
|
||||
# 82| 3: [VarAccess] <set-?>
|
||||
# 83| 1: [ExprStmt] <Expr>;
|
||||
# 83| 0: [MethodCall] fn(...)
|
||||
# 83| -1: [ThisAccess] this
|
||||
|
||||
@@ -58,6 +58,7 @@
|
||||
| delegatedProperties.kt:19:34:19:51 | ...::... | delegatedProperties.kt:19:9:19:51 | <set-varResource1> | PropertyRefExpr |
|
||||
| delegatedProperties.kt:19:34:19:51 | <get-varResource1>(...) | delegatedProperties.kt:19:34:19:51 | get | MethodCall |
|
||||
| delegatedProperties.kt:19:34:19:51 | <get-varResource1>(...) | delegatedProperties.kt:19:34:19:51 | get | MethodCall |
|
||||
| delegatedProperties.kt:19:34:19:51 | <set-?> | delegatedProperties.kt:19:9:19:51 | <set-varResource1> | VarAccess |
|
||||
| delegatedProperties.kt:19:34:19:51 | <set-varResource1>(...) | delegatedProperties.kt:19:34:19:51 | set | MethodCall |
|
||||
| delegatedProperties.kt:19:34:19:51 | <set-varResource1>(...) | delegatedProperties.kt:19:34:19:51 | set | MethodCall |
|
||||
| delegatedProperties.kt:19:34:19:51 | Integer | delegatedProperties.kt:19:9:19:51 | <get-varResource1> | TypeAccess |
|
||||
@@ -82,7 +83,6 @@
|
||||
| delegatedProperties.kt:19:34:19:51 | setValue(...) | delegatedProperties.kt:19:9:19:51 | <set-varResource1> | MethodCall |
|
||||
| delegatedProperties.kt:19:34:19:51 | this | delegatedProperties.kt:19:34:19:51 | invoke | ThisAccess |
|
||||
| delegatedProperties.kt:19:34:19:51 | this | delegatedProperties.kt:19:34:19:51 | invoke | ThisAccess |
|
||||
| delegatedProperties.kt:19:34:19:51 | value | delegatedProperties.kt:19:9:19:51 | <set-varResource1> | VarAccess |
|
||||
| delegatedProperties.kt:19:34:19:51 | varResource1$delegate | delegatedProperties.kt:19:9:19:51 | <get-varResource1> | VarAccess |
|
||||
| delegatedProperties.kt:19:34:19:51 | varResource1$delegate | delegatedProperties.kt:19:9:19:51 | <set-varResource1> | VarAccess |
|
||||
| delegatedProperties.kt:20:9:20:29 | ConsoleKt | delegatedProperties.kt:18:5:40:5 | fn | TypeAccess |
|
||||
@@ -166,6 +166,7 @@
|
||||
| delegatedProperties.kt:34:31:34:48 | ...::... | delegatedProperties.kt:34:9:34:48 | <set-readWrite> | PropertyRefExpr |
|
||||
| delegatedProperties.kt:34:31:34:48 | <get-readWrite>(...) | delegatedProperties.kt:34:31:34:48 | get | MethodCall |
|
||||
| delegatedProperties.kt:34:31:34:48 | <get-readWrite>(...) | delegatedProperties.kt:34:31:34:48 | get | MethodCall |
|
||||
| delegatedProperties.kt:34:31:34:48 | <set-?> | delegatedProperties.kt:34:9:34:48 | <set-readWrite> | VarAccess |
|
||||
| delegatedProperties.kt:34:31:34:48 | <set-readWrite>(...) | delegatedProperties.kt:34:31:34:48 | set | MethodCall |
|
||||
| delegatedProperties.kt:34:31:34:48 | <set-readWrite>(...) | delegatedProperties.kt:34:31:34:48 | set | MethodCall |
|
||||
| delegatedProperties.kt:34:31:34:48 | Integer | delegatedProperties.kt:34:9:34:48 | <get-readWrite> | TypeAccess |
|
||||
@@ -193,7 +194,6 @@
|
||||
| delegatedProperties.kt:34:31:34:48 | setValue(...) | delegatedProperties.kt:34:9:34:48 | <set-readWrite> | MethodCall |
|
||||
| delegatedProperties.kt:34:31:34:48 | this | delegatedProperties.kt:34:31:34:48 | invoke | ThisAccess |
|
||||
| delegatedProperties.kt:34:31:34:48 | this | delegatedProperties.kt:34:31:34:48 | invoke | ThisAccess |
|
||||
| delegatedProperties.kt:34:31:34:48 | value | delegatedProperties.kt:34:9:34:48 | <set-readWrite> | VarAccess |
|
||||
| delegatedProperties.kt:36:9:36:29 | ConsoleKt | delegatedProperties.kt:18:5:40:5 | fn | TypeAccess |
|
||||
| delegatedProperties.kt:36:9:36:29 | println(...) | delegatedProperties.kt:18:5:40:5 | fn | MethodCall |
|
||||
| delegatedProperties.kt:36:17:36:28 | getVarResource0(...) | delegatedProperties.kt:18:5:40:5 | fn | MethodCall |
|
||||
@@ -777,6 +777,7 @@
|
||||
| delegatedProperties.kt:82:40:82:54 | <dispatchReceiver> | delegatedProperties.kt:82:40:82:54 | | VarAccess |
|
||||
| delegatedProperties.kt:82:40:82:54 | <get-delegatedToMember3>(...) | delegatedProperties.kt:82:40:82:54 | get | MethodCall |
|
||||
| delegatedProperties.kt:82:40:82:54 | <get-delegatedToMember3>(...) | delegatedProperties.kt:82:40:82:54 | get | MethodCall |
|
||||
| delegatedProperties.kt:82:40:82:54 | <set-?> | delegatedProperties.kt:82:9:82:54 | <set-delegatedToMember3> | VarAccess |
|
||||
| delegatedProperties.kt:82:40:82:54 | <set-delegatedToMember3>(...) | delegatedProperties.kt:82:40:82:54 | set | MethodCall |
|
||||
| delegatedProperties.kt:82:40:82:54 | <set-delegatedToMember3>(...) | delegatedProperties.kt:82:40:82:54 | set | MethodCall |
|
||||
| delegatedProperties.kt:82:40:82:54 | Integer | delegatedProperties.kt:81:5:84:5 | fn | TypeAccess |
|
||||
@@ -819,7 +820,6 @@
|
||||
| delegatedProperties.kt:82:40:82:54 | this.<dispatchReceiver> | delegatedProperties.kt:82:40:82:54 | | VarAccess |
|
||||
| delegatedProperties.kt:82:40:82:54 | this.<dispatchReceiver> | delegatedProperties.kt:82:40:82:54 | get | VarAccess |
|
||||
| delegatedProperties.kt:82:40:82:54 | this.<dispatchReceiver> | delegatedProperties.kt:82:40:82:54 | set | VarAccess |
|
||||
| delegatedProperties.kt:82:40:82:54 | value | delegatedProperties.kt:82:9:82:54 | <set-delegatedToMember3> | VarAccess |
|
||||
| delegatedProperties.kt:83:9:83:12 | fn(...) | delegatedProperties.kt:81:5:84:5 | fn | MethodCall |
|
||||
| delegatedProperties.kt:83:9:83:12 | this | delegatedProperties.kt:81:5:84:5 | fn | ThisAccess |
|
||||
| delegatedProperties.kt:87:1:87:46 | MyClass | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
|
||||
Reference in New Issue
Block a user