1) Added setting of syntax properties to italic, underline and strike through.
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / compiler / parser / RecoveredElement.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2003 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials 
4  * are made available under the terms of the Common Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v10.html
7  * 
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11 package net.sourceforge.phpdt.internal.compiler.parser;
12
13 //import net.sourceforge.phpdt.internal.compiler.ast.ASTNode;
14 import net.sourceforge.phpdt.internal.compiler.ast.Block;
15 import net.sourceforge.phpdt.internal.compiler.ast.Statement;
16
17 /**
18  * Internal structure for parsing recovery
19  */
20 public class RecoveredElement {
21
22         public RecoveredElement parent;
23
24         public int bracketBalance;
25
26         public boolean foundOpeningBrace;
27
28         protected Parser recoveringParser;
29
30 //      public RecoveredElement(RecoveredElement parent, int bracketBalance) {
31 //              this(parent, bracketBalance, null);
32 //      }
33
34 //      public RecoveredElement(RecoveredElement parent, int bracketBalance,
35 //                      Parser parser) {
36 //              this.parent = parent;
37 //              this.bracketBalance = bracketBalance;
38 //              this.recoveringParser = parser;
39 //      }
40
41         /*
42          * Record a method declaration
43          */
44         // public RecoveredElement add(AbstractMethodDeclaration methodDeclaration,
45         // int bracketBalance) {
46         //
47         // /* default behavior is to delegate recording to parent if any */
48         // if (parent == null) {
49         // return this; // ignore
50         // } else {
51         // this.updateSourceEndIfNecessary(this.previousAvailableLineEnd(methodDeclaration.declarationSourceStart
52         // - 1));
53         // return this.parent.add(methodDeclaration, bracketBalance);
54         // }
55         // }
56         /*
57          * Record a nested block declaration
58          */
59         public RecoveredElement add(Block nestedBlockDeclaration, int bracketBalance) {
60
61                 /* default behavior is to delegate recording to parent if any */
62                 if (parent == null) {
63                         return this; // ignore
64                 } else {
65                         this
66                                         .updateSourceEndIfNecessary(this
67                                                         .previousAvailableLineEnd(nestedBlockDeclaration.sourceStart - 1));
68                         return this.parent.add(nestedBlockDeclaration, bracketBalance);
69                 }
70         }
71
72         /*
73          * Record a field declaration
74          */
75         // public RecoveredElement add(FieldDeclaration fieldDeclaration, int
76         // bracketBalance) {
77         //
78         // /* default behavior is to delegate recording to parent if any */
79         // if (parent == null) {
80         // return this; // ignore
81         // } else {
82         // this.updateSourceEndIfNecessary(this.previousAvailableLineEnd(fieldDeclaration.declarationSourceStart
83         // - 1));
84         // return this.parent.add(fieldDeclaration, bracketBalance);
85         // }
86         // }
87         // /*
88         // * Record an import reference
89         // */
90         // public RecoveredElement add(ImportReference importReference, int
91         // bracketBalance){
92         //
93         // /* default behavior is to delegate recording to parent if any */
94         // if (parent == null) {
95         // return this; // ignore
96         // } else {
97         // this.updateSourceEndIfNecessary(this.previousAvailableLineEnd(importReference.declarationSourceStart
98         // - 1));
99         // return this.parent.add(importReference, bracketBalance);
100         // }
101         // }
102         // /*
103         // * Record a local declaration
104         // */
105         // public RecoveredElement add(LocalDeclaration localDeclaration, int
106         // bracketBalance) {
107         //
108         // /* default behavior is to delegate recording to parent if any */
109         // if (parent == null) {
110         // return this; // ignore
111         // } else {
112         // this.updateSourceEndIfNecessary(this.previousAvailableLineEnd(localDeclaration.declarationSourceStart
113         // - 1));
114         // return this.parent.add(localDeclaration, bracketBalance);
115         // }
116         // }
117         /*
118          * Record a statement
119          */
120         public RecoveredElement add(Statement statement, int bracketBalance) {
121
122                 /* default behavior is to delegate recording to parent if any */
123                 if (parent == null) {
124                         return this; // ignore
125                 } else {
126                         this.updateSourceEndIfNecessary(this
127                                         .previousAvailableLineEnd(statement.sourceStart - 1));
128                         return this.parent.add(statement, bracketBalance);
129                 }
130         }
131
132         /*
133          * Record a type declaration
134          */
135         // public RecoveredElement add(TypeDeclaration typeDeclaration, int
136         // bracketBalance){
137         //
138         // /* default behavior is to delegate recording to parent if any */
139         // if (parent == null) {
140         // return this; // ignore
141         // } else {
142         // this.updateSourceEndIfNecessary(this.previousAvailableLineEnd(typeDeclaration.declarationSourceStart
143         // - 1));
144         // return this.parent.add(typeDeclaration, bracketBalance);
145         // }
146         // }
147         /*
148          * Answer the depth of this element, considering the parent link.
149          */
150 //      public int depth() {
151 //              int depth = 0;
152 //              RecoveredElement current = this;
153 //              while ((current = current.parent) != null)
154 //                      depth++;
155 //              return depth;
156 //      }
157
158         /*
159          * Answer the enclosing method node, or null if none
160          */
161         // public RecoveredInitializer enclosingInitializer(){
162         // RecoveredElement current = this;
163         // while (current != null){
164         // if (current instanceof RecoveredInitializer){
165         // return (RecoveredInitializer) current;
166         // }
167         // current = current.parent;
168         // }
169         // return null;
170         // }
171         /*
172          * Answer the enclosing method node, or null if none
173          */
174         // public RecoveredMethod enclosingMethod(){
175         // RecoveredElement current = this;
176         // while (current != null){
177         // if (current instanceof RecoveredMethod){
178         // return (RecoveredMethod) current;
179         // }
180         // current = current.parent;
181         // }
182         // return null;
183         // }
184         /*
185          * Answer the enclosing type node, or null if none
186          */
187         // public RecoveredType enclosingType(){
188         // RecoveredElement current = this;
189         // while (current != null){
190         // if (current instanceof RecoveredType){
191         // return (RecoveredType) current;
192         // }
193         // current = current.parent;
194         // }
195         // return null;
196         // }
197         /*
198          * Answer the closest specified parser
199          */
200         public Parser parser() {
201                 RecoveredElement current = this;
202                 while (current != null) {
203                         if (current.recoveringParser != null) {
204                                 return current.recoveringParser;
205                         }
206                         current = current.parent;
207                 }
208                 return null;
209         }
210
211         /*
212          * Answer the associated parsed structure
213          */
214 //      public ASTNode parseTree() {
215 //              return null;
216 //      }
217
218         /*
219          * Iterate the enclosing blocks and tag them so as to preserve their content
220          */
221         // public void preserveEnclosingBlocks(){
222         // RecoveredElement current = this;
223         // while (current != null){
224         // if (current instanceof RecoveredBlock){
225         // ((RecoveredBlock)current).preserveContent = true;
226         // }
227         // if (current instanceof RecoveredType){ // for anonymous types
228         // ((RecoveredType)current).preserveContent = true;
229         // }
230         // current = current.parent;
231         // }
232         // }
233         /*
234          * Answer the position of the previous line end if there is nothing but
235          * spaces in between it and the line end. Used to trim spaces on unclosed
236          * elements.
237          */
238         public int previousAvailableLineEnd(int position) {
239
240                 Parser parser = this.parser();
241                 if (parser == null)
242                         return position;
243
244                 Scanner scanner = parser.scanner;
245                 if (scanner.lineEnds == null)
246                         return position;
247
248                 int index = scanner.getLineNumber(position);
249                 if (index < 2)
250                         return position;
251                 int previousLineEnd = scanner.lineEnds[index - 2];
252
253                 char[] source = scanner.source;
254                 for (int i = previousLineEnd + 1; i < position; i++) {
255                         if (!(source[i] == ' ' || source[i] == '\t'))
256                                 return position;
257                 }
258                 return previousLineEnd;
259         }
260
261         /*
262          * Answer the very source end of the corresponding parse node
263          */
264 //      public int sourceEnd() {
265 //              return 0;
266 //      }
267
268 //      protected String tabString(int tab) {
269 //              StringBuffer result = new StringBuffer();
270 //              for (int i = tab; i > 0; i--) {
271 //                      result.append("  "); //$NON-NLS-1$
272 //              }
273 //              return result.toString();
274 //      }
275
276         /*
277          * Answer the top node
278          */
279         public RecoveredElement topElement() {
280                 RecoveredElement current = this;
281                 while (current.parent != null) {
282                         current = current.parent;
283                 }
284                 return current;
285         }
286
287         public String toString() {
288                 return toString(0);
289         }
290
291         public String toString(int tab) {
292                 return super.toString();
293         }
294
295         /*
296          * Answer the enclosing type node, or null if none
297          */
298         // public RecoveredType type(){
299         // RecoveredElement current = this;
300         // while (current != null){
301         // if (current instanceof RecoveredType){
302         // return (RecoveredType) current;
303         // }
304         // current = current.parent;
305         // }
306         // return null;
307         // }
308         /*
309          * Update the bodyStart of the corresponding parse node
310          */
311         public void updateBodyStart(int bodyStart) {
312                 this.foundOpeningBrace = true;
313         }
314
315         /*
316          * Update the corresponding parse node from parser state which is about to
317          * disappear because of restarting recovery
318          */
319 //      public void updateFromParserState() {
320 //      }
321
322         /*
323          * A closing brace got consumed, might have closed the current element, in
324          * which case both the currentElement is exited
325          */
326 //      public RecoveredElement updateOnClosingBrace(int braceStart, int braceEnd) {
327 //              if ((--bracketBalance <= 0) && (parent != null)) {
328 //                      this.updateSourceEndIfNecessary(braceEnd);
329 //                      return parent;
330 //              }
331 //              return this;
332 //      }
333
334         /*
335          * An opening brace got consumed, might be the expected opening one of the
336          * current element, in which case the bodyStart is updated.
337          */
338 //      public RecoveredElement updateOnOpeningBrace(int braceEnd) {
339 //
340 //              if (bracketBalance++ == 0) {
341 //                      this.updateBodyStart(braceEnd + 1);
342 //                      return this;
343 //              }
344 //              return null; // no update is necessary
345 //      }
346
347         /*
348          * Final update the corresponding parse node
349          */
350 //      public void updateParseTree() {
351 //      }
352
353         /*
354          * Update the declarationSourceEnd of the corresponding parse node
355          */
356         public void updateSourceEndIfNecessary(int sourceEnd) {
357         }
358 }