Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

1692
LINES

< > BotCompany Repo | #1020877 // PrettyPrintVisitor2 (adapted from JavaParser)

JavaX fragment (include)

1  
/*
2  
 * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
3  
 * Copyright (C) 2011, 2013-2016 The JavaParser Team.
4  
 *
5  
 * This file is part of JavaParser.
6  
 *
7  
 * JavaParser can be used either under the terms of
8  
 * a) the GNU Lesser General Public License as published by
9  
 *     the Free Software Foundation, either version 3 of the License, or
10  
 *     (at your option) any later version.
11  
 * b) the terms of the Apache License
12  
 *
13  
 * You should have received a copy of both licenses in LICENCE.LGPL and
14  
 * LICENCE.APACHE. Please refer to those files for details.
15  
 *
16  
 * JavaParser is distributed in the hope that it will be useful,
17  
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  
 * GNU Lesser General Public License for more details.
20  
 */
21  
22  
//import com.github.javaparser.printer.*;
23  
import com.github.javaparser.ast.*;
24  
import com.github.javaparser.ast.Modifier;
25  
import com.github.javaparser.ast.body.*;
26  
import com.github.javaparser.ast.comments.BlockComment;
27  
import com.github.javaparser.ast.comments.Comment;
28  
import com.github.javaparser.ast.comments.JavadocComment;
29  
import com.github.javaparser.ast.comments.LineComment;
30  
import com.github.javaparser.ast.expr.*;
31  
import com.github.javaparser.ast.modules.*;
32  
import com.github.javaparser.ast.nodeTypes.*;
33  
import com.github.javaparser.ast.stmt.*;
34  
import com.github.javaparser.ast.type.*;
35  
import com.github.javaparser.ast.type.Type;
36  
import com.github.javaparser.ast.visitor.Visitable;
37  
import com.github.javaparser.ast.visitor.VoidVisitor;
38  
39  
import java.util.*;
40  
import java.util.concurrent.atomic.AtomicBoolean;
41  
import java.util.stream.Collectors;
42  
43  
import static com.github.javaparser.ast.Node.Parsedness.UNPARSABLE;
44  
import static com.github.javaparser.utils.PositionUtils.sortByBeginPosition;
45  
import static com.github.javaparser.utils.Utils.*;
46  
import static java.util.Comparator.comparingInt;
47  
48  
/**
49  
 * Outputs the AST as formatted Java source code.
50  
 *
51  
 * @author Julio Vilmar Gesser
52  
 */
53  
sclass PrettyPrintVisitor2 implements VoidVisitor<Void> {
54  
    protected final PrettyPrinterConfiguration configuration;
55  
    protected final SourcePrinter printer;
56  
57  
    *(PrettyPrinterConfiguration prettyPrinterConfiguration) {
58  
        configuration = prettyPrinterConfiguration;
59  
        printer = new SourcePrinter(configuration);
60  
    }
61  
62  
    public String getSource() {
63  
        return printer.getSource();
64  
    }
65  
66  
    private void printModifiers(final NodeList<Modifier> modifiers) {
67  
        if (modifiers.size() > 0) {
68  
            printer.print(modifiers.stream().map(Modifier::getKeyword).map(Modifier.Keyword::asString).collect(Collectors.joining(" ")) + " ");
69  
        }
70  
    }
71  
72  
    private void printMembers(final NodeList<BodyDeclaration<?>> members, final Void arg) {
73  
        bool first = true;
74  
        for (final BodyDeclaration<?> member : members) {
75  
            if (first) first = false; else printer.println();
76  
            member.accept(this, arg);
77  
            printer.println();
78  
        }
79  
    }
80  
81  
    private void printMemberAnnotations(final NodeList<AnnotationExpr> annotations, final Void arg) {
82  
        if (annotations.isEmpty()) {
83  
            return;
84  
        }
85  
        for (final AnnotationExpr a : annotations) {
86  
            a.accept(this, arg);
87  
            printer.println();
88  
        }
89  
    }
90  
91  
    private void printAnnotations(final NodeList<AnnotationExpr> annotations, boolean prefixWithASpace,
92  
                                  final Void arg) {
93  
        if (annotations.isEmpty()) {
94  
            return;
95  
        }
96  
        if (prefixWithASpace) {
97  
            printer.print(" ");
98  
        }
99  
        for (AnnotationExpr annotation : annotations) {
100  
            annotation.accept(this, arg);
101  
            printer.print(" ");
102  
        }
103  
    }
104  
105  
    private void printTypeArgs(final NodeWithTypeArguments<?> nodeWithTypeArguments, final Void arg) {
106  
        NodeList<Type> typeArguments = nodeWithTypeArguments.getTypeArguments().orElse(null);
107  
        if (!isNullOrEmpty(typeArguments)) {
108  
            printer.print("<");
109  
            for (final Iterator<Type> i = typeArguments.iterator(); i.hasNext(); ) {
110  
                final Type t = i.next();
111  
                t.accept(this, arg);
112  
                if (i.hasNext()) {
113  
                    printer.print(", ");
114  
                }
115  
            }
116  
            printer.print(">");
117  
        }
118  
    }
119  
120  
    private void printTypeParameters(final NodeList<TypeParameter> args, final Void arg) {
121  
        if (!isNullOrEmpty(args)) {
122  
            printer.print("<");
123  
            for (final Iterator<TypeParameter> i = args.iterator(); i.hasNext(); ) {
124  
                final TypeParameter t = i.next();
125  
                t.accept(this, arg);
126  
                if (i.hasNext()) {
127  
                    printer.print(", ");
128  
                }
129  
            }
130  
            printer.print(">");
131  
        }
132  
    }
133  
134  
    private void printArguments(final NodeList<Expression> args, final Void arg) {
135  
        printer.print("(");
136  
        if (!isNullOrEmpty(args)) {
137  
            boolean columnAlignParameters = (args.size() > 1) && configuration.isColumnAlignParameters();
138  
            if (columnAlignParameters) {
139  
                printer.indentWithAlignTo(printer.getCursor().column);
140  
            }
141  
            for (final Iterator<Expression> i = args.iterator(); i.hasNext(); ) {
142  
                final Expression e = i.next();
143  
                e.accept(this, arg);
144  
                if (i.hasNext()) {
145  
                    printer.print(",");
146  
                    if (columnAlignParameters) {
147  
                        printer.println();
148  
                    } else {
149  
                        printer.print(" ");
150  
                    }
151  
                }
152  
            }
153  
            if (columnAlignParameters) {
154  
                printer.unindent();
155  
            }
156  
        }
157  
        printer.print(")");
158  
    }
159  
160  
    private void printPrePostFixOptionalList(final NodeList<? extends Visitable> args, final Void arg, String prefix, String separator, String postfix) {
161  
        if (!args.isEmpty()) {
162  
            printer.print(prefix);
163  
            for (final Iterator<? extends Visitable> i = args.iterator(); i.hasNext(); ) {
164  
                final Visitable v = i.next();
165  
                v.accept(this, arg);
166  
                if (i.hasNext()) {
167  
                    printer.print(separator);
168  
                }
169  
            }
170  
            printer.print(postfix);
171  
        }
172  
    }
173  
174  
    private void printPrePostFixRequiredList(final NodeList<? extends Visitable> args, final Void arg, String prefix, String separator, String postfix) {
175  
        printer.print(prefix);
176  
        if (!args.isEmpty()) {
177  
            for (final Iterator<? extends Visitable> i = args.iterator(); i.hasNext(); ) {
178  
                final Visitable v = i.next();
179  
                v.accept(this, arg);
180  
                if (i.hasNext()) {
181  
                    printer.print(separator);
182  
                }
183  
            }
184  
        }
185  
        printer.print(postfix);
186  
    }
187  
188  
    private void printComment(final Optional<Comment> comment, final Void arg) {
189  
        comment.ifPresent(c -> c.accept(this, arg));
190  
    }
191  
192  
    @Override
193  
    public void visit(final CompilationUnit n, final Void arg) {
194  
        printComment(n.getComment(), arg);
195  
        if (n.getParsed() == UNPARSABLE) {
196  
            printer.println("???");
197  
            return;
198  
        }
199  
200  
        if (n.getPackageDeclaration().isPresent()) {
201  
            n.getPackageDeclaration().get().accept(this, arg);
202  
        }
203  
204  
        n.getImports().accept(this, arg);
205  
        if (!n.getImports().isEmpty()) {
206  
            printer.println();
207  
        }
208  
209  
        for (final Iterator<TypeDeclaration<?>> i = n.getTypes().iterator(); i.hasNext(); ) {
210  
            i.next().accept(this, arg);
211  
            printer.println();
212  
            if (i.hasNext()) {
213  
                printer.println();
214  
            }
215  
        }
216  
217  
        n.getModule().ifPresent(m -> m.accept(this, arg));
218  
219  
        printOrphanCommentsEnding(n);
220  
    }
221  
222  
    @Override
223  
    public void visit(final PackageDeclaration n, final Void arg) {
224  
        printComment(n.getComment(), arg);
225  
        printMemberAnnotations(n.getAnnotations(), arg);
226  
        printer.print("package ");
227  
        n.getName().accept(this, arg);
228  
        printer.println(";");
229  
        printer.println();
230  
231  
        printOrphanCommentsEnding(n);
232  
    }
233  
234  
    @Override
235  
    public void visit(final NameExpr n, final Void arg) {
236  
        printComment(n.getComment(), arg);
237  
        n.getName().accept(this, arg);
238  
239  
        printOrphanCommentsEnding(n);
240  
    }
241  
242  
    @Override
243  
    public void visit(final Name n, final Void arg) {
244  
        printComment(n.getComment(), arg);
245  
        if (n.getQualifier().isPresent()) {
246  
            n.getQualifier().get().accept(this, arg);
247  
            printer.print(".");
248  
        }
249  
        printer.print(n.getIdentifier());
250  
251  
        printOrphanCommentsEnding(n);
252  
    }
253  
254  
    @Override
255  
    public void visit(SimpleName n, Void arg) {
256  
        printer.print(n.getIdentifier());
257  
    }
258  
259  
    @Override
260  
    public void visit(final ClassOrInterfaceDeclaration n, final Void arg) {
261  
        printComment(n.getComment(), arg);
262  
        printMemberAnnotations(n.getAnnotations(), arg);
263  
        printModifiers(n.getModifiers());
264  
265  
        if (n.isInterface()) {
266  
            printer.print("interface ");
267  
        } else {
268  
            printer.print("class ");
269  
        }
270  
271  
        n.getName().accept(this, arg);
272  
273  
        printTypeParameters(n.getTypeParameters(), arg);
274  
275  
        if (!n.getExtendedTypes().isEmpty()) {
276  
            printer.print(" extends ");
277  
            for (final Iterator<ClassOrInterfaceType> i = n.getExtendedTypes().iterator(); i.hasNext(); ) {
278  
                final ClassOrInterfaceType c = i.next();
279  
                c.accept(this, arg);
280  
                if (i.hasNext()) {
281  
                    printer.print(", ");
282  
                }
283  
            }
284  
        }
285  
286  
        if (!n.getImplementedTypes().isEmpty()) {
287  
            printer.print(" implements ");
288  
            for (final Iterator<ClassOrInterfaceType> i = n.getImplementedTypes().iterator(); i.hasNext(); ) {
289  
                final ClassOrInterfaceType c = i.next();
290  
                c.accept(this, arg);
291  
                if (i.hasNext()) {
292  
                    printer.print(", ");
293  
                }
294  
            }
295  
        }
296  
297  
        printer.println(" {");
298  
        printer.indent();
299  
        if (!isNullOrEmpty(n.getMembers())) {
300  
            printMembers(n.getMembers(), arg);
301  
        }
302  
303  
        printOrphanCommentsEnding(n);
304  
305  
        printer.unindent();
306  
        printer.print("}");
307  
    }
308  
309  
    @Override
310  
    public void visit(final JavadocComment n, final Void arg) {
311  
        if (configuration.isPrintComments() && configuration.isPrintJavadoc()) {
312  
            printer.println("/**");
313  
            final String commentContent = normalizeEolInTextBlock(n.getContent(), configuration.getEndOfLineCharacter());
314  
            String[] lines = commentContent.split("\\R");
315  
            boolean skippingLeadingEmptyLines = true;
316  
            boolean prependEmptyLine = false;
317  
            boolean prependSpace = Arrays.stream(lines).anyMatch(line -> !line.isEmpty() && !line.startsWith(" "));
318  
            for (String line : lines) {
319  
                final String trimmedLine = line.trim();
320  
                if (trimmedLine.startsWith("*")) {
321  
                    line = trimmedLine.substring(1);
322  
                }
323  
                line = trimTrailingSpaces(line);
324  
                if (line.isEmpty()) {
325  
                    if (!skippingLeadingEmptyLines) {
326  
                        prependEmptyLine = true;
327  
                    }
328  
                } else {
329  
                    skippingLeadingEmptyLines = false;
330  
                    if (prependEmptyLine) {
331  
                        printer.println(" *");
332  
                        prependEmptyLine = false;
333  
                    }
334  
                    printer.print(" *");
335  
                    if (prependSpace) {
336  
                        printer.print(" ");
337  
                    }
338  
                    printer.println(line);
339  
                }
340  
            }
341  
            printer.println(" */");
342  
        }
343  
    }
344  
345  
    @Override
346  
    public void visit(final ClassOrInterfaceType n, final Void arg) {
347  
        printComment(n.getComment(), arg);
348  
        if (n.getScope().isPresent()) {
349  
            n.getScope().get().accept(this, arg);
350  
            printer.print(".");
351  
        }
352  
        printAnnotations(n.getAnnotations(), false, arg);
353  
354  
        n.getName().accept(this, arg);
355  
356  
        if (n.isUsingDiamondOperator()) {
357  
            printer.print("<>");
358  
        } else {
359  
            printTypeArgs(n, arg);
360  
        }
361  
    }
362  
363  
    @Override
364  
    public void visit(final TypeParameter n, final Void arg) {
365  
        printComment(n.getComment(), arg);
366  
        printAnnotations(n.getAnnotations(), false, arg);
367  
        n.getName().accept(this, arg);
368  
        if (!isNullOrEmpty(n.getTypeBound())) {
369  
            printer.print(" extends ");
370  
            for (final Iterator<ClassOrInterfaceType> i = n.getTypeBound().iterator(); i.hasNext(); ) {
371  
                final ClassOrInterfaceType c = i.next();
372  
                c.accept(this, arg);
373  
                if (i.hasNext()) {
374  
                    printer.print(" & ");
375  
                }
376  
            }
377  
        }
378  
    }
379  
380  
    @Override
381  
    public void visit(final PrimitiveType n, final Void arg) {
382  
        printComment(n.getComment(), arg);
383  
        printAnnotations(n.getAnnotations(), true, arg);
384  
        printer.print(n.getType().asString());
385  
    }
386  
387  
    @Override
388  
    public void visit(final ArrayType n, final Void arg) {
389  
        final List<ArrayType> arrayTypeBuffer = new LinkedList<>();
390  
        Type type = n;
391  
        while (type instanceof ArrayType) {
392  
            final ArrayType arrayType = (ArrayType) type;
393  
            arrayTypeBuffer.add(arrayType);
394  
            type = arrayType.getComponentType();
395  
        }
396  
397  
        type.accept(this, arg);
398  
        for (ArrayType arrayType : arrayTypeBuffer) {
399  
            printAnnotations(arrayType.getAnnotations(), true, arg);
400  
            printer.print("[]");
401  
        }
402  
    }
403  
404  
    @Override
405  
    public void visit(final ArrayCreationLevel n, final Void arg) {
406  
        printAnnotations(n.getAnnotations(), true, arg);
407  
        printer.print("[");
408  
        if (n.getDimension().isPresent()) {
409  
            n.getDimension().get().accept(this, arg);
410  
        }
411  
        printer.print("]");
412  
    }
413  
414  
    @Override
415  
    public void visit(final IntersectionType n, final Void arg) {
416  
        printComment(n.getComment(), arg);
417  
        printAnnotations(n.getAnnotations(), false, arg);
418  
        boolean isFirst = true;
419  
        for (ReferenceType element : n.getElements()) {
420  
            if (isFirst) {
421  
                isFirst = false;
422  
            } else {
423  
                printer.print(" & ");
424  
            }
425  
            element.accept(this, arg);
426  
        }
427  
    }
428  
429  
    @Override
430  
    public void visit(final UnionType n, final Void arg) {
431  
        printComment(n.getComment(), arg);
432  
        printAnnotations(n.getAnnotations(), true, arg);
433  
        boolean isFirst = true;
434  
        for (ReferenceType element : n.getElements()) {
435  
            if (isFirst) {
436  
                isFirst = false;
437  
            } else {
438  
                printer.print(" | ");
439  
            }
440  
            element.accept(this, arg);
441  
        }
442  
    }
443  
444  
    @Override
445  
    public void visit(final WildcardType n, final Void arg) {
446  
        printComment(n.getComment(), arg);
447  
        printAnnotations(n.getAnnotations(), false, arg);
448  
        printer.print("?");
449  
        if (n.getExtendedType().isPresent()) {
450  
            printer.print(" extends ");
451  
            n.getExtendedType().get().accept(this, arg);
452  
        }
453  
        if (n.getSuperType().isPresent()) {
454  
            printer.print(" super ");
455  
            n.getSuperType().get().accept(this, arg);
456  
        }
457  
    }
458  
459  
    @Override
460  
    public void visit(final UnknownType n, final Void arg) {
461  
        // Nothing to print
462  
    }
463  
464  
    @Override
465  
    public void visit(final FieldDeclaration n, final Void arg) {
466  
        printOrphanCommentsBeforeThisChildNode(n);
467  
468  
        printComment(n.getComment(), arg);
469  
        printMemberAnnotations(n.getAnnotations(), arg);
470  
        printModifiers(n.getModifiers());
471  
        if (!n.getVariables().isEmpty()) {
472  
            Optional<Type> maximumCommonType = n.getMaximumCommonType();
473  
            maximumCommonType.ifPresent(t -> t.accept(this, arg));
474  
            if (!maximumCommonType.isPresent()) {
475  
                printer.print("???");
476  
            }
477  
        }
478  
479  
        printer.print(" ");
480  
        for (final Iterator<VariableDeclarator> i = n.getVariables().iterator(); i.hasNext(); ) {
481  
            final VariableDeclarator var = i.next();
482  
            var.accept(this, arg);
483  
            if (i.hasNext()) {
484  
                printer.print(", ");
485  
            }
486  
        }
487  
488  
        printer.print(";");
489  
    }
490  
491  
    @Override
492  
    public void visit(final VariableDeclarator n, final Void arg) {
493  
        printComment(n.getComment(), arg);
494  
        n.getName().accept(this, arg);
495  
496  
        n.findAncestor(NodeWithVariables.class).ifPresent(ancestor -> {
497  
            ((NodeWithVariables<?>) ancestor).getMaximumCommonType().ifPresent(commonType -> {
498  
499  
                final Type type = n.getType();
500  
501  
                ArrayType arrayType = null;
502  
503  
                for (int i = commonType.getArrayLevel(); i < type.getArrayLevel(); i++) {
504  
                    if (arrayType == null) {
505  
                        arrayType = (ArrayType) type;
506  
                    } else {
507  
                        arrayType = (ArrayType) arrayType.getComponentType();
508  
                    }
509  
                    printAnnotations(arrayType.getAnnotations(), true, arg);
510  
                    printer.print("[]");
511  
                }
512  
            });
513  
        });
514  
515  
        if (n.getInitializer().isPresent()) {
516  
            printer.print(" = ");
517  
            n.getInitializer().get().accept(this, arg);
518  
        }
519  
    }
520  
521  
    @Override
522  
    public void visit(final ArrayInitializerExpr n, final Void arg) {
523  
        printComment(n.getComment(), arg);
524  
        printer.print("{");
525  
        if (!isNullOrEmpty(n.getValues())) {
526  
            printer.print(" ");
527  
            for (final Iterator<Expression> i = n.getValues().iterator(); i.hasNext(); ) {
528  
                final Expression expr = i.next();
529  
                expr.accept(this, arg);
530  
                if (i.hasNext()) {
531  
                    printer.print(", ");
532  
                }
533  
            }
534  
            printer.print(" ");
535  
        }
536  
        printOrphanCommentsEnding(n);
537  
        printer.print("}");
538  
    }
539  
540  
    @Override
541  
    public void visit(final VoidType n, final Void arg) {
542  
        printComment(n.getComment(), arg);
543  
        printAnnotations(n.getAnnotations(), false, arg);
544  
        printer.print("void");
545  
    }
546  
547  
    @Override
548  
    public void visit(final VarType n, final Void arg) {
549  
        printComment(n.getComment(), arg);
550  
        printAnnotations(n.getAnnotations(), false, arg);
551  
        printer.print("var");
552  
    }
553  
554  
    @Override
555  
    public void visit(Modifier n, Void arg) {
556  
        printer.print(n.getKeyword().asString());
557  
        printer.print(" ");
558  
    }
559  
560  
    @Override
561  
    public void visit(final ArrayAccessExpr n, final Void arg) {
562  
        printComment(n.getComment(), arg);
563  
        n.getName().accept(this, arg);
564  
        printer.print("[");
565  
        n.getIndex().accept(this, arg);
566  
        printer.print("]");
567  
    }
568  
569  
    @Override
570  
    public void visit(final ArrayCreationExpr n, final Void arg) {
571  
        printComment(n.getComment(), arg);
572  
        printer.print("new ");
573  
        n.getElementType().accept(this, arg);
574  
        for (ArrayCreationLevel level : n.getLevels()) {
575  
            level.accept(this, arg);
576  
        }
577  
        if (n.getInitializer().isPresent()) {
578  
            printer.print(" ");
579  
            n.getInitializer().get().accept(this, arg);
580  
        }
581  
    }
582  
583  
    @Override
584  
    public void visit(final AssignExpr n, final Void arg) {
585  
        printComment(n.getComment(), arg);
586  
        n.getTarget().accept(this, arg);
587  
        printer.print(" ");
588  
        printer.print(n.getOperator().asString());
589  
        printer.print(" ");
590  
        n.getValue().accept(this, arg);
591  
    }
592  
593  
    @Override
594  
    public void visit(final BinaryExpr n, final Void arg) {
595  
        printComment(n.getComment(), arg);
596  
        n.getLeft().accept(this, arg);
597  
        printer.print(" ");
598  
        printer.print(n.getOperator().asString());
599  
        printer.print(" ");
600  
        n.getRight().accept(this, arg);
601  
    }
602  
603  
    @Override
604  
    public void visit(final CastExpr n, final Void arg) {
605  
        printComment(n.getComment(), arg);
606  
        printer.print("(");
607  
        n.getType().accept(this, arg);
608  
        printer.print(") ");
609  
        n.getExpression().accept(this, arg);
610  
    }
611  
612  
    @Override
613  
    public void visit(final ClassExpr n, final Void arg) {
614  
        printComment(n.getComment(), arg);
615  
        n.getType().accept(this, arg);
616  
        printer.print(".class");
617  
    }
618  
619  
    @Override
620  
    public void visit(final ConditionalExpr n, final Void arg) {
621  
        printComment(n.getComment(), arg);
622  
        n.getCondition().accept(this, arg);
623  
        printer.print(" ? ");
624  
        n.getThenExpr().accept(this, arg);
625  
        printer.print(" : ");
626  
        n.getElseExpr().accept(this, arg);
627  
    }
628  
629  
    @Override
630  
    public void visit(final EnclosedExpr n, final Void arg) {
631  
        printComment(n.getComment(), arg);
632  
        printer.print("(");
633  
        n.getInner().accept(this, arg);
634  
        printer.print(")");
635  
    }
636  
637  
    @Override
638  
    public void visit(final FieldAccessExpr n, final Void arg) {
639  
        printComment(n.getComment(), arg);
640  
        n.getScope().accept(this, arg);
641  
        printer.print(".");
642  
        n.getName().accept(this, arg);
643  
    }
644  
645  
    @Override
646  
    public void visit(final InstanceOfExpr n, final Void arg) {
647  
        printComment(n.getComment(), arg);
648  
        n.getExpression().accept(this, arg);
649  
        printer.print(" instanceof ");
650  
        n.getType().accept(this, arg);
651  
    }
652  
653  
    @Override
654  
    public void visit(final CharLiteralExpr n, final Void arg) {
655  
        printComment(n.getComment(), arg);
656  
        printer.print("'");
657  
        printer.print(n.getValue());
658  
        printer.print("'");
659  
    }
660  
661  
    @Override
662  
    public void visit(final DoubleLiteralExpr n, final Void arg) {
663  
        printComment(n.getComment(), arg);
664  
        printer.print(n.getValue());
665  
    }
666  
667  
    @Override
668  
    public void visit(final IntegerLiteralExpr n, final Void arg) {
669  
        printComment(n.getComment(), arg);
670  
        printer.print(n.getValue());
671  
    }
672  
673  
    @Override
674  
    public void visit(final LongLiteralExpr n, final Void arg) {
675  
        printComment(n.getComment(), arg);
676  
        printer.print(n.getValue());
677  
    }
678  
679  
    @Override
680  
    public void visit(final StringLiteralExpr n, final Void arg) {
681  
        printComment(n.getComment(), arg);
682  
        printer.print("\"");
683  
        printer.print(n.getValue());
684  
        printer.print("\"");
685  
    }
686  
687  
    @Override
688  
    public void visit(final BooleanLiteralExpr n, final Void arg) {
689  
        printComment(n.getComment(), arg);
690  
        printer.print(String.valueOf(n.getValue()));
691  
    }
692  
693  
    @Override
694  
    public void visit(final NullLiteralExpr n, final Void arg) {
695  
        printComment(n.getComment(), arg);
696  
        printer.print("null");
697  
    }
698  
699  
    @Override
700  
    public void visit(final ThisExpr n, final Void arg) {
701  
        printComment(n.getComment(), arg);
702  
        if (n.getClassExpr().isPresent()) {
703  
            n.getClassExpr().get().accept(this, arg);
704  
            printer.print(".");
705  
        }
706  
        printer.print("this");
707  
    }
708  
709  
    @Override
710  
    public void visit(final SuperExpr n, final Void arg) {
711  
        printComment(n.getComment(), arg);
712  
        if (n.getClassExpr().isPresent()) {
713  
            n.getClassExpr().get().accept(this, arg);
714  
            printer.print(".");
715  
        }
716  
        printer.print("super");
717  
    }
718  
719  
    @Override
720  
    public void visit(final MethodCallExpr n, final Void arg) {
721  
        printComment(n.getComment(), arg);
722  
723  
        // determine whether we do reindenting for aligmnent at all
724  
        // - is it enabled?
725  
        // - are we in a statement where we want the alignment?
726  
        // - are we not directly in the argument list of a method call expression?
727  
        AtomicBoolean columnAlignFirstMethodChain = new AtomicBoolean();
728  
        if (configuration.isColumnAlignFirstMethodChain()) {
729  
            // pick the kind of expressions where vertically aligning method calls is okay.
730  
            if (n.findAncestor(Statement.class).map(p -> p.isReturnStmt()
731  
                    || p.isThrowStmt()
732  
                    || p.isAssertStmt()
733  
                    || p.isExpressionStmt()).orElse(false)) {
734  
                // search for first parent that does not have its child as scope
735  
                Node c = n;
736  
                Optional<Node> p = c.getParentNode();
737  
                while (p.isPresent() && p.filter(NodeWithTraversableScope.class::isInstance)
738  
                        .map(NodeWithTraversableScope.class::cast)
739  
                        .flatMap(NodeWithTraversableScope::traverseScope)
740  
                        .map(c::equals)
741  
                        .orElse(false)) {
742  
                    c = p.get();
743  
                    p = c.getParentNode();
744  
                }
745  
746  
                // check if the parent is a method call and thus we are in an argument list
747  
                columnAlignFirstMethodChain.set(!p.filter(MethodCallExpr.class::isInstance).isPresent());
748  
            }
749  
        }
750  
751  
        // we are at the last method call of a call chain
752  
        // this means we do not start reindenting for alignment or we undo it
753  
        AtomicBoolean lastMethodInCallChain = new AtomicBoolean(true);
754  
        if (columnAlignFirstMethodChain.get()) {
755  
            Node node = n;
756  
            while (node.getParentNode()
757  
                    .filter(NodeWithTraversableScope.class::isInstance)
758  
                    .map(NodeWithTraversableScope.class::cast)
759  
                    .flatMap(NodeWithTraversableScope::traverseScope)
760  
                    .map(node::equals)
761  
                    .orElse(false)) {
762  
                node = node.getParentNode().orElseThrow(AssertionError::new);
763  
                if (node instanceof MethodCallExpr) {
764  
                    lastMethodInCallChain.set(false);
765  
                    break;
766  
                }
767  
            }
768  
        }
769  
770  
        // search whether there is a method call with scope in the scope already
771  
        // this means that we probably started reindenting for alignment there
772  
        AtomicBoolean methodCallWithScopeInScope = new AtomicBoolean();
773  
        if (columnAlignFirstMethodChain.get()) {
774  
            Optional<Expression> s = n.getScope();
775  
            while (s.filter(NodeWithTraversableScope.class::isInstance).isPresent()) {
776  
                Optional<Expression> parentScope = s.map(NodeWithTraversableScope.class::cast)
777  
                        .flatMap(NodeWithTraversableScope::traverseScope);
778  
                if (s.filter(MethodCallExpr.class::isInstance).isPresent() && parentScope.isPresent()) {
779  
                    methodCallWithScopeInScope.set(true);
780  
                    break;
781  
                }
782  
                s = parentScope;
783  
            }
784  
        }
785  
786  
        // we have a scope
787  
        // this means we are not the first method in the chain
788  
        n.getScope().ifPresent(scope -> {
789  
            scope.accept(this, arg);
790  
            if (columnAlignFirstMethodChain.get()) {
791  
                if (methodCallWithScopeInScope.get()) {
792  
                    /* We're a method call on the result of something (method call, property access, ...) that is not stand alone,
793  
                       and not the first one with scope, like:
794  
                       we're x() in a.b().x(), or in a=b().c[15].d.e().x().
795  
                       That means that the "else" has been executed by one of the methods in the scope chain, so that the alignment
796  
                       is set to the "." of that method.
797  
                       That means we will align to that "." when we start a new line: */
798  
                    printer.println();
799  
                } else if (!lastMethodInCallChain.get()) {
800  
                    /* We're the first method call on the result of something in the chain (method call, property access, ...),
801  
                       but we are not at the same time the last method call in that chain, like:
802  
                       we're x() in a().x().y(), or in Long.x().y.z(). That means we get to dictate the indent of following method
803  
                       calls in this chain by setting the cursor to where we are now: just before the "."
804  
                       that start this method call. */
805  
                    printer.reindentWithAlignToCursor();
806  
                }
807  
            }
808  
            printer.print(".");
809  
        });
810  
811  
        printTypeArgs(n, arg);
812  
        n.getName().accept(this, arg);
813  
        printer.duplicateIndent();
814  
        printArguments(n.getArguments(), arg);
815  
        printer.unindent();
816  
        if (columnAlignFirstMethodChain.get() && methodCallWithScopeInScope.get() && lastMethodInCallChain.get()) {
817  
            // undo the aligning after the arguments of the last method call are printed
818  
            printer.reindentToPreviousLevel();
819  
        }
820  
    }
821  
822  
    @Override
823  
    public void visit(final ObjectCreationExpr n, final Void arg) {
824  
        printComment(n.getComment(), arg);
825  
        if (n.getScope().isPresent()) {
826  
            n.getScope().get().accept(this, arg);
827  
            printer.print(".");
828  
        }
829  
830  
        printer.print("new ");
831  
832  
        printTypeArgs(n, arg);
833  
        if (!isNullOrEmpty(n.getTypeArguments().orElse(null))) {
834  
            printer.print(" ");
835  
        }
836  
837  
        n.getType().accept(this, arg);
838  
839  
        printArguments(n.getArguments(), arg);
840  
841  
        if (n.getAnonymousClassBody().isPresent()) {
842  
            printer.println(" {");
843  
            printer.indent();
844  
            printMembers(n.getAnonymousClassBody().get(), arg);
845  
            printer.unindent();
846  
            printer.print("}");
847  
        }
848  
    }
849  
850  
    @Override
851  
    public void visit(final UnaryExpr n, final Void arg) {
852  
        printComment(n.getComment(), arg);
853  
        if (n.getOperator().isPrefix()) {
854  
            printer.print(n.getOperator().asString());
855  
        }
856  
857  
        n.getExpression().accept(this, arg);
858  
859  
        if (n.getOperator().isPostfix()) {
860  
            printer.print(n.getOperator().asString());
861  
        }
862  
    }
863  
864  
    @Override
865  
    public void visit(final ConstructorDeclaration n, final Void arg) {
866  
        printComment(n.getComment(), arg);
867  
        printMemberAnnotations(n.getAnnotations(), arg);
868  
        printModifiers(n.getModifiers());
869  
870  
        printTypeParameters(n.getTypeParameters(), arg);
871  
        if (n.isGeneric()) {
872  
            printer.print(" ");
873  
        }
874  
        n.getName().accept(this, arg);
875  
876  
        printer.print("(");
877  
        if (!n.getParameters().isEmpty()) {
878  
            for (final Iterator<Parameter> i = n.getParameters().iterator(); i.hasNext(); ) {
879  
                final Parameter p = i.next();
880  
                p.accept(this, arg);
881  
                if (i.hasNext()) {
882  
                    printer.print(", ");
883  
                }
884  
            }
885  
        }
886  
        printer.print(")");
887  
888  
        if (!isNullOrEmpty(n.getThrownExceptions())) {
889  
            printer.print(" throws ");
890  
            for (final Iterator<ReferenceType> i = n.getThrownExceptions().iterator(); i.hasNext(); ) {
891  
                final ReferenceType name = i.next();
892  
                name.accept(this, arg);
893  
                if (i.hasNext()) {
894  
                    printer.print(", ");
895  
                }
896  
            }
897  
        }
898  
        printer.print(" ");
899  
        n.getBody().accept(this, arg);
900  
    }
901  
902  
    @Override
903  
    public void visit(final MethodDeclaration n, final Void arg) {
904  
        printOrphanCommentsBeforeThisChildNode(n);
905  
906  
        printComment(n.getComment(), arg);
907  
        printMemberAnnotations(n.getAnnotations(), arg);
908  
        printModifiers(n.getModifiers());
909  
        printTypeParameters(n.getTypeParameters(), arg);
910  
        if (!isNullOrEmpty(n.getTypeParameters())) {
911  
            printer.print(" ");
912  
        }
913  
914  
        n.getType().accept(this, arg);
915  
        printer.print(" ");
916  
        n.getName().accept(this, arg);
917  
918  
        printer.print("(");
919  
        n.getReceiverParameter().ifPresent(rp -> {
920  
            rp.accept(this, arg);
921  
            if (!isNullOrEmpty(n.getParameters())) {
922  
                printer.print(", ");
923  
            }
924  
        });
925  
        if (!isNullOrEmpty(n.getParameters())) {
926  
            for (final Iterator<Parameter> i = n.getParameters().iterator(); i.hasNext(); ) {
927  
                final Parameter p = i.next();
928  
                p.accept(this, arg);
929  
                if (i.hasNext()) {
930  
                    printer.print(", ");
931  
                }
932  
            }
933  
        }
934  
        printer.print(")");
935  
936  
        if (!isNullOrEmpty(n.getThrownExceptions())) {
937  
            printer.print(" throws ");
938  
            for (final Iterator<ReferenceType> i = n.getThrownExceptions().iterator(); i.hasNext(); ) {
939  
                final ReferenceType name = i.next();
940  
                name.accept(this, arg);
941  
                if (i.hasNext()) {
942  
                    printer.print(", ");
943  
                }
944  
            }
945  
        }
946  
        if (!n.getBody().isPresent()) {
947  
            printer.print(";");
948  
        } else {
949  
            printer.print(" ");
950  
            n.getBody().get().accept(this, arg);
951  
        }
952  
    }
953  
954  
    @Override
955  
    public void visit(final Parameter n, final Void arg) {
956  
        printComment(n.getComment(), arg);
957  
        printAnnotations(n.getAnnotations(), false, arg);
958  
        printModifiers(n.getModifiers());
959  
        n.getType().accept(this, arg);
960  
        if (n.isVarArgs()) {
961  
            printAnnotations(n.getVarArgsAnnotations(), false, arg);
962  
            printer.print("...");
963  
        }
964  
        if (!(n.getType() instanceof UnknownType)) {
965  
            printer.print(" ");
966  
        }
967  
        n.getName().accept(this, arg);
968  
    }
969  
970  
    @Override
971  
    public void visit(final ReceiverParameter n, final Void arg) {
972  
        printComment(n.getComment(), arg);
973  
        printAnnotations(n.getAnnotations(), false, arg);
974  
        n.getType().accept(this, arg);
975  
        printer.print(" ");
976  
        n.getName().accept(this, arg);
977  
    }
978  
979  
    @Override
980  
    public void visit(final ExplicitConstructorInvocationStmt n, final Void arg) {
981  
        printComment(n.getComment(), arg);
982  
        if (n.isThis()) {
983  
            printTypeArgs(n, arg);
984  
            printer.print("this");
985  
        } else {
986  
            if (n.getExpression().isPresent()) {
987  
                n.getExpression().get().accept(this, arg);
988  
                printer.print(".");
989  
            }
990  
            printTypeArgs(n, arg);
991  
            printer.print("super");
992  
        }
993  
        printArguments(n.getArguments(), arg);
994  
        printer.print(";");
995  
    }
996  
997  
    @Override
998  
    public void visit(final VariableDeclarationExpr n, final Void arg) {
999  
        printComment(n.getComment(), arg);
1000  
        if (n.getParentNode().map(ExpressionStmt.class::isInstance).orElse(false)) {
1001  
            printMemberAnnotations(n.getAnnotations(), arg);
1002  
        } else {
1003  
            printAnnotations(n.getAnnotations(), false, arg);
1004  
        }
1005  
        printModifiers(n.getModifiers());
1006  
1007  
        if (!n.getVariables().isEmpty()) {
1008  
            n.getMaximumCommonType().ifPresent(t -> t.accept(this, arg));
1009  
        }
1010  
        printer.print(" ");
1011  
1012  
        for (final Iterator<VariableDeclarator> i = n.getVariables().iterator(); i.hasNext(); ) {
1013  
            final VariableDeclarator v = i.next();
1014  
            v.accept(this, arg);
1015  
            if (i.hasNext()) {
1016  
                printer.print(", ");
1017  
            }
1018  
        }
1019  
    }
1020  
1021  
    @Override
1022  
    public void visit(final LocalClassDeclarationStmt n, final Void arg) {
1023  
        printComment(n.getComment(), arg);
1024  
        n.getClassDeclaration().accept(this, arg);
1025  
    }
1026  
1027  
    @Override
1028  
    public void visit(final AssertStmt n, final Void arg) {
1029  
        printComment(n.getComment(), arg);
1030  
        printer.print("assert ");
1031  
        n.getCheck().accept(this, arg);
1032  
        if (n.getMessage().isPresent()) {
1033  
            printer.print(" : ");
1034  
            n.getMessage().get().accept(this, arg);
1035  
        }
1036  
        printer.print(";");
1037  
    }
1038  
1039  
    @Override
1040  
    public void visit(final BlockStmt n, final Void arg) {
1041  
        printOrphanCommentsBeforeThisChildNode(n);
1042  
        printComment(n.getComment(), arg);
1043  
        printer.println("{");
1044  
        if (n.getStatements() != null) {
1045  
            printer.indent();
1046  
            for (final Statement s : n.getStatements()) {
1047  
                s.accept(this, arg);
1048  
                printer.println();
1049  
            }
1050  
            printer.unindent();
1051  
        }
1052  
        printOrphanCommentsEnding(n);
1053  
        printer.print("}");
1054  
    }
1055  
1056  
    @Override
1057  
    public void visit(final LabeledStmt n, final Void arg) {
1058  
        printComment(n.getComment(), arg);
1059  
        n.getLabel().accept(this, arg);
1060  
        printer.print(": ");
1061  
        n.getStatement().accept(this, arg);
1062  
    }
1063  
1064  
    @Override
1065  
    public void visit(final EmptyStmt n, final Void arg) {
1066  
        printComment(n.getComment(), arg);
1067  
        printer.print(";");
1068  
    }
1069  
1070  
    @Override
1071  
    public void visit(final ExpressionStmt n, final Void arg) {
1072  
        printOrphanCommentsBeforeThisChildNode(n);
1073  
        printComment(n.getComment(), arg);
1074  
        n.getExpression().accept(this, arg);
1075  
        printer.print(";");
1076  
    }
1077  
1078  
    @Override
1079  
    public void visit(final SwitchStmt n, final Void arg) {
1080  
        printSwitchNode(n, arg);
1081  
    }
1082  
1083  
    @Override
1084  
    public void visit(SwitchExpr n, Void arg) {
1085  
        printSwitchNode(n, arg);
1086  
    }
1087  
1088  
    private void printSwitchNode(SwitchNode n, Void arg) {
1089  
        printComment(n.getComment(), arg);
1090  
        printer.print("switch(");
1091  
        n.getSelector().accept(this, arg);
1092  
        printer.println(") {");
1093  
        if (n.getEntries() != null) {
1094  
            printer.indent();
1095  
            for (final SwitchEntryStmt e : n.getEntries()) {
1096  
                e.accept(this, arg);
1097  
            }
1098  
            printer.unindent();
1099  
        }
1100  
        printer.print("}");
1101  
    }
1102  
1103  
    @Override
1104  
    public void visit(final SwitchEntryStmt n, final Void arg) {
1105  
        printComment(n.getComment(), arg);
1106  
        if (n.getLabel().isPresent()) {
1107  
            printer.print("case ");
1108  
            n.getLabel().get().accept(this, arg);
1109  
            printer.print(":");
1110  
        } else {
1111  
            printer.print("default:");
1112  
        }
1113  
        printer.println();
1114  
        printer.indent();
1115  
        if (n.getStatements() != null) {
1116  
            for (final Statement s : n.getStatements()) {
1117  
                s.accept(this, arg);
1118  
                printer.println();
1119  
            }
1120  
        }
1121  
        printer.unindent();
1122  
    }
1123  
1124  
    @Override
1125  
    public void visit(final BreakStmt n, final Void arg) {
1126  
        printComment(n.getComment(), arg);
1127  
        printer.print("break");
1128  
        n.getLabel().ifPresent(l -> printer.print(" ").print(l.getIdentifier()));
1129  
        printer.print(";");
1130  
    }
1131  
1132  
    @Override
1133  
    public void visit(final ReturnStmt n, final Void arg) {
1134  
        printComment(n.getComment(), arg);
1135  
        printer.print("return");
1136  
        if (n.getExpression().isPresent()) {
1137  
            printer.print(" ");
1138  
            n.getExpression().get().accept(this, arg);
1139  
        }
1140  
        printer.print(";");
1141  
    }
1142  
1143  
    @Override
1144  
    public void visit(final EnumDeclaration n, final Void arg) {
1145  
        printComment(n.getComment(), arg);
1146  
        printMemberAnnotations(n.getAnnotations(), arg);
1147  
        printModifiers(n.getModifiers());
1148  
1149  
        printer.print("enum ");
1150  
        n.getName().accept(this, arg);
1151  
1152  
        if (!n.getImplementedTypes().isEmpty()) {
1153  
            printer.print(" implements ");
1154  
            for (final Iterator<ClassOrInterfaceType> i = n.getImplementedTypes().iterator(); i.hasNext(); ) {
1155  
                final ClassOrInterfaceType c = i.next();
1156  
                c.accept(this, arg);
1157  
                if (i.hasNext()) {
1158  
                    printer.print(", ");
1159  
                }
1160  
            }
1161  
        }
1162  
1163  
        printer.println(" {");
1164  
        printer.indent();
1165  
        if (n.getEntries().isNonEmpty()) {
1166  
            final boolean alignVertically =
1167  
                    // Either we hit the constant amount limit in the configurations, or...
1168  
                    n.getEntries().size() > configuration.getMaxEnumConstantsToAlignHorizontally() ||
1169  
                            // any of the constants has a comment.
1170  
                            n.getEntries().stream().anyMatch(e -> e.getComment().isPresent());
1171  
            printer.println();
1172  
            for (final Iterator<EnumConstantDeclaration> i = n.getEntries().iterator(); i.hasNext(); ) {
1173  
                final EnumConstantDeclaration e = i.next();
1174  
                e.accept(this, arg);
1175  
                if (i.hasNext()) {
1176  
                    if (alignVertically) {
1177  
                        printer.println(",");
1178  
                    } else {
1179  
                        printer.print(", ");
1180  
                    }
1181  
                }
1182  
            }
1183  
        }
1184  
        if (!n.getMembers().isEmpty()) {
1185  
            printer.println(";");
1186  
            printMembers(n.getMembers(), arg);
1187  
        } else {
1188  
            if (!n.getEntries().isEmpty()) {
1189  
                printer.println();
1190  
            }
1191  
        }
1192  
        printer.unindent();
1193  
        printer.print("}");
1194  
    }
1195  
1196  
    @Override
1197  
    public void visit(final EnumConstantDeclaration n, final Void arg) {
1198  
        printComment(n.getComment(), arg);
1199  
        printMemberAnnotations(n.getAnnotations(), arg);
1200  
        n.getName().accept(this, arg);
1201  
1202  
        if (!n.getArguments().isEmpty()) {
1203  
            printArguments(n.getArguments(), arg);
1204  
        }
1205  
1206  
        if (!n.getClassBody().isEmpty()) {
1207  
            printer.println(" {");
1208  
            printer.indent();
1209  
            printMembers(n.getClassBody(), arg);
1210  
            printer.unindent();
1211  
            printer.println("}");
1212  
        }
1213  
    }
1214  
1215  
    @Override
1216  
    public void visit(final InitializerDeclaration n, final Void arg) {
1217  
        printComment(n.getComment(), arg);
1218  
        if (n.isStatic()) {
1219  
            printer.print("static ");
1220  
        }
1221  
        n.getBody().accept(this, arg);
1222  
    }
1223  
1224  
    @Override
1225  
    public void visit(final IfStmt n, final Void arg) {
1226  
        printComment(n.getComment(), arg);
1227  
        printer.print("if (");
1228  
        n.getCondition().accept(this, arg);
1229  
        final boolean thenBlock = n.getThenStmt() instanceof BlockStmt;
1230  
        if (thenBlock) // block statement should start on the same line
1231  
            printer.print(") ");
1232  
        else {
1233  
            printer.println(")");
1234  
            printer.indent();
1235  
        }
1236  
        n.getThenStmt().accept(this, arg);
1237  
        if (!thenBlock)
1238  
            printer.unindent();
1239  
        if (n.getElseStmt().isPresent()) {
1240  
            if (thenBlock)
1241  
                printer.print(" ");
1242  
            else
1243  
                printer.println();
1244  
            final boolean elseIf = n.getElseStmt().orElse(null) instanceof IfStmt;
1245  
            final boolean elseBlock = n.getElseStmt().orElse(null) instanceof BlockStmt;
1246  
            if (elseIf || elseBlock) // put chained if and start of block statement on a same level
1247  
                printer.print("else ");
1248  
            else {
1249  
                printer.println("else");
1250  
                printer.indent();
1251  
            }
1252  
            if (n.getElseStmt().isPresent())
1253  
                n.getElseStmt().get().accept(this, arg);
1254  
            if (!(elseIf || elseBlock))
1255  
                printer.unindent();
1256  
        }
1257  
    }
1258  
1259  
    @Override
1260  
    public void visit(final WhileStmt n, final Void arg) {
1261  
        printComment(n.getComment(), arg);
1262  
        printer.print("while (");
1263  
        n.getCondition().accept(this, arg);
1264  
        printer.print(") ");
1265  
        n.getBody().accept(this, arg);
1266  
    }
1267  
1268  
    @Override
1269  
    public void visit(final ContinueStmt n, final Void arg) {
1270  
        printComment(n.getComment(), arg);
1271  
        printer.print("continue");
1272  
        n.getLabel().ifPresent(l -> printer.print(" ").print(l.getIdentifier()));
1273  
        printer.print(";");
1274  
    }
1275  
1276  
    @Override
1277  
    public void visit(final DoStmt n, final Void arg) {
1278  
        printComment(n.getComment(), arg);
1279  
        printer.print("do ");
1280  
        n.getBody().accept(this, arg);
1281  
        printer.print(" while (");
1282  
        n.getCondition().accept(this, arg);
1283  
        printer.print(");");
1284  
    }
1285  
1286  
    @Override
1287  
    public void visit(final ForEachStmt n, final Void arg) {
1288  
        printComment(n.getComment(), arg);
1289  
        printer.print("for (");
1290  
        n.getVariable().accept(this, arg);
1291  
        printer.print(" : ");
1292  
        n.getIterable().accept(this, arg);
1293  
        printer.print(") ");
1294  
        n.getBody().accept(this, arg);
1295  
    }
1296  
1297  
    @Override
1298  
    public void visit(final ForStmt n, final Void arg) {
1299  
        printComment(n.getComment(), arg);
1300  
        printer.print("for (");
1301  
        if (n.getInitialization() != null) {
1302  
            for (final Iterator<Expression> i = n.getInitialization().iterator(); i.hasNext(); ) {
1303  
                final Expression e = i.next();
1304  
                e.accept(this, arg);
1305  
                if (i.hasNext()) {
1306  
                    printer.print(", ");
1307  
                }
1308  
            }
1309  
        }
1310  
        printer.print("; ");
1311  
        if (n.getCompare().isPresent()) {
1312  
            n.getCompare().get().accept(this, arg);
1313  
        }
1314  
        printer.print("; ");
1315  
        if (n.getUpdate() != null) {
1316  
            for (final Iterator<Expression> i = n.getUpdate().iterator(); i.hasNext(); ) {
1317  
                final Expression e = i.next();
1318  
                e.accept(this, arg);
1319  
                if (i.hasNext()) {
1320  
                    printer.print(", ");
1321  
                }
1322  
            }
1323  
        }
1324  
        printer.print(") ");
1325  
        n.getBody().accept(this, arg);
1326  
    }
1327  
1328  
    @Override
1329  
    public void visit(final ThrowStmt n, final Void arg) {
1330  
        printComment(n.getComment(), arg);
1331  
        printer.print("throw ");
1332  
        n.getExpression().accept(this, arg);
1333  
        printer.print(";");
1334  
    }
1335  
1336  
    @Override
1337  
    public void visit(final SynchronizedStmt n, final Void arg) {
1338  
        printComment(n.getComment(), arg);
1339  
        printer.print("synchronized (");
1340  
        n.getExpression().accept(this, arg);
1341  
        printer.print(") ");
1342  
        n.getBody().accept(this, arg);
1343  
    }
1344  
1345  
    @Override
1346  
    public void visit(final TryStmt n, final Void arg) {
1347  
        printComment(n.getComment(), arg);
1348  
        printer.print("try ");
1349  
        if (!n.getResources().isEmpty()) {
1350  
            printer.print("(");
1351  
            Iterator<Expression> resources = n.getResources().iterator();
1352  
            boolean first = true;
1353  
            while (resources.hasNext()) {
1354  
                resources.next().accept(this, arg);
1355  
                if (resources.hasNext()) {
1356  
                    printer.print(";");
1357  
                    printer.println();
1358  
                    if (first) {
1359  
                        printer.indent();
1360  
                    }
1361  
                }
1362  
                first = false;
1363  
            }
1364  
            if (n.getResources().size() > 1) {
1365  
                printer.unindent();
1366  
            }
1367  
            printer.print(") ");
1368  
        }
1369  
        n.getTryBlock().accept(this, arg);
1370  
        for (final CatchClause c : n.getCatchClauses()) {
1371  
            c.accept(this, arg);
1372  
        }
1373  
        if (n.getFinallyBlock().isPresent()) {
1374  
            printer.print(" finally ");
1375  
            n.getFinallyBlock().get().accept(this, arg);
1376  
        }
1377  
    }
1378  
1379  
    @Override
1380  
    public void visit(final CatchClause n, final Void arg) {
1381  
        printComment(n.getComment(), arg);
1382  
        printer.print(" catch (");
1383  
        n.getParameter().accept(this, arg);
1384  
        printer.print(") ");
1385  
        n.getBody().accept(this, arg);
1386  
    }
1387  
1388  
    @Override
1389  
    public void visit(final AnnotationDeclaration n, final Void arg) {
1390  
        printComment(n.getComment(), arg);
1391  
        printMemberAnnotations(n.getAnnotations(), arg);
1392  
        printModifiers(n.getModifiers());
1393  
1394  
        printer.print("@interface ");
1395  
        n.getName().accept(this, arg);
1396  
        printer.println(" {");
1397  
        printer.indent();
1398  
        if (n.getMembers() != null) {
1399  
            printMembers(n.getMembers(), arg);
1400  
        }
1401  
        printer.unindent();
1402  
        printer.print("}");
1403  
    }
1404  
1405  
    @Override
1406  
    public void visit(final AnnotationMemberDeclaration n, final Void arg) {
1407  
        printComment(n.getComment(), arg);
1408  
        printMemberAnnotations(n.getAnnotations(), arg);
1409  
        printModifiers(n.getModifiers());
1410  
1411  
        n.getType().accept(this, arg);
1412  
        printer.print(" ");
1413  
        n.getName().accept(this, arg);
1414  
        printer.print("()");
1415  
        if (n.getDefaultValue().isPresent()) {
1416  
            printer.print(" default ");
1417  
            n.getDefaultValue().get().accept(this, arg);
1418  
        }
1419  
        printer.print(";");
1420  
    }
1421  
1422  
    @Override
1423  
    public void visit(final MarkerAnnotationExpr n, final Void arg) {
1424  
        printComment(n.getComment(), arg);
1425  
        printer.print("@");
1426  
        n.getName().accept(this, arg);
1427  
    }
1428  
1429  
    @Override
1430  
    public void visit(final SingleMemberAnnotationExpr n, final Void arg) {
1431  
        printComment(n.getComment(), arg);
1432  
        printer.print("@");
1433  
        n.getName().accept(this, arg);
1434  
        printer.print("(");
1435  
        n.getMemberValue().accept(this, arg);
1436  
        printer.print(")");
1437  
    }
1438  
1439  
    @Override
1440  
    public void visit(final NormalAnnotationExpr n, final Void arg) {
1441  
        printComment(n.getComment(), arg);
1442  
        printer.print("@");
1443  
        n.getName().accept(this, arg);
1444  
        printer.print("(");
1445  
        if (n.getPairs() != null) {
1446  
            for (final Iterator<MemberValuePair> i = n.getPairs().iterator(); i.hasNext(); ) {
1447  
                final MemberValuePair m = i.next();
1448  
                m.accept(this, arg);
1449  
                if (i.hasNext()) {
1450  
                    printer.print(", ");
1451  
                }
1452  
            }
1453  
        }
1454  
        printer.print(")");
1455  
    }
1456  
1457  
    @Override
1458  
    public void visit(final MemberValuePair n, final Void arg) {
1459  
        printComment(n.getComment(), arg);
1460  
        n.getName().accept(this, arg);
1461  
        printer.print(" = ");
1462  
        n.getValue().accept(this, arg);
1463  
    }
1464  
1465  
    @Override
1466  
    public void visit(final LineComment n, final Void arg) {
1467  
        if (configuration.isIgnoreComments()) {
1468  
            return;
1469  
        }
1470  
        printer
1471  
                .print("// ")
1472  
                .println(normalizeEolInTextBlock(n.getContent(), "").trim());
1473  
    }
1474  
1475  
    @Override
1476  
    public void visit(final BlockComment n, final Void arg) {
1477  
        if (configuration.isIgnoreComments()) {
1478  
            return;
1479  
        }
1480  
        final String commentContent = normalizeEolInTextBlock(n.getContent(), configuration.getEndOfLineCharacter());
1481  
        String[] lines = commentContent.split("\\R", -1); // as BlockComment should not be formatted, -1 to preserve any trailing empty line if present
1482  
        printer.print("/*");
1483  
        for (int i = 0; i < (lines.length - 1); i++) {
1484  
            printer.print(lines[i]);
1485  
            printer.print(configuration.getEndOfLineCharacter()); // Avoids introducing indentation in blockcomments. ie: do not use println() as it would trigger indentation at the next print call.
1486  
        }
1487  
        printer.print(lines[lines.length - 1]); // last line is not followed by a newline, and simply terminated with `*/`
1488  
        printer.println("*/");
1489  
    }
1490  
1491  
    @Override
1492  
    public void visit(LambdaExpr n, Void arg) {
1493  
        printComment(n.getComment(), arg);
1494  
1495  
        final NodeList<Parameter> parameters = n.getParameters();
1496  
        final boolean printPar = n.isEnclosingParameters();
1497  
1498  
        if (printPar) {
1499  
            printer.print("(");
1500  
        }
1501  
        for (Iterator<Parameter> i = parameters.iterator(); i.hasNext(); ) {
1502  
            Parameter p = i.next();
1503  
            p.accept(this, arg);
1504  
            if (i.hasNext()) {
1505  
                printer.print(", ");
1506  
            }
1507  
        }
1508  
        if (printPar) {
1509  
            printer.print(")");
1510  
        }
1511  
1512  
        printer.print(" -> ");
1513  
        final Statement body = n.getBody();
1514  
        if (body instanceof ExpressionStmt) {
1515  
            // Print the expression directly
1516  
            ((ExpressionStmt) body).getExpression().accept(this, arg);
1517  
        } else {
1518  
            body.accept(this, arg);
1519  
        }
1520  
    }
1521  
1522  
    @Override
1523  
    public void visit(MethodReferenceExpr n, Void arg) {
1524  
        printComment(n.getComment(), arg);
1525  
        Expression scope = n.getScope();
1526  
        String identifier = n.getIdentifier();
1527  
        if (scope != null) {
1528  
            n.getScope().accept(this, arg);
1529  
        }
1530  
1531  
        printer.print("::");
1532  
        printTypeArgs(n, arg);
1533  
        if (identifier != null) {
1534  
            printer.print(identifier);
1535  
        }
1536  
    }
1537  
1538  
    @Override
1539  
    public void visit(TypeExpr n, Void arg) {
1540  
        printComment(n.getComment(), arg);
1541  
        if (n.getType() != null) {
1542  
            n.getType().accept(this, arg);
1543  
        }
1544  
    }
1545  
1546  
    @Override
1547  
    public void visit(NodeList n, Void arg) {
1548  
        if (configuration.isOrderImports() && n.size() > 0 && n.get(0) instanceof ImportDeclaration) {
1549  
            //noinspection unchecked
1550  
            NodeList<ImportDeclaration> modifiableList = new NodeList<>(n);
1551  
            modifiableList.sort(
1552  
                    comparingInt((ImportDeclaration i) -> i.isStatic() ? 0 : 1)
1553  
                            .thenComparing(NodeWithName::getNameAsString));
1554  
            for (Object node : modifiableList) {
1555  
                ((Node) node).accept(this, arg);
1556  
            }
1557  
        } else {
1558  
            for (Object node : n) {
1559  
                ((Node) node).accept(this, arg);
1560  
            }
1561  
        }
1562  
    }
1563  
1564  
    @Override
1565  
    public void visit(final ImportDeclaration n, final Void arg) {
1566  
        printComment(n.getComment(), arg);
1567  
        printer.print("import ");
1568  
        if (n.isStatic()) {
1569  
            printer.print("static ");
1570  
        }
1571  
        n.getName().accept(this, arg);
1572  
        if (n.isAsterisk()) {
1573  
            printer.print(".*");
1574  
        }
1575  
        printer.println(";");
1576  
1577  
        printOrphanCommentsEnding(n);
1578  
    }
1579  
1580  
1581  
    @Override
1582  
    public void visit(ModuleDeclaration n, Void arg) {
1583  
        printMemberAnnotations(n.getAnnotations(), arg);
1584  
        if (n.isOpen()) {
1585  
            printer.print("open ");
1586  
        }
1587  
        printer.print("module ");
1588  
        n.getName().accept(this, arg);
1589  
        printer.println(" {").indent();
1590  
        n.getDirectives().accept(this, arg);
1591  
        printer.unindent().println("}");
1592  
    }
1593  
1594  
    @Override
1595  
    public void visit(ModuleRequiresDirective n, Void arg) {
1596  
        printer.print("requires ");
1597  
        printModifiers(n.getModifiers());
1598  
        n.getName().accept(this, arg);
1599  
        printer.println(";");
1600  
    }
1601  
1602  
    @Override
1603  
    public void visit(ModuleExportsDirective n, Void arg) {
1604  
        printer.print("exports ");
1605  
        n.getName().accept(this, arg);
1606  
        printPrePostFixOptionalList(n.getModuleNames(), arg, " to ", ", ", "");
1607  
        printer.println(";");
1608  
    }
1609  
1610  
    @Override
1611  
    public void visit(ModuleProvidesDirective n, Void arg) {
1612  
        printer.print("provides ");
1613  
        n.getName().accept(this, arg);
1614  
        printPrePostFixRequiredList(n.getWith(), arg, " with ", ", ", "");
1615  
        printer.println(";");
1616  
    }
1617  
1618  
    @Override
1619  
    public void visit(ModuleUsesDirective n, Void arg) {
1620  
        printer.print("uses ");
1621  
        n.getName().accept(this, arg);
1622  
        printer.println(";");
1623  
    }
1624  
1625  
    @Override
1626  
    public void visit(ModuleOpensDirective n, Void arg) {
1627  
        printer.print("opens ");
1628  
        n.getName().accept(this, arg);
1629  
        printPrePostFixOptionalList(n.getModuleNames(), arg, " to ", ", ", "");
1630  
        printer.println(";");
1631  
    }
1632  
1633  
    @Override
1634  
    public void visit(UnparsableStmt n, Void arg) {
1635  
        printer.print("???;");
1636  
    }
1637  
1638  
    private void printOrphanCommentsBeforeThisChildNode(final Node node) {
1639  
        if (configuration.isIgnoreComments()) return;
1640  
        if (node instanceof Comment) return;
1641  
1642  
        Node parent = node.getParentNode().orElse(null);
1643  
        if (parent == null) return;
1644  
        List<Node> everything = new LinkedList<>();
1645  
        everything.addAll(parent.getChildNodes());
1646  
        sortByBeginPosition(everything);
1647  
        int positionOfTheChild = -1;
1648  
        for (int i = 0; i < everything.size(); i++) {
1649  
            if (everything.get(i) == node) positionOfTheChild = i;
1650  
        }
1651  
        if (positionOfTheChild == -1) {
1652  
            throw new AssertionError("I am not a child of my parent.");
1653  
        }
1654  
        int positionOfPreviousChild = -1;
1655  
        for (int i = positionOfTheChild - 1; i >= 0 && positionOfPreviousChild == -1; i--) {
1656  
            if (!(everything.get(i) instanceof Comment)) positionOfPreviousChild = i;
1657  
        }
1658  
        for (int i = positionOfPreviousChild + 1; i < positionOfTheChild; i++) {
1659  
            Node nodeToPrint = everything.get(i);
1660  
            if (!(nodeToPrint instanceof Comment))
1661  
                throw new RuntimeException(
1662  
                        "Expected comment, instead " + nodeToPrint.getClass() + ". Position of previous child: "
1663  
                                + positionOfPreviousChild + ", position of child " + positionOfTheChild);
1664  
            nodeToPrint.accept(this, null);
1665  
        }
1666  
    }
1667  
1668  
    private void printOrphanCommentsEnding(final Node node) {
1669  
        if (configuration.isIgnoreComments()) return;
1670  
1671  
        List<Node> everything = new LinkedList<>();
1672  
        everything.addAll(node.getChildNodes());
1673  
        sortByBeginPosition(everything);
1674  
        if (everything.isEmpty()) {
1675  
            return;
1676  
        }
1677  
1678  
        int commentsAtEnd = 0;
1679  
        boolean findingComments = true;
1680  
        while (findingComments && commentsAtEnd < everything.size()) {
1681  
            Node last = everything.get(everything.size() - 1 - commentsAtEnd);
1682  
            findingComments = (last instanceof Comment);
1683  
            if (findingComments) {
1684  
                commentsAtEnd++;
1685  
            }
1686  
        }
1687  
        for (int i = 0; i < commentsAtEnd; i++) {
1688  
            everything.get(everything.size() - commentsAtEnd + i).accept(this, null);
1689  
        }
1690  
    }
1691  
1692  
}

download  show line numbers  debug dex  old transpilations   

Travelled to 8 computer(s): bhatertpkbcr, cfunsshuasjs, gwrvuhgaqvyk, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tvejysmllsmz, vouqrxazstgt

No comments. add comment

Snippet ID: #1020877
Snippet name: PrettyPrintVisitor2 (adapted from JavaParser)
Eternal ID of this version: #1020877/5
Text MD5: e5b169b790774bb972fdf53d7759666f
Author: stefan
Category: javax / pretty printing
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2019-01-07 15:10:37
Source code size: 59387 bytes / 1692 lines
Pitched / IR pitched: No / No
Views / Downloads: 200 / 365
Version history: 4 change(s)
Referenced in: [show references]