KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 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 field structure for parsing recovery
15  */

16 import org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration;
17 import org.eclipse.jdt.internal.compiler.ast.ArrayQualifiedTypeReference;
18 import org.eclipse.jdt.internal.compiler.ast.ArrayTypeReference;
19 import org.eclipse.jdt.internal.compiler.ast.ASTNode;
20 import org.eclipse.jdt.internal.compiler.ast.Expression;
21 import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
22 import org.eclipse.jdt.internal.compiler.ast.Statement;
23 import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
24
25 public class RecoveredField extends RecoveredElement {
26
27     public FieldDeclaration fieldDeclaration;
28     boolean alreadyCompletedFieldInitialization;
29     
30     public RecoveredType[] anonymousTypes;
31     public int anonymousTypeCount;
32 public RecoveredField(FieldDeclaration fieldDeclaration, RecoveredElement parent, int bracketBalance){
33     this(fieldDeclaration, parent, bracketBalance, null);
34 }
35 public RecoveredField(FieldDeclaration fieldDeclaration, RecoveredElement parent, int bracketBalance, Parser parser){
36     super(parent, bracketBalance, parser);
37     this.fieldDeclaration = fieldDeclaration;
38     this.alreadyCompletedFieldInitialization = fieldDeclaration.initialization != null;
39 }
40 /*
41  * Record an expression statement if field is expecting an initialization expression,
42  * used for completion inside field initializers.
43  */

44 public RecoveredElement add(Statement statement, int bracketBalanceValue) {
45
46     if (this.alreadyCompletedFieldInitialization || !(statement instanceof Expression)) {
47         return super.add(statement, bracketBalanceValue);
48     } else {
49         this.alreadyCompletedFieldInitialization = true;
50         this.fieldDeclaration.initialization = (Expression)statement;
51         this.fieldDeclaration.declarationSourceEnd = statement.sourceEnd;
52         this.fieldDeclaration.declarationEnd = statement.sourceEnd;
53         return this;
54     }
55 }
56 /*
57  * Record a type declaration if this field is expecting an initialization expression
58  * and the type is an anonymous type.
59  * Used for completion inside field initializers.
60  */

61 public RecoveredElement add(TypeDeclaration typeDeclaration, int bracketBalanceValue) {
62
63     if (this.alreadyCompletedFieldInitialization
64             || ((typeDeclaration.bits & ASTNode.IsAnonymousType) == 0)
65             || (this.fieldDeclaration.declarationSourceEnd != 0 && typeDeclaration.sourceStart > this.fieldDeclaration.declarationSourceEnd)) {
66         return super.add(typeDeclaration, bracketBalanceValue);
67     } else {
68         // Prepare anonymous type list
69
if (this.anonymousTypes == null) {
70             this.anonymousTypes = new RecoveredType[5];
71             this.anonymousTypeCount = 0;
72         } else {
73             if (this.anonymousTypeCount == this.anonymousTypes.length) {
74                 System.arraycopy(
75                     this.anonymousTypes,
76                     0,
77                     (this.anonymousTypes = new RecoveredType[2 * this.anonymousTypeCount]),
78                     0,
79                     this.anonymousTypeCount);
80             }
81         }
82         // Store type declaration as an anonymous type
83
RecoveredType element = new RecoveredType(typeDeclaration, this, bracketBalanceValue);
84         this.anonymousTypes[this.anonymousTypeCount++] = element;
85         return element;
86     }
87 }
88 /*
89  * Answer the associated parsed structure
90  */

91 public ASTNode parseTree(){
92     return fieldDeclaration;
93 }
94 /*
95  * Answer the very source end of the corresponding parse node
96  */

97 public int sourceEnd(){
98     return this.fieldDeclaration.declarationSourceEnd;
99 }
100 public String JavaDoc toString(int tab){
101     StringBuffer JavaDoc buffer = new StringBuffer JavaDoc(tabString(tab));
102     buffer.append("Recovered field:\n"); //$NON-NLS-1$
103
fieldDeclaration.print(tab + 1, buffer);
104     if (this.anonymousTypes != null) {
105         for (int i = 0; i < this.anonymousTypeCount; i++){
106             buffer.append("\n"); //$NON-NLS-1$
107
buffer.append(anonymousTypes[i].toString(tab + 1));
108         }
109     }
110     return buffer.toString();
111 }
112 public FieldDeclaration updatedFieldDeclaration(){
113
114     if (this.anonymousTypes != null) {
115         if(fieldDeclaration.initialization == null) {
116             for (int i = 0; i < this.anonymousTypeCount; i++){
117                 RecoveredType recoveredType = anonymousTypes[i];
118                 TypeDeclaration typeDeclaration = recoveredType.typeDeclaration;
119                 if(typeDeclaration.declarationSourceEnd == 0) {
120                     typeDeclaration.declarationSourceEnd = this.fieldDeclaration.declarationSourceEnd;
121                     typeDeclaration.bodyEnd = this.fieldDeclaration.declarationSourceEnd;
122                 }
123                 if (recoveredType.preserveContent){
124                     TypeDeclaration anonymousType = recoveredType.updatedTypeDeclaration();
125                     fieldDeclaration.initialization = anonymousType.allocation;
126                     if(this.fieldDeclaration.declarationSourceEnd == 0) {
127                         int end = anonymousType.declarationSourceEnd;
128                         this.fieldDeclaration.declarationSourceEnd = end;
129                         this.fieldDeclaration.declarationEnd = end;
130                     }
131                 }
132             }
133             if (this.anonymousTypeCount > 0) fieldDeclaration.bits |= ASTNode.HasLocalType;
134         } else if(fieldDeclaration.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT) {
135             // fieldDeclaration is an enum constant
136
for (int i = 0; i < this.anonymousTypeCount; i++){
137                 RecoveredType recoveredType = anonymousTypes[i];
138                 TypeDeclaration typeDeclaration = recoveredType.typeDeclaration;
139                 if(typeDeclaration.declarationSourceEnd == 0) {
140                     typeDeclaration.declarationSourceEnd = this.fieldDeclaration.declarationSourceEnd;
141                     typeDeclaration.bodyEnd = this.fieldDeclaration.declarationSourceEnd;
142                 }
143                 recoveredType.updatedTypeDeclaration();
144             }
145         }
146     }
147     return fieldDeclaration;
148 }
149 /*
150  * A closing brace got consumed, might have closed the current element,
151  * in which case both the currentElement is exited.
152  *
153  * Fields have no associated braces, thus if matches, then update parent.
154  */

155 public RecoveredElement updateOnClosingBrace(int braceStart, int braceEnd){
156     if (bracketBalance > 0){ // was an array initializer
157
bracketBalance--;
158         if (bracketBalance == 0) {
159             if(fieldDeclaration.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT) {
160                 updateSourceEndIfNecessary(braceEnd - 1);
161                 return parent;
162             } else {
163                 alreadyCompletedFieldInitialization = true;
164             }
165         }
166         return this;
167     } else if (bracketBalance == 0) {
168         alreadyCompletedFieldInitialization = true;
169         updateSourceEndIfNecessary(braceEnd - 1);
170     }
171     if (parent != null){
172         return parent.updateOnClosingBrace(braceStart, braceEnd);
173     }
174     return this;
175 }
176 /*
177  * An opening brace got consumed, might be the expected opening one of the current element,
178  * in which case the bodyStart is updated.
179  */

180 public RecoveredElement updateOnOpeningBrace(int braceStart, int braceEnd){
181     if (fieldDeclaration.declarationSourceEnd == 0
182         && (fieldDeclaration.type instanceof ArrayTypeReference || fieldDeclaration.type instanceof ArrayQualifiedTypeReference)
183         && !alreadyCompletedFieldInitialization){
184         bracketBalance++;
185         return null; // no update is necessary (array initializer)
186
}
187     if (fieldDeclaration.declarationSourceEnd == 0
188         && fieldDeclaration.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT){
189         bracketBalance++;
190         return null; // no update is necessary (enum constant)
191
}
192     // might be an array initializer
193
this.updateSourceEndIfNecessary(braceStart - 1, braceEnd - 1);
194     return this.parent.updateOnOpeningBrace(braceStart, braceEnd);
195 }
196 public void updateParseTree(){
197     this.updatedFieldDeclaration();
198 }
199 /*
200  * Update the declarationSourceEnd of the corresponding parse node
201  */

202 public void updateSourceEndIfNecessary(int bodyStart, int bodyEnd){
203     if (this.fieldDeclaration.declarationSourceEnd == 0) {
204         this.fieldDeclaration.declarationSourceEnd = bodyEnd;
205         this.fieldDeclaration.declarationEnd = bodyEnd;
206     }
207 }
208 }
209
Popular Tags