Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
6465078
kotlin tests: synchronise test inputs between test-kotlin1 and test-k…
andersfugmann Jul 7, 2026
da28c40
kotlin extractor: fold unaryMinus(IrConst) into a signed literal in K2
andersfugmann Jul 7, 2026
bf8b4ab
kotlin tests: sync generated-throws.kt source between test-kotlin1 an…
andersfugmann Jul 7, 2026
1778b15
kotlin tests: sync dataflow/foreach test inputs and K2 expected output
andersfugmann Jul 7, 2026
bb17e31
kotlin-extractor: PSI-backed source locations for expression-level nodes
andersfugmann Jul 7, 2026
1e24a5f
kotlin-extractor: fix NotNullExpr start offset to span from operand
andersfugmann Jul 7, 2026
19092fb
kotlin-extractor: fix K1 local variable locations to span from val/va…
andersfugmann Jul 7, 2026
7eb7180
fix property and accessor locations using PSI
andersfugmann Jul 8, 2026
b8a1692
kotlin-extractor: converge local variable entity locations across lan…
andersfugmann Jul 10, 2026
19774cc
kotlin-extractor: converge backing-field locations across language ve…
andersfugmann Jul 10, 2026
e37d89b
Kotlin: converge default property-accessor locations onto the K2-nati…
andersfugmann Jul 10, 2026
240103e
Kotlin: converge implicit primary constructor locations onto the K2-n…
andersfugmann Jul 11, 2026
b2f94da
Kotlin: converge delegated property accessor locations onto K2 proper…
andersfugmann Jul 11, 2026
18a6bde
Kotlin: converge delegated-property accessor body expression location…
andersfugmann Jul 11, 2026
8db987e
Converge if/when branch (WhenBranch) locations onto K2 per-branch spans
andersfugmann Jul 11, 2026
7994893
Converge bare-assignment ExprStmt wrapper locations onto K2
andersfugmann Jul 11, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
470 changes: 442 additions & 28 deletions java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt

Large diffs are not rendered by default.

20 changes: 20 additions & 0 deletions java/kotlin-extractor/src/main/kotlin/TrapWriter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,20 @@ open class FileTrapWriter(
/** The ID for the file that we are extracting from. */
val fileId = mkFileId(filePath, populateFileTables)

/**
* When non-null, any location computed with a start/end offset pair exactly equal to
* [scopedOffsetRemap]`.first` is emitted as if it had the offset pair
* [scopedOffsetRemap]`.second`.
*
* This is used to normalise the source range of the synthesised body expressions of a
* delegated-property accessor: the K1 frontend anchors them at the enclosing
* `KtPropertyDelegate` (i.e. including the `by` keyword), whereas K2 anchors them at the
* delegate expression itself. The remap is set only while extracting such an accessor
* body and matches the full `by`-inclusive range exactly, so it never affects unrelated
* locations.
*/
var scopedOffsetRemap: Pair<Pair<Int, Int>, Pair<Int, Int>>? = null

override fun getDiagnosticTrapWriter(): DiagnosticTrapWriter {
return dtw
}
Expand Down Expand Up @@ -398,6 +412,12 @@ class SourceFileTrapWriter(
private val fileEntry = irFile.fileEntry

override fun getLocation(startOffset: Int, endOffset: Int): Label<DbLocation> {
scopedOffsetRemap?.let { (from, to) ->
if (startOffset == from.first && endOffset == from.second) {
return getLocation(to.first, to.second)
}
}

if (startOffset == UNDEFINED_OFFSET || endOffset == UNDEFINED_OFFSET) {
if (startOffset != endOffset) {
loggerBase.warn(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ exprs
| Test.java:5:19:5:25 | Integer | Integer |
| Test.java:5:38:5:44 | Integer | Integer |
| Test.java:5:58:5:58 | p | Integer |
| user.kt:2:7:2:7 | x | int |
| user.kt:2:3:2:16 | x | int |
| user.kt:2:11:2:11 | t | Test |
| user.kt:2:11:2:16 | f(...) | Integer |
| user.kt:2:13:2:16 | <implicit not null> | int |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,7 @@ def.kt:
# 50| 1: [LocalVariableDeclStmt] var ...;
# 50| 1: [LocalVariableDeclExpr] x
# 50| 0: [IntegerLiteral] 10
# 53| 3: [FieldDeclaration] int p;
#-----| -2: (Annotations)
# 56| 1: [Annotation] Annot0k
# 0| 1: [IntegerLiteral] 0
# 53| -1: [TypeAccess] int
# 57| 0: [IntegerLiteral] 5
# 57| 4: [Method] getP
# 57| 3: [Method] getP
#-----| 1: (Annotations)
# 54| 1: [Annotation] Annot0k
# 0| 1: [IntegerLiteral] 0
Expand All @@ -59,6 +53,12 @@ def.kt:
# 57| 0: [ReturnStmt] return ...
# 57| 0: [VarAccess] DefKt.p
# 57| -1: [TypeAccess] DefKt
# 57| 4: [FieldDeclaration] int p;
#-----| -2: (Annotations)
# 56| 1: [Annotation] Annot0k
# 0| 1: [IntegerLiteral] 0
# 57| -1: [TypeAccess] int
# 57| 0: [IntegerLiteral] 5
# 57| 5: [Method] setP
#-----| 1: (Annotations)
# 55| 1: [Annotation] Annot0k
Expand All @@ -72,7 +72,7 @@ def.kt:
# 57| 0: [AssignExpr] ...=...
# 57| 0: [VarAccess] DefKt.p
# 57| -1: [TypeAccess] DefKt
# 57| 1: [VarAccess] <set-?>
# 53| 1: [VarAccess] <set-?>
# 59| 6: [ExtensionMethod] myExtension
# 59| 3: [TypeAccess] Unit
#-----| 4: (Parameters)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ annotations
| def.kt:41:5:41:12 | Annot0k | def.kt:42:5:42:19 | Z | def.kt:5:1:21:60 | Annot0k |
| def.kt:45:1:45:8 | Annot0k | def.kt:46:1:51:1 | fn | def.kt:5:1:21:60 | Annot0k |
| def.kt:46:21:46:28 | Annot0k | def.kt:46:21:46:39 | a | def.kt:5:1:21:60 | Annot0k |
| def.kt:54:1:54:12 | Annot0k | def.kt:57:1:57:23 | getP | def.kt:5:1:21:60 | Annot0k |
| def.kt:55:1:55:12 | Annot0k | def.kt:57:1:57:23 | setP | def.kt:5:1:21:60 | Annot0k |
| def.kt:56:1:56:14 | Annot0k | def.kt:53:1:57:23 | p | def.kt:5:1:21:60 | Annot0k |
| def.kt:54:1:54:12 | Annot0k | def.kt:57:1:57:19 | getP | def.kt:5:1:21:60 | Annot0k |
| def.kt:55:1:55:12 | Annot0k | def.kt:57:1:57:19 | setP | def.kt:5:1:21:60 | Annot0k |
| def.kt:56:1:56:14 | Annot0k | def.kt:57:1:57:23 | p | def.kt:5:1:21:60 | Annot0k |
| def.kt:59:5:59:21 | Annot0k | def.kt:59:5:59:28 | <this> | def.kt:5:1:21:60 | Annot0k |
| use.java:10:5:10:21 | Annot0j | use.java:14:18:14:18 | Z | Annot0j.java:1:19:1:25 | Annot0j |
| use.java:11:5:11:90 | Annot1j | use.java:14:18:14:18 | Z | Annot1j.java:1:19:1:25 | Annot1j |
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
| Test.java:2:17:2:17 | m | m | m |
| test.kt:4:9:4:18 | getX_prop | getX_prop | getX |
| test.kt:6:5:6:19 | getX | getX | getX |
| test.kt:10:5:10:19 | changeY | changeY | setY |
| test.kt:10:5:10:19 | y | y | getY |
| test.kt:10:5:10:14 | changeY | changeY | setY |
| test.kt:10:5:10:14 | y | y | getY |
| test.kt:13:5:13:15 | method | method | fn |
| test.kt:17:5:17:14 | p | p | p |
| test.kt:18:23:18:32 | w | w | q |
22 changes: 11 additions & 11 deletions java/ql/test-kotlin1/library-tests/classes/PrintAst.expected
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ classes.kt:
# 66| 1: [ExprStmt] <Expr>;
# 66| 0: [ClassInstanceExpr] new (...)
# 66| -3: [TypeAccess] Object
# 65| 1: [WhenBranch] ... -> ...
# 68| 1: [WhenBranch] ... -> ...
# 65| 0: [BooleanLiteral] true
# 68| 1: [ReturnStmt] return ...
# 68| 0: [StmtExpr] <Stmt>
Expand Down Expand Up @@ -658,7 +658,14 @@ generic_anonymous.kt:
# 1| 0: [ReturnStmt] return ...
# 1| 0: [VarAccess] this.t
# 1| -1: [ThisAccess] this
# 3| 4: [FieldDeclaration] new Object(...) { ... } x;
# 3| 4: [Method] getX$private
# 3| 3: [TypeAccess] new Object(...) { ... }
# 3| 0: [TypeAccess] T
# 3| 5: [BlockStmt] { ... }
# 3| 0: [ReturnStmt] return ...
# 3| 0: [VarAccess] this.x
# 3| -1: [ThisAccess] this
# 3| 5: [FieldDeclaration] new Object(...) { ... } x;
# 3| -1: [TypeAccess] new Object(...) { ... }
# 3| 0: [TypeAccess] T
# 3| 0: [StmtExpr] <Stmt>
Expand Down Expand Up @@ -686,13 +693,6 @@ generic_anonymous.kt:
# 3| 1: [ExprStmt] <Expr>;
# 3| 0: [ClassInstanceExpr] new (...)
# 3| -3: [TypeAccess] Object
# 3| 5: [Method] getX$private
# 3| 3: [TypeAccess] new Object(...) { ... }
# 3| 0: [TypeAccess] T
# 3| 5: [BlockStmt] { ... }
# 3| 0: [ReturnStmt] return ...
# 3| 0: [VarAccess] this.x
# 3| -1: [ThisAccess] this
# 7| 6: [Method] get
# 7| 3: [TypeAccess] T
# 7| 5: [BlockStmt] { ... }
Expand Down Expand Up @@ -892,7 +892,7 @@ localClassField.kt:
# 4| 1: [ExprStmt] <Expr>;
# 4| 0: [ClassInstanceExpr] new L(...)
# 4| -3: [TypeAccess] L
# 2| 1: [WhenBranch] ... -> ...
# 5| 1: [WhenBranch] ... -> ...
# 2| 0: [BooleanLiteral] true
# 5| 1: [BlockStmt] { ... }
# 2| 3: [Method] getX
Expand All @@ -916,7 +916,7 @@ localClassField.kt:
# 9| 1: [ExprStmt] <Expr>;
# 9| 0: [ClassInstanceExpr] new L(...)
# 9| -3: [TypeAccess] L
# 7| 1: [WhenBranch] ... -> ...
# 10| 1: [WhenBranch] ... -> ...
# 7| 0: [BooleanLiteral] true
# 10| 1: [BlockStmt] { ... }
# 7| 5: [Method] getY
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,19 @@
| generic_anonymous.kt:1:26:1:33 | this | Generic |
| generic_anonymous.kt:1:26:1:33 | this.t | T |
| generic_anonymous.kt:3:3:5:3 | ...=... | new Object(...) { ... } |
| generic_anonymous.kt:3:3:5:3 | T | T |
| generic_anonymous.kt:3:3:5:3 | new Object(...) { ... } | new Object(...) { ... } |
| generic_anonymous.kt:3:3:5:3 | this | Generic |
| generic_anonymous.kt:3:3:5:3 | x | new Object(...) { ... } |
| generic_anonymous.kt:3:11:3:15 | T | T |
| generic_anonymous.kt:3:11:3:15 | new Object(...) { ... } | new Object(...) { ... } |
| generic_anonymous.kt:3:11:5:3 | T | T |
| generic_anonymous.kt:3:11:5:3 | new Object(...) { ... } | new Object(...) { ... } |
| generic_anonymous.kt:3:11:5:3 | this | Generic |
| generic_anonymous.kt:3:11:5:3 | this.x | new Object(...) { ... } |
| generic_anonymous.kt:3:19:5:3 | <Stmt> | new Object(...) { ... } |
| generic_anonymous.kt:3:19:5:3 | Object | Object |
| generic_anonymous.kt:3:19:5:3 | new (...) | new Object(...) { ... } |
| generic_anonymous.kt:4:7:4:16 | T | T |
| generic_anonymous.kt:4:7:4:20 | ...=... | T |
| generic_anonymous.kt:4:7:4:20 | T | T |
| generic_anonymous.kt:4:7:4:20 | T | T |
| generic_anonymous.kt:4:7:4:20 | member | T |
| generic_anonymous.kt:4:7:4:20 | this | new Object(...) { ... } |
| generic_anonymous.kt:4:7:4:20 | this.member | T |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,17 @@ comments
| comments.kt:95:1:95:163 | // Diagnostic Matches: % Couldn't get owner of KDoc. The comment is extracted without an owner. ...while extracting a file (comments.kt) at %comments.kt:1:1:96:0% | // Diagnostic Matches: % Couldn't get owner of KDoc. The comment is extracted without an owner. ...while extracting a file (comments.kt) at %comments.kt:1:1:96:0% |
commentOwners
| comments.kt:4:1:11:3 | /**\n * A group of *members*.\n *\n * This class has no useful logic; it's just a documentation example.\n *\n * @property name the name of this group.\n * @constructor Creates an empty group.\n */ | comments.kt:12:1:31:1 | Group |
| comments.kt:14:5:16:7 | /**\n * Members of this group.\n */ | comments.kt:17:5:17:46 | members |
| comments.kt:14:5:16:7 | /**\n * Members of this group.\n */ | comments.kt:17:5:17:46 | members |
| comments.kt:14:5:16:7 | /**\n * Members of this group.\n */ | comments.kt:17:13:17:46 | getMembers$private |
| comments.kt:14:5:16:7 | /**\n * Members of this group.\n */ | comments.kt:17:13:17:23 | getMembers$private |
| comments.kt:14:5:16:7 | /**\n * Members of this group.\n */ | comments.kt:17:13:17:46 | members |
| comments.kt:14:5:16:7 | /**\n * Members of this group.\n */ | comments.kt:17:13:17:46 | members |
| comments.kt:19:5:22:7 | /**\n * Adds a [member] to this group.\n * @return the new size of the group.\n */ | comments.kt:23:5:26:5 | add |
| comments.kt:35:5:35:34 | /** Medium is in the middle */ | comments.kt:36:5:36:14 | Medium |
| comments.kt:37:5:37:23 | /** This is high */ | comments.kt:38:5:38:11 | High |
| comments.kt:48:1:50:3 | /**\n * A type alias comment\n */ | comments.kt:51:1:51:24 | MyType |
| comments.kt:54:5:56:7 | /**\n * An init block comment\n */ | comments.kt:53:1:58:1 | InitBlock |
| comments.kt:61:5:63:7 | /**\n * A prop comment\n */ | comments.kt:64:5:68:17 | prop |
| comments.kt:65:9:67:11 | /**\n * An accessor comment\n */ | comments.kt:68:9:68:17 | getProp |
| comments.kt:71:9:73:11 | /**\n * An anonymous function comment\n */ | comments.kt:70:5:76:10 | getL |
| comments.kt:71:9:73:11 | /**\n * An anonymous function comment\n */ | comments.kt:70:5:70:20 | getL |
| comments.kt:71:9:73:11 | /**\n * An anonymous function comment\n */ | comments.kt:70:5:76:10 | l |
| comments.kt:71:9:73:11 | /**\n * An anonymous function comment\n */ | comments.kt:70:5:76:10 | l |
| comments.kt:79:9:81:11 | /**\n * A local function comment\n */ | comments.kt:82:9:82:24 | localFn |
Expand Down
Loading
Loading