Skip to content

Commit c20f802

Browse files
Java: PrintAst: Supprt generic parameters
1 parent 19af3e5 commit c20f802

File tree

2 files changed

+62
-5
lines changed

2 files changed

+62
-5
lines changed

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,8 @@ class TypeVariable extends BoundedType, @typevariable {
180180
or
181181
result = getASuppliedType().(TypeVariable).getAnUltimatelySuppliedType()
182182
}
183+
184+
override string getAPrimaryQlClass() { result = "TypeVariable" }
183185
}
184186

185187
/**

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

Lines changed: 60 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,9 @@ private newtype TPrintAstNode =
8989
TElementNode(Element el) { shouldPrint(el, _) } or
9090
TAnnotationsNode(Annotatable ann) { shouldPrint(ann, _) and ann.hasAnnotation() } or
9191
TParametersNode(Callable c) { shouldPrint(c, _) and not c.hasNoParameters() } or
92-
TBaseTypesNode(ClassOrInterface ty) { shouldPrint(ty, _) }
92+
TBaseTypesNode(ClassOrInterface ty) { shouldPrint(ty, _) } or
93+
TGenericTypeNode(GenericType ty) { shouldPrint(ty, _) } or
94+
TGenericCallableNode(GenericCallable c) { shouldPrint(c, _) }
9395

9496
/**
9597
* A node in the output tree.
@@ -221,12 +223,15 @@ final class CallableNode extends ElementNode {
221223
result.(AnnotationsNode).getAnnotated() = callable
222224
or
223225
childIndex = 1 and
224-
result.(ElementNode).getElement().(Expr).isNthChildOf(callable, -1) // return type
226+
result.(GenericCallableNode).getCallable() = callable
225227
or
226228
childIndex = 2 and
227-
result.(ParametersNode).getCallable() = callable
229+
result.(ElementNode).getElement().(Expr).isNthChildOf(callable, -1) // return type
228230
or
229231
childIndex = 3 and
232+
result.(ParametersNode).getCallable() = callable
233+
or
234+
childIndex = 4 and
230235
result.(ElementNode).getElement() = callable.getBody()
231236
}
232237
}
@@ -273,10 +278,13 @@ final class ClassInterfaceNode extends ElementNode {
273278
}
274279

275280
override PrintAstNode getChild(int childIndex) {
276-
// TODO: generic params, javadoc?
277-
childIndex = -2 and
281+
// TODO: javadoc
282+
childIndex = -3 and
278283
result.(AnnotationsNode).getAnnotated() = ty
279284
or
285+
childIndex = -2 and
286+
result.(GenericTypeNode).getType() = ty
287+
or
280288
childIndex = -1 and
281289
result.(BaseTypesNode).getClassOrInterface() = ty
282290
or
@@ -341,6 +349,17 @@ final class ImportNode extends ElementNode {
341349
ImportNode() { element instanceof Import }
342350
}
343351

352+
/**
353+
* A node representing a `TypeVariable`.
354+
*/
355+
final class TypeVariableNode extends ElementNode {
356+
TypeVariableNode() { element instanceof TypeVariable }
357+
358+
override ElementNode getChild(int childIndex) {
359+
result.getElement().(Expr).isNthChildOf(element, childIndex)
360+
}
361+
}
362+
344363
/**
345364
* A node representing the annotations of an `Annotatable`.
346365
* Only rendered if there is at least one annotation.
@@ -408,6 +427,42 @@ final class BaseTypesNode extends PrintAstNode, TBaseTypesNode {
408427
ClassOrInterface getClassOrInterface() { result = ty }
409428
}
410429

430+
/**
431+
* A node representing the type parameters of a `Class` or `Interface`.
432+
* Only rendered when the type in question is indeed generic.
433+
*/
434+
final class GenericTypeNode extends PrintAstNode, TGenericTypeNode {
435+
GenericType ty;
436+
437+
GenericTypeNode() { this = TGenericTypeNode(ty) }
438+
439+
override string toString() { result = "(Generic Parameters)" }
440+
441+
override ElementNode getChild(int childIndex) {
442+
result.getElement().(TypeVariable) = ty.getTypeParameter(childIndex)
443+
}
444+
445+
GenericType getType() { result = ty }
446+
}
447+
448+
/**
449+
* A node representing the type parameters of a `Callable`.
450+
* Only rendered when the callable in question is indeed generic.
451+
*/
452+
final class GenericCallableNode extends PrintAstNode, TGenericCallableNode {
453+
GenericCallable c;
454+
455+
GenericCallableNode() { this = TGenericCallableNode(c) }
456+
457+
override string toString() { result = "(Generic Parameters)" }
458+
459+
override ElementNode getChild(int childIndex) {
460+
result.getElement().(TypeVariable) = c.getTypeParameter(childIndex)
461+
}
462+
463+
GenericCallable getCallable() { result = c }
464+
}
465+
411466
/** Holds if `node` belongs to the output tree, and its property `key` has the given `value`. */
412467
query predicate nodes(PrintAstNode node, string key, string value) { value = node.getProperty(key) }
413468

0 commit comments

Comments
 (0)