View Javadoc

1   /*
2    * ASSourceFactory.java
3    * 
4    * Copyright (c) 2006-2008 David Holroyd
5    *
6    * Licensed under the Apache License, Version 2.0 (the "License");
7    * you may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  
19  package uk.co.badgersinfoil.metaas;
20  
21  import java.util.List;
22  import org.asdt.core.internal.antlr.AS3Parser;
23  import uk.co.badgersinfoil.metaas.dom.ASArrayAccessExpression;
24  import uk.co.badgersinfoil.metaas.dom.ASArrayLiteral;
25  import uk.co.badgersinfoil.metaas.dom.ASAssignmentExpression;
26  import uk.co.badgersinfoil.metaas.dom.ASBinaryExpression;
27  import uk.co.badgersinfoil.metaas.dom.ASBlock;
28  import uk.co.badgersinfoil.metaas.dom.ASBooleanLiteral;
29  import uk.co.badgersinfoil.metaas.dom.ASCompilationUnit;
30  import uk.co.badgersinfoil.metaas.dom.ASConditionalExpression;
31  import uk.co.badgersinfoil.metaas.dom.ASDescendantExpression;
32  import uk.co.badgersinfoil.metaas.dom.Expression;
33  import uk.co.badgersinfoil.metaas.dom.ASExpressionAttribute;
34  import uk.co.badgersinfoil.metaas.dom.ASFieldAccessExpression;
35  import uk.co.badgersinfoil.metaas.dom.ASFilterExpression;
36  import uk.co.badgersinfoil.metaas.dom.ASFunctionExpression;
37  import uk.co.badgersinfoil.metaas.dom.ASInvocationExpression;
38  import uk.co.badgersinfoil.metaas.dom.ASNewExpression;
39  import uk.co.badgersinfoil.metaas.dom.ASNullLiteral;
40  import uk.co.badgersinfoil.metaas.dom.ASObjectLiteral;
41  import uk.co.badgersinfoil.metaas.dom.ASPostfixExpression;
42  import uk.co.badgersinfoil.metaas.dom.ASPrefixExpression;
43  import uk.co.badgersinfoil.metaas.dom.ASPropertyAttribute;
44  import uk.co.badgersinfoil.metaas.dom.ASRegexpLiteral;
45  import uk.co.badgersinfoil.metaas.dom.ASSimpleNameExpression;
46  import uk.co.badgersinfoil.metaas.dom.ASStarAttribute;
47  import uk.co.badgersinfoil.metaas.dom.ASStringLiteral;
48  import uk.co.badgersinfoil.metaas.dom.ASIntegerLiteral;
49  import uk.co.badgersinfoil.metaas.dom.ASUndefinedLiteral;
50  import uk.co.badgersinfoil.metaas.dom.ASXMLLiteral;
51  import uk.co.badgersinfoil.metaas.impl.AS3FragmentParser;
52  import uk.co.badgersinfoil.metaas.impl.ASTASArrayAccessExpression;
53  import uk.co.badgersinfoil.metaas.impl.ASTASArrayLiteral;
54  import uk.co.badgersinfoil.metaas.impl.ASTASBooleanLiteral;
55  import uk.co.badgersinfoil.metaas.impl.ASTASConditionalExpression;
56  import uk.co.badgersinfoil.metaas.impl.ASTASDescendantExpression;
57  import uk.co.badgersinfoil.metaas.impl.ASTASExpressionAttribute;
58  import uk.co.badgersinfoil.metaas.impl.ASTASFieldAccessExpression;
59  import uk.co.badgersinfoil.metaas.impl.ASTASFilterExpression;
60  import uk.co.badgersinfoil.metaas.impl.ASTASFunctionExpression;
61  import uk.co.badgersinfoil.metaas.impl.ASTASIntegerLiteral;
62  import uk.co.badgersinfoil.metaas.impl.ASTASInvocationExpression;
63  import uk.co.badgersinfoil.metaas.impl.ASTASNewExpression;
64  import uk.co.badgersinfoil.metaas.impl.ASTASNullLiteral;
65  import uk.co.badgersinfoil.metaas.impl.ASTASObjectLiteral;
66  import uk.co.badgersinfoil.metaas.impl.ASTASPostfixExpression;
67  import uk.co.badgersinfoil.metaas.impl.ASTASPrefixExpression;
68  import uk.co.badgersinfoil.metaas.impl.ASTASPropertyAttribute;
69  import uk.co.badgersinfoil.metaas.impl.ASTASRegexpLiteral;
70  import uk.co.badgersinfoil.metaas.impl.ASTASSimpleNameExpression;
71  import uk.co.badgersinfoil.metaas.impl.ASTASStarAttribute;
72  import uk.co.badgersinfoil.metaas.impl.ASTASStringLiteral;
73  import uk.co.badgersinfoil.metaas.impl.ASTASUndefinedLiteral;
74  import uk.co.badgersinfoil.metaas.impl.ASTActionScriptParser;
75  import uk.co.badgersinfoil.metaas.impl.ASTActionScriptProject;
76  import uk.co.badgersinfoil.metaas.impl.ASTActionScriptWriter;
77  import uk.co.badgersinfoil.metaas.impl.ASTBuilder;
78  import uk.co.badgersinfoil.metaas.impl.ASTStatementList;
79  import uk.co.badgersinfoil.metaas.impl.ASTUtils;
80  import uk.co.badgersinfoil.metaas.impl.ASTASXMLLiteral;
81  import uk.co.badgersinfoil.metaas.impl.ExpressionBuilder;
82  import uk.co.badgersinfoil.metaas.impl.TokenBuilder;
83  import uk.co.badgersinfoil.metaas.impl.antlr.LinkedListToken;
84  import uk.co.badgersinfoil.metaas.impl.antlr.LinkedListTree;
85  
86  // TODO: an isKeyword(String) test would be nice
87  
88  /**
89   * Core class providing access to metaas functionality.
90   */
91  public class ActionScriptFactory {
92  
93  	/**
94  	 * Creates a new CompilationUnit which defines a class with the given
95  	 * name.  To populate the new class, you can do something like,
96  	 * <pre>
97  	 * CompilationUnit cu = fact.newClass("MyTest");
98  	 * ASTClassType myclass = (ASTClassType)cu.getType();
99  	 * // ... add stuff to myclass  ...
100 	 * </pre>
101 	 */
102 	public ASCompilationUnit newClass(String qualifiedClassName) {
103 		return ASTBuilder.synthesizeClass(qualifiedClassName);
104 	}
105 
106 	/**
107 	 * Creates a new CompilationUnit which defines an interface with the
108 	 * given name.  To populate the new interface, you can do something
109 	 * like,
110 	 * <pre>
111 	 * CompilationUnit cu = fact.newClass("MyTest");
112 	 * ASTClassType myiface = (ASTInterfaceType)cu.getType();
113 	 * // ... add stuff to myiface  ...
114 	 * </pre>
115 	 */
116 	public ASCompilationUnit newInterface(String qualifiedInterfaceName) {
117 		return ASTBuilder.synthesizeInterface(qualifiedInterfaceName);
118 	}
119 
120 	public ActionScriptWriter newWriter() {
121 		return new ASTActionScriptWriter();
122 	}
123 	
124 	public ActionScriptParser newParser() {
125 		return new ASTActionScriptParser();
126 	}
127 
128 	/**
129 	 * Escape the given String and place within double quotes so that it
130 	 * will be a valid ActionScript string literal.
131 	 */
132 	public static String str(String str) {
133 		StringBuffer result = new StringBuffer("\"");
134 		for (int i=0; i<str.length(); i++) {
135 			char c = str.charAt(i);
136 			switch (c) {
137 			    case '\n':
138 				result.append("\\n");
139 				break;
140 			    case '\t':
141 				result.append("\\t");
142 				break;
143 			    case '\r':
144 				result.append("\\r");
145 				break;
146 			    case '"':
147 				result.append("\\\"");
148 				break;
149 			    case '\\':
150 				result.append("\\\\");
151 				break;
152 			    default:
153 				result.append(c);
154 			}
155 		}
156 		result.append('"');
157 		return result.toString();
158 	}
159 
160 	/**
161 	 * Creates a new ActionScript block statement.  Can be supplied to an
162 	 * {@link uk.co.badgersinfoil.metaas.dom.ASIfStatement}, for instance.
163 	 */
164 	public ASBlock newBlock() {
165 		LinkedListTree block = ASTBuilder.newBlock();
166 		return new ASTStatementList(block);
167 	}
168 
169 	public ActionScriptProject newEmptyASProject(String outputLocation) {
170 		ASTActionScriptProject project = new ASTActionScriptProject(this);
171 		project.setOutputLocation(outputLocation);
172 		return project;
173 	}
174 
175 	public ASStringLiteral newStringLiteral(String string) {
176 		return new ASTASStringLiteral(ASTUtils.newAST(AS3Parser.STRING_LITERAL, str(string)));
177 	}
178 
179 	public ASIntegerLiteral newIntegerLiteral(int i) {
180 		return new ASTASIntegerLiteral(ASTUtils.newAST(AS3Parser.DECIMAL_LITERAL, String.valueOf(i)));
181 	}
182 
183 	public ASNullLiteral newNullLiteral() {
184 		return new ASTASNullLiteral(ASTUtils.newAST(AS3Parser.NULL, "null"));
185 	}
186 
187 	public ASBooleanLiteral newBooleanLiteral(boolean b) {
188 		LinkedListTree ast = b ? ASTUtils.newAST(AS3Parser.TRUE, "true")
189 		                       : ASTUtils.newAST(AS3Parser.FALSE, "false");
190 		return new ASTASBooleanLiteral(ast);
191 	}
192 
193 	public ASUndefinedLiteral newUndefinedLiteral() {
194 		return new ASTASUndefinedLiteral(ASTUtils.newAST(AS3Parser.UNDEFINED, "undefined"));
195 	}
196 
197 	public ASBinaryExpression newAddExpression(Expression left, Expression right) {
198 		return ASTBuilder.newBinaryExpression(TokenBuilder.newPlus(), left, right);
199 	}
200 
201 	public ASBinaryExpression newAndExpression(Expression left, Expression right) {
202 		return ASTBuilder.newBinaryExpression(TokenBuilder.newAnd(), left, right);
203 	}
204 
205 	public ASBinaryExpression newBitAndExpression(Expression left, Expression right) {
206 		return ASTBuilder.newBinaryExpression(TokenBuilder.newBitAnd(), left, right);
207 	}
208 
209 	public ASBinaryExpression newBitOrExpression(Expression left, Expression right) {
210 		return ASTBuilder.newBinaryExpression(TokenBuilder.newBitOr(), left, right);
211 	}
212 
213 	public ASBinaryExpression newBitXorExpression(Expression left, Expression right) {
214 		return ASTBuilder.newBinaryExpression(TokenBuilder.newBitXor(), left, right);
215 	}
216 
217 	public ASBinaryExpression newDivisionExpression(Expression left, Expression right) {
218 		return ASTBuilder.newBinaryExpression(TokenBuilder.newDiv(), left, right);
219 	}
220 
221 	public ASBinaryExpression newEqualsExpression(Expression left, Expression right) {
222 		return ASTBuilder.newBinaryExpression(TokenBuilder.newEquals(), left, right);
223 	}
224 
225 	public ASBinaryExpression newGreaterEqualsExpression(Expression left, Expression right) {
226 		return ASTBuilder.newBinaryExpression(TokenBuilder.newGreaterEquals(), left, right);
227 	}
228 
229 	public ASBinaryExpression newGreaterThanExpression(Expression left, Expression right) {
230 		return ASTBuilder.newBinaryExpression(TokenBuilder.newGreater(), left, right);
231 	}
232 
233 	public ASBinaryExpression newLessEqualsExpression(Expression left, Expression right) {
234 		return ASTBuilder.newBinaryExpression(TokenBuilder.newLessEquals(), left, right);
235 	}
236 
237 	public ASBinaryExpression newLessThanExpression(Expression left, Expression right) {
238 		return ASTBuilder.newBinaryExpression(TokenBuilder.newLess(), left, right);
239 	}
240 
241 	public ASBinaryExpression newModuloExpression(Expression left, Expression right) {
242 		return ASTBuilder.newBinaryExpression(TokenBuilder.newModulo(), left, right);
243 	}
244 
245 	public ASBinaryExpression newMultiplyExpression(Expression left, Expression right) {
246 		return ASTBuilder.newBinaryExpression(TokenBuilder.newMult(), left, right);
247 	}
248 
249 	public ASBinaryExpression newNotEqualsExpression(Expression left, Expression right) {
250 		return ASTBuilder.newBinaryExpression(TokenBuilder.newNotEquals(), left, right);
251 	}
252 
253 	public ASBinaryExpression newOrExpression(Expression left, Expression right) {
254 		return ASTBuilder.newBinaryExpression(TokenBuilder.newOr(), left, right);
255 	}
256 
257 	public ASBinaryExpression newShiftLeftExpression(Expression left, Expression right) {
258 		return ASTBuilder.newBinaryExpression(TokenBuilder.newShiftLeft(), left, right);
259 	}
260 
261 	public ASBinaryExpression newShiftRightExpression(Expression left, Expression right) {
262 		return ASTBuilder.newBinaryExpression(TokenBuilder.newShiftRight(), left, right);
263 	}
264 
265 	public ASBinaryExpression newShiftRightUnsignedExpression(Expression left, Expression right) {
266 		return ASTBuilder.newBinaryExpression(TokenBuilder.newShiftRightUnsigned(), left, right);
267 	}
268 
269 	public ASBinaryExpression newSubtractExpression(Expression left, Expression right) {
270 		return ASTBuilder.newBinaryExpression(TokenBuilder.newMinus(), left, right);
271 	}
272 
273 	/**
274 	 * 
275 	 * @throws SyntaxException if the given string is not a vaild
276 	 *         ActionScript 3 expression.
277 	 */
278 	public Expression newExpression(String expr) {
279 		LinkedListTree ast = AS3FragmentParser.parseExpr(expr);
280 		// ANTLR creates a 'nil' parent node (in case the result is a
281 		// list).  We break the link to that parent because we assert
282 		// the parent is null when child nodes are attached elsewhere
283 		// in the tree.
284 		ast.setParent(null);
285 		return ExpressionBuilder.build(ast);
286 	}
287 
288 	private ASPrefixExpression newPrefixExpression(LinkedListToken op, Expression sub) {
289 		LinkedListTree ast = ASTUtils.newAST(op);
290 		LinkedListTree subExpr = ast(sub);
291 		ASTBuilder.assertNoParent("sub-expression", subExpr);
292 		ast.addChildWithTokens(subExpr);
293 		return new ASTASPrefixExpression(ast);
294 	}
295 
296 	public ASPrefixExpression newPreDecExpression(Expression sub) {
297 		return newPrefixExpression(TokenBuilder.newPreDec(), sub);
298 	}
299 
300 	public ASPrefixExpression newPreIncExpression(Expression sub) {
301 		return newPrefixExpression(TokenBuilder.newPreInc(), sub);
302 	}
303 
304 	public ASPrefixExpression newPositiveExpression(Expression sub) {
305 		return newPrefixExpression(TokenBuilder.newPlus(), sub);
306 	}
307 
308 	public ASPrefixExpression newNegativeExpression(Expression sub) {
309 		return newPrefixExpression(TokenBuilder.newMinus(), sub);
310 	}
311 
312 	public ASPrefixExpression newNotExpression(Expression sub) {
313 		return newPrefixExpression(TokenBuilder.newNot(), sub);
314 	}
315 
316 	private ASPostfixExpression newPostfixExpression(LinkedListToken op, Expression sub) {
317 		LinkedListTree ast = ASTUtils.newAST(op);
318 		LinkedListTree subExpr = ast(sub);
319 		ASTBuilder.assertNoParent("sub-expression", subExpr);
320 		ast.addChild(subExpr);
321 		ast.setStartToken(subExpr.getStartToken());
322 		subExpr.getStopToken().setNext(op);
323 		return new ASTASPostfixExpression(ast);
324 	}
325 
326 	public ASPostfixExpression newPostDecExpression(Expression sub) {
327 		return newPostfixExpression(TokenBuilder.newPostDec(), sub);
328 	}
329 
330 	public ASPostfixExpression newPostIncExpression(Expression sub) {
331 		return newPostfixExpression(TokenBuilder.newPostInc(), sub);
332 	}
333 
334 	public ASNewExpression newNewExpression(Expression subexpression, List args) {
335 		LinkedListTree ast = ASTUtils.newAST(AS3Parser.NEW, "new");
336 		ast.appendToken(TokenBuilder.newSpace());
337 		LinkedListTree subExpr = ast(subexpression);
338 		ASTBuilder.assertNoParent("sub-expression", subExpr);
339 		// TODO: recursively check the given subexpression
340 		ast.addChildWithTokens(subExpr);
341 		LinkedListTree arguments = ASTUtils.newParentheticAST(AS3Parser.ARGUMENTS, AS3Parser.LPAREN, "(", AS3Parser.RPAREN, ")");
342 		ast.addChildWithTokens(arguments);
343 		ASTASNewExpression result = new ASTASNewExpression(ast);
344 		result.setArguments(args);
345 		return result;
346 	}
347 
348 	public ASInvocationExpression newInvocationExpression(Expression sub, List args) {
349 		LinkedListTree ast = ASTUtils.newImaginaryAST(AS3Parser.METHOD_CALL);
350 		LinkedListTree subExpr = ast(sub);
351 		ASTBuilder.assertNoParent("sub-expression", subExpr);
352 		// TODO: recursively check the given subexpression
353 		ast.addChildWithTokens(subExpr);
354 		LinkedListTree arguments = ASTUtils.newParentheticAST(AS3Parser.ARGUMENTS, AS3Parser.LPAREN, "(", AS3Parser.RPAREN, ")");
355 		ast.addChildWithTokens(arguments);
356 		ASTASInvocationExpression result = new ASTASInvocationExpression(ast);
357 		result.setArguments(args);
358 		return result;
359 	}
360 
361 	public ASArrayAccessExpression newArrayAccessExpression(Expression target,
362 	                                                        Expression subscript)
363 	{
364 		LinkedListTree ast = ASTUtils.newImaginaryAST(AS3Parser.ARRAY_ACC);
365 		LinkedListTree targetExpr = ast(target);
366 		ASTBuilder.assertNoParent("target expression", targetExpr);
367 		// TODO: recursively check the given subexpression
368 		ast.addChildWithTokens(targetExpr);
369 		ast.appendToken(TokenBuilder.newLBrack());
370 		LinkedListTree subscriptExpr = ast(subscript);
371 		ASTBuilder.assertNoParent("subscript expression", subscriptExpr);
372 		ast.addChildWithTokens(subscriptExpr);
373 		ast.appendToken(TokenBuilder.newRBrack());
374 		ASTASArrayAccessExpression result = new ASTASArrayAccessExpression(ast);
375 		return result;
376 	}
377 
378 	public ASAssignmentExpression newAssignExpression(Expression left,
379 	                                                  Expression right)
380 	{
381 		return ASTBuilder.newAssignExpression(TokenBuilder.newAssign(),
382 		                                      left, right);
383 	}
384 
385 	public ASAssignmentExpression newAddAssignExpression(Expression left,
386 	                                                     Expression right)
387 	{
388 		return ASTBuilder.newAssignExpression(TokenBuilder.newAddAssign(),
389 		                                      left, right);
390 	}
391 
392 	public ASAssignmentExpression newBitAndAssignExpression(Expression left,
393 	                                                        Expression right)
394 	{
395 		return ASTBuilder.newAssignExpression(TokenBuilder.newBitAndAssign(),
396 		                                      left, right);
397 	}
398 
399 	public ASAssignmentExpression newBitOrAssignExpression(Expression left,
400 	                                                       Expression right)
401 	{
402 		return ASTBuilder.newAssignExpression(TokenBuilder.newBitOrAssign(),
403 		                                      left, right);
404 	}
405 
406 	public ASAssignmentExpression newBitXorAssignExpression(Expression left,
407 	                                                        Expression right)
408 	{
409 		return ASTBuilder.newAssignExpression(TokenBuilder.newBitXorAssign(),
410 		                                      left, right);
411 	}
412 
413 	public ASAssignmentExpression newDivideAssignExpression(Expression left,
414 	                                                        Expression right)
415 	{
416 		return ASTBuilder.newAssignExpression(TokenBuilder.newDivAssign(),
417 		                                      left, right);
418 	}
419 
420 	public ASAssignmentExpression newModuloAssignExpression(Expression left,
421 	                                                        Expression right)
422 	{
423 		return ASTBuilder.newAssignExpression(TokenBuilder.newModAssign(),
424 		                                      left, right);
425 	}
426 
427 	public ASAssignmentExpression newMultiplyAssignExpression(Expression left,
428 	                                                          Expression right)
429 	{
430 		return ASTBuilder.newAssignExpression(TokenBuilder.newMulAssign(),
431 		                                      left, right);
432 	}
433 
434 	public ASAssignmentExpression newShiftLeftAssignExpression(Expression left,
435 	                                                          Expression right)
436 	{
437 		return ASTBuilder.newAssignExpression(TokenBuilder.newSLAssign(),
438 		                                      left, right);
439 	}
440 
441 	public ASAssignmentExpression newShiftRightAssignExpression(Expression left,
442 	                                                            Expression right)
443 	{
444 		return ASTBuilder.newAssignExpression(TokenBuilder.newSRAssign(),
445 		                                      left, right);
446 	}
447 
448 	public ASAssignmentExpression newShiftRightUnsignedAssignExpression(Expression left,
449 	                                                                    Expression right)
450 	{
451 		return ASTBuilder.newAssignExpression(TokenBuilder.newSRUAssign(),
452 		                                      left, right);
453 	}
454 
455 	public ASAssignmentExpression newSubtractAssignExpression(Expression left,
456 	                                                  Expression right)
457 	{
458 		return ASTBuilder.newAssignExpression(TokenBuilder.newSubAssign(),
459 		                                      left, right);
460 	}
461 
462 	public ASFieldAccessExpression newFieldAccessExpression(Expression target, String name) {
463 		LinkedListTree ast
464 			= ASTBuilder.newFieldAccessExpression(ast(target),
465 		                                              ASTUtils.newAST(AS3Parser.IDENT, name));
466 		return new ASTASFieldAccessExpression(ast);
467 	}
468 
469 	public ASConditionalExpression newConditionalExpression(Expression conditionExpr,
470 	                                                        Expression thenExpr,
471 	                                                        Expression elseExpr)
472 	{
473 		LinkedListTree ast
474 			= ASTBuilder.newConditionalExpression(ast(conditionExpr),
475 		                                              ast(thenExpr),
476 		                                              ast(elseExpr));
477 		return new ASTASConditionalExpression(ast);
478 	}
479 
480 	private static LinkedListTree ast(Expression expr) {
481 		return ASTUtils.ast(expr);
482 	}
483 
484 	public ASFunctionExpression newFunctionExpression() {
485 		LinkedListTree ast = ASTBuilder.newFunctionExpression();
486 		return new ASTASFunctionExpression(ast);
487 	}
488 
489 	/**
490 	 * @param entries a list of {@link Expression} objects.
491 	 */
492 	public ASArrayLiteral newArrayLiteral() {
493 		LinkedListTree ast = ASTBuilder.newArrayLiteral();
494 		return new ASTASArrayLiteral(ast);
495 	}
496 
497 	public ASObjectLiteral newObjectLiteral() {
498 		LinkedListTree ast = ASTBuilder.newObjectLiteral();
499 		return new ASTASObjectLiteral(ast);
500 	}
501 
502 	public ASXMLLiteral newXMLLiteral(String value) {
503 		LinkedListTree ast = AS3FragmentParser.parseXMLLiteral(value);
504 		return new ASTASXMLLiteral(ast);
505 	}
506 
507 	public ASRegexpLiteral newRegexpLiteral(String value, int flags) {
508 		StringBuffer flagList = new StringBuffer();
509 		if ((flags & ASRegexpLiteral.FLAG_DOT_ALL) != 0) {
510 			flagList.append('s');
511 		}
512 		if ((flags & ASRegexpLiteral.FLAG_EXTENDED) != 0) {
513 			flagList.append('x');
514 		}
515 		if ((flags & ASRegexpLiteral.FLAG_GLOBAL) != 0) {
516 			flagList.append('g');
517 		}
518 		if ((flags & ASRegexpLiteral.FLAG_IGNORE_CASE) != 0) {
519 			flagList.append('i');
520 		}
521 		value = regexpEscapeDelimiter(value);
522 		LinkedListTree ast = AS3FragmentParser.parseRegexpLiteral("/"+value+"/"+flagList);
523 		return new ASTASRegexpLiteral(ast);
524 	}
525 
526 	private static String regexpEscapeDelimiter(String value) {
527 		StringBuffer result = new StringBuffer();
528 		for (int i=0; i<value.length(); i++) {
529 			char c = value.charAt(i);
530 			switch (c) {
531 				case '/': result.append("\\/"); break;
532 				default: result.append(c); break;
533 			}
534 		}
535 		return result.toString();
536 	}
537 
538 	public ASDescendantExpression newDescendantExpression(Expression target,
539 	                                                      Expression selector)
540 	{
541 		LinkedListTree ast
542 			= ASTBuilder.newDescendantExpression(ast(target),
543 			                                     ast(selector));
544 		return new ASTASDescendantExpression(ast);
545 	}
546 
547 	public ASFilterExpression newFilterExpression(Expression target,
548 	                                              Expression selector)
549 	{
550 		LinkedListTree ast
551 			= ASTBuilder.newFilterExpression(ast(target),
552 			                                 ast(selector));
553 		return new ASTASFilterExpression(ast);
554 	}
555 
556 	public ASStarAttribute newStarAttribute() {
557 		LinkedListTree ast = ASTBuilder.newStarAttribute();
558 		return new ASTASStarAttribute(ast);
559 	}
560 
561 	public ASPropertyAttribute newPropertyAttribute(String propertyName) {
562 		LinkedListTree ast = ASTBuilder.newPropertyAttribute(propertyName);
563 		return new ASTASPropertyAttribute(ast);
564 	}
565 
566 	public ASExpressionAttribute newExpressionAttribute(Expression expr) {
567 		LinkedListTree ast = ASTBuilder.newExpressionAttribute(ast(expr));
568 		return new ASTASExpressionAttribute(ast);
569 	}
570 
571 	public ASSimpleNameExpression newSimpleName(String name) {
572 		LinkedListTree ast = AS3FragmentParser.parseSimpleIdent(name);
573 		return new ASTASSimpleNameExpression(ast);
574 	}
575 }