Retain Member.getInitializer for Kotlin programs

I opt to identify any syntactic initializer. These are broader in scope than Java's member initializers, which are necessarily context-free, whereas in Kotlin the primary constructor's parameters can be referred to.
This commit is contained in:
Chris Smowton
2022-03-01 12:20:02 +00:00
committed by Ian Lynagh
parent 37543e7a86
commit 13cd145a76
6 changed files with 31 additions and 1 deletions

View File

@@ -517,6 +517,19 @@ class AssignExpr extends Assignment, @assignexpr {
override string getAPrimaryQlClass() { result = "AssignExpr" }
}
/**
* A Kotlin class member initializer assignment.
*
* For example, `class X { val y = 1 }`
*/
class KtInitializerAssignExpr extends AssignExpr {
KtInitializerAssignExpr() {
ktInitializerAssignment(this)
}
override string getAPrimaryQlClass() { result = "KtInitializerAssignExpr" }
}
/**
* A common super-class to represent compound assignments, which include an implicit operator.
*

View File

@@ -638,6 +638,16 @@ class Field extends Member, ExprParent, @field, Variable {
// (CodeQL models explicit initializer blocks as BlockStmt in initializer methods)
exprStmt.getParent() = im.getBody()
)
or
// Kotlin initializers are more general than Java's, in that they may refer to
// primary constructor parameters. This identifies a syntactic initializer, so
// `class A { val y = 1 }` is an initializer, as is `class B(x: Int) { val y = x }`,
// but `class C { var x: Int; init { x = 1 } }` is not, and neither is
// `class D { var x: Int; constructor(y: Int) { x = y } }`
exists(KtInitializerAssignExpr e |
e.getDest() = this.getAnAccess() and
e.getSource() = result
)
}
/**