KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > compiler > parser > RecoveredElement


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.internal.compiler.parser;
12
13 /**
14  * Internal structure for parsing recovery
15  */

16 import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
17 import org.eclipse.jdt.internal.compiler.ast.ASTNode;
18 import org.eclipse.jdt.internal.compiler.ast.Block;
19 import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
20 import org.eclipse.jdt.internal.compiler.ast.ImportReference;
21 import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
22 import org.eclipse.jdt.internal.compiler.ast.Statement;
23 import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
24 import org.eclipse.jdt.internal.compiler.util.Util;
25
26 public class RecoveredElement {
27
28     public RecoveredElement parent;
29     public int bracketBalance;
30     public boolean foundOpeningBrace;
31     protected Parser recoveringParser;
32 public RecoveredElement(RecoveredElement parent, int bracketBalance){
33     this(parent, bracketBalance, null);
34 }
35 public RecoveredElement(RecoveredElement parent, int bracketBalance, Parser parser){
36     this.parent = parent;
37     this.bracketBalance = bracketBalance;
38     this.recoveringParser = parser;
39 }
40 /*
41  * Record a method declaration
42  */

43 public RecoveredElement add(AbstractMethodDeclaration methodDeclaration, int bracketBalanceValue) {
44
45     /* default behavior is to delegate recording to parent if any */
46     if (this.parent == null) return this; // ignore
47
this.updateSourceEndIfNecessary(this.previousAvailableLineEnd(methodDeclaration.declarationSourceStart - 1));
48     return this.parent.add(methodDeclaration, bracketBalanceValue);
49 }
50 /*
51  * Record a nested block declaration
52  */

53 public RecoveredElement add(Block nestedBlockDeclaration, int bracketBalanceValue) {
54
55     /* default behavior is to delegate recording to parent if any */
56     if (this.parent == null) return this; // ignore
57
this.updateSourceEndIfNecessary(this.previousAvailableLineEnd(nestedBlockDeclaration.sourceStart - 1));
58     return this.parent.add(nestedBlockDeclaration, bracketBalanceValue);
59 }
60 /*
61  * Record a field declaration
62  */

63 public RecoveredElement add(FieldDeclaration fieldDeclaration, int bracketBalanceValue) {
64
65     /* default behavior is to delegate recording to parent if any */
66     if (this.parent == null) return this; // ignore
67
this.updateSourceEndIfNecessary(this.previousAvailableLineEnd(fieldDeclaration.declarationSourceStart - 1));
68     return this.parent.add(fieldDeclaration, bracketBalanceValue);
69 }
70 /*
71  * Record an import reference
72  */

73 public RecoveredElement add(ImportReference importReference, int bracketBalanceValue){
74
75     /* default behavior is to delegate recording to parent if any */
76     if (this.parent == null) return this; // ignore
77
this.updateSourceEndIfNecessary(this.previousAvailableLineEnd(importReference.declarationSourceStart - 1));
78     return this.parent.add(importReference, bracketBalanceValue);
79 }
80 /*
81  * Record a local declaration
82  */

83 public RecoveredElement add(LocalDeclaration localDeclaration, int bracketBalanceValue) {
84
85     /* default behavior is to delegate recording to parent if any */
86     if (this.parent == null) return this; // ignore
87
this.updateSourceEndIfNecessary(this.previousAvailableLineEnd(localDeclaration.declarationSourceStart - 1));
88     return this.parent.add(localDeclaration, bracketBalanceValue);
89 }
90 /*
91  * Record a statement
92  */

93 public RecoveredElement add(Statement statement, int bracketBalanceValue) {
94
95     /* default behavior is to delegate recording to parent if any */
96     if (this.parent == null) return this; // ignore
97
this.updateSourceEndIfNecessary(this.previousAvailableLineEnd(statement.sourceStart - 1));
98     return this.parent.add(statement, bracketBalanceValue);
99 }
100 /*
101  * Record a type declaration
102  */

103 public RecoveredElement add(TypeDeclaration typeDeclaration, int bracketBalanceValue){
104
105     /* default behavior is to delegate recording to parent if any */
106     if (this.parent == null) return this; // ignore
107
this.updateSourceEndIfNecessary(this.previousAvailableLineEnd(typeDeclaration.declarationSourceStart - 1));
108     return this.parent.add(typeDeclaration, bracketBalanceValue);
109 }
110 protected void addBlockStatement(RecoveredBlock recoveredBlock) {
111     Block block = recoveredBlock.blockDeclaration;
112     if(block.statements != null) {
113         Statement[] statements = block.statements;
114         for (int i = 0; i < statements.length; i++) {
115             recoveredBlock.add(statements[i], 0);
116         }
117     }
118 }
119 /*
120  * Answer the depth of this element, considering the parent link.
121  */

122 public int depth(){
123     int depth = 0;
124     RecoveredElement current = this;
125     while ((current = current.parent) != null) depth++;
126     return depth;
127 }
128 /*
129  * Answer the enclosing method node, or null if none
130  */

131 public RecoveredInitializer enclosingInitializer(){
132     RecoveredElement current = this;
133     while (current != null){
134         if (current instanceof RecoveredInitializer){
135             return (RecoveredInitializer) current;
136         }
137         current = current.parent;
138     }
139     return null;
140 }
141 /*
142  * Answer the enclosing method node, or null if none
143  */

144 public RecoveredMethod enclosingMethod(){
145     RecoveredElement current = this;
146     while (current != null){
147         if (current instanceof RecoveredMethod){
148             return (RecoveredMethod) current;
149         }
150         current = current.parent;
151     }
152     return null;
153 }
154 /*
155  * Answer the enclosing type node, or null if none
156  */

157 public RecoveredType enclosingType(){
158     RecoveredElement current = this;
159     while (current != null){
160         if (current instanceof RecoveredType){
161             return (RecoveredType) current;
162         }
163         current = current.parent;
164     }
165     return null;
166 }
167 /*
168  * Answer the closest specified parser
169  */

170 public Parser parser(){
171     RecoveredElement current = this;
172     while (current != null){
173         if (current.recoveringParser != null){
174             return current.recoveringParser;
175         }
176         current = current.parent;
177     }
178     return null;
179 }
180 /*
181  * Answer the associated parsed structure
182  */

183 public ASTNode parseTree(){
184     return null;
185 }
186 /*
187  * Iterate the enclosing blocks and tag them so as to preserve their content
188  */

189 public void preserveEnclosingBlocks(){
190     RecoveredElement current = this;
191     while (current != null){
192         if (current instanceof RecoveredBlock){
193             ((RecoveredBlock)current).preserveContent = true;
194         }
195         if (current instanceof RecoveredType){ // for anonymous types
196
((RecoveredType)current).preserveContent = true;
197         }
198         current = current.parent;
199     }
200 }
201 /*
202  * Answer the position of the previous line end if
203  * there is nothing but spaces in between it and the
204  * line end. Used to trim spaces on unclosed elements.
205  */

206 public int previousAvailableLineEnd(int position){
207
208     Parser parser = this.parser();
209     if (parser == null) return position;
210     
211     Scanner scanner = parser.scanner;
212     if (scanner.lineEnds == null) return position;
213     
214     int index = Util.getLineNumber(position, scanner.lineEnds, 0, scanner.linePtr);
215     if (index < 2) return position;
216     int previousLineEnd = scanner.lineEnds[index-2];
217
218     char[] source = scanner.source;
219     for (int i = previousLineEnd+1; i < position; i++){
220         if (!(source[i] == ' ' || source[i] == '\t')) return position;
221     }
222     return previousLineEnd;
223 }
224 /*
225  * Answer the very source end of the corresponding parse node
226  */

227 public int sourceEnd(){
228     return 0;
229 }
230 protected String JavaDoc tabString(int tab) {
231     StringBuffer JavaDoc result = new StringBuffer JavaDoc();
232     for (int i = tab; i > 0; i--) {
233         result.append(" "); //$NON-NLS-1$
234
}
235     return result.toString();
236 }
237 /*
238  * Answer the top node
239  */

240 public RecoveredElement topElement(){
241     RecoveredElement current = this;
242     while (current.parent != null){
243         current = current.parent;
244     }
245     return current;
246 }
247 public String JavaDoc toString() {
248     return toString(0);
249 }
250 public String JavaDoc toString(int tab) {
251     return super.toString();
252 }
253 /*
254  * Answer the enclosing type node, or null if none
255  */

256 public RecoveredType type(){
257     RecoveredElement current = this;
258     while (current != null){
259         if (current instanceof RecoveredType){
260             return (RecoveredType) current;
261         }
262         current = current.parent;
263     }
264     return null;
265 }
266 /*
267  * Update the bodyStart of the corresponding parse node
268  */

269 public void updateBodyStart(int bodyStart){
270     this.foundOpeningBrace = true;
271 }
272 /*
273  * Update the corresponding parse node from parser state which
274  * is about to disappear because of restarting recovery
275  */

276 public void updateFromParserState(){
277     // default implementation: do nothing
278
}
279 /*
280  * A closing brace got consumed, might have closed the current element,
281  * in which case both the currentElement is exited
282  */

283 public RecoveredElement updateOnClosingBrace(int braceStart, int braceEnd){
284     if ((--this.bracketBalance <= 0) && (this.parent != null)){
285         this.updateSourceEndIfNecessary(braceStart, braceEnd);
286         return this.parent;
287     }
288     return this;
289 }
290 /*
291  * An opening brace got consumed, might be the expected opening one of the current element,
292  * in which case the bodyStart is updated.
293  */

294 /*public RecoveredElement updateOnOpeningBrace(int braceEnd){return null;}*/
295 public RecoveredElement updateOnOpeningBrace(int braceStart, int braceEnd){
296
297     if (this.bracketBalance++ == 0){
298         this.updateBodyStart(braceEnd + 1);
299         return this;
300     }
301     return null; // no update is necessary
302
}
303 /*
304  * Final update the corresponding parse node
305  */

306 public void updateParseTree(){
307     // default implementation: do nothing
308
}
309 /*
310  * Update the declarationSourceEnd of the corresponding parse node
311  */

312 public void updateSourceEndIfNecessary(int braceStart, int braceEnd){
313     // default implementation: do nothing
314
}
315 public void updateSourceEndIfNecessary(int sourceEnd){
316     this.updateSourceEndIfNecessary(sourceEnd + 1, sourceEnd);
317 }
318 }
319
Popular Tags