@@ -113,6 +113,10 @@ private predicate locationSortKeys(Element ast, string file, int line, int colum
113113 */
114114private newtype TPrintAstNode =
115115 TElementNode ( Element el ) { shouldPrint ( el , _) } or
116+ TForInitNode ( ForStmt fs ) { shouldPrint ( fs , _) and exists ( fs .getAnInit ( ) ) } or
117+ TLocalVarDeclNode ( LocalVariableDeclExpr lvde ) {
118+ shouldPrint ( lvde , _) and lvde .getParent ( ) instanceof SingleLocalVarDeclParent
119+ } or
116120 TAnnotationsNode ( Annotatable ann ) {
117121 shouldPrint ( ann , _) and ann .hasAnnotation ( ) and not partOfAnnotation ( ann )
118122 } or
@@ -221,56 +225,148 @@ abstract class ElementNode extends PrintAstNode, TElementNode {
221225 final Element getElement ( ) { result = element }
222226}
223227
228+ /**
229+ * A node representing an `Expr` or a `Stmt`.
230+ */
231+ class ExprStmtNode extends ElementNode {
232+ ExprStmtNode ( ) { element instanceof ExprOrStmt }
233+
234+ override PrintAstNode getChild ( int childIndex ) {
235+ exists ( Element el | result .( ElementNode ) .getElement ( ) = el |
236+ el .( Expr ) .isNthChildOf ( element , childIndex )
237+ or
238+ el .( Stmt ) .isNthChildOf ( element , childIndex )
239+ )
240+ }
241+ }
242+
243+ /**
244+ * Holds if the given expression is part of an annotation.
245+ */
224246private predicate partOfAnnotation ( Expr e ) {
225247 e instanceof Annotation
226248 or
227249 e instanceof ArrayInit and
228250 partOfAnnotation ( e .getParent ( ) )
229251}
230252
231- private Expr getAnAnnotationChild ( Expr e ) {
232- partOfAnnotation ( e ) and
233- (
234- result = e .( Annotation ) .getValue ( _)
253+ /**
254+ * A node representing an `Expr` that is part of an annotation.
255+ */
256+ final class AnnotationPartNode extends ExprStmtNode {
257+ AnnotationPartNode ( ) { partOfAnnotation ( element ) }
258+
259+ override ElementNode getChild ( int childIndex ) {
260+ result .getElement ( ) =
261+ rank [ childIndex ] ( Element ch , string file , int line , int column |
262+ ch = getAnAnnotationChild ( ) and locationSortKeys ( ch , file , line , column )
263+ |
264+ ch order by file , line , column
265+ )
266+ }
267+
268+ private Expr getAnAnnotationChild ( ) {
269+ result = element .( Annotation ) .getValue ( _)
235270 or
236- result = e .( ArrayInit ) .getAnInit ( )
271+ result = element .( ArrayInit ) .getAnInit ( )
237272 or
238- result = e .( ArrayInit ) .( Annotatable ) .getAnAnnotation ( )
239- )
273+ result = element .( ArrayInit ) .( Annotatable ) .getAnAnnotation ( )
274+ }
240275}
241276
242277/**
243- * An node representing an `Expr` or a `Stmt `.
278+ * A node representing a `LocalVariableDeclExpr `.
244279 */
245- final class ExprStmtNode extends ElementNode {
246- ExprStmtNode ( ) { element instanceof ExprOrStmt }
280+ final class LocalVarDeclExprNode extends ExprStmtNode {
281+ LocalVarDeclExprNode ( ) { element instanceof LocalVariableDeclExpr }
247282
248283 override PrintAstNode getChild ( int childIndex ) {
249- exists ( Element el | result .( ElementNode ) .getElement ( ) = el |
250- el .( Expr ) .isNthChildOf ( element , childIndex ) and
251- not partOfAnnotation ( element )
252- or
253- el .( Stmt ) .isNthChildOf ( element , childIndex )
254- or
255- childIndex = - 4 and
256- el = element .( ClassInstanceExpr ) .getAnonymousClass ( )
257- or
258- childIndex = 0 and
259- el = element .( LocalClassDeclStmt ) .getLocalClass ( )
260- or
261- partOfAnnotation ( element ) and
262- el =
263- rank [ childIndex ] ( Element ch , string file , int line , int column |
264- ch = getAnAnnotationChild ( element ) and locationSortKeys ( ch , file , line , column )
265- |
266- ch order by file , line , column
267- )
268- )
284+ result = super .getChild ( childIndex )
269285 or
270- exists ( Element el | result .( AnnotationsNode ) .getAnnotated ( ) = el |
271- childIndex = - 2 and
272- el = element .( LocalVariableDeclExpr ) .getVariable ( )
273- )
286+ childIndex = - 2 and
287+ result .( AnnotationsNode ) .getAnnotated ( ) = element .( LocalVariableDeclExpr ) .getVariable ( )
288+ }
289+ }
290+
291+ /**
292+ * A node representing a `ClassInstanceExpr`.
293+ */
294+ final class ClassInstanceExprNode extends ExprStmtNode {
295+ ClassInstanceExprNode ( ) { element instanceof ClassInstanceExpr }
296+
297+ override ElementNode getChild ( int childIndex ) {
298+ result = super .getChild ( childIndex )
299+ or
300+ childIndex = - 4 and
301+ result .getElement ( ) = element .( ClassInstanceExpr ) .getAnonymousClass ( )
302+ }
303+ }
304+
305+ /**
306+ * A node representing a `LocalClassDeclStmt`.
307+ */
308+ final class LocalClassDeclStmtNode extends ExprStmtNode {
309+ LocalClassDeclStmtNode ( ) { element instanceof LocalClassDeclStmt }
310+
311+ override ElementNode getChild ( int childIndex ) {
312+ result = super .getChild ( childIndex )
313+ or
314+ childIndex = 0 and
315+ result .getElement ( ) = element .( LocalClassDeclStmt ) .getLocalClass ( )
316+ }
317+ }
318+
319+ /**
320+ * A node representing a `ForStmt`.
321+ */
322+ final class ForStmtNode extends ExprStmtNode {
323+ ForStmtNode ( ) { element instanceof ForStmt }
324+
325+ override PrintAstNode getChild ( int childIndex ) {
326+ childIndex >= 1 and
327+ result = super .getChild ( childIndex )
328+ or
329+ childIndex = 0 and
330+ result .( ForInitNode ) .getForStmt ( ) = element
331+ }
332+ }
333+
334+ /**
335+ * An element that can be the parent of up to one `LocalVariableDeclExpr` for which we want
336+ * to use a synthetic node to hold the variable declaration and its `TypeAccess`.
337+ */
338+ private class SingleLocalVarDeclParent extends ExprOrStmt {
339+ SingleLocalVarDeclParent ( ) {
340+ this instanceof EnhancedForStmt or
341+ this instanceof CatchClause or
342+ this .( InstanceOfExpr ) .isPattern ( )
343+ }
344+
345+ /** Gets the variable declaration that this element contains */
346+ LocalVariableDeclExpr getVariable ( ) { result .getParent ( ) = this }
347+
348+ /** Gets the type access of the variable */
349+ Expr getTypeAccess ( ) { result = getVariable ( ) .getTypeAccess ( ) }
350+ }
351+
352+ /**
353+ * A node representing an element that can be the parent of up to one `LocalVariableDeclExpr` for which we
354+ * want to use a synthetic node to variable declaration and its type access.
355+ *
356+ * Excludes `LocalVariableDeclStmt` and `ForStmt`, as they can hold multiple declarations.
357+ * For these cases, either a synthetic node is not necassary or a different synthetic node is used.
358+ */
359+ final class SingleLocalVarDeclParentNode extends ExprStmtNode {
360+ SingleLocalVarDeclParent lvdp ;
361+
362+ SingleLocalVarDeclParentNode ( ) { lvdp = element }
363+
364+ override PrintAstNode getChild ( int childIndex ) {
365+ result = super .getChild ( childIndex ) and
366+ not result .( ElementNode ) .getElement ( ) = [ lvdp .getVariable ( ) , lvdp .getTypeAccess ( ) ]
367+ or
368+ childIndex = lvdp .getVariable ( ) .getIndex ( ) and
369+ result .( LocalVarDeclSynthNode ) .getVariable ( ) = lvdp .getVariable ( )
274370 }
275371}
276372
@@ -432,6 +528,51 @@ final class TypeVariableNode extends ElementNode {
432528 }
433529}
434530
531+ /**
532+ * A node representing the initializers of a `ForStmt`.
533+ */
534+ final class ForInitNode extends PrintAstNode , TForInitNode {
535+ ForStmt fs ;
536+
537+ ForInitNode ( ) { this = TForInitNode ( fs ) }
538+
539+ override string toString ( ) { result = "(For Initializers) " }
540+
541+ override ElementNode getChild ( int childIndex ) {
542+ childIndex >= 0 and
543+ result .getElement ( ) .( Expr ) .isNthChildOf ( fs , - childIndex )
544+ }
545+
546+ /**
547+ * Gets the underlying `ForStmt`.
548+ */
549+ ForStmt getForStmt ( ) { result = fs }
550+ }
551+
552+ /**
553+ * A synthetic node holding a `LocalVariableDeclExpr` and its type access.
554+ */
555+ final class LocalVarDeclSynthNode extends PrintAstNode , TLocalVarDeclNode {
556+ LocalVariableDeclExpr lvde ;
557+
558+ LocalVarDeclSynthNode ( ) { this = TLocalVarDeclNode ( lvde ) }
559+
560+ override string toString ( ) { result = "(Single Local Variable Declaration)" }
561+
562+ override ElementNode getChild ( int childIndex ) {
563+ childIndex = 0 and
564+ result .getElement ( ) = lvde .getTypeAccess ( )
565+ or
566+ childIndex = 1 and
567+ result .getElement ( ) = lvde
568+ }
569+
570+ /**
571+ * Gets the underlying `LocalVariableDeclExpr`
572+ */
573+ LocalVariableDeclExpr getVariable ( ) { result = lvde }
574+ }
575+
435576/**
436577 * A node representing the annotations of an `Annotatable`.
437578 * Only rendered if there is at least one annotation.
0 commit comments