View | Details | Raw Unified | Return to bug 215759 | Differences between
and this patch

Collapse All | Expand All

(-)dom/org/eclipse/jdt/core/dom/NaiveASTFlattener.java (-1601 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2007 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.jdt.core.dom;
12
13
import java.util.Iterator;
14
import java.util.List;
15
16
/**
17
 * Internal AST visitor for serializing an AST in a quick and dirty fashion.
18
 * For various reasons the resulting string is not necessarily legal
19
 * Java code; and even if it is legal Java code, it is not necessarily the string
20
 * that corresponds to the given AST. Although useless for most purposes, it's
21
 * fine for generating debug print strings.
22
 * <p>
23
 * Example usage:
24
 * <code>
25
 * <pre>
26
 *    NaiveASTFlattener p = new NaiveASTFlattener();
27
 *    node.accept(p);
28
 *    String result = p.getResult();
29
 * </pre>
30
 * </code>
31
 * Call the <code>reset</code> method to clear the previous result before reusing an
32
 * existing instance.
33
 * </p>
34
 * 
35
 * @since 2.0
36
 */
37
class NaiveASTFlattener extends ASTVisitor {
38
	
39
	/**
40
	 * The string buffer into which the serialized representation of the AST is
41
	 * written.
42
	 */
43
	private StringBuffer buffer;
44
	
45
	private int indent = 0;
46
	
47
	/**
48
	 * Creates a new AST printer.
49
	 */
50
	NaiveASTFlattener() {
51
		this.buffer = new StringBuffer();
52
	}
53
	
54
	/**
55
	 * Returns the string accumulated in the visit.
56
	 *
57
	 * @return the serialized 
58
	 */
59
	public String getResult() {
60
		return this.buffer.toString();
61
	}
62
	
63
	/**
64
	 * Resets this printer so that it can be used again.
65
	 */
66
	public void reset() {
67
		this.buffer.setLength(0);
68
	}
69
	
70
	void printIndent() {
71
		for (int i = 0; i < this.indent; i++) 
72
			this.buffer.append("  "); //$NON-NLS-1$
73
	}
74
	
75
	/**
76
	 * Appends the text representation of the given modifier flags, followed by a single space.
77
	 * Used for 3.0 modifiers and annotations.
78
	 * 
79
	 * @param ext the list of modifier and annotation nodes
80
	 * (element type: <code>IExtendedModifiers</code>)
81
	 */
82
	void printModifiers(List ext) {
83
		for (Iterator it = ext.iterator(); it.hasNext(); ) {
84
			ASTNode p = (ASTNode) it.next();
85
			p.accept(this);
86
			this.buffer.append(" ");//$NON-NLS-1$
87
		}
88
	}		
89
	
90
	/**
91
	 * Appends the text representation of the given modifier flags, followed by a single space.
92
	 * Used for JLS2 modifiers.
93
	 * 
94
	 * @param modifiers the modifier flags
95
	 */
96
	void printModifiers(int modifiers) {
97
		if (Modifier.isPublic(modifiers)) {
98
			this.buffer.append("public ");//$NON-NLS-1$
99
		}
100
		if (Modifier.isProtected(modifiers)) {
101
			this.buffer.append("protected ");//$NON-NLS-1$
102
		}
103
		if (Modifier.isPrivate(modifiers)) {
104
			this.buffer.append("private ");//$NON-NLS-1$
105
		}
106
		if (Modifier.isStatic(modifiers)) {
107
			this.buffer.append("static ");//$NON-NLS-1$
108
		}
109
		if (Modifier.isAbstract(modifiers)) {
110
			this.buffer.append("abstract ");//$NON-NLS-1$
111
		}
112
		if (Modifier.isFinal(modifiers)) {
113
			this.buffer.append("final ");//$NON-NLS-1$
114
		}
115
		if (Modifier.isSynchronized(modifiers)) {
116
			this.buffer.append("synchronized ");//$NON-NLS-1$
117
		}
118
		if (Modifier.isVolatile(modifiers)) {
119
			this.buffer.append("volatile ");//$NON-NLS-1$
120
		}
121
		if (Modifier.isNative(modifiers)) {
122
			this.buffer.append("native ");//$NON-NLS-1$
123
		}
124
		if (Modifier.isStrictfp(modifiers)) {
125
			this.buffer.append("strictfp ");//$NON-NLS-1$
126
		}
127
		if (Modifier.isTransient(modifiers)) {
128
			this.buffer.append("transient ");//$NON-NLS-1$
129
		}
130
	}		
131
	
132
	/*
133
	 * @see ASTVisitor#visit(AnnotationTypeDeclaration)
134
	 * @since 3.1
135
	 */
136
	public boolean visit(AnnotationTypeDeclaration node) {
137
		if (node.getJavadoc() != null) {
138
			node.getJavadoc().accept(this);
139
		}
140
		printIndent();
141
		printModifiers(node.modifiers());
142
		this.buffer.append("@interface ");//$NON-NLS-1$
143
		node.getName().accept(this);
144
		this.buffer.append(" {");//$NON-NLS-1$
145
		for (Iterator it = node.bodyDeclarations().iterator(); it.hasNext(); ) {
146
			BodyDeclaration d = (BodyDeclaration) it.next();
147
			d.accept(this);
148
		}
149
		this.buffer.append("}\n");//$NON-NLS-1$
150
		return false;
151
	}
152
	
153
	/*
154
	 * @see ASTVisitor#visit(AnnotationTypeMemberDeclaration)
155
	 * @since 3.1
156
	 */
157
	public boolean visit(AnnotationTypeMemberDeclaration node) {
158
		if (node.getJavadoc() != null) {
159
			node.getJavadoc().accept(this);
160
		}
161
		printIndent();
162
		printModifiers(node.modifiers());
163
		node.getType().accept(this);
164
		this.buffer.append(" ");//$NON-NLS-1$
165
		node.getName().accept(this);
166
		this.buffer.append("()");//$NON-NLS-1$
167
		if (node.getDefault() != null) {
168
			this.buffer.append(" default ");//$NON-NLS-1$
169
			node.getDefault().accept(this);
170
		}
171
		this.buffer.append(";\n");//$NON-NLS-1$
172
		return false;
173
	}
174
	
175
	/*
176
	 * @see ASTVisitor#visit(AnonymousClassDeclaration)
177
	 */
178
	public boolean visit(AnonymousClassDeclaration node) {
179
		this.buffer.append("{\n");//$NON-NLS-1$
180
		this.indent++;
181
		for (Iterator it = node.bodyDeclarations().iterator(); it.hasNext(); ) {
182
			BodyDeclaration b = (BodyDeclaration) it.next();
183
			b.accept(this);
184
		}
185
		this.indent--;
186
		printIndent();
187
		this.buffer.append("}\n");//$NON-NLS-1$
188
		return false;
189
	}
190
191
	/*
192
	 * @see ASTVisitor#visit(ArrayAccess)
193
	 */
194
	public boolean visit(ArrayAccess node) {
195
		node.getArray().accept(this);
196
		this.buffer.append("[");//$NON-NLS-1$
197
		node.getIndex().accept(this);
198
		this.buffer.append("]");//$NON-NLS-1$
199
		return false;
200
	}
201
202
	/*
203
	 * @see ASTVisitor#visit(ArrayCreation)
204
	 */
205
	public boolean visit(ArrayCreation node) {
206
		this.buffer.append("new ");//$NON-NLS-1$
207
		ArrayType at = node.getType();
208
		int dims = at.getDimensions();
209
		Type elementType = at.getElementType();
210
		elementType.accept(this);
211
		for (Iterator it = node.dimensions().iterator(); it.hasNext(); ) {
212
			this.buffer.append("[");//$NON-NLS-1$
213
			Expression e = (Expression) it.next();
214
			e.accept(this);
215
			this.buffer.append("]");//$NON-NLS-1$
216
			dims--;
217
		}
218
		// add empty "[]" for each extra array dimension
219
		for (int i= 0; i < dims; i++) {
220
			this.buffer.append("[]");//$NON-NLS-1$
221
		}
222
		if (node.getInitializer() != null) {
223
			node.getInitializer().accept(this);
224
		}
225
		return false;
226
	}
227
228
	/*
229
	 * @see ASTVisitor#visit(ArrayInitializer)
230
	 */
231
	public boolean visit(ArrayInitializer node) {
232
		this.buffer.append("{");//$NON-NLS-1$
233
		for (Iterator it = node.expressions().iterator(); it.hasNext(); ) {
234
			Expression e = (Expression) it.next();
235
			e.accept(this);
236
			if (it.hasNext()) {
237
				this.buffer.append(",");//$NON-NLS-1$
238
			}
239
		}
240
		this.buffer.append("}");//$NON-NLS-1$
241
		return false;
242
	}
243
244
	/*
245
	 * @see ASTVisitor#visit(ArrayType)
246
	 */
247
	public boolean visit(ArrayType node) {
248
		node.getComponentType().accept(this);
249
		this.buffer.append("[]");//$NON-NLS-1$
250
		return false;
251
	}
252
253
	/*
254
	 * @see ASTVisitor#visit(AssertStatement)
255
	 */
256
	public boolean visit(AssertStatement node) {
257
		printIndent();
258
		this.buffer.append("assert ");//$NON-NLS-1$
259
		node.getExpression().accept(this);
260
		if (node.getMessage() != null) {
261
			this.buffer.append(" : ");//$NON-NLS-1$
262
			node.getMessage().accept(this);
263
		}
264
		this.buffer.append(";\n");//$NON-NLS-1$
265
		return false;
266
	}
267
268
	/*
269
	 * @see ASTVisitor#visit(Assignment)
270
	 */
271
	public boolean visit(Assignment node) {
272
		node.getLeftHandSide().accept(this);
273
		this.buffer.append(node.getOperator().toString());
274
		node.getRightHandSide().accept(this);
275
		return false;
276
	}
277
278
	/*
279
	 * @see ASTVisitor#visit(Block)
280
	 */
281
	public boolean visit(Block node) {
282
		this.buffer.append("{\n");//$NON-NLS-1$
283
		this.indent++;
284
		for (Iterator it = node.statements().iterator(); it.hasNext(); ) {
285
			Statement s = (Statement) it.next();
286
			s.accept(this);
287
		}
288
		this.indent--;
289
		printIndent();
290
		this.buffer.append("}\n");//$NON-NLS-1$
291
		return false;
292
	}
293
294
	/*
295
	 * @see ASTVisitor#visit(BlockComment)
296
	 * @since 3.0
297
	 */
298
	public boolean visit(BlockComment node) {
299
		printIndent();
300
		this.buffer.append("/* */");//$NON-NLS-1$
301
		return false;
302
	}
303
304
	/*
305
	 * @see ASTVisitor#visit(BooleanLiteral)
306
	 */
307
	public boolean visit(BooleanLiteral node) {
308
		if (node.booleanValue() == true) {
309
			this.buffer.append("true");//$NON-NLS-1$
310
		} else {
311
			this.buffer.append("false");//$NON-NLS-1$
312
		}
313
		return false;
314
	}
315
316
	/*
317
	 * @see ASTVisitor#visit(BreakStatement)
318
	 */
319
	public boolean visit(BreakStatement node) {
320
		printIndent();
321
		this.buffer.append("break");//$NON-NLS-1$
322
		if (node.getLabel() != null) {
323
			this.buffer.append(" ");//$NON-NLS-1$
324
			node.getLabel().accept(this);
325
		}
326
		this.buffer.append(";\n");//$NON-NLS-1$
327
		return false;
328
	}
329
330
	/*
331
	 * @see ASTVisitor#visit(CastExpression)
332
	 */
333
	public boolean visit(CastExpression node) {
334
		this.buffer.append("(");//$NON-NLS-1$
335
		node.getType().accept(this);
336
		this.buffer.append(")");//$NON-NLS-1$
337
		node.getExpression().accept(this);
338
		return false;
339
	}
340
341
	/*
342
	 * @see ASTVisitor#visit(CatchClause)
343
	 */
344
	public boolean visit(CatchClause node) {
345
		this.buffer.append("catch (");//$NON-NLS-1$
346
		node.getException().accept(this);
347
		this.buffer.append(") ");//$NON-NLS-1$
348
		node.getBody().accept(this);
349
		return false;
350
	}
351
352
	/*
353
	 * @see ASTVisitor#visit(CharacterLiteral)
354
	 */
355
	public boolean visit(CharacterLiteral node) {
356
		this.buffer.append(node.getEscapedValue());
357
		return false;
358
	}
359
360
	/*
361
	 * @see ASTVisitor#visit(ClassInstanceCreation)
362
	 */
363
	public boolean visit(ClassInstanceCreation node) {
364
		if (node.getExpression() != null) {
365
			node.getExpression().accept(this);
366
			this.buffer.append(".");//$NON-NLS-1$
367
		}
368
		this.buffer.append("new ");//$NON-NLS-1$
369
		if (node.getAST().apiLevel() == AST.JLS2_INTERNAL) {
370
			node.internalGetName().accept(this);
371
		}
372
		if (node.getAST().apiLevel() >= AST.JLS3) {
373
			if (!node.typeArguments().isEmpty()) {
374
				this.buffer.append("<");//$NON-NLS-1$
375
				for (Iterator it = node.typeArguments().iterator(); it.hasNext(); ) {
376
					Type t = (Type) it.next();
377
					t.accept(this);
378
					if (it.hasNext()) {
379
						this.buffer.append(",");//$NON-NLS-1$
380
					}
381
				}
382
				this.buffer.append(">");//$NON-NLS-1$
383
			}
384
			node.getType().accept(this);
385
		}
386
		this.buffer.append("(");//$NON-NLS-1$
387
		for (Iterator it = node.arguments().iterator(); it.hasNext(); ) {
388
			Expression e = (Expression) it.next();
389
			e.accept(this);
390
			if (it.hasNext()) {
391
				this.buffer.append(",");//$NON-NLS-1$
392
			}
393
		}
394
		this.buffer.append(")");//$NON-NLS-1$
395
		if (node.getAnonymousClassDeclaration() != null) {
396
			node.getAnonymousClassDeclaration().accept(this);
397
		}
398
		return false;
399
	}
400
401
	/*
402
	 * @see ASTVisitor#visit(CompilationUnit)
403
	 */
404
	public boolean visit(CompilationUnit node) {
405
		if (node.getPackage() != null) {
406
			node.getPackage().accept(this);
407
		}
408
		for (Iterator it = node.imports().iterator(); it.hasNext(); ) {
409
			ImportDeclaration d = (ImportDeclaration) it.next();
410
			d.accept(this);
411
		}
412
		for (Iterator it = node.types().iterator(); it.hasNext(); ) {
413
			AbstractTypeDeclaration d = (AbstractTypeDeclaration) it.next();
414
			d.accept(this);
415
		}
416
		return false;
417
	}
418
419
	/*
420
	 * @see ASTVisitor#visit(ConditionalExpression)
421
	 */
422
	public boolean visit(ConditionalExpression node) {
423
		node.getExpression().accept(this);
424
		this.buffer.append(" ? ");//$NON-NLS-1$
425
		node.getThenExpression().accept(this);
426
		this.buffer.append(" : ");//$NON-NLS-1$
427
		node.getElseExpression().accept(this);
428
		return false;
429
	}
430
431
	/*
432
	 * @see ASTVisitor#visit(ConstructorInvocation)
433
	 */
434
	public boolean visit(ConstructorInvocation node) {
435
		printIndent();
436
		if (node.getAST().apiLevel() >= AST.JLS3) {
437
			if (!node.typeArguments().isEmpty()) {
438
				this.buffer.append("<");//$NON-NLS-1$
439
				for (Iterator it = node.typeArguments().iterator(); it.hasNext(); ) {
440
					Type t = (Type) it.next();
441
					t.accept(this);
442
					if (it.hasNext()) {
443
						this.buffer.append(",");//$NON-NLS-1$
444
					}
445
				}
446
				this.buffer.append(">");//$NON-NLS-1$
447
			}
448
		}
449
		this.buffer.append("this(");//$NON-NLS-1$
450
		for (Iterator it = node.arguments().iterator(); it.hasNext(); ) {
451
			Expression e = (Expression) it.next();
452
			e.accept(this);
453
			if (it.hasNext()) {
454
				this.buffer.append(",");//$NON-NLS-1$
455
			}
456
		}
457
		this.buffer.append(");\n");//$NON-NLS-1$
458
		return false;
459
	}
460
461
	/*
462
	 * @see ASTVisitor#visit(ContinueStatement)
463
	 */
464
	public boolean visit(ContinueStatement node) {
465
		printIndent();
466
		this.buffer.append("continue");//$NON-NLS-1$
467
		if (node.getLabel() != null) {
468
			this.buffer.append(" ");//$NON-NLS-1$
469
			node.getLabel().accept(this);
470
		}
471
		this.buffer.append(";\n");//$NON-NLS-1$
472
		return false;
473
	}
474
475
	/*
476
	 * @see ASTVisitor#visit(DoStatement)
477
	 */
478
	public boolean visit(DoStatement node) {
479
		printIndent();
480
		this.buffer.append("do ");//$NON-NLS-1$
481
		node.getBody().accept(this);
482
		this.buffer.append(" while (");//$NON-NLS-1$
483
		node.getExpression().accept(this);
484
		this.buffer.append(");\n");//$NON-NLS-1$
485
		return false;
486
	}
487
488
	/*
489
	 * @see ASTVisitor#visit(EmptyStatement)
490
	 */
491
	public boolean visit(EmptyStatement node) {
492
		printIndent();
493
		this.buffer.append(";\n");//$NON-NLS-1$
494
		return false;
495
	}
496
497
	/*
498
	 * @see ASTVisitor#visit(EnhancedForStatement)
499
	 * @since 3.1
500
	 */
501
	public boolean visit(EnhancedForStatement node) {
502
		printIndent();
503
		this.buffer.append("for (");//$NON-NLS-1$
504
		node.getParameter().accept(this);
505
		this.buffer.append(" : ");//$NON-NLS-1$
506
		node.getExpression().accept(this);
507
		this.buffer.append(") ");//$NON-NLS-1$
508
		node.getBody().accept(this);
509
		return false;
510
	}
511
512
	/*
513
	 * @see ASTVisitor#visit(EnumConstantDeclaration)
514
	 * @since 3.1
515
	 */
516
	public boolean visit(EnumConstantDeclaration node) {
517
		if (node.getJavadoc() != null) {
518
			node.getJavadoc().accept(this);
519
		}
520
		printIndent();
521
		printModifiers(node.modifiers());
522
		node.getName().accept(this);
523
		if (!node.arguments().isEmpty()) {
524
			this.buffer.append("(");//$NON-NLS-1$
525
			for (Iterator it = node.arguments().iterator(); it.hasNext(); ) {
526
				Expression e = (Expression) it.next();
527
				e.accept(this);
528
				if (it.hasNext()) {
529
					this.buffer.append(",");//$NON-NLS-1$
530
				}
531
			}
532
			this.buffer.append(")");//$NON-NLS-1$
533
		}
534
		if (node.getAnonymousClassDeclaration() != null) {
535
			node.getAnonymousClassDeclaration().accept(this);
536
		}
537
		return false;
538
	}
539
540
	/*
541
	 * @see ASTVisitor#visit(EnumDeclaration)
542
	 * @since 3.1
543
	 */
544
	public boolean visit(EnumDeclaration node) {
545
		if (node.getJavadoc() != null) {
546
			node.getJavadoc().accept(this);
547
		}
548
		printIndent();
549
		printModifiers(node.modifiers());
550
		this.buffer.append("enum ");//$NON-NLS-1$
551
		node.getName().accept(this);
552
		this.buffer.append(" ");//$NON-NLS-1$
553
		if (!node.superInterfaceTypes().isEmpty()) {
554
			this.buffer.append("implements ");//$NON-NLS-1$
555
			for (Iterator it = node.superInterfaceTypes().iterator(); it.hasNext(); ) {
556
				Type t = (Type) it.next();
557
				t.accept(this);
558
				if (it.hasNext()) {
559
					this.buffer.append(", ");//$NON-NLS-1$
560
				}
561
			}
562
			this.buffer.append(" ");//$NON-NLS-1$
563
		}
564
		this.buffer.append("{");//$NON-NLS-1$
565
		for (Iterator it = node.enumConstants().iterator(); it.hasNext(); ) {
566
			EnumConstantDeclaration d = (EnumConstantDeclaration) it.next();
567
			d.accept(this);
568
			// enum constant declarations do not include punctuation
569
			if (it.hasNext()) {
570
				// enum constant declarations are separated by commas
571
				this.buffer.append(", ");//$NON-NLS-1$
572
			}
573
		}
574
		if (!node.bodyDeclarations().isEmpty()) {
575
			this.buffer.append("; ");//$NON-NLS-1$
576
			for (Iterator it = node.bodyDeclarations().iterator(); it.hasNext(); ) {
577
				BodyDeclaration d = (BodyDeclaration) it.next();
578
				d.accept(this);
579
				// other body declarations include trailing punctuation
580
			}
581
		}
582
		this.buffer.append("}\n");//$NON-NLS-1$
583
		return false;
584
	}
585
586
	/*
587
	 * @see ASTVisitor#visit(ExpressionStatement)
588
	 */
589
	public boolean visit(ExpressionStatement node) {
590
		printIndent();
591
		node.getExpression().accept(this);
592
		this.buffer.append(";\n");//$NON-NLS-1$
593
		return false;
594
	}
595
596
	/*
597
	 * @see ASTVisitor#visit(FieldAccess)
598
	 */
599
	public boolean visit(FieldAccess node) {
600
		node.getExpression().accept(this);
601
		this.buffer.append(".");//$NON-NLS-1$
602
		node.getName().accept(this);
603
		return false;
604
	}
605
606
	/*
607
	 * @see ASTVisitor#visit(FieldDeclaration)
608
	 */
609
	public boolean visit(FieldDeclaration node) {
610
		if (node.getJavadoc() != null) {
611
			node.getJavadoc().accept(this);
612
		}
613
		printIndent();
614
		if (node.getAST().apiLevel() == AST.JLS2_INTERNAL) {
615
			printModifiers(node.getModifiers());
616
		}
617
		if (node.getAST().apiLevel() >= AST.JLS3) {
618
			printModifiers(node.modifiers());
619
		}
620
		node.getType().accept(this);
621
		this.buffer.append(" ");//$NON-NLS-1$
622
		for (Iterator it = node.fragments().iterator(); it.hasNext(); ) {
623
			VariableDeclarationFragment f = (VariableDeclarationFragment) it.next();
624
			f.accept(this);
625
			if (it.hasNext()) {
626
				this.buffer.append(", ");//$NON-NLS-1$
627
			}
628
		}
629
		this.buffer.append(";\n");//$NON-NLS-1$
630
		return false;
631
	}
632
633
	/*
634
	 * @see ASTVisitor#visit(ForStatement)
635
	 */
636
	public boolean visit(ForStatement node) {
637
		printIndent();
638
		this.buffer.append("for (");//$NON-NLS-1$
639
		for (Iterator it = node.initializers().iterator(); it.hasNext(); ) {
640
			Expression e = (Expression) it.next();
641
			e.accept(this);
642
			if (it.hasNext()) buffer.append(", ");//$NON-NLS-1$
643
		}
644
		this.buffer.append("; ");//$NON-NLS-1$
645
		if (node.getExpression() != null) {
646
			node.getExpression().accept(this);
647
		}
648
		this.buffer.append("; ");//$NON-NLS-1$
649
		for (Iterator it = node.updaters().iterator(); it.hasNext(); ) {
650
			Expression e = (Expression) it.next();
651
			e.accept(this);
652
			if (it.hasNext()) buffer.append(", ");//$NON-NLS-1$
653
		}
654
		this.buffer.append(") ");//$NON-NLS-1$
655
		node.getBody().accept(this);
656
		return false;
657
	}
658
659
	/*
660
	 * @see ASTVisitor#visit(IfStatement)
661
	 */
662
	public boolean visit(IfStatement node) {
663
		printIndent();
664
		this.buffer.append("if (");//$NON-NLS-1$
665
		node.getExpression().accept(this);
666
		this.buffer.append(") ");//$NON-NLS-1$
667
		node.getThenStatement().accept(this);
668
		if (node.getElseStatement() != null) {
669
			this.buffer.append(" else ");//$NON-NLS-1$
670
			node.getElseStatement().accept(this);
671
		}
672
		return false;
673
	}
674
675
	/*
676
	 * @see ASTVisitor#visit(ImportDeclaration)
677
	 */
678
	public boolean visit(ImportDeclaration node) {
679
		printIndent();
680
		this.buffer.append("import ");//$NON-NLS-1$
681
		if (node.getAST().apiLevel() >= AST.JLS3) {
682
			if (node.isStatic()) {
683
				this.buffer.append("static ");//$NON-NLS-1$
684
			}
685
		}
686
		node.getName().accept(this);
687
		if (node.isOnDemand()) {
688
			this.buffer.append(".*");//$NON-NLS-1$
689
		}
690
		this.buffer.append(";\n");//$NON-NLS-1$
691
		return false;
692
	}
693
694
	/*
695
	 * @see ASTVisitor#visit(InfixExpression)
696
	 */
697
	public boolean visit(InfixExpression node) {
698
		node.getLeftOperand().accept(this);
699
		this.buffer.append(' ');  // for cases like x= i - -1; or x= i++ + ++i;
700
		this.buffer.append(node.getOperator().toString());
701
		this.buffer.append(' ');
702
		node.getRightOperand().accept(this);
703
		final List extendedOperands = node.extendedOperands();
704
		if (extendedOperands.size() != 0) {
705
			this.buffer.append(' ');
706
			for (Iterator it = extendedOperands.iterator(); it.hasNext(); ) {
707
				this.buffer.append(node.getOperator().toString()).append(' ');
708
				Expression e = (Expression) it.next();
709
				e.accept(this);
710
			}
711
		}
712
		return false;
713
	}
714
715
	/*
716
	 * @see ASTVisitor#visit(InstanceofExpression)
717
	 */
718
	public boolean visit(InstanceofExpression node) {
719
		node.getLeftOperand().accept(this);
720
		this.buffer.append(" instanceof ");//$NON-NLS-1$
721
		node.getRightOperand().accept(this);
722
		return false;
723
	}
724
725
	/*
726
	 * @see ASTVisitor#visit(Initializer)
727
	 */
728
	public boolean visit(Initializer node) {
729
		if (node.getJavadoc() != null) {
730
			node.getJavadoc().accept(this);
731
		}
732
		if (node.getAST().apiLevel() == AST.JLS2_INTERNAL) {
733
			printModifiers(node.getModifiers());
734
		}
735
		if (node.getAST().apiLevel() >= AST.JLS3) {
736
			printModifiers(node.modifiers());
737
		}
738
		node.getBody().accept(this);
739
		return false;
740
	}
741
742
	/*
743
	 * @see ASTVisitor#visit(Javadoc)
744
	 */
745
	public boolean visit(Javadoc node) {
746
		printIndent();
747
		this.buffer.append("/** ");//$NON-NLS-1$
748
		for (Iterator it = node.tags().iterator(); it.hasNext(); ) {
749
			ASTNode e = (ASTNode) it.next();
750
			e.accept(this);
751
		}
752
		this.buffer.append("\n */\n");//$NON-NLS-1$
753
		return false;
754
	}
755
756
	/*
757
	 * @see ASTVisitor#visit(LabeledStatement)
758
	 */
759
	public boolean visit(LabeledStatement node) {
760
		printIndent();
761
		node.getLabel().accept(this);
762
		this.buffer.append(": ");//$NON-NLS-1$
763
		node.getBody().accept(this);
764
		return false;
765
	}
766
767
	/*
768
	 * @see ASTVisitor#visit(LineComment)
769
	 * @since 3.0
770
	 */
771
	public boolean visit(LineComment node) {
772
		this.buffer.append("//\n");//$NON-NLS-1$
773
		return false;
774
	}
775
776
	/*
777
	 * @see ASTVisitor#visit(MarkerAnnotation)
778
	 * @since 3.1
779
	 */
780
	public boolean visit(MarkerAnnotation node) {
781
		this.buffer.append("@");//$NON-NLS-1$
782
		node.getTypeName().accept(this);
783
		return false;
784
	}
785
	
786
	/*
787
	 * @see ASTVisitor#visit(MemberRef)
788
	 * @since 3.0
789
	 */
790
	public boolean visit(MemberRef node) {
791
		if (node.getQualifier() != null) {
792
			node.getQualifier().accept(this);
793
		}
794
		this.buffer.append("#");//$NON-NLS-1$
795
		node.getName().accept(this);
796
		return false;
797
	}
798
	
799
	/*
800
	 * @see ASTVisitor#visit(MemberValuePair)
801
	 * @since 3.1
802
	 */
803
	public boolean visit(MemberValuePair node) {
804
		node.getName().accept(this);
805
		this.buffer.append("=");//$NON-NLS-1$
806
		node.getValue().accept(this);
807
		return false;
808
	}
809
	
810
	/*
811
	 * @see ASTVisitor#visit(MethodRef)
812
	 * @since 3.0
813
	 */
814
	public boolean visit(MethodRef node) {
815
		if (node.getQualifier() != null) {
816
			node.getQualifier().accept(this);
817
		}
818
		this.buffer.append("#");//$NON-NLS-1$
819
		node.getName().accept(this);
820
		this.buffer.append("(");//$NON-NLS-1$
821
		for (Iterator it = node.parameters().iterator(); it.hasNext(); ) {
822
			MethodRefParameter e = (MethodRefParameter) it.next();
823
			e.accept(this);
824
			if (it.hasNext()) {
825
				this.buffer.append(",");//$NON-NLS-1$
826
			}
827
		}
828
		this.buffer.append(")");//$NON-NLS-1$
829
		return false;
830
	}
831
	
832
	/*
833
	 * @see ASTVisitor#visit(MethodRefParameter)
834
	 * @since 3.0
835
	 */
836
	public boolean visit(MethodRefParameter node) {
837
		node.getType().accept(this);
838
		if (node.getAST().apiLevel() >= AST.JLS3) {
839
			if (node.isVarargs()) {
840
				this.buffer.append("...");//$NON-NLS-1$
841
			}
842
		}
843
		if (node.getName() != null) {
844
			this.buffer.append(" ");//$NON-NLS-1$
845
			node.getName().accept(this);
846
		}
847
		return false;
848
	}
849
	
850
	/*
851
	 * @see ASTVisitor#visit(MethodDeclaration)
852
	 */
853
	public boolean visit(MethodDeclaration node) {
854
		if (node.getJavadoc() != null) {
855
			node.getJavadoc().accept(this);
856
		}
857
		printIndent();
858
		if (node.getAST().apiLevel() == AST.JLS2_INTERNAL) {
859
			printModifiers(node.getModifiers());
860
		}
861
		if (node.getAST().apiLevel() >= AST.JLS3) {
862
			printModifiers(node.modifiers());
863
			if (!node.typeParameters().isEmpty()) {
864
				this.buffer.append("<");//$NON-NLS-1$
865
				for (Iterator it = node.typeParameters().iterator(); it.hasNext(); ) {
866
					TypeParameter t = (TypeParameter) it.next();
867
					t.accept(this);
868
					if (it.hasNext()) {
869
						this.buffer.append(",");//$NON-NLS-1$
870
					}
871
				}
872
				this.buffer.append(">");//$NON-NLS-1$
873
			}
874
		}
875
		if (!node.isConstructor()) {
876
			if (node.getAST().apiLevel() == AST.JLS2_INTERNAL) {
877
				node.internalGetReturnType().accept(this);
878
			} else {
879
				if (node.getReturnType2() != null) {
880
					node.getReturnType2().accept(this);
881
				} else {
882
					// methods really ought to have a return type
883
					this.buffer.append("void");//$NON-NLS-1$
884
				}
885
			}
886
			this.buffer.append(" ");//$NON-NLS-1$
887
		}
888
		node.getName().accept(this);
889
		this.buffer.append("(");//$NON-NLS-1$
890
		for (Iterator it = node.parameters().iterator(); it.hasNext(); ) {
891
			SingleVariableDeclaration v = (SingleVariableDeclaration) it.next();
892
			v.accept(this);
893
			if (it.hasNext()) {
894
				this.buffer.append(",");//$NON-NLS-1$
895
			}
896
		}
897
		this.buffer.append(")");//$NON-NLS-1$
898
		for (int i = 0; i < node.getExtraDimensions(); i++) {
899
			this.buffer.append("[]"); //$NON-NLS-1$
900
		}		
901
		if (!node.thrownExceptions().isEmpty()) {
902
			this.buffer.append(" throws ");//$NON-NLS-1$
903
			for (Iterator it = node.thrownExceptions().iterator(); it.hasNext(); ) {
904
				Name n = (Name) it.next();
905
				n.accept(this);
906
				if (it.hasNext()) {
907
					this.buffer.append(", ");//$NON-NLS-1$
908
				}
909
			}
910
			this.buffer.append(" ");//$NON-NLS-1$
911
		}
912
		if (node.getBody() == null) {
913
			this.buffer.append(";\n");//$NON-NLS-1$
914
		} else {
915
			node.getBody().accept(this);
916
		}
917
		return false;
918
	}
919
920
	/*
921
	 * @see ASTVisitor#visit(MethodInvocation)
922
	 */
923
	public boolean visit(MethodInvocation node) {
924
		if (node.getExpression() != null) {
925
			node.getExpression().accept(this);
926
			this.buffer.append(".");//$NON-NLS-1$
927
		}
928
		if (node.getAST().apiLevel() >= AST.JLS3) {
929
			if (!node.typeArguments().isEmpty()) {
930
				this.buffer.append("<");//$NON-NLS-1$
931
				for (Iterator it = node.typeArguments().iterator(); it.hasNext(); ) {
932
					Type t = (Type) it.next();
933
					t.accept(this);
934
					if (it.hasNext()) {
935
						this.buffer.append(",");//$NON-NLS-1$
936
					}
937
				}
938
				this.buffer.append(">");//$NON-NLS-1$
939
			}
940
		}
941
		node.getName().accept(this);
942
		this.buffer.append("(");//$NON-NLS-1$
943
		for (Iterator it = node.arguments().iterator(); it.hasNext(); ) {
944
			Expression e = (Expression) it.next();
945
			e.accept(this);
946
			if (it.hasNext()) {
947
				this.buffer.append(",");//$NON-NLS-1$
948
			}
949
		}
950
		this.buffer.append(")");//$NON-NLS-1$
951
		return false;
952
	}
953
954
	/*
955
	 * @see ASTVisitor#visit(Modifier)
956
	 * @since 3.1
957
	 */
958
	public boolean visit(Modifier node) {
959
		this.buffer.append(node.getKeyword().toString());
960
		return false;
961
	}
962
	
963
	/*
964
	 * @see ASTVisitor#visit(NormalAnnotation)
965
	 * @since 3.1
966
	 */
967
	public boolean visit(NormalAnnotation node) {
968
		this.buffer.append("@");//$NON-NLS-1$
969
		node.getTypeName().accept(this);
970
		this.buffer.append("(");//$NON-NLS-1$
971
		for (Iterator it = node.values().iterator(); it.hasNext(); ) {
972
			MemberValuePair p = (MemberValuePair) it.next();
973
			p.accept(this);
974
			if (it.hasNext()) {
975
				this.buffer.append(",");//$NON-NLS-1$
976
			}
977
		}
978
		this.buffer.append(")");//$NON-NLS-1$
979
		return false;
980
	}
981
	
982
	/*
983
	 * @see ASTVisitor#visit(NullLiteral)
984
	 */
985
	public boolean visit(NullLiteral node) {
986
		this.buffer.append("null");//$NON-NLS-1$
987
		return false;
988
	}
989
990
	/*
991
	 * @see ASTVisitor#visit(NumberLiteral)
992
	 */
993
	public boolean visit(NumberLiteral node) {
994
		this.buffer.append(node.getToken());
995
		return false;
996
	}
997
998
	/*
999
	 * @see ASTVisitor#visit(PackageDeclaration)
1000
	 */
1001
	public boolean visit(PackageDeclaration node) {
1002
		if (node.getAST().apiLevel() >= AST.JLS3) {
1003
			if (node.getJavadoc() != null) {
1004
				node.getJavadoc().accept(this);
1005
			}
1006
			for (Iterator it = node.annotations().iterator(); it.hasNext(); ) {
1007
				Annotation p = (Annotation) it.next();
1008
				p.accept(this);
1009
				this.buffer.append(" ");//$NON-NLS-1$
1010
			}
1011
		}
1012
		printIndent();
1013
		this.buffer.append("package ");//$NON-NLS-1$
1014
		node.getName().accept(this);
1015
		this.buffer.append(";\n");//$NON-NLS-1$
1016
		return false;
1017
	}
1018
1019
	/*
1020
	 * @see ASTVisitor#visit(ParameterizedType)
1021
	 * @since 3.1
1022
	 */
1023
	public boolean visit(ParameterizedType node) {
1024
		node.getType().accept(this);
1025
		this.buffer.append("<");//$NON-NLS-1$
1026
		for (Iterator it = node.typeArguments().iterator(); it.hasNext(); ) {
1027
			Type t = (Type) it.next();
1028
			t.accept(this);
1029
			if (it.hasNext()) {
1030
				this.buffer.append(",");//$NON-NLS-1$
1031
			}
1032
		}
1033
		this.buffer.append(">");//$NON-NLS-1$
1034
		return false;
1035
	}
1036
1037
	/*
1038
	 * @see ASTVisitor#visit(ParenthesizedExpression)
1039
	 */
1040
	public boolean visit(ParenthesizedExpression node) {
1041
		this.buffer.append("(");//$NON-NLS-1$
1042
		node.getExpression().accept(this);
1043
		this.buffer.append(")");//$NON-NLS-1$
1044
		return false;
1045
	}
1046
1047
	/*
1048
	 * @see ASTVisitor#visit(PostfixExpression)
1049
	 */
1050
	public boolean visit(PostfixExpression node) {
1051
		node.getOperand().accept(this);
1052
		this.buffer.append(node.getOperator().toString());
1053
		return false;
1054
	}
1055
1056
	/*
1057
	 * @see ASTVisitor#visit(PrefixExpression)
1058
	 */
1059
	public boolean visit(PrefixExpression node) {
1060
		this.buffer.append(node.getOperator().toString());
1061
		node.getOperand().accept(this);
1062
		return false;
1063
	}
1064
1065
	/*
1066
	 * @see ASTVisitor#visit(PrimitiveType)
1067
	 */
1068
	public boolean visit(PrimitiveType node) {
1069
		this.buffer.append(node.getPrimitiveTypeCode().toString());
1070
		return false;
1071
	}
1072
1073
	/*
1074
	 * @see ASTVisitor#visit(QualifiedName)
1075
	 */
1076
	public boolean visit(QualifiedName node) {
1077
		node.getQualifier().accept(this);
1078
		this.buffer.append(".");//$NON-NLS-1$
1079
		node.getName().accept(this);
1080
		return false;
1081
	}
1082
1083
	/*
1084
	 * @see ASTVisitor#visit(QualifiedType)
1085
	 * @since 3.1
1086
	 */
1087
	public boolean visit(QualifiedType node) {
1088
		node.getQualifier().accept(this);
1089
		this.buffer.append(".");//$NON-NLS-1$
1090
		node.getName().accept(this);
1091
		return false;
1092
	}
1093
1094
	/*
1095
	 * @see ASTVisitor#visit(ReturnStatement)
1096
	 */
1097
	public boolean visit(ReturnStatement node) {
1098
		printIndent();
1099
		this.buffer.append("return");//$NON-NLS-1$
1100
		if (node.getExpression() != null) {
1101
			this.buffer.append(" ");//$NON-NLS-1$
1102
			node.getExpression().accept(this);
1103
		}
1104
		this.buffer.append(";\n");//$NON-NLS-1$
1105
		return false;
1106
	}
1107
1108
	/*
1109
	 * @see ASTVisitor#visit(SimpleName)
1110
	 */
1111
	public boolean visit(SimpleName node) {
1112
		this.buffer.append(node.getIdentifier());
1113
		return false;
1114
	}
1115
1116
	/*
1117
	 * @see ASTVisitor#visit(SimpleType)
1118
	 */
1119
	public boolean visit(SimpleType node) {
1120
		return true;
1121
	}
1122
1123
	/*
1124
	 * @see ASTVisitor#visit(SingleMemberAnnotation)
1125
	 * @since 3.1
1126
	 */
1127
	public boolean visit(SingleMemberAnnotation node) {
1128
		this.buffer.append("@");//$NON-NLS-1$
1129
		node.getTypeName().accept(this);
1130
		this.buffer.append("(");//$NON-NLS-1$
1131
		node.getValue().accept(this);
1132
		this.buffer.append(")");//$NON-NLS-1$
1133
		return false;
1134
	}
1135
	
1136
	/*
1137
	 * @see ASTVisitor#visit(SingleVariableDeclaration)
1138
	 */
1139
	public boolean visit(SingleVariableDeclaration node) {
1140
		printIndent();
1141
		if (node.getAST().apiLevel() == AST.JLS2_INTERNAL) {
1142
			printModifiers(node.getModifiers());
1143
		}
1144
		if (node.getAST().apiLevel() >= AST.JLS3) {
1145
			printModifiers(node.modifiers());
1146
		}
1147
		node.getType().accept(this);
1148
		if (node.getAST().apiLevel() >= AST.JLS3) {
1149
			if (node.isVarargs()) {
1150
				this.buffer.append("...");//$NON-NLS-1$
1151
			}
1152
		}
1153
		this.buffer.append(" ");//$NON-NLS-1$
1154
		node.getName().accept(this);
1155
		for (int i = 0; i < node.getExtraDimensions(); i++) {
1156
			this.buffer.append("[]"); //$NON-NLS-1$
1157
		}			
1158
		if (node.getInitializer() != null) {
1159
			this.buffer.append("=");//$NON-NLS-1$
1160
			node.getInitializer().accept(this);
1161
		}
1162
		return false;
1163
	}
1164
1165
	/*
1166
	 * @see ASTVisitor#visit(StringLiteral)
1167
	 */
1168
	public boolean visit(StringLiteral node) {
1169
		this.buffer.append(node.getEscapedValue());
1170
		return false;
1171
	}
1172
1173
	/*
1174
	 * @see ASTVisitor#visit(SuperConstructorInvocation)
1175
	 */
1176
	public boolean visit(SuperConstructorInvocation node) {
1177
		printIndent();
1178
		if (node.getExpression() != null) {
1179
			node.getExpression().accept(this);
1180
			this.buffer.append(".");//$NON-NLS-1$
1181
		}
1182
		if (node.getAST().apiLevel() >= AST.JLS3) {
1183
			if (!node.typeArguments().isEmpty()) {
1184
				this.buffer.append("<");//$NON-NLS-1$
1185
				for (Iterator it = node.typeArguments().iterator(); it.hasNext(); ) {
1186
					Type t = (Type) it.next();
1187
					t.accept(this);
1188
					if (it.hasNext()) {
1189
						this.buffer.append(",");//$NON-NLS-1$
1190
					}
1191
				}
1192
				this.buffer.append(">");//$NON-NLS-1$
1193
			}
1194
		}
1195
		this.buffer.append("super(");//$NON-NLS-1$
1196
		for (Iterator it = node.arguments().iterator(); it.hasNext(); ) {
1197
			Expression e = (Expression) it.next();
1198
			e.accept(this);
1199
			if (it.hasNext()) {
1200
				this.buffer.append(",");//$NON-NLS-1$
1201
			}
1202
		}
1203
		this.buffer.append(");\n");//$NON-NLS-1$
1204
		return false;
1205
	}
1206
1207
	/*
1208
	 * @see ASTVisitor#visit(SuperFieldAccess)
1209
	 */
1210
	public boolean visit(SuperFieldAccess node) {
1211
		if (node.getQualifier() != null) {
1212
			node.getQualifier().accept(this);
1213
			this.buffer.append(".");//$NON-NLS-1$
1214
		}
1215
		this.buffer.append("super.");//$NON-NLS-1$
1216
		node.getName().accept(this);
1217
		return false;
1218
	}
1219
1220
	/*
1221
	 * @see ASTVisitor#visit(SuperMethodInvocation)
1222
	 */
1223
	public boolean visit(SuperMethodInvocation node) {
1224
		if (node.getQualifier() != null) {
1225
			node.getQualifier().accept(this);
1226
			this.buffer.append(".");//$NON-NLS-1$
1227
		}
1228
		this.buffer.append("super.");//$NON-NLS-1$
1229
		if (node.getAST().apiLevel() >= AST.JLS3) {
1230
			if (!node.typeArguments().isEmpty()) {
1231
				this.buffer.append("<");//$NON-NLS-1$
1232
				for (Iterator it = node.typeArguments().iterator(); it.hasNext(); ) {
1233
					Type t = (Type) it.next();
1234
					t.accept(this);
1235
					if (it.hasNext()) {
1236
						this.buffer.append(",");//$NON-NLS-1$
1237
					}
1238
				}
1239
				this.buffer.append(">");//$NON-NLS-1$
1240
			}
1241
		}
1242
		node.getName().accept(this);
1243
		this.buffer.append("(");//$NON-NLS-1$
1244
		for (Iterator it = node.arguments().iterator(); it.hasNext(); ) {
1245
			Expression e = (Expression) it.next();
1246
			e.accept(this);
1247
			if (it.hasNext()) {
1248
				this.buffer.append(",");//$NON-NLS-1$
1249
			}
1250
		}
1251
		this.buffer.append(")");//$NON-NLS-1$
1252
		return false;
1253
	}
1254
1255
	/*
1256
	 * @see ASTVisitor#visit(SwitchCase)
1257
	 */
1258
	public boolean visit(SwitchCase node) {
1259
		if (node.isDefault()) {
1260
			this.buffer.append("default :\n");//$NON-NLS-1$
1261
		} else {
1262
			this.buffer.append("case ");//$NON-NLS-1$
1263
			node.getExpression().accept(this);
1264
			this.buffer.append(":\n");//$NON-NLS-1$
1265
		}
1266
		this.indent++; //decremented in visit(SwitchStatement)
1267
		return false;
1268
	}
1269
1270
	/*
1271
	 * @see ASTVisitor#visit(SwitchStatement)
1272
	 */
1273
	public boolean visit(SwitchStatement node) {
1274
		this.buffer.append("switch (");//$NON-NLS-1$
1275
		node.getExpression().accept(this);
1276
		this.buffer.append(") ");//$NON-NLS-1$
1277
		this.buffer.append("{\n");//$NON-NLS-1$
1278
		this.indent++;
1279
		for (Iterator it = node.statements().iterator(); it.hasNext(); ) {
1280
			Statement s = (Statement) it.next();
1281
			s.accept(this);
1282
			this.indent--; // incremented in visit(SwitchCase)
1283
		}
1284
		this.indent--;
1285
		printIndent();
1286
		this.buffer.append("}\n");//$NON-NLS-1$
1287
		return false;
1288
	}
1289
1290
	/*
1291
	 * @see ASTVisitor#visit(SynchronizedStatement)
1292
	 */
1293
	public boolean visit(SynchronizedStatement node) {
1294
		this.buffer.append("synchronized (");//$NON-NLS-1$
1295
		node.getExpression().accept(this);
1296
		this.buffer.append(") ");//$NON-NLS-1$
1297
		node.getBody().accept(this);
1298
		return false;
1299
	}
1300
1301
	/*
1302
	 * @see ASTVisitor#visit(TagElement)
1303
	 * @since 3.0
1304
	 */
1305
	public boolean visit(TagElement node) {
1306
		if (node.isNested()) {
1307
			// nested tags are always enclosed in braces
1308
			this.buffer.append("{");//$NON-NLS-1$
1309
		} else {
1310
			// top-level tags always begin on a new line
1311
			this.buffer.append("\n * ");//$NON-NLS-1$
1312
		}
1313
		boolean previousRequiresWhiteSpace = false;
1314
		if (node.getTagName() != null) {
1315
			this.buffer.append(node.getTagName());
1316
			previousRequiresWhiteSpace = true;
1317
		}
1318
		boolean previousRequiresNewLine = false;
1319
		for (Iterator it = node.fragments().iterator(); it.hasNext(); ) {
1320
			ASTNode e = (ASTNode) it.next();
1321
			// assume text elements include necessary leading and trailing whitespace
1322
			// but Name, MemberRef, MethodRef, and nested TagElement do not include white space
1323
			boolean currentIncludesWhiteSpace = (e instanceof TextElement);
1324
			if (previousRequiresNewLine && currentIncludesWhiteSpace) {
1325
				this.buffer.append("\n * ");//$NON-NLS-1$
1326
			}
1327
			previousRequiresNewLine = currentIncludesWhiteSpace;
1328
			// add space if required to separate
1329
			if (previousRequiresWhiteSpace && !currentIncludesWhiteSpace) {
1330
				this.buffer.append(" "); //$NON-NLS-1$
1331
			}
1332
			e.accept(this);
1333
			previousRequiresWhiteSpace = !currentIncludesWhiteSpace && !(e instanceof TagElement);
1334
		}
1335
		if (node.isNested()) {
1336
			this.buffer.append("}");//$NON-NLS-1$
1337
		}
1338
		return false;
1339
	}
1340
	
1341
	/*
1342
	 * @see ASTVisitor#visit(TextElement)
1343
	 * @since 3.0
1344
	 */
1345
	public boolean visit(TextElement node) {
1346
		this.buffer.append(node.getText());
1347
		return false;
1348
	}
1349
	
1350
	/*
1351
	 * @see ASTVisitor#visit(ThisExpression)
1352
	 */
1353
	public boolean visit(ThisExpression node) {
1354
		if (node.getQualifier() != null) {
1355
			node.getQualifier().accept(this);
1356
			this.buffer.append(".");//$NON-NLS-1$
1357
		}
1358
		this.buffer.append("this");//$NON-NLS-1$
1359
		return false;
1360
	}
1361
1362
	/*
1363
	 * @see ASTVisitor#visit(ThrowStatement)
1364
	 */
1365
	public boolean visit(ThrowStatement node) {
1366
		printIndent();
1367
		this.buffer.append("throw ");//$NON-NLS-1$
1368
		node.getExpression().accept(this);
1369
		this.buffer.append(";\n");//$NON-NLS-1$
1370
		return false;
1371
	}
1372
1373
	/*
1374
	 * @see ASTVisitor#visit(TryStatement)
1375
	 */
1376
	public boolean visit(TryStatement node) {
1377
		printIndent();
1378
		this.buffer.append("try ");//$NON-NLS-1$
1379
		node.getBody().accept(this);
1380
		this.buffer.append(" ");//$NON-NLS-1$
1381
		for (Iterator it = node.catchClauses().iterator(); it.hasNext(); ) {
1382
			CatchClause cc = (CatchClause) it.next();
1383
			cc.accept(this);
1384
		}
1385
		if (node.getFinally() != null) {
1386
			this.buffer.append(" finally ");//$NON-NLS-1$
1387
			node.getFinally().accept(this);
1388
		}
1389
		return false;
1390
	}
1391
1392
	/*
1393
	 * @see ASTVisitor#visit(TypeDeclaration)
1394
	 */
1395
	public boolean visit(TypeDeclaration node) {
1396
		if (node.getJavadoc() != null) {
1397
			node.getJavadoc().accept(this);
1398
		}
1399
		if (node.getAST().apiLevel() == AST.JLS2_INTERNAL) {
1400
			printModifiers(node.getModifiers());
1401
		}
1402
		if (node.getAST().apiLevel() >= AST.JLS3) {
1403
			printModifiers(node.modifiers());
1404
		}
1405
		this.buffer.append(node.isInterface() ? "interface " : "class ");//$NON-NLS-2$//$NON-NLS-1$
1406
		node.getName().accept(this);
1407
		if (node.getAST().apiLevel() >= AST.JLS3) {
1408
			if (!node.typeParameters().isEmpty()) {
1409
				this.buffer.append("<");//$NON-NLS-1$
1410
				for (Iterator it = node.typeParameters().iterator(); it.hasNext(); ) {
1411
					TypeParameter t = (TypeParameter) it.next();
1412
					t.accept(this);
1413
					if (it.hasNext()) {
1414
						this.buffer.append(",");//$NON-NLS-1$
1415
					}
1416
				}
1417
				this.buffer.append(">");//$NON-NLS-1$
1418
			}
1419
		}
1420
		this.buffer.append(" ");//$NON-NLS-1$
1421
		if (node.getAST().apiLevel() == AST.JLS2_INTERNAL) {
1422
			if (node.internalGetSuperclass() != null) {
1423
				this.buffer.append("extends ");//$NON-NLS-1$
1424
				node.internalGetSuperclass().accept(this);
1425
				this.buffer.append(" ");//$NON-NLS-1$
1426
			}
1427
			if (!node.internalSuperInterfaces().isEmpty()) {
1428
				this.buffer.append(node.isInterface() ? "extends " : "implements ");//$NON-NLS-2$//$NON-NLS-1$
1429
				for (Iterator it = node.internalSuperInterfaces().iterator(); it.hasNext(); ) {
1430
					Name n = (Name) it.next();
1431
					n.accept(this);
1432
					if (it.hasNext()) {
1433
						this.buffer.append(", ");//$NON-NLS-1$
1434
					}
1435
				}
1436
				this.buffer.append(" ");//$NON-NLS-1$
1437
			}
1438
		}
1439
		if (node.getAST().apiLevel() >= AST.JLS3) {
1440
			if (node.getSuperclassType() != null) {
1441
				this.buffer.append("extends ");//$NON-NLS-1$
1442
				node.getSuperclassType().accept(this);
1443
				this.buffer.append(" ");//$NON-NLS-1$
1444
			}
1445
			if (!node.superInterfaceTypes().isEmpty()) {
1446
				this.buffer.append(node.isInterface() ? "extends " : "implements ");//$NON-NLS-2$//$NON-NLS-1$
1447
				for (Iterator it = node.superInterfaceTypes().iterator(); it.hasNext(); ) {
1448
					Type t = (Type) it.next();
1449
					t.accept(this);
1450
					if (it.hasNext()) {
1451
						this.buffer.append(", ");//$NON-NLS-1$
1452
					}
1453
				}
1454
				this.buffer.append(" ");//$NON-NLS-1$
1455
			}
1456
		}
1457
		this.buffer.append("{\n");//$NON-NLS-1$
1458
		this.indent++;
1459
		for (Iterator it = node.bodyDeclarations().iterator(); it.hasNext(); ) {
1460
			BodyDeclaration d = (BodyDeclaration) it.next();
1461
			d.accept(this);
1462
		}
1463
		this.indent--;
1464
		printIndent();
1465
		this.buffer.append("}\n");//$NON-NLS-1$
1466
		return false;
1467
	}
1468
1469
	/*
1470
	 * @see ASTVisitor#visit(TypeDeclarationStatement)
1471
	 */
1472
	public boolean visit(TypeDeclarationStatement node) {
1473
		if (node.getAST().apiLevel() == AST.JLS2_INTERNAL) {
1474
			node.internalGetTypeDeclaration().accept(this);
1475
		}
1476
		if (node.getAST().apiLevel() >= AST.JLS3) {
1477
			node.getDeclaration().accept(this);
1478
		}
1479
		return false;
1480
	}
1481
1482
	/*
1483
	 * @see ASTVisitor#visit(TypeLiteral)
1484
	 */
1485
	public boolean visit(TypeLiteral node) {
1486
		node.getType().accept(this);
1487
		this.buffer.append(".class");//$NON-NLS-1$
1488
		return false;
1489
	}
1490
1491
	/*
1492
	 * @see ASTVisitor#visit(TypeParameter)
1493
	 * @since 3.1
1494
	 */
1495
	public boolean visit(TypeParameter node) {
1496
		node.getName().accept(this);
1497
		if (!node.typeBounds().isEmpty()) {
1498
			this.buffer.append(" extends ");//$NON-NLS-1$
1499
			for (Iterator it = node.typeBounds().iterator(); it.hasNext(); ) {
1500
				Type t = (Type) it.next();
1501
				t.accept(this);
1502
				if (it.hasNext()) {
1503
					this.buffer.append(" & ");//$NON-NLS-1$
1504
				}
1505
			}
1506
		}
1507
		return false;
1508
	}
1509
1510
	/*
1511
	 * @see ASTVisitor#visit(VariableDeclarationExpression)
1512
	 */
1513
	public boolean visit(VariableDeclarationExpression node) {
1514
		if (node.getAST().apiLevel() == AST.JLS2_INTERNAL) {
1515
			printModifiers(node.getModifiers());
1516
		}
1517
		if (node.getAST().apiLevel() >= AST.JLS3) {
1518
			printModifiers(node.modifiers());
1519
		}
1520
		node.getType().accept(this);
1521
		this.buffer.append(" ");//$NON-NLS-1$
1522
		for (Iterator it = node.fragments().iterator(); it.hasNext(); ) {
1523
			VariableDeclarationFragment f = (VariableDeclarationFragment) it.next();
1524
			f.accept(this);
1525
			if (it.hasNext()) {
1526
				this.buffer.append(", ");//$NON-NLS-1$
1527
			}
1528
		}
1529
		return false;
1530
	}
1531
1532
	/*
1533
	 * @see ASTVisitor#visit(VariableDeclarationFragment)
1534
	 */
1535
	public boolean visit(VariableDeclarationFragment node) {
1536
		node.getName().accept(this);
1537
		for (int i = 0; i < node.getExtraDimensions(); i++) {
1538
			this.buffer.append("[]");//$NON-NLS-1$
1539
		}
1540
		if (node.getInitializer() != null) {
1541
			this.buffer.append("=");//$NON-NLS-1$
1542
			node.getInitializer().accept(this);
1543
		}
1544
		return false;
1545
	}
1546
1547
	/*
1548
	 * @see ASTVisitor#visit(VariableDeclarationStatement)
1549
	 */
1550
	public boolean visit(VariableDeclarationStatement node) {
1551
		printIndent();
1552
		if (node.getAST().apiLevel() == AST.JLS2_INTERNAL) {
1553
			printModifiers(node.getModifiers());
1554
		}
1555
		if (node.getAST().apiLevel() >= AST.JLS3) {
1556
			printModifiers(node.modifiers());
1557
		}
1558
		node.getType().accept(this);
1559
		this.buffer.append(" ");//$NON-NLS-1$
1560
		for (Iterator it = node.fragments().iterator(); it.hasNext(); ) {
1561
			VariableDeclarationFragment f = (VariableDeclarationFragment) it.next();
1562
			f.accept(this);
1563
			if (it.hasNext()) {
1564
				this.buffer.append(", ");//$NON-NLS-1$
1565
			}
1566
		}
1567
		this.buffer.append(";\n");//$NON-NLS-1$
1568
		return false;
1569
	}
1570
1571
	/*
1572
	 * @see ASTVisitor#visit(WildcardType)
1573
	 * @since 3.1
1574
	 */
1575
	public boolean visit(WildcardType node) {
1576
		this.buffer.append("?");//$NON-NLS-1$
1577
		Type bound = node.getBound();
1578
		if (bound != null) {
1579
			if (node.isUpperBound()) {
1580
				this.buffer.append(" extends ");//$NON-NLS-1$
1581
			} else {
1582
				this.buffer.append(" super ");//$NON-NLS-1$
1583
			}
1584
			bound.accept(this);
1585
		}
1586
		return false;
1587
	}
1588
1589
	/*
1590
	 * @see ASTVisitor#visit(WhileStatement)
1591
	 */
1592
	public boolean visit(WhileStatement node) {
1593
		printIndent();
1594
		this.buffer.append("while (");//$NON-NLS-1$
1595
		node.getExpression().accept(this);
1596
		this.buffer.append(") ");//$NON-NLS-1$
1597
		node.getBody().accept(this);
1598
		return false;
1599
	}
1600
1601
}
(-)dom/org/eclipse/jdt/core/dom/ASTNode.java (+2 lines)
Lines 19-24 Link Here
19
import java.util.List;
19
import java.util.List;
20
import java.util.Map;
20
import java.util.Map;
21
21
22
import org.eclipse.jdt.internal.core.dom.NaiveASTFlattener;
23
22
/**
24
/**
23
 * Abstract superclass of all Abstract Syntax Tree (AST) node types.
25
 * Abstract superclass of all Abstract Syntax Tree (AST) node types.
24
 * <p>
26
 * <p>
(-)META-INF/MANIFEST.MF (+1 lines)
Lines 35-40 Link Here
35
 org.eclipse.jdt.internal.compiler.util;x-friends:="org.eclipse.jdt.compiler.tool,org.eclipse.jdt.apt.pluggable.core",
35
 org.eclipse.jdt.internal.compiler.util;x-friends:="org.eclipse.jdt.compiler.tool,org.eclipse.jdt.apt.pluggable.core",
36
 org.eclipse.jdt.internal.core;x-friends:="org.eclipse.jdt.apt.pluggable.core",
36
 org.eclipse.jdt.internal.core;x-friends:="org.eclipse.jdt.apt.pluggable.core",
37
 org.eclipse.jdt.internal.core.builder;x-friends:="org.eclipse.jdt.apt.pluggable.core",
37
 org.eclipse.jdt.internal.core.builder;x-friends:="org.eclipse.jdt.apt.pluggable.core",
38
 org.eclipse.jdt.internal.core.dom;x-internal:=true,
38
 org.eclipse.jdt.internal.core.dom.rewrite;x-internal:=true,
39
 org.eclipse.jdt.internal.core.dom.rewrite;x-internal:=true,
39
 org.eclipse.jdt.internal.core.eval;x-internal:=true,
40
 org.eclipse.jdt.internal.core.eval;x-internal:=true,
40
 org.eclipse.jdt.internal.core.hierarchy;x-internal:=true,
41
 org.eclipse.jdt.internal.core.hierarchy;x-internal:=true,
(-)dom/org/eclipse/jdt/internal/core/dom/NaiveASTFlattener.java (+1752 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2008 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.jdt.internal.core.dom;
12
13
import java.util.Iterator;
14
import java.util.List;
15
16
import org.eclipse.jdt.core.dom.AST;
17
import org.eclipse.jdt.core.dom.ASTNode;
18
import org.eclipse.jdt.core.dom.ASTVisitor;
19
import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
20
import org.eclipse.jdt.core.dom.Annotation;
21
import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration;
22
import org.eclipse.jdt.core.dom.AnnotationTypeMemberDeclaration;
23
import org.eclipse.jdt.core.dom.AnonymousClassDeclaration;
24
import org.eclipse.jdt.core.dom.ArrayAccess;
25
import org.eclipse.jdt.core.dom.ArrayCreation;
26
import org.eclipse.jdt.core.dom.ArrayInitializer;
27
import org.eclipse.jdt.core.dom.ArrayType;
28
import org.eclipse.jdt.core.dom.AssertStatement;
29
import org.eclipse.jdt.core.dom.Assignment;
30
import org.eclipse.jdt.core.dom.Block;
31
import org.eclipse.jdt.core.dom.BlockComment;
32
import org.eclipse.jdt.core.dom.BodyDeclaration;
33
import org.eclipse.jdt.core.dom.BooleanLiteral;
34
import org.eclipse.jdt.core.dom.BreakStatement;
35
import org.eclipse.jdt.core.dom.CastExpression;
36
import org.eclipse.jdt.core.dom.CatchClause;
37
import org.eclipse.jdt.core.dom.CharacterLiteral;
38
import org.eclipse.jdt.core.dom.ClassInstanceCreation;
39
import org.eclipse.jdt.core.dom.CompilationUnit;
40
import org.eclipse.jdt.core.dom.ConditionalExpression;
41
import org.eclipse.jdt.core.dom.ConstructorInvocation;
42
import org.eclipse.jdt.core.dom.ContinueStatement;
43
import org.eclipse.jdt.core.dom.DoStatement;
44
import org.eclipse.jdt.core.dom.EmptyStatement;
45
import org.eclipse.jdt.core.dom.EnhancedForStatement;
46
import org.eclipse.jdt.core.dom.EnumConstantDeclaration;
47
import org.eclipse.jdt.core.dom.EnumDeclaration;
48
import org.eclipse.jdt.core.dom.Expression;
49
import org.eclipse.jdt.core.dom.ExpressionStatement;
50
import org.eclipse.jdt.core.dom.FieldAccess;
51
import org.eclipse.jdt.core.dom.FieldDeclaration;
52
import org.eclipse.jdt.core.dom.ForStatement;
53
import org.eclipse.jdt.core.dom.IfStatement;
54
import org.eclipse.jdt.core.dom.ImportDeclaration;
55
import org.eclipse.jdt.core.dom.InfixExpression;
56
import org.eclipse.jdt.core.dom.Initializer;
57
import org.eclipse.jdt.core.dom.InstanceofExpression;
58
import org.eclipse.jdt.core.dom.Javadoc;
59
import org.eclipse.jdt.core.dom.LabeledStatement;
60
import org.eclipse.jdt.core.dom.LineComment;
61
import org.eclipse.jdt.core.dom.MarkerAnnotation;
62
import org.eclipse.jdt.core.dom.MemberRef;
63
import org.eclipse.jdt.core.dom.MemberValuePair;
64
import org.eclipse.jdt.core.dom.MethodDeclaration;
65
import org.eclipse.jdt.core.dom.MethodInvocation;
66
import org.eclipse.jdt.core.dom.MethodRef;
67
import org.eclipse.jdt.core.dom.MethodRefParameter;
68
import org.eclipse.jdt.core.dom.Modifier;
69
import org.eclipse.jdt.core.dom.Name;
70
import org.eclipse.jdt.core.dom.NormalAnnotation;
71
import org.eclipse.jdt.core.dom.NullLiteral;
72
import org.eclipse.jdt.core.dom.NumberLiteral;
73
import org.eclipse.jdt.core.dom.PackageDeclaration;
74
import org.eclipse.jdt.core.dom.ParameterizedType;
75
import org.eclipse.jdt.core.dom.ParenthesizedExpression;
76
import org.eclipse.jdt.core.dom.PostfixExpression;
77
import org.eclipse.jdt.core.dom.PrefixExpression;
78
import org.eclipse.jdt.core.dom.PrimitiveType;
79
import org.eclipse.jdt.core.dom.QualifiedName;
80
import org.eclipse.jdt.core.dom.QualifiedType;
81
import org.eclipse.jdt.core.dom.ReturnStatement;
82
import org.eclipse.jdt.core.dom.SimpleName;
83
import org.eclipse.jdt.core.dom.SimpleType;
84
import org.eclipse.jdt.core.dom.SingleMemberAnnotation;
85
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
86
import org.eclipse.jdt.core.dom.Statement;
87
import org.eclipse.jdt.core.dom.StringLiteral;
88
import org.eclipse.jdt.core.dom.SuperConstructorInvocation;
89
import org.eclipse.jdt.core.dom.SuperFieldAccess;
90
import org.eclipse.jdt.core.dom.SuperMethodInvocation;
91
import org.eclipse.jdt.core.dom.SwitchCase;
92
import org.eclipse.jdt.core.dom.SwitchStatement;
93
import org.eclipse.jdt.core.dom.SynchronizedStatement;
94
import org.eclipse.jdt.core.dom.TagElement;
95
import org.eclipse.jdt.core.dom.TextElement;
96
import org.eclipse.jdt.core.dom.ThisExpression;
97
import org.eclipse.jdt.core.dom.ThrowStatement;
98
import org.eclipse.jdt.core.dom.TryStatement;
99
import org.eclipse.jdt.core.dom.Type;
100
import org.eclipse.jdt.core.dom.TypeDeclaration;
101
import org.eclipse.jdt.core.dom.TypeDeclarationStatement;
102
import org.eclipse.jdt.core.dom.TypeLiteral;
103
import org.eclipse.jdt.core.dom.TypeParameter;
104
import org.eclipse.jdt.core.dom.VariableDeclarationExpression;
105
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
106
import org.eclipse.jdt.core.dom.VariableDeclarationStatement;
107
import org.eclipse.jdt.core.dom.WhileStatement;
108
import org.eclipse.jdt.core.dom.WildcardType;
109
110
/**
111
 * Internal AST visitor for serializing an AST in a quick and dirty fashion.
112
 * For various reasons the resulting string is not necessarily legal
113
 * Java code; and even if it is legal Java code, it is not necessarily the string
114
 * that corresponds to the given AST. Although useless for most purposes, it's
115
 * fine for generating debug print strings.
116
 * <p>
117
 * Example usage:
118
 * <code>
119
 * <pre>
120
 *    NaiveASTFlattener p = new NaiveASTFlattener();
121
 *    node.accept(p);
122
 *    String result = p.getResult();
123
 * </pre>
124
 * </code>
125
 * Call the <code>reset</code> method to clear the previous result before reusing an
126
 * existing instance.
127
 * </p>
128
 * 
129
 * @since 2.0
130
 */
131
public class NaiveASTFlattener extends ASTVisitor {
132
	/**
133
	 * Internal synonym for {@link AST#JLS2}. Use to alleviate
134
	 * deprecation warnings.
135
	 * @deprecated
136
	 * @since 3.4
137
	 */
138
	private static final int JLS2 = AST.JLS2;
139
	
140
	/**
141
	 * The string buffer into which the serialized representation of the AST is
142
	 * written.
143
	 */
144
	protected StringBuffer buffer;
145
	
146
	private int indent = 0;
147
	
148
	/**
149
	 * Creates a new AST printer.
150
	 */
151
	public NaiveASTFlattener() {
152
		this.buffer = new StringBuffer();
153
	}
154
	
155
	/**
156
	 * Internal synonym for {@link ClassInstanceCreation#getName()}. Use to alleviate
157
	 * deprecation warnings.
158
	 * @deprecated
159
	 * @since 3.4
160
	 */
161
	private Name getName(ClassInstanceCreation node) {
162
		return node.getName();
163
	}
164
	
165
	/**
166
	 * Returns the string accumulated in the visit.
167
	 *
168
	 * @return the serialized 
169
	 */
170
	public String getResult() {
171
		return this.buffer.toString();
172
	}
173
	
174
	/**
175
	 * Internal synonym for {@link MethodDeclaration#getReturnType()}. Use to alleviate
176
	 * deprecation warnings.
177
	 * @deprecated
178
	 * @since 3.4
179
	 */
180
	private Type getReturnType(MethodDeclaration node) {
181
		return node.getReturnType();
182
	}
183
	
184
	/**
185
	 * Internal synonym for {@link TypeDeclaration#getSuperclass()}. Use to alleviate
186
	 * deprecation warnings.
187
	 * @deprecated
188
	 * @since 3.4
189
	 */
190
	private Name getSuperclass(TypeDeclaration node) {
191
		return node.getSuperclass();
192
	}		
193
	
194
	/**
195
	 * Internal synonym for {@link TypeDeclarationStatement#getTypeDeclaration()}. Use to alleviate
196
	 * deprecation warnings.
197
	 * @deprecated
198
	 * @since 3.4
199
	 */
200
	private TypeDeclaration getTypeDeclaration(TypeDeclarationStatement node) {
201
		return node.getTypeDeclaration();
202
	}		
203
	
204
	void printIndent() {
205
		for (int i = 0; i < this.indent; i++) 
206
			this.buffer.append("  "); //$NON-NLS-1$
207
	}
208
	
209
	/**
210
	 * Appends the text representation of the given modifier flags, followed by a single space.
211
	 * Used for JLS2 modifiers.
212
	 * 
213
	 * @param modifiers the modifier flags
214
	 */
215
	void printModifiers(int modifiers) {
216
		if (Modifier.isPublic(modifiers)) {
217
			this.buffer.append("public ");//$NON-NLS-1$
218
		}
219
		if (Modifier.isProtected(modifiers)) {
220
			this.buffer.append("protected ");//$NON-NLS-1$
221
		}
222
		if (Modifier.isPrivate(modifiers)) {
223
			this.buffer.append("private ");//$NON-NLS-1$
224
		}
225
		if (Modifier.isStatic(modifiers)) {
226
			this.buffer.append("static ");//$NON-NLS-1$
227
		}
228
		if (Modifier.isAbstract(modifiers)) {
229
			this.buffer.append("abstract ");//$NON-NLS-1$
230
		}
231
		if (Modifier.isFinal(modifiers)) {
232
			this.buffer.append("final ");//$NON-NLS-1$
233
		}
234
		if (Modifier.isSynchronized(modifiers)) {
235
			this.buffer.append("synchronized ");//$NON-NLS-1$
236
		}
237
		if (Modifier.isVolatile(modifiers)) {
238
			this.buffer.append("volatile ");//$NON-NLS-1$
239
		}
240
		if (Modifier.isNative(modifiers)) {
241
			this.buffer.append("native ");//$NON-NLS-1$
242
		}
243
		if (Modifier.isStrictfp(modifiers)) {
244
			this.buffer.append("strictfp ");//$NON-NLS-1$
245
		}
246
		if (Modifier.isTransient(modifiers)) {
247
			this.buffer.append("transient ");//$NON-NLS-1$
248
		}
249
	}
250
	
251
	/**
252
	 * Appends the text representation of the given modifier flags, followed by a single space.
253
	 * Used for 3.0 modifiers and annotations.
254
	 * 
255
	 * @param ext the list of modifier and annotation nodes
256
	 * (element type: <code>IExtendedModifiers</code>)
257
	 */
258
	void printModifiers(List ext) {
259
		for (Iterator it = ext.iterator(); it.hasNext(); ) {
260
			ASTNode p = (ASTNode) it.next();
261
			p.accept(this);
262
			this.buffer.append(" ");//$NON-NLS-1$
263
		}
264
	}
265
266
	/**
267
	 * Resets this printer so that it can be used again.
268
	 */
269
	public void reset() {
270
		this.buffer.setLength(0);
271
	}
272
273
	/**
274
	 * Internal synonym for {@link TypeDeclaration#superInterfaces()}. Use to alleviate
275
	 * deprecation warnings.
276
	 * @deprecated
277
	 * @since 3.4
278
	 */
279
	private List superInterfaces(TypeDeclaration node) {
280
		return node.superInterfaces();
281
	}
282
283
	/*
284
	 * @see ASTVisitor#visit(AnnotationTypeDeclaration)
285
	 * @since 3.1
286
	 */
287
	public boolean visit(AnnotationTypeDeclaration node) {
288
		if (node.getJavadoc() != null) {
289
			node.getJavadoc().accept(this);
290
		}
291
		printIndent();
292
		printModifiers(node.modifiers());
293
		this.buffer.append("@interface ");//$NON-NLS-1$
294
		node.getName().accept(this);
295
		this.buffer.append(" {");//$NON-NLS-1$
296
		for (Iterator it = node.bodyDeclarations().iterator(); it.hasNext(); ) {
297
			BodyDeclaration d = (BodyDeclaration) it.next();
298
			d.accept(this);
299
		}
300
		this.buffer.append("}\n");//$NON-NLS-1$
301
		return false;
302
	}
303
304
	/*
305
	 * @see ASTVisitor#visit(AnnotationTypeMemberDeclaration)
306
	 * @since 3.1
307
	 */
308
	public boolean visit(AnnotationTypeMemberDeclaration node) {
309
		if (node.getJavadoc() != null) {
310
			node.getJavadoc().accept(this);
311
		}
312
		printIndent();
313
		printModifiers(node.modifiers());
314
		node.getType().accept(this);
315
		this.buffer.append(" ");//$NON-NLS-1$
316
		node.getName().accept(this);
317
		this.buffer.append("()");//$NON-NLS-1$
318
		if (node.getDefault() != null) {
319
			this.buffer.append(" default ");//$NON-NLS-1$
320
			node.getDefault().accept(this);
321
		}
322
		this.buffer.append(";\n");//$NON-NLS-1$
323
		return false;
324
	}
325
326
	/*
327
	 * @see ASTVisitor#visit(AnonymousClassDeclaration)
328
	 */
329
	public boolean visit(AnonymousClassDeclaration node) {
330
		this.buffer.append("{\n");//$NON-NLS-1$
331
		this.indent++;
332
		for (Iterator it = node.bodyDeclarations().iterator(); it.hasNext(); ) {
333
			BodyDeclaration b = (BodyDeclaration) it.next();
334
			b.accept(this);
335
		}
336
		this.indent--;
337
		printIndent();
338
		this.buffer.append("}\n");//$NON-NLS-1$
339
		return false;
340
	}
341
342
	/*
343
	 * @see ASTVisitor#visit(ArrayAccess)
344
	 */
345
	public boolean visit(ArrayAccess node) {
346
		node.getArray().accept(this);
347
		this.buffer.append("[");//$NON-NLS-1$
348
		node.getIndex().accept(this);
349
		this.buffer.append("]");//$NON-NLS-1$
350
		return false;
351
	}
352
353
	/*
354
	 * @see ASTVisitor#visit(ArrayCreation)
355
	 */
356
	public boolean visit(ArrayCreation node) {
357
		this.buffer.append("new ");//$NON-NLS-1$
358
		ArrayType at = node.getType();
359
		int dims = at.getDimensions();
360
		Type elementType = at.getElementType();
361
		elementType.accept(this);
362
		for (Iterator it = node.dimensions().iterator(); it.hasNext(); ) {
363
			this.buffer.append("[");//$NON-NLS-1$
364
			Expression e = (Expression) it.next();
365
			e.accept(this);
366
			this.buffer.append("]");//$NON-NLS-1$
367
			dims--;
368
		}
369
		// add empty "[]" for each extra array dimension
370
		for (int i= 0; i < dims; i++) {
371
			this.buffer.append("[]");//$NON-NLS-1$
372
		}
373
		if (node.getInitializer() != null) {
374
			node.getInitializer().accept(this);
375
		}
376
		return false;
377
	}
378
379
	/*
380
	 * @see ASTVisitor#visit(ArrayInitializer)
381
	 */
382
	public boolean visit(ArrayInitializer node) {
383
		this.buffer.append("{");//$NON-NLS-1$
384
		for (Iterator it = node.expressions().iterator(); it.hasNext(); ) {
385
			Expression e = (Expression) it.next();
386
			e.accept(this);
387
			if (it.hasNext()) {
388
				this.buffer.append(",");//$NON-NLS-1$
389
			}
390
		}
391
		this.buffer.append("}");//$NON-NLS-1$
392
		return false;
393
	}
394
395
	/*
396
	 * @see ASTVisitor#visit(ArrayType)
397
	 */
398
	public boolean visit(ArrayType node) {
399
		node.getComponentType().accept(this);
400
		this.buffer.append("[]");//$NON-NLS-1$
401
		return false;
402
	}
403
404
	/*
405
	 * @see ASTVisitor#visit(AssertStatement)
406
	 */
407
	public boolean visit(AssertStatement node) {
408
		printIndent();
409
		this.buffer.append("assert ");//$NON-NLS-1$
410
		node.getExpression().accept(this);
411
		if (node.getMessage() != null) {
412
			this.buffer.append(" : ");//$NON-NLS-1$
413
			node.getMessage().accept(this);
414
		}
415
		this.buffer.append(";\n");//$NON-NLS-1$
416
		return false;
417
	}
418
419
	/*
420
	 * @see ASTVisitor#visit(Assignment)
421
	 */
422
	public boolean visit(Assignment node) {
423
		node.getLeftHandSide().accept(this);
424
		this.buffer.append(node.getOperator().toString());
425
		node.getRightHandSide().accept(this);
426
		return false;
427
	}
428
429
	/*
430
	 * @see ASTVisitor#visit(Block)
431
	 */
432
	public boolean visit(Block node) {
433
		this.buffer.append("{\n");//$NON-NLS-1$
434
		this.indent++;
435
		for (Iterator it = node.statements().iterator(); it.hasNext(); ) {
436
			Statement s = (Statement) it.next();
437
			s.accept(this);
438
		}
439
		this.indent--;
440
		printIndent();
441
		this.buffer.append("}\n");//$NON-NLS-1$
442
		return false;
443
	}
444
445
	/*
446
	 * @see ASTVisitor#visit(BlockComment)
447
	 * @since 3.0
448
	 */
449
	public boolean visit(BlockComment node) {
450
		printIndent();
451
		this.buffer.append("/* */");//$NON-NLS-1$
452
		return false;
453
	}
454
455
	/*
456
	 * @see ASTVisitor#visit(BooleanLiteral)
457
	 */
458
	public boolean visit(BooleanLiteral node) {
459
		if (node.booleanValue() == true) {
460
			this.buffer.append("true");//$NON-NLS-1$
461
		} else {
462
			this.buffer.append("false");//$NON-NLS-1$
463
		}
464
		return false;
465
	}
466
467
	/*
468
	 * @see ASTVisitor#visit(BreakStatement)
469
	 */
470
	public boolean visit(BreakStatement node) {
471
		printIndent();
472
		this.buffer.append("break");//$NON-NLS-1$
473
		if (node.getLabel() != null) {
474
			this.buffer.append(" ");//$NON-NLS-1$
475
			node.getLabel().accept(this);
476
		}
477
		this.buffer.append(";\n");//$NON-NLS-1$
478
		return false;
479
	}
480
481
	/*
482
	 * @see ASTVisitor#visit(CastExpression)
483
	 */
484
	public boolean visit(CastExpression node) {
485
		this.buffer.append("(");//$NON-NLS-1$
486
		node.getType().accept(this);
487
		this.buffer.append(")");//$NON-NLS-1$
488
		node.getExpression().accept(this);
489
		return false;
490
	}
491
492
	/*
493
	 * @see ASTVisitor#visit(CatchClause)
494
	 */
495
	public boolean visit(CatchClause node) {
496
		this.buffer.append("catch (");//$NON-NLS-1$
497
		node.getException().accept(this);
498
		this.buffer.append(") ");//$NON-NLS-1$
499
		node.getBody().accept(this);
500
		return false;
501
	}
502
503
	/*
504
	 * @see ASTVisitor#visit(CharacterLiteral)
505
	 */
506
	public boolean visit(CharacterLiteral node) {
507
		this.buffer.append(node.getEscapedValue());
508
		return false;
509
	}
510
511
	/*
512
	 * @see ASTVisitor#visit(ClassInstanceCreation)
513
	 */
514
	public boolean visit(ClassInstanceCreation node) {
515
		if (node.getExpression() != null) {
516
			node.getExpression().accept(this);
517
			this.buffer.append(".");//$NON-NLS-1$
518
		}
519
		this.buffer.append("new ");//$NON-NLS-1$
520
		if (node.getAST().apiLevel() == JLS2) {
521
			this.getName(node).accept(this);
522
		}
523
		if (node.getAST().apiLevel() >= AST.JLS3) {
524
			if (!node.typeArguments().isEmpty()) {
525
				this.buffer.append("<");//$NON-NLS-1$
526
				for (Iterator it = node.typeArguments().iterator(); it.hasNext(); ) {
527
					Type t = (Type) it.next();
528
					t.accept(this);
529
					if (it.hasNext()) {
530
						this.buffer.append(",");//$NON-NLS-1$
531
					}
532
				}
533
				this.buffer.append(">");//$NON-NLS-1$
534
			}
535
			node.getType().accept(this);
536
		}
537
		this.buffer.append("(");//$NON-NLS-1$
538
		for (Iterator it = node.arguments().iterator(); it.hasNext(); ) {
539
			Expression e = (Expression) it.next();
540
			e.accept(this);
541
			if (it.hasNext()) {
542
				this.buffer.append(",");//$NON-NLS-1$
543
			}
544
		}
545
		this.buffer.append(")");//$NON-NLS-1$
546
		if (node.getAnonymousClassDeclaration() != null) {
547
			node.getAnonymousClassDeclaration().accept(this);
548
		}
549
		return false;
550
	}
551
552
	/*
553
	 * @see ASTVisitor#visit(CompilationUnit)
554
	 */
555
	public boolean visit(CompilationUnit node) {
556
		if (node.getPackage() != null) {
557
			node.getPackage().accept(this);
558
		}
559
		for (Iterator it = node.imports().iterator(); it.hasNext(); ) {
560
			ImportDeclaration d = (ImportDeclaration) it.next();
561
			d.accept(this);
562
		}
563
		for (Iterator it = node.types().iterator(); it.hasNext(); ) {
564
			AbstractTypeDeclaration d = (AbstractTypeDeclaration) it.next();
565
			d.accept(this);
566
		}
567
		return false;
568
	}
569
570
	/*
571
	 * @see ASTVisitor#visit(ConditionalExpression)
572
	 */
573
	public boolean visit(ConditionalExpression node) {
574
		node.getExpression().accept(this);
575
		this.buffer.append(" ? ");//$NON-NLS-1$
576
		node.getThenExpression().accept(this);
577
		this.buffer.append(" : ");//$NON-NLS-1$
578
		node.getElseExpression().accept(this);
579
		return false;
580
	}
581
582
	/*
583
	 * @see ASTVisitor#visit(ConstructorInvocation)
584
	 */
585
	public boolean visit(ConstructorInvocation node) {
586
		printIndent();
587
		if (node.getAST().apiLevel() >= AST.JLS3) {
588
			if (!node.typeArguments().isEmpty()) {
589
				this.buffer.append("<");//$NON-NLS-1$
590
				for (Iterator it = node.typeArguments().iterator(); it.hasNext(); ) {
591
					Type t = (Type) it.next();
592
					t.accept(this);
593
					if (it.hasNext()) {
594
						this.buffer.append(",");//$NON-NLS-1$
595
					}
596
				}
597
				this.buffer.append(">");//$NON-NLS-1$
598
			}
599
		}
600
		this.buffer.append("this(");//$NON-NLS-1$
601
		for (Iterator it = node.arguments().iterator(); it.hasNext(); ) {
602
			Expression e = (Expression) it.next();
603
			e.accept(this);
604
			if (it.hasNext()) {
605
				this.buffer.append(",");//$NON-NLS-1$
606
			}
607
		}
608
		this.buffer.append(");\n");//$NON-NLS-1$
609
		return false;
610
	}
611
612
	/*
613
	 * @see ASTVisitor#visit(ContinueStatement)
614
	 */
615
	public boolean visit(ContinueStatement node) {
616
		printIndent();
617
		this.buffer.append("continue");//$NON-NLS-1$
618
		if (node.getLabel() != null) {
619
			this.buffer.append(" ");//$NON-NLS-1$
620
			node.getLabel().accept(this);
621
		}
622
		this.buffer.append(";\n");//$NON-NLS-1$
623
		return false;
624
	}
625
626
	/*
627
	 * @see ASTVisitor#visit(DoStatement)
628
	 */
629
	public boolean visit(DoStatement node) {
630
		printIndent();
631
		this.buffer.append("do ");//$NON-NLS-1$
632
		node.getBody().accept(this);
633
		this.buffer.append(" while (");//$NON-NLS-1$
634
		node.getExpression().accept(this);
635
		this.buffer.append(");\n");//$NON-NLS-1$
636
		return false;
637
	}
638
639
	/*
640
	 * @see ASTVisitor#visit(EmptyStatement)
641
	 */
642
	public boolean visit(EmptyStatement node) {
643
		printIndent();
644
		this.buffer.append(";\n");//$NON-NLS-1$
645
		return false;
646
	}
647
648
	/*
649
	 * @see ASTVisitor#visit(EnhancedForStatement)
650
	 * @since 3.1
651
	 */
652
	public boolean visit(EnhancedForStatement node) {
653
		printIndent();
654
		this.buffer.append("for (");//$NON-NLS-1$
655
		node.getParameter().accept(this);
656
		this.buffer.append(" : ");//$NON-NLS-1$
657
		node.getExpression().accept(this);
658
		this.buffer.append(") ");//$NON-NLS-1$
659
		node.getBody().accept(this);
660
		return false;
661
	}
662
663
	/*
664
	 * @see ASTVisitor#visit(EnumConstantDeclaration)
665
	 * @since 3.1
666
	 */
667
	public boolean visit(EnumConstantDeclaration node) {
668
		if (node.getJavadoc() != null) {
669
			node.getJavadoc().accept(this);
670
		}
671
		printIndent();
672
		printModifiers(node.modifiers());
673
		node.getName().accept(this);
674
		if (!node.arguments().isEmpty()) {
675
			this.buffer.append("(");//$NON-NLS-1$
676
			for (Iterator it = node.arguments().iterator(); it.hasNext(); ) {
677
				Expression e = (Expression) it.next();
678
				e.accept(this);
679
				if (it.hasNext()) {
680
					this.buffer.append(",");//$NON-NLS-1$
681
				}
682
			}
683
			this.buffer.append(")");//$NON-NLS-1$
684
		}
685
		if (node.getAnonymousClassDeclaration() != null) {
686
			node.getAnonymousClassDeclaration().accept(this);
687
		}
688
		return false;
689
	}
690
691
	/*
692
	 * @see ASTVisitor#visit(EnumDeclaration)
693
	 * @since 3.1
694
	 */
695
	public boolean visit(EnumDeclaration node) {
696
		if (node.getJavadoc() != null) {
697
			node.getJavadoc().accept(this);
698
		}
699
		printIndent();
700
		printModifiers(node.modifiers());
701
		this.buffer.append("enum ");//$NON-NLS-1$
702
		node.getName().accept(this);
703
		this.buffer.append(" ");//$NON-NLS-1$
704
		if (!node.superInterfaceTypes().isEmpty()) {
705
			this.buffer.append("implements ");//$NON-NLS-1$
706
			for (Iterator it = node.superInterfaceTypes().iterator(); it.hasNext(); ) {
707
				Type t = (Type) it.next();
708
				t.accept(this);
709
				if (it.hasNext()) {
710
					this.buffer.append(", ");//$NON-NLS-1$
711
				}
712
			}
713
			this.buffer.append(" ");//$NON-NLS-1$
714
		}
715
		this.buffer.append("{");//$NON-NLS-1$
716
		for (Iterator it = node.enumConstants().iterator(); it.hasNext(); ) {
717
			EnumConstantDeclaration d = (EnumConstantDeclaration) it.next();
718
			d.accept(this);
719
			// enum constant declarations do not include punctuation
720
			if (it.hasNext()) {
721
				// enum constant declarations are separated by commas
722
				this.buffer.append(", ");//$NON-NLS-1$
723
			}
724
		}
725
		if (!node.bodyDeclarations().isEmpty()) {
726
			this.buffer.append("; ");//$NON-NLS-1$
727
			for (Iterator it = node.bodyDeclarations().iterator(); it.hasNext(); ) {
728
				BodyDeclaration d = (BodyDeclaration) it.next();
729
				d.accept(this);
730
				// other body declarations include trailing punctuation
731
			}
732
		}
733
		this.buffer.append("}\n");//$NON-NLS-1$
734
		return false;
735
	}
736
737
	/*
738
	 * @see ASTVisitor#visit(ExpressionStatement)
739
	 */
740
	public boolean visit(ExpressionStatement node) {
741
		printIndent();
742
		node.getExpression().accept(this);
743
		this.buffer.append(";\n");//$NON-NLS-1$
744
		return false;
745
	}
746
747
	/*
748
	 * @see ASTVisitor#visit(FieldAccess)
749
	 */
750
	public boolean visit(FieldAccess node) {
751
		node.getExpression().accept(this);
752
		this.buffer.append(".");//$NON-NLS-1$
753
		node.getName().accept(this);
754
		return false;
755
	}
756
757
	/*
758
	 * @see ASTVisitor#visit(FieldDeclaration)
759
	 */
760
	public boolean visit(FieldDeclaration node) {
761
		if (node.getJavadoc() != null) {
762
			node.getJavadoc().accept(this);
763
		}
764
		printIndent();
765
		if (node.getAST().apiLevel() == JLS2) {
766
			printModifiers(node.getModifiers());
767
		}
768
		if (node.getAST().apiLevel() >= AST.JLS3) {
769
			printModifiers(node.modifiers());
770
		}
771
		node.getType().accept(this);
772
		this.buffer.append(" ");//$NON-NLS-1$
773
		for (Iterator it = node.fragments().iterator(); it.hasNext(); ) {
774
			VariableDeclarationFragment f = (VariableDeclarationFragment) it.next();
775
			f.accept(this);
776
			if (it.hasNext()) {
777
				this.buffer.append(", ");//$NON-NLS-1$
778
			}
779
		}
780
		this.buffer.append(";\n");//$NON-NLS-1$
781
		return false;
782
	}
783
784
	/*
785
	 * @see ASTVisitor#visit(ForStatement)
786
	 */
787
	public boolean visit(ForStatement node) {
788
		printIndent();
789
		this.buffer.append("for (");//$NON-NLS-1$
790
		for (Iterator it = node.initializers().iterator(); it.hasNext(); ) {
791
			Expression e = (Expression) it.next();
792
			e.accept(this);
793
			if (it.hasNext()) buffer.append(", ");//$NON-NLS-1$
794
		}
795
		this.buffer.append("; ");//$NON-NLS-1$
796
		if (node.getExpression() != null) {
797
			node.getExpression().accept(this);
798
		}
799
		this.buffer.append("; ");//$NON-NLS-1$
800
		for (Iterator it = node.updaters().iterator(); it.hasNext(); ) {
801
			Expression e = (Expression) it.next();
802
			e.accept(this);
803
			if (it.hasNext()) buffer.append(", ");//$NON-NLS-1$
804
		}
805
		this.buffer.append(") ");//$NON-NLS-1$
806
		node.getBody().accept(this);
807
		return false;
808
	}
809
810
	/*
811
	 * @see ASTVisitor#visit(IfStatement)
812
	 */
813
	public boolean visit(IfStatement node) {
814
		printIndent();
815
		this.buffer.append("if (");//$NON-NLS-1$
816
		node.getExpression().accept(this);
817
		this.buffer.append(") ");//$NON-NLS-1$
818
		node.getThenStatement().accept(this);
819
		if (node.getElseStatement() != null) {
820
			this.buffer.append(" else ");//$NON-NLS-1$
821
			node.getElseStatement().accept(this);
822
		}
823
		return false;
824
	}
825
826
	/*
827
	 * @see ASTVisitor#visit(ImportDeclaration)
828
	 */
829
	public boolean visit(ImportDeclaration node) {
830
		printIndent();
831
		this.buffer.append("import ");//$NON-NLS-1$
832
		if (node.getAST().apiLevel() >= AST.JLS3) {
833
			if (node.isStatic()) {
834
				this.buffer.append("static ");//$NON-NLS-1$
835
			}
836
		}
837
		node.getName().accept(this);
838
		if (node.isOnDemand()) {
839
			this.buffer.append(".*");//$NON-NLS-1$
840
		}
841
		this.buffer.append(";\n");//$NON-NLS-1$
842
		return false;
843
	}
844
845
	/*
846
	 * @see ASTVisitor#visit(InfixExpression)
847
	 */
848
	public boolean visit(InfixExpression node) {
849
		node.getLeftOperand().accept(this);
850
		this.buffer.append(' ');  // for cases like x= i - -1; or x= i++ + ++i;
851
		this.buffer.append(node.getOperator().toString());
852
		this.buffer.append(' ');
853
		node.getRightOperand().accept(this);
854
		final List extendedOperands = node.extendedOperands();
855
		if (extendedOperands.size() != 0) {
856
			this.buffer.append(' ');
857
			for (Iterator it = extendedOperands.iterator(); it.hasNext(); ) {
858
				this.buffer.append(node.getOperator().toString()).append(' ');
859
				Expression e = (Expression) it.next();
860
				e.accept(this);
861
			}
862
		}
863
		return false;
864
	}
865
866
	/*
867
	 * @see ASTVisitor#visit(Initializer)
868
	 */
869
	public boolean visit(Initializer node) {
870
		if (node.getJavadoc() != null) {
871
			node.getJavadoc().accept(this);
872
		}
873
		if (node.getAST().apiLevel() == JLS2) {
874
			printModifiers(node.getModifiers());
875
		}
876
		if (node.getAST().apiLevel() >= AST.JLS3) {
877
			printModifiers(node.modifiers());
878
		}
879
		node.getBody().accept(this);
880
		return false;
881
	}
882
883
	/*
884
	 * @see ASTVisitor#visit(InstanceofExpression)
885
	 */
886
	public boolean visit(InstanceofExpression node) {
887
		node.getLeftOperand().accept(this);
888
		this.buffer.append(" instanceof ");//$NON-NLS-1$
889
		node.getRightOperand().accept(this);
890
		return false;
891
	}
892
	
893
	/*
894
	 * @see ASTVisitor#visit(Javadoc)
895
	 */
896
	public boolean visit(Javadoc node) {
897
		printIndent();
898
		this.buffer.append("/** ");//$NON-NLS-1$
899
		for (Iterator it = node.tags().iterator(); it.hasNext(); ) {
900
			ASTNode e = (ASTNode) it.next();
901
			e.accept(this);
902
		}
903
		this.buffer.append("\n */\n");//$NON-NLS-1$
904
		return false;
905
	}
906
	
907
	/*
908
	 * @see ASTVisitor#visit(LabeledStatement)
909
	 */
910
	public boolean visit(LabeledStatement node) {
911
		printIndent();
912
		node.getLabel().accept(this);
913
		this.buffer.append(": ");//$NON-NLS-1$
914
		node.getBody().accept(this);
915
		return false;
916
	}
917
	
918
	/*
919
	 * @see ASTVisitor#visit(LineComment)
920
	 * @since 3.0
921
	 */
922
	public boolean visit(LineComment node) {
923
		this.buffer.append("//\n");//$NON-NLS-1$
924
		return false;
925
	}
926
	
927
	/*
928
	 * @see ASTVisitor#visit(MarkerAnnotation)
929
	 * @since 3.1
930
	 */
931
	public boolean visit(MarkerAnnotation node) {
932
		this.buffer.append("@");//$NON-NLS-1$
933
		node.getTypeName().accept(this);
934
		return false;
935
	}
936
	
937
	/*
938
	 * @see ASTVisitor#visit(MemberRef)
939
	 * @since 3.0
940
	 */
941
	public boolean visit(MemberRef node) {
942
		if (node.getQualifier() != null) {
943
			node.getQualifier().accept(this);
944
		}
945
		this.buffer.append("#");//$NON-NLS-1$
946
		node.getName().accept(this);
947
		return false;
948
	}
949
	
950
	/*
951
	 * @see ASTVisitor#visit(MemberValuePair)
952
	 * @since 3.1
953
	 */
954
	public boolean visit(MemberValuePair node) {
955
		node.getName().accept(this);
956
		this.buffer.append("=");//$NON-NLS-1$
957
		node.getValue().accept(this);
958
		return false;
959
	}
960
961
	/*
962
	 * @see ASTVisitor#visit(MethodDeclaration)
963
	 */
964
	public boolean visit(MethodDeclaration node) {
965
		if (node.getJavadoc() != null) {
966
			node.getJavadoc().accept(this);
967
		}
968
		printIndent();
969
		if (node.getAST().apiLevel() == JLS2) {
970
			printModifiers(node.getModifiers());
971
		}
972
		if (node.getAST().apiLevel() >= AST.JLS3) {
973
			printModifiers(node.modifiers());
974
			if (!node.typeParameters().isEmpty()) {
975
				this.buffer.append("<");//$NON-NLS-1$
976
				for (Iterator it = node.typeParameters().iterator(); it.hasNext(); ) {
977
					TypeParameter t = (TypeParameter) it.next();
978
					t.accept(this);
979
					if (it.hasNext()) {
980
						this.buffer.append(",");//$NON-NLS-1$
981
					}
982
				}
983
				this.buffer.append(">");//$NON-NLS-1$
984
			}
985
		}
986
		if (!node.isConstructor()) {
987
			if (node.getAST().apiLevel() == JLS2) {
988
				this.getReturnType(node).accept(this);
989
			} else {
990
				if (node.getReturnType2() != null) {
991
					node.getReturnType2().accept(this);
992
				} else {
993
					// methods really ought to have a return type
994
					this.buffer.append("void");//$NON-NLS-1$
995
				}
996
			}
997
			this.buffer.append(" ");//$NON-NLS-1$
998
		}
999
		node.getName().accept(this);
1000
		this.buffer.append("(");//$NON-NLS-1$
1001
		for (Iterator it = node.parameters().iterator(); it.hasNext(); ) {
1002
			SingleVariableDeclaration v = (SingleVariableDeclaration) it.next();
1003
			v.accept(this);
1004
			if (it.hasNext()) {
1005
				this.buffer.append(",");//$NON-NLS-1$
1006
			}
1007
		}
1008
		this.buffer.append(")");//$NON-NLS-1$
1009
		for (int i = 0; i < node.getExtraDimensions(); i++) {
1010
			this.buffer.append("[]"); //$NON-NLS-1$
1011
		}		
1012
		if (!node.thrownExceptions().isEmpty()) {
1013
			this.buffer.append(" throws ");//$NON-NLS-1$
1014
			for (Iterator it = node.thrownExceptions().iterator(); it.hasNext(); ) {
1015
				Name n = (Name) it.next();
1016
				n.accept(this);
1017
				if (it.hasNext()) {
1018
					this.buffer.append(", ");//$NON-NLS-1$
1019
				}
1020
			}
1021
			this.buffer.append(" ");//$NON-NLS-1$
1022
		}
1023
		if (node.getBody() == null) {
1024
			this.buffer.append(";\n");//$NON-NLS-1$
1025
		} else {
1026
			node.getBody().accept(this);
1027
		}
1028
		return false;
1029
	}
1030
1031
	/*
1032
	 * @see ASTVisitor#visit(MethodInvocation)
1033
	 */
1034
	public boolean visit(MethodInvocation node) {
1035
		if (node.getExpression() != null) {
1036
			node.getExpression().accept(this);
1037
			this.buffer.append(".");//$NON-NLS-1$
1038
		}
1039
		if (node.getAST().apiLevel() >= AST.JLS3) {
1040
			if (!node.typeArguments().isEmpty()) {
1041
				this.buffer.append("<");//$NON-NLS-1$
1042
				for (Iterator it = node.typeArguments().iterator(); it.hasNext(); ) {
1043
					Type t = (Type) it.next();
1044
					t.accept(this);
1045
					if (it.hasNext()) {
1046
						this.buffer.append(",");//$NON-NLS-1$
1047
					}
1048
				}
1049
				this.buffer.append(">");//$NON-NLS-1$
1050
			}
1051
		}
1052
		node.getName().accept(this);
1053
		this.buffer.append("(");//$NON-NLS-1$
1054
		for (Iterator it = node.arguments().iterator(); it.hasNext(); ) {
1055
			Expression e = (Expression) it.next();
1056
			e.accept(this);
1057
			if (it.hasNext()) {
1058
				this.buffer.append(",");//$NON-NLS-1$
1059
			}
1060
		}
1061
		this.buffer.append(")");//$NON-NLS-1$
1062
		return false;
1063
	}
1064
	
1065
	/*
1066
	 * @see ASTVisitor#visit(MethodRef)
1067
	 * @since 3.0
1068
	 */
1069
	public boolean visit(MethodRef node) {
1070
		if (node.getQualifier() != null) {
1071
			node.getQualifier().accept(this);
1072
		}
1073
		this.buffer.append("#");//$NON-NLS-1$
1074
		node.getName().accept(this);
1075
		this.buffer.append("(");//$NON-NLS-1$
1076
		for (Iterator it = node.parameters().iterator(); it.hasNext(); ) {
1077
			MethodRefParameter e = (MethodRefParameter) it.next();
1078
			e.accept(this);
1079
			if (it.hasNext()) {
1080
				this.buffer.append(",");//$NON-NLS-1$
1081
			}
1082
		}
1083
		this.buffer.append(")");//$NON-NLS-1$
1084
		return false;
1085
	}
1086
	
1087
	/*
1088
	 * @see ASTVisitor#visit(MethodRefParameter)
1089
	 * @since 3.0
1090
	 */
1091
	public boolean visit(MethodRefParameter node) {
1092
		node.getType().accept(this);
1093
		if (node.getAST().apiLevel() >= AST.JLS3) {
1094
			if (node.isVarargs()) {
1095
				this.buffer.append("...");//$NON-NLS-1$
1096
			}
1097
		}
1098
		if (node.getName() != null) {
1099
			this.buffer.append(" ");//$NON-NLS-1$
1100
			node.getName().accept(this);
1101
		}
1102
		return false;
1103
	}
1104
1105
	/*
1106
	 * @see ASTVisitor#visit(Modifier)
1107
	 * @since 3.1
1108
	 */
1109
	public boolean visit(Modifier node) {
1110
		this.buffer.append(node.getKeyword().toString());
1111
		return false;
1112
	}
1113
1114
	/*
1115
	 * @see ASTVisitor#visit(NormalAnnotation)
1116
	 * @since 3.1
1117
	 */
1118
	public boolean visit(NormalAnnotation node) {
1119
		this.buffer.append("@");//$NON-NLS-1$
1120
		node.getTypeName().accept(this);
1121
		this.buffer.append("(");//$NON-NLS-1$
1122
		for (Iterator it = node.values().iterator(); it.hasNext(); ) {
1123
			MemberValuePair p = (MemberValuePair) it.next();
1124
			p.accept(this);
1125
			if (it.hasNext()) {
1126
				this.buffer.append(",");//$NON-NLS-1$
1127
			}
1128
		}
1129
		this.buffer.append(")");//$NON-NLS-1$
1130
		return false;
1131
	}
1132
1133
	/*
1134
	 * @see ASTVisitor#visit(NullLiteral)
1135
	 */
1136
	public boolean visit(NullLiteral node) {
1137
		this.buffer.append("null");//$NON-NLS-1$
1138
		return false;
1139
	}
1140
1141
	/*
1142
	 * @see ASTVisitor#visit(NumberLiteral)
1143
	 */
1144
	public boolean visit(NumberLiteral node) {
1145
		this.buffer.append(node.getToken());
1146
		return false;
1147
	}
1148
1149
	/*
1150
	 * @see ASTVisitor#visit(PackageDeclaration)
1151
	 */
1152
	public boolean visit(PackageDeclaration node) {
1153
		if (node.getAST().apiLevel() >= AST.JLS3) {
1154
			if (node.getJavadoc() != null) {
1155
				node.getJavadoc().accept(this);
1156
			}
1157
			for (Iterator it = node.annotations().iterator(); it.hasNext(); ) {
1158
				Annotation p = (Annotation) it.next();
1159
				p.accept(this);
1160
				this.buffer.append(" ");//$NON-NLS-1$
1161
			}
1162
		}
1163
		printIndent();
1164
		this.buffer.append("package ");//$NON-NLS-1$
1165
		node.getName().accept(this);
1166
		this.buffer.append(";\n");//$NON-NLS-1$
1167
		return false;
1168
	}
1169
1170
	/*
1171
	 * @see ASTVisitor#visit(ParameterizedType)
1172
	 * @since 3.1
1173
	 */
1174
	public boolean visit(ParameterizedType node) {
1175
		node.getType().accept(this);
1176
		this.buffer.append("<");//$NON-NLS-1$
1177
		for (Iterator it = node.typeArguments().iterator(); it.hasNext(); ) {
1178
			Type t = (Type) it.next();
1179
			t.accept(this);
1180
			if (it.hasNext()) {
1181
				this.buffer.append(",");//$NON-NLS-1$
1182
			}
1183
		}
1184
		this.buffer.append(">");//$NON-NLS-1$
1185
		return false;
1186
	}
1187
1188
	/*
1189
	 * @see ASTVisitor#visit(ParenthesizedExpression)
1190
	 */
1191
	public boolean visit(ParenthesizedExpression node) {
1192
		this.buffer.append("(");//$NON-NLS-1$
1193
		node.getExpression().accept(this);
1194
		this.buffer.append(")");//$NON-NLS-1$
1195
		return false;
1196
	}
1197
1198
	/*
1199
	 * @see ASTVisitor#visit(PostfixExpression)
1200
	 */
1201
	public boolean visit(PostfixExpression node) {
1202
		node.getOperand().accept(this);
1203
		this.buffer.append(node.getOperator().toString());
1204
		return false;
1205
	}
1206
1207
	/*
1208
	 * @see ASTVisitor#visit(PrefixExpression)
1209
	 */
1210
	public boolean visit(PrefixExpression node) {
1211
		this.buffer.append(node.getOperator().toString());
1212
		node.getOperand().accept(this);
1213
		return false;
1214
	}
1215
1216
	/*
1217
	 * @see ASTVisitor#visit(PrimitiveType)
1218
	 */
1219
	public boolean visit(PrimitiveType node) {
1220
		this.buffer.append(node.getPrimitiveTypeCode().toString());
1221
		return false;
1222
	}
1223
1224
	/*
1225
	 * @see ASTVisitor#visit(QualifiedName)
1226
	 */
1227
	public boolean visit(QualifiedName node) {
1228
		node.getQualifier().accept(this);
1229
		this.buffer.append(".");//$NON-NLS-1$
1230
		node.getName().accept(this);
1231
		return false;
1232
	}
1233
1234
	/*
1235
	 * @see ASTVisitor#visit(QualifiedType)
1236
	 * @since 3.1
1237
	 */
1238
	public boolean visit(QualifiedType node) {
1239
		node.getQualifier().accept(this);
1240
		this.buffer.append(".");//$NON-NLS-1$
1241
		node.getName().accept(this);
1242
		return false;
1243
	}
1244
1245
	/*
1246
	 * @see ASTVisitor#visit(ReturnStatement)
1247
	 */
1248
	public boolean visit(ReturnStatement node) {
1249
		printIndent();
1250
		this.buffer.append("return");//$NON-NLS-1$
1251
		if (node.getExpression() != null) {
1252
			this.buffer.append(" ");//$NON-NLS-1$
1253
			node.getExpression().accept(this);
1254
		}
1255
		this.buffer.append(";\n");//$NON-NLS-1$
1256
		return false;
1257
	}
1258
	
1259
	/*
1260
	 * @see ASTVisitor#visit(SimpleName)
1261
	 */
1262
	public boolean visit(SimpleName node) {
1263
		this.buffer.append(node.getIdentifier());
1264
		return false;
1265
	}
1266
1267
	/*
1268
	 * @see ASTVisitor#visit(SimpleType)
1269
	 */
1270
	public boolean visit(SimpleType node) {
1271
		return true;
1272
	}
1273
1274
	/*
1275
	 * @see ASTVisitor#visit(SingleMemberAnnotation)
1276
	 * @since 3.1
1277
	 */
1278
	public boolean visit(SingleMemberAnnotation node) {
1279
		this.buffer.append("@");//$NON-NLS-1$
1280
		node.getTypeName().accept(this);
1281
		this.buffer.append("(");//$NON-NLS-1$
1282
		node.getValue().accept(this);
1283
		this.buffer.append(")");//$NON-NLS-1$
1284
		return false;
1285
	}
1286
1287
	/*
1288
	 * @see ASTVisitor#visit(SingleVariableDeclaration)
1289
	 */
1290
	public boolean visit(SingleVariableDeclaration node) {
1291
		printIndent();
1292
		if (node.getAST().apiLevel() == JLS2) {
1293
			printModifiers(node.getModifiers());
1294
		}
1295
		if (node.getAST().apiLevel() >= AST.JLS3) {
1296
			printModifiers(node.modifiers());
1297
		}
1298
		node.getType().accept(this);
1299
		if (node.getAST().apiLevel() >= AST.JLS3) {
1300
			if (node.isVarargs()) {
1301
				this.buffer.append("...");//$NON-NLS-1$
1302
			}
1303
		}
1304
		this.buffer.append(" ");//$NON-NLS-1$
1305
		node.getName().accept(this);
1306
		for (int i = 0; i < node.getExtraDimensions(); i++) {
1307
			this.buffer.append("[]"); //$NON-NLS-1$
1308
		}			
1309
		if (node.getInitializer() != null) {
1310
			this.buffer.append("=");//$NON-NLS-1$
1311
			node.getInitializer().accept(this);
1312
		}
1313
		return false;
1314
	}
1315
1316
	/*
1317
	 * @see ASTVisitor#visit(StringLiteral)
1318
	 */
1319
	public boolean visit(StringLiteral node) {
1320
		this.buffer.append(node.getEscapedValue());
1321
		return false;
1322
	}
1323
1324
	/*
1325
	 * @see ASTVisitor#visit(SuperConstructorInvocation)
1326
	 */
1327
	public boolean visit(SuperConstructorInvocation node) {
1328
		printIndent();
1329
		if (node.getExpression() != null) {
1330
			node.getExpression().accept(this);
1331
			this.buffer.append(".");//$NON-NLS-1$
1332
		}
1333
		if (node.getAST().apiLevel() >= AST.JLS3) {
1334
			if (!node.typeArguments().isEmpty()) {
1335
				this.buffer.append("<");//$NON-NLS-1$
1336
				for (Iterator it = node.typeArguments().iterator(); it.hasNext(); ) {
1337
					Type t = (Type) it.next();
1338
					t.accept(this);
1339
					if (it.hasNext()) {
1340
						this.buffer.append(",");//$NON-NLS-1$
1341
					}
1342
				}
1343
				this.buffer.append(">");//$NON-NLS-1$
1344
			}
1345
		}
1346
		this.buffer.append("super(");//$NON-NLS-1$
1347
		for (Iterator it = node.arguments().iterator(); it.hasNext(); ) {
1348
			Expression e = (Expression) it.next();
1349
			e.accept(this);
1350
			if (it.hasNext()) {
1351
				this.buffer.append(",");//$NON-NLS-1$
1352
			}
1353
		}
1354
		this.buffer.append(");\n");//$NON-NLS-1$
1355
		return false;
1356
	}
1357
1358
	/*
1359
	 * @see ASTVisitor#visit(SuperFieldAccess)
1360
	 */
1361
	public boolean visit(SuperFieldAccess node) {
1362
		if (node.getQualifier() != null) {
1363
			node.getQualifier().accept(this);
1364
			this.buffer.append(".");//$NON-NLS-1$
1365
		}
1366
		this.buffer.append("super.");//$NON-NLS-1$
1367
		node.getName().accept(this);
1368
		return false;
1369
	}
1370
1371
	/*
1372
	 * @see ASTVisitor#visit(SuperMethodInvocation)
1373
	 */
1374
	public boolean visit(SuperMethodInvocation node) {
1375
		if (node.getQualifier() != null) {
1376
			node.getQualifier().accept(this);
1377
			this.buffer.append(".");//$NON-NLS-1$
1378
		}
1379
		this.buffer.append("super.");//$NON-NLS-1$
1380
		if (node.getAST().apiLevel() >= AST.JLS3) {
1381
			if (!node.typeArguments().isEmpty()) {
1382
				this.buffer.append("<");//$NON-NLS-1$
1383
				for (Iterator it = node.typeArguments().iterator(); it.hasNext(); ) {
1384
					Type t = (Type) it.next();
1385
					t.accept(this);
1386
					if (it.hasNext()) {
1387
						this.buffer.append(",");//$NON-NLS-1$
1388
					}
1389
				}
1390
				this.buffer.append(">");//$NON-NLS-1$
1391
			}
1392
		}
1393
		node.getName().accept(this);
1394
		this.buffer.append("(");//$NON-NLS-1$
1395
		for (Iterator it = node.arguments().iterator(); it.hasNext(); ) {
1396
			Expression e = (Expression) it.next();
1397
			e.accept(this);
1398
			if (it.hasNext()) {
1399
				this.buffer.append(",");//$NON-NLS-1$
1400
			}
1401
		}
1402
		this.buffer.append(")");//$NON-NLS-1$
1403
		return false;
1404
	}
1405
1406
	/*
1407
	 * @see ASTVisitor#visit(SwitchCase)
1408
	 */
1409
	public boolean visit(SwitchCase node) {
1410
		if (node.isDefault()) {
1411
			this.buffer.append("default :\n");//$NON-NLS-1$
1412
		} else {
1413
			this.buffer.append("case ");//$NON-NLS-1$
1414
			node.getExpression().accept(this);
1415
			this.buffer.append(":\n");//$NON-NLS-1$
1416
		}
1417
		this.indent++; //decremented in visit(SwitchStatement)
1418
		return false;
1419
	}
1420
	
1421
	/*
1422
	 * @see ASTVisitor#visit(SwitchStatement)
1423
	 */
1424
	public boolean visit(SwitchStatement node) {
1425
		this.buffer.append("switch (");//$NON-NLS-1$
1426
		node.getExpression().accept(this);
1427
		this.buffer.append(") ");//$NON-NLS-1$
1428
		this.buffer.append("{\n");//$NON-NLS-1$
1429
		this.indent++;
1430
		for (Iterator it = node.statements().iterator(); it.hasNext(); ) {
1431
			Statement s = (Statement) it.next();
1432
			s.accept(this);
1433
			this.indent--; // incremented in visit(SwitchCase)
1434
		}
1435
		this.indent--;
1436
		printIndent();
1437
		this.buffer.append("}\n");//$NON-NLS-1$
1438
		return false;
1439
	}
1440
	
1441
	/*
1442
	 * @see ASTVisitor#visit(SynchronizedStatement)
1443
	 */
1444
	public boolean visit(SynchronizedStatement node) {
1445
		this.buffer.append("synchronized (");//$NON-NLS-1$
1446
		node.getExpression().accept(this);
1447
		this.buffer.append(") ");//$NON-NLS-1$
1448
		node.getBody().accept(this);
1449
		return false;
1450
	}
1451
1452
	/*
1453
	 * @see ASTVisitor#visit(TagElement)
1454
	 * @since 3.0
1455
	 */
1456
	public boolean visit(TagElement node) {
1457
		if (node.isNested()) {
1458
			// nested tags are always enclosed in braces
1459
			this.buffer.append("{");//$NON-NLS-1$
1460
		} else {
1461
			// top-level tags always begin on a new line
1462
			this.buffer.append("\n * ");//$NON-NLS-1$
1463
		}
1464
		boolean previousRequiresWhiteSpace = false;
1465
		if (node.getTagName() != null) {
1466
			this.buffer.append(node.getTagName());
1467
			previousRequiresWhiteSpace = true;
1468
		}
1469
		boolean previousRequiresNewLine = false;
1470
		for (Iterator it = node.fragments().iterator(); it.hasNext(); ) {
1471
			ASTNode e = (ASTNode) it.next();
1472
			// assume text elements include necessary leading and trailing whitespace
1473
			// but Name, MemberRef, MethodRef, and nested TagElement do not include white space
1474
			boolean currentIncludesWhiteSpace = (e instanceof TextElement);
1475
			if (previousRequiresNewLine && currentIncludesWhiteSpace) {
1476
				this.buffer.append("\n * ");//$NON-NLS-1$
1477
			}
1478
			previousRequiresNewLine = currentIncludesWhiteSpace;
1479
			// add space if required to separate
1480
			if (previousRequiresWhiteSpace && !currentIncludesWhiteSpace) {
1481
				this.buffer.append(" "); //$NON-NLS-1$
1482
			}
1483
			e.accept(this);
1484
			previousRequiresWhiteSpace = !currentIncludesWhiteSpace && !(e instanceof TagElement);
1485
		}
1486
		if (node.isNested()) {
1487
			this.buffer.append("}");//$NON-NLS-1$
1488
		}
1489
		return false;
1490
	}
1491
1492
	/*
1493
	 * @see ASTVisitor#visit(TextElement)
1494
	 * @since 3.0
1495
	 */
1496
	public boolean visit(TextElement node) {
1497
		this.buffer.append(node.getText());
1498
		return false;
1499
	}
1500
1501
	/*
1502
	 * @see ASTVisitor#visit(ThisExpression)
1503
	 */
1504
	public boolean visit(ThisExpression node) {
1505
		if (node.getQualifier() != null) {
1506
			node.getQualifier().accept(this);
1507
			this.buffer.append(".");//$NON-NLS-1$
1508
		}
1509
		this.buffer.append("this");//$NON-NLS-1$
1510
		return false;
1511
	}
1512
1513
	/*
1514
	 * @see ASTVisitor#visit(ThrowStatement)
1515
	 */
1516
	public boolean visit(ThrowStatement node) {
1517
		printIndent();
1518
		this.buffer.append("throw ");//$NON-NLS-1$
1519
		node.getExpression().accept(this);
1520
		this.buffer.append(";\n");//$NON-NLS-1$
1521
		return false;
1522
	}
1523
1524
	/*
1525
	 * @see ASTVisitor#visit(TryStatement)
1526
	 */
1527
	public boolean visit(TryStatement node) {
1528
		printIndent();
1529
		this.buffer.append("try ");//$NON-NLS-1$
1530
		node.getBody().accept(this);
1531
		this.buffer.append(" ");//$NON-NLS-1$
1532
		for (Iterator it = node.catchClauses().iterator(); it.hasNext(); ) {
1533
			CatchClause cc = (CatchClause) it.next();
1534
			cc.accept(this);
1535
		}
1536
		if (node.getFinally() != null) {
1537
			this.buffer.append(" finally ");//$NON-NLS-1$
1538
			node.getFinally().accept(this);
1539
		}
1540
		return false;
1541
	}
1542
1543
	/*
1544
	 * @see ASTVisitor#visit(TypeDeclaration)
1545
	 */
1546
	public boolean visit(TypeDeclaration node) {
1547
		if (node.getJavadoc() != null) {
1548
			node.getJavadoc().accept(this);
1549
		}
1550
		if (node.getAST().apiLevel() == JLS2) {
1551
			printModifiers(node.getModifiers());
1552
		}
1553
		if (node.getAST().apiLevel() >= AST.JLS3) {
1554
			printModifiers(node.modifiers());
1555
		}
1556
		this.buffer.append(node.isInterface() ? "interface " : "class ");//$NON-NLS-2$//$NON-NLS-1$
1557
		node.getName().accept(this);
1558
		if (node.getAST().apiLevel() >= AST.JLS3) {
1559
			if (!node.typeParameters().isEmpty()) {
1560
				this.buffer.append("<");//$NON-NLS-1$
1561
				for (Iterator it = node.typeParameters().iterator(); it.hasNext(); ) {
1562
					TypeParameter t = (TypeParameter) it.next();
1563
					t.accept(this);
1564
					if (it.hasNext()) {
1565
						this.buffer.append(",");//$NON-NLS-1$
1566
					}
1567
				}
1568
				this.buffer.append(">");//$NON-NLS-1$
1569
			}
1570
		}
1571
		this.buffer.append(" ");//$NON-NLS-1$
1572
		if (node.getAST().apiLevel() == JLS2) {
1573
			if (this.getSuperclass(node) != null) {
1574
				this.buffer.append("extends ");//$NON-NLS-1$
1575
				this.getSuperclass(node).accept(this);
1576
				this.buffer.append(" ");//$NON-NLS-1$
1577
			}
1578
			if (!this.superInterfaces(node).isEmpty()) {
1579
				this.buffer.append(node.isInterface() ? "extends " : "implements ");//$NON-NLS-2$//$NON-NLS-1$
1580
				for (Iterator it = this.superInterfaces(node).iterator(); it.hasNext(); ) {
1581
					Name n = (Name) it.next();
1582
					n.accept(this);
1583
					if (it.hasNext()) {
1584
						this.buffer.append(", ");//$NON-NLS-1$
1585
					}
1586
				}
1587
				this.buffer.append(" ");//$NON-NLS-1$
1588
			}
1589
		}
1590
		if (node.getAST().apiLevel() >= AST.JLS3) {
1591
			if (node.getSuperclassType() != null) {
1592
				this.buffer.append("extends ");//$NON-NLS-1$
1593
				node.getSuperclassType().accept(this);
1594
				this.buffer.append(" ");//$NON-NLS-1$
1595
			}
1596
			if (!node.superInterfaceTypes().isEmpty()) {
1597
				this.buffer.append(node.isInterface() ? "extends " : "implements ");//$NON-NLS-2$//$NON-NLS-1$
1598
				for (Iterator it = node.superInterfaceTypes().iterator(); it.hasNext(); ) {
1599
					Type t = (Type) it.next();
1600
					t.accept(this);
1601
					if (it.hasNext()) {
1602
						this.buffer.append(", ");//$NON-NLS-1$
1603
					}
1604
				}
1605
				this.buffer.append(" ");//$NON-NLS-1$
1606
			}
1607
		}
1608
		this.buffer.append("{\n");//$NON-NLS-1$
1609
		this.indent++;
1610
		for (Iterator it = node.bodyDeclarations().iterator(); it.hasNext(); ) {
1611
			BodyDeclaration d = (BodyDeclaration) it.next();
1612
			d.accept(this);
1613
		}
1614
		this.indent--;
1615
		printIndent();
1616
		this.buffer.append("}\n");//$NON-NLS-1$
1617
		return false;
1618
	}
1619
1620
	/*
1621
	 * @see ASTVisitor#visit(TypeDeclarationStatement)
1622
	 */
1623
	public boolean visit(TypeDeclarationStatement node) {
1624
		if (node.getAST().apiLevel() == JLS2) {
1625
			this.getTypeDeclaration(node).accept(this);
1626
		}
1627
		if (node.getAST().apiLevel() >= AST.JLS3) {
1628
			node.getDeclaration().accept(this);
1629
		}
1630
		return false;
1631
	}
1632
1633
	/*
1634
	 * @see ASTVisitor#visit(TypeLiteral)
1635
	 */
1636
	public boolean visit(TypeLiteral node) {
1637
		node.getType().accept(this);
1638
		this.buffer.append(".class");//$NON-NLS-1$
1639
		return false;
1640
	}
1641
1642
	/*
1643
	 * @see ASTVisitor#visit(TypeParameter)
1644
	 * @since 3.1
1645
	 */
1646
	public boolean visit(TypeParameter node) {
1647
		node.getName().accept(this);
1648
		if (!node.typeBounds().isEmpty()) {
1649
			this.buffer.append(" extends ");//$NON-NLS-1$
1650
			for (Iterator it = node.typeBounds().iterator(); it.hasNext(); ) {
1651
				Type t = (Type) it.next();
1652
				t.accept(this);
1653
				if (it.hasNext()) {
1654
					this.buffer.append(" & ");//$NON-NLS-1$
1655
				}
1656
			}
1657
		}
1658
		return false;
1659
	}
1660
1661
	/*
1662
	 * @see ASTVisitor#visit(VariableDeclarationExpression)
1663
	 */
1664
	public boolean visit(VariableDeclarationExpression node) {
1665
		if (node.getAST().apiLevel() == JLS2) {
1666
			printModifiers(node.getModifiers());
1667
		}
1668
		if (node.getAST().apiLevel() >= AST.JLS3) {
1669
			printModifiers(node.modifiers());
1670
		}
1671
		node.getType().accept(this);
1672
		this.buffer.append(" ");//$NON-NLS-1$
1673
		for (Iterator it = node.fragments().iterator(); it.hasNext(); ) {
1674
			VariableDeclarationFragment f = (VariableDeclarationFragment) it.next();
1675
			f.accept(this);
1676
			if (it.hasNext()) {
1677
				this.buffer.append(", ");//$NON-NLS-1$
1678
			}
1679
		}
1680
		return false;
1681
	}
1682
1683
	/*
1684
	 * @see ASTVisitor#visit(VariableDeclarationFragment)
1685
	 */
1686
	public boolean visit(VariableDeclarationFragment node) {
1687
		node.getName().accept(this);
1688
		for (int i = 0; i < node.getExtraDimensions(); i++) {
1689
			this.buffer.append("[]");//$NON-NLS-1$
1690
		}
1691
		if (node.getInitializer() != null) {
1692
			this.buffer.append("=");//$NON-NLS-1$
1693
			node.getInitializer().accept(this);
1694
		}
1695
		return false;
1696
	}
1697
1698
	/*
1699
	 * @see ASTVisitor#visit(VariableDeclarationStatement)
1700
	 */
1701
	public boolean visit(VariableDeclarationStatement node) {
1702
		printIndent();
1703
		if (node.getAST().apiLevel() == JLS2) {
1704
			printModifiers(node.getModifiers());
1705
		}
1706
		if (node.getAST().apiLevel() >= AST.JLS3) {
1707
			printModifiers(node.modifiers());
1708
		}
1709
		node.getType().accept(this);
1710
		this.buffer.append(" ");//$NON-NLS-1$
1711
		for (Iterator it = node.fragments().iterator(); it.hasNext(); ) {
1712
			VariableDeclarationFragment f = (VariableDeclarationFragment) it.next();
1713
			f.accept(this);
1714
			if (it.hasNext()) {
1715
				this.buffer.append(", ");//$NON-NLS-1$
1716
			}
1717
		}
1718
		this.buffer.append(";\n");//$NON-NLS-1$
1719
		return false;
1720
	}
1721
1722
	/*
1723
	 * @see ASTVisitor#visit(WhileStatement)
1724
	 */
1725
	public boolean visit(WhileStatement node) {
1726
		printIndent();
1727
		this.buffer.append("while (");//$NON-NLS-1$
1728
		node.getExpression().accept(this);
1729
		this.buffer.append(") ");//$NON-NLS-1$
1730
		node.getBody().accept(this);
1731
		return false;
1732
	}
1733
1734
	/*
1735
	 * @see ASTVisitor#visit(WildcardType)
1736
	 * @since 3.1
1737
	 */
1738
	public boolean visit(WildcardType node) {
1739
		this.buffer.append("?");//$NON-NLS-1$
1740
		Type bound = node.getBound();
1741
		if (bound != null) {
1742
			if (node.isUpperBound()) {
1743
				this.buffer.append(" extends ");//$NON-NLS-1$
1744
			} else {
1745
				this.buffer.append(" super ");//$NON-NLS-1$
1746
			}
1747
			bound.accept(this);
1748
		}
1749
		return false;
1750
	}
1751
1752
}
(-)src/org/eclipse/jdt/core/tests/dom/AbstractASTTests.java (-12 / +142 lines)
Lines 22-28 Link Here
22
import org.eclipse.jdt.core.IProblemRequestor;
22
import org.eclipse.jdt.core.IProblemRequestor;
23
import org.eclipse.jdt.core.JavaModelException;
23
import org.eclipse.jdt.core.JavaModelException;
24
import org.eclipse.jdt.core.WorkingCopyOwner;
24
import org.eclipse.jdt.core.WorkingCopyOwner;
25
import org.eclipse.jdt.core.compiler.CharOperation;
26
import org.eclipse.jdt.core.compiler.IProblem;
25
import org.eclipse.jdt.core.compiler.IProblem;
27
import org.eclipse.jdt.core.dom.AST;
26
import org.eclipse.jdt.core.dom.AST;
28
import org.eclipse.jdt.core.dom.ASTNode;
27
import org.eclipse.jdt.core.dom.ASTNode;
Lines 55-64 Link Here
55
import org.eclipse.jdt.core.tests.model.ModifyingResourceTests;
54
import org.eclipse.jdt.core.tests.model.ModifyingResourceTests;
56
import org.eclipse.jdt.core.tests.util.Util;
55
import org.eclipse.jdt.core.tests.util.Util;
57
56
58
public class AbstractASTTests extends ModifyingResourceTests {
57
public class AbstractASTTests extends ModifyingResourceTests implements DefaultMarkedNodeLabelProviderOptions {
59
58
	
60
//	ICompilationUnit[] workingCopies;
59
	/** @deprecated Using deprecated code */
61
60
	private static final int AST_INTERNAL_JLS2 = AST.JLS2;
61
	public static final int astInternalJLS2() {
62
		return AST_INTERNAL_JLS2;
63
	}
64
	
65
	// TODO (frederic) use this field while converting instead of method argument
66
	protected int testLevel = AST_INTERNAL_JLS2;
67
	
62
	public AbstractASTTests(String name) {
68
	public AbstractASTTests(String name) {
63
		super(name);
69
		super(name);
64
	}
70
	}
Lines 70-89 Link Here
70
	public class MarkerInfo {
76
	public class MarkerInfo {
71
		String path;
77
		String path;
72
		String source;
78
		String source;
79
		
80
		String markerStartStart;
81
		String markerStartEnd;
82
		String markerEndStart;
83
		String markerEndEnd;
84
		
73
		int[] astStarts, astEnds;
85
		int[] astStarts, astEnds;
74
		
86
		
75
		public MarkerInfo(String source) {
87
		public MarkerInfo(String source) {
76
			this(null, source);
88
			this(null, source);
77
		}
89
		}
78
		public MarkerInfo(String path, String source) {
90
		public MarkerInfo(String path, String source) {
91
			this(path, source, "/*", "*/", "start", "end");
92
		}
93
		public MarkerInfo(
94
				String source,
95
				String markerBeginning,
96
				String markerEnding,
97
				String markerStart,
98
				String markerEnd) {
99
			this(null, source, markerBeginning, markerEnding, markerStart, markerEnd);
100
		}
101
		
102
		public MarkerInfo(
103
				String path,
104
				String source,
105
				String markerBeginning,
106
				String markerEnding,
107
				String markerStart,
108
				String markerEnd) {
79
			this.path = path;
109
			this.path = path;
80
			this.source = source;
110
			this.source = source;
111
			
112
			this.markerStartStart = markerBeginning + markerStart;
113
			this.markerStartEnd = markerEnding;
114
			this.markerEndStart = markerBeginning + markerEnd;
115
			this.markerEndEnd = markerEnding;
81
116
82
			int markerIndex = 1;
117
			int markerIndex = 1;
83
			while (source.indexOf("/*start" + markerIndex + "*/") != -1) {
118
			while (source.indexOf(this.markerStartStart + markerIndex + this.markerStartEnd) != -1) {
84
				markerIndex++;
119
				markerIndex++;
85
			}
120
			}
86
			int astNumber = source.indexOf("/*start*/") != -1 ? markerIndex : markerIndex-1;
121
			int astNumber = source.indexOf(this.markerStartStart + this.markerStartEnd) != -1 ? markerIndex : markerIndex-1;
87
			this.astStarts = new int[astNumber];
122
			this.astStarts = new int[astNumber];
88
			this.astEnds = new int[astNumber];
123
			this.astEnds = new int[astNumber];
89
			
124
			
Lines 101-110 Link Here
101
		}
136
		}
102
		
137
		
103
		private void removeMarkerFromSource(String marker, int sourceIndex, int astNumber) {
138
		private void removeMarkerFromSource(String marker, int sourceIndex, int astNumber) {
104
			char[] markerChars = marker.toCharArray();
139
			int markerLength = marker.length();
105
			this.source = new String(CharOperation.replace(this.source.toCharArray(), markerChars, CharOperation.NO_CHAR));
140
			this.source = this.source.substring(0, sourceIndex).concat(this.source.substring(sourceIndex + markerLength));
106
			// shift previously recorded positions
141
			// shift previously recorded positions
107
			int markerLength = markerChars.length;
108
			for (int i = 0; i < astNumber; i++) {
142
			for (int i = 0; i < astNumber; i++) {
109
				if (this.astStarts[i] > sourceIndex)
143
				if (this.astStarts[i] > sourceIndex)
110
					this.astStarts[i] -= markerLength;
144
					this.astStarts[i] -= markerLength;
Lines 121-128 Link Here
121
			} else
155
			} else
122
				markerNumber = Integer.toString(markerIndex);
156
				markerNumber = Integer.toString(markerIndex);
123
			
157
			
124
			String markerStart = "/*start" + markerNumber + "*/";
158
			String markerStart = this.markerStartStart + markerNumber + this.markerStartEnd;
125
			String markerEnd = "/*end" + markerNumber + "*/";
159
			String markerEnd = this.markerEndStart + markerNumber + this.markerEndEnd;
126
			int astStart = this.source.indexOf(markerStart); // start of AST inclusive
160
			int astStart = this.source.indexOf(markerStart); // start of AST inclusive
127
			this.astStarts[markerIndex-1] = astStart;
161
			this.astStarts[markerIndex-1] = astStart;
128
			removeMarkerFromSource(markerStart, astStart, markerIndex-1);
162
			removeMarkerFromSource(markerStart, astStart, markerIndex-1);
Lines 147-152 Link Here
147
			return result;
181
			return result;
148
		}
182
		}
149
	}
183
	}
184
	
185
	public static class ASTResult {
186
		public String result; // marked ast output
187
		public String source; // source without marker
188
		public ASTResult(String result, String source) {
189
			this.result = result;
190
			this.source = source;
191
		}
192
	}
150
		
193
		
151
	protected void assertASTNodeEquals(String expected, ASTNode node) {
194
	protected void assertASTNodeEquals(String expected, ASTNode node) {
152
		String actual = node.toString();
195
		String actual = node.toString();
Lines 226-232 Link Here
226
		}
269
		}
227
		assertEquals(message, expected, actual);
270
		assertEquals(message, expected, actual);
228
	}
271
	}
272
	
273
	protected void assertASTResult(
274
			String expected,
275
			ASTResult actual) throws JavaModelException {
276
		
277
		if (!expected.equals(actual.result)) {
278
			System.out.println();
279
			System.out.println(actual.source);
280
			System.out.println(Util.displayString(actual.result, 3));
281
		}
282
		
283
		assertEquals(expected, actual.result);
284
	}
229
285
286
	// TODO (frederic) replace all ASTParser creation with by calling this method
287
	protected ASTParser createASTParser() {
288
	    ASTParser parser = ASTParser.newParser(this.testLevel);
289
	    return parser;
290
    }
230
	/*
291
	/*
231
	 * Builds an AST from the info source (which is assumed to be the source attached to the given class file), 
292
	 * Builds an AST from the info source (which is assumed to be the source attached to the given class file), 
232
	 * and returns the AST node that was delimited by the astStart and astEnd of the marker info.
293
	 * and returns the AST node that was delimited by the astStart and astEnd of the marker info.
Lines 376-381 Link Here
376
		return nodes;
437
		return nodes;
377
	}
438
	}
378
	
439
	
440
	protected ASTResult buildMarkedAST(
441
			String path,
442
			String content) throws JavaModelException {
443
		return
444
			this.buildMarkedAST(
445
					path,
446
					content,
447
					true, // enable statement recovery
448
					true, // report ast
449
					true, // report problems
450
					new MarkedASTFlattener.DefaultMarkedNodeLabelProvider(ALL_OPTIONS));
451
	}
452
	
453
	protected ASTResult buildMarkedAST(
454
			String path,
455
			String content,
456
			boolean enableStatementRecovery,
457
			boolean reportAST,
458
			boolean reportProblems,
459
			int options) throws JavaModelException {
460
		return 
461
			this.buildMarkedAST(
462
					path,
463
					content,
464
					enableStatementRecovery,
465
					reportAST,
466
					reportProblems,
467
					new MarkedASTFlattener.DefaultMarkedNodeLabelProvider(options));
468
	}
469
	
470
	/*
471
	 * Removes the marker comments "[*?*]" from the given new contents
472
	 * (where ? is either empty or a number), or use the current contents if the given new contents is null.
473
	 * Builds an AST from the resulting source and information about marked nodes.
474
	 */
475
	protected ASTResult buildMarkedAST(
476
			String path,
477
			String content,
478
			boolean enableStatementRecovery,
479
			boolean reportAST,
480
			boolean reportProblems,
481
			MarkedASTFlattener.DefaultMarkedNodeLabelProvider labelProvider) throws JavaModelException {
482
		
483
		MarkerInfo markerInfo;
484
		markerInfo = new MarkerInfo(content, "[*", "*]", "", "");
485
		content = markerInfo.source;
486
		
487
		ICompilationUnit compilationUnit = getWorkingCopy(path, content, true);
488
		
489
		ASTParser parser = createASTParser();
490
		parser.setSource(compilationUnit);
491
		parser.setResolveBindings(true);
492
		parser.setWorkingCopyOwner(this.wcOwner);
493
		parser.setStatementsRecovery(enableStatementRecovery);
494
		CompilationUnit unit = (CompilationUnit)parser.createAST(null);
495
		
496
		MarkedASTFlattener flattener =
497
			new MarkedASTFlattener(
498
					reportAST,
499
					reportProblems,
500
					labelProvider);
501
		flattener.process(unit, markerInfo);
502
		
503
		ASTResult result = new ASTResult(flattener.getResult(), markerInfo.source);
504
		
505
		compilationUnit.discardWorkingCopy();
506
		
507
		return result;
508
	}
379
509
380
	protected MarkerInfo[] createMarkerInfos(String[] pathAndSources) {
510
	protected MarkerInfo[] createMarkerInfos(String[] pathAndSources) {
381
		MarkerInfo[] markerInfos = new MarkerInfo[pathAndSources.length / 2];
511
		MarkerInfo[] markerInfos = new MarkerInfo[pathAndSources.length / 2];
(-)src/org/eclipse/jdt/core/tests/dom/ConverterTestSetup.java (-20 / +9 lines)
Lines 26-38 Link Here
26
import org.eclipse.jdt.core.tests.util.Util;
26
import org.eclipse.jdt.core.tests.util.Util;
27
27
28
public abstract class ConverterTestSetup extends AbstractASTTests {
28
public abstract class ConverterTestSetup extends AbstractASTTests {
29
29
	
30
	/** @deprecated Using deprecated code */
31
	public static final int AST_INTERNAL_JLS2 = AST.JLS2;
32
33
	protected AST ast;
30
	protected AST ast;
34
	// TODO (frederic) use this field while converting instead of method argument
35
	protected int testLevel = AST_INTERNAL_JLS2;
36
	static List TEST_SUITES = null;
31
	static List TEST_SUITES = null;
37
	static boolean PROJECT_SETUP = false;
32
	static boolean PROJECT_SETUP = false;
38
33
Lines 40-51 Link Here
40
		super(name);
35
		super(name);
41
	}
36
	}
42
37
43
	// TODO (frederic) replace all ASTParser creation with by calling this method
44
	protected ASTParser createASTParser() {
45
	    ASTParser parser = ASTParser.newParser(this.testLevel);
46
	    return parser;
47
    }
48
49
	protected IPath getConverterJCLPath() {
38
	protected IPath getConverterJCLPath() {
50
		return getConverterJCLPath(""); //$NON-NLS-1$
39
		return getConverterJCLPath(""); //$NON-NLS-1$
51
	}
40
	}
Lines 124-146 Link Here
124
	}
113
	}
125
114
126
	public ASTNode runConversion(ICompilationUnit unit, boolean resolveBindings) {
115
	public ASTNode runConversion(ICompilationUnit unit, boolean resolveBindings) {
127
		return runConversion(AST_INTERNAL_JLS2, unit, resolveBindings);
116
		return runConversion(astInternalJLS2(), unit, resolveBindings);
128
	}
117
	}
129
118
130
	public ASTNode runConversion(ICompilationUnit unit, int position, boolean resolveBindings) {
119
	public ASTNode runConversion(ICompilationUnit unit, int position, boolean resolveBindings) {
131
		return runConversion(AST_INTERNAL_JLS2, unit, position, resolveBindings);
120
		return runConversion(astInternalJLS2(), unit, position, resolveBindings);
132
	}
121
	}
133
122
134
	public ASTNode runConversion(IClassFile classFile, int position, boolean resolveBindings) {
123
	public ASTNode runConversion(IClassFile classFile, int position, boolean resolveBindings) {
135
		return runConversion(AST_INTERNAL_JLS2, classFile, position, resolveBindings);
124
		return runConversion(astInternalJLS2(), classFile, position, resolveBindings);
136
	}
125
	}
137
126
138
	public ASTNode runConversion(char[] source, String unitName, IJavaProject project) {
127
	public ASTNode runConversion(char[] source, String unitName, IJavaProject project) {
139
		return runConversion(AST_INTERNAL_JLS2, source, unitName, project);
128
		return runConversion(astInternalJLS2(), source, unitName, project);
140
	}
129
	}
141
130
142
	public ASTNode runConversion(char[] source, String unitName, IJavaProject project, boolean resolveBindings) {
131
	public ASTNode runConversion(char[] source, String unitName, IJavaProject project, boolean resolveBindings) {
143
		return runConversion(AST_INTERNAL_JLS2, source, unitName, project, resolveBindings);
132
		return runConversion(astInternalJLS2(), source, unitName, project, resolveBindings);
144
	}
133
	}
145
134
146
	public ASTNode runConversion(int astLevel, ICompilationUnit unit, boolean resolveBindings) {
135
	public ASTNode runConversion(int astLevel, ICompilationUnit unit, boolean resolveBindings) {
Lines 418-424 Link Here
418
		// Create parser
407
		// Create parser
419
		ASTParser parser;
408
		ASTParser parser;
420
		if (checkJLS2) {
409
		if (checkJLS2) {
421
			parser = ASTParser.newParser(AST_INTERNAL_JLS2);
410
			parser = ASTParser.newParser(astInternalJLS2());
422
			parser.setSource(unit);
411
			parser.setSource(unit);
423
			parser.setResolveBindings(resolveBindings);
412
			parser.setResolveBindings(resolveBindings);
424
			parser.createAST(null);
413
			parser.createAST(null);
Lines 505-514 Link Here
505
	}
494
	}
506
495
507
	public ASTNode runConversion(char[] source, String unitName, IJavaProject project, Map options, boolean resolveBindings) {
496
	public ASTNode runConversion(char[] source, String unitName, IJavaProject project, Map options, boolean resolveBindings) {
508
		return runConversion(AST_INTERNAL_JLS2, source, unitName, project, options, resolveBindings);
497
		return runConversion(astInternalJLS2(), source, unitName, project, options, resolveBindings);
509
	}
498
	}
510
	public ASTNode runConversion(char[] source, String unitName, IJavaProject project, Map options) {
499
	public ASTNode runConversion(char[] source, String unitName, IJavaProject project, Map options) {
511
		return runConversion(AST_INTERNAL_JLS2, source, unitName, project, options);
500
		return runConversion(astInternalJLS2(), source, unitName, project, options);
512
	}
501
	}
513
502
514
	protected ASTNode getASTNodeToCompare(org.eclipse.jdt.core.dom.CompilationUnit unit) {
503
	protected ASTNode getASTNodeToCompare(org.eclipse.jdt.core.dom.CompilationUnit unit) {
(-)src/org/eclipse/jdt/core/tests/dom/ASTConverterBugsTest.java (+119 lines)
Lines 536-539 Link Here
536
		methodDeclaration.resolveBinding()
536
		methodDeclaration.resolveBinding()
537
	);
537
	);
538
}
538
}
539
540
/*
541
 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=215759
542
 */
543
/**
544
 * @bug 215759: DOM AST regression tests should be improved
545
 * @test these tests test the new DOM AST test framework
546
 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=215759"
547
 */
548
public void testBug215759a() throws CoreException {
549
	this.workingCopies = new ICompilationUnit[1];
550
551
	this.workingCopies[0] = getWorkingCopy(
552
			"/Converter/src/p/Y.java",
553
			"package p;\n" + 
554
			"public class  Y {\n" + 
555
			"}",
556
			true/*resolve*/);
557
	
558
	ASTResult result = this.buildMarkedAST(
559
			"/Converter/src/p/X.java",
560
			"package p;\n" + 
561
			"public class X extends Y {\n" + 
562
			"	/**\n" + 
563
			"	 * blabla1\n" + 
564
			"	 * @param [*1*]string[*1*] blabla2\n" + 
565
			"	 */\n" + 
566
			"	protected [*2*]String[*2*] foo(String string) {\n" + 
567
			"		return [*3*](\"\" + string + \"\")[*3*] + (\"\");\n" + 
568
			"	}\n" + 
569
			"	/*comment*/[*4*]protected void bar() {}[*4*]\n" + 
570
			"	#\n" + 
571
			"}");
572
	
573
	assertASTResult(
574
			"===== AST =====\n" + 
575
			"package p;\n" + 
576
			"public class X extends Y {\n" + 
577
			"  /** \n" + 
578
			" * blabla1\n" + 
579
			" * @param [*1*]string[*1*] blabla2\n" + 
580
			" */\n" + 
581
			"  protected [*2*]String[*2*] foo(  String string){\n" + 
582
			"    return [*3*](\"\" + string + \"\")[*3*] + (\"\");\n" + 
583
			"  }\n" + 
584
			"  [*4*]protected void bar(){\n" + 
585
			"  }[*4*]\n" + 
586
			"}\n" + 
587
			"\n" + 
588
			"===== Details =====\n" + 
589
			"1:SIMPLE_NAME,[66,6],,,[VARIABLE,Lp/X;.foo(Ljava/lang/String;)Ljava/lang/String;#string,]\n" + 
590
			"2:SIMPLE_TYPE,[97,6],,,[TYPE,Ljava/lang/String;,]\n" + 
591
			"2:SIMPLE_NAME,[97,6],,,[TYPE,Ljava/lang/String;,]\n" + 
592
			"3:PARENTHESIZED_EXPRESSION,[134,18],,,[N/A]\n" + 
593
			"4:METHOD_DECLARATION,[176,23],,,[METHOD,Lp/X;.bar()V,]\n" + 
594
			"===== Problems =====\n" + 
595
			"1. ERROR in /Converter/src/p/X.java (at line 11)\n" + 
596
			"	#\n" + 
597
			"	^\n" + 
598
			"Syntax error on token \"Invalid Character\", delete this token\n",
599
			result);
600
}
601
602
public void testBug215759b() throws CoreException {
603
	this.workingCopies = new ICompilationUnit[1];
604
	
605
	this.workingCopies[0] = getWorkingCopy(
606
			"/Converter/src/p/Y.java",
607
			"package p;\n" + 
608
			"public class  Y {\n" + 
609
			"}",
610
			true/*resolve*/);
611
	
612
	ASTResult result = this.buildMarkedAST(
613
			"/Converter/src/p/X.java",
614
			"package p;\n" + 
615
			"public class X extends Y {\n" + 
616
			"	/**\n" + 
617
			"	 * blabla1\n" + 
618
			"	 * @param [*1*]string[*1*] blabla2\n" + 
619
			"	 */\n" + 
620
			"	protected [*2*]String[*2*] foo(String string) {\n" + 
621
			"		return [*3*](\"\" + string + \"\")[*3*] + (\"\");\n" + 
622
			"	}\n" + 
623
			"	/*comment*/[*4*]protected void bar() {}[*4*]\n" + 
624
			"	[*5*]/**@deprecated*/protected void bar2() {}[*5*]\n" + 
625
			"}");
626
	
627
	assertASTResult(
628
			"===== AST =====\n" + 
629
			"package p;\n" + 
630
			"public class X extends Y {\n" + 
631
			"  /** \n" + 
632
			" * blabla1\n" + 
633
			" * @param [*1*]string[*1*] blabla2\n" + 
634
			" */\n" + 
635
			"  protected [*2*]String[*2*] foo(  String string){\n" + 
636
			"    return [*3*](\"\" + string + \"\")[*3*] + (\"\");\n" + 
637
			"  }\n" + 
638
			"  [*4*]protected void bar(){\n" + 
639
			"  }[*4*]\n" + 
640
			"  [*5*]/** \n" + 
641
			" * @deprecated\n" + 
642
			" */\n" + 
643
			"  protected void bar2(){\n" + 
644
			"  }[*5*]\n" + 
645
			"}\n" + 
646
			"\n" + 
647
			"===== Details =====\n" + 
648
			"1:SIMPLE_NAME,[66,6],,,[VARIABLE,Lp/X;.foo(Ljava/lang/String;)Ljava/lang/String;#string,]\n" + 
649
			"2:SIMPLE_TYPE,[97,6],,,[TYPE,Ljava/lang/String;,]\n" + 
650
			"2:SIMPLE_NAME,[97,6],,,[TYPE,Ljava/lang/String;,]\n" + 
651
			"3:PARENTHESIZED_EXPRESSION,[134,18],,,[N/A]\n" + 
652
			"4:METHOD_DECLARATION,[176,23],[165,34],,[METHOD,Lp/X;.bar()V,]\n" + 
653
			"5:METHOD_DECLARATION,[201,40],,,[METHOD,Lp/X;.bar2()V,DEPRECATED]\n" + 
654
			"===== Problems =====\n" + 
655
			"No Problem",
656
			result);
657
}
539
}
658
}
(-)src/org/eclipse/jdt/core/tests/dom/MarkedASTFlattener.java (+574 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.jdt.core.tests.dom;
12
13
import java.util.HashMap;
14
import java.util.Map;
15
16
import org.eclipse.jdt.core.compiler.IProblem;
17
import org.eclipse.jdt.core.dom.ASTNode;
18
import org.eclipse.jdt.core.dom.AnonymousClassDeclaration;
19
import org.eclipse.jdt.core.dom.ArrayType;
20
import org.eclipse.jdt.core.dom.Assignment;
21
import org.eclipse.jdt.core.dom.CompilationUnit;
22
import org.eclipse.jdt.core.dom.IBinding;
23
import org.eclipse.jdt.core.dom.MarkerAnnotation;
24
import org.eclipse.jdt.core.dom.MethodDeclaration;
25
import org.eclipse.jdt.core.dom.MethodInvocation;
26
import org.eclipse.jdt.core.dom.NormalAnnotation;
27
import org.eclipse.jdt.core.dom.PackageDeclaration;
28
import org.eclipse.jdt.core.dom.ParameterizedType;
29
import org.eclipse.jdt.core.dom.QualifiedName;
30
import org.eclipse.jdt.core.dom.SimpleName;
31
import org.eclipse.jdt.core.dom.SimpleType;
32
import org.eclipse.jdt.core.dom.SingleMemberAnnotation;
33
import org.eclipse.jdt.core.dom.TypeDeclaration;
34
import org.eclipse.jdt.core.dom.TypeDeclarationStatement;
35
import org.eclipse.jdt.core.dom.TypeParameter;
36
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
37
import org.eclipse.jdt.core.dom.WildcardType;
38
import org.eclipse.jdt.core.tests.util.Util;
39
import org.eclipse.jdt.internal.core.dom.NaiveASTFlattener;
40
41
/**
42
 * Serialize the ast and decorate this ast with markers.
43
 * Compute also extra information about marked nodes.
44
 */
45
public class MarkedASTFlattener extends NaiveASTFlattener {
46
	public static class DefaultMarkedNodeLabelProvider extends MarkedNodeLabelProvider implements DefaultMarkedNodeLabelProviderOptions {
47
		
48
		private int options;
49
		
50
		public DefaultMarkedNodeLabelProvider(int options) {
51
			this.options = options;
52
		}
53
		
54
		private void appendBinding(ASTNode node, StringBuffer buffer) {
55
			buffer.append('[');
56
			try {
57
				IBinding binding = resolveBinding(node);
58
				if (binding != null) {
59
					boolean first = true;
60
					if ((this.options & BINDING_KIND) != 0) {
61
						if (!first) buffer.append(',');
62
						first = false;
63
						
64
						this.appendBindingKind(binding, buffer);
65
					}
66
					if ((this.options & BINDING_KEY) != 0) {
67
						if (!first) buffer.append(',');
68
						first = false;
69
						
70
						this.appendBindingKey(binding, buffer);
71
					}
72
					if ((this.options & BINDING_FLAGS) != 0) {
73
						if (!first) buffer.append(',');
74
						first = false;
75
						
76
						this.appendBindingFlags(binding, buffer);
77
					}
78
				} else {
79
					buffer.append("null");
80
				}
81
			} catch (IllegalArgumentException e) {
82
				buffer.append("N/A");
83
			}
84
			
85
			buffer.append(']');
86
		}
87
		
88
		private void appendBindingFlags(IBinding binding, StringBuffer buffer) {
89
			boolean firstFlag = true;
90
			if (binding.isDeprecated()) {
91
				if (!firstFlag) buffer.append('|');
92
				firstFlag = false;
93
				
94
				buffer.append("DEPRECATED");
95
			}
96
			if (binding.isSynthetic()) {
97
				if (!firstFlag) buffer.append('|');
98
				firstFlag = false;
99
				
100
				buffer.append("SYNTHETIC");
101
			}
102
			if (binding.isRecovered()) {
103
				if (!firstFlag) buffer.append('|');
104
				firstFlag = false;
105
				
106
				buffer.append("RECOVERED");
107
			}
108
		}
109
110
		private void appendBindingKey(IBinding binding, StringBuffer buffer) {
111
			buffer.append(binding.getKey());
112
		}
113
114
		private void appendBindingKind(IBinding binding, StringBuffer buffer) {
115
			switch (binding.getKind()) {
116
				case IBinding.ANNOTATION:
117
					buffer.append("ANNOTATION");break;
118
				case IBinding.MEMBER_VALUE_PAIR:
119
					buffer.append("MEMBER_VALUE_PAIR");break;
120
				case IBinding.METHOD:
121
					buffer.append("METHOD");break;
122
				case IBinding.PACKAGE:
123
					buffer.append("PACKAGE");break;
124
				case IBinding.TYPE:
125
					buffer.append("TYPE");break;
126
				case IBinding.VARIABLE:
127
					buffer.append("VARIABLE");break;
128
				default:
129
					buffer.append("UNKNOWN");break;
130
			}
131
		}
132
133
		private void appendFlags(ASTNode node, StringBuffer buffer) {
134
			boolean firstFlag = true;
135
			int flags = node.getFlags();
136
			if ((flags & ASTNode.MALFORMED) != 0) {
137
				if (!firstFlag) buffer.append('|');
138
				firstFlag = false;
139
				
140
				buffer.append("MALFORMED");
141
			}
142
			if ((flags & ASTNode.PROTECT) != 0) {
143
				if (!firstFlag) buffer.append('|');
144
				firstFlag = false;
145
				
146
				buffer.append("PROTECT");
147
			}
148
			if ((flags & ASTNode.RECOVERED) != 0) {
149
				if (!firstFlag) buffer.append('|');
150
				firstFlag = false;
151
				
152
				buffer.append("RECOVERED");
153
			}
154
		
155
			// All nodes are ORIGINAL by default. So an information is printed only when the node isn't ORIGINAL
156
			if ((flags & ASTNode.ORIGINAL) == 0) {
157
				if (!firstFlag) buffer.append('|');
158
				firstFlag = false;
159
				
160
				buffer.append("!ORIGINAL");
161
			}
162
		}
163
164
		private void appendNodeExtendedPosition(ASTNode node, StringBuffer buffer) {
165
			ASTNode root = node.getRoot();
166
			
167
			if (root.getNodeType() == ASTNode.COMPILATION_UNIT) {
168
				CompilationUnit cu = (CompilationUnit) root;
169
				
170
				int extendedStartPosition = cu.getExtendedStartPosition(node);
171
				int extendedLength = cu.getExtendedLength(node);
172
				if (extendedStartPosition != node.getStartPosition() ||
173
						extendedLength != node.getLength()) {
174
					buffer.append('[');
175
					buffer.append(cu.getExtendedStartPosition(node));
176
					buffer.append(',');
177
					buffer.append(cu.getExtendedLength(node));
178
					buffer.append(']');
179
				}
180
				
181
			} else {
182
				buffer.append("[N/A]");
183
			}
184
			
185
		}
186
187
		private void appendNodePosition(ASTNode node, StringBuffer buffer) {
188
			buffer.append('[');
189
			buffer.append(node.getStartPosition());
190
			buffer.append(',');
191
			buffer.append(node.getLength());
192
			buffer.append(']');
193
		}
194
195
		private void appendNodeType(ASTNode node, StringBuffer buffer) {
196
			switch (node.getNodeType()) {
197
				case ASTNode.ANNOTATION_TYPE_DECLARATION :
198
					buffer.append("ANNOTATION_TYPE_DECLARATION");break;
199
				case ASTNode.ANNOTATION_TYPE_MEMBER_DECLARATION :
200
					buffer.append("ANNOTATION_TYPE_MEMBER_DECLARATION");break;
201
				case ASTNode.ANONYMOUS_CLASS_DECLARATION :
202
					buffer.append("ANONYMOUS_CLASS_DECLARATION");break;
203
				case ASTNode.ARRAY_ACCESS :
204
					buffer.append("ARRAY_ACCESS");break;
205
				case ASTNode.ARRAY_CREATION :
206
					buffer.append("ARRAY_CREATION");break;
207
				case ASTNode.ARRAY_INITIALIZER :
208
					buffer.append("ARRAY_INITIALIZER");break;
209
				case ASTNode.ARRAY_TYPE :
210
					buffer.append("ARRAY_TYPE");break;
211
				case ASTNode.ASSERT_STATEMENT :
212
					buffer.append("ASSERT_STATEMENT");break;
213
				case ASTNode.ASSIGNMENT :
214
					buffer.append("ASSIGNMENT");break;
215
				case ASTNode.BLOCK :
216
					buffer.append("BLOCK");break;
217
				case ASTNode.BLOCK_COMMENT :
218
					buffer.append("BLOCK_COMMENT");break;
219
				case ASTNode.BOOLEAN_LITERAL :
220
					buffer.append("BOOLEAN_LITERAL");break;
221
				case ASTNode.BREAK_STATEMENT :
222
					buffer.append("BREAK_STATEMENT");break;
223
				case ASTNode.CAST_EXPRESSION :
224
					buffer.append("CAST_EXPRESSION");break;
225
				case ASTNode.CATCH_CLAUSE :
226
					buffer.append("CATCH_CLAUSE");break;
227
				case ASTNode.CHARACTER_LITERAL :
228
					buffer.append("CHARACTER_LITERAL");break;
229
				case ASTNode.CLASS_INSTANCE_CREATION :
230
					buffer.append("CLASS_INSTANCE_CREATION");break;
231
				case ASTNode.COMPILATION_UNIT :
232
					buffer.append("COMPILATION_UNIT");break;
233
				case ASTNode.CONDITIONAL_EXPRESSION :
234
					buffer.append("CONDITIONAL_EXPRESSION");break;
235
				case ASTNode.CONSTRUCTOR_INVOCATION :
236
					buffer.append("CONSTRUCTOR_INVOCATION");break;
237
				case ASTNode.CONTINUE_STATEMENT :
238
					buffer.append("CONTINUE_STATEMENT");break;
239
				case ASTNode.DO_STATEMENT :
240
					buffer.append("DO_STATEMENT");break;
241
				case ASTNode.EMPTY_STATEMENT :
242
					buffer.append("EMPTY_STATEMENT");break;
243
				case ASTNode.ENHANCED_FOR_STATEMENT :
244
					buffer.append("ENHANCED_FOR_STATEMENT");break;
245
				case ASTNode.ENUM_CONSTANT_DECLARATION :
246
					buffer.append("ENUM_CONSTANT_DECLARATION");break;
247
				case ASTNode.ENUM_DECLARATION :
248
					buffer.append("ENUM_DECLARATION");break;
249
				case ASTNode.EXPRESSION_STATEMENT :
250
					buffer.append("EXPRESSION_STATEMENT");break;
251
				case ASTNode.FIELD_ACCESS :
252
					buffer.append("FIELD_ACCESS");break;
253
				case ASTNode.FIELD_DECLARATION :
254
					buffer.append("FIELD_DECLARATION");break;
255
				case ASTNode.FOR_STATEMENT :
256
					buffer.append("FOR_STATEMENT");break;
257
				case ASTNode.IF_STATEMENT :
258
					buffer.append("IF_STATEMENT");break;
259
				case ASTNode.IMPORT_DECLARATION :
260
					buffer.append("IMPORT_DECLARATION");break;
261
				case ASTNode.INFIX_EXPRESSION :
262
					buffer.append("INFIX_EXPRESSION");break;
263
				case ASTNode.INITIALIZER :
264
					buffer.append("INITIALIZER");break;
265
				case ASTNode.INSTANCEOF_EXPRESSION :
266
					buffer.append("INSTANCEOF_EXPRESSION");break;
267
				case ASTNode.JAVADOC :
268
					buffer.append("JAVADOC");break;
269
				case ASTNode.LABELED_STATEMENT :
270
					buffer.append("LABELED_STATEMENT");break;
271
				case ASTNode.LINE_COMMENT :
272
					buffer.append("LINE_COMMENT");break;
273
				case ASTNode.MARKER_ANNOTATION :
274
					buffer.append("MARKER_ANNOTATION");break;
275
				case ASTNode.MEMBER_REF :
276
					buffer.append("MEMBER_REF");break;
277
				case ASTNode.MEMBER_VALUE_PAIR :
278
					buffer.append("MEMBER_VALUE_PAIR");break;
279
				case ASTNode.METHOD_DECLARATION :
280
					buffer.append("METHOD_DECLARATION");break;
281
				case ASTNode.METHOD_INVOCATION :
282
					buffer.append("METHOD_INVOCATION");break;
283
				case ASTNode.METHOD_REF :
284
					buffer.append("METHOD_REF");break;
285
				case ASTNode.METHOD_REF_PARAMETER :
286
					buffer.append("METHOD_REF_PARAMETER");break;
287
				case ASTNode.MODIFIER :
288
					buffer.append("MODIFIER");break;
289
				case ASTNode.NORMAL_ANNOTATION :
290
					buffer.append("NORMAL_ANNOTATION");break;
291
				case ASTNode.NULL_LITERAL :
292
					buffer.append("NULL_LITERAL");break;
293
				case ASTNode.NUMBER_LITERAL :
294
					buffer.append("NUMBER_LITERAL");break;
295
				case ASTNode.PACKAGE_DECLARATION :
296
					buffer.append("PACKAGE_DECLARATION");break;
297
				case ASTNode.PARAMETERIZED_TYPE :
298
					buffer.append("PARAMETERIZED_TYPE");break;
299
				case ASTNode.PARENTHESIZED_EXPRESSION :
300
					buffer.append("PARENTHESIZED_EXPRESSION");break;
301
				case ASTNode.POSTFIX_EXPRESSION :
302
					buffer.append("POSTFIX_EXPRESSION");break;
303
				case ASTNode.PREFIX_EXPRESSION :
304
					buffer.append("PREFIX_EXPRESSION");break;
305
				case ASTNode.PRIMITIVE_TYPE :
306
					buffer.append("PRIMITIVE_TYPE");break;
307
				case ASTNode.QUALIFIED_NAME :
308
					buffer.append("QUALIFIED_NAME");break;
309
				case ASTNode.QUALIFIED_TYPE :
310
					buffer.append("QUALIFIED_TYPE");break;
311
				case ASTNode.RETURN_STATEMENT :
312
					buffer.append("RETURN_STATEMENT");break;
313
				case ASTNode.SIMPLE_NAME :
314
					buffer.append("SIMPLE_NAME");break;
315
				case ASTNode.SIMPLE_TYPE :
316
					buffer.append("SIMPLE_TYPE");break;
317
				case ASTNode.SINGLE_MEMBER_ANNOTATION :
318
					buffer.append("SINGLE_MEMBER_ANNOTATION");break;
319
				case ASTNode.SINGLE_VARIABLE_DECLARATION :
320
					buffer.append("SINGLE_VARIABLE_DECLARATION");break;
321
				case ASTNode.STRING_LITERAL :
322
					buffer.append("STRING_LITERAL");break;
323
				case ASTNode.SUPER_CONSTRUCTOR_INVOCATION :
324
					buffer.append("SUPER_CONSTRUCTOR_INVOCATION");break;
325
				case ASTNode.SUPER_FIELD_ACCESS :
326
					buffer.append("SUPER_FIELD_ACCESS");break;
327
				case ASTNode.SUPER_METHOD_INVOCATION :
328
					buffer.append("SUPER_METHOD_INVOCATION");break;
329
				case ASTNode.SWITCH_CASE:
330
					buffer.append("SWITCH_CASE");break;
331
				case ASTNode.SWITCH_STATEMENT :
332
					buffer.append("SWITCH_STATEMENT");break;
333
				case ASTNode.SYNCHRONIZED_STATEMENT :
334
					buffer.append("SYNCHRONIZED_STATEMENT");break;
335
				case ASTNode.TAG_ELEMENT :
336
					buffer.append("TAG_ELEMENT");break;
337
				case ASTNode.TEXT_ELEMENT :
338
					buffer.append("TEXT_ELEMENT");break;
339
				case ASTNode.THIS_EXPRESSION :
340
					buffer.append("THIS_EXPRESSION");break;
341
				case ASTNode.THROW_STATEMENT :
342
					buffer.append("THROW_STATEMENT");break;
343
				case ASTNode.TRY_STATEMENT :
344
					buffer.append("TRY_STATEMENT");break;
345
				case ASTNode.TYPE_DECLARATION :
346
					buffer.append("TYPE_DECLARATION");break;
347
				case ASTNode.TYPE_DECLARATION_STATEMENT :
348
					buffer.append("TYPE_DECLARATION_STATEMENT");break;
349
				case ASTNode.TYPE_LITERAL :
350
					buffer.append("TYPE_LITERAL");break;
351
				case ASTNode.TYPE_PARAMETER :
352
					buffer.append("TYPE_PARAMETER");break;
353
				case ASTNode.VARIABLE_DECLARATION_EXPRESSION :
354
					buffer.append("VARIABLE_DECLARATION_EXPRESSION");break;
355
				case ASTNode.VARIABLE_DECLARATION_FRAGMENT :
356
					buffer.append("VARIABLE_DECLARATION_FRAGMENT");break;
357
				case ASTNode.VARIABLE_DECLARATION_STATEMENT :
358
					buffer.append("VARIABLE_DECLARATION_STATEMENT");break;
359
				case ASTNode.WHILE_STATEMENT :
360
					buffer.append("WHILE_STATEMENT");break;
361
				case ASTNode.WILDCARD_TYPE :
362
					buffer.append("WILDCARD_TYPE");break;
363
				default:
364
					buffer.append("UNKNOWN");
365
			}
366
		}
367
368
		public String getText(ASTNode node) {
369
			StringBuffer buffer = new StringBuffer();
370
			
371
			boolean first = true;
372
			
373
			if ((this.options & NODE_TYPE) != 0) {
374
				if (!first) buffer.append(',');
375
				first = false;
376
				
377
				this.appendNodeType(node, buffer);
378
			}
379
			if ((this.options & NODE_POSITION) != 0) {
380
				if (!first) buffer.append(',');
381
				first = false;
382
				
383
				this.appendNodePosition(node, buffer);
384
			}
385
			
386
			if ((this.options & NODE_EXTENDED_POSITION) != 0) {
387
				if (!first) buffer.append(',');
388
				first = false;
389
				
390
				this.appendNodeExtendedPosition(node, buffer);
391
			}
392
			
393
			if ((this.options & NODE_FLAGS) != 0) {
394
				if (!first) buffer.append(',');
395
				first = false;
396
				
397
				this.appendFlags(node, buffer);
398
			}
399
			
400
			if ((this.options & BINDING_OPTIONS) != 0) {
401
				if (!first) buffer.append(',');
402
				first = false;
403
				
404
				this.appendBinding(node, buffer);
405
			}
406
			
407
			return buffer.toString();
408
		}
409
		
410
		protected IBinding resolveBinding(ASTNode node) {
411
			switch (node.getNodeType()) {
412
				case ASTNode.PACKAGE_DECLARATION:
413
					return ((PackageDeclaration) node).resolveBinding();
414
				case ASTNode.TYPE_DECLARATION:
415
					return ((TypeDeclaration) node).resolveBinding();
416
				case ASTNode.ANONYMOUS_CLASS_DECLARATION:
417
					return ((AnonymousClassDeclaration) node).resolveBinding();
418
				case ASTNode.TYPE_DECLARATION_STATEMENT:
419
					return ((TypeDeclarationStatement) node).resolveBinding();
420
				case ASTNode.METHOD_DECLARATION:
421
					return ((MethodDeclaration) node).resolveBinding();
422
				case ASTNode.METHOD_INVOCATION:
423
					return ((MethodInvocation) node).resolveMethodBinding();
424
				case ASTNode.TYPE_PARAMETER:
425
					return ((TypeParameter) node).resolveBinding();
426
				case ASTNode.PARAMETERIZED_TYPE:
427
					return ((ParameterizedType) node).resolveBinding();
428
				case ASTNode.WILDCARD_TYPE:
429
					return ((WildcardType) node).resolveBinding();
430
				case ASTNode.SIMPLE_NAME:
431
					return ((SimpleName) node).resolveBinding();
432
				case ASTNode.ARRAY_TYPE:
433
					return ((ArrayType) node).resolveBinding();
434
				case ASTNode.ASSIGNMENT:
435
					return ((Assignment) node).getRightHandSide().resolveTypeBinding();
436
				case ASTNode.SIMPLE_TYPE:
437
					return ((SimpleType) node).resolveBinding();
438
				case ASTNode.QUALIFIED_NAME:
439
					return ((QualifiedName) node).resolveBinding();
440
				case ASTNode.MARKER_ANNOTATION:
441
					return ((MarkerAnnotation) node).resolveAnnotationBinding();
442
				case ASTNode.NORMAL_ANNOTATION:
443
					return ((NormalAnnotation) node).resolveAnnotationBinding();
444
				case ASTNode.SINGLE_MEMBER_ANNOTATION:
445
					return ((SingleMemberAnnotation) node).resolveAnnotationBinding();
446
				case ASTNode.VARIABLE_DECLARATION_FRAGMENT:
447
					return ((VariableDeclarationFragment) node).resolveBinding();
448
				default:
449
					throw new IllegalArgumentException();
450
			}
451
		}
452
	}
453
	
454
	/**
455
	 * Compute extra information about a marked node
456
	 */
457
	public static abstract class MarkedNodeLabelProvider {
458
		public abstract String getText(ASTNode node);
459
	}
460
	
461
	private final static String AST_DELIMITER = "===== AST =====";
462
	private final static String DETAILS_DELIMITER = "===== Details =====";
463
	private final static String PROBLEMS_DELIMITER = "===== Problems =====";
464
	
465
	private final static String NO_PROBLEM = "No Problem";
466
	
467
	// options
468
	private boolean reportAST;
469
	private boolean reportProblems;
470
	
471
	private String source;
472
	private CompilationUnit unit;
473
	private AbstractASTTests.MarkerInfo markerInfo;
474
	
475
	private Map markerFromNode;
476
	private Map nodeFromMarker;
477
	private Map markerPositonInBuffer;
478
479
	private StringBuffer markedNodesBuffer;
480
	
481
	private MarkedNodeLabelProvider labelProvider;
482
	
483
	public MarkedASTFlattener(
484
			boolean reportAST,
485
			boolean reportProblems,
486
			MarkedNodeLabelProvider labelProvider) {
487
		
488
		this.reportAST = reportAST;
489
		this.reportProblems = reportProblems;
490
		
491
		this.markedNodesBuffer = new StringBuffer();
492
		this.labelProvider = labelProvider;
493
	}
494
	
495
	public String getResult() {
496
		StringBuffer resultBuffer = new StringBuffer();
497
		
498
		if (this.reportAST) {
499
			resultBuffer.append(AST_DELIMITER);
500
			resultBuffer.append('\n');
501
			resultBuffer.append(super.getResult());
502
			resultBuffer.append('\n');
503
		}
504
		
505
		resultBuffer.append(DETAILS_DELIMITER);
506
		resultBuffer.append(this.markedNodesBuffer);
507
		
508
		if (reportProblems) {
509
			resultBuffer.append('\n');
510
			resultBuffer.append(PROBLEMS_DELIMITER);
511
			resultBuffer.append('\n');
512
			
513
			StringBuffer problemBuffer = new StringBuffer();
514
			IProblem[] problems = unit.getProblems();
515
			int problemCount = problems.length;
516
			if (problemCount != 0) {
517
				for (int i = 0; i < problemCount; i++) {
518
					org.eclipse.jdt.core.tests.util.Util.appendProblem(problemBuffer, problems[i], source == null ? null : source.toCharArray() , i + 1);
519
				}
520
			} else {
521
				problemBuffer.append(NO_PROBLEM);
522
			}
523
			resultBuffer.append(Util.convertToIndependantLineDelimiter(problemBuffer.toString()));
524
		}
525
		
526
		return resultBuffer.toString();
527
	}
528
	
529
	public void postVisit(ASTNode node) {
530
		String markerName;
531
		if (this.reportAST && (markerName = (String)this.markerFromNode.get(node)) != null) {
532
			// add start marker
533
			int pos = ((Integer)this.markerPositonInBuffer.get(markerName)).intValue();
534
			while (Character.isWhitespace(this.buffer.charAt(pos))) {pos++;}
535
			this.buffer.insert(pos, this.markerInfo.markerStartStart + markerName + this.markerInfo.markerStartEnd);
536
			
537
			// add end marker
538
			pos = this.buffer.length() - 1;
539
			while (Character.isWhitespace(this.buffer.charAt(pos))) {pos--;}
540
			this.buffer.insert(pos + 1, this.markerInfo.markerEndStart + markerName + this.markerInfo.markerEndEnd);
541
		}
542
	}
543
	public void preVisit(ASTNode node) {
544
		String markerName = null;
545
		int index = markerInfo.indexOfASTStart(node.getStartPosition());
546
		if (index != -1 && node.getStartPosition() + node.getLength() == markerInfo.astEnds[index]) {
547
			markerName = String.valueOf(index + 1);
548
			
549
			if (this.nodeFromMarker.get(markerName) == null) {
550
				this.markerFromNode.put(node, markerName);
551
				this.nodeFromMarker.put(markerName, node);
552
				this.markerPositonInBuffer.put(markerName, new Integer(this.buffer.length()));
553
			}
554
		}
555
		
556
		if (markerName != null) {
557
			this.markedNodesBuffer.append('\n');
558
			this.markedNodesBuffer.append(markerName);
559
			this.markedNodesBuffer.append(':');
560
			this.markedNodesBuffer.append(this.labelProvider.getText(node));
561
		}
562
	}
563
	
564
	public void process(CompilationUnit cu, AbstractASTTests.MarkerInfo mf) {
565
		this.source = mf.source;
566
		this.unit = cu;
567
		this.markerInfo = mf;
568
		
569
		this.markerFromNode = new HashMap();
570
		this.nodeFromMarker = new HashMap();
571
		this.markerPositonInBuffer = new HashMap();
572
		this.unit.accept(this);
573
	}
574
}
(-)src/org/eclipse/jdt/core/tests/dom/DefaultMarkedNodeLabelProviderOptions.java (+68 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.jdt.core.tests.dom;
12
13
public interface DefaultMarkedNodeLabelProviderOptions {
14
	/**
15
	 * No extra information about marked nodes will be display.
16
	 */
17
	public static final int NO_OPTIONS = 0;
18
	
19
	/**
20
	 * All extra information about marked nodes will be display.
21
	 */
22
	public static final int ALL_OPTIONS = ~NO_OPTIONS;
23
	
24
	/**
25
	 * Marked nodes type will be display.
26
	 */
27
	public static final int NODE_TYPE = 1;
28
	
29
	/**
30
	 * Marked nodes position will be display.
31
	 */
32
	public static final int NODE_POSITION = 2;
33
	
34
	/**
35
	 * Marked nodes extended position will be display.
36
	 */
37
	public static final int NODE_EXTENDED_POSITION = 4;
38
	
39
	/**
40
	 * Marked nodes flags will be display.
41
	 */
42
	public static final int NODE_FLAGS = 8;
43
	
44
	/**
45
	 * Marked nodes binding kind will be display.
46
	 */
47
	public static final int BINDING_KIND = 16;
48
	
49
	/**
50
	 * Marked nodes binding key will be display.
51
	 */
52
	public static final int BINDING_KEY = 32;
53
	
54
	/**
55
	 * Marked nodes binding flags will be display.
56
	 */
57
	public static final int BINDING_FLAGS = 64;
58
	
59
	/**
60
	 * All extra nodes information about marked nodes will be display.
61
	 */
62
	public static final int NODE_OPTIONS = NODE_TYPE | NODE_POSITION | NODE_EXTENDED_POSITION | NODE_FLAGS;
63
	
64
	/**
65
	 * All extra bindings information about marked nodes will be display.
66
	 */
67
	public static final int BINDING_OPTIONS = BINDING_KIND | BINDING_KEY | BINDING_FLAGS;
68
}

Return to bug 215759