1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package com.puppycrawl.tools.checkstyle;
21
22 import java.util.ArrayDeque;
23 import java.util.ArrayList;
24 import java.util.Collections;
25 import java.util.Iterator;
26 import java.util.List;
27 import java.util.Optional;
28 import java.util.Queue;
29 import java.util.stream.Collectors;
30
31 import org.antlr.v4.runtime.BufferedTokenStream;
32 import org.antlr.v4.runtime.CommonTokenStream;
33 import org.antlr.v4.runtime.ParserRuleContext;
34 import org.antlr.v4.runtime.Token;
35 import org.antlr.v4.runtime.tree.ParseTree;
36 import org.antlr.v4.runtime.tree.TerminalNode;
37
38 import com.puppycrawl.tools.checkstyle.api.TokenTypes;
39 import com.puppycrawl.tools.checkstyle.grammar.java.JavaLanguageLexer;
40 import com.puppycrawl.tools.checkstyle.grammar.java.JavaLanguageParser;
41 import com.puppycrawl.tools.checkstyle.grammar.java.JavaLanguageParserBaseVisitor;
42 import com.puppycrawl.tools.checkstyle.utils.TokenUtil;
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97 public final class JavaAstVisitor extends JavaLanguageParserBaseVisitor<DetailAstImpl> {
98
99
100 private static final String LEFT_SHIFT = "<<";
101
102
103 private static final String UNSIGNED_RIGHT_SHIFT = ">>>";
104
105
106 private static final String RIGHT_SHIFT = ">>";
107
108
109
110
111
112 private static final int[] EXPRESSIONS_WITH_NO_EXPR_ROOT = {
113 TokenTypes.CTOR_CALL,
114 TokenTypes.SUPER_CTOR_CALL,
115 TokenTypes.LAMBDA,
116 };
117
118
119 private final BufferedTokenStream tokens;
120
121
122
123
124
125
126 public JavaAstVisitor(CommonTokenStream tokenStream) {
127 tokens = tokenStream;
128 }
129
130 @Override
131 public DetailAstImpl visitCompilationUnit(JavaLanguageParser.CompilationUnitContext ctx) {
132 final DetailAstImpl compilationUnit;
133
134 final boolean isEmptyFile = ctx.children.size() == 1;
135 if (isEmptyFile) {
136 compilationUnit = null;
137 }
138 else {
139 compilationUnit = createImaginary(TokenTypes.COMPILATION_UNIT);
140
141 processChildren(compilationUnit, ctx.children.subList(0, ctx.children.size() - 1));
142 }
143 return compilationUnit;
144 }
145
146 @Override
147 public DetailAstImpl visitPackageDeclaration(
148 JavaLanguageParser.PackageDeclarationContext ctx) {
149 final DetailAstImpl packageDeclaration =
150 create(TokenTypes.PACKAGE_DEF, (Token) ctx.LITERAL_PACKAGE().getPayload());
151 packageDeclaration.addChild(visit(ctx.annotations()));
152 packageDeclaration.addChild(visit(ctx.qualifiedName()));
153 packageDeclaration.addChild(create(ctx.SEMI()));
154 return packageDeclaration;
155 }
156
157 @Override
158 public DetailAstImpl visitImportDec(JavaLanguageParser.ImportDecContext ctx) {
159 final DetailAstImpl importRoot = create(ctx.start);
160
161
162 final TerminalNode literalStaticNode = ctx.LITERAL_STATIC();
163 if (literalStaticNode != null) {
164 importRoot.setType(TokenTypes.STATIC_IMPORT);
165 importRoot.addChild(create(literalStaticNode));
166 }
167
168
169 final boolean isStarImport = ctx.STAR() != null;
170 if (isStarImport) {
171 final DetailAstImpl dot = create(ctx.DOT());
172 dot.addChild(visit(ctx.qualifiedName()));
173 dot.addChild(create(ctx.STAR()));
174 importRoot.addChild(dot);
175 }
176 else {
177 importRoot.addChild(visit(ctx.qualifiedName()));
178 }
179
180 importRoot.addChild(create(ctx.SEMI()));
181 return importRoot;
182 }
183
184 @Override
185 public DetailAstImpl visitSingleSemiImport(JavaLanguageParser.SingleSemiImportContext ctx) {
186 return create(ctx.SEMI());
187 }
188
189 @Override
190 public DetailAstImpl visitTypeDeclaration(JavaLanguageParser.TypeDeclarationContext ctx) {
191 final DetailAstImpl typeDeclaration;
192 if (ctx.type == null) {
193 typeDeclaration = create(ctx.semi.get(0));
194 ctx.semi.subList(1, ctx.semi.size())
195 .forEach(semi -> addLastSibling(typeDeclaration, create(semi)));
196 }
197 else {
198 typeDeclaration = visit(ctx.type);
199 }
200 return typeDeclaration;
201 }
202
203 @Override
204 public DetailAstImpl visitModifier(JavaLanguageParser.ModifierContext ctx) {
205 return flattenedTree(ctx);
206 }
207
208 @Override
209 public DetailAstImpl visitVariableModifier(JavaLanguageParser.VariableModifierContext ctx) {
210 return flattenedTree(ctx);
211 }
212
213 @Override
214 public DetailAstImpl visitClassDeclaration(JavaLanguageParser.ClassDeclarationContext ctx) {
215 return createTypeDeclaration(ctx, TokenTypes.CLASS_DEF, ctx.mods);
216 }
217
218 @Override
219 public DetailAstImpl visitRecordDeclaration(JavaLanguageParser.RecordDeclarationContext ctx) {
220 return createTypeDeclaration(ctx, TokenTypes.RECORD_DEF, ctx.mods);
221 }
222
223 @Override
224 public DetailAstImpl visitRecordComponentsList(
225 JavaLanguageParser.RecordComponentsListContext ctx) {
226 final DetailAstImpl lparen = create(ctx.LPAREN());
227
228
229 if (ctx.recordComponents() == null) {
230 addLastSibling(lparen, createImaginary(TokenTypes.RECORD_COMPONENTS));
231 }
232 else {
233 addLastSibling(lparen, visit(ctx.recordComponents()));
234 }
235 addLastSibling(lparen, create(ctx.RPAREN()));
236 return lparen;
237 }
238
239 @Override
240 public DetailAstImpl visitRecordComponents(JavaLanguageParser.RecordComponentsContext ctx) {
241 final DetailAstImpl recordComponents = createImaginary(TokenTypes.RECORD_COMPONENTS);
242 processChildren(recordComponents, ctx.children);
243 return recordComponents;
244 }
245
246 @Override
247 public DetailAstImpl visitRecordComponent(JavaLanguageParser.RecordComponentContext ctx) {
248 final DetailAstImpl recordComponent = createImaginary(TokenTypes.RECORD_COMPONENT_DEF);
249 processChildren(recordComponent, ctx.children);
250 return recordComponent;
251 }
252
253 @Override
254 public DetailAstImpl visitLastRecordComponent(
255 JavaLanguageParser.LastRecordComponentContext ctx) {
256 final DetailAstImpl recordComponent = createImaginary(TokenTypes.RECORD_COMPONENT_DEF);
257 processChildren(recordComponent, ctx.children);
258 return recordComponent;
259 }
260
261 @Override
262 public DetailAstImpl visitRecordBody(JavaLanguageParser.RecordBodyContext ctx) {
263 final DetailAstImpl objBlock = createImaginary(TokenTypes.OBJBLOCK);
264 processChildren(objBlock, ctx.children);
265 return objBlock;
266 }
267
268 @Override
269 public DetailAstImpl visitCompactConstructorDeclaration(
270 JavaLanguageParser.CompactConstructorDeclarationContext ctx) {
271 final DetailAstImpl compactConstructor = createImaginary(TokenTypes.COMPACT_CTOR_DEF);
272 compactConstructor.addChild(createModifiers(ctx.mods));
273 compactConstructor.addChild(visit(ctx.id()));
274 compactConstructor.addChild(visit(ctx.constructorBlock()));
275 return compactConstructor;
276 }
277
278 @Override
279 public DetailAstImpl visitClassExtends(JavaLanguageParser.ClassExtendsContext ctx) {
280 final DetailAstImpl classExtends = create(ctx.EXTENDS_CLAUSE());
281 classExtends.addChild(visit(ctx.type));
282 return classExtends;
283 }
284
285 @Override
286 public DetailAstImpl visitImplementsClause(JavaLanguageParser.ImplementsClauseContext ctx) {
287 final DetailAstImpl classImplements = create(TokenTypes.IMPLEMENTS_CLAUSE,
288 (Token) ctx.LITERAL_IMPLEMENTS().getPayload());
289 classImplements.addChild(visit(ctx.typeList()));
290 return classImplements;
291 }
292
293 @Override
294 public DetailAstImpl visitTypeParameters(JavaLanguageParser.TypeParametersContext ctx) {
295 final DetailAstImpl typeParameters = createImaginary(TokenTypes.TYPE_PARAMETERS);
296 typeParameters.addChild(create(TokenTypes.GENERIC_START, (Token) ctx.LT().getPayload()));
297
298 processChildren(typeParameters, ctx.children.subList(1, ctx.children.size() - 1));
299 typeParameters.addChild(create(TokenTypes.GENERIC_END, (Token) ctx.GT().getPayload()));
300 return typeParameters;
301 }
302
303 @Override
304 public DetailAstImpl visitTypeParameter(JavaLanguageParser.TypeParameterContext ctx) {
305 final DetailAstImpl typeParameter = createImaginary(TokenTypes.TYPE_PARAMETER);
306 processChildren(typeParameter, ctx.children);
307 return typeParameter;
308 }
309
310 @Override
311 public DetailAstImpl visitTypeUpperBounds(JavaLanguageParser.TypeUpperBoundsContext ctx) {
312
313 final DetailAstImpl typeUpperBounds = create(TokenTypes.TYPE_UPPER_BOUNDS,
314 (Token) ctx.EXTENDS_CLAUSE().getPayload());
315
316 processChildren(typeUpperBounds, ctx.children.subList(1, ctx.children.size()));
317 return typeUpperBounds;
318 }
319
320 @Override
321 public DetailAstImpl visitTypeBound(JavaLanguageParser.TypeBoundContext ctx) {
322 final DetailAstImpl typeBoundType = visit(ctx.typeBoundType(0));
323 final Iterator<JavaLanguageParser.TypeBoundTypeContext> typeBoundTypeIterator =
324 ctx.typeBoundType().listIterator(1);
325 ctx.BAND().forEach(band -> {
326 addLastSibling(typeBoundType, create(TokenTypes.TYPE_EXTENSION_AND,
327 (Token) band.getPayload()));
328 addLastSibling(typeBoundType, visit(typeBoundTypeIterator.next()));
329 });
330 return typeBoundType;
331 }
332
333 @Override
334 public DetailAstImpl visitTypeBoundType(JavaLanguageParser.TypeBoundTypeContext ctx) {
335 return flattenedTree(ctx);
336 }
337
338 @Override
339 public DetailAstImpl visitEnumDeclaration(JavaLanguageParser.EnumDeclarationContext ctx) {
340 return createTypeDeclaration(ctx, TokenTypes.ENUM_DEF, ctx.mods);
341 }
342
343 @Override
344 public DetailAstImpl visitEnumBody(JavaLanguageParser.EnumBodyContext ctx) {
345 final DetailAstImpl objBlock = createImaginary(TokenTypes.OBJBLOCK);
346 processChildren(objBlock, ctx.children);
347 return objBlock;
348 }
349
350 @Override
351 public DetailAstImpl visitEnumConstants(JavaLanguageParser.EnumConstantsContext ctx) {
352 return flattenedTree(ctx);
353 }
354
355 @Override
356 public DetailAstImpl visitEnumConstant(JavaLanguageParser.EnumConstantContext ctx) {
357 final DetailAstImpl enumConstant =
358 createImaginary(TokenTypes.ENUM_CONSTANT_DEF);
359 processChildren(enumConstant, ctx.children);
360 return enumConstant;
361 }
362
363 @Override
364 public DetailAstImpl visitEnumBodyDeclarations(
365 JavaLanguageParser.EnumBodyDeclarationsContext ctx) {
366 return flattenedTree(ctx);
367 }
368
369 @Override
370 public DetailAstImpl visitInterfaceDeclaration(
371 JavaLanguageParser.InterfaceDeclarationContext ctx) {
372 return createTypeDeclaration(ctx, TokenTypes.INTERFACE_DEF, ctx.mods);
373 }
374
375 @Override
376 public DetailAstImpl visitInterfaceExtends(JavaLanguageParser.InterfaceExtendsContext ctx) {
377 final DetailAstImpl interfaceExtends = create(ctx.EXTENDS_CLAUSE());
378 interfaceExtends.addChild(visit(ctx.typeList()));
379 return interfaceExtends;
380 }
381
382 @Override
383 public DetailAstImpl visitClassBody(JavaLanguageParser.ClassBodyContext ctx) {
384 final DetailAstImpl objBlock = createImaginary(TokenTypes.OBJBLOCK);
385 processChildren(objBlock, ctx.children);
386 return objBlock;
387 }
388
389 @Override
390 public DetailAstImpl visitInterfaceBody(JavaLanguageParser.InterfaceBodyContext ctx) {
391 final DetailAstImpl objBlock = createImaginary(TokenTypes.OBJBLOCK);
392 processChildren(objBlock, ctx.children);
393 return objBlock;
394 }
395
396 @Override
397 public DetailAstImpl visitEmptyClass(JavaLanguageParser.EmptyClassContext ctx) {
398 return flattenedTree(ctx);
399 }
400
401 @Override
402 public DetailAstImpl visitClassBlock(JavaLanguageParser.ClassBlockContext ctx) {
403 final DetailAstImpl classBlock;
404 if (ctx.LITERAL_STATIC() == null) {
405
406 classBlock = createImaginary(TokenTypes.INSTANCE_INIT);
407 }
408 else {
409 classBlock = create(TokenTypes.STATIC_INIT, (Token) ctx.LITERAL_STATIC().getPayload());
410 classBlock.setText(TokenUtil.getTokenName(TokenTypes.STATIC_INIT));
411 }
412 classBlock.addChild(visit(ctx.block()));
413 return classBlock;
414 }
415
416 @Override
417 public DetailAstImpl visitMethodDeclaration(JavaLanguageParser.MethodDeclarationContext ctx) {
418 final DetailAstImpl methodDef = createImaginary(TokenTypes.METHOD_DEF);
419 methodDef.addChild(createModifiers(ctx.mods));
420
421
422 processChildren(methodDef, ctx.children.stream()
423 .filter(child -> !(child instanceof JavaLanguageParser.ArrayDeclaratorContext))
424 .toList());
425
426
427 final DetailAstImpl typeAst = (DetailAstImpl) methodDef.findFirstToken(TokenTypes.TYPE);
428 ctx.cStyleArrDec.forEach(child -> typeAst.addChild(visit(child)));
429
430 return methodDef;
431 }
432
433 @Override
434 public DetailAstImpl visitMethodBody(JavaLanguageParser.MethodBodyContext ctx) {
435 return flattenedTree(ctx);
436 }
437
438 @Override
439 public DetailAstImpl visitThrowsList(JavaLanguageParser.ThrowsListContext ctx) {
440 final DetailAstImpl throwsRoot = create(ctx.LITERAL_THROWS());
441 throwsRoot.addChild(visit(ctx.qualifiedNameList()));
442 return throwsRoot;
443 }
444
445 @Override
446 public DetailAstImpl visitConstructorDeclaration(
447 JavaLanguageParser.ConstructorDeclarationContext ctx) {
448 final DetailAstImpl constructorDeclaration = createImaginary(TokenTypes.CTOR_DEF);
449 constructorDeclaration.addChild(createModifiers(ctx.mods));
450 processChildren(constructorDeclaration, ctx.children);
451 return constructorDeclaration;
452 }
453
454 @Override
455 public DetailAstImpl visitFieldDeclaration(JavaLanguageParser.FieldDeclarationContext ctx) {
456 final DetailAstImpl dummyNode = new DetailAstImpl();
457
458
459
460 processChildren(dummyNode, ctx.children.subList(1, ctx.children.size() - 1));
461 dummyNode.getFirstChild().addChild(create(ctx.SEMI()));
462 return dummyNode.getFirstChild();
463 }
464
465 @Override
466 public DetailAstImpl visitInterfaceBodyDeclaration(
467 JavaLanguageParser.InterfaceBodyDeclarationContext ctx) {
468 final DetailAstImpl returnTree;
469 if (ctx.SEMI() == null) {
470 returnTree = visit(ctx.interfaceMemberDeclaration());
471 }
472 else {
473 returnTree = create(ctx.SEMI());
474 }
475 return returnTree;
476 }
477
478 @Override
479 public DetailAstImpl visitInterfaceMethodDeclaration(
480 JavaLanguageParser.InterfaceMethodDeclarationContext ctx) {
481 final DetailAstImpl methodDef = createImaginary(TokenTypes.METHOD_DEF);
482 methodDef.addChild(createModifiers(ctx.mods));
483
484
485 final List<ParseTree> children = ctx.children
486 .stream()
487 .filter(child -> !(child instanceof JavaLanguageParser.ArrayDeclaratorContext))
488 .toList();
489 processChildren(methodDef, children);
490
491
492 final DetailAstImpl typeAst = (DetailAstImpl) methodDef.findFirstToken(TokenTypes.TYPE);
493 ctx.cStyleArrDec.forEach(child -> typeAst.addChild(visit(child)));
494
495 return methodDef;
496 }
497
498 @Override
499 public DetailAstImpl visitVariableDeclarators(
500 JavaLanguageParser.VariableDeclaratorsContext ctx) {
501 return flattenedTree(ctx);
502 }
503
504 @Override
505 public DetailAstImpl visitVariableDeclarator(
506 JavaLanguageParser.VariableDeclaratorContext ctx) {
507 final DetailAstImpl variableDef = createImaginary(TokenTypes.VARIABLE_DEF);
508 variableDef.addChild(createModifiers(ctx.mods));
509
510 final DetailAstImpl type = visit(ctx.type);
511 variableDef.addChild(type);
512 variableDef.addChild(visit(ctx.id()));
513
514
515 ctx.arrayDeclarator().forEach(child -> type.addChild(visit(child)));
516
517
518 final TerminalNode assignNode = ctx.ASSIGN();
519 if (assignNode != null) {
520 final DetailAstImpl assign = create(assignNode);
521 variableDef.addChild(assign);
522 assign.addChild(visit(ctx.variableInitializer()));
523 }
524 return variableDef;
525 }
526
527 @Override
528 public DetailAstImpl visitVariableDeclaratorId(
529 JavaLanguageParser.VariableDeclaratorIdContext ctx) {
530 final DetailAstImpl root = new DetailAstImpl();
531 root.addChild(createModifiers(ctx.mods));
532 final DetailAstImpl type = visit(ctx.type);
533 root.addChild(type);
534
535 final DetailAstImpl declaratorId;
536 if (ctx.LITERAL_THIS() == null) {
537 declaratorId = visit(ctx.qualifiedName());
538 }
539 else if (ctx.DOT() == null) {
540 declaratorId = create(ctx.LITERAL_THIS());
541 }
542 else {
543 declaratorId = create(ctx.DOT());
544 declaratorId.addChild(visit(ctx.qualifiedName()));
545 declaratorId.addChild(create(ctx.LITERAL_THIS()));
546 }
547
548 root.addChild(declaratorId);
549 ctx.arrayDeclarator().forEach(child -> type.addChild(visit(child)));
550
551 return root.getFirstChild();
552 }
553
554 @Override
555 public DetailAstImpl visitArrayInitializer(JavaLanguageParser.ArrayInitializerContext ctx) {
556 final DetailAstImpl arrayInitializer = create(TokenTypes.ARRAY_INIT, ctx.start);
557
558 processChildren(arrayInitializer, ctx.children.subList(1, ctx.children.size()));
559 return arrayInitializer;
560 }
561
562 @Override
563 public DetailAstImpl visitClassOrInterfaceType(
564 JavaLanguageParser.ClassOrInterfaceTypeContext ctx) {
565 final DetailAstPair currentAST = new DetailAstPair();
566 DetailAstPair.addAstChild(currentAST, visit(ctx.id()));
567 DetailAstPair.addAstChild(currentAST, visit(ctx.typeArguments()));
568
569
570 for (ParserRuleContext extendedContext : ctx.extended) {
571 final DetailAstImpl dot = create(extendedContext.start);
572 DetailAstPair.makeAstRoot(currentAST, dot);
573 extendedContext.children
574 .forEach(child -> DetailAstPair.addAstChild(currentAST, visit(child)));
575 }
576
577
578 final DetailAstImpl returnTree;
579 if (ctx.createImaginaryNode) {
580 returnTree = createImaginary(TokenTypes.TYPE);
581 returnTree.addChild(currentAST.root);
582 }
583 else {
584 returnTree = currentAST.root;
585 }
586 return returnTree;
587 }
588
589 @Override
590 public DetailAstImpl visitSimpleTypeArgument(
591 JavaLanguageParser.SimpleTypeArgumentContext ctx) {
592 final DetailAstImpl typeArgument =
593 createImaginary(TokenTypes.TYPE_ARGUMENT);
594 typeArgument.addChild(visit(ctx.typeType()));
595 return typeArgument;
596 }
597
598 @Override
599 public DetailAstImpl visitWildCardTypeArgument(
600 JavaLanguageParser.WildCardTypeArgumentContext ctx) {
601 final DetailAstImpl typeArgument = createImaginary(TokenTypes.TYPE_ARGUMENT);
602 typeArgument.addChild(visit(ctx.annotations()));
603 typeArgument.addChild(create(TokenTypes.WILDCARD_TYPE,
604 (Token) ctx.QUESTION().getPayload()));
605
606 if (ctx.upperBound != null) {
607 final DetailAstImpl upperBound = create(TokenTypes.TYPE_UPPER_BOUNDS, ctx.upperBound);
608 upperBound.addChild(visit(ctx.typeType()));
609 typeArgument.addChild(upperBound);
610 }
611 else if (ctx.lowerBound != null) {
612 final DetailAstImpl lowerBound = create(TokenTypes.TYPE_LOWER_BOUNDS, ctx.lowerBound);
613 lowerBound.addChild(visit(ctx.typeType()));
614 typeArgument.addChild(lowerBound);
615 }
616
617 return typeArgument;
618 }
619
620 @Override
621 public DetailAstImpl visitQualifiedNameList(JavaLanguageParser.QualifiedNameListContext ctx) {
622 return flattenedTree(ctx);
623 }
624
625 @Override
626 public DetailAstImpl visitFormalParameters(JavaLanguageParser.FormalParametersContext ctx) {
627 final DetailAstImpl lparen = create(ctx.LPAREN());
628
629
630 if (ctx.formalParameterList() == null) {
631 addLastSibling(lparen, createImaginary(TokenTypes.PARAMETERS));
632 }
633 else {
634 addLastSibling(lparen, visit(ctx.formalParameterList()));
635 }
636 addLastSibling(lparen, create(ctx.RPAREN()));
637 return lparen;
638 }
639
640 @Override
641 public DetailAstImpl visitFormalParameterList(
642 JavaLanguageParser.FormalParameterListContext ctx) {
643 final DetailAstImpl parameters = createImaginary(TokenTypes.PARAMETERS);
644 processChildren(parameters, ctx.children);
645 return parameters;
646 }
647
648 @Override
649 public DetailAstImpl visitFormalParameter(JavaLanguageParser.FormalParameterContext ctx) {
650 final DetailAstImpl variableDeclaratorId =
651 visitVariableDeclaratorId(ctx.variableDeclaratorId());
652 final DetailAstImpl parameterDef = createImaginary(TokenTypes.PARAMETER_DEF);
653 parameterDef.addChild(variableDeclaratorId);
654 return parameterDef;
655 }
656
657 @Override
658 public DetailAstImpl visitLastFormalParameter(
659 JavaLanguageParser.LastFormalParameterContext ctx) {
660 final DetailAstImpl parameterDef =
661 createImaginary(TokenTypes.PARAMETER_DEF);
662 parameterDef.addChild(visit(ctx.variableDeclaratorId()));
663 final DetailAstImpl ident = (DetailAstImpl) parameterDef.findFirstToken(TokenTypes.IDENT);
664 ident.addPreviousSibling(create(ctx.ELLIPSIS()));
665
666 final DetailAstImpl type = (DetailAstImpl) parameterDef.findFirstToken(TokenTypes.TYPE);
667 type.addChild(visit(ctx.annotations()));
668 return parameterDef;
669 }
670
671 @Override
672 public DetailAstImpl visitQualifiedName(JavaLanguageParser.QualifiedNameContext ctx) {
673 final DetailAstImpl ast = visit(ctx.id());
674 final DetailAstPair currentAst = new DetailAstPair();
675 DetailAstPair.addAstChild(currentAst, ast);
676
677 for (ParserRuleContext extendedContext : ctx.extended) {
678 final DetailAstImpl dot = create(extendedContext.start);
679 DetailAstPair.makeAstRoot(currentAst, dot);
680 final List<ParseTree> childList = extendedContext
681 .children.subList(1, extendedContext.children.size());
682 processChildren(dot, childList);
683 }
684 return currentAst.getRoot();
685 }
686
687 @Override
688 public DetailAstImpl visitLiteral(JavaLanguageParser.LiteralContext ctx) {
689 return flattenedTree(ctx);
690 }
691
692 @Override
693 public DetailAstImpl visitIntegerLiteral(JavaLanguageParser.IntegerLiteralContext ctx) {
694 final int[] longTypes = {
695 JavaLanguageLexer.DECIMAL_LITERAL_LONG,
696 JavaLanguageLexer.HEX_LITERAL_LONG,
697 JavaLanguageLexer.OCT_LITERAL_LONG,
698 JavaLanguageLexer.BINARY_LITERAL_LONG,
699 };
700
701 final int tokenType;
702 if (TokenUtil.isOfType(ctx.start.getType(), longTypes)) {
703 tokenType = TokenTypes.NUM_LONG;
704 }
705 else {
706 tokenType = TokenTypes.NUM_INT;
707 }
708
709 return create(tokenType, ctx.start);
710 }
711
712 @Override
713 public DetailAstImpl visitFloatLiteral(JavaLanguageParser.FloatLiteralContext ctx) {
714 final DetailAstImpl floatLiteral;
715 if (TokenUtil.isOfType(ctx.start.getType(),
716 JavaLanguageLexer.DOUBLE_LITERAL, JavaLanguageLexer.HEX_DOUBLE_LITERAL)) {
717 floatLiteral = create(TokenTypes.NUM_DOUBLE, ctx.start);
718 }
719 else {
720 floatLiteral = create(TokenTypes.NUM_FLOAT, ctx.start);
721 }
722 return floatLiteral;
723 }
724
725 @Override
726 public DetailAstImpl visitTextBlockLiteral(JavaLanguageParser.TextBlockLiteralContext ctx) {
727 final DetailAstImpl textBlockLiteralBegin = create(ctx.TEXT_BLOCK_LITERAL_BEGIN());
728 textBlockLiteralBegin.addChild(create(ctx.TEXT_BLOCK_CONTENT()));
729 textBlockLiteralBegin.addChild(create(ctx.TEXT_BLOCK_LITERAL_END()));
730 return textBlockLiteralBegin;
731 }
732
733 @Override
734 public DetailAstImpl visitAnnotations(JavaLanguageParser.AnnotationsContext ctx) {
735 final DetailAstImpl annotations;
736
737 if (!ctx.createImaginaryNode && ctx.anno.isEmpty()) {
738
739 annotations = null;
740 }
741 else {
742
743 annotations = createImaginary(TokenTypes.ANNOTATIONS);
744 processChildren(annotations, ctx.anno);
745 }
746
747 return annotations;
748 }
749
750 @Override
751 public DetailAstImpl visitAnnotation(JavaLanguageParser.AnnotationContext ctx) {
752 final DetailAstImpl annotation = createImaginary(TokenTypes.ANNOTATION);
753 processChildren(annotation, ctx.children);
754 return annotation;
755 }
756
757 @Override
758 public DetailAstImpl visitElementValuePairs(JavaLanguageParser.ElementValuePairsContext ctx) {
759 return flattenedTree(ctx);
760 }
761
762 @Override
763 public DetailAstImpl visitElementValuePair(JavaLanguageParser.ElementValuePairContext ctx) {
764 final DetailAstImpl elementValuePair =
765 createImaginary(TokenTypes.ANNOTATION_MEMBER_VALUE_PAIR);
766 processChildren(elementValuePair, ctx.children);
767 return elementValuePair;
768 }
769
770 @Override
771 public DetailAstImpl visitElementValue(JavaLanguageParser.ElementValueContext ctx) {
772 return flattenedTree(ctx);
773 }
774
775 @Override
776 public DetailAstImpl visitElementValueArrayInitializer(
777 JavaLanguageParser.ElementValueArrayInitializerContext ctx) {
778 final DetailAstImpl arrayInit =
779 create(TokenTypes.ANNOTATION_ARRAY_INIT, (Token) ctx.LCURLY().getPayload());
780 processChildren(arrayInit, ctx.children.subList(1, ctx.children.size()));
781 return arrayInit;
782 }
783
784 @Override
785 public DetailAstImpl visitAnnotationTypeDeclaration(
786 JavaLanguageParser.AnnotationTypeDeclarationContext ctx) {
787 return createTypeDeclaration(ctx, TokenTypes.ANNOTATION_DEF, ctx.mods);
788 }
789
790 @Override
791 public DetailAstImpl visitAnnotationTypeBody(
792 JavaLanguageParser.AnnotationTypeBodyContext ctx) {
793 final DetailAstImpl objBlock = createImaginary(TokenTypes.OBJBLOCK);
794 processChildren(objBlock, ctx.children);
795 return objBlock;
796 }
797
798 @Override
799 public DetailAstImpl visitAnnotationTypeElementDeclaration(
800 JavaLanguageParser.AnnotationTypeElementDeclarationContext ctx) {
801 final DetailAstImpl returnTree;
802 if (ctx.SEMI() == null) {
803 returnTree = visit(ctx.annotationTypeElementRest());
804 }
805 else {
806 returnTree = create(ctx.SEMI());
807 }
808 return returnTree;
809 }
810
811 @Override
812 public DetailAstImpl visitAnnotationField(JavaLanguageParser.AnnotationFieldContext ctx) {
813 final DetailAstImpl dummyNode = new DetailAstImpl();
814
815
816 processChildren(dummyNode, Collections.singletonList(ctx.children.get(1)));
817
818
819 dummyNode.getFirstChild().addChild(create(ctx.SEMI()));
820 return dummyNode.getFirstChild();
821 }
822
823 @Override
824 public DetailAstImpl visitAnnotationType(JavaLanguageParser.AnnotationTypeContext ctx) {
825 return flattenedTree(ctx);
826 }
827
828 @Override
829 public DetailAstImpl visitAnnotationMethodRest(
830 JavaLanguageParser.AnnotationMethodRestContext ctx) {
831 final DetailAstImpl annotationFieldDef =
832 createImaginary(TokenTypes.ANNOTATION_FIELD_DEF);
833 annotationFieldDef.addChild(createModifiers(ctx.mods));
834 annotationFieldDef.addChild(visit(ctx.type));
835
836
837 processChildren(annotationFieldDef, ctx.children.stream()
838 .filter(child -> !(child instanceof JavaLanguageParser.ArrayDeclaratorContext))
839 .toList());
840
841
842 final DetailAstImpl typeAst =
843 (DetailAstImpl) annotationFieldDef.findFirstToken(TokenTypes.TYPE);
844 ctx.cStyleArrDec.forEach(child -> typeAst.addChild(visit(child)));
845
846 return annotationFieldDef;
847 }
848
849 @Override
850 public DetailAstImpl visitDefaultValue(JavaLanguageParser.DefaultValueContext ctx) {
851 final DetailAstImpl defaultValue = create(ctx.LITERAL_DEFAULT());
852 defaultValue.addChild(visit(ctx.elementValue()));
853 return defaultValue;
854 }
855
856 @Override
857 public DetailAstImpl visitConstructorBlock(JavaLanguageParser.ConstructorBlockContext ctx) {
858 final DetailAstImpl slist = create(TokenTypes.SLIST, ctx.start);
859
860 processChildren(slist, ctx.children.subList(1, ctx.children.size()));
861 return slist;
862 }
863
864 @Override
865 public DetailAstImpl visitExplicitCtorCall(JavaLanguageParser.ExplicitCtorCallContext ctx) {
866 final DetailAstImpl root;
867 if (ctx.LITERAL_THIS() == null) {
868 root = create(TokenTypes.SUPER_CTOR_CALL, (Token) ctx.LITERAL_SUPER().getPayload());
869 }
870 else {
871 root = create(TokenTypes.CTOR_CALL, (Token) ctx.LITERAL_THIS().getPayload());
872 }
873 root.addChild(visit(ctx.typeArguments()));
874 root.addChild(visit(ctx.arguments()));
875 root.addChild(create(ctx.SEMI()));
876 return root;
877 }
878
879 @Override
880 public DetailAstImpl visitPrimaryCtorCall(JavaLanguageParser.PrimaryCtorCallContext ctx) {
881 final DetailAstImpl primaryCtorCall = create(TokenTypes.SUPER_CTOR_CALL,
882 (Token) ctx.LITERAL_SUPER().getPayload());
883
884 processChildren(primaryCtorCall, ctx.children.stream()
885 .filter(child -> !child.equals(ctx.LITERAL_SUPER()))
886 .toList());
887 return primaryCtorCall;
888 }
889
890 @Override
891 public DetailAstImpl visitBlock(JavaLanguageParser.BlockContext ctx) {
892 final DetailAstImpl slist = create(TokenTypes.SLIST, ctx.start);
893
894 processChildren(slist, ctx.children.subList(1, ctx.children.size()));
895 return slist;
896 }
897
898 @Override
899 public DetailAstImpl visitLocalVar(JavaLanguageParser.LocalVarContext ctx) {
900 return flattenedTree(ctx);
901 }
902
903 @Override
904 public DetailAstImpl visitBlockStat(JavaLanguageParser.BlockStatContext ctx) {
905 return flattenedTree(ctx);
906 }
907
908 @Override
909 public DetailAstImpl visitAssertExp(JavaLanguageParser.AssertExpContext ctx) {
910 final DetailAstImpl assertExp = create(ctx.ASSERT());
911
912 processChildren(assertExp, ctx.children.subList(1, ctx.children.size()));
913 return assertExp;
914 }
915
916 @Override
917 public DetailAstImpl visitIfStat(JavaLanguageParser.IfStatContext ctx) {
918 final DetailAstImpl ifStat = create(ctx.LITERAL_IF());
919
920 processChildren(ifStat, ctx.children.subList(1, ctx.children.size()));
921 return ifStat;
922 }
923
924 @Override
925 public DetailAstImpl visitForStat(JavaLanguageParser.ForStatContext ctx) {
926 final DetailAstImpl forInit = create(ctx.start);
927
928 processChildren(forInit, ctx.children.subList(1, ctx.children.size()));
929 return forInit;
930 }
931
932 @Override
933 public DetailAstImpl visitWhileStat(JavaLanguageParser.WhileStatContext ctx) {
934 final DetailAstImpl whileStatement = create(ctx.start);
935
936 processChildren(whileStatement, ctx.children.subList(1, ctx.children.size()));
937 return whileStatement;
938 }
939
940 @Override
941 public DetailAstImpl visitDoStat(JavaLanguageParser.DoStatContext ctx) {
942 final DetailAstImpl doStatement = create(ctx.start);
943
944 doStatement.addChild(visit(ctx.statement()));
945
946 doStatement.addChild(create(TokenTypes.DO_WHILE, (Token) ctx.LITERAL_WHILE().getPayload()));
947 doStatement.addChild(visit(ctx.parExpression()));
948 doStatement.addChild(create(ctx.SEMI()));
949 return doStatement;
950 }
951
952 @Override
953 public DetailAstImpl visitTryStat(JavaLanguageParser.TryStatContext ctx) {
954 final DetailAstImpl tryStat = create(ctx.start);
955
956 processChildren(tryStat, ctx.children.subList(1, ctx.children.size()));
957 return tryStat;
958 }
959
960 @Override
961 public DetailAstImpl visitTryWithResourceStat(
962 JavaLanguageParser.TryWithResourceStatContext ctx) {
963 final DetailAstImpl tryWithResources = create(ctx.LITERAL_TRY());
964
965 processChildren(tryWithResources, ctx.children.subList(1, ctx.children.size()));
966 return tryWithResources;
967 }
968
969 @Override
970 public DetailAstImpl visitYieldStat(JavaLanguageParser.YieldStatContext ctx) {
971 final DetailAstImpl yieldParent = create(ctx.LITERAL_YIELD());
972
973 processChildren(yieldParent, ctx.children.subList(1, ctx.children.size()));
974 return yieldParent;
975 }
976
977 @Override
978 public DetailAstImpl visitSyncStat(JavaLanguageParser.SyncStatContext ctx) {
979 final DetailAstImpl syncStatement = create(ctx.start);
980
981 processChildren(syncStatement, ctx.children.subList(1, ctx.children.size()));
982 return syncStatement;
983 }
984
985 @Override
986 public DetailAstImpl visitReturnStat(JavaLanguageParser.ReturnStatContext ctx) {
987 final DetailAstImpl returnStat = create(ctx.LITERAL_RETURN());
988
989 processChildren(returnStat, ctx.children.subList(1, ctx.children.size()));
990 return returnStat;
991 }
992
993 @Override
994 public DetailAstImpl visitThrowStat(JavaLanguageParser.ThrowStatContext ctx) {
995 final DetailAstImpl throwStat = create(ctx.LITERAL_THROW());
996
997 processChildren(throwStat, ctx.children.subList(1, ctx.children.size()));
998 return throwStat;
999 }
1000
1001 @Override
1002 public DetailAstImpl visitBreakStat(JavaLanguageParser.BreakStatContext ctx) {
1003 final DetailAstImpl literalBreak = create(ctx.LITERAL_BREAK());
1004
1005 processChildren(literalBreak, ctx.children.subList(1, ctx.children.size()));
1006 return literalBreak;
1007 }
1008
1009 @Override
1010 public DetailAstImpl visitContinueStat(JavaLanguageParser.ContinueStatContext ctx) {
1011 final DetailAstImpl continueStat = create(ctx.LITERAL_CONTINUE());
1012
1013 processChildren(continueStat, ctx.children.subList(1, ctx.children.size()));
1014 return continueStat;
1015 }
1016
1017 @Override
1018 public DetailAstImpl visitEmptyStat(JavaLanguageParser.EmptyStatContext ctx) {
1019 return create(TokenTypes.EMPTY_STAT, ctx.start);
1020 }
1021
1022 @Override
1023 public DetailAstImpl visitExpStat(JavaLanguageParser.ExpStatContext ctx) {
1024 final DetailAstImpl expStatRoot = visit(ctx.statementExpression);
1025 addLastSibling(expStatRoot, create(ctx.SEMI()));
1026 return expStatRoot;
1027 }
1028
1029 @Override
1030 public DetailAstImpl visitLabelStat(JavaLanguageParser.LabelStatContext ctx) {
1031 final DetailAstImpl labelStat = create(TokenTypes.LABELED_STAT,
1032 (Token) ctx.COLON().getPayload());
1033 labelStat.addChild(visit(ctx.id()));
1034 labelStat.addChild(visit(ctx.statement()));
1035 return labelStat;
1036 }
1037
1038 @Override
1039 public DetailAstImpl visitSwitchExpressionOrStatement(
1040 JavaLanguageParser.SwitchExpressionOrStatementContext ctx) {
1041 final DetailAstImpl switchStat = create(ctx.LITERAL_SWITCH());
1042 switchStat.addChild(visit(ctx.parExpression()));
1043 switchStat.addChild(create(ctx.LCURLY()));
1044 switchStat.addChild(visit(ctx.switchBlock()));
1045 switchStat.addChild(create(ctx.RCURLY()));
1046 return switchStat;
1047 }
1048
1049 @Override
1050 public DetailAstImpl visitSwitchRules(JavaLanguageParser.SwitchRulesContext ctx) {
1051 final DetailAstImpl dummyRoot = new DetailAstImpl();
1052 ctx.switchLabeledRule().forEach(switchLabeledRuleContext -> {
1053 final DetailAstImpl switchRule = visit(switchLabeledRuleContext);
1054 final DetailAstImpl switchRuleParent = createImaginary(TokenTypes.SWITCH_RULE);
1055 switchRuleParent.addChild(switchRule);
1056 dummyRoot.addChild(switchRuleParent);
1057 });
1058 return dummyRoot.getFirstChild();
1059 }
1060
1061 @Override
1062 public DetailAstImpl visitSwitchBlocks(JavaLanguageParser.SwitchBlocksContext ctx) {
1063 final DetailAstImpl dummyRoot = new DetailAstImpl();
1064 ctx.groups.forEach(group -> dummyRoot.addChild(visit(group)));
1065
1066
1067 if (!ctx.emptyLabels.isEmpty()) {
1068 final DetailAstImpl emptyLabelParent =
1069 createImaginary(TokenTypes.CASE_GROUP);
1070 ctx.emptyLabels.forEach(label -> emptyLabelParent.addChild(visit(label)));
1071 dummyRoot.addChild(emptyLabelParent);
1072 }
1073 return dummyRoot.getFirstChild();
1074 }
1075
1076 @Override
1077 public DetailAstImpl visitSwitchLabeledExpression(
1078 JavaLanguageParser.SwitchLabeledExpressionContext ctx) {
1079 return flattenedTree(ctx);
1080 }
1081
1082 @Override
1083 public DetailAstImpl visitSwitchLabeledBlock(
1084 JavaLanguageParser.SwitchLabeledBlockContext ctx) {
1085 return flattenedTree(ctx);
1086 }
1087
1088 @Override
1089 public DetailAstImpl visitSwitchLabeledThrow(
1090 JavaLanguageParser.SwitchLabeledThrowContext ctx) {
1091 final DetailAstImpl switchLabel = visit(ctx.switchLabel());
1092 addLastSibling(switchLabel, create(ctx.LAMBDA()));
1093 final DetailAstImpl literalThrow = create(ctx.LITERAL_THROW());
1094 literalThrow.addChild(visit(ctx.expression()));
1095 literalThrow.addChild(create(ctx.SEMI()));
1096 addLastSibling(switchLabel, literalThrow);
1097 return switchLabel;
1098 }
1099
1100 @Override
1101 public DetailAstImpl visitElseStat(JavaLanguageParser.ElseStatContext ctx) {
1102 final DetailAstImpl elseStat = create(ctx.LITERAL_ELSE());
1103
1104 processChildren(elseStat, ctx.children.subList(1, ctx.children.size()));
1105 return elseStat;
1106 }
1107
1108 @Override
1109 public DetailAstImpl visitCatchClause(JavaLanguageParser.CatchClauseContext ctx) {
1110 final DetailAstImpl catchClause = create(TokenTypes.LITERAL_CATCH,
1111 (Token) ctx.LITERAL_CATCH().getPayload());
1112
1113 processChildren(catchClause, ctx.children.subList(1, ctx.children.size()));
1114 return catchClause;
1115 }
1116
1117 @Override
1118 public DetailAstImpl visitCatchParameter(JavaLanguageParser.CatchParameterContext ctx) {
1119 final DetailAstImpl catchParameterDef = createImaginary(TokenTypes.PARAMETER_DEF);
1120 catchParameterDef.addChild(createModifiers(ctx.mods));
1121
1122 processChildren(catchParameterDef, ctx.children.stream()
1123 .filter(child -> !(child instanceof JavaLanguageParser.VariableModifierContext))
1124 .toList());
1125 return catchParameterDef;
1126 }
1127
1128 @Override
1129 public DetailAstImpl visitCatchType(JavaLanguageParser.CatchTypeContext ctx) {
1130 final DetailAstImpl type = createImaginary(TokenTypes.TYPE);
1131 processChildren(type, ctx.children);
1132 return type;
1133 }
1134
1135 @Override
1136 public DetailAstImpl visitFinallyBlock(JavaLanguageParser.FinallyBlockContext ctx) {
1137 final DetailAstImpl finallyBlock = create(ctx.LITERAL_FINALLY());
1138
1139 processChildren(finallyBlock, ctx.children.subList(1, ctx.children.size()));
1140 return finallyBlock;
1141 }
1142
1143 @Override
1144 public DetailAstImpl visitResourceSpecification(
1145 JavaLanguageParser.ResourceSpecificationContext ctx) {
1146 final DetailAstImpl resourceSpecification =
1147 createImaginary(TokenTypes.RESOURCE_SPECIFICATION);
1148 processChildren(resourceSpecification, ctx.children);
1149 return resourceSpecification;
1150 }
1151
1152 @Override
1153 public DetailAstImpl visitResources(JavaLanguageParser.ResourcesContext ctx) {
1154 final DetailAstImpl firstResource = visit(ctx.resource(0));
1155 final DetailAstImpl resources = createImaginary(TokenTypes.RESOURCES);
1156 resources.addChild(firstResource);
1157 processChildren(resources, ctx.children.subList(1, ctx.children.size()));
1158 return resources;
1159 }
1160
1161 @Override
1162 public DetailAstImpl visitResourceDeclaration(
1163 JavaLanguageParser.ResourceDeclarationContext ctx) {
1164 final DetailAstImpl resource = createImaginary(TokenTypes.RESOURCE);
1165 resource.addChild(visit(ctx.variableDeclaratorId()));
1166
1167 final DetailAstImpl assign = create(ctx.ASSIGN());
1168 resource.addChild(assign);
1169 assign.addChild(visit(ctx.expression()));
1170 return resource;
1171 }
1172
1173 @Override
1174 public DetailAstImpl visitVariableAccess(JavaLanguageParser.VariableAccessContext ctx) {
1175 final DetailAstImpl resource = createImaginary(TokenTypes.RESOURCE);
1176
1177 final DetailAstImpl childNode;
1178 if (ctx.LITERAL_THIS() == null) {
1179 childNode = visit(ctx.id());
1180 }
1181 else {
1182 childNode = create(ctx.LITERAL_THIS());
1183 }
1184
1185 if (ctx.accessList.isEmpty()) {
1186 resource.addChild(childNode);
1187 }
1188 else {
1189 final DetailAstPair currentAst = new DetailAstPair();
1190 ctx.accessList.forEach(fieldAccess -> {
1191 DetailAstPair.addAstChild(currentAst, visit(fieldAccess.expr()));
1192 DetailAstPair.makeAstRoot(currentAst, create(fieldAccess.DOT()));
1193 });
1194 resource.addChild(currentAst.getRoot());
1195 resource.getFirstChild().addChild(childNode);
1196 }
1197 return resource;
1198 }
1199
1200 @Override
1201 public DetailAstImpl visitSwitchBlockStatementGroup(
1202 JavaLanguageParser.SwitchBlockStatementGroupContext ctx) {
1203 final DetailAstImpl caseGroup = createImaginary(TokenTypes.CASE_GROUP);
1204 processChildren(caseGroup, ctx.switchLabel());
1205 final DetailAstImpl sList = createImaginary(TokenTypes.SLIST);
1206 processChildren(sList, ctx.slists);
1207 caseGroup.addChild(sList);
1208 return caseGroup;
1209 }
1210
1211 @Override
1212 public DetailAstImpl visitCaseLabel(JavaLanguageParser.CaseLabelContext ctx) {
1213 final DetailAstImpl caseLabel = create(ctx.LITERAL_CASE());
1214
1215 processChildren(caseLabel, ctx.children.subList(1, ctx.children.size()));
1216 return caseLabel;
1217 }
1218
1219 @Override
1220 public DetailAstImpl visitDefaultLabel(JavaLanguageParser.DefaultLabelContext ctx) {
1221 final DetailAstImpl defaultLabel = create(ctx.LITERAL_DEFAULT());
1222 if (ctx.COLON() != null) {
1223 defaultLabel.addChild(create(ctx.COLON()));
1224 }
1225 return defaultLabel;
1226 }
1227
1228 @Override
1229 public DetailAstImpl visitCaseConstants(JavaLanguageParser.CaseConstantsContext ctx) {
1230 return flattenedTree(ctx);
1231 }
1232
1233 @Override
1234 public DetailAstImpl visitCaseConstant(JavaLanguageParser.CaseConstantContext ctx) {
1235 return flattenedTree(ctx);
1236 }
1237
1238 @Override
1239 public DetailAstImpl visitEnhancedFor(JavaLanguageParser.EnhancedForContext ctx) {
1240 final DetailAstImpl leftParen = create(ctx.LPAREN());
1241 final DetailAstImpl enhancedForControl =
1242 visit(ctx.getChild(1));
1243 final DetailAstImpl forEachClause = createImaginary(TokenTypes.FOR_EACH_CLAUSE);
1244 forEachClause.addChild(enhancedForControl);
1245 addLastSibling(leftParen, forEachClause);
1246 addLastSibling(leftParen, create(ctx.RPAREN()));
1247 return leftParen;
1248 }
1249
1250 @Override
1251 public DetailAstImpl visitForFor(JavaLanguageParser.ForForContext ctx) {
1252 final DetailAstImpl dummyRoot = new DetailAstImpl();
1253 dummyRoot.addChild(create(ctx.LPAREN()));
1254
1255 if (ctx.forInit() == null) {
1256 final DetailAstImpl imaginaryForInitParent =
1257 createImaginary(TokenTypes.FOR_INIT);
1258 dummyRoot.addChild(imaginaryForInitParent);
1259 }
1260 else {
1261 dummyRoot.addChild(visit(ctx.forInit()));
1262 }
1263
1264 dummyRoot.addChild(create(ctx.SEMI(0)));
1265
1266 final DetailAstImpl forCondParent = createImaginary(TokenTypes.FOR_CONDITION);
1267 forCondParent.addChild(visit(ctx.forCond));
1268 dummyRoot.addChild(forCondParent);
1269 dummyRoot.addChild(create(ctx.SEMI(1)));
1270
1271 final DetailAstImpl forItParent = createImaginary(TokenTypes.FOR_ITERATOR);
1272 forItParent.addChild(visit(ctx.forUpdate));
1273 dummyRoot.addChild(forItParent);
1274
1275 dummyRoot.addChild(create(ctx.RPAREN()));
1276
1277 return dummyRoot.getFirstChild();
1278 }
1279
1280 @Override
1281 public DetailAstImpl visitForInit(JavaLanguageParser.ForInitContext ctx) {
1282 final DetailAstImpl forInit = createImaginary(TokenTypes.FOR_INIT);
1283 processChildren(forInit, ctx.children);
1284 return forInit;
1285 }
1286
1287 @Override
1288 public DetailAstImpl visitEnhancedForControl(
1289 JavaLanguageParser.EnhancedForControlContext ctx) {
1290 final DetailAstImpl variableDeclaratorId =
1291 visit(ctx.variableDeclaratorId());
1292 final DetailAstImpl variableDef = createImaginary(TokenTypes.VARIABLE_DEF);
1293 variableDef.addChild(variableDeclaratorId);
1294
1295 addLastSibling(variableDef, create(ctx.COLON()));
1296 addLastSibling(variableDef, visit(ctx.expression()));
1297 return variableDef;
1298 }
1299
1300 @Override
1301 public DetailAstImpl visitEnhancedForControlWithRecordPattern(
1302 JavaLanguageParser.EnhancedForControlWithRecordPatternContext ctx) {
1303 final DetailAstImpl recordPattern =
1304 visit(ctx.pattern());
1305 addLastSibling(recordPattern, create(ctx.COLON()));
1306 addLastSibling(recordPattern, visit(ctx.expression()));
1307 return recordPattern;
1308 }
1309
1310 @Override
1311 public DetailAstImpl visitParExpression(JavaLanguageParser.ParExpressionContext ctx) {
1312 return flattenedTree(ctx);
1313 }
1314
1315 @Override
1316 public DetailAstImpl visitExpressionList(JavaLanguageParser.ExpressionListContext ctx) {
1317 final DetailAstImpl elist = createImaginary(TokenTypes.ELIST);
1318 processChildren(elist, ctx.children);
1319 return elist;
1320 }
1321
1322 @Override
1323 public DetailAstImpl visitExpression(JavaLanguageParser.ExpressionContext ctx) {
1324 return buildExpressionNode(ctx.expr());
1325 }
1326
1327 @Override
1328 public DetailAstImpl visitRefOp(JavaLanguageParser.RefOpContext ctx) {
1329 final DetailAstImpl bop = create(ctx.bop);
1330 final DetailAstImpl leftChild = visit(ctx.expr());
1331 final DetailAstImpl rightChild = create(TokenTypes.IDENT, ctx.stop);
1332 bop.addChild(leftChild);
1333 bop.addChild(rightChild);
1334 return bop;
1335 }
1336
1337 @Override
1338 public DetailAstImpl visitSuperExp(JavaLanguageParser.SuperExpContext ctx) {
1339 final DetailAstImpl bop = create(ctx.bop);
1340 bop.addChild(visit(ctx.expr()));
1341 bop.addChild(create(ctx.LITERAL_SUPER()));
1342 DetailAstImpl superSuffixParent = visit(ctx.superSuffix());
1343
1344 if (superSuffixParent == null) {
1345 superSuffixParent = bop;
1346 }
1347 else {
1348 DetailAstImpl firstChild = superSuffixParent;
1349 while (firstChild.getFirstChild() != null) {
1350 firstChild = firstChild.getFirstChild();
1351 }
1352 firstChild.addPreviousSibling(bop);
1353 }
1354
1355 return superSuffixParent;
1356 }
1357
1358 @Override
1359 public DetailAstImpl visitInstanceOfExp(JavaLanguageParser.InstanceOfExpContext ctx) {
1360 final DetailAstImpl literalInstanceOf = create(ctx.LITERAL_INSTANCEOF());
1361 literalInstanceOf.addChild(visit(ctx.expr()));
1362 final ParseTree patternOrType = ctx.getChild(2);
1363
1364 final DetailAstImpl patternDef;
1365 if (patternOrType instanceof JavaLanguageParser.ParenPatternContext) {
1366
1367 patternDef = createImaginary(TokenTypes.PATTERN_DEF);
1368 patternDef.addChild(visit(patternOrType));
1369 }
1370 else {
1371 patternDef = visit(patternOrType);
1372 }
1373 literalInstanceOf.addChild(patternDef);
1374 return literalInstanceOf;
1375 }
1376
1377 @Override
1378 public DetailAstImpl visitBitShift(JavaLanguageParser.BitShiftContext ctx) {
1379 final DetailAstImpl shiftOperation;
1380
1381
1382
1383
1384 if (ctx.LT().size() == LEFT_SHIFT.length()) {
1385 shiftOperation = create(TokenTypes.SL, (Token) ctx.LT(0).getPayload());
1386 shiftOperation.setText(LEFT_SHIFT);
1387 }
1388 else if (ctx.GT().size() == UNSIGNED_RIGHT_SHIFT.length()) {
1389 shiftOperation = create(TokenTypes.BSR, (Token) ctx.GT(0).getPayload());
1390 shiftOperation.setText(UNSIGNED_RIGHT_SHIFT);
1391 }
1392 else {
1393 shiftOperation = create(TokenTypes.SR, (Token) ctx.GT(0).getPayload());
1394 shiftOperation.setText(RIGHT_SHIFT);
1395 }
1396
1397 shiftOperation.addChild(visit(ctx.expr(0)));
1398 shiftOperation.addChild(visit(ctx.expr(1)));
1399 return shiftOperation;
1400 }
1401
1402 @Override
1403 public DetailAstImpl visitNewExp(JavaLanguageParser.NewExpContext ctx) {
1404 final DetailAstImpl newExp = create(ctx.LITERAL_NEW());
1405
1406 processChildren(newExp, ctx.children.subList(1, ctx.children.size()));
1407 return newExp;
1408 }
1409
1410 @Override
1411 public DetailAstImpl visitPrefix(JavaLanguageParser.PrefixContext ctx) {
1412 final int tokenType = switch (ctx.prefix.getType()) {
1413 case JavaLanguageLexer.PLUS -> TokenTypes.UNARY_PLUS;
1414 case JavaLanguageLexer.MINUS -> TokenTypes.UNARY_MINUS;
1415 default -> ctx.prefix.getType();
1416 };
1417 final DetailAstImpl prefix = create(tokenType, ctx.prefix);
1418 prefix.addChild(visit(ctx.expr()));
1419 return prefix;
1420 }
1421
1422 @Override
1423 public DetailAstImpl visitCastExp(JavaLanguageParser.CastExpContext ctx) {
1424 final DetailAstImpl cast = create(TokenTypes.TYPECAST, (Token) ctx.LPAREN().getPayload());
1425
1426 processChildren(cast, ctx.children.subList(1, ctx.children.size()));
1427 return cast;
1428 }
1429
1430 @Override
1431 public DetailAstImpl visitIndexOp(JavaLanguageParser.IndexOpContext ctx) {
1432
1433 final DetailAstImpl indexOp = create(TokenTypes.INDEX_OP,
1434 (Token) ctx.LBRACK().getPayload());
1435
1436
1437 indexOp.addChild(visit(ctx.expr(0)));
1438
1439
1440 final DetailAstImpl expr = visit(ctx.expr(1));
1441 final DetailAstImpl imaginaryExpr = createImaginary(TokenTypes.EXPR);
1442 imaginaryExpr.addChild(expr);
1443 indexOp.addChild(imaginaryExpr);
1444
1445
1446 indexOp.addChild(create(ctx.RBRACK()));
1447 return indexOp;
1448 }
1449
1450 @Override
1451 public DetailAstImpl visitInvOp(JavaLanguageParser.InvOpContext ctx) {
1452 final DetailAstPair currentAst = new DetailAstPair();
1453
1454 final DetailAstImpl returnAst = visit(ctx.expr());
1455 DetailAstPair.addAstChild(currentAst, returnAst);
1456 DetailAstPair.makeAstRoot(currentAst, create(ctx.bop));
1457
1458 DetailAstPair.addAstChild(currentAst,
1459 visit(ctx.nonWildcardTypeArguments()));
1460 DetailAstPair.addAstChild(currentAst, visit(ctx.id()));
1461 final DetailAstImpl lparen = create(TokenTypes.METHOD_CALL,
1462 (Token) ctx.LPAREN().getPayload());
1463 DetailAstPair.makeAstRoot(currentAst, lparen);
1464
1465
1466 final DetailAstImpl expressionList = Optional.ofNullable(visit(ctx.expressionList()))
1467 .orElseGet(() -> createImaginary(TokenTypes.ELIST));
1468
1469 DetailAstPair.addAstChild(currentAst, expressionList);
1470 DetailAstPair.addAstChild(currentAst, create(ctx.RPAREN()));
1471
1472 return currentAst.root;
1473 }
1474
1475 @Override
1476 public DetailAstImpl visitInitExp(JavaLanguageParser.InitExpContext ctx) {
1477 final DetailAstImpl dot = create(ctx.bop);
1478 dot.addChild(visit(ctx.expr()));
1479 final DetailAstImpl literalNew = create(ctx.LITERAL_NEW());
1480 literalNew.addChild(visit(ctx.nonWildcardTypeArguments()));
1481 literalNew.addChild(visit(ctx.innerCreator()));
1482 dot.addChild(literalNew);
1483 return dot;
1484 }
1485
1486 @Override
1487 public DetailAstImpl visitSimpleMethodCall(JavaLanguageParser.SimpleMethodCallContext ctx) {
1488 final DetailAstImpl methodCall = create(TokenTypes.METHOD_CALL,
1489 (Token) ctx.LPAREN().getPayload());
1490 methodCall.addChild(visit(ctx.id()));
1491
1492 final DetailAstImpl expressionList = Optional.ofNullable(visit(ctx.expressionList()))
1493 .orElseGet(() -> createImaginary(TokenTypes.ELIST));
1494
1495 methodCall.addChild(expressionList);
1496 methodCall.addChild(create((Token) ctx.RPAREN().getPayload()));
1497 return methodCall;
1498 }
1499
1500 @Override
1501 public DetailAstImpl visitLambdaExp(JavaLanguageParser.LambdaExpContext ctx) {
1502 final DetailAstImpl lambda = create(ctx.LAMBDA());
1503 lambda.addChild(visit(ctx.lambdaParameters()));
1504
1505 final JavaLanguageParser.BlockContext blockContext = ctx.block();
1506 final DetailAstImpl rightHandLambdaChild;
1507 if (blockContext != null) {
1508 rightHandLambdaChild = visit(blockContext);
1509 }
1510 else {
1511
1512
1513
1514
1515 rightHandLambdaChild = buildExpressionNode(ctx.expr());
1516 }
1517 lambda.addChild(rightHandLambdaChild);
1518 return lambda;
1519 }
1520
1521 @Override
1522 public DetailAstImpl visitThisExp(JavaLanguageParser.ThisExpContext ctx) {
1523 final DetailAstImpl bop = create(ctx.bop);
1524 bop.addChild(visit(ctx.expr()));
1525 bop.addChild(create(ctx.LITERAL_THIS()));
1526 return bop;
1527 }
1528
1529 @Override
1530 public DetailAstImpl visitPrimaryExp(JavaLanguageParser.PrimaryExpContext ctx) {
1531 return flattenedTree(ctx);
1532 }
1533
1534 @Override
1535 public DetailAstImpl visitPostfix(JavaLanguageParser.PostfixContext ctx) {
1536 final DetailAstImpl postfix;
1537 if (ctx.postfix.getType() == JavaLanguageLexer.INC) {
1538 postfix = create(TokenTypes.POST_INC, ctx.postfix);
1539 }
1540 else {
1541 postfix = create(TokenTypes.POST_DEC, ctx.postfix);
1542 }
1543 postfix.addChild(visit(ctx.expr()));
1544 return postfix;
1545 }
1546
1547 @Override
1548 public DetailAstImpl visitMethodRef(JavaLanguageParser.MethodRefContext ctx) {
1549 final DetailAstImpl doubleColon = create(TokenTypes.METHOD_REF,
1550 (Token) ctx.DOUBLE_COLON().getPayload());
1551 final List<ParseTree> children = ctx.children.stream()
1552 .filter(child -> !child.equals(ctx.DOUBLE_COLON()))
1553 .toList();
1554 processChildren(doubleColon, children);
1555 return doubleColon;
1556 }
1557
1558 @Override
1559 public DetailAstImpl visitTernaryOp(JavaLanguageParser.TernaryOpContext ctx) {
1560 final DetailAstImpl root = create(ctx.QUESTION());
1561 processChildren(root, ctx.children.stream()
1562 .filter(child -> !child.equals(ctx.QUESTION()))
1563 .toList());
1564 return root;
1565 }
1566
1567 @Override
1568 public DetailAstImpl visitBinOp(JavaLanguageParser.BinOpContext ctx) {
1569 final DetailAstImpl bop = create(ctx.bop);
1570
1571
1572
1573 final List<JavaLanguageParser.BinOpContext> binOpList = new ArrayList<>();
1574 ParseTree firstExpression = ctx.expr(0);
1575 while (firstExpression instanceof JavaLanguageParser.BinOpContext) {
1576
1577 binOpList.add((JavaLanguageParser.BinOpContext) firstExpression);
1578 firstExpression = ((JavaLanguageParser.BinOpContext) firstExpression).expr(0);
1579 }
1580
1581 if (binOpList.isEmpty()) {
1582 final DetailAstImpl leftChild = visit(ctx.children.get(0));
1583 bop.addChild(leftChild);
1584 }
1585 else {
1586
1587
1588 final Queue<DetailAstImpl> descendantList = binOpList.parallelStream()
1589 .map(this::getInnerBopAst)
1590 .collect(Collectors.toCollection(ArrayDeque::new));
1591
1592 bop.addChild(descendantList.poll());
1593 DetailAstImpl pointer = bop.getFirstChild();
1594
1595 for (DetailAstImpl descendant : descendantList) {
1596 pointer.getFirstChild().addPreviousSibling(descendant);
1597 pointer = descendant;
1598 }
1599 }
1600
1601 bop.addChild(visit(ctx.children.get(2)));
1602 return bop;
1603 }
1604
1605
1606
1607
1608
1609
1610
1611 private DetailAstImpl getInnerBopAst(JavaLanguageParser.BinOpContext descendant) {
1612 final DetailAstImpl innerBop = create(descendant.bop);
1613 final JavaLanguageParser.ExprContext expr = descendant.expr(0);
1614 if (!(expr instanceof JavaLanguageParser.BinOpContext)) {
1615 innerBop.addChild(visit(expr));
1616 }
1617 innerBop.addChild(visit(descendant.expr(1)));
1618 return innerBop;
1619 }
1620
1621 @Override
1622 public DetailAstImpl visitMethodCall(JavaLanguageParser.MethodCallContext ctx) {
1623 final DetailAstImpl methodCall = create(TokenTypes.METHOD_CALL,
1624 (Token) ctx.LPAREN().getPayload());
1625
1626 final DetailAstImpl expressionList = Optional.ofNullable(visit(ctx.expressionList()))
1627 .orElseGet(() -> createImaginary(TokenTypes.ELIST));
1628
1629 final DetailAstImpl dot = create(ctx.DOT());
1630 dot.addChild(visit(ctx.expr()));
1631 dot.addChild(visit(ctx.id()));
1632 methodCall.addChild(dot);
1633 methodCall.addChild(expressionList);
1634 methodCall.addChild(create((Token) ctx.RPAREN().getPayload()));
1635 return methodCall;
1636 }
1637
1638 @Override
1639 public DetailAstImpl visitTypeCastParameters(
1640 JavaLanguageParser.TypeCastParametersContext ctx) {
1641 final DetailAstImpl typeType = visit(ctx.typeType(0));
1642 for (int i = 0; i < ctx.BAND().size(); i++) {
1643 addLastSibling(typeType, create(TokenTypes.TYPE_EXTENSION_AND,
1644 (Token) ctx.BAND(i).getPayload()));
1645 addLastSibling(typeType, visit(ctx.typeType(i + 1)));
1646 }
1647 return typeType;
1648 }
1649
1650 @Override
1651 public DetailAstImpl visitSingleLambdaParam(JavaLanguageParser.SingleLambdaParamContext ctx) {
1652 return flattenedTree(ctx);
1653 }
1654
1655 @Override
1656 public DetailAstImpl visitFormalLambdaParam(JavaLanguageParser.FormalLambdaParamContext ctx) {
1657 final DetailAstImpl lparen = create(ctx.LPAREN());
1658
1659
1660 final DetailAstImpl parameters = Optional.ofNullable(visit(ctx.formalParameterList()))
1661 .orElseGet(() -> createImaginary(TokenTypes.PARAMETERS));
1662 addLastSibling(lparen, parameters);
1663 addLastSibling(lparen, create(ctx.RPAREN()));
1664 return lparen;
1665 }
1666
1667 @Override
1668 public DetailAstImpl visitMultiLambdaParam(JavaLanguageParser.MultiLambdaParamContext ctx) {
1669 final DetailAstImpl lparen = create(ctx.LPAREN());
1670 addLastSibling(lparen, visit(ctx.multiLambdaParams()));
1671 addLastSibling(lparen, create(ctx.RPAREN()));
1672 return lparen;
1673 }
1674
1675 @Override
1676 public DetailAstImpl visitMultiLambdaParams(JavaLanguageParser.MultiLambdaParamsContext ctx) {
1677 final DetailAstImpl parameters = createImaginary(TokenTypes.PARAMETERS);
1678 parameters.addChild(createLambdaParameter(ctx.id(0)));
1679
1680 for (int i = 0; i < ctx.COMMA().size(); i++) {
1681 parameters.addChild(create(ctx.COMMA(i)));
1682 parameters.addChild(createLambdaParameter(ctx.id(i + 1)));
1683 }
1684 return parameters;
1685 }
1686
1687
1688
1689
1690
1691
1692
1693
1694 private DetailAstImpl createLambdaParameter(JavaLanguageParser.IdContext ctx) {
1695 final DetailAstImpl ident = visitId(ctx);
1696 final DetailAstImpl parameter = createImaginary(TokenTypes.PARAMETER_DEF);
1697 final DetailAstImpl modifiers = createImaginary(TokenTypes.MODIFIERS);
1698 final DetailAstImpl type = createImaginary(TokenTypes.TYPE);
1699 parameter.addChild(modifiers);
1700 parameter.addChild(type);
1701 parameter.addChild(ident);
1702 return parameter;
1703 }
1704
1705 @Override
1706 public DetailAstImpl visitParenPrimary(JavaLanguageParser.ParenPrimaryContext ctx) {
1707 return flattenedTree(ctx);
1708 }
1709
1710 @Override
1711 public DetailAstImpl visitTokenPrimary(JavaLanguageParser.TokenPrimaryContext ctx) {
1712 return flattenedTree(ctx);
1713 }
1714
1715 @Override
1716 public DetailAstImpl visitClassRefPrimary(JavaLanguageParser.ClassRefPrimaryContext ctx) {
1717 final DetailAstImpl dot = create(ctx.DOT());
1718 final DetailAstImpl primaryTypeNoArray = visit(ctx.type);
1719 dot.addChild(primaryTypeNoArray);
1720 if (TokenUtil.isOfType(primaryTypeNoArray, TokenTypes.DOT)) {
1721
1722 ctx.arrayDeclarator()
1723 .forEach(child -> primaryTypeNoArray.addChild(visit(child)));
1724 }
1725 else {
1726 ctx.arrayDeclarator()
1727 .forEach(child -> addLastSibling(primaryTypeNoArray, visit(child)));
1728 }
1729 dot.addChild(create(ctx.LITERAL_CLASS()));
1730 return dot;
1731 }
1732
1733 @Override
1734 public DetailAstImpl visitPrimitivePrimary(JavaLanguageParser.PrimitivePrimaryContext ctx) {
1735 final DetailAstImpl dot = create(ctx.DOT());
1736 final DetailAstImpl primaryTypeNoArray = visit(ctx.type);
1737 dot.addChild(primaryTypeNoArray);
1738 ctx.arrayDeclarator().forEach(child -> dot.addChild(visit(child)));
1739 dot.addChild(create(ctx.LITERAL_CLASS()));
1740 return dot;
1741 }
1742
1743 @Override
1744 public DetailAstImpl visitCreator(JavaLanguageParser.CreatorContext ctx) {
1745 return flattenedTree(ctx);
1746 }
1747
1748 @Override
1749 public DetailAstImpl visitCreatedNameObject(JavaLanguageParser.CreatedNameObjectContext ctx) {
1750 final DetailAstPair currentAST = new DetailAstPair();
1751 DetailAstPair.addAstChild(currentAST, visit(ctx.annotations()));
1752 DetailAstPair.addAstChild(currentAST, visit(ctx.id()));
1753 DetailAstPair.addAstChild(currentAST, visit(ctx.typeArgumentsOrDiamond()));
1754
1755
1756 for (ParserRuleContext extendedContext : ctx.extended) {
1757 final DetailAstImpl dot = create(extendedContext.start);
1758 DetailAstPair.makeAstRoot(currentAST, dot);
1759 final List<ParseTree> childList = extendedContext
1760 .children.subList(1, extendedContext.children.size());
1761 processChildren(dot, childList);
1762 }
1763
1764 return currentAST.root;
1765 }
1766
1767 @Override
1768 public DetailAstImpl visitCreatedNamePrimitive(
1769 JavaLanguageParser.CreatedNamePrimitiveContext ctx) {
1770 return flattenedTree(ctx);
1771 }
1772
1773 @Override
1774 public DetailAstImpl visitInnerCreator(JavaLanguageParser.InnerCreatorContext ctx) {
1775 return flattenedTree(ctx);
1776 }
1777
1778 @Override
1779 public DetailAstImpl visitArrayCreatorRest(JavaLanguageParser.ArrayCreatorRestContext ctx) {
1780 final DetailAstImpl arrayDeclarator = create(TokenTypes.ARRAY_DECLARATOR,
1781 (Token) ctx.LBRACK().getPayload());
1782 final JavaLanguageParser.ExpressionContext expression = ctx.expression();
1783 final TerminalNode rbrack = ctx.RBRACK();
1784
1785 for (int i = 1; i < ctx.children.size(); i++) {
1786 if (ctx.children.get(i) == rbrack) {
1787 arrayDeclarator.addChild(create(rbrack));
1788 }
1789 else if (ctx.children.get(i) == expression) {
1790
1791 arrayDeclarator.addChild(visit(expression));
1792 }
1793 else {
1794 addLastSibling(arrayDeclarator, visit(ctx.children.get(i)));
1795 }
1796 }
1797 return arrayDeclarator;
1798 }
1799
1800 @Override
1801 public DetailAstImpl visitBracketsWithExp(JavaLanguageParser.BracketsWithExpContext ctx) {
1802 final DetailAstImpl dummyRoot = new DetailAstImpl();
1803 dummyRoot.addChild(visit(ctx.annotations()));
1804 final DetailAstImpl arrayDeclarator =
1805 create(TokenTypes.ARRAY_DECLARATOR, (Token) ctx.LBRACK().getPayload());
1806 arrayDeclarator.addChild(visit(ctx.expression()));
1807 arrayDeclarator.addChild(create(ctx.stop));
1808 dummyRoot.addChild(arrayDeclarator);
1809 return dummyRoot.getFirstChild();
1810 }
1811
1812 @Override
1813 public DetailAstImpl visitClassCreatorRest(JavaLanguageParser.ClassCreatorRestContext ctx) {
1814 return flattenedTree(ctx);
1815 }
1816
1817 @Override
1818 public DetailAstImpl visitDiamond(JavaLanguageParser.DiamondContext ctx) {
1819 final DetailAstImpl typeArguments =
1820 createImaginary(TokenTypes.TYPE_ARGUMENTS);
1821 typeArguments.addChild(create(TokenTypes.GENERIC_START,
1822 (Token) ctx.LT().getPayload()));
1823 typeArguments.addChild(create(TokenTypes.GENERIC_END,
1824 (Token) ctx.GT().getPayload()));
1825 return typeArguments;
1826 }
1827
1828 @Override
1829 public DetailAstImpl visitTypeArgs(JavaLanguageParser.TypeArgsContext ctx) {
1830 return flattenedTree(ctx);
1831 }
1832
1833 @Override
1834 public DetailAstImpl visitNonWildcardDiamond(
1835 JavaLanguageParser.NonWildcardDiamondContext ctx) {
1836 final DetailAstImpl typeArguments =
1837 createImaginary(TokenTypes.TYPE_ARGUMENTS);
1838 typeArguments.addChild(create(TokenTypes.GENERIC_START,
1839 (Token) ctx.LT().getPayload()));
1840 typeArguments.addChild(create(TokenTypes.GENERIC_END,
1841 (Token) ctx.GT().getPayload()));
1842 return typeArguments;
1843 }
1844
1845 @Override
1846 public DetailAstImpl visitNonWildcardTypeArguments(
1847 JavaLanguageParser.NonWildcardTypeArgumentsContext ctx) {
1848 final DetailAstImpl typeArguments = createImaginary(TokenTypes.TYPE_ARGUMENTS);
1849 typeArguments.addChild(create(TokenTypes.GENERIC_START, (Token) ctx.LT().getPayload()));
1850 typeArguments.addChild(visit(ctx.typeArgumentsTypeList()));
1851 typeArguments.addChild(create(TokenTypes.GENERIC_END, (Token) ctx.GT().getPayload()));
1852 return typeArguments;
1853 }
1854
1855 @Override
1856 public DetailAstImpl visitTypeArgumentsTypeList(
1857 JavaLanguageParser.TypeArgumentsTypeListContext ctx) {
1858 final DetailAstImpl firstIdent = visit(ctx.typeType(0));
1859 final DetailAstImpl firstTypeArgument = createImaginary(TokenTypes.TYPE_ARGUMENT);
1860 firstTypeArgument.addChild(firstIdent);
1861
1862 for (int i = 0; i < ctx.COMMA().size(); i++) {
1863 addLastSibling(firstTypeArgument, create(ctx.COMMA(i)));
1864 final DetailAstImpl ident = visit(ctx.typeType(i + 1));
1865 final DetailAstImpl typeArgument = createImaginary(TokenTypes.TYPE_ARGUMENT);
1866 typeArgument.addChild(ident);
1867 addLastSibling(firstTypeArgument, typeArgument);
1868 }
1869 return firstTypeArgument;
1870 }
1871
1872 @Override
1873 public DetailAstImpl visitTypeList(JavaLanguageParser.TypeListContext ctx) {
1874 return flattenedTree(ctx);
1875 }
1876
1877 @Override
1878 public DetailAstImpl visitTypeType(JavaLanguageParser.TypeTypeContext ctx) {
1879 final DetailAstImpl type = createImaginary(TokenTypes.TYPE);
1880 processChildren(type, ctx.children);
1881
1882 final DetailAstImpl returnTree;
1883 if (ctx.createImaginaryNode) {
1884 returnTree = type;
1885 }
1886 else {
1887 returnTree = type.getFirstChild();
1888 }
1889 return returnTree;
1890 }
1891
1892 @Override
1893 public DetailAstImpl visitArrayDeclarator(JavaLanguageParser.ArrayDeclaratorContext ctx) {
1894 final DetailAstImpl arrayDeclarator = create(TokenTypes.ARRAY_DECLARATOR,
1895 (Token) ctx.LBRACK().getPayload());
1896 arrayDeclarator.addChild(create(ctx.RBRACK()));
1897
1898 final DetailAstImpl returnTree;
1899 final DetailAstImpl annotations = visit(ctx.anno);
1900 if (annotations == null) {
1901 returnTree = arrayDeclarator;
1902 }
1903 else {
1904 returnTree = annotations;
1905 addLastSibling(returnTree, arrayDeclarator);
1906 }
1907 return returnTree;
1908 }
1909
1910 @Override
1911 public DetailAstImpl visitPrimitiveType(JavaLanguageParser.PrimitiveTypeContext ctx) {
1912 return create(ctx.start);
1913 }
1914
1915 @Override
1916 public DetailAstImpl visitTypeArguments(JavaLanguageParser.TypeArgumentsContext ctx) {
1917 final DetailAstImpl typeArguments = createImaginary(TokenTypes.TYPE_ARGUMENTS);
1918 typeArguments.addChild(create(TokenTypes.GENERIC_START, (Token) ctx.LT().getPayload()));
1919
1920 processChildren(typeArguments, ctx.children.subList(1, ctx.children.size() - 1));
1921 typeArguments.addChild(create(TokenTypes.GENERIC_END, (Token) ctx.GT().getPayload()));
1922 return typeArguments;
1923 }
1924
1925 @Override
1926 public DetailAstImpl visitSuperSuffixDot(JavaLanguageParser.SuperSuffixDotContext ctx) {
1927 final DetailAstImpl root;
1928 if (ctx.LPAREN() == null) {
1929 root = create(ctx.DOT());
1930 root.addChild(visit(ctx.id()));
1931 }
1932 else {
1933 root = create(TokenTypes.METHOD_CALL, (Token) ctx.LPAREN().getPayload());
1934
1935 final DetailAstImpl dot = create(ctx.DOT());
1936 dot.addChild(visit(ctx.id()));
1937 root.addChild(dot);
1938
1939 final DetailAstImpl expressionList = Optional.ofNullable(visit(ctx.expressionList()))
1940 .orElseGet(() -> createImaginary(TokenTypes.ELIST));
1941 root.addChild(expressionList);
1942
1943 root.addChild(create(ctx.RPAREN()));
1944 }
1945
1946 return root;
1947 }
1948
1949 @Override
1950 public DetailAstImpl visitArguments(JavaLanguageParser.ArgumentsContext ctx) {
1951 final DetailAstImpl lparen = create(ctx.LPAREN());
1952
1953
1954 final DetailAstImpl expressionList = Optional.ofNullable(visit(ctx.expressionList()))
1955 .orElseGet(() -> createImaginary(TokenTypes.ELIST));
1956 addLastSibling(lparen, expressionList);
1957 addLastSibling(lparen, create(ctx.RPAREN()));
1958 return lparen;
1959 }
1960
1961 @Override
1962 public DetailAstImpl visitPattern(JavaLanguageParser.PatternContext ctx) {
1963 final JavaLanguageParser.InnerPatternContext innerPattern = ctx.innerPattern();
1964 final ParserRuleContext primaryPattern = innerPattern.primaryPattern();
1965 final ParserRuleContext recordPattern = innerPattern.recordPattern();
1966 final boolean isSimpleTypePattern = primaryPattern != null
1967 && primaryPattern.getChild(0) instanceof JavaLanguageParser.TypePatternContext;
1968
1969 final DetailAstImpl pattern;
1970
1971 if (recordPattern != null) {
1972 pattern = visit(recordPattern);
1973 }
1974 else if (isSimpleTypePattern) {
1975
1976 pattern = visit(primaryPattern);
1977 }
1978 else {
1979 pattern = createImaginary(TokenTypes.PATTERN_DEF);
1980 pattern.addChild(visit(ctx.getChild(0)));
1981 }
1982 return pattern;
1983 }
1984
1985 @Override
1986 public DetailAstImpl visitInnerPattern(JavaLanguageParser.InnerPatternContext ctx) {
1987 return flattenedTree(ctx);
1988 }
1989
1990 @Override
1991 public DetailAstImpl visitGuardedPattern(JavaLanguageParser.GuardedPatternContext ctx) {
1992 final DetailAstImpl guardAstNode = flattenedTree(ctx.guard());
1993 guardAstNode.addChild(visit(ctx.primaryPattern()));
1994 guardAstNode.addChild(visit(ctx.expression()));
1995 return guardAstNode;
1996 }
1997
1998 @Override
1999 public DetailAstImpl visitParenPattern(JavaLanguageParser.ParenPatternContext ctx) {
2000 final DetailAstImpl lparen = create(ctx.LPAREN());
2001 final ParseTree innerPattern = ctx.getChild(1);
2002 lparen.addChild(visit(innerPattern));
2003 lparen.addChild(create(ctx.RPAREN()));
2004 return lparen;
2005 }
2006
2007 @Override
2008 public DetailAstImpl visitRecordPatternDef(JavaLanguageParser.RecordPatternDefContext ctx) {
2009 return flattenedTree(ctx);
2010 }
2011
2012 @Override
2013 public DetailAstImpl visitTypePatternDef(
2014 JavaLanguageParser.TypePatternDefContext ctx) {
2015 final DetailAstImpl type = visit(ctx.type);
2016 final DetailAstImpl patternVariableDef = createImaginary(TokenTypes.PATTERN_VARIABLE_DEF);
2017 patternVariableDef.addChild(createModifiers(ctx.mods));
2018 patternVariableDef.addChild(type);
2019 patternVariableDef.addChild(visit(ctx.id()));
2020 return patternVariableDef;
2021 }
2022
2023 @Override
2024 public DetailAstImpl visitUnnamedPatternDef(JavaLanguageParser.UnnamedPatternDefContext ctx) {
2025 return create(TokenTypes.UNNAMED_PATTERN_DEF, ctx.start);
2026 }
2027
2028 @Override
2029 public DetailAstImpl visitRecordPattern(JavaLanguageParser.RecordPatternContext ctx) {
2030 final DetailAstImpl recordPattern = createImaginary(TokenTypes.RECORD_PATTERN_DEF);
2031 recordPattern.addChild(createModifiers(ctx.mods));
2032 processChildren(recordPattern,
2033 ctx.children.subList(ctx.mods.size(), ctx.children.size()));
2034 return recordPattern;
2035 }
2036
2037 @Override
2038 public DetailAstImpl visitRecordComponentPatternList(
2039 JavaLanguageParser.RecordComponentPatternListContext ctx) {
2040 final DetailAstImpl recordComponents =
2041 createImaginary(TokenTypes.RECORD_PATTERN_COMPONENTS);
2042 processChildren(recordComponents, ctx.children);
2043 return recordComponents;
2044 }
2045
2046 @Override
2047 public DetailAstImpl visitPermittedSubclassesAndInterfaces(
2048 JavaLanguageParser.PermittedSubclassesAndInterfacesContext ctx) {
2049 final DetailAstImpl literalPermits =
2050 create(TokenTypes.PERMITS_CLAUSE, (Token) ctx.LITERAL_PERMITS().getPayload());
2051
2052 processChildren(literalPermits, ctx.children.subList(1, ctx.children.size()));
2053 return literalPermits;
2054 }
2055
2056 @Override
2057 public DetailAstImpl visitId(JavaLanguageParser.IdContext ctx) {
2058 return create(TokenTypes.IDENT, ctx.start);
2059 }
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069 private DetailAstImpl flattenedTree(ParserRuleContext ctx) {
2070 final DetailAstImpl dummyNode = new DetailAstImpl();
2071 processChildren(dummyNode, ctx.children);
2072 return dummyNode.getFirstChild();
2073 }
2074
2075
2076
2077
2078
2079
2080
2081
2082 private void processChildren(DetailAstImpl parent, List<? extends ParseTree> children) {
2083 children.forEach(child -> {
2084 if (child instanceof TerminalNode) {
2085
2086 parent.addChild(create((TerminalNode) child));
2087 }
2088 else {
2089
2090 parent.addChild(visit(child));
2091 }
2092 });
2093 }
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103 private static DetailAstImpl createImaginary(int tokenType) {
2104 final DetailAstImpl detailAst = new DetailAstImpl();
2105 detailAst.setType(tokenType);
2106 detailAst.setText(TokenUtil.getTokenName(tokenType));
2107 return detailAst;
2108 }
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118 private DetailAstImpl create(int tokenType, Token startToken) {
2119 final DetailAstImpl ast = create(startToken);
2120 ast.setType(tokenType);
2121 return ast;
2122 }
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132 private DetailAstImpl create(Token token) {
2133 final int tokenIndex = token.getTokenIndex();
2134 final List<Token> tokensToLeft =
2135 tokens.getHiddenTokensToLeft(tokenIndex, JavaLanguageLexer.COMMENTS);
2136 final List<Token> tokensToRight =
2137 tokens.getHiddenTokensToRight(tokenIndex, JavaLanguageLexer.COMMENTS);
2138
2139 final DetailAstImpl detailAst = new DetailAstImpl();
2140 detailAst.initialize(token);
2141 if (tokensToLeft != null) {
2142 detailAst.setHiddenBefore(tokensToLeft);
2143 }
2144 if (tokensToRight != null) {
2145 detailAst.setHiddenAfter(tokensToRight);
2146 }
2147 return detailAst;
2148 }
2149
2150
2151
2152
2153
2154
2155
2156
2157 private DetailAstImpl create(TerminalNode node) {
2158 return create((Token) node.getPayload());
2159 }
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169 private DetailAstImpl createTypeDeclaration(ParserRuleContext ctx, int type,
2170 List<? extends ParseTree> modifierList) {
2171 final DetailAstImpl typeDeclaration = createImaginary(type);
2172 typeDeclaration.addChild(createModifiers(modifierList));
2173 processChildren(typeDeclaration, ctx.children);
2174 return typeDeclaration;
2175 }
2176
2177
2178
2179
2180
2181
2182
2183 private DetailAstImpl createModifiers(List<? extends ParseTree> modifierList) {
2184 final DetailAstImpl mods = createImaginary(TokenTypes.MODIFIERS);
2185 processChildren(mods, modifierList);
2186 return mods;
2187 }
2188
2189
2190
2191
2192
2193
2194
2195 private static void addLastSibling(DetailAstImpl self, DetailAstImpl sibling) {
2196 DetailAstImpl nextSibling = self;
2197 if (nextSibling != null) {
2198 while (nextSibling.getNextSibling() != null) {
2199 nextSibling = nextSibling.getNextSibling();
2200 }
2201 nextSibling.setNextSibling(sibling);
2202 }
2203 }
2204
2205 @Override
2206 public DetailAstImpl visit(ParseTree tree) {
2207 DetailAstImpl ast = null;
2208 if (tree != null) {
2209 ast = tree.accept(this);
2210 }
2211 return ast;
2212 }
2213
2214
2215
2216
2217
2218
2219
2220
2221 private DetailAstImpl buildExpressionNode(ParseTree exprNode) {
2222 final DetailAstImpl expression = visit(exprNode);
2223
2224 final DetailAstImpl exprRoot;
2225 if (TokenUtil.isOfType(expression, EXPRESSIONS_WITH_NO_EXPR_ROOT)) {
2226 exprRoot = expression;
2227 }
2228 else {
2229
2230 exprRoot = createImaginary(TokenTypes.EXPR);
2231 exprRoot.addChild(expression);
2232 }
2233 return exprRoot;
2234 }
2235
2236
2237
2238
2239 private static final class DetailAstPair {
2240
2241
2242 private DetailAstImpl root;
2243
2244
2245 private DetailAstImpl child;
2246
2247
2248
2249
2250 private void advanceChildToEnd() {
2251 while (child.getNextSibling() != null) {
2252 child = child.getNextSibling();
2253 }
2254 }
2255
2256
2257
2258
2259
2260
2261 private DetailAstImpl getRoot() {
2262 return root;
2263 }
2264
2265
2266
2267
2268
2269
2270
2271
2272 private static void makeAstRoot(DetailAstPair pair, DetailAstImpl ast) {
2273 ast.addChild(pair.root);
2274 pair.child = pair.root;
2275 pair.advanceChildToEnd();
2276 pair.root = ast;
2277 }
2278
2279
2280
2281
2282
2283
2284
2285 private static void addAstChild(DetailAstPair pair, DetailAstImpl ast) {
2286 if (ast != null) {
2287 if (pair.root == null) {
2288 pair.root = ast;
2289 }
2290 else {
2291 pair.child.setNextSibling(ast);
2292 }
2293 pair.child = ast;
2294 }
2295 }
2296 }
2297 }