Makefile fixup
[org.ibex.tool.git] / src / org / eclipse / jdt / internal / compiler / parser / RecoveredInitializer.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2004 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 org.eclipse.jdt.internal.compiler.parser;
12
13 /**
14  * Internal initializer structure for parsing recovery 
15  */
16 import org.eclipse.jdt.core.compiler.*;
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.Initializer;
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.lookup.BaseTypes;
25 import org.eclipse.jdt.internal.compiler.lookup.CompilerModifiers;
26
27 public class RecoveredInitializer extends RecoveredField implements CompilerModifiers, TerminalTokens, BaseTypes {
28
29         public RecoveredType[] localTypes;
30         public int localTypeCount;
31
32         public RecoveredBlock initializerBody;  
33
34 public RecoveredInitializer(FieldDeclaration fieldDeclaration, RecoveredElement parent, int bracketBalance){
35         this(fieldDeclaration, parent, bracketBalance, null);
36 }
37 public RecoveredInitializer(FieldDeclaration fieldDeclaration, RecoveredElement parent, int bracketBalance, Parser parser){
38         super(fieldDeclaration, parent, bracketBalance, parser);
39         this.foundOpeningBrace = true;
40 }
41 /*
42  * Record a nested block declaration
43  */
44 public RecoveredElement add(Block nestedBlockDeclaration, int bracketBalanceValue) {
45
46         /* default behavior is to delegate recording to parent if any,
47         do not consider elements passed the known end (if set)
48         it must be belonging to an enclosing element 
49         */
50         if (fieldDeclaration.declarationSourceEnd > 0
51                         && nestedBlockDeclaration.sourceStart > fieldDeclaration.declarationSourceEnd){
52                 if (this.parent == null) return this; // ignore
53                 return this.parent.add(nestedBlockDeclaration, bracketBalanceValue);
54         }
55         /* consider that if the opening brace was not found, it is there */
56         if (!foundOpeningBrace){
57                 foundOpeningBrace = true;
58                 this.bracketBalance++;
59         }
60         initializerBody = new RecoveredBlock(nestedBlockDeclaration, this, bracketBalanceValue);
61         if (nestedBlockDeclaration.sourceEnd == 0) return initializerBody;
62         return this;
63 }
64 /*
65  * Record a field declaration (act like inside method body)
66  */
67 public RecoveredElement add(FieldDeclaration newFieldDeclaration, int bracketBalanceValue) {
68
69         /* local variables inside initializer can only be final and non void */
70         char[][] fieldTypeName;
71         if ((newFieldDeclaration.modifiers & ~AccFinal) != 0 /* local var can only be final */
72                         || (newFieldDeclaration.type == null) // initializer
73                         || ((fieldTypeName = newFieldDeclaration.type.getTypeName()).length == 1 // non void
74                                 && CharOperation.equals(fieldTypeName[0], VoidBinding.sourceName()))){ 
75                 if (this.parent == null) return this; // ignore
76                 this.updateSourceEndIfNecessary(this.previousAvailableLineEnd(newFieldDeclaration.declarationSourceStart - 1));
77                 return this.parent.add(newFieldDeclaration, bracketBalanceValue);
78         }
79
80         /* default behavior is to delegate recording to parent if any,
81         do not consider elements passed the known end (if set)
82         it must be belonging to an enclosing element 
83         */
84         if (this.fieldDeclaration.declarationSourceEnd > 0
85                         && newFieldDeclaration.declarationSourceStart > this.fieldDeclaration.declarationSourceEnd){
86                 if (this.parent == null) return this; // ignore
87                 return this.parent.add(newFieldDeclaration, bracketBalanceValue);
88         }
89         // still inside initializer, treat as local variable
90         return this; // ignore
91 }
92 /*
93  * Record a local declaration - regular method should have been created a block body
94  */
95 public RecoveredElement add(LocalDeclaration localDeclaration, int bracketBalanceValue) {
96
97         /* do not consider a type starting passed the type end (if set)
98                 it must be belonging to an enclosing type */
99         if (fieldDeclaration.declarationSourceEnd != 0 
100                         && localDeclaration.declarationSourceStart > fieldDeclaration.declarationSourceEnd){
101                 if (parent == null) return this; // ignore
102                 return this.parent.add(localDeclaration, bracketBalanceValue);
103         }
104         /* method body should have been created */
105         Block block = new Block(0);
106         block.sourceStart = ((Initializer)fieldDeclaration).sourceStart;
107         RecoveredElement element = this.add(block, 1);
108         return element.add(localDeclaration, bracketBalanceValue);      
109 }
110 /*
111  * Record a statement - regular method should have been created a block body
112  */
113 public RecoveredElement add(Statement statement, int bracketBalanceValue) {
114
115         /* do not consider a statement starting passed the initializer end (if set)
116                 it must be belonging to an enclosing type */
117         if (fieldDeclaration.declarationSourceEnd != 0 
118                         && statement.sourceStart > fieldDeclaration.declarationSourceEnd){
119                 if (parent == null) return this; // ignore
120                 return this.parent.add(statement, bracketBalanceValue);
121         }
122         /* initializer body should have been created */
123         Block block = new Block(0);
124         block.sourceStart = ((Initializer)fieldDeclaration).sourceStart;
125         RecoveredElement element = this.add(block, 1);
126         return element.add(statement, bracketBalanceValue);     
127 }
128 public RecoveredElement add(TypeDeclaration typeDeclaration, int bracketBalanceValue) {
129
130         /* do not consider a type starting passed the type end (if set)
131                 it must be belonging to an enclosing type */
132         if (fieldDeclaration.declarationSourceEnd != 0 
133                         && typeDeclaration.declarationSourceStart > fieldDeclaration.declarationSourceEnd){
134                 if (parent == null) return this; // ignore
135                 return this.parent.add(typeDeclaration, bracketBalanceValue);
136         }
137         if ((typeDeclaration.bits & ASTNode.IsLocalTypeMASK) != 0){
138                 /* method body should have been created */
139                 Block block = new Block(0);
140                 block.sourceStart = ((Initializer)fieldDeclaration).sourceStart;
141                 RecoveredElement element = this.add(block, 1);
142                 return element.add(typeDeclaration, bracketBalanceValue);       
143         }       
144         if (localTypes == null) {
145                 localTypes = new RecoveredType[5];
146                 localTypeCount = 0;
147         } else {
148                 if (localTypeCount == localTypes.length) {
149                         System.arraycopy(
150                                 localTypes, 
151                                 0, 
152                                 (localTypes = new RecoveredType[2 * localTypeCount]), 
153                                 0, 
154                                 localTypeCount); 
155                 }
156         }
157         RecoveredType element = new RecoveredType(typeDeclaration, this, bracketBalanceValue);
158         localTypes[localTypeCount++] = element;
159
160         /* consider that if the opening brace was not found, it is there */
161         if (!foundOpeningBrace){
162                 foundOpeningBrace = true;
163                 this.bracketBalance++;
164         }
165         return element;
166 }
167 public String toString(int tab) {
168         StringBuffer result = new StringBuffer(tabString(tab));
169         result.append("Recovered initializer:\n"); //$NON-NLS-1$
170         this.fieldDeclaration.print(tab + 1, result);
171         if (this.initializerBody != null) {
172                 result.append("\n"); //$NON-NLS-1$
173                 result.append(this.initializerBody.toString(tab + 1));
174         }
175         return result.toString();
176 }
177 public FieldDeclaration updatedFieldDeclaration(){
178
179         if (initializerBody != null){
180                 Block block = initializerBody.updatedBlock();
181                 if (block != null){
182                         ((Initializer)fieldDeclaration).block = block;
183                 }
184                 if (this.localTypeCount > 0) fieldDeclaration.bits |= ASTNode.HasLocalTypeMASK;
185
186         }       
187         if (fieldDeclaration.sourceEnd == 0){
188                 fieldDeclaration.sourceEnd = fieldDeclaration.declarationSourceEnd;
189         }
190         return fieldDeclaration;
191 }
192 /*
193  * A closing brace got consumed, might have closed the current element,
194  * in which case both the currentElement is exited
195  */
196 public RecoveredElement updateOnClosingBrace(int braceStart, int braceEnd){
197         if ((--bracketBalance <= 0) && (parent != null)){
198                 this.updateSourceEndIfNecessary(braceStart, braceEnd);
199                 return parent;
200         }
201         return this;
202 }
203 /*
204  * An opening brace got consumed, might be the expected opening one of the current element,
205  * in which case the bodyStart is updated.
206  */
207 public RecoveredElement updateOnOpeningBrace(int braceStart, int braceEnd){
208         bracketBalance++;
209         return this; // request to restart
210 }
211 /*
212  * Update the declarationSourceEnd of the corresponding parse node
213  */
214 public void updateSourceEndIfNecessary(int braceStart, int braceEnd){
215         if (this.fieldDeclaration.declarationSourceEnd == 0) {
216                 Initializer initializer = (Initializer)fieldDeclaration;
217                 if(parser().rBraceSuccessorStart >= braceEnd) {
218                         if (initializer.bodyStart < parser().rBraceEnd) {
219                                 initializer.declarationSourceEnd = parser().rBraceEnd;
220                         } else {
221                                 initializer.declarationSourceEnd = initializer.bodyStart;
222                         }
223                         if (initializer.bodyStart < parser().rBraceStart) {
224                                 initializer.bodyEnd = parser().rBraceStart;
225                         } else {
226                                 initializer.bodyEnd = initializer.bodyStart;
227                         }
228                 } else {
229                         initializer.declarationSourceEnd = braceEnd;
230                         initializer.bodyEnd  = braceStart - 1;
231                 }
232                 if(initializer.block != null) {
233                         initializer.block.sourceEnd = initializer.declarationSourceEnd;
234                 }
235         }
236 }
237 }