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