Skip to main content

This CGIT instance is deprecated, and repositories have been moved to Gitlab or Github. See the repository descriptions for specific locations.

summaryrefslogtreecommitdiffstats
blob: c7e58a9483c7f5358a6bcdba76d7bf89f7047f62 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
/*******************************************************************************
 * Copyright (c) 2004, 2006 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
/*


 */
package org.eclipse.jem.workbench.utility;

import java.text.MessageFormat;
import java.util.HashMap;
import java.util.List;

import org.eclipse.jdt.core.dom.*;

import org.eclipse.jem.internal.instantiation.*;
 
/**
 * Create a parse tree from an AST node.
 * @since 1.0.0
 */
public class ParseTreeCreationFromAST extends ASTVisitor {
	protected final Resolver resolver;
	protected PTExpression expression;	// Each visit (or endvisit) will put into expression the result of the visit if it produced an expression.
	
	/**
	 * This is the abstract base class used by ParseTreeCreationFromAST to resolve the types to the appropriate
	 * types (e.g. "String" to "java.lang.String"). 
	 * 
	 * @see org.eclipse.jem.workbench.utility.ParseTreeCreationFromAST
	 * @since 1.0.0
	 */
	public static abstract class Resolver {
		
		/**
		 * Resolve the Name. It can return either a PTName if it is just a classname,
		 * or a PTFieldAccess if it resolves to a PTFieldAccess. The PTFieldAccess should
		 * be complete. e.g we have class like:
		 * <code>
		 * 	package xyz; 
		 * 	public class AClass {
		 * 		public java.awt.Rectangle rect;
		 * 	} 
		 * </code>
		 * Then a Name like <code>AClass.rect.x</code> should resolve to:
		 * 
		 * PTFieldAccess:
		 * 	receiver: 
		 * 		PTFieldAccess
		 * 			receiver: xyz.AClass
		 * 			field: "rect"
		 * 	field: "x"
		 *
		 * Actually it can return any valid expression that has a value (i.e. it cannot be a method invocation with a <code>void</code> return type). 
		 * 
		 * @param name
		 * @return Either a fully-qualified name (as a PTName) or a PTFieldAccess, any other type of expression.
		 * 
		 * @since 1.0.0
		 */
		public abstract PTExpression resolveName(Name name) throws InvalidExpressionException;
		
		/**
		 * Resolve the type. If it is an array type return it in format "type[][]".
		 * 
		 * @param type
		 * @return The type name, including brackets if array type.
		 * 
		 * @since 1.0.0
		 */
		public abstract String resolveType(Type type) throws InvalidExpressionException;
		
		/**
		 * This is for resolving "this" literal. It should either return a PTThisLiteral, if it
		 * can't do resolve, or some PTExpression that can resolve to "this" for evaluation.
		 * 
		 * @return If resolvable, a PTExpression, else a PTThisLiteral if not resolvable.
		 * @throws InvalidExpressionException
		 * 
		 * @since 1.0.0
		 */
		public abstract PTExpression resolveThis() throws InvalidExpressionException;
		
		/**
		 * Resolve the type specified as a Name. It may be a simple name or it may be
		 * a qualified name. This is used when we have Name that we know must be a
		 * type. This is so that there is no confusion with it possibly being a field or variable
		 * that has the same case and spelling as a type name.
		 * @param name
		 * @return the type name.
		 * @throws InvalidExpressionException
		 * 
		 * @since 1.0.0
		 */
		public abstract String resolveType(Name name) throws InvalidExpressionException;
		
		/**
		 * This is used by the resolver if it can't resolve for some reason. This will throw
		 * an invalid expression exception which will be handled by the ParseTreeCreationFromAST.
		 * 
		 * @param msg Message to be put into the exception.
		 * @throws InvalidExpressionException
		 * 
		 * @since 1.0.0
		 */
		protected final void throwInvalidExpressionException(String msg) throws InvalidExpressionException {
			throw new InvalidExpressionException(msg);
		}
	}
	
	/*
	 * When an invalid expression has been found this exception should be thrown. It will
	 * be caught at the top and converted into an InvalidExpression and the rest of the parse tree will be
	 * thrown away. 
	 * 
	 * The message will be a message as to why it is invalid.
	 * 
	 * @since 1.0.0
	 */
	protected static class InvalidExpressionException extends IllegalArgumentException {
		
		/**
		 * Comment for <code>serialVersionUID</code>
		 * 
		 * @since 1.1.0
		 */
		private static final long serialVersionUID = 2429845631915206678L;

		/**
		 * @param s The message to be used in the final invalid expression.
		 * 
		 * @since 1.0.0
		 */
		public InvalidExpressionException(String s) {
			super(s);
		}
	}

	/**
	 * Construct with the given resolver.
	 * 
	 * @param resolver
	 * 
	 * @since 1.0.0
	 */
	public ParseTreeCreationFromAST(Resolver resolver) {
		this.resolver = resolver;
	}

	/**
	 * Process the AST Expression and return a PTExpression. If any part was invalid, then
	 * only an PTInvalidExpression will be returned.
	 * 
	 * @param astExpression
	 * @return The PTExpression.
	 * 
	 * @since 1.0.0
	 */
	public final PTExpression createExpression(Expression astExpression) {
		try {
			return perform(astExpression);
		} catch (InvalidExpressionException e) {
			// Create a msg that is formed of the exception message and the full init string.
			String msg = MessageFormat.format(WorkbenchUtilityMessages.ParseTreeCreationFromAST_0, new Object[] {e.getLocalizedMessage(), astExpression.toString()}); 
			PTInvalidExpression exp = InstantiationFactory.eINSTANCE.createPTInvalidExpression();
			exp.setMessage(msg);
			return exp;
		}	
	}
	
	/*
	 * Visit the AST expression and get the ParseTree Expression.
	 * This is used by the individual visits when parsing a tree.
	 * It passes to the top method (createExpression), which can
	 * handle the InvalidExpressionException.
	 * 
	 * If any visit doesn't return an expression, then an invalid
	 * expression exception will be thrown to indicate this. If the
	 * incoming expression is <code>null</code>, then return of <code>null</code> is ok because
	 * this would be for an optional expression which didn't exist.
	 * 
	 * @return The new ParseTree Expression or <code>null</code> if incoming expression was null. 
	 * 
	 * @see createExpression(org.eclipse.jdt.core.dom.Expression)
	 * @exception InvalidExpressionException
	 * @since 1.0.0
	 */
	protected final PTExpression perform(Expression astExpression) {
		if (astExpression != null) {
			expression = null;
			astExpression.accept(this);
			if (expression == null)
				throw new InvalidExpressionException(MessageFormat.format(WorkbenchUtilityMessages.ParseTreeCreationFromAST_ExpressionTooComplicated_EXC_, new Object[] {astExpression.toString()})); 
			return expression;
		} else
			return null;	// This is ok. It means an optional expression was being processed and the expression didn't exist.
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ArrayAccess)
	 */
	public boolean visit(ArrayAccess node) {
		PTArrayAccess aa = InstantiationFactory.eINSTANCE.createPTArrayAccess();
		List indexes = aa.getIndexes();
		Expression arrayExp = node;
		while (arrayExp.getNodeType() == ASTNode.ARRAY_ACCESS) {
			// Visit the index to get the index expression.
			ArrayAccess array = (ArrayAccess) arrayExp; 
			indexes.add(0, perform(array.getIndex()));	// We're trying to create the final expression from inside out, the indexes are created in reverse order.
			arrayExp = array.getArray();
		}
		aa.setArray(perform(arrayExp));	// Final arrayExp is the true expression.
		expression = aa;	// Set the return expression for this visit.
		return false;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ArrayCreation)
	 */
	public boolean visit(ArrayCreation node) {
		PTArrayCreation ac = InstantiationFactory.eINSTANCE.createPTArrayCreation();
		ac.setType(resolver.resolveType(node.getType()));
		List acDims = ac.getDimensions();
		List nDims = node.dimensions();
		int nsize = nDims.size();
		for (int i = 0; i < nsize; i++) {
			acDims.add(perform((Expression) nDims.get(i)));
		}
		ac.setInitializer((PTArrayInitializer) perform(node.getInitializer()));
		expression = ac;
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ArrayInitializer)
	 */
	public boolean visit(ArrayInitializer node) {
		PTArrayInitializer ai = InstantiationFactory.eINSTANCE.createPTArrayInitializer();
		List exps = node.expressions();
		List aiexps = ai.getExpressions();
		int nexp = exps.size();
		for (int i = 0; i < nexp; i++) {
			aiexps.add(perform((Expression) exps.get(i)));
		}
		expression = ai;
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.Assignment)
	 */
	public boolean visit(Assignment node) {
		return false;	// We can't handle assignment.
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.BooleanLiteral)
	 */
	public boolean visit(BooleanLiteral node) {
		PTBooleanLiteral bl = InstantiationFactory.eINSTANCE.createPTBooleanLiteral();
		bl.setBooleanValue(node.booleanValue());
		expression = bl;
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.CastExpression)
	 */
	public boolean visit(CastExpression node) {
		PTCastExpression ct	= InstantiationFactory.eINSTANCE.createPTCastExpression();
		ct.setType(resolver.resolveType(node.getType()));
		ct.setExpression(perform(node.getExpression()));
		expression = ct;
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.CharacterLiteral)
	 */
	public boolean visit(CharacterLiteral node) {
		PTCharacterLiteral cl = InstantiationFactory.eINSTANCE.createPTCharacterLiteral();
		cl.setEscapedValue(node.getEscapedValue());
		cl.setCharValue(node.charValue());
		expression = cl;
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ClassInstanceCreation)
	 */
	public boolean visit(ClassInstanceCreation node) {
		if (node.getAnonymousClassDeclaration() != null) { 
			PTAnonymousClassDeclaration adecl = InstantiationFactory.eINSTANCE.createPTAnonymousClassDeclaration();
			adecl.setDeclaration(node.toString());
			expression = adecl;
		} else {
			PTClassInstanceCreation cic = InstantiationFactory.eINSTANCE.createPTClassInstanceCreation();
			// If ast level = 2, then you must use getName, but the name needs to be turned into a type
			// so that it can be resolved. If ast level > 2, then it will return a type to be resolved.
			// Note: can't just use resolve name on the name because if a field and a class were spelled
			// the same then the codegen resolver would return an instance ref to the field instead.
			String type = node.getAST().apiLevel() == AST.JLS2 ? resolver.resolveType(node.getName()) : resolver.resolveType(node.getType());
			if (type == null) {
				type = node.getAST().apiLevel() == AST.JLS2 ? node.getName().getFullyQualifiedName() : node.getType().toString();
			}
			cic.setType(type);
			List args = cic.getArguments();
			List nargs = node.arguments();
			int nsize = nargs.size();
			for (int i = 0; i < nsize; i++) {
				args.add(perform((Expression) nargs.get(i)));
			}
			expression = cic;
		}
		return false;

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ConditionalExpression)
	 */
	public boolean visit(ConditionalExpression node) {
		PTConditionalExpression ce = InstantiationFactory.eINSTANCE.createPTConditionalExpression();
		ce.setCondition(perform(node.getExpression()));
		ce.setTrue(perform(node.getThenExpression()));
		ce.setFalse(perform(node.getElseExpression()));
		expression = ce;
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.FieldAccess)
	 */
	public boolean visit(FieldAccess node) {
		expression = createFieldAccess(node.getName().getIdentifier(), perform(node.getExpression()));
		return false;
	}
	
	protected PTExpression createFieldAccess(String name, PTExpression receiver) {
		PTFieldAccess fa = InstantiationFactory.eINSTANCE.createPTFieldAccess();
		fa.setReceiver(receiver);
		fa.setField(name);
		return fa;
	}

	private static HashMap infixOperToParseOper;
	private final PTInfixOperator getParseInfix(InfixExpression.Operator operator) {
		if (prefixOperToParseOper == null) {
			infixOperToParseOper = new HashMap(5);
			infixOperToParseOper.put(InfixExpression.Operator.AND, PTInfixOperator.AND_LITERAL);
			infixOperToParseOper.put(InfixExpression.Operator.CONDITIONAL_AND, PTInfixOperator.CONDITIONAL_AND_LITERAL);
			infixOperToParseOper.put(InfixExpression.Operator.CONDITIONAL_OR, PTInfixOperator.CONDITIONAL_OR_LITERAL);
			infixOperToParseOper.put(InfixExpression.Operator.DIVIDE, PTInfixOperator.DIVIDE_LITERAL);
			infixOperToParseOper.put(InfixExpression.Operator.EQUALS, PTInfixOperator.EQUALS_LITERAL);
			infixOperToParseOper.put(InfixExpression.Operator.GREATER_EQUALS, PTInfixOperator.GREATER_EQUALS_LITERAL);
			infixOperToParseOper.put(InfixExpression.Operator.GREATER, PTInfixOperator.GREATER_LITERAL);
			infixOperToParseOper.put(InfixExpression.Operator.LEFT_SHIFT, PTInfixOperator.LEFT_SHIFT_LITERAL);
			infixOperToParseOper.put(InfixExpression.Operator.LESS_EQUALS, PTInfixOperator.LESS_EQUALS_LITERAL);
			infixOperToParseOper.put(InfixExpression.Operator.LESS, PTInfixOperator.LESS_LITERAL);
			infixOperToParseOper.put(InfixExpression.Operator.MINUS, PTInfixOperator.MINUS_LITERAL);
			infixOperToParseOper.put(InfixExpression.Operator.NOT_EQUALS, PTInfixOperator.NOT_EQUALS_LITERAL);
			infixOperToParseOper.put(InfixExpression.Operator.OR, PTInfixOperator.OR_LITERAL);
			infixOperToParseOper.put(InfixExpression.Operator.PLUS, PTInfixOperator.PLUS_LITERAL);
			infixOperToParseOper.put(InfixExpression.Operator.REMAINDER, PTInfixOperator.REMAINDER_LITERAL);
			infixOperToParseOper.put(InfixExpression.Operator.RIGHT_SHIFT_SIGNED, PTInfixOperator.RIGHT_SHIFT_SIGNED_LITERAL);
			infixOperToParseOper.put(InfixExpression.Operator.RIGHT_SHIFT_UNSIGNED, PTInfixOperator.RIGHT_SHIFT_UNSIGNED_LITERAL);
			infixOperToParseOper.put(InfixExpression.Operator.TIMES, PTInfixOperator.TIMES_LITERAL);
			infixOperToParseOper.put(InfixExpression.Operator.XOR, PTInfixOperator.XOR_LITERAL);
		}
		return (PTInfixOperator) infixOperToParseOper.get(operator);
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.InfixExpression)
	 */
	public boolean visit(InfixExpression node) {
		PTInfixExpression inf = InstantiationFactory.eINSTANCE.createPTInfixExpression();
		inf.setLeftOperand(perform(node.getLeftOperand()));
		PTInfixOperator inoper = getParseInfix(node.getOperator());
		if (inoper == null) {
			// It is not one we can handle.
			throw new InvalidExpressionException(
					MessageFormat.format(WorkbenchUtilityMessages.ParseTreeCreationFromAST_OperatorTooComplicatedToHandle_EXC_, new Object[] { node.getOperator().toString() })); 
		}
		inf.setOperator(inoper);
		inf.setRightOperand(perform(node.getRightOperand()));
		List eops = inf.getExtendedOperands();
		List neops = node.extendedOperands();
		int nsize = neops.size();
		for (int i = 0; i < nsize; i++) {
			eops.add(perform((Expression) neops.get(i)));
		}
		expression = inf;
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.InstanceofExpression)
	 */
	public boolean visit(InstanceofExpression node) {
		PTInstanceof inof = InstantiationFactory.eINSTANCE.createPTInstanceof();
		inof.setOperand(perform(node.getLeftOperand()));
		inof.setType(resolver.resolveType(node.getRightOperand()));
		expression = inof;
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.PostfixExpression)
	 */
	public boolean visit(PostfixExpression node) {
		return false;	// We can't handle post fix.
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.MethodInvocation)
	 */
	public boolean visit(MethodInvocation node) {
		expression = createMethodInvocation(node.getName().getIdentifier(), perform(node.getExpression()), node.arguments());
		return false;
	}

	/**
	 * Create a method invocation using the giving receiver, name, args.
	 * @param node
	 * @return
	 * 
	 * @since 1.2.0
	 */
	protected PTMethodInvocation createMethodInvocation(String name, PTExpression receiver, List argExpressions) {
		PTMethodInvocation mi = InstantiationFactory.eINSTANCE.createPTMethodInvocation();
		mi.setReceiver(receiver);
		mi.setName(name);
		List args = mi.getArguments();
		int nsize = argExpressions.size();
		for (int i = 0; i < nsize; i++) {
			args.add(perform((Expression) argExpressions.get(i)));
		}
		return mi;
	}
	
	

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.NullLiteral)
	 */
	public boolean visit(NullLiteral node) {
		expression = InstantiationFactory.eINSTANCE.createPTNullLiteral();
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.NumberLiteral)
	 */
	public boolean visit(NumberLiteral node) {
		PTNumberLiteral nl = InstantiationFactory.eINSTANCE.createPTNumberLiteral();
		nl.setToken(node.getToken());
		expression = nl;
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ParenthesizedExpression)
	 */
	public boolean visit(ParenthesizedExpression node) {
		PTParenthesizedExpression pe = InstantiationFactory.eINSTANCE.createPTParenthesizedExpression();
		pe.setExpression(perform(node.getExpression()));
		expression = pe;
		return false;
	}

	private static HashMap prefixOperToParseOper;
	private final PTPrefixOperator getParsePrefix(PrefixExpression.Operator operator) {
		if (prefixOperToParseOper == null) {
			prefixOperToParseOper = new HashMap(5);
			prefixOperToParseOper.put(PrefixExpression.Operator.COMPLEMENT, PTPrefixOperator.COMPLEMENT_LITERAL);
			prefixOperToParseOper.put(PrefixExpression.Operator.MINUS, PTPrefixOperator.MINUS_LITERAL);
			prefixOperToParseOper.put(PrefixExpression.Operator.NOT, PTPrefixOperator.NOT_LITERAL);
			prefixOperToParseOper.put(PrefixExpression.Operator.PLUS, PTPrefixOperator.PLUS_LITERAL);
		}
		return (PTPrefixOperator) prefixOperToParseOper.get(operator);
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.PrefixExpression)
	 */
	public boolean visit(PrefixExpression node) {
		if (node.getOperand().getNodeType() == ASTNode.NUMBER_LITERAL) {
			// For number literals we see if it is a "+" or "-" prefix, and if it is, we simply
			// create a PTNumberLiteral with the operator already in it. It is a simplification.
			// Any other operator we've left alone since those won't be decoded simply by the
			// Number decoder.
			// If not a number literal, then leave alone since needs to be handled as a prefix
			// operation.
			PrefixExpression.Operator operator = node.getOperator();
			if (operator == PrefixExpression.Operator.PLUS || operator == PrefixExpression.Operator.MINUS) {
				PTNumberLiteral nm = InstantiationFactory.eINSTANCE.createPTNumberLiteral();
				nm.setToken(operator.toString() + ((NumberLiteral) node.getOperand()).getToken());
				expression = nm;
				return false;
			}
		}

		PTPrefixExpression pe = InstantiationFactory.eINSTANCE.createPTPrefixExpression();
		PTPrefixOperator ptoper = getParsePrefix(node.getOperator());
		if (ptoper == null) {
			// It is not one we can handle.
			throw new InvalidExpressionException(
				MessageFormat.format(WorkbenchUtilityMessages.ParseTreeCreationFromAST_OperatorTooComplicatedToHandle_EXC_, new Object[] { node.getOperator().toString() })); 
		}
		pe.setOperator(ptoper);
		pe.setExpression(perform(node.getOperand()));
		expression = pe;
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.QualifiedName)
	 */
	public boolean visit(QualifiedName node) {
		expression = resolver.resolveName(node);
		return false;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.SimpleName)
	 */
	public boolean visit(SimpleName node) {
		expression = resolver.resolveName(node);
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.StringLiteral)
	 */
	public boolean visit(StringLiteral node) {
		PTStringLiteral sl = InstantiationFactory.eINSTANCE.createPTStringLiteral();
		sl.setEscapedValue(node.getEscapedValue());
		sl.setLiteralValue(node.getLiteralValue());
		expression = sl;
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.SuperFieldAccess)
	 */
	public boolean visit(SuperFieldAccess node) {
		expression = createFieldAccess(node.getName().getIdentifier(), resolver.resolveThis());
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.SuperMethodInvocation)
	 */
	public boolean visit(SuperMethodInvocation node) {
		expression = createMethodInvocation(node.getName().getIdentifier(), resolver.resolveThis(), node.arguments());
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ThisExpression)
	 */
	public boolean visit(ThisExpression node) {
		expression = resolver.resolveThis();
		return false;	
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.TypeLiteral)
	 */
	public boolean visit(TypeLiteral node) {
		PTTypeLiteral ptl = InstantiationFactory.eINSTANCE.createPTTypeLiteral();
		ptl.setType(resolver.resolveType(node.getType()));
		expression = ptl;
		return false;
	}

}

Back to the top