Abstract syntax tree classes for working with Java and Kotlin programs¶
CodeQL has a large selection of classes for representing the abstract syntax tree of Java and Kotlin programs.
The abstract syntax tree (AST) represents the syntactic structure of a program. Nodes on the AST represent elements such as statements and expressions.
Writing CodeQL queries for Kotlin versus Java analysis¶
Generally you use the same classes to write queries for Kotlin and for Java. You use the same libraries such as DataFlow, TaintTracking, or SSA, and the same classes such as MethodAccess
or Class
for both languages. When you want to access Kotlin-specific elements (such as a WhenExpr
) you’ll need to use Kotlin-specific CodeQL classes.
There are however some important cases where writing queries for Kotlin can produce surprising results compared to writing queries for Java, as CodeQL works with the JVM bytecode representation of the Kotlin source code.
Be careful when you model code elements that don’t exist in Java, such as NotNullExpr (expr!!)
, because they could interact in unexpected ways with common predicates. For example, MethodAccess.getQualifier()
returns a NotNullExpr
instead of a VarAccess
in the following Kotlin code:
someVar!!.someMethodCall()
In that specific case, you can use the predicate Expr.getUnderlyingExpr()
. This goes directly to the underlying VarAccess
to produce a more similar behavior to that in Java.
Nullable elements (?
) can also produce unexpected behavior. To avoid a NullPointerException
, Kotlin may inline calls like expr.toString()
to String.valueOf(expr)
when expr
is nullable. Make sure that you write CodeQL around the extracted code, which may not exactly match the code as written in the codebase.
Another example is that if-else expressions in Kotlin are translated into WhenExprs
in CodeQL, instead of the more typical IfStmt
seen in Java.
In general, you can debug these issues with the AST (you can use the CodeQL: View AST
command from Visual Studio Code’s CodeQL extension, or run the PrintAst.ql
query) and see exactly what CodeQL is extracting from your code.
Statement classes¶
This table lists all subclasses of Stmt.
Expression classes¶
There are many expression classes, so we present them by category. All classes in this section are subclasses of Expr.
Literals¶
All classes in this subsection are subclasses of Literal.
Expression syntax example | CodeQL class |
---|---|
true |
BooleanLiteral |
23 |
IntegerLiteral |
23l |
LongLiteral |
4.2f |
FloatingPointLiteral |
4.2 |
DoubleLiteral |
'a' |
CharacterLiteral |
"Hello" |
StringLiteral |
null |
NullLiteral |
Unary expressions¶
All classes in this subsection are subclasses of UnaryExpr.
Expression syntax | CodeQL class | Superclasses | Remarks |
---|---|---|---|
Expr++ |
PostIncExpr | UnaryAssignExpr | |
Expr-- |
PostDecExpr | UnaryAssignExpr | |
++ Expr |
PreIncExpr | UnaryAssignExpr | |
-- Expr |
PreDecExpr | UnaryAssignExpr | |
~ Expr |
BitNotExpr | BitwiseExpr | see below for other subclasses of BitwiseExpr |
- Expr |
MinusExpr | ||
+ Expr |
PlusExpr | ||
! Expr |
LogNotExpr | LogicExpr | see below for other subclasses of LogicExpr |
Binary expressions¶
All classes in this subsection are subclasses of BinaryExpr.
Expression syntax | CodeQL class | Superclasses |
---|---|---|
Expr * Expr |
MulExpr | |
Expr / Expr |
DivExpr | |
Expr % Expr |
RemExpr | |
Expr + Expr |
AddExpr | |
Expr - Expr |
SubExpr | |
Expr << Expr |
LShiftExpr | |
Expr >> Expr |
RShiftExpr | |
Expr >>> Expr |
URShiftExpr | |
Expr && Expr |
AndLogicalExpr | LogicExpr |
Expr || Expr |
OrLogicalExpr | LogicExpr |
Expr < Expr |
LTExpr | ComparisonExpr |
Expr > Expr |
GTExpr | ComparisonExpr |
Expr <= Expr |
LEExpr | ComparisonExpr |
Expr >= Expr |
GEExpr | ComparisonExpr |
Expr == Expr |
EQExpr | EqualityTest |
Expr != Expr |
NEExpr | EqualityTest |
Expr & Expr |
AndBitwiseExpr | BitwiseExpr |
Expr | Expr |
OrBitwiseExpr | BitwiseExpr |
Expr ^ Expr |
XorBitwiseExpr | BitwiseExpr |
Assignment expressions¶
All classes in this table are subclasses of Assignment.
Expression syntax | CodeQL class | Superclasses |
---|---|---|
Expr = Expr |
AssignExpr | |
Expr += Expr |
AssignAddExpr | AssignOp |
Expr -= Expr |
AssignSubExpr | AssignOp |
Expr *= Expr |
AssignMulExpr | AssignOp |
Expr /= Expr |
AssignDivExpr | AssignOp |
Expr %= Expr |
AssignRemExpr | AssignOp |
Expr &= Expr |
AssignAndExpr | AssignOp |
Expr |= Expr |
AssignOrExpr | AssignOp |
Expr ^= Expr |
AssignXorExpr | AssignOp |
Expr <<= Expr |
AssignLShiftExpr | AssignOp |
Expr >>= Expr |
AssignRShiftExpr | AssignOp |
Expr >>>= Expr |
AssignURShiftExpr | AssignOp |
Accesses¶
Expression syntax examples | CodeQL class |
---|---|
this |
ThisAccess |
Outer.this |
|
super |
SuperAccess |
Outer.super |
|
x |
VarAccess |
e.f |
|
a[i] |
ArrayAccess |
f(...) |
MethodAccess |
e.m(...) |
|
String |
TypeAccess |
java.lang.String |
|
? extends Number |
WildcardTypeAccess |
? super Double |
A VarAccess that refers to a field is a FieldAccess.
Miscellaneous¶
Expression syntax examples | CodeQL class | Remarks |
---|---|---|
(int) f |
CastExpr | |
o instanceof String |
InstanceOfExpr | |
Expr ? Expr : Expr |
ConditionalExpr | |
String. class |
TypeLiteral | |
new A() |
ClassInstanceExpr | |
new String[3][2] |
ArrayCreationExpr | |
new int[] { 23, 42 } |
||
{ 23, 42 } |
ArrayInit | can only appear as an initializer or as a child of an ArrayCreationExpr |
@Annot(key=val) |
Annotation |