Files
codeql/java/ql/lib/semmle/code/java/PrettyPrintAst.qll
2025-06-24 10:25:06 +02:00

1130 lines
32 KiB
Plaintext

/**
* Provides pretty-printed representations of the AST, in particular top-level
* classes and interfaces.
*/
overlay[local?]
module;
import java
/**
* Holds if the pretty-printed representation of `c` has the line `s` at line
* number `line`.
*/
predicate pp(ClassOrInterface c, string s, int line) {
not c instanceof NestedType and
s =
strictconcat(string part, int i |
exists(PpAst e | getEnclosingAst*(e) = c | ppPart(e, part, line, i))
|
part order by i
)
}
private PpAst getEnclosingAst(PpAst e) {
e.(Expr).getEnclosingCallable() = result or
e.(Stmt).getEnclosingCallable() = result or
e.(Member).getDeclaringType() = result or
e.(NestedType).getEnclosingType() = result
}
/**
* An AST element to pretty-print. This is either an `Expr`, `Stmt`, `Class`,
* `Interface`, or `Member`.
*
* Subclasses specify how they are printed by giving a sequence of printable
* items. Each item in the sequence is either a string given by `getPart`, a
* line break given by `newline`, or another AST element given by `getChild`.
* The ordering of the sequence is given by the indices `i` in each of the
* three predicates.
*/
private class PpAst extends Top {
/** Gets the `i`th item to print. */
string getPart(int i) { none() }
/** Holds if the `i`th item to print is a line break. */
predicate newline(int i) { none() }
/** Gets the `i`th item to print. */
PpAst getChild(int i) { none() }
/**
* Holds if the `i`th item to print is a `PpAst` given by `getChild(i)` and
* that this should be indented.
*/
predicate indents(int i) { none() }
}
/** Gets the indentation level of the AST element `e`. */
private int indentLevel(PpAst e) {
exists(ClassOrInterface c | c = e and not c instanceof NestedType and result = 0)
or
exists(PpAst parent, int i, int lev |
e = parent.getChild(i) and
lev = indentLevel(parent) and
if parent.indents(i) then result = lev + 1 else result = lev
)
}
/**
* Gets the `i`th item to print belonging to `e`. This is similar to
* `e.getPart(i)`, but also include parentheses.
*/
private string getPart(PpAst e, int i) {
result = e.getPart(i)
or
e.(Expr).isParenthesized() and
(
i = -1 + min(int j | exists(e.getPart(j)) or e.newline(j) or exists(e.getChild(j))) and
result = "("
or
i = 1 + max(int j | exists(e.getPart(j)) or e.newline(j) or exists(e.getChild(j))) and
result = ")"
)
}
/**
* Gets the number of string parts contained in `e` and recursively in its
* children.
*/
language[monotonicAggregates]
private int numParts(PpAst e) {
result =
count(int i | exists(getPart(e, i))) +
sum(PpAst child | child = e.getChild(_) | numParts(child))
}
/**
* Gets the number of line breaks contained in `e` and recursively in its
* children.
*/
language[monotonicAggregates]
private int numLines(PpAst e) {
result = count(int i | e.newline(i)) + sum(PpAst child | child = e.getChild(_) | numLines(child))
}
/**
* Gets an index to a string part, line break, or child in `e` with rank `r`.
*/
private int getIndex(PpAst e, int r) {
result = rank[r](int i | exists(getPart(e, i)) or e.newline(i) or exists(e.getChild(i)))
}
/** Holds if the `ix`th item of `e` should be printed at `(line, pos)`. */
private predicate startPos(PpAst e, int ix, int line, int pos) {
exists(ClassOrInterface c |
c = e and not c instanceof NestedType and ix = getIndex(e, 1) and line = 0 and pos = 0
)
or
exists(PpAst parent, int parix |
startPos(parent, parix, line, pos) and e = parent.getChild(parix) and ix = getIndex(e, 1)
)
or
exists(int prevIx, int r | prevIx = getIndex(e, r - 1) and ix = getIndex(e, r) |
exists(getPart(e, prevIx)) and startPos(e, prevIx, line, pos - 1)
or
e.newline(prevIx) and startPos(e, prevIx, line - 1, _) and pos = 0
or
exists(PpAst child, int l, int p |
child = e.getChild(prevIx) and
startPos(e, prevIx, l, p) and
line = l + numLines(child) and
pos = p + numParts(child)
)
)
}
/**
* Holds if the pretty-printed representation of `e` contributes `part` to occur
* on `(line, pos)`. This does not include string parts belonging to children of
* `e`.
*/
private predicate ppPart(PpAst e, string part, int line, int pos) {
exists(int i | part = getPart(e, i) and startPos(e, i, line, pos))
or
exists(int i | exists(getPart(e, i)) or e.newline(i) |
startPos(e, i, line, 0) and
pos = -1 and
part = concat(int ind | ind in [1 .. indentLevel(e)] | " ")
)
}
/*
* Expressions
*/
private class PpArrayAccess extends PpAst, ArrayAccess {
override string getPart(int i) {
i = 1 and result = "["
or
i = 3 and result = "]"
}
override PpAst getChild(int i) {
i = 0 and result = this.getArray()
or
i = 2 and result = this.getIndexExpr()
}
}
private class PpArrayCreationExpr extends PpAst, ArrayCreationExpr {
override string getPart(int i) {
i = 0 and result = "new "
or
i = 1 and result = this.baseType()
or
i = 2 + 3 * this.dimensionIndex() and result = "["
or
i = 4 + 3 * this.dimensionIndex() and result = "]"
or
i = 4 + 3 * this.exprDims() + [1 .. this.nonExprDims()] and result = "[]"
}
private string baseType() { result = this.getType().(Array).getElementType().toString() }
private int dimensionIndex() { exists(this.getDimension(result)) }
private int exprDims() { result = max(int j | j = 0 or j = 1 + this.dimensionIndex()) }
private int nonExprDims() { result = this.getType().(Array).getDimension() - this.exprDims() }
override PpAst getChild(int i) {
exists(int j | result = this.getDimension(j) and i = 3 + 3 * j)
or
i = 5 + 3 * this.exprDims() + this.nonExprDims() and result = this.getInit()
}
}
private class PpArrayInit extends PpAst, ArrayInit {
override string getPart(int i) {
i = 0 and result = "{ "
or
exists(int j | exists(this.getInit(j)) and j != 0 and i = 2 * j and result = ", ")
or
i = 2 + 2 * max(int j | exists(this.getInit(j)) or j = 0) and result = " }"
}
override PpAst getChild(int i) { exists(int j | result = this.getInit(j) and i = 1 + 2 * j) }
}
private class PpAssignment extends PpAst, Assignment {
override string getPart(int i) {
i = 1 and
this instanceof AssignExpr and
result = " = "
or
i = 1 and
result = " " + this.(AssignOp).getOp() + " "
}
override PpAst getChild(int i) {
i = 0 and result = this.getDest()
or
i = 2 and result = this.getRhs()
}
}
private class PpLiteral extends PpAst, Literal {
override string getPart(int i) { i = 0 and result = this.getLiteral() }
}
private class PpBinaryExpr extends PpAst, BinaryExpr {
override string getPart(int i) { i = 1 and result = this.getOp() }
override PpAst getChild(int i) {
i = 0 and result = this.getLeftOperand()
or
i = 2 and result = this.getRightOperand()
}
}
private class PpUnaryExpr extends PpAst, UnaryExpr {
override string getPart(int i) {
i = 0 and result = "++" and this instanceof PreIncExpr
or
i = 0 and result = "--" and this instanceof PreDecExpr
or
i = 0 and result = "-" and this instanceof MinusExpr
or
i = 0 and result = "+" and this instanceof PlusExpr
or
i = 0 and result = "~" and this instanceof BitNotExpr
or
i = 0 and result = "!" and this instanceof LogNotExpr
or
i = 2 and result = "++" and this instanceof PostIncExpr
or
i = 2 and result = "--" and this instanceof PostDecExpr
}
override PpAst getChild(int i) { i = 1 and result = this.getExpr() }
}
private class PpCastExpr extends PpAst, CastExpr {
override string getPart(int i) {
i = 0 and result = "("
or
i = 2 and result = ")"
}
override PpAst getChild(int i) {
i = 1 and result = this.getTypeExpr()
or
i = 3 and result = this.getExpr()
}
}
private class PpSafeCastExpr extends PpAst, SafeCastExpr {
override string getPart(int i) { i = 1 and result = "as?" }
override PpAst getChild(int i) {
i = 0 and result = this.getExpr()
or
i = 2 and result = this.getTypeExpr()
}
}
private class PpImplicitCastExpr extends PpAst, ImplicitCastExpr {
override PpAst getChild(int i) { i = 0 and result = this.getExpr() }
}
private class PpImplicitNotNullExpr extends PpAst, ImplicitNotNullExpr {
override PpAst getChild(int i) { i = 0 and result = this.getExpr() }
}
private class PpImplicitCoercionToUnitExpr extends PpAst, ImplicitCoercionToUnitExpr {
override PpAst getChild(int i) { i = 0 and result = this.getExpr() }
}
private class PpCall extends PpAst, Call {
override string getPart(int i) {
i = 1 and exists(this.getQualifier()) and result = "."
or
i = 2 and
(
result = this.(MethodCall).getMethod().getName()
or
result = "this" and this instanceof ThisConstructorInvocationStmt
or
result = "super" and this instanceof SuperConstructorInvocationStmt
or
result = "new " and this instanceof ClassInstanceExpr and not this instanceof FunctionalExpr
or
result = "new /* -> */ " and this instanceof LambdaExpr
or
result = "new /* :: */ " and this instanceof MemberRefExpr
)
or
i = 4 and result = "("
or
exists(int argi |
exists(this.getArgument(argi)) and argi != 0 and i = 4 + 2 * argi and result = ", "
)
or
i = 5 + 2 * this.getNumArgument() and result = ")"
or
i = 6 + 2 * this.getNumArgument() and result = ";" and this instanceof Stmt
or
i = 6 + 2 * this.getNumArgument() and
result = " " and
exists(this.(ClassInstanceExpr).getAnonymousClass())
}
override PpAst getChild(int i) {
i = 0 and result = this.getQualifier()
or
i = 3 and result = this.(ClassInstanceExpr).getTypeName()
or
exists(int argi | i = 5 + 2 * argi and result = this.getArgument(argi))
or
i = 7 + 2 * this.getNumArgument() and result = this.(ClassInstanceExpr).getAnonymousClass()
}
}
private class PpConditionalExpr extends PpAst, ConditionalExpr {
override string getPart(int i) {
i = 1 and result = " ? "
or
i = 3 and result = " : "
}
override PpAst getChild(int i) {
i = 0 and result = this.getCondition()
or
i = 2 and result = this.getTrueExpr()
or
i = 4 and result = this.getFalseExpr()
}
}
private class PpSwitchExpr extends PpAst, SwitchExpr {
override string getPart(int i) {
i = 0 and result = "switch ("
or
i = 2 and result = ") {"
or
i = 4 + 2 * count(this.getAStmt()) and result = "}"
}
override predicate newline(int i) { i = 3 or this.hasChildAt(_, i - 1) }
override PpAst getChild(int i) {
i = 1 and result = this.getExpr()
or
this.hasChildAt(result, i)
}
override predicate indents(int i) { this.hasChildAt(_, i) }
private predicate hasChildAt(PpAst c, int i) {
exists(int index | c = this.getStmt(index) and i = 4 + 2 * index)
}
}
private class PpInstanceOfExpr extends PpAst, InstanceOfExpr {
override string getPart(int i) {
i = 1 and result = " instanceof "
or
i = 3 and result = " " and this.getPattern() instanceof LocalVariableDeclExpr
or
i = 4 and
result = this.getPattern().asBindingOrUnnamedPattern().getName()
}
override PpAst getChild(int i) {
i = 0 and result = this.getExpr()
or
i = 2 and result = this.getTypeName()
or
i = 2 and result = this.getPattern().asRecordPattern()
}
}
private class PpLocalVariableDeclExpr extends PpAst, LocalVariableDeclExpr {
override string getPart(int i) {
i = 0 and
(if this.isAnonymous() then result = "_" else result = this.getName())
or
i = 1 and result = " = " and exists(this.getInit())
}
override PpAst getChild(int i) { i = 2 and result = this.getInit() }
}
private class PpTypeLiteral extends PpAst, TypeLiteral {
override string getPart(int i) { i = 1 and result = ".class" }
override PpAst getChild(int i) { i = 0 and result = this.getTypeName() }
}
private class PpThisAccess extends PpAst, ThisAccess {
override string getPart(int i) {
i = 1 and
if exists(this.getQualifier()) then result = ".this" else result = "this"
}
override PpAst getChild(int i) { i = 0 and result = this.getQualifier() }
}
private class PpSuperAccess extends PpAst, SuperAccess {
override string getPart(int i) {
i = 1 and
if exists(this.getQualifier()) then result = ".super" else result = "super"
}
override PpAst getChild(int i) { i = 0 and result = this.getQualifier() }
}
private class PpVarAccess extends PpAst, VarAccess {
override string getPart(int i) {
exists(string name | name = this.(VarAccess).getVariable().getName() and i = 1 |
if exists(this.getQualifier()) then result = "." + name else result = name
)
}
override PpAst getChild(int i) { i = 0 and result = this.getQualifier() }
}
private class PpTypeAccess extends PpAst, TypeAccess {
override string getPart(int i) { i = 0 and result = this.toString() }
}
private class PpArrayTypeAccess extends PpAst, ArrayTypeAccess {
override string getPart(int i) { i = 1 and result = "[]" }
override PpAst getChild(int i) { i = 0 and result = this.getComponentName() }
}
private class PpUnionTypeAccess extends PpAst, UnionTypeAccess {
override string getPart(int i) {
exists(int j | i = 2 * j - 1 and j != 0 and result = " | " and exists(this.getAlternative(j)))
}
private Expr getAlternative(int j) { result = this.getAnAlternative() and j = result.getIndex() }
override PpAst getChild(int i) { exists(int j | i = 2 * j and result = this.getAlternative(j)) }
}
private class PpIntersectionTypeAccess extends PpAst, IntersectionTypeAccess {
override string getPart(int i) {
exists(int j | i = 2 * j - 1 and j != 0 and result = " & " and exists(this.getBound(j)))
}
override PpAst getChild(int i) { exists(int j | i = 2 * j and result = this.getBound(j)) }
}
private class PpPackageAccess extends PpAst, PackageAccess {
override string getPart(int i) { i = 0 and result = "package" }
}
private class PpWildcardTypeAccess extends PpAst, WildcardTypeAccess {
override string getPart(int i) {
i = 0 and result = "?"
or
i = 1 and result = " extends " and exists(this.getUpperBound())
or
i = 1 and result = " super " and exists(this.getLowerBound())
}
override PpAst getChild(int i) {
i = 2 and result = this.getUpperBound()
or
i = 2 and result = this.getLowerBound()
}
}
/*
* Statements
*/
private class PpBlock extends PpAst, BlockStmt {
override string getPart(int i) {
i = 0 and result = "{"
or
i = 2 + 2 * this.getNumStmt() and result = "}"
}
override predicate newline(int i) { i = 1 or this.hasChildAt(_, i - 1) }
override PpAst getChild(int i) { this.hasChildAt(result, i) }
override predicate indents(int i) { this.hasChildAt(_, i) }
private predicate hasChildAt(PpAst c, int i) {
exists(int index | c = this.getStmt(index) and i = 2 + 2 * index)
}
}
private class PpIfStmt extends PpAst, IfStmt {
override string getPart(int i) {
i = 0 and result = "if ("
or
i = 2 and result = ")"
or
i = 3 and result = " " and this.getThen() instanceof BlockStmt
or
exists(this.getElse()) and
(
i = 5 and result = " " and this.getThen() instanceof BlockStmt
or
i = 6 and result = "else"
or
i = 7 and result = " " and this.getElse() instanceof BlockStmt
)
}
override predicate newline(int i) {
i = 3 and not this.getThen() instanceof BlockStmt
or
exists(this.getElse()) and
(
i = 5 and not this.getThen() instanceof BlockStmt
or
i = 7 and not this.getElse() instanceof BlockStmt
)
}
override PpAst getChild(int i) {
i = 1 and result = this.getCondition()
or
i = 4 and result = this.getThen()
or
i = 8 and result = this.getElse()
}
override predicate indents(int i) {
i = 4 and not this.getThen() instanceof BlockStmt
or
i = 8 and not this.getElse() instanceof BlockStmt
}
}
private class PpForStmt extends PpAst, ForStmt {
override string getPart(int i) {
i = 0 and result = "for ("
or
i = 2 and result = " " and this.getInit(0) instanceof LocalVariableDeclExpr
or
exists(int j | j > 0 and exists(this.getInit(j)) and i = 2 + 2 * j and result = ", ")
or
i = 1 + this.lastInitIndex() and result = "; "
or
i = 3 + this.lastInitIndex() and result = "; "
or
exists(int j |
j > 0 and exists(this.getUpdate(j)) and i = 3 + this.lastInitIndex() + 2 * j and result = ", "
)
or
i = 1 + this.lastUpdateIndex() and result = ")"
or
i = 2 + this.lastUpdateIndex() and result = " " and this.getStmt() instanceof BlockStmt
}
private int lastInitIndex() { result = 3 + 2 * max(int j | exists(this.getInit(j))) }
private int lastUpdateIndex() {
result = 4 + this.lastInitIndex() + 2 * max(int j | exists(this.getUpdate(j)))
}
override predicate newline(int i) {
i = 2 + this.lastUpdateIndex() and not this.getStmt() instanceof BlockStmt
}
override PpAst getChild(int i) {
i = 1 and result = this.getInit(0).(LocalVariableDeclExpr).getTypeAccess()
or
exists(int j | result = this.getInit(j) and i = 3 + 2 * j)
or
i = 2 + this.lastInitIndex() and result = this.getCondition()
or
exists(int j | result = this.getUpdate(j) and i = 4 + this.lastInitIndex() + 2 * j)
or
i = 3 + this.lastUpdateIndex() and result = this.getStmt()
}
override predicate indents(int i) {
i = 3 + this.lastUpdateIndex() and not this.getStmt() instanceof BlockStmt
}
}
private class PpEnhancedForStmt extends PpAst, EnhancedForStmt {
override string getPart(int i) {
i = 0 and result = "for ("
or
i = 2 and result = " "
or
i = 4 and result = " : "
or
i = 6 and
if this.getStmt() instanceof BlockStmt then result = ") " else result = ")"
}
override PpAst getChild(int i) {
i = 1 and result = this.getVariable().getTypeAccess()
or
i = 3 and result = this.getVariable()
or
i = 5 and result = this.getExpr()
or
i = 7 and result = this.getStmt()
}
override predicate indents(int i) { i = 7 and not this.getStmt() instanceof BlockStmt }
}
private class PpWhileStmt extends PpAst, WhileStmt {
override string getPart(int i) {
i = 0 and result = "while ("
or
i = 2 and result = ")"
or
i = 3 and result = " " and this.getStmt() instanceof BlockStmt
}
override predicate newline(int i) { i = 3 and not this.getStmt() instanceof BlockStmt }
override PpAst getChild(int i) {
i = 1 and result = this.getCondition()
or
i = 4 and result = this.getStmt()
}
override predicate indents(int i) { i = 4 and not this.getStmt() instanceof BlockStmt }
}
private class PpDoStmt extends PpAst, DoStmt {
override string getPart(int i) {
i = 0 and result = "do"
or
i in [1, 3] and result = " " and this.getStmt() instanceof BlockStmt
or
i = 4 and result = "while ("
or
i = 6 and result = ");"
}
override predicate newline(int i) { i in [1, 3] and not this.getStmt() instanceof BlockStmt }
override PpAst getChild(int i) {
i = 2 and result = this.getStmt()
or
i = 5 and result = this.getCondition()
}
override predicate indents(int i) { i = 2 and not this.getStmt() instanceof BlockStmt }
}
private class PpTryStmt extends PpAst, TryStmt {
override string getPart(int i) {
i = 0 and result = "try "
or
i = 1 and result = "(" and exists(this.getAResource())
or
exists(int j | exists(this.getResourceExpr(j)) and i = 3 + 2 * j and result = ";")
or
i = 2 + this.lastResourceIndex() and result = ") " and exists(this.getAResource())
or
i = 1 + this.lastCatchIndex() and result = " finally " and exists(this.getFinally())
}
private int lastResourceIndex() {
result = 2 + 2 * max(int j | exists(this.getResource(j)) or j = 0)
}
private int lastCatchIndex() {
result = 4 + this.lastResourceIndex() + max(int j | exists(this.getCatchClause(j)) or j = 0)
}
override PpAst getChild(int i) {
exists(int j | i = 2 + 2 * j and result = this.getResource(j))
or
i = 3 + this.lastResourceIndex() and result = this.getBlock()
or
exists(int j | i = 4 + this.lastResourceIndex() + j and result = this.getCatchClause(j))
or
i = 2 + this.lastCatchIndex() and result = this.getFinally()
}
}
private class PpCatchClause extends PpAst, CatchClause {
override string getPart(int i) {
i = 0 and result = " catch ("
or
i = 2 and result = " "
or
i = 4 and result = ") "
}
override PpAst getChild(int i) {
i = 1 and result = this.getVariable().getTypeAccess()
or
i = 3 and result = this.getVariable()
or
i = 5 and result = this.getBlock()
}
}
private class PpSwitchStmt extends PpAst, SwitchStmt {
override string getPart(int i) {
i = 0 and result = "switch ("
or
i = 2 and result = ") {"
or
i = 4 + 2 * count(this.getAStmt()) and result = "}"
}
override predicate newline(int i) { i = 3 or this.hasChildAt(_, i - 1) }
override PpAst getChild(int i) {
i = 1 and result = this.getExpr()
or
this.hasChildAt(result, i)
}
override predicate indents(int i) { this.hasChildAt(_, i) }
private predicate hasChildAt(PpAst c, int i) {
exists(int index | c = this.getStmt(index) and i = 4 + 2 * index)
}
}
private predicate isNonNullDefaultCase(SwitchCase sc) {
sc instanceof DefaultCase and not sc instanceof NullDefaultCase
}
private class PpSwitchCase extends PpAst, SwitchCase {
PpSwitchCase() { not this instanceof PatternCase }
override string getPart(int i) {
i = 0 and result = "default" and isNonNullDefaultCase(this)
or
i = 0 and result = "case null, default" and this instanceof NullDefaultCase
or
i = 0 and result = "case " and not this instanceof DefaultCase
or
exists(int j | i = 2 * j and j != 0 and result = ", " and exists(this.(ConstCase).getValue(j)))
or
i = 1 + this.lastConstCaseValueIndex() and result = ":" and not this.isRule()
or
i = 1 + this.lastConstCaseValueIndex() and result = " -> " and this.isRule()
or
i = 3 + this.lastConstCaseValueIndex() and result = ";" and exists(this.getRuleExpression())
}
private int lastConstCaseValueIndex() {
result = 1 + 2 * (max(int j | j = 0 or exists(this.(ConstCase).getValue(j))))
}
override PpAst getChild(int i) {
exists(int j | i = 1 + 2 * j and result = this.(ConstCase).getValue(j))
or
i = 2 + this.lastConstCaseValueIndex() and result = this.getRuleExpression()
or
i = 2 + this.lastConstCaseValueIndex() and result = this.getRuleStatement()
}
}
private class PpPatternCase extends PpAst, PatternCase {
private predicate isAnonymousPattern(int n) {
this.getPattern(n).asBindingOrUnnamedPattern().isAnonymous()
}
override string getPart(int i) {
exists(int n, int base | exists(this.getPattern(n)) and base = n * 4 |
i = base and
(if n = 0 then result = "case " else result = ", ")
or
i = base + 2 and
this.getPattern(n) instanceof LocalVariableDeclExpr and
(
exists(this.getPattern(n).asBindingOrUnnamedPattern().getTypeAccess())
or
not this.isAnonymousPattern(n)
) and
result = " "
or
i = base + 3 and
(
if this.isAnonymousPattern(n)
then result = "_"
else result = this.getPattern(n).asBindingOrUnnamedPattern().getName()
)
)
or
exists(int base | base = (max(int n | exists(this.getPattern(n))) + 1) * 4 |
i = base and result = ":" and not this.isRule()
or
i = base and result = " -> " and this.isRule()
or
i = base + 2 and result = ";" and exists(this.getRuleExpression())
)
}
override PpAst getChild(int i) {
exists(int n, int base | exists(this.getPattern(n)) and base = n * 4 |
i = base + 1 and
result = this.getPattern(n).asBindingOrUnnamedPattern().getTypeAccess()
or
i = base + 1 and result = this.getPattern(n).asRecordPattern()
)
or
exists(int base | base = (max(int n | exists(this.getPattern(n))) + 1) * 4 |
i = base + 1 and result = this.getRuleExpression()
or
i = base + 1 and result = this.getRuleStatement()
)
}
}
private class PpSynchronizedStmt extends PpAst, SynchronizedStmt {
override string getPart(int i) {
i = 0 and result = "synchronized ("
or
i = 2 and result = ")"
or
i = 3 and result = " "
}
override PpAst getChild(int i) {
i = 1 and result = this.getExpr()
or
i = 4 and result = this.getBlock()
}
}
private class PpReturnStmt extends PpAst, ReturnStmt {
override string getPart(int i) {
if exists(this.getResult())
then
i = 0 and result = "return "
or
i = 2 and result = ";"
else (
i = 0 and result = "return;"
)
}
override PpAst getChild(int i) { i = 1 and result = this.getResult() }
}
private class PpThrowStmt extends PpAst, ThrowStmt {
override string getPart(int i) {
i = 0 and result = "throw "
or
i = 2 and result = ";"
}
override PpAst getChild(int i) { i = 1 and result = this.getExpr() }
}
private class PpBreakStmt extends PpAst, BreakStmt {
override string getPart(int i) {
i = 0 and result = "break"
or
i = 1 and result = " " and exists(this.getLabel())
or
i = 2 and result = this.getLabel()
or
i = 3 and result = ";"
}
}
private class PpYieldStmt extends PpAst, YieldStmt {
override string getPart(int i) {
i = 0 and result = "yield "
or
i = 2 and result = ";"
}
override PpAst getChild(int i) { i = 1 and result = this.getValue() }
}
private class PpContinueStmt extends PpAst, ContinueStmt {
override string getPart(int i) {
i = 0 and result = "continue"
or
i = 1 and result = " " and exists(this.getLabel())
or
i = 2 and result = this.getLabel()
or
i = 3 and result = ";"
}
}
private class PpEmptyStmt extends PpAst, EmptyStmt {
override string getPart(int i) { i = 0 and result = ";" }
}
private class PpExprStmt extends PpAst, ExprStmt {
override string getPart(int i) { i = 1 and result = ";" }
override PpAst getChild(int i) { i = 0 and result = this.getExpr() }
}
private class PpLabeledStmt extends PpAst, LabeledStmt {
override string getPart(int i) {
i = 0 and result = this.getLabel()
or
i = 1 and result = ":"
}
override predicate newline(int i) { i = 2 }
override PpAst getChild(int i) { i = 3 and result = this.getStmt() }
}
private class PpAssertStmt extends PpAst, AssertStmt {
override string getPart(int i) {
i = 0 and result = "assert "
or
i = 2 and result = " : " and exists(this.getMessage())
or
i = 4 and result = ";"
}
override PpAst getChild(int i) {
i = 1 and result = this.getExpr()
or
i = 3 and result = this.getMessage()
}
}
private class PpLocalVariableDeclStmt extends PpAst, LocalVariableDeclStmt {
override string getPart(int i) {
i = 0 and not exists(this.getAVariable().getTypeAccess()) and result = "var"
or
i = 1 and result = " "
or
exists(int v | v > 1 and i = 2 * v - 1 and result = ", " and v = this.getAVariableIndex())
or
i = 2 * max(this.getAVariableIndex()) + 1 and result = ";"
}
override PpAst getChild(int i) {
i = 0 and result = this.getAVariable().getTypeAccess()
or
exists(int v | i = 2 * v and result = this.getVariable(v))
}
}
private class PpLocalTypeDeclStmt extends PpAst, LocalTypeDeclStmt {
override PpAst getChild(int i) { i = 0 and result = this.getLocalType() }
}
/*
* Classes, interfaces, and members
*/
private string getMemberId(Member m) {
result = m.(Callable).getSignature()
or
result = m.getName() and not m instanceof Callable
}
private class PpClassOrInterface extends PpAst, ClassOrInterface {
override string getPart(int i) {
not this instanceof AnonymousClass and
(
result = getModifierPart(this, i)
or
i = 0 and result = "class " and this instanceof Class
or
i = 0 and result = "interface " and this instanceof Interface
or
i = 1 and result = this.getName()
or
i = 2 and result = " "
)
or
i = 3 and result = "{"
or
i = 5 + 3 * max(this.memberRank(_)) and result = "}"
}
override predicate newline(int i) {
exists(int ci | ci = 3 + 3 * this.memberRank(_) | i = ci - 1 or i = ci + 1)
}
private int memberRank(Member member) {
member =
rank[result](Member m |
m = this.getAMember()
|
m order by m.getLocation().getStartLine(), m.getLocation().getStartColumn(), getMemberId(m)
)
}
override PpAst getChild(int i) { this.memberRank(result) * 3 + 3 = i }
override predicate indents(int i) { this.memberRank(_) * 3 + 3 = i }
}
private string getModifierPart(Modifiable m, int i) {
m.isAbstract() and result = "abstract " and i = -12
or
m.isPublic() and result = "public " and i = -11
or
m.isProtected() and result = "protected " and i = -10
or
m.isPrivate() and result = "private " and i = -9
or
m.isStatic() and result = "static " and i = -8
or
m.isFinal() and result = "final " and i = -7
or
m.isVolatile() and result = "volatile " and i = -6
or
m.isSynchronized() and result = "synchronized " and i = -5
or
m.isNative() and result = "native " and i = -4
or
m.isDefault() and result = "default " and i = -3
or
m.isTransient() and result = "transient " and i = -2
or
m.isStrictfp() and result = "strictfp " and i = -1
}
private class PpField extends PpAst, Field {
override string getPart(int i) {
result = getModifierPart(this, i)
or
i = 0 and result = this.getType().toString()
or
i = 1 and result = " "
or
i = 2 and result = this.getName()
or
i = 3 and result = ";"
}
}
private class PpCallable extends PpAst, Callable {
override string getPart(int i) {
result = getModifierPart(this, i)
or
i = 0 and result = this.getReturnType().toString() and this instanceof Method
or
i = 1 and result = " " and this instanceof Method
or
i = 2 and
(if this.getName() = "" then result = "<no name>" else result = this.getName())
or
i = 3 and result = "("
or
exists(Parameter p, int n | this.getParameter(n) = p |
i = 4 + 4 * n and result = p.getType().toString()
or
i = 5 + 4 * n and result = " "
or
i = 6 + 4 * n and result = p.getName()
or
i = 7 + 4 * n and result = ", " and n < this.getNumberOfParameters() - 1
)
or
i = 4 + 4 * this.getNumberOfParameters() and result = ") "
or
i = 5 + 4 * this.getNumberOfParameters() and
not exists(this.getBody()) and
result = "{ <missing body> }"
}
override PpAst getChild(int i) {
i = 5 + 4 * this.getNumberOfParameters() and result = this.getBody()
}
}
private class PpRecordPattern extends PpAst, RecordPatternExpr {
override string getPart(int i) {
i = 0 and result = this.getType().getName()
or
i = 1 and result = "("
or
i = 1 + ((any(int x | x >= 1 and exists(this.getSubPattern(x)))) * 4) and result = ", "
or
i = 1 + (count(this.getSubPattern(_)) * 4) and result = ")"
or
exists(int x, LocalVariableDeclExpr v, int offset | v = this.getSubPattern(x) |
i = (offset) + (x * 4) and
(
offset = 2 and not exists(v.getTypeAccess()) and result = "var"
or
offset = 3 and result = " "
)
)
}
override PpAst getChild(int i) {
exists(int x, PatternExpr subPattern, int offset | subPattern = this.getSubPattern(x) |
i = (offset) + (x * 4) and
(
result = subPattern.(RecordPatternExpr) and offset = 2
or
result = subPattern.(LocalVariableDeclExpr).getTypeAccess() and offset = 2
or
result = subPattern.(LocalVariableDeclExpr) and offset = 4
)
)
}
}