1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package uk.co.badgersinfoil.metaas.impl;
20
21 import java.util.List;
22 import org.asdt.core.internal.antlr.AS3Parser;
23 import uk.co.badgersinfoil.metaas.ActionScriptFactory;
24 import uk.co.badgersinfoil.metaas.SyntaxException;
25 import uk.co.badgersinfoil.metaas.dom.ASAssignmentExpression;
26 import uk.co.badgersinfoil.metaas.dom.ASBinaryExpression;
27 import uk.co.badgersinfoil.metaas.dom.ASCompilationUnit;
28 import uk.co.badgersinfoil.metaas.dom.Expression;
29 import uk.co.badgersinfoil.metaas.dom.Visibility;
30 import uk.co.badgersinfoil.metaas.impl.antlr.LinkedListToken;
31 import uk.co.badgersinfoil.metaas.impl.antlr.LinkedListTree;
32
33
34
35
36
37
38 public class ASTBuilder {
39
40 private ASTBuilder() {
41
42 }
43
44 public static LinkedListTree newExprStmt(LinkedListTree expr) {
45 LinkedListTree exprStmt = ASTUtils.newImaginaryAST(AS3Parser.EXPR_STMNT);
46 exprStmt.addChildWithTokens(expr);
47 exprStmt.appendToken(TokenBuilder.newSemi());
48 return exprStmt;
49 }
50
51 public static AS3ASTCompilationUnit synthesizeClass(String qualifiedName) {
52 LinkedListTree unit = ASTUtils.newImaginaryAST(AS3Parser.COMPILATION_UNIT);
53 LinkedListTree pkg = ASTUtils.newAST(AS3Parser.PACKAGE, "package");
54 pkg.appendToken(TokenBuilder.newSpace());
55 unit.addChildWithTokens(pkg);
56 pkg.appendToken(TokenBuilder.newSpace());
57 String packageName = packageNameFrom(qualifiedName);
58 if (packageName != null) {
59 pkg.addChildWithTokens(AS3FragmentParser.parseIdent(packageName));
60 }
61 LinkedListTree packageBlock = newBlock();
62 pkg.addChildWithTokens(packageBlock);
63 String className = typeNameFrom(qualifiedName);
64
65 LinkedListTree clazz = synthesizeAS3Class(className);
66 ASTUtils.addChildWithIndentation(packageBlock, clazz);
67 return new AS3ASTCompilationUnit(unit);
68 }
69
70 public static ASCompilationUnit synthesizeInterface(String qualifiedName) {
71 LinkedListTree unit = ASTUtils.newImaginaryAST(AS3Parser.COMPILATION_UNIT);
72 LinkedListTree pkg = ASTUtils.newAST(AS3Parser.PACKAGE, "package");
73 unit.addChildWithTokens(pkg);
74 pkg.appendToken(TokenBuilder.newSpace());
75 String packageName = packageNameFrom(qualifiedName);
76 if (packageName != null) {
77 pkg.addChildWithTokens(AS3FragmentParser.parseIdent(packageName));
78 }
79 LinkedListTree packageBlock = newBlock();
80 pkg.addChildWithTokens(packageBlock);
81
82 LinkedListTree iface = synthesizeAS3Interface(qualifiedName);
83 ASTUtils.addChildWithIndentation(packageBlock, iface);
84 return new AS3ASTCompilationUnit(unit);
85 }
86
87 private static LinkedListTree synthesizeAS3Interface(String qualifiedName) {
88 LinkedListTree iface = ASTUtils.newImaginaryAST(AS3Parser.INTERFACE_DEF);
89 LinkedListTree modifiers = ASTUtils.newImaginaryAST(AS3Parser.MODIFIERS);
90 iface.addChildWithTokens(modifiers);
91 modifiers.addChildWithTokens(ASTUtils.newAST(AS3Parser.PUBLIC, "public"));
92 modifiers.appendToken(TokenBuilder.newSpace());
93 iface.appendToken(TokenBuilder.newInterface());
94 iface.appendToken(TokenBuilder.newSpace());
95 iface.addChildWithTokens(ASTUtils.newAST(AS3Parser.IDENT, typeNameFrom(qualifiedName)));
96 iface.appendToken(TokenBuilder.newSpace());
97 iface.addChildWithTokens(newTypeBlock());
98 LinkedListTree annos = ASTUtils.newPlaceholderAST(AS3Parser.ANNOTATIONS);
99 iface.addChildWithTokens(0, annos);
100 return iface;
101 }
102
103 private static String typeNameFrom(String qualifiedName) {
104 int p = qualifiedName.lastIndexOf('.');
105 if (p == -1) {
106 return qualifiedName;
107 }
108 return qualifiedName.substring(p+1);
109 }
110
111 private static LinkedListTree synthesizeAS3Class(String className) {
112 LinkedListTree clazz = ASTUtils.newImaginaryAST(AS3Parser.CLASS_DEF);
113 LinkedListTree modifiers = ASTUtils.newImaginaryAST(AS3Parser.MODIFIERS);
114 clazz.addChildWithTokens(modifiers);
115 LinkedListTree modPublic = ASTUtils.newAST(AS3Parser.PUBLIC, "public");
116 modifiers.addChildWithTokens(modPublic);
117 modifiers.appendToken(TokenBuilder.newSpace());
118 clazz.appendToken(TokenBuilder.newClass());
119 clazz.appendToken(TokenBuilder.newSpace());
120 clazz.addChildWithTokens(ASTUtils.newAST(AS3Parser.IDENT, className));
121 clazz.appendToken(TokenBuilder.newSpace());
122 clazz.addChildWithTokens(newTypeBlock());
123 LinkedListTree annos = ASTUtils.newPlaceholderAST(AS3Parser.ANNOTATIONS);
124 clazz.addChildWithTokens(0, annos);
125 return clazz;
126 }
127
128 private static String packageNameFrom(String qualifiedName) {
129 int p = qualifiedName.lastIndexOf('.');
130 if (p == -1) {
131 return null;
132 }
133 return qualifiedName.substring(0, p);
134 }
135
136 public static ASTASMethod newClassMethod(String name, Visibility visibility, String returnType) {
137 LinkedListTree def = ASTUtils.newImaginaryAST(AS3Parser.METHOD_DEF);
138 LinkedListTree annos = ASTUtils.newPlaceholderAST(AS3Parser.ANNOTATIONS);
139 def.addChildWithTokens(annos);
140 def.addChildWithTokens(ModifierUtils.toModifiers(visibility));
141 def.appendToken(TokenBuilder.newFunction());
142 def.appendToken(TokenBuilder.newSpace());
143 LinkedListTree acc = ASTUtils.newPlaceholderAST(AS3Parser.ACCESSOR_ROLE);
144 def.addChildWithTokens(acc);
145 LinkedListTree methName = ASTUtils.newAST(AS3Parser.IDENT, name);
146 def.addChildWithTokens(methName);
147 def.addChildWithTokens(ASTUtils.newParentheticAST(AS3Parser.PARAMS, AS3Parser.LPAREN, "(", AS3Parser.RPAREN, ")"));
148 if (returnType != null) {
149 def.addChildWithTokens(AS3FragmentParser.parseTypeSpec(returnType));
150 }
151 def.appendToken(TokenBuilder.newSpace());
152 LinkedListTree block = newBlock();
153 def.addChildWithTokens(block);
154
155 return new ASTASMethod(def);
156 }
157
158 public static ASTASField newField(String name, Visibility visibility, String type) {
159 if (name.indexOf('.') != -1) {
160 throw new SyntaxException("field name must not contain '.'");
161 }
162 LinkedListTree decl = ASTUtils.newImaginaryAST(AS3Parser.VAR_DEF);
163 LinkedListTree annos = ASTUtils.newPlaceholderAST(AS3Parser.ANNOTATIONS);
164 decl.addChildWithTokens(annos);
165 decl.addChildWithTokens(ModifierUtils.toModifiers(visibility));
166 decl.addChildWithTokens(ASTUtils.newAST(AS3Parser.VAR, "var"));
167 decl.appendToken(TokenBuilder.newSpace());
168 LinkedListTree def = ASTUtils.newAST(AS3Parser.IDENT, name);
169 decl.addChildWithTokens(def);
170 if (type != null) {
171 def.addChildWithTokens(AS3FragmentParser.parseTypeSpec(type));
172 }
173 decl.appendToken(TokenBuilder.newSemi());
174 return new ASTASField(decl);
175 }
176
177 public static ASTASMethod newInterfaceMethod(String name, Visibility visibility, String returnType) {
178 LinkedListTree def = ASTUtils.newImaginaryAST(AS3Parser.METHOD_DEF);
179 LinkedListTree annos = ASTUtils.newPlaceholderAST(AS3Parser.ANNOTATIONS);
180 def.addChildWithTokens(annos);
181 def.addChildWithTokens(ModifierUtils.toModifiers(visibility));
182 def.appendToken(TokenBuilder.newFunction());
183 def.appendToken(TokenBuilder.newSpace());
184 LinkedListTree acc = ASTUtils.newPlaceholderAST(AS3Parser.ACCESSOR_ROLE);
185 def.addChildWithTokens(acc);
186 LinkedListTree methName = ASTUtils.newAST(AS3Parser.IDENT, name);
187 def.addChildWithTokens(methName);
188 def.addChildWithTokens(ASTUtils.newParentheticAST(AS3Parser.PARAMS, AS3Parser.LPAREN, "(", AS3Parser.RPAREN, ")"));
189 if (returnType != null) {
190 def.addChildWithTokens(AS3FragmentParser.parseTypeSpec(returnType));
191 }
192 def.appendToken(TokenBuilder.newSemi());
193
194 return new ASTASMethod(def);
195 }
196
197 public static LinkedListTree newBlock() {
198 return newBlock(AS3Parser.BLOCK);
199 }
200
201 public static LinkedListTree newTypeBlock() {
202 return newBlock(AS3Parser.TYPE_BLOCK);
203 }
204
205 private static LinkedListTree newBlock(int type) {
206 LinkedListTree ast = ASTUtils.newParentheticAST(type,
207 AS3Parser.LCURLY, "{",
208 AS3Parser.RCURLY, "}");
209 LinkedListToken nl = TokenBuilder.newNewline();
210 ast.getInitialInsertionAfter().afterInsert(nl);
211 ast.setInitialInsertionAfter(nl);
212 return ast;
213 }
214
215 public static LinkedListTree newMetadataTag(String name) {
216 LinkedListTree ast = ASTUtils.newParentheticAST(AS3Parser.ANNOTATION,
217 AS3Parser.LBRACK, "[",
218 AS3Parser.RBRACK, "]");
219 ast.addChildWithTokens(ASTUtils.newAST(AS3Parser.IDENT, name));
220 return ast;
221 }
222
223
224
225
226 private static LinkedListTree condition(LinkedListTree expr) {
227 LinkedListTree cond = ASTUtils.newParentheticAST(AS3Parser.CONDITION,
228 AS3Parser.LPAREN, "(",
229 AS3Parser.RPAREN, ")");
230 cond.addChildWithTokens(expr);
231 return cond;
232 }
233
234 public static LinkedListTree newIf(String condition) {
235 return newIf(AS3FragmentParser.parseExpr(condition));
236 }
237 public static LinkedListTree newIf(LinkedListTree condition) {
238 LinkedListTree ifStmt = ASTUtils.newAST(AS3Parser.IF, "if");
239 ifStmt.appendToken(TokenBuilder.newSpace());
240 ifStmt.addChildWithTokens(condition(condition));
241 ifStmt.appendToken(TokenBuilder.newSpace());
242 ifStmt.addChildWithTokens(ASTBuilder.newBlock());
243 return ifStmt;
244 }
245
246 public static LinkedListTree newFor(String init, String condition, String iterate) {
247 return newFor(init==null ? null : AS3FragmentParser.parseForInit(init),
248 condition==null ? null : AS3FragmentParser.parseForCond(condition),
249 iterate==null ? null : AS3FragmentParser.parseForIter(iterate));
250 }
251 public static LinkedListTree newFor(LinkedListTree init, LinkedListTree condition, LinkedListTree iterate) {
252 LinkedListTree forStmt = ASTUtils.newAST(AS3Parser.FOR, "for");
253 forStmt.appendToken(TokenBuilder.newSpace());
254 forStmt.appendToken(TokenBuilder.newLParen());
255 if (init != null) {
256 forStmt.addChildWithTokens(init);
257 } else {
258 LinkedListTree initStmt = ASTUtils.newPlaceholderAST(AS3Parser.FOR_INIT);
259 forStmt.addChildWithTokens(initStmt);
260 }
261 forStmt.appendToken(TokenBuilder.newSemi());
262 forStmt.appendToken(TokenBuilder.newSpace());
263 if (condition != null) {
264 forStmt.addChildWithTokens(condition);
265 } else {
266 LinkedListTree condStmt = ASTUtils.newPlaceholderAST(AS3Parser.FOR_CONDITION);
267 forStmt.addChildWithTokens(condStmt);
268 }
269 forStmt.appendToken(TokenBuilder.newSemi());
270 forStmt.appendToken(TokenBuilder.newSpace());
271 if (iterate != null) {
272 forStmt.addChildWithTokens(iterate);
273 } else {
274 LinkedListTree iterStmt = ASTUtils.newPlaceholderAST(AS3Parser.FOR_ITERATOR);
275 forStmt.addChildWithTokens(iterStmt);
276 }
277 forStmt.appendToken(TokenBuilder.newRParen());
278 return forStmt;
279 }
280
281 public static LinkedListTree newForIn(String declaration, String expression) {
282 return newForIn(AS3FragmentParser.parseForInVar(declaration),
283 AS3FragmentParser.parseExpr(expression));
284 }
285 public static LinkedListTree newForIn(LinkedListTree declaration, LinkedListTree expression) {
286 LinkedListTree forStmt = ASTUtils.newAST(AS3Parser.FOR_IN, "for");
287 forStmt.appendToken(TokenBuilder.newSpace());
288 genForInSetup(forStmt, declaration, expression);
289 return forStmt;
290 }
291
292 public static LinkedListTree newForEachIn(String declaration, String expression) {
293 return newForEachIn(AS3FragmentParser.parseForInVar(declaration),
294 AS3FragmentParser.parseExpr(expression));
295 }
296 public static LinkedListTree newForEachIn(LinkedListTree declaration, LinkedListTree expression) {
297 LinkedListTree forStmt = ASTUtils.newAST(AS3Parser.FOR_EACH, "for");
298 forStmt.appendToken(TokenBuilder.newSpace());
299 forStmt.appendToken(TokenBuilder.newEach());
300 genForInSetup(forStmt, declaration, expression);
301 return forStmt;
302 }
303
304
305
306
307 private static void genForInSetup(LinkedListTree forStmt,
308 LinkedListTree declaration,
309 LinkedListTree expression)
310 {
311 forStmt.appendToken(TokenBuilder.newLParen());
312 forStmt.addChildWithTokens(declaration);
313 forStmt.appendToken(TokenBuilder.newSpace());
314 forStmt.appendToken(TokenBuilder.newIn());
315 forStmt.appendToken(TokenBuilder.newSpace());
316 forStmt.addChildWithTokens(expression);
317 forStmt.appendToken(TokenBuilder.newRParen());
318 }
319
320 public static LinkedListTree newWhile(String condition) {
321 return newWhile(AS3FragmentParser.parseExpr(condition));
322 }
323 public static LinkedListTree newWhile(LinkedListTree condition) {
324 LinkedListTree whileStmt = ASTUtils.newAST(AS3Parser.WHILE, "while");
325 whileStmt.appendToken(TokenBuilder.newSpace());
326 whileStmt.addChildWithTokens(condition(condition));
327 return whileStmt;
328 }
329
330 public static LinkedListTree newDoWhile(String condition) {
331 return newDoWhile(AS3FragmentParser.parseExpr(condition));
332 }
333 public static LinkedListTree newDoWhile(LinkedListTree condition) {
334 LinkedListTree doWhileStmt = ASTUtils.newAST(AS3Parser.DO, "do");
335 doWhileStmt.appendToken(TokenBuilder.newSpace());
336 LinkedListTree block = ASTBuilder.newBlock();
337 doWhileStmt.addChildWithTokens(block);
338 doWhileStmt.appendToken(TokenBuilder.newSpace());
339 doWhileStmt.appendToken(TokenBuilder.newWhile());
340 doWhileStmt.appendToken(TokenBuilder.newSpace());
341 doWhileStmt.addChildWithTokens(condition(condition));
342 doWhileStmt.appendToken(TokenBuilder.newSemi());
343 return doWhileStmt;
344 }
345
346 public static LinkedListTree newSwitch(String condition) {
347 return newSwitch(AS3FragmentParser.parseExpr(condition));
348 }
349 public static LinkedListTree newSwitch(LinkedListTree condition) {
350 LinkedListTree switchStmt = ASTUtils.newAST(AS3Parser.SWITCH, "switch");
351 switchStmt.appendToken(TokenBuilder.newSpace());
352 switchStmt.addChildWithTokens(condition(condition));
353 switchStmt.appendToken(TokenBuilder.newSpace());
354 LinkedListTree block = ASTBuilder.newBlock();
355 switchStmt.addChildWithTokens(block);
356 return switchStmt;
357 }
358
359 public static LinkedListTree newWith(String expr) {
360 return newWith(AS3FragmentParser.parseExpr(expr));
361 }
362 public static LinkedListTree newWith(LinkedListTree expr) {
363 LinkedListTree withStmt = ASTUtils.newAST(AS3Parser.WITH, "with");
364 withStmt.appendToken(TokenBuilder.newSpace());
365 withStmt.addChildWithTokens(condition(expr));
366 return withStmt;
367 }
368
369 public static LinkedListTree newDeclaration(String assignment) {
370 return newDeclaration(AS3FragmentParser.parseVariableDeclarator(assignment));
371 }
372 public static LinkedListTree newDeclaration(LinkedListTree assignment) {
373 LinkedListTree declStmt = ASTUtils.newAST(AS3Parser.VAR, "var");
374 declStmt.appendToken(TokenBuilder.newSpace());
375 declStmt.addChildWithTokens(assignment);
376 declStmt.appendToken(TokenBuilder.newSemi());
377 return declStmt;
378 }
379
380 public static LinkedListTree newReturn(String expr) {
381 return newReturn(expr==null ? null : AS3FragmentParser.parseExpr(expr));
382 }
383 public static LinkedListTree newReturn(LinkedListTree expr) {
384 LinkedListTree returnStmt = ASTUtils.newAST(AS3Parser.RETURN, "return");
385 if (expr != null) {
386 returnStmt.appendToken(TokenBuilder.newSpace());
387 returnStmt.addChildWithTokens(expr);
388 }
389 returnStmt.appendToken(TokenBuilder.newSemi());
390 return returnStmt;
391 }
392
393
394
395
396 public static LinkedListTree newSuperStatement(List args) {
397 LinkedListTree superStmt = ASTUtils.newAST(AS3Parser.SUPER, "super");
398 LinkedListTree argumentsNode = ASTUtils.newParentheticAST(AS3Parser.ARGUMENTS, AS3Parser.LPAREN, "(", AS3Parser.RPAREN, ")");
399 ArgumentUtils.overwriteArgsWithExpressionList(argumentsNode, args);
400 superStmt.addChildWithTokens(argumentsNode);
401 superStmt.appendToken(TokenBuilder.newSemi());
402 return superStmt;
403 }
404
405 public static LinkedListTree newBreakStatement() {
406 LinkedListTree breakStmt = ASTUtils.newAST(AS3Parser.BREAK, "break");
407 breakStmt.appendToken(TokenBuilder.newSemi());
408 return breakStmt;
409 }
410
411 public static LinkedListTree newTryStatement() {
412 LinkedListTree tryStmt = ASTUtils.newAST(AS3Parser.TRY, "try");
413 tryStmt.appendToken(TokenBuilder.newSpace());
414 tryStmt.addChildWithTokens(newBlock());
415 return tryStmt;
416 }
417
418 public static LinkedListTree newCatchClause(String var, String type) {
419 LinkedListTree tryStmt = ASTUtils.newAST(AS3Parser.CATCH, "catch");
420 tryStmt.appendToken(TokenBuilder.newSpace());
421 tryStmt.appendToken(TokenBuilder.newLParen());
422 tryStmt.addChildWithTokens(AS3FragmentParser.parseSimpleIdent(var));
423 if (type != null) {
424 tryStmt.addChildWithTokens(AS3FragmentParser.parseTypeSpec(type));
425 }
426 tryStmt.appendToken(TokenBuilder.newRParen());
427 tryStmt.appendToken(TokenBuilder.newSpace());
428 tryStmt.addChildWithTokens(newBlock());
429 return tryStmt;
430 }
431
432 public static LinkedListTree newFinallyClause() {
433 LinkedListTree tryStmt = ASTUtils.newAST(AS3Parser.FINALLY, "finally");
434 tryStmt.appendToken(TokenBuilder.newSpace());
435 tryStmt.addChildWithTokens(newBlock());
436 return tryStmt;
437 }
438
439 public static LinkedListTree newContinueStatement() {
440 LinkedListTree continueStmt = ASTUtils.newAST(AS3Parser.CONTINUE, "continue");
441 continueStmt.appendToken(TokenBuilder.newSemi());
442 return continueStmt;
443 }
444
445 public static ASBinaryExpression newBinaryExpression(LinkedListToken op, Expression left, Expression right) {
446 LinkedListTree ast = ASTUtils.newAST(op);
447 LinkedListTree leftExpr = ((ASTExpression)left).getAST();
448 assertNoParent("left-hand expression", leftExpr);
449 LinkedListTree rightExpr = ((ASTExpression)right).getAST();
450 if (precidence(ast) < precidence(leftExpr)) {
451 leftExpr = parenthise(leftExpr);
452 }
453 if (precidence(ast) < precidence(rightExpr)) {
454 rightExpr = parenthise(rightExpr);
455 }
456
457 ast.addChild(leftExpr);
458 ast.addChild(rightExpr);
459 leftExpr.getStopToken().setNext(op);
460 rightExpr.getStartToken().setPrev(op);
461 ast.setStartToken(leftExpr.getStartToken());
462 ast.setStopToken(rightExpr.getStopToken());
463 spaceEitherSide(op);
464 return new ASTASBinaryExpression(ast);
465 }
466
467 public static ASAssignmentExpression newAssignExpression(LinkedListToken op, Expression left, Expression right) {
468 LinkedListTree ast = ASTUtils.newAST(op);
469 LinkedListTree leftExpr = ((ASTExpression)left).getAST();
470 assertNoParent("left-hand expression", leftExpr);
471 LinkedListTree rightExpr = ((ASTExpression)right).getAST();
472 if (precidence(ast) < precidence(leftExpr)) {
473 leftExpr = parenthise(leftExpr);
474 }
475 if (precidence(ast) < precidence(rightExpr)) {
476 rightExpr = parenthise(rightExpr);
477 }
478
479 ast.addChild(leftExpr);
480 ast.addChild(rightExpr);
481 leftExpr.getStopToken().setNext(op);
482 rightExpr.getStartToken().setPrev(op);
483 ast.setStartToken(leftExpr.getStartToken());
484 ast.setStopToken(rightExpr.getStopToken());
485 spaceEitherSide(op);
486 return new ASTASAssignmentExpression(ast);
487 }
488
489 public static void assertNoParent(String astDescription, LinkedListTree ast)
490 {
491 if (ast.getParent() != null) {
492 throw new SyntaxException(astDescription+" cannot be added to a second parent node");
493 }
494 }
495
496 private static LinkedListTree parenthise(LinkedListTree expr) {
497 LinkedListTree result = ASTUtils.newParentheticAST(AS3Parser.ENCPS_EXPR, AS3Parser.LPAREN, "(", AS3Parser.RPAREN, ")");
498 result.addChildWithTokens(expr);
499 return result;
500 }
501
502 private static int precidence(LinkedListTree ast) {
503 switch (ast.getType()) {
504 case AS3Parser.ASSIGN:
505 case AS3Parser.STAR_ASSIGN:
506 case AS3Parser.DIV_ASSIGN:
507 case AS3Parser.MOD_ASSIGN:
508 case AS3Parser.PLUS_ASSIGN:
509 case AS3Parser.MINUS_ASSIGN:
510 case AS3Parser.SL_ASSIGN:
511 case AS3Parser.SR_ASSIGN:
512 case AS3Parser.BSR_ASSIGN:
513 case AS3Parser.BAND_ASSIGN:
514 case AS3Parser.BXOR_ASSIGN:
515 case AS3Parser.BOR_ASSIGN:
516 case AS3Parser.LAND_ASSIGN:
517 case AS3Parser.LOR_ASSIGN:
518 return 13;
519 case AS3Parser.QUESTION:
520 return 12;
521 case AS3Parser.LOR:
522 return 11;
523 case AS3Parser.LAND:
524 return 10;
525 case AS3Parser.BOR:
526 return 9;
527 case AS3Parser.BXOR:
528 return 8;
529 case AS3Parser.BAND:
530 return 7;
531 case AS3Parser.STRICT_EQUAL:
532 case AS3Parser.STRICT_NOT_EQUAL:
533 case AS3Parser.NOT_EQUAL:
534 case AS3Parser.EQUAL:
535 return 6;
536 case AS3Parser.IN:
537 case AS3Parser.LT:
538 case AS3Parser.GT:
539 case AS3Parser.LE:
540 case AS3Parser.GE:
541 case AS3Parser.IS:
542 case AS3Parser.AS:
543 case AS3Parser.INSTANCEOF:
544 return 5;
545 case AS3Parser.SL:
546 case AS3Parser.SR:
547 case AS3Parser.BSR:
548 return 4;
549 case AS3Parser.PLUS:
550 case AS3Parser.MINUS:
551 return 3;
552 case AS3Parser.STAR:
553 case AS3Parser.DIV:
554 case AS3Parser.MOD:
555 return 2;
556 default:
557 return 1;
558 }
559 }
560
561 public static LinkedListTree newFieldAccessExpression(LinkedListTree target, LinkedListTree name) {
562 LinkedListToken op = TokenBuilder.newDot();
563 LinkedListTree ast = ASTUtils.newAST(op);
564 assertNoParent("target expression", target);
565
566 ast.addChild(target);
567 ast.addChild(name);
568 target.getStopToken().setNext(op);
569 name.getStartToken().setPrev(op);
570 ast.setStartToken(target.getStartToken());
571 ast.setStopToken(name.getStopToken());
572 return ast;
573 }
574
575 public static LinkedListTree newConditionalExpression(LinkedListTree conditionExpr,
576 LinkedListTree thenExpr,
577 LinkedListTree elseExpr)
578 {
579 LinkedListToken op = TokenBuilder.newQuestion();
580 LinkedListToken colon = TokenBuilder.newColon();
581 LinkedListTree ast = ASTUtils.newAST(op);
582
583 ast.addChild(conditionExpr);
584 conditionExpr.getStopToken().setNext(op);
585 ast.addChild(thenExpr);
586 thenExpr.getStartToken().setPrev(op);
587 thenExpr.getStopToken().setNext(colon);
588 ast.addChild(elseExpr);
589 elseExpr.getStartToken().setPrev(colon);
590 ast.setStartToken(conditionExpr.getStartToken());
591 ast.setStopToken(elseExpr.getStopToken());
592 spaceEitherSide(op);
593 spaceEitherSide(colon);
594 return ast;
595 }
596
597 private static void spaceEitherSide(LinkedListToken token) {
598 token.beforeInsert(TokenBuilder.newSpace());
599 token.afterInsert(TokenBuilder.newSpace());
600 }
601
602 public static LinkedListTree newFunctionExpression() {
603 LinkedListTree def = ASTUtils.newImaginaryAST(AS3Parser.FUNC_DEF);
604 def.appendToken(TokenBuilder.newFunction());
605 def.appendToken(TokenBuilder.newSpace());
606
607 def.addChildWithTokens(ASTUtils.newParentheticAST(AS3Parser.PARAMS, AS3Parser.LPAREN, "(", AS3Parser.RPAREN, ")"));
608 def.appendToken(TokenBuilder.newSpace());
609 LinkedListTree block = newBlock();
610 def.addChildWithTokens(block);
611 return def;
612 }
613
614 public static LinkedListTree newArrayLiteral() {
615 LinkedListTree lit = ASTUtils.newParentheticAST(AS3Parser.ARRAY_LITERAL, AS3Parser.LBRACK, "[", AS3Parser.RBRACK, "]");
616 return lit;
617 }
618
619 public static LinkedListTree newObjectLiteral() {
620 LinkedListTree lit = newBlock(AS3Parser.OBJECT_LITERAL);
621 return lit;
622 }
623
624 public static LinkedListTree newObjectField(String name,
625 LinkedListTree value)
626 {
627 LinkedListTree field = ASTUtils.newImaginaryAST(AS3Parser.OBJECT_FIELD);
628 field.addChildWithTokens(AS3FragmentParser.parseSimpleIdent(name));
629 field.appendToken(TokenBuilder.newColon());
630 field.appendToken(TokenBuilder.newSpace());
631 field.addChildWithTokens(value);
632 return field;
633 }
634
635 public static LinkedListTree newThrowStatement(LinkedListTree ast) {
636 LinkedListTree thrw = ASTUtils.newAST(AS3Parser.THROW, "throw");
637 thrw.appendToken(TokenBuilder.newSpace());
638 thrw.addChildWithTokens(ast);
639 thrw.appendToken(TokenBuilder.newSemi());
640 return thrw;
641 }
642
643 public static LinkedListTree newDescendantExpression(LinkedListTree target,
644 LinkedListTree selector)
645 {
646 LinkedListToken op = TokenBuilder.newE4XDescendant();
647 LinkedListTree ast = ASTUtils.newAST(op);
648 assertNoParent("left-hand expression", target);
649
650 if (precidence(ast) < precidence(target)) {
651 target = parenthise(target);
652 }
653 if (precidence(ast) < precidence(selector)) {
654 selector = parenthise(selector);
655 }
656
657 ast.addChild(target);
658 ast.addChild(selector);
659 target.getStopToken().setNext(op);
660 selector.getStartToken().setPrev(op);
661 ast.setStartToken(target.getStartToken());
662 ast.setStopToken(selector.getStopToken());
663 return ast;
664 }
665
666 public static LinkedListTree newFilterExpression(LinkedListTree target,
667 LinkedListTree selector)
668 {
669 LinkedListTree ast = ASTUtils.newImaginaryAST(AS3Parser.E4X_FILTER);
670 assertNoParent("target expression", target);
671 assertNoParent("query expression", target);
672
673 ast.addChildWithTokens(target);
674 ast.appendToken(TokenBuilder.newDot());
675 ast.appendToken(TokenBuilder.newLParen());
676 ast.addChildWithTokens(selector);
677 ast.appendToken(TokenBuilder.newRParen());
678 return ast;
679 }
680
681 public static LinkedListTree newStarAttribute() {
682 LinkedListTree ast = ASTUtils.newImaginaryAST(AS3Parser.E4X_ATTRI_STAR);
683 ast.appendToken(TokenBuilder.newAt());
684 ast.appendToken(TokenBuilder.newStar());
685 return ast;
686 }
687
688 public static LinkedListTree newPropertyAttribute(String propertyName) {
689 LinkedListTree ast = ASTUtils.newImaginaryAST(AS3Parser.E4X_ATTRI_PROPERTY);
690 ast.appendToken(TokenBuilder.newAt());
691 LinkedListTree prop = AS3FragmentParser.parseQualifiedIdent(propertyName);
692 ast.addChildWithTokens(prop);
693 return ast;
694 }
695
696 public static LinkedListTree newExpressionAttribute(LinkedListTree expr) {
697 LinkedListTree ast = ASTUtils.newImaginaryAST(AS3Parser.E4X_ATTRI_EXPR);
698 ast.appendToken(TokenBuilder.newAt());
699 ast.appendToken(TokenBuilder.newLBrack());
700 ast.addChildWithTokens(expr);
701 ast.appendToken(TokenBuilder.newRBrack());
702 return ast;
703 }
704
705 public static LinkedListTree newString(String value) {
706 return ASTUtils.newAST(AS3Parser.STRING_LITERAL, ActionScriptFactory.str(value));
707 }
708
709 public static LinkedListTree newDefaultXMLNamespace(LinkedListTree namespace) {
710 LinkedListTree ast = ASTUtils.newImaginaryAST(AS3Parser.DEFAULT_XML_NAMESPACE);
711 ast.appendToken(TokenBuilder.newDefault());
712 ast.appendToken(TokenBuilder.newSpace());
713 ast.appendToken(TokenBuilder.newXml());
714 ast.appendToken(TokenBuilder.newSpace());
715 ast.appendToken(TokenBuilder.newNamespace());
716 ast.appendToken(TokenBuilder.newSpace());
717 ast.appendToken(TokenBuilder.newAssign());
718 ast.appendToken(TokenBuilder.newSpace());
719 ast.addChildWithTokens(namespace);
720 ast.appendToken(TokenBuilder.newSemi());
721 return ast;
722 }
723 }