Skip to content

Commit 9c8a468

Browse files
Java: PrintAst: Add synthetic nodes for other declarations
1 parent 3e960c1 commit 9c8a468

File tree

2 files changed

+80
-10
lines changed

2 files changed

+80
-10
lines changed

java/ql/src/semmle/code/java/PrintAst.qll

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,9 @@ private predicate locationSortKeys(Element ast, string file, int line, int colum
114114
private newtype TPrintAstNode =
115115
TElementNode(Element el) { shouldPrint(el, _) } or
116116
TForInitNode(ForStmt fs) { shouldPrint(fs, _) and exists(fs.getAnInit()) } or
117+
TLocalVarDeclNode(LocalVariableDeclExpr lvde) {
118+
shouldPrint(lvde, _) and lvde.getParent() instanceof LocalVarDeclParent
119+
} or
117120
TAnnotationsNode(Annotatable ann) {
118121
shouldPrint(ann, _) and ann.hasAnnotation() and not partOfAnnotation(ann)
119122
} or
@@ -330,6 +333,46 @@ final class ForStmtNode extends ExprStmtNode {
330333
}
331334
}
332335

336+
/**
337+
* An element that can be the parent of a `LocalVariableDeclExpr` for which we want
338+
* to use a synthetic node to hold the variable declaration and its `TypeAccess`.
339+
*/
340+
private class LocalVarDeclParent extends ExprOrStmt {
341+
LocalVarDeclParent() {
342+
this instanceof EnhancedForStmt or
343+
this instanceof CatchClause or
344+
this.(InstanceOfExpr).isPattern()
345+
}
346+
347+
/** Gets the variable declaration that this element contains */
348+
LocalVariableDeclExpr getVariable() { result.getParent() = this }
349+
350+
/** Gets the type access of the variable */
351+
Expr getTypeAccess() { result = getVariable().getTypeAccess() }
352+
}
353+
354+
/**
355+
* A node representing an element that can be the parent of a `LocalVariableDeclExpr` for which we
356+
* want to use a synthetic node to variable declaration and its type access.
357+
*
358+
* Excludes:
359+
* - `LocalVariableDeclStmt` because a synthetic node isn't needed
360+
* - `ForStmt` becasue a different synthetic node is already used
361+
*/
362+
final class LocalVarDeclParentNode extends ExprStmtNode {
363+
LocalVarDeclParent lvdp;
364+
365+
LocalVarDeclParentNode() { lvdp = element }
366+
367+
override PrintAstNode getChild(int childIndex) {
368+
result = super.getChild(childIndex) and
369+
not result.(ElementNode).getElement() = [lvdp.getVariable(), lvdp.getTypeAccess()]
370+
or
371+
childIndex = lvdp.getVariable().getIndex() and
372+
result.(LocalVarDeclSynthNode).getVariable() = lvdp.getVariable()
373+
}
374+
}
375+
333376
/**
334377
* A node representing a `Callable`, such as method declaration.
335378
*/
@@ -509,6 +552,30 @@ final class ForInitNode extends PrintAstNode, TForInitNode {
509552
ForStmt getForStmt() { result = fs }
510553
}
511554

555+
/**
556+
* A synthetic node holding a `LocalVariableDeclExpr` and its type access.
557+
*/
558+
final class LocalVarDeclSynthNode extends PrintAstNode, TLocalVarDeclNode {
559+
LocalVariableDeclExpr lvde;
560+
561+
LocalVarDeclSynthNode() { this = TLocalVarDeclNode(lvde) }
562+
563+
override string toString() { result = "(Local Variable Declaration)" }
564+
565+
override ElementNode getChild(int childIndex) {
566+
childIndex = 0 and
567+
result.getElement() = lvde.getTypeAccess()
568+
or
569+
childIndex = 1 and
570+
result.getElement() = lvde
571+
}
572+
573+
/**
574+
* Gets the underlying `LocalVariableDeclExpr`
575+
*/
576+
LocalVariableDeclExpr getVariable() { result = lvde }
577+
}
578+
512579
/**
513580
* A node representing the annotations of an `Annotatable`.
514581
* Only rendered if there is at least one annotation.

java/ql/test/library-tests/java7/MultiCatch/PrintAst.expected

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,11 @@ MultiCatch.java:
2121
# 14| 0: [ClassInstanceExpr] new SQLException(...)
2222
# 14| -3: [TypeAccess] SQLException
2323
# 15| 0: [CatchClause] stmt
24-
# 15| -1: [UnionTypeAccess] ...|...
25-
# 15| 0: [TypeAccess] IOException
26-
# 15| 1: [TypeAccess] SQLException
27-
# 15| 0: [LocalVariableDeclExpr] e
24+
#-----| 0: (Local Variable Declaration)
25+
# 15| 0: [UnionTypeAccess] ...|...
26+
# 15| 0: [TypeAccess] IOException
27+
# 15| 1: [TypeAccess] SQLException
28+
# 15| 1: [LocalVariableDeclExpr] e
2829
# 16| 1: [BlockStmt] stmt
2930
# 17| 0: [ExprStmt] stmt
3031
# 17| 0: [MethodAccess] printStackTrace(...)
@@ -55,10 +56,11 @@ MultiCatch.java:
5556
# 30| 0: [ClassInstanceExpr] new Exception(...)
5657
# 30| -3: [TypeAccess] Exception
5758
# 31| 0: [CatchClause] stmt
58-
# 31| -1: [UnionTypeAccess] ...|...
59-
# 31| 0: [TypeAccess] IOException
60-
# 31| 1: [TypeAccess] SQLException
61-
# 31| 0: [LocalVariableDeclExpr] e
59+
#-----| 0: (Local Variable Declaration)
60+
# 31| 0: [UnionTypeAccess] ...|...
61+
# 31| 0: [TypeAccess] IOException
62+
# 31| 1: [TypeAccess] SQLException
63+
# 31| 1: [LocalVariableDeclExpr] e
6264
# 32| 1: [BlockStmt] stmt
6365
# 35| 4: [Method] ordinaryCatch
6466
# 35| 3: [TypeAccess] void
@@ -69,6 +71,7 @@ MultiCatch.java:
6971
# 39| 0: [ClassInstanceExpr] new IOException(...)
7072
# 39| -3: [TypeAccess] IOException
7173
# 40| 0: [CatchClause] stmt
72-
# 40| -1: [TypeAccess] Exception
73-
# 40| 0: [LocalVariableDeclExpr] e
74+
#-----| 0: (Local Variable Declaration)
75+
# 40| 0: [TypeAccess] Exception
76+
# 40| 1: [LocalVariableDeclExpr] e
7477
# 41| 1: [BlockStmt] stmt

0 commit comments

Comments
 (0)