removed Makefile; lifted repo/org.ibex.tool/src/ to src/
[org.ibex.tool.git] / src / org / eclipse / jdt / internal / compiler / parser / RecoveredField.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 field structure for parsing recovery 
15  */
16 import org.eclipse.jdt.internal.compiler.ast.ArrayTypeReference;
17 import org.eclipse.jdt.internal.compiler.ast.ASTNode;
18 import org.eclipse.jdt.internal.compiler.ast.Expression;
19 import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
20 import org.eclipse.jdt.internal.compiler.ast.Statement;
21 import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
22
23 public class RecoveredField extends RecoveredElement {
24
25         public FieldDeclaration fieldDeclaration;
26         boolean alreadyCompletedFieldInitialization;
27         
28         public RecoveredType[] anonymousTypes;
29         public int anonymousTypeCount;
30 public RecoveredField(FieldDeclaration fieldDeclaration, RecoveredElement parent, int bracketBalance){
31         this(fieldDeclaration, parent, bracketBalance, null);
32 }
33 public RecoveredField(FieldDeclaration fieldDeclaration, RecoveredElement parent, int bracketBalance, Parser parser){
34         super(parent, bracketBalance, parser);
35         this.fieldDeclaration = fieldDeclaration;
36         this.alreadyCompletedFieldInitialization = fieldDeclaration.initialization != null;
37 }
38 /*
39  * Record an expression statement if field is expecting an initialization expression,
40  * used for completion inside field initializers.
41  */
42 public RecoveredElement add(Statement statement, int bracketBalanceValue) {
43
44         if (this.alreadyCompletedFieldInitialization || !(statement instanceof Expression)) {
45                 return super.add(statement, bracketBalanceValue);
46         } else {
47                 this.alreadyCompletedFieldInitialization = true;
48                 this.fieldDeclaration.initialization = (Expression)statement;
49                 this.fieldDeclaration.declarationSourceEnd = statement.sourceEnd;
50                 this.fieldDeclaration.declarationEnd = statement.sourceEnd;
51                 return this;
52         }
53 }
54 /*
55  * Record a type declaration if this field is expecting an initialization expression 
56  * and the type is an anonymous type.
57  * Used for completion inside field initializers.
58  */
59 public RecoveredElement add(TypeDeclaration typeDeclaration, int bracketBalanceValue) {
60
61         if (this.alreadyCompletedFieldInitialization 
62                         || ((typeDeclaration.bits & ASTNode.IsAnonymousTypeMASK) == 0)
63                         || (this.fieldDeclaration.declarationSourceEnd != 0 && typeDeclaration.sourceStart > this.fieldDeclaration.declarationSourceEnd)) {
64                 return super.add(typeDeclaration, bracketBalanceValue);
65         } else { 
66                 // Prepare anonymous type list
67                 if (this.anonymousTypes == null) {
68                         this.anonymousTypes = new RecoveredType[5];
69                         this.anonymousTypeCount = 0;
70                 } else {
71                         if (this.anonymousTypeCount == this.anonymousTypes.length) {
72                                 System.arraycopy(
73                                         this.anonymousTypes, 
74                                         0, 
75                                         (this.anonymousTypes = new RecoveredType[2 * this.anonymousTypeCount]), 
76                                         0, 
77                                         this.anonymousTypeCount); 
78                         }
79                 }
80                 // Store type declaration as an anonymous type
81                 RecoveredType element = new RecoveredType(typeDeclaration, this, bracketBalanceValue);
82                 this.anonymousTypes[this.anonymousTypeCount++] = element;
83                 return element;
84         }
85 }
86 /* 
87  * Answer the associated parsed structure
88  */
89 public ASTNode parseTree(){
90         return fieldDeclaration;
91 }
92 /*
93  * Answer the very source end of the corresponding parse node
94  */
95 public int sourceEnd(){
96         return this.fieldDeclaration.declarationSourceEnd;
97 }
98 public String toString(int tab){
99         StringBuffer buffer = new StringBuffer(tabString(tab));
100         buffer.append("Recovered field:\n"); //$NON-NLS-1$
101         fieldDeclaration.print(tab + 1, buffer);
102         if (this.anonymousTypes != null) {
103                 for (int i = 0; i < this.anonymousTypeCount; i++){
104                         buffer.append("\n"); //$NON-NLS-1$
105                         buffer.append(anonymousTypes[i].toString(tab + 1));
106                 }
107         }
108         return buffer.toString();
109 }
110 public FieldDeclaration updatedFieldDeclaration(){
111
112         if (this.anonymousTypes != null && fieldDeclaration.initialization == null) {
113                 for (int i = 0; i < this.anonymousTypeCount; i++){
114                         if (anonymousTypes[i].preserveContent){
115                                 fieldDeclaration.initialization = this.anonymousTypes[i].updatedTypeDeclaration().allocation;
116                         }
117                 }
118                 if (this.anonymousTypeCount > 0) fieldDeclaration.bits |= ASTNode.HasLocalTypeMASK;
119         }
120         return fieldDeclaration;
121 }
122 /*
123  * A closing brace got consumed, might have closed the current element,
124  * in which case both the currentElement is exited.
125  *
126  * Fields have no associated braces, thus if matches, then update parent.
127  */
128 public RecoveredElement updateOnClosingBrace(int braceStart, int braceEnd){
129         if (bracketBalance > 0){ // was an array initializer
130                 bracketBalance--;
131                 if (bracketBalance == 0) alreadyCompletedFieldInitialization = true;
132                 return this;
133         } else if (bracketBalance == 0) {
134                 alreadyCompletedFieldInitialization = true;
135                 updateSourceEndIfNecessary(braceEnd - 1);
136         }
137         if (parent != null){
138                 return parent.updateOnClosingBrace(braceStart, braceEnd);
139         }
140         return this;
141 }
142 /*
143  * An opening brace got consumed, might be the expected opening one of the current element,
144  * in which case the bodyStart is updated.
145  */
146 public RecoveredElement updateOnOpeningBrace(int braceStart, int braceEnd){
147         if (fieldDeclaration.declarationSourceEnd == 0 
148                 && fieldDeclaration.type instanceof ArrayTypeReference
149                 && !alreadyCompletedFieldInitialization){
150                 bracketBalance++;
151                 return null; // no update is necessary  (array initializer)
152         }
153         // might be an array initializer
154         this.updateSourceEndIfNecessary(braceStart - 1, braceEnd - 1);  
155         return this.parent.updateOnOpeningBrace(braceStart, braceEnd);  
156 }
157 public void updateParseTree(){
158         this.updatedFieldDeclaration();
159 }
160 /*
161  * Update the declarationSourceEnd of the corresponding parse node
162  */
163 public void updateSourceEndIfNecessary(int bodyStart, int bodyEnd){
164         if (this.fieldDeclaration.declarationSourceEnd == 0) {
165                 this.fieldDeclaration.declarationSourceEnd = bodyEnd;
166                 this.fieldDeclaration.declarationEnd = bodyEnd;
167         }
168 }
169 }