1 | /* |
---|---|
2 | * Copyright (C) 2007-2010 JĂșlio Vilmar Gesser. |
3 | * Copyright (C) 2011, 2013-2020 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 | package com.github.javaparser.printer; |
23 | |
24 | import com.github.javaparser.GeneratedJavaParserConstants; |
25 | import com.github.javaparser.ast.*; |
26 | import com.github.javaparser.ast.body.*; |
27 | import com.github.javaparser.ast.comments.Comment; |
28 | import com.github.javaparser.ast.expr.*; |
29 | import com.github.javaparser.ast.modules.*; |
30 | import com.github.javaparser.ast.observer.ObservableProperty; |
31 | import com.github.javaparser.ast.stmt.*; |
32 | import com.github.javaparser.ast.type.*; |
33 | import com.github.javaparser.metamodel.JavaParserMetaModel; |
34 | import com.github.javaparser.printer.concretesyntaxmodel.CsmConditional; |
35 | import com.github.javaparser.printer.concretesyntaxmodel.CsmElement; |
36 | import com.github.javaparser.printer.concretesyntaxmodel.CsmMix; |
37 | |
38 | import java.util.*; |
39 | import java.util.stream.Collectors; |
40 | |
41 | import static com.github.javaparser.GeneratedJavaParserConstants.*; |
42 | import static com.github.javaparser.ast.observer.ObservableProperty.*; |
43 | import static com.github.javaparser.printer.concretesyntaxmodel.CsmConditional.Condition.*; |
44 | import static com.github.javaparser.printer.concretesyntaxmodel.CsmElement.*; |
45 | |
46 | /** |
47 | * The Concrete Syntax Model for a single node type. It knows the syntax used to represent a certain element in Java |
48 | * code. |
49 | */ |
50 | public class ConcreteSyntaxModel { |
51 | |
52 | private static final Map<Class, CsmElement> concreteSyntaxModelByClass = new HashMap<>(); |
53 | private static Optional<String> initializationError; |
54 | |
55 | private static CsmElement modifiers() { |
56 | return list(ObservableProperty.MODIFIERS, space(), none(), space()); |
57 | } |
58 | |
59 | /** |
60 | * Build a mix collecting all the elements specified. |
61 | */ |
62 | private static CsmElement mix(CsmElement... elements) { |
63 | return new CsmMix(Arrays.asList(elements)); |
64 | } |
65 | |
66 | private static CsmElement memberAnnotations() { |
67 | return list(ObservableProperty.ANNOTATIONS, newline(), none(), newline()); |
68 | } |
69 | |
70 | private static CsmElement annotations() { |
71 | return list(ObservableProperty.ANNOTATIONS, space(), none(), newline()); |
72 | } |
73 | |
74 | private static CsmElement typeParameters() { |
75 | return list(ObservableProperty.TYPE_PARAMETERS, sequence(comma(), space()), token(GeneratedJavaParserConstants.LT), |
76 | sequence(token(GeneratedJavaParserConstants.GT), space())); |
77 | } |
78 | |
79 | private static CsmElement typeArguments() { |
80 | return list(ObservableProperty.TYPE_ARGUMENTS, sequence(comma(), space()), token(GeneratedJavaParserConstants.LT), |
81 | sequence(token(GeneratedJavaParserConstants.GT))); |
82 | } |
83 | |
84 | static { |
85 | |
86 | /// |
87 | /// Body |
88 | /// |
89 | |
90 | concreteSyntaxModelByClass.put(AnnotationDeclaration.class, sequence( |
91 | comment(), |
92 | memberAnnotations(), |
93 | modifiers(), |
94 | token(GeneratedJavaParserConstants.AT), |
95 | token(GeneratedJavaParserConstants.INTERFACE), |
96 | space(), |
97 | child(ObservableProperty.NAME), |
98 | space(), |
99 | token(LBRACE), |
100 | newline(), |
101 | indent(), |
102 | list(ObservableProperty.MEMBERS, newline(), none(), none(), newline()), |
103 | unindent(), |
104 | token(RBRACE) |
105 | )); |
106 | |
107 | concreteSyntaxModelByClass.put(AnnotationMemberDeclaration.class, sequence( |
108 | comment(), |
109 | memberAnnotations(), |
110 | modifiers(), |
111 | child(ObservableProperty.TYPE), |
112 | space(), |
113 | child(ObservableProperty.NAME), |
114 | token(LPAREN), |
115 | token(RPAREN), |
116 | conditional(ObservableProperty.DEFAULT_VALUE, IS_PRESENT, sequence(space(), token(GeneratedJavaParserConstants._DEFAULT), space(), child(DEFAULT_VALUE))), |
117 | semicolon() |
118 | )); |
119 | |
120 | concreteSyntaxModelByClass.put(ClassOrInterfaceDeclaration.class, sequence( |
121 | comment(), |
122 | memberAnnotations(), |
123 | modifiers(), |
124 | conditional(ObservableProperty.INTERFACE, FLAG, token(GeneratedJavaParserConstants.INTERFACE), token(GeneratedJavaParserConstants.CLASS)), |
125 | space(), |
126 | child(ObservableProperty.NAME), |
127 | list(TYPE_PARAMETERS, sequence(comma(), space()), string(GeneratedJavaParserConstants.LT), string(GeneratedJavaParserConstants.GT)), |
128 | list(ObservableProperty.EXTENDED_TYPES, |
129 | sequence(string(GeneratedJavaParserConstants.COMMA), space()), |
130 | sequence(space(), token(GeneratedJavaParserConstants.EXTENDS), space()), |
131 | none()), |
132 | list(ObservableProperty.IMPLEMENTED_TYPES, sequence(string(GeneratedJavaParserConstants.COMMA), space()), sequence( |
133 | space(), |
134 | token(GeneratedJavaParserConstants.IMPLEMENTS), |
135 | space()), none()), |
136 | space(), |
137 | block(sequence(newline(), list(ObservableProperty.MEMBERS, sequence(newline(), newline()), newline(), newline()))) |
138 | )); |
139 | |
140 | concreteSyntaxModelByClass.put(ConstructorDeclaration.class, sequence( |
141 | comment(), |
142 | memberAnnotations(), |
143 | modifiers(), |
144 | typeParameters(), |
145 | child(ObservableProperty.NAME), |
146 | token(GeneratedJavaParserConstants.LPAREN), |
147 | list(ObservableProperty.PARAMETERS, sequence(comma(), space()), none(), none()), |
148 | token(GeneratedJavaParserConstants.RPAREN), |
149 | list(ObservableProperty.THROWN_EXCEPTIONS, sequence(comma(), space()), sequence(space(), token(GeneratedJavaParserConstants.THROWS), space()), none()), |
150 | space(), |
151 | child(ObservableProperty.BODY) |
152 | )); |
153 | |
154 | concreteSyntaxModelByClass.put(EnumConstantDeclaration.class, sequence( |
155 | comment(), |
156 | memberAnnotations(), |
157 | child(ObservableProperty.NAME), |
158 | list(ObservableProperty.ARGUMENTS, sequence(comma(), space()), token(GeneratedJavaParserConstants.LPAREN), token(GeneratedJavaParserConstants.RPAREN)), |
159 | conditional(CLASS_BODY, IS_NOT_EMPTY, sequence(space(), token(GeneratedJavaParserConstants.LBRACE), newline(), indent(), newline(), |
160 | list(ObservableProperty.CLASS_BODY, newline(), newline(), none(), newline()), |
161 | unindent(), |
162 | token(RBRACE), newline())) |
163 | )); |
164 | |
165 | concreteSyntaxModelByClass.put(EnumDeclaration.class, sequence( |
166 | comment(), |
167 | annotations(), |
168 | modifiers(), |
169 | token(GeneratedJavaParserConstants.ENUM), |
170 | space(), |
171 | child(ObservableProperty.NAME), |
172 | list(ObservableProperty.IMPLEMENTED_TYPES, |
173 | sequence(comma(), space()), |
174 | sequence(space(), token(GeneratedJavaParserConstants.IMPLEMENTS), space()), |
175 | none()), |
176 | space(), |
177 | token(GeneratedJavaParserConstants.LBRACE), |
178 | newline(), |
179 | indent(), |
180 | newline(), |
181 | list(ObservableProperty.ENTRIES, |
182 | sequence(comma(), newline()), |
183 | none(), |
184 | none()), |
185 | conditional(ObservableProperty.MEMBERS, IS_EMPTY, |
186 | conditional(ObservableProperty.ENTRIES, IS_NOT_EMPTY, newline()), |
187 | sequence(semicolon(), newline(), newline(), list(ObservableProperty.MEMBERS, newline(), newline(), none(), newline()))), |
188 | unindent(), |
189 | token(RBRACE) |
190 | )); |
191 | |
192 | concreteSyntaxModelByClass.put(FieldDeclaration.class, sequence( |
193 | orphanCommentsBeforeThis(), |
194 | comment(), |
195 | annotations(), |
196 | modifiers(), |
197 | conditional(ObservableProperty.VARIABLES, IS_NOT_EMPTY, child(ObservableProperty.MAXIMUM_COMMON_TYPE)), |
198 | space(), |
199 | list(ObservableProperty.VARIABLES, sequence(comma(), space())), |
200 | semicolon())); |
201 | |
202 | concreteSyntaxModelByClass.put(InitializerDeclaration.class, sequence( |
203 | comment(), |
204 | conditional(ObservableProperty.STATIC, FLAG, sequence(token(GeneratedJavaParserConstants.STATIC), space())), |
205 | child(ObservableProperty.BODY))); |
206 | |
207 | concreteSyntaxModelByClass.put(MethodDeclaration.class, sequence( |
208 | orphanCommentsBeforeThis(), |
209 | comment(), |
210 | mix(memberAnnotations(), modifiers()), |
211 | typeParameters(), |
212 | child(ObservableProperty.TYPE), |
213 | space(), |
214 | child(ObservableProperty.NAME), |
215 | token(GeneratedJavaParserConstants.LPAREN), |
216 | conditional(ObservableProperty.RECEIVER_PARAMETER, IS_PRESENT, sequence(child(ObservableProperty.RECEIVER_PARAMETER), comma(), space())), |
217 | list(ObservableProperty.PARAMETERS, sequence(comma(), space()), none(), none()), |
218 | token(GeneratedJavaParserConstants.RPAREN), |
219 | list(ObservableProperty.THROWN_EXCEPTIONS, sequence(comma(), space()), sequence(space(), token(GeneratedJavaParserConstants.THROWS), space()), none()), |
220 | conditional(ObservableProperty.BODY, IS_PRESENT, sequence(space(), child(ObservableProperty.BODY)), semicolon()) |
221 | )); |
222 | |
223 | concreteSyntaxModelByClass.put(Parameter.class, sequence( |
224 | comment(), |
225 | list(ObservableProperty.ANNOTATIONS, space(), none(), space()), |
226 | modifiers(), |
227 | child(ObservableProperty.TYPE), |
228 | conditional(ObservableProperty.VAR_ARGS, FLAG, sequence( |
229 | list(ObservableProperty.VAR_ARGS_ANNOTATIONS, space(), none(), none()), |
230 | token(GeneratedJavaParserConstants.ELLIPSIS))), |
231 | space(), |
232 | child(ObservableProperty.NAME))); |
233 | |
234 | concreteSyntaxModelByClass.put(ReceiverParameter.class, sequence( |
235 | comment(), |
236 | list(ObservableProperty.ANNOTATIONS, space(), none(), space()), |
237 | child(ObservableProperty.TYPE), |
238 | space(), |
239 | child(ObservableProperty.NAME))); |
240 | |
241 | concreteSyntaxModelByClass.put(VariableDeclarator.class, sequence( |
242 | comment(), |
243 | child(ObservableProperty.NAME), |
244 | // FIXME: we should introduce a derived property |
245 | // list(ObservableProperty.EXTRA_ARRAY_LEVELS), |
246 | conditional(ObservableProperty.INITIALIZER, IS_PRESENT, sequence(space(), token(GeneratedJavaParserConstants.ASSIGN), space(), |
247 | child(ObservableProperty.INITIALIZER))) |
248 | )); |
249 | |
250 | /// |
251 | /// Expressions |
252 | /// |
253 | |
254 | concreteSyntaxModelByClass.put(ArrayAccessExpr.class, sequence( |
255 | comment(), |
256 | child(ObservableProperty.NAME), |
257 | token(GeneratedJavaParserConstants.LBRACKET), |
258 | child(ObservableProperty.INDEX), |
259 | token(GeneratedJavaParserConstants.RBRACKET) |
260 | )); |
261 | |
262 | concreteSyntaxModelByClass.put(ArrayCreationExpr.class, sequence( |
263 | comment(), |
264 | token(GeneratedJavaParserConstants.NEW), |
265 | space(), |
266 | child(ObservableProperty.ELEMENT_TYPE), |
267 | list(ObservableProperty.LEVELS), |
268 | conditional(ObservableProperty.INITIALIZER, IS_PRESENT, sequence(space(), child(ObservableProperty.INITIALIZER))) |
269 | )); |
270 | |
271 | concreteSyntaxModelByClass.put(ArrayInitializerExpr.class, sequence( |
272 | comment(), |
273 | token(GeneratedJavaParserConstants.LBRACE), |
274 | list(ObservableProperty.VALUES, sequence(comma(), space()), space(), space()), |
275 | orphanCommentsEnding(), |
276 | token(RBRACE))); |
277 | |
278 | concreteSyntaxModelByClass.put(AssignExpr.class, sequence( |
279 | comment(), |
280 | child(ObservableProperty.TARGET), |
281 | space(), |
282 | attribute(ObservableProperty.OPERATOR), |
283 | space(), |
284 | child(ObservableProperty.VALUE) |
285 | )); |
286 | |
287 | concreteSyntaxModelByClass.put(BinaryExpr.class, sequence( |
288 | comment(), |
289 | child(ObservableProperty.LEFT), |
290 | space(), |
291 | attribute(ObservableProperty.OPERATOR), |
292 | space(), |
293 | child(ObservableProperty.RIGHT) |
294 | )); |
295 | |
296 | concreteSyntaxModelByClass.put(BooleanLiteralExpr.class, sequence( |
297 | comment(), attribute(VALUE) |
298 | )); |
299 | |
300 | concreteSyntaxModelByClass.put(CastExpr.class, sequence( |
301 | comment(), |
302 | token(GeneratedJavaParserConstants.LPAREN), |
303 | child(ObservableProperty.TYPE), |
304 | token(GeneratedJavaParserConstants.RPAREN), |
305 | space(), |
306 | child(ObservableProperty.EXPRESSION) |
307 | )); |
308 | |
309 | concreteSyntaxModelByClass.put(CharLiteralExpr.class, sequence( |
310 | comment(), |
311 | charToken(ObservableProperty.VALUE) |
312 | )); |
313 | |
314 | concreteSyntaxModelByClass.put(ClassExpr.class, sequence( |
315 | comment(), child(ObservableProperty.TYPE), token(GeneratedJavaParserConstants.DOT), token(GeneratedJavaParserConstants.CLASS))); |
316 | |
317 | concreteSyntaxModelByClass.put(ConditionalExpr.class, sequence( |
318 | comment(), |
319 | child(ObservableProperty.CONDITION), |
320 | space(), |
321 | token(GeneratedJavaParserConstants.HOOK), |
322 | space(), |
323 | child(ObservableProperty.THEN_EXPR), |
324 | space(), |
325 | token(GeneratedJavaParserConstants.COLON), |
326 | space(), |
327 | child(ObservableProperty.ELSE_EXPR) |
328 | )); |
329 | |
330 | concreteSyntaxModelByClass.put(DoubleLiteralExpr.class, sequence( |
331 | comment(), |
332 | attribute(ObservableProperty.VALUE) |
333 | )); |
334 | |
335 | concreteSyntaxModelByClass.put(EnclosedExpr.class, sequence( |
336 | comment(), |
337 | token(GeneratedJavaParserConstants.LPAREN), |
338 | child(ObservableProperty.INNER), |
339 | token(GeneratedJavaParserConstants.RPAREN) |
340 | )); |
341 | |
342 | concreteSyntaxModelByClass.put(FieldAccessExpr.class, sequence( |
343 | comment(), |
344 | child(SCOPE), |
345 | token(GeneratedJavaParserConstants.DOT), |
346 | child(ObservableProperty.NAME) |
347 | )); |
348 | |
349 | concreteSyntaxModelByClass.put(InstanceOfExpr.class, sequence( |
350 | comment(), |
351 | child(ObservableProperty.EXPRESSION), |
352 | space(), |
353 | token(GeneratedJavaParserConstants.INSTANCEOF), |
354 | space(), |
355 | child(ObservableProperty.TYPE) |
356 | )); |
357 | |
358 | concreteSyntaxModelByClass.put(IntegerLiteralExpr.class, sequence( |
359 | comment(), |
360 | attribute(ObservableProperty.VALUE) |
361 | )); |
362 | |
363 | concreteSyntaxModelByClass.put(LambdaExpr.class, sequence( |
364 | comment(), |
365 | conditional(ObservableProperty.ENCLOSING_PARAMETERS, FLAG, token(GeneratedJavaParserConstants.LPAREN)), |
366 | list(ObservableProperty.PARAMETERS, sequence(comma(), space())), |
367 | conditional(ObservableProperty.ENCLOSING_PARAMETERS, FLAG, token(GeneratedJavaParserConstants.RPAREN)), |
368 | space(), |
369 | token(GeneratedJavaParserConstants.ARROW), |
370 | space(), |
371 | conditional(ObservableProperty.EXPRESSION_BODY, IS_PRESENT, child(ObservableProperty.EXPRESSION_BODY), child(ObservableProperty.BODY)) |
372 | )); |
373 | |
374 | concreteSyntaxModelByClass.put(LongLiteralExpr.class, sequence( |
375 | comment(), |
376 | attribute(ObservableProperty.VALUE) |
377 | )); |
378 | |
379 | concreteSyntaxModelByClass.put(MarkerAnnotationExpr.class, sequence(comment(), token(GeneratedJavaParserConstants.AT), attribute(ObservableProperty.NAME))); |
380 | |
381 | concreteSyntaxModelByClass.put(MemberValuePair.class, sequence(comment(), |
382 | child(ObservableProperty.NAME), |
383 | space(), |
384 | token(GeneratedJavaParserConstants.ASSIGN), |
385 | space(), |
386 | child(ObservableProperty.VALUE))); |
387 | |
388 | concreteSyntaxModelByClass.put(MethodCallExpr.class, sequence( |
389 | comment(), |
390 | conditional(ObservableProperty.SCOPE, IS_PRESENT, sequence(child(ObservableProperty.SCOPE), token(GeneratedJavaParserConstants.DOT))), |
391 | typeArguments(), |
392 | child(ObservableProperty.NAME), |
393 | token(GeneratedJavaParserConstants.LPAREN), |
394 | list(ObservableProperty.ARGUMENTS, sequence(comma(), space()), none(), none()), |
395 | token(GeneratedJavaParserConstants.RPAREN) |
396 | )); |
397 | |
398 | concreteSyntaxModelByClass.put(MethodReferenceExpr.class, sequence( |
399 | comment(), |
400 | child(ObservableProperty.SCOPE), |
401 | token(GeneratedJavaParserConstants.DOUBLECOLON), |
402 | typeArguments(), |
403 | attribute(ObservableProperty.IDENTIFIER) |
404 | )); |
405 | |
406 | concreteSyntaxModelByClass.put(Modifier.class, attribute(ObservableProperty.KEYWORD)); |
407 | |
408 | concreteSyntaxModelByClass.put(Name.class, sequence( |
409 | comment(), |
410 | conditional(ObservableProperty.QUALIFIER, IS_PRESENT, sequence(child(ObservableProperty.QUALIFIER), token(GeneratedJavaParserConstants.DOT))), |
411 | attribute(ObservableProperty.IDENTIFIER), |
412 | orphanCommentsEnding() |
413 | )); |
414 | |
415 | concreteSyntaxModelByClass.put(NameExpr.class, sequence( |
416 | comment(), |
417 | child(ObservableProperty.NAME), |
418 | orphanCommentsEnding() |
419 | )); |
420 | |
421 | concreteSyntaxModelByClass.put(NormalAnnotationExpr.class, sequence( |
422 | comment(), |
423 | token(GeneratedJavaParserConstants.AT), |
424 | child(ObservableProperty.NAME), |
425 | token(GeneratedJavaParserConstants.LPAREN), |
426 | list(ObservableProperty.PAIRS, sequence(comma(), space())), |
427 | token(GeneratedJavaParserConstants.RPAREN) |
428 | )); |
429 | |
430 | concreteSyntaxModelByClass.put(NullLiteralExpr.class, sequence( |
431 | comment(), |
432 | token(GeneratedJavaParserConstants.NULL) |
433 | )); |
434 | |
435 | concreteSyntaxModelByClass.put(ObjectCreationExpr.class, sequence( |
436 | comment(), |
437 | conditional(ObservableProperty.SCOPE, IS_PRESENT, sequence(child(ObservableProperty.SCOPE), token(GeneratedJavaParserConstants.DOT))), |
438 | token(GeneratedJavaParserConstants.NEW), |
439 | space(), |
440 | list(ObservableProperty.TYPE_ARGUMENTS, sequence(comma(), space()), token(LT), token(GT)), |
441 | conditional(ObservableProperty.TYPE_ARGUMENTS, IS_NOT_EMPTY, space()), |
442 | child(ObservableProperty.TYPE), |
443 | token(GeneratedJavaParserConstants.LPAREN), |
444 | list(ObservableProperty.ARGUMENTS, sequence(comma(), space()), none(), none()), |
445 | token(GeneratedJavaParserConstants.RPAREN), |
446 | conditional(ObservableProperty.ANONYMOUS_CLASS_BODY, IS_PRESENT, |
447 | sequence( |
448 | space(), token(LBRACE), newline(), indent(), |
449 | list(ObservableProperty.ANONYMOUS_CLASS_BODY, |
450 | newline(), |
451 | newline(), |
452 | newline(), |
453 | newline()), |
454 | unindent(), |
455 | token(RBRACE) |
456 | )) |
457 | )); |
458 | |
459 | concreteSyntaxModelByClass.put(SimpleName.class, attribute(ObservableProperty.IDENTIFIER)); |
460 | |
461 | concreteSyntaxModelByClass.put(SingleMemberAnnotationExpr.class, sequence( |
462 | comment(), |
463 | token(GeneratedJavaParserConstants.AT), |
464 | child(ObservableProperty.NAME), |
465 | token(GeneratedJavaParserConstants.LPAREN), |
466 | child(ObservableProperty.MEMBER_VALUE), |
467 | token(GeneratedJavaParserConstants.RPAREN))); |
468 | |
469 | concreteSyntaxModelByClass.put(StringLiteralExpr.class, sequence( |
470 | comment(), |
471 | stringToken(ObservableProperty.VALUE) |
472 | )); |
473 | |
474 | concreteSyntaxModelByClass.put(TextBlockLiteralExpr.class, sequence( |
475 | comment(), |
476 | textBlockToken(ObservableProperty.VALUE) |
477 | )); |
478 | |
479 | concreteSyntaxModelByClass.put(SuperExpr.class, sequence( |
480 | comment(), |
481 | conditional(TYPE_NAME, IS_PRESENT, sequence(child(TYPE_NAME), token(GeneratedJavaParserConstants.DOT))), |
482 | token(GeneratedJavaParserConstants.SUPER) |
483 | )); |
484 | |
485 | concreteSyntaxModelByClass.put(ThisExpr.class, sequence( |
486 | comment(), |
487 | conditional(TYPE_NAME, IS_PRESENT, sequence(child(TYPE_NAME), token(GeneratedJavaParserConstants.DOT))), |
488 | token(GeneratedJavaParserConstants.THIS) |
489 | )); |
490 | |
491 | concreteSyntaxModelByClass.put(TypeExpr.class, sequence( |
492 | comment(), |
493 | child(ObservableProperty.TYPE) |
494 | )); |
495 | |
496 | concreteSyntaxModelByClass.put(UnaryExpr.class, sequence( |
497 | conditional(ObservableProperty.PREFIX, FLAG, attribute(ObservableProperty.OPERATOR)), |
498 | child(ObservableProperty.EXPRESSION), |
499 | conditional(ObservableProperty.POSTFIX, FLAG, attribute(ObservableProperty.OPERATOR)) |
500 | )); |
501 | |
502 | concreteSyntaxModelByClass.put(VariableDeclarationExpr.class, sequence( |
503 | comment(), |
504 | list(ObservableProperty.ANNOTATIONS, space(), none(), space()), |
505 | modifiers(), |
506 | child(ObservableProperty.MAXIMUM_COMMON_TYPE), |
507 | space(), |
508 | list(ObservableProperty.VARIABLES, sequence(comma(), space())) |
509 | )); |
510 | |
511 | /// |
512 | /// Statements |
513 | /// |
514 | |
515 | concreteSyntaxModelByClass.put(AssertStmt.class, sequence( |
516 | comment(), |
517 | token(GeneratedJavaParserConstants.ASSERT), |
518 | space(), |
519 | child(ObservableProperty.CHECK), |
520 | conditional(ObservableProperty.MESSAGE, IS_PRESENT, sequence( |
521 | space(), |
522 | token(GeneratedJavaParserConstants.COLON), |
523 | space(), |
524 | child(ObservableProperty.MESSAGE) |
525 | )), |
526 | semicolon() |
527 | )); |
528 | |
529 | concreteSyntaxModelByClass.put(BlockStmt.class, sequence( |
530 | orphanCommentsBeforeThis(), |
531 | comment(), |
532 | token(GeneratedJavaParserConstants.LBRACE), |
533 | newline(), |
534 | list(ObservableProperty.STATEMENTS, newline(), indent(), sequence(newline(), unindent())), |
535 | orphanCommentsEnding(), |
536 | token(RBRACE) |
537 | )); |
538 | |
539 | concreteSyntaxModelByClass.put(BreakStmt.class, sequence( |
540 | comment(), |
541 | token(GeneratedJavaParserConstants.BREAK), |
542 | conditional(ObservableProperty.LABEL, IS_PRESENT, sequence(space(), child(ObservableProperty.LABEL))), |
543 | semicolon() |
544 | )); |
545 | |
546 | concreteSyntaxModelByClass.put(CatchClause.class, sequence( |
547 | comment(), |
548 | space(), |
549 | token(GeneratedJavaParserConstants.CATCH), |
550 | space(), |
551 | token(LPAREN), |
552 | child(ObservableProperty.PARAMETER), |
553 | token(RPAREN), |
554 | space(), |
555 | child(BODY) |
556 | )); |
557 | |
558 | concreteSyntaxModelByClass.put(ContinueStmt.class, sequence( |
559 | comment(), |
560 | token(GeneratedJavaParserConstants.CONTINUE), |
561 | conditional(ObservableProperty.LABEL, IS_PRESENT, sequence(space(), child(ObservableProperty.LABEL))), |
562 | semicolon() |
563 | )); |
564 | |
565 | concreteSyntaxModelByClass.put(DoStmt.class, sequence( |
566 | comment(), |
567 | token(GeneratedJavaParserConstants.DO), |
568 | space(), |
569 | child(ObservableProperty.BODY), |
570 | space(), |
571 | token(GeneratedJavaParserConstants.WHILE), |
572 | space(), |
573 | token(GeneratedJavaParserConstants.LPAREN), |
574 | child(ObservableProperty.CONDITION), |
575 | token(GeneratedJavaParserConstants.RPAREN), |
576 | semicolon() |
577 | )); |
578 | |
579 | concreteSyntaxModelByClass.put(EmptyStmt.class, sequence( |
580 | comment(), |
581 | token(GeneratedJavaParserConstants.SEMICOLON) |
582 | )); |
583 | |
584 | concreteSyntaxModelByClass.put(UnparsableStmt.class, sequence( |
585 | comment(), |
586 | token(GeneratedJavaParserConstants.SEMICOLON) |
587 | )); |
588 | |
589 | concreteSyntaxModelByClass.put(ExplicitConstructorInvocationStmt.class, sequence( |
590 | comment(), |
591 | conditional(ObservableProperty.THIS, FLAG, |
592 | sequence(typeArguments(), token(GeneratedJavaParserConstants.THIS)), |
593 | sequence( |
594 | conditional(ObservableProperty.EXPRESSION, IS_PRESENT, sequence(child(ObservableProperty.EXPRESSION), token(GeneratedJavaParserConstants.DOT))), |
595 | typeArguments(), |
596 | token(GeneratedJavaParserConstants.SUPER) |
597 | )), |
598 | token(GeneratedJavaParserConstants.LPAREN), |
599 | list(ObservableProperty.ARGUMENTS, sequence(comma(), space())), |
600 | token(GeneratedJavaParserConstants.RPAREN), |
601 | semicolon() |
602 | )); |
603 | |
604 | concreteSyntaxModelByClass.put(ExpressionStmt.class, sequence( |
605 | orphanCommentsBeforeThis(), |
606 | comment(), |
607 | child(ObservableProperty.EXPRESSION), |
608 | semicolon() |
609 | )); |
610 | |
611 | concreteSyntaxModelByClass.put(ForEachStmt.class, sequence( |
612 | comment(), |
613 | token(GeneratedJavaParserConstants.FOR), |
614 | space(), |
615 | token(GeneratedJavaParserConstants.LPAREN), |
616 | child(ObservableProperty.VARIABLE), |
617 | space(), |
618 | token(GeneratedJavaParserConstants.COLON), |
619 | space(), |
620 | child(ObservableProperty.ITERABLE), |
621 | token(GeneratedJavaParserConstants.RPAREN), |
622 | space(), |
623 | child(ObservableProperty.BODY) |
624 | )); |
625 | |
626 | concreteSyntaxModelByClass.put(ForStmt.class, sequence( |
627 | comment(), |
628 | token(GeneratedJavaParserConstants.FOR), |
629 | space(), |
630 | token(GeneratedJavaParserConstants.LPAREN), |
631 | list(ObservableProperty.INITIALIZATION, sequence(comma(), space())), |
632 | semicolon(), |
633 | space(), |
634 | child(ObservableProperty.COMPARE), |
635 | semicolon(), |
636 | space(), |
637 | list(ObservableProperty.UPDATE, sequence(comma(), space())), |
638 | token(GeneratedJavaParserConstants.RPAREN), |
639 | space(), |
640 | child(ObservableProperty.BODY) |
641 | )); |
642 | |
643 | concreteSyntaxModelByClass.put(IfStmt.class, sequence( |
644 | comment(), |
645 | token(GeneratedJavaParserConstants.IF), |
646 | space(), |
647 | token(GeneratedJavaParserConstants.LPAREN), |
648 | child(ObservableProperty.CONDITION), |
649 | token(GeneratedJavaParserConstants.RPAREN), |
650 | conditional(ObservableProperty.THEN_BLOCK, CsmConditional.Condition.FLAG, |
651 | sequence(space(), child(ObservableProperty.THEN_STMT), |
652 | conditional(ObservableProperty.ELSE_STMT, IS_PRESENT, space())), |
653 | sequence(newline(), indent(), child(ObservableProperty.THEN_STMT), |
654 | conditional(ObservableProperty.ELSE_STMT, IS_PRESENT, newline()), |
655 | unindent())), |
656 | conditional(ObservableProperty.ELSE_STMT, IS_PRESENT, |
657 | sequence(token(GeneratedJavaParserConstants.ELSE), |
658 | conditional(Arrays.asList(ObservableProperty.ELSE_BLOCK, ObservableProperty.CASCADING_IF_STMT), CsmConditional.Condition.FLAG, |
659 | sequence(space(), child(ObservableProperty.ELSE_STMT)), |
660 | sequence(newline(), indent(), child(ObservableProperty.ELSE_STMT), unindent())))) |
661 | )); |
662 | |
663 | concreteSyntaxModelByClass.put(LabeledStmt.class, sequence( |
664 | comment(), |
665 | child(ObservableProperty.LABEL), |
666 | token(GeneratedJavaParserConstants.COLON), |
667 | space(), |
668 | child(ObservableProperty.STATEMENT) |
669 | )); |
670 | |
671 | concreteSyntaxModelByClass.put(LocalClassDeclarationStmt.class, sequence( |
672 | comment(), |
673 | child(ObservableProperty.CLASS_DECLARATION) |
674 | )); |
675 | |
676 | concreteSyntaxModelByClass.put(ReturnStmt.class, sequence( |
677 | comment(), |
678 | token(GeneratedJavaParserConstants.RETURN), |
679 | conditional(ObservableProperty.EXPRESSION, IS_PRESENT, sequence(space(), child(ObservableProperty.EXPRESSION))), |
680 | semicolon())); |
681 | |
682 | concreteSyntaxModelByClass.put(YieldStmt.class, sequence( |
683 | comment(), |
684 | token(YIELD), |
685 | conditional(ObservableProperty.EXPRESSION, IS_PRESENT, sequence(space(), child(ObservableProperty.EXPRESSION))), |
686 | semicolon())); |
687 | |
688 | concreteSyntaxModelByClass.put(SwitchEntry.class, sequence( |
689 | comment(), |
690 | conditional(ObservableProperty.LABELS, IS_NOT_EMPTY, |
691 | sequence(token(GeneratedJavaParserConstants.CASE), space(), list(ObservableProperty.LABELS), token(GeneratedJavaParserConstants.COLON)), |
692 | sequence(token(GeneratedJavaParserConstants._DEFAULT), token(GeneratedJavaParserConstants.COLON))), |
693 | newline(), |
694 | indent(), |
695 | list(ObservableProperty.STATEMENTS, newline(), none(), newline()), |
696 | unindent() |
697 | )); |
698 | |
699 | concreteSyntaxModelByClass.put(SwitchStmt.class, sequence( |
700 | comment(), |
701 | token(GeneratedJavaParserConstants.SWITCH), |
702 | token(GeneratedJavaParserConstants.LPAREN), |
703 | child(ObservableProperty.SELECTOR), |
704 | token(GeneratedJavaParserConstants.RPAREN), |
705 | space(), |
706 | token(GeneratedJavaParserConstants.LBRACE), |
707 | newline(), |
708 | list(ObservableProperty.ENTRIES, none(), indent(), unindent()), |
709 | token(GeneratedJavaParserConstants.RBRACE) |
710 | )); |
711 | |
712 | concreteSyntaxModelByClass.put(SwitchExpr.class, sequence( |
713 | comment(), |
714 | token(GeneratedJavaParserConstants.SWITCH), |
715 | token(GeneratedJavaParserConstants.LPAREN), |
716 | child(ObservableProperty.SELECTOR), |
717 | token(GeneratedJavaParserConstants.RPAREN), |
718 | space(), |
719 | token(GeneratedJavaParserConstants.LBRACE), |
720 | newline(), |
721 | list(ObservableProperty.ENTRIES, none(), indent(), unindent()), |
722 | token(GeneratedJavaParserConstants.RBRACE) |
723 | )); |
724 | |
725 | concreteSyntaxModelByClass.put(SynchronizedStmt.class, sequence( |
726 | comment(), |
727 | token(GeneratedJavaParserConstants.SYNCHRONIZED), |
728 | space(), |
729 | token(LPAREN), |
730 | child(EXPRESSION), |
731 | token(RPAREN), |
732 | space(), |
733 | child(BODY) |
734 | )); |
735 | |
736 | concreteSyntaxModelByClass.put(ThrowStmt.class, sequence( |
737 | comment(), |
738 | token(GeneratedJavaParserConstants.THROW), |
739 | space(), |
740 | child(ObservableProperty.EXPRESSION), |
741 | semicolon() |
742 | )); |
743 | |
744 | concreteSyntaxModelByClass.put(TryStmt.class, sequence( |
745 | comment(), |
746 | token(GeneratedJavaParserConstants.TRY), |
747 | space(), |
748 | conditional(ObservableProperty.RESOURCES, CsmConditional.Condition.IS_NOT_EMPTY, sequence( |
749 | token(LPAREN), |
750 | list(ObservableProperty.RESOURCES, sequence(semicolon(), newline()), indent(), unindent()), |
751 | token(RPAREN), |
752 | space())), |
753 | child(ObservableProperty.TRY_BLOCK), |
754 | list(ObservableProperty.CATCH_CLAUSES), |
755 | conditional(ObservableProperty.FINALLY_BLOCK, IS_PRESENT, sequence(space(), token(GeneratedJavaParserConstants.FINALLY), space(), child(ObservableProperty.FINALLY_BLOCK))) |
756 | )); |
757 | |
758 | concreteSyntaxModelByClass.put(WhileStmt.class, sequence( |
759 | comment(), |
760 | token(GeneratedJavaParserConstants.WHILE), |
761 | space(), |
762 | token(GeneratedJavaParserConstants.LPAREN), |
763 | child(ObservableProperty.CONDITION), |
764 | token(GeneratedJavaParserConstants.RPAREN), |
765 | space(), |
766 | child(ObservableProperty.BODY) |
767 | )); |
768 | |
769 | /// |
770 | /// Types |
771 | /// |
772 | |
773 | concreteSyntaxModelByClass.put(ArrayType.class, sequence( |
774 | child(ObservableProperty.COMPONENT_TYPE), |
775 | list(ObservableProperty.ANNOTATIONS), |
776 | string(GeneratedJavaParserConstants.LBRACKET), |
777 | string(GeneratedJavaParserConstants.RBRACKET))); |
778 | |
779 | concreteSyntaxModelByClass.put(ClassOrInterfaceType.class, sequence(comment(), |
780 | conditional(SCOPE, IS_PRESENT, sequence(child(SCOPE), string(GeneratedJavaParserConstants.DOT))), |
781 | list(ANNOTATIONS, space(), none(), space()), |
782 | child(NAME), |
783 | conditional(ObservableProperty.USING_DIAMOND_OPERATOR, FLAG, |
784 | sequence(string(GeneratedJavaParserConstants.LT), string(GeneratedJavaParserConstants.GT)), |
785 | list(TYPE_ARGUMENTS, sequence(comma(), space()), string(GeneratedJavaParserConstants.LT), string(GeneratedJavaParserConstants.GT))))); |
786 | |
787 | concreteSyntaxModelByClass.put(IntersectionType.class, sequence( |
788 | comment(), |
789 | annotations(), |
790 | list(ObservableProperty.ELEMENTS, sequence(space(), token(GeneratedJavaParserConstants.BIT_AND), space())))); |
791 | |
792 | concreteSyntaxModelByClass.put(PrimitiveType.class, sequence( |
793 | comment(), |
794 | list(ObservableProperty.ANNOTATIONS), |
795 | attribute(ObservableProperty.TYPE))); |
796 | |
797 | concreteSyntaxModelByClass.put(TypeParameter.class, sequence( |
798 | comment(), |
799 | annotations(), |
800 | child(ObservableProperty.NAME), |
801 | list(ObservableProperty.TYPE_BOUND, |
802 | sequence( |
803 | space(), |
804 | token(GeneratedJavaParserConstants.BIT_AND), |
805 | space()), |
806 | sequence( |
807 | space(), |
808 | token(GeneratedJavaParserConstants.EXTENDS), |
809 | space()), |
810 | none()) |
811 | )); |
812 | |
813 | concreteSyntaxModelByClass.put(UnionType.class, sequence( |
814 | comment(), |
815 | annotations(), |
816 | list(ObservableProperty.ELEMENTS, sequence(space(), token(GeneratedJavaParserConstants.BIT_OR), space())) |
817 | )); |
818 | |
819 | concreteSyntaxModelByClass.put(UnknownType.class, none()); |
820 | |
821 | concreteSyntaxModelByClass.put(VoidType.class, sequence(comment(), annotations(), token(GeneratedJavaParserConstants.VOID))); |
822 | |
823 | concreteSyntaxModelByClass.put(VarType.class, sequence(comment(), annotations(), string(GeneratedJavaParserConstants.IDENTIFIER, "var"))); |
824 | |
825 | concreteSyntaxModelByClass.put(WildcardType.class, sequence(comment(), annotations(), token(GeneratedJavaParserConstants.HOOK), |
826 | conditional(ObservableProperty.EXTENDED_TYPE, IS_PRESENT, sequence(space(), token(GeneratedJavaParserConstants.EXTENDS), space(), child(EXTENDED_TYPE))), |
827 | conditional(ObservableProperty.SUPER_TYPE, IS_PRESENT, sequence(space(), token(GeneratedJavaParserConstants.SUPER), space(), child(SUPER_TYPE))))); |
828 | |
829 | /// |
830 | /// Top Level |
831 | /// |
832 | |
833 | concreteSyntaxModelByClass.put(ArrayCreationLevel.class, sequence( |
834 | annotations(), |
835 | token(GeneratedJavaParserConstants.LBRACKET), |
836 | child(ObservableProperty.DIMENSION), |
837 | token(GeneratedJavaParserConstants.RBRACKET) |
838 | )); |
839 | |
840 | concreteSyntaxModelByClass.put(CompilationUnit.class, sequence( |
841 | comment(), |
842 | child(ObservableProperty.PACKAGE_DECLARATION), |
843 | list(ObservableProperty.IMPORTS, newline(), none(), sequence(newline(), newline())), |
844 | list(TYPES, newline(), newline(), none(), newline()), |
845 | child(ObservableProperty.MODULE), |
846 | orphanCommentsEnding())); |
847 | |
848 | concreteSyntaxModelByClass.put(ImportDeclaration.class, sequence( |
849 | comment(), |
850 | token(GeneratedJavaParserConstants.IMPORT), |
851 | space(), |
852 | conditional(ObservableProperty.STATIC, FLAG, sequence(token(GeneratedJavaParserConstants.STATIC), space())), |
853 | child(ObservableProperty.NAME), |
854 | conditional(ASTERISK, FLAG, sequence(token(GeneratedJavaParserConstants.DOT), token(GeneratedJavaParserConstants.STAR))), |
855 | semicolon(), |
856 | orphanCommentsEnding() |
857 | )); |
858 | |
859 | concreteSyntaxModelByClass.put(PackageDeclaration.class, sequence( |
860 | comment(), |
861 | memberAnnotations(), |
862 | token(GeneratedJavaParserConstants.PACKAGE), |
863 | space(), |
864 | child(ObservableProperty.NAME), |
865 | semicolon(), |
866 | newline(), |
867 | newline(), |
868 | orphanCommentsEnding())); |
869 | |
870 | /// |
871 | /// Module info |
872 | /// |
873 | |
874 | concreteSyntaxModelByClass.put(ModuleDeclaration.class, sequence( |
875 | memberAnnotations(), |
876 | conditional(ObservableProperty.OPEN, FLAG, sequence(token(GeneratedJavaParserConstants.OPEN), space())), |
877 | token(GeneratedJavaParserConstants.MODULE), |
878 | space(), |
879 | child(ObservableProperty.NAME), |
880 | space(), |
881 | token(GeneratedJavaParserConstants.LBRACE), |
882 | newline(), |
883 | indent(), |
884 | list(ObservableProperty.DIRECTIVES), |
885 | unindent(), |
886 | token(GeneratedJavaParserConstants.RBRACE), |
887 | newline() |
888 | )); |
889 | |
890 | concreteSyntaxModelByClass.put(ModuleExportsDirective.class, sequence( |
891 | token(GeneratedJavaParserConstants.EXPORTS), |
892 | space(), |
893 | child(ObservableProperty.NAME), |
894 | list(ObservableProperty.MODULE_NAMES, |
895 | sequence(comma(), space()), |
896 | sequence(space(), token(GeneratedJavaParserConstants.TO), space()), |
897 | none()), |
898 | semicolon(), |
899 | newline() |
900 | )); |
901 | |
902 | concreteSyntaxModelByClass.put(ModuleOpensDirective.class, sequence( |
903 | token(GeneratedJavaParserConstants.OPENS), |
904 | space(), |
905 | child(ObservableProperty.NAME), |
906 | list(ObservableProperty.MODULE_NAMES, |
907 | sequence(comma(), space()), |
908 | sequence(space(), token(GeneratedJavaParserConstants.TO), space()), |
909 | none()), |
910 | semicolon(), |
911 | newline() |
912 | )); |
913 | |
914 | concreteSyntaxModelByClass.put(ModuleProvidesDirective.class, sequence( |
915 | token(GeneratedJavaParserConstants.PROVIDES), |
916 | space(), |
917 | child(ObservableProperty.NAME), |
918 | list(ObservableProperty.WITH, |
919 | sequence(comma(), space()), |
920 | sequence(space(), token(GeneratedJavaParserConstants.WITH), space()), |
921 | none()), |
922 | semicolon(), |
923 | newline() |
924 | )); |
925 | |
926 | concreteSyntaxModelByClass.put(ModuleRequiresDirective.class, sequence( |
927 | token(GeneratedJavaParserConstants.REQUIRES), |
928 | space(), |
929 | modifiers(), |
930 | child(ObservableProperty.NAME), |
931 | semicolon(), |
932 | newline() |
933 | )); |
934 | |
935 | concreteSyntaxModelByClass.put(ModuleUsesDirective.class, sequence( |
936 | token(GeneratedJavaParserConstants.USES), |
937 | space(), |
938 | child(ObservableProperty.NAME), |
939 | semicolon(), |
940 | newline() |
941 | )); |
942 | |
943 | List<String> unsupportedNodeClassNames = JavaParserMetaModel.getNodeMetaModels().stream() |
944 | .filter(c -> !c.isAbstract() && !Comment.class.isAssignableFrom(c.getType()) && !concreteSyntaxModelByClass.containsKey(c.getType())) |
945 | .map(nm -> nm.getType().getSimpleName()) |
946 | .collect(Collectors.toList()); |
947 | if (unsupportedNodeClassNames.isEmpty()) { |
948 | initializationError = Optional.empty(); |
949 | } else { |
950 | initializationError = Optional.of("The " + ConcreteSyntaxModel.class.getSimpleName() + " should include support for these classes: " + String.join(", ", unsupportedNodeClassNames)); |
951 | } |
952 | } |
953 | |
954 | private ConcreteSyntaxModel() { |
955 | |
956 | } |
957 | |
958 | public static void genericPrettyPrint(Node node, SourcePrinter printer) { |
959 | forClass(node.getClass()).prettyPrint(node, printer); |
960 | } |
961 | |
962 | public static String genericPrettyPrint(Node node) { |
963 | SourcePrinter sourcePrinter = new SourcePrinter(); |
964 | forClass(node.getClass()).prettyPrint(node, sourcePrinter); |
965 | return sourcePrinter.toString(); |
966 | } |
967 | |
968 | public static CsmElement forClass(Class<? extends Node> nodeClazz) { |
969 | initializationError.ifPresent(s -> { |
970 | throw new IllegalStateException(s); |
971 | }); |
972 | if (!concreteSyntaxModelByClass.containsKey(nodeClazz)) { |
973 | throw new UnsupportedOperationException(nodeClazz.getSimpleName()); |
974 | } |
975 | return concreteSyntaxModelByClass.get(nodeClazz); |
976 | } |
977 | |
978 | } |
979 |
Members