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.ArrayList;
23 import java.util.Collections;
24 import java.util.Iterator;
25 import java.util.List;
26 import java.util.Optional;
27 import java.util.Queue;
28 import java.util.concurrent.ConcurrentLinkedQueue;
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 .collect(Collectors.toUnmodifiableList()));
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 .collect(Collectors.toUnmodifiableList());
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 .collect(Collectors.toUnmodifiableList()));
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 .collect(Collectors.toUnmodifiableList()));
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 .collect(Collectors.toUnmodifiableList()));
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;
1413 switch (ctx.prefix.getType()) {
1414 case JavaLanguageLexer.PLUS:
1415 tokenType = TokenTypes.UNARY_PLUS;
1416 break;
1417 case JavaLanguageLexer.MINUS:
1418 tokenType = TokenTypes.UNARY_MINUS;
1419 break;
1420 default:
1421 tokenType = ctx.prefix.getType();
1422 }
1423 final DetailAstImpl prefix = create(tokenType, ctx.prefix);
1424 prefix.addChild(visit(ctx.expr()));
1425 return prefix;
1426 }
1427
1428 @Override
1429 public DetailAstImpl visitCastExp(JavaLanguageParser.CastExpContext ctx) {
1430 final DetailAstImpl cast = create(TokenTypes.TYPECAST, (Token) ctx.LPAREN().getPayload());
1431
1432 processChildren(cast, ctx.children.subList(1, ctx.children.size()));
1433 return cast;
1434 }
1435
1436 @Override
1437 public DetailAstImpl visitIndexOp(JavaLanguageParser.IndexOpContext ctx) {
1438
1439 final DetailAstImpl indexOp = create(TokenTypes.INDEX_OP,
1440 (Token) ctx.LBRACK().getPayload());
1441
1442
1443 indexOp.addChild(visit(ctx.expr(0)));
1444
1445
1446 final DetailAstImpl expr = visit(ctx.expr(1));
1447 final DetailAstImpl imaginaryExpr = createImaginary(TokenTypes.EXPR);
1448 imaginaryExpr.addChild(expr);
1449 indexOp.addChild(imaginaryExpr);
1450
1451
1452 indexOp.addChild(create(ctx.RBRACK()));
1453 return indexOp;
1454 }
1455
1456 @Override
1457 public DetailAstImpl visitInvOp(JavaLanguageParser.InvOpContext ctx) {
1458 final DetailAstPair currentAst = new DetailAstPair();
1459
1460 final DetailAstImpl returnAst = visit(ctx.expr());
1461 DetailAstPair.addAstChild(currentAst, returnAst);
1462 DetailAstPair.makeAstRoot(currentAst, create(ctx.bop));
1463
1464 DetailAstPair.addAstChild(currentAst,
1465 visit(ctx.nonWildcardTypeArguments()));
1466 DetailAstPair.addAstChild(currentAst, visit(ctx.id()));
1467 final DetailAstImpl lparen = create(TokenTypes.METHOD_CALL,
1468 (Token) ctx.LPAREN().getPayload());
1469 DetailAstPair.makeAstRoot(currentAst, lparen);
1470
1471
1472 final DetailAstImpl expressionList = Optional.ofNullable(visit(ctx.expressionList()))
1473 .orElseGet(() -> createImaginary(TokenTypes.ELIST));
1474
1475 DetailAstPair.addAstChild(currentAst, expressionList);
1476 DetailAstPair.addAstChild(currentAst, create(ctx.RPAREN()));
1477
1478 return currentAst.root;
1479 }
1480
1481 @Override
1482 public DetailAstImpl visitInitExp(JavaLanguageParser.InitExpContext ctx) {
1483 final DetailAstImpl dot = create(ctx.bop);
1484 dot.addChild(visit(ctx.expr()));
1485 final DetailAstImpl literalNew = create(ctx.LITERAL_NEW());
1486 literalNew.addChild(visit(ctx.nonWildcardTypeArguments()));
1487 literalNew.addChild(visit(ctx.innerCreator()));
1488 dot.addChild(literalNew);
1489 return dot;
1490 }
1491
1492 @Override
1493 public DetailAstImpl visitSimpleMethodCall(JavaLanguageParser.SimpleMethodCallContext ctx) {
1494 final DetailAstImpl methodCall = create(TokenTypes.METHOD_CALL,
1495 (Token) ctx.LPAREN().getPayload());
1496 methodCall.addChild(visit(ctx.id()));
1497
1498 final DetailAstImpl expressionList = Optional.ofNullable(visit(ctx.expressionList()))
1499 .orElseGet(() -> createImaginary(TokenTypes.ELIST));
1500
1501 methodCall.addChild(expressionList);
1502 methodCall.addChild(create((Token) ctx.RPAREN().getPayload()));
1503 return methodCall;
1504 }
1505
1506 @Override
1507 public DetailAstImpl visitLambdaExp(JavaLanguageParser.LambdaExpContext ctx) {
1508 final DetailAstImpl lambda = create(ctx.LAMBDA());
1509 lambda.addChild(visit(ctx.lambdaParameters()));
1510
1511 final JavaLanguageParser.BlockContext blockContext = ctx.block();
1512 final DetailAstImpl rightHandLambdaChild;
1513 if (blockContext != null) {
1514 rightHandLambdaChild = visit(blockContext);
1515 }
1516 else {
1517
1518
1519
1520
1521 rightHandLambdaChild = buildExpressionNode(ctx.expr());
1522 }
1523 lambda.addChild(rightHandLambdaChild);
1524 return lambda;
1525 }
1526
1527 @Override
1528 public DetailAstImpl visitThisExp(JavaLanguageParser.ThisExpContext ctx) {
1529 final DetailAstImpl bop = create(ctx.bop);
1530 bop.addChild(visit(ctx.expr()));
1531 bop.addChild(create(ctx.LITERAL_THIS()));
1532 return bop;
1533 }
1534
1535 @Override
1536 public DetailAstImpl visitPrimaryExp(JavaLanguageParser.PrimaryExpContext ctx) {
1537 return flattenedTree(ctx);
1538 }
1539
1540 @Override
1541 public DetailAstImpl visitPostfix(JavaLanguageParser.PostfixContext ctx) {
1542 final DetailAstImpl postfix;
1543 if (ctx.postfix.getType() == JavaLanguageLexer.INC) {
1544 postfix = create(TokenTypes.POST_INC, ctx.postfix);
1545 }
1546 else {
1547 postfix = create(TokenTypes.POST_DEC, ctx.postfix);
1548 }
1549 postfix.addChild(visit(ctx.expr()));
1550 return postfix;
1551 }
1552
1553 @Override
1554 public DetailAstImpl visitMethodRef(JavaLanguageParser.MethodRefContext ctx) {
1555 final DetailAstImpl doubleColon = create(TokenTypes.METHOD_REF,
1556 (Token) ctx.DOUBLE_COLON().getPayload());
1557 final List<ParseTree> children = ctx.children.stream()
1558 .filter(child -> !child.equals(ctx.DOUBLE_COLON()))
1559 .collect(Collectors.toUnmodifiableList());
1560 processChildren(doubleColon, children);
1561 return doubleColon;
1562 }
1563
1564 @Override
1565 public DetailAstImpl visitTernaryOp(JavaLanguageParser.TernaryOpContext ctx) {
1566 final DetailAstImpl root = create(ctx.QUESTION());
1567 processChildren(root, ctx.children.stream()
1568 .filter(child -> !child.equals(ctx.QUESTION()))
1569 .collect(Collectors.toUnmodifiableList()));
1570 return root;
1571 }
1572
1573 @Override
1574 public DetailAstImpl visitBinOp(JavaLanguageParser.BinOpContext ctx) {
1575 final DetailAstImpl bop = create(ctx.bop);
1576
1577
1578
1579 final List<JavaLanguageParser.BinOpContext> binOpList = new ArrayList<>();
1580 ParseTree firstExpression = ctx.expr(0);
1581 while (firstExpression instanceof JavaLanguageParser.BinOpContext) {
1582
1583 binOpList.add((JavaLanguageParser.BinOpContext) firstExpression);
1584 firstExpression = ((JavaLanguageParser.BinOpContext) firstExpression).expr(0);
1585 }
1586
1587 if (binOpList.isEmpty()) {
1588 final DetailAstImpl leftChild = visit(ctx.children.get(0));
1589 bop.addChild(leftChild);
1590 }
1591 else {
1592
1593
1594 final Queue<DetailAstImpl> descendantList = binOpList.parallelStream()
1595 .map(this::getInnerBopAst)
1596 .collect(Collectors.toCollection(ConcurrentLinkedQueue::new));
1597
1598 bop.addChild(descendantList.poll());
1599 DetailAstImpl pointer = bop.getFirstChild();
1600
1601 for (DetailAstImpl descendant : descendantList) {
1602 pointer.getFirstChild().addPreviousSibling(descendant);
1603 pointer = descendant;
1604 }
1605 }
1606
1607 bop.addChild(visit(ctx.children.get(2)));
1608 return bop;
1609 }
1610
1611
1612
1613
1614
1615
1616
1617 private DetailAstImpl getInnerBopAst(JavaLanguageParser.BinOpContext descendant) {
1618 final DetailAstImpl innerBop = create(descendant.bop);
1619 final JavaLanguageParser.ExprContext expr = descendant.expr(0);
1620 if (!(expr instanceof JavaLanguageParser.BinOpContext)) {
1621 innerBop.addChild(visit(expr));
1622 }
1623 innerBop.addChild(visit(descendant.expr(1)));
1624 return innerBop;
1625 }
1626
1627 @Override
1628 public DetailAstImpl visitMethodCall(JavaLanguageParser.MethodCallContext ctx) {
1629 final DetailAstImpl methodCall = create(TokenTypes.METHOD_CALL,
1630 (Token) ctx.LPAREN().getPayload());
1631
1632 final DetailAstImpl expressionList = Optional.ofNullable(visit(ctx.expressionList()))
1633 .orElseGet(() -> createImaginary(TokenTypes.ELIST));
1634
1635 final DetailAstImpl dot = create(ctx.DOT());
1636 dot.addChild(visit(ctx.expr()));
1637 dot.addChild(visit(ctx.id()));
1638 methodCall.addChild(dot);
1639 methodCall.addChild(expressionList);
1640 methodCall.addChild(create((Token) ctx.RPAREN().getPayload()));
1641 return methodCall;
1642 }
1643
1644 @Override
1645 public DetailAstImpl visitTypeCastParameters(
1646 JavaLanguageParser.TypeCastParametersContext ctx) {
1647 final DetailAstImpl typeType = visit(ctx.typeType(0));
1648 for (int i = 0; i < ctx.BAND().size(); i++) {
1649 addLastSibling(typeType, create(TokenTypes.TYPE_EXTENSION_AND,
1650 (Token) ctx.BAND(i).getPayload()));
1651 addLastSibling(typeType, visit(ctx.typeType(i + 1)));
1652 }
1653 return typeType;
1654 }
1655
1656 @Override
1657 public DetailAstImpl visitSingleLambdaParam(JavaLanguageParser.SingleLambdaParamContext ctx) {
1658 return flattenedTree(ctx);
1659 }
1660
1661 @Override
1662 public DetailAstImpl visitFormalLambdaParam(JavaLanguageParser.FormalLambdaParamContext ctx) {
1663 final DetailAstImpl lparen = create(ctx.LPAREN());
1664
1665
1666 final DetailAstImpl parameters = Optional.ofNullable(visit(ctx.formalParameterList()))
1667 .orElseGet(() -> createImaginary(TokenTypes.PARAMETERS));
1668 addLastSibling(lparen, parameters);
1669 addLastSibling(lparen, create(ctx.RPAREN()));
1670 return lparen;
1671 }
1672
1673 @Override
1674 public DetailAstImpl visitMultiLambdaParam(JavaLanguageParser.MultiLambdaParamContext ctx) {
1675 final DetailAstImpl lparen = create(ctx.LPAREN());
1676 addLastSibling(lparen, visit(ctx.multiLambdaParams()));
1677 addLastSibling(lparen, create(ctx.RPAREN()));
1678 return lparen;
1679 }
1680
1681 @Override
1682 public DetailAstImpl visitMultiLambdaParams(JavaLanguageParser.MultiLambdaParamsContext ctx) {
1683 final DetailAstImpl parameters = createImaginary(TokenTypes.PARAMETERS);
1684 parameters.addChild(createLambdaParameter(ctx.id(0)));
1685
1686 for (int i = 0; i < ctx.COMMA().size(); i++) {
1687 parameters.addChild(create(ctx.COMMA(i)));
1688 parameters.addChild(createLambdaParameter(ctx.id(i + 1)));
1689 }
1690 return parameters;
1691 }
1692
1693
1694
1695
1696
1697
1698
1699
1700 private DetailAstImpl createLambdaParameter(JavaLanguageParser.IdContext ctx) {
1701 final DetailAstImpl ident = visitId(ctx);
1702 final DetailAstImpl parameter = createImaginary(TokenTypes.PARAMETER_DEF);
1703 final DetailAstImpl modifiers = createImaginary(TokenTypes.MODIFIERS);
1704 final DetailAstImpl type = createImaginary(TokenTypes.TYPE);
1705 parameter.addChild(modifiers);
1706 parameter.addChild(type);
1707 parameter.addChild(ident);
1708 return parameter;
1709 }
1710
1711 @Override
1712 public DetailAstImpl visitParenPrimary(JavaLanguageParser.ParenPrimaryContext ctx) {
1713 return flattenedTree(ctx);
1714 }
1715
1716 @Override
1717 public DetailAstImpl visitTokenPrimary(JavaLanguageParser.TokenPrimaryContext ctx) {
1718 return flattenedTree(ctx);
1719 }
1720
1721 @Override
1722 public DetailAstImpl visitClassRefPrimary(JavaLanguageParser.ClassRefPrimaryContext ctx) {
1723 final DetailAstImpl dot = create(ctx.DOT());
1724 final DetailAstImpl primaryTypeNoArray = visit(ctx.type);
1725 dot.addChild(primaryTypeNoArray);
1726 if (TokenUtil.isOfType(primaryTypeNoArray, TokenTypes.DOT)) {
1727
1728 ctx.arrayDeclarator()
1729 .forEach(child -> primaryTypeNoArray.addChild(visit(child)));
1730 }
1731 else {
1732 ctx.arrayDeclarator()
1733 .forEach(child -> addLastSibling(primaryTypeNoArray, visit(child)));
1734 }
1735 dot.addChild(create(ctx.LITERAL_CLASS()));
1736 return dot;
1737 }
1738
1739 @Override
1740 public DetailAstImpl visitPrimitivePrimary(JavaLanguageParser.PrimitivePrimaryContext ctx) {
1741 final DetailAstImpl dot = create(ctx.DOT());
1742 final DetailAstImpl primaryTypeNoArray = visit(ctx.type);
1743 dot.addChild(primaryTypeNoArray);
1744 ctx.arrayDeclarator().forEach(child -> dot.addChild(visit(child)));
1745 dot.addChild(create(ctx.LITERAL_CLASS()));
1746 return dot;
1747 }
1748
1749 @Override
1750 public DetailAstImpl visitCreator(JavaLanguageParser.CreatorContext ctx) {
1751 return flattenedTree(ctx);
1752 }
1753
1754 @Override
1755 public DetailAstImpl visitCreatedNameObject(JavaLanguageParser.CreatedNameObjectContext ctx) {
1756 final DetailAstPair currentAST = new DetailAstPair();
1757 DetailAstPair.addAstChild(currentAST, visit(ctx.annotations()));
1758 DetailAstPair.addAstChild(currentAST, visit(ctx.id()));
1759 DetailAstPair.addAstChild(currentAST, visit(ctx.typeArgumentsOrDiamond()));
1760
1761
1762 for (ParserRuleContext extendedContext : ctx.extended) {
1763 final DetailAstImpl dot = create(extendedContext.start);
1764 DetailAstPair.makeAstRoot(currentAST, dot);
1765 final List<ParseTree> childList = extendedContext
1766 .children.subList(1, extendedContext.children.size());
1767 processChildren(dot, childList);
1768 }
1769
1770 return currentAST.root;
1771 }
1772
1773 @Override
1774 public DetailAstImpl visitCreatedNamePrimitive(
1775 JavaLanguageParser.CreatedNamePrimitiveContext ctx) {
1776 return flattenedTree(ctx);
1777 }
1778
1779 @Override
1780 public DetailAstImpl visitInnerCreator(JavaLanguageParser.InnerCreatorContext ctx) {
1781 return flattenedTree(ctx);
1782 }
1783
1784 @Override
1785 public DetailAstImpl visitArrayCreatorRest(JavaLanguageParser.ArrayCreatorRestContext ctx) {
1786 final DetailAstImpl arrayDeclarator = create(TokenTypes.ARRAY_DECLARATOR,
1787 (Token) ctx.LBRACK().getPayload());
1788 final JavaLanguageParser.ExpressionContext expression = ctx.expression();
1789 final TerminalNode rbrack = ctx.RBRACK();
1790
1791 for (int i = 1; i < ctx.children.size(); i++) {
1792 if (ctx.children.get(i) == rbrack) {
1793 arrayDeclarator.addChild(create(rbrack));
1794 }
1795 else if (ctx.children.get(i) == expression) {
1796
1797 arrayDeclarator.addChild(visit(expression));
1798 }
1799 else {
1800 addLastSibling(arrayDeclarator, visit(ctx.children.get(i)));
1801 }
1802 }
1803 return arrayDeclarator;
1804 }
1805
1806 @Override
1807 public DetailAstImpl visitBracketsWithExp(JavaLanguageParser.BracketsWithExpContext ctx) {
1808 final DetailAstImpl dummyRoot = new DetailAstImpl();
1809 dummyRoot.addChild(visit(ctx.annotations()));
1810 final DetailAstImpl arrayDeclarator =
1811 create(TokenTypes.ARRAY_DECLARATOR, (Token) ctx.LBRACK().getPayload());
1812 arrayDeclarator.addChild(visit(ctx.expression()));
1813 arrayDeclarator.addChild(create(ctx.stop));
1814 dummyRoot.addChild(arrayDeclarator);
1815 return dummyRoot.getFirstChild();
1816 }
1817
1818 @Override
1819 public DetailAstImpl visitClassCreatorRest(JavaLanguageParser.ClassCreatorRestContext ctx) {
1820 return flattenedTree(ctx);
1821 }
1822
1823 @Override
1824 public DetailAstImpl visitDiamond(JavaLanguageParser.DiamondContext ctx) {
1825 final DetailAstImpl typeArguments =
1826 createImaginary(TokenTypes.TYPE_ARGUMENTS);
1827 typeArguments.addChild(create(TokenTypes.GENERIC_START,
1828 (Token) ctx.LT().getPayload()));
1829 typeArguments.addChild(create(TokenTypes.GENERIC_END,
1830 (Token) ctx.GT().getPayload()));
1831 return typeArguments;
1832 }
1833
1834 @Override
1835 public DetailAstImpl visitTypeArgs(JavaLanguageParser.TypeArgsContext ctx) {
1836 return flattenedTree(ctx);
1837 }
1838
1839 @Override
1840 public DetailAstImpl visitNonWildcardDiamond(
1841 JavaLanguageParser.NonWildcardDiamondContext ctx) {
1842 final DetailAstImpl typeArguments =
1843 createImaginary(TokenTypes.TYPE_ARGUMENTS);
1844 typeArguments.addChild(create(TokenTypes.GENERIC_START,
1845 (Token) ctx.LT().getPayload()));
1846 typeArguments.addChild(create(TokenTypes.GENERIC_END,
1847 (Token) ctx.GT().getPayload()));
1848 return typeArguments;
1849 }
1850
1851 @Override
1852 public DetailAstImpl visitNonWildcardTypeArguments(
1853 JavaLanguageParser.NonWildcardTypeArgumentsContext ctx) {
1854 final DetailAstImpl typeArguments = createImaginary(TokenTypes.TYPE_ARGUMENTS);
1855 typeArguments.addChild(create(TokenTypes.GENERIC_START, (Token) ctx.LT().getPayload()));
1856 typeArguments.addChild(visit(ctx.typeArgumentsTypeList()));
1857 typeArguments.addChild(create(TokenTypes.GENERIC_END, (Token) ctx.GT().getPayload()));
1858 return typeArguments;
1859 }
1860
1861 @Override
1862 public DetailAstImpl visitTypeArgumentsTypeList(
1863 JavaLanguageParser.TypeArgumentsTypeListContext ctx) {
1864 final DetailAstImpl firstIdent = visit(ctx.typeType(0));
1865 final DetailAstImpl firstTypeArgument = createImaginary(TokenTypes.TYPE_ARGUMENT);
1866 firstTypeArgument.addChild(firstIdent);
1867
1868 for (int i = 0; i < ctx.COMMA().size(); i++) {
1869 addLastSibling(firstTypeArgument, create(ctx.COMMA(i)));
1870 final DetailAstImpl ident = visit(ctx.typeType(i + 1));
1871 final DetailAstImpl typeArgument = createImaginary(TokenTypes.TYPE_ARGUMENT);
1872 typeArgument.addChild(ident);
1873 addLastSibling(firstTypeArgument, typeArgument);
1874 }
1875 return firstTypeArgument;
1876 }
1877
1878 @Override
1879 public DetailAstImpl visitTypeList(JavaLanguageParser.TypeListContext ctx) {
1880 return flattenedTree(ctx);
1881 }
1882
1883 @Override
1884 public DetailAstImpl visitTypeType(JavaLanguageParser.TypeTypeContext ctx) {
1885 final DetailAstImpl type = createImaginary(TokenTypes.TYPE);
1886 processChildren(type, ctx.children);
1887
1888 final DetailAstImpl returnTree;
1889 if (ctx.createImaginaryNode) {
1890 returnTree = type;
1891 }
1892 else {
1893 returnTree = type.getFirstChild();
1894 }
1895 return returnTree;
1896 }
1897
1898 @Override
1899 public DetailAstImpl visitArrayDeclarator(JavaLanguageParser.ArrayDeclaratorContext ctx) {
1900 final DetailAstImpl arrayDeclarator = create(TokenTypes.ARRAY_DECLARATOR,
1901 (Token) ctx.LBRACK().getPayload());
1902 arrayDeclarator.addChild(create(ctx.RBRACK()));
1903
1904 final DetailAstImpl returnTree;
1905 final DetailAstImpl annotations = visit(ctx.anno);
1906 if (annotations == null) {
1907 returnTree = arrayDeclarator;
1908 }
1909 else {
1910 returnTree = annotations;
1911 addLastSibling(returnTree, arrayDeclarator);
1912 }
1913 return returnTree;
1914 }
1915
1916 @Override
1917 public DetailAstImpl visitPrimitiveType(JavaLanguageParser.PrimitiveTypeContext ctx) {
1918 return create(ctx.start);
1919 }
1920
1921 @Override
1922 public DetailAstImpl visitTypeArguments(JavaLanguageParser.TypeArgumentsContext ctx) {
1923 final DetailAstImpl typeArguments = createImaginary(TokenTypes.TYPE_ARGUMENTS);
1924 typeArguments.addChild(create(TokenTypes.GENERIC_START, (Token) ctx.LT().getPayload()));
1925
1926 processChildren(typeArguments, ctx.children.subList(1, ctx.children.size() - 1));
1927 typeArguments.addChild(create(TokenTypes.GENERIC_END, (Token) ctx.GT().getPayload()));
1928 return typeArguments;
1929 }
1930
1931 @Override
1932 public DetailAstImpl visitSuperSuffixDot(JavaLanguageParser.SuperSuffixDotContext ctx) {
1933 final DetailAstImpl root;
1934 if (ctx.LPAREN() == null) {
1935 root = create(ctx.DOT());
1936 root.addChild(visit(ctx.id()));
1937 }
1938 else {
1939 root = create(TokenTypes.METHOD_CALL, (Token) ctx.LPAREN().getPayload());
1940
1941 final DetailAstImpl dot = create(ctx.DOT());
1942 dot.addChild(visit(ctx.id()));
1943 root.addChild(dot);
1944
1945 final DetailAstImpl expressionList = Optional.ofNullable(visit(ctx.expressionList()))
1946 .orElseGet(() -> createImaginary(TokenTypes.ELIST));
1947 root.addChild(expressionList);
1948
1949 root.addChild(create(ctx.RPAREN()));
1950 }
1951
1952 return root;
1953 }
1954
1955 @Override
1956 public DetailAstImpl visitArguments(JavaLanguageParser.ArgumentsContext ctx) {
1957 final DetailAstImpl lparen = create(ctx.LPAREN());
1958
1959
1960 final DetailAstImpl expressionList = Optional.ofNullable(visit(ctx.expressionList()))
1961 .orElseGet(() -> createImaginary(TokenTypes.ELIST));
1962 addLastSibling(lparen, expressionList);
1963 addLastSibling(lparen, create(ctx.RPAREN()));
1964 return lparen;
1965 }
1966
1967 @Override
1968 public DetailAstImpl visitPattern(JavaLanguageParser.PatternContext ctx) {
1969 final JavaLanguageParser.InnerPatternContext innerPattern = ctx.innerPattern();
1970 final ParserRuleContext primaryPattern = innerPattern.primaryPattern();
1971 final ParserRuleContext recordPattern = innerPattern.recordPattern();
1972 final boolean isSimpleTypePattern = primaryPattern != null
1973 && primaryPattern.getChild(0) instanceof JavaLanguageParser.TypePatternContext;
1974
1975 final DetailAstImpl pattern;
1976
1977 if (recordPattern != null) {
1978 pattern = visit(recordPattern);
1979 }
1980 else if (isSimpleTypePattern) {
1981
1982 pattern = visit(primaryPattern);
1983 }
1984 else {
1985 pattern = createImaginary(TokenTypes.PATTERN_DEF);
1986 pattern.addChild(visit(ctx.getChild(0)));
1987 }
1988 return pattern;
1989 }
1990
1991 @Override
1992 public DetailAstImpl visitInnerPattern(JavaLanguageParser.InnerPatternContext ctx) {
1993 return flattenedTree(ctx);
1994 }
1995
1996 @Override
1997 public DetailAstImpl visitGuardedPattern(JavaLanguageParser.GuardedPatternContext ctx) {
1998 final DetailAstImpl guardAstNode = flattenedTree(ctx.guard());
1999 guardAstNode.addChild(visit(ctx.primaryPattern()));
2000 guardAstNode.addChild(visit(ctx.expression()));
2001 return guardAstNode;
2002 }
2003
2004 @Override
2005 public DetailAstImpl visitParenPattern(JavaLanguageParser.ParenPatternContext ctx) {
2006 final DetailAstImpl lparen = create(ctx.LPAREN());
2007 final ParseTree innerPattern = ctx.getChild(1);
2008 lparen.addChild(visit(innerPattern));
2009 lparen.addChild(create(ctx.RPAREN()));
2010 return lparen;
2011 }
2012
2013 @Override
2014 public DetailAstImpl visitRecordPatternDef(JavaLanguageParser.RecordPatternDefContext ctx) {
2015 return flattenedTree(ctx);
2016 }
2017
2018 @Override
2019 public DetailAstImpl visitTypePatternDef(
2020 JavaLanguageParser.TypePatternDefContext ctx) {
2021 final DetailAstImpl type = visit(ctx.type);
2022 final DetailAstImpl patternVariableDef = createImaginary(TokenTypes.PATTERN_VARIABLE_DEF);
2023 patternVariableDef.addChild(createModifiers(ctx.mods));
2024 patternVariableDef.addChild(type);
2025 patternVariableDef.addChild(visit(ctx.id()));
2026 return patternVariableDef;
2027 }
2028
2029 @Override
2030 public DetailAstImpl visitUnnamedPatternDef(JavaLanguageParser.UnnamedPatternDefContext ctx) {
2031 return create(TokenTypes.UNNAMED_PATTERN_DEF, ctx.start);
2032 }
2033
2034 @Override
2035 public DetailAstImpl visitRecordPattern(JavaLanguageParser.RecordPatternContext ctx) {
2036 final DetailAstImpl recordPattern = createImaginary(TokenTypes.RECORD_PATTERN_DEF);
2037 recordPattern.addChild(createModifiers(ctx.mods));
2038 processChildren(recordPattern,
2039 ctx.children.subList(ctx.mods.size(), ctx.children.size()));
2040 return recordPattern;
2041 }
2042
2043 @Override
2044 public DetailAstImpl visitRecordComponentPatternList(
2045 JavaLanguageParser.RecordComponentPatternListContext ctx) {
2046 final DetailAstImpl recordComponents =
2047 createImaginary(TokenTypes.RECORD_PATTERN_COMPONENTS);
2048 processChildren(recordComponents, ctx.children);
2049 return recordComponents;
2050 }
2051
2052 @Override
2053 public DetailAstImpl visitPermittedSubclassesAndInterfaces(
2054 JavaLanguageParser.PermittedSubclassesAndInterfacesContext ctx) {
2055 final DetailAstImpl literalPermits =
2056 create(TokenTypes.PERMITS_CLAUSE, (Token) ctx.LITERAL_PERMITS().getPayload());
2057
2058 processChildren(literalPermits, ctx.children.subList(1, ctx.children.size()));
2059 return literalPermits;
2060 }
2061
2062 @Override
2063 public DetailAstImpl visitId(JavaLanguageParser.IdContext ctx) {
2064 return create(TokenTypes.IDENT, ctx.start);
2065 }
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075 private DetailAstImpl flattenedTree(ParserRuleContext ctx) {
2076 final DetailAstImpl dummyNode = new DetailAstImpl();
2077 processChildren(dummyNode, ctx.children);
2078 return dummyNode.getFirstChild();
2079 }
2080
2081
2082
2083
2084
2085
2086
2087
2088 private void processChildren(DetailAstImpl parent, List<? extends ParseTree> children) {
2089 children.forEach(child -> {
2090 if (child instanceof TerminalNode) {
2091
2092 parent.addChild(create((TerminalNode) child));
2093 }
2094 else {
2095
2096 parent.addChild(visit(child));
2097 }
2098 });
2099 }
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109 private static DetailAstImpl createImaginary(int tokenType) {
2110 final DetailAstImpl detailAst = new DetailAstImpl();
2111 detailAst.setType(tokenType);
2112 detailAst.setText(TokenUtil.getTokenName(tokenType));
2113 return detailAst;
2114 }
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124 private DetailAstImpl create(int tokenType, Token startToken) {
2125 final DetailAstImpl ast = create(startToken);
2126 ast.setType(tokenType);
2127 return ast;
2128 }
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138 private DetailAstImpl create(Token token) {
2139 final int tokenIndex = token.getTokenIndex();
2140 final List<Token> tokensToLeft =
2141 tokens.getHiddenTokensToLeft(tokenIndex, JavaLanguageLexer.COMMENTS);
2142 final List<Token> tokensToRight =
2143 tokens.getHiddenTokensToRight(tokenIndex, JavaLanguageLexer.COMMENTS);
2144
2145 final DetailAstImpl detailAst = new DetailAstImpl();
2146 detailAst.initialize(token);
2147 if (tokensToLeft != null) {
2148 detailAst.setHiddenBefore(tokensToLeft);
2149 }
2150 if (tokensToRight != null) {
2151 detailAst.setHiddenAfter(tokensToRight);
2152 }
2153 return detailAst;
2154 }
2155
2156
2157
2158
2159
2160
2161
2162
2163 private DetailAstImpl create(TerminalNode node) {
2164 return create((Token) node.getPayload());
2165 }
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175 private DetailAstImpl createTypeDeclaration(ParserRuleContext ctx, int type,
2176 List<? extends ParseTree> modifierList) {
2177 final DetailAstImpl typeDeclaration = createImaginary(type);
2178 typeDeclaration.addChild(createModifiers(modifierList));
2179 processChildren(typeDeclaration, ctx.children);
2180 return typeDeclaration;
2181 }
2182
2183
2184
2185
2186
2187
2188
2189 private DetailAstImpl createModifiers(List<? extends ParseTree> modifierList) {
2190 final DetailAstImpl mods = createImaginary(TokenTypes.MODIFIERS);
2191 processChildren(mods, modifierList);
2192 return mods;
2193 }
2194
2195
2196
2197
2198
2199
2200
2201 private static void addLastSibling(DetailAstImpl self, DetailAstImpl sibling) {
2202 DetailAstImpl nextSibling = self;
2203 if (nextSibling != null) {
2204 while (nextSibling.getNextSibling() != null) {
2205 nextSibling = nextSibling.getNextSibling();
2206 }
2207 nextSibling.setNextSibling(sibling);
2208 }
2209 }
2210
2211 @Override
2212 public DetailAstImpl visit(ParseTree tree) {
2213 DetailAstImpl ast = null;
2214 if (tree != null) {
2215 ast = tree.accept(this);
2216 }
2217 return ast;
2218 }
2219
2220
2221
2222
2223
2224
2225
2226
2227 private DetailAstImpl buildExpressionNode(ParseTree exprNode) {
2228 final DetailAstImpl expression = visit(exprNode);
2229
2230 final DetailAstImpl exprRoot;
2231 if (TokenUtil.isOfType(expression, EXPRESSIONS_WITH_NO_EXPR_ROOT)) {
2232 exprRoot = expression;
2233 }
2234 else {
2235
2236 exprRoot = createImaginary(TokenTypes.EXPR);
2237 exprRoot.addChild(expression);
2238 }
2239 return exprRoot;
2240 }
2241
2242
2243
2244
2245 private static final class DetailAstPair {
2246
2247
2248 private DetailAstImpl root;
2249
2250
2251 private DetailAstImpl child;
2252
2253
2254
2255
2256 private void advanceChildToEnd() {
2257 while (child.getNextSibling() != null) {
2258 child = child.getNextSibling();
2259 }
2260 }
2261
2262
2263
2264
2265
2266
2267 private DetailAstImpl getRoot() {
2268 return root;
2269 }
2270
2271
2272
2273
2274
2275
2276
2277
2278 private static void makeAstRoot(DetailAstPair pair, DetailAstImpl ast) {
2279 ast.addChild(pair.root);
2280 pair.child = pair.root;
2281 pair.advanceChildToEnd();
2282 pair.root = ast;
2283 }
2284
2285
2286
2287
2288
2289
2290
2291 private static void addAstChild(DetailAstPair pair, DetailAstImpl ast) {
2292 if (ast != null) {
2293 if (pair.root == null) {
2294 pair.root = ast;
2295 }
2296 else {
2297 pair.child.setNextSibling(ast);
2298 }
2299 pair.child = ast;
2300 }
2301 }
2302 }
2303 }