removed Makefile; lifted repo/org.ibex.tool/src/ to src/
[org.ibex.tool.git] / src / org / eclipse / jdt / internal / compiler / parser / RecoveredInitializer.java
diff --git a/src/org/eclipse/jdt/internal/compiler/parser/RecoveredInitializer.java b/src/org/eclipse/jdt/internal/compiler/parser/RecoveredInitializer.java
new file mode 100644 (file)
index 0000000..66d1aae
--- /dev/null
@@ -0,0 +1,237 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.parser;
+
+/**
+ * Internal initializer structure for parsing recovery 
+ */
+import org.eclipse.jdt.core.compiler.*;
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.ast.Block;
+import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.Initializer;
+import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.Statement;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.lookup.BaseTypes;
+import org.eclipse.jdt.internal.compiler.lookup.CompilerModifiers;
+
+public class RecoveredInitializer extends RecoveredField implements CompilerModifiers, TerminalTokens, BaseTypes {
+
+       public RecoveredType[] localTypes;
+       public int localTypeCount;
+
+       public RecoveredBlock initializerBody;  
+
+public RecoveredInitializer(FieldDeclaration fieldDeclaration, RecoveredElement parent, int bracketBalance){
+       this(fieldDeclaration, parent, bracketBalance, null);
+}
+public RecoveredInitializer(FieldDeclaration fieldDeclaration, RecoveredElement parent, int bracketBalance, Parser parser){
+       super(fieldDeclaration, parent, bracketBalance, parser);
+       this.foundOpeningBrace = true;
+}
+/*
+ * Record a nested block declaration
+ */
+public RecoveredElement add(Block nestedBlockDeclaration, int bracketBalanceValue) {
+
+       /* default behavior is to delegate recording to parent if any,
+       do not consider elements passed the known end (if set)
+       it must be belonging to an enclosing element 
+       */
+       if (fieldDeclaration.declarationSourceEnd > 0
+                       && nestedBlockDeclaration.sourceStart > fieldDeclaration.declarationSourceEnd){
+               if (this.parent == null) return this; // ignore
+               return this.parent.add(nestedBlockDeclaration, bracketBalanceValue);
+       }
+       /* consider that if the opening brace was not found, it is there */
+       if (!foundOpeningBrace){
+               foundOpeningBrace = true;
+               this.bracketBalance++;
+       }
+       initializerBody = new RecoveredBlock(nestedBlockDeclaration, this, bracketBalanceValue);
+       if (nestedBlockDeclaration.sourceEnd == 0) return initializerBody;
+       return this;
+}
+/*
+ * Record a field declaration (act like inside method body)
+ */
+public RecoveredElement add(FieldDeclaration newFieldDeclaration, int bracketBalanceValue) {
+
+       /* local variables inside initializer can only be final and non void */
+       char[][] fieldTypeName;
+       if ((newFieldDeclaration.modifiers & ~AccFinal) != 0 /* local var can only be final */
+                       || (newFieldDeclaration.type == null) // initializer
+                       || ((fieldTypeName = newFieldDeclaration.type.getTypeName()).length == 1 // non void
+                               && CharOperation.equals(fieldTypeName[0], VoidBinding.sourceName()))){ 
+               if (this.parent == null) return this; // ignore
+               this.updateSourceEndIfNecessary(this.previousAvailableLineEnd(newFieldDeclaration.declarationSourceStart - 1));
+               return this.parent.add(newFieldDeclaration, bracketBalanceValue);
+       }
+
+       /* default behavior is to delegate recording to parent if any,
+       do not consider elements passed the known end (if set)
+       it must be belonging to an enclosing element 
+       */
+       if (this.fieldDeclaration.declarationSourceEnd > 0
+                       && newFieldDeclaration.declarationSourceStart > this.fieldDeclaration.declarationSourceEnd){
+               if (this.parent == null) return this; // ignore
+               return this.parent.add(newFieldDeclaration, bracketBalanceValue);
+       }
+       // still inside initializer, treat as local variable
+       return this; // ignore
+}
+/*
+ * Record a local declaration - regular method should have been created a block body
+ */
+public RecoveredElement add(LocalDeclaration localDeclaration, int bracketBalanceValue) {
+
+       /* do not consider a type starting passed the type end (if set)
+               it must be belonging to an enclosing type */
+       if (fieldDeclaration.declarationSourceEnd != 0 
+                       && localDeclaration.declarationSourceStart > fieldDeclaration.declarationSourceEnd){
+               if (parent == null) return this; // ignore
+               return this.parent.add(localDeclaration, bracketBalanceValue);
+       }
+       /* method body should have been created */
+       Block block = new Block(0);
+       block.sourceStart = ((Initializer)fieldDeclaration).sourceStart;
+       RecoveredElement element = this.add(block, 1);
+       return element.add(localDeclaration, bracketBalanceValue);      
+}
+/*
+ * Record a statement - regular method should have been created a block body
+ */
+public RecoveredElement add(Statement statement, int bracketBalanceValue) {
+
+       /* do not consider a statement starting passed the initializer end (if set)
+               it must be belonging to an enclosing type */
+       if (fieldDeclaration.declarationSourceEnd != 0 
+                       && statement.sourceStart > fieldDeclaration.declarationSourceEnd){
+               if (parent == null) return this; // ignore
+               return this.parent.add(statement, bracketBalanceValue);
+       }
+       /* initializer body should have been created */
+       Block block = new Block(0);
+       block.sourceStart = ((Initializer)fieldDeclaration).sourceStart;
+       RecoveredElement element = this.add(block, 1);
+       return element.add(statement, bracketBalanceValue);     
+}
+public RecoveredElement add(TypeDeclaration typeDeclaration, int bracketBalanceValue) {
+
+       /* do not consider a type starting passed the type end (if set)
+               it must be belonging to an enclosing type */
+       if (fieldDeclaration.declarationSourceEnd != 0 
+                       && typeDeclaration.declarationSourceStart > fieldDeclaration.declarationSourceEnd){
+               if (parent == null) return this; // ignore
+               return this.parent.add(typeDeclaration, bracketBalanceValue);
+       }
+       if ((typeDeclaration.bits & ASTNode.IsLocalTypeMASK) != 0){
+               /* method body should have been created */
+               Block block = new Block(0);
+               block.sourceStart = ((Initializer)fieldDeclaration).sourceStart;
+               RecoveredElement element = this.add(block, 1);
+               return element.add(typeDeclaration, bracketBalanceValue);       
+       }       
+       if (localTypes == null) {
+               localTypes = new RecoveredType[5];
+               localTypeCount = 0;
+       } else {
+               if (localTypeCount == localTypes.length) {
+                       System.arraycopy(
+                               localTypes, 
+                               0, 
+                               (localTypes = new RecoveredType[2 * localTypeCount]), 
+                               0, 
+                               localTypeCount); 
+               }
+       }
+       RecoveredType element = new RecoveredType(typeDeclaration, this, bracketBalanceValue);
+       localTypes[localTypeCount++] = element;
+
+       /* consider that if the opening brace was not found, it is there */
+       if (!foundOpeningBrace){
+               foundOpeningBrace = true;
+               this.bracketBalance++;
+       }
+       return element;
+}
+public String toString(int tab) {
+       StringBuffer result = new StringBuffer(tabString(tab));
+       result.append("Recovered initializer:\n"); //$NON-NLS-1$
+       this.fieldDeclaration.print(tab + 1, result);
+       if (this.initializerBody != null) {
+               result.append("\n"); //$NON-NLS-1$
+               result.append(this.initializerBody.toString(tab + 1));
+       }
+       return result.toString();
+}
+public FieldDeclaration updatedFieldDeclaration(){
+
+       if (initializerBody != null){
+               Block block = initializerBody.updatedBlock();
+               if (block != null){
+                       ((Initializer)fieldDeclaration).block = block;
+               }
+               if (this.localTypeCount > 0) fieldDeclaration.bits |= ASTNode.HasLocalTypeMASK;
+
+       }       
+       if (fieldDeclaration.sourceEnd == 0){
+               fieldDeclaration.sourceEnd = fieldDeclaration.declarationSourceEnd;
+       }
+       return fieldDeclaration;
+}
+/*
+ * A closing brace got consumed, might have closed the current element,
+ * in which case both the currentElement is exited
+ */
+public RecoveredElement updateOnClosingBrace(int braceStart, int braceEnd){
+       if ((--bracketBalance <= 0) && (parent != null)){
+               this.updateSourceEndIfNecessary(braceStart, braceEnd);
+               return parent;
+       }
+       return this;
+}
+/*
+ * An opening brace got consumed, might be the expected opening one of the current element,
+ * in which case the bodyStart is updated.
+ */
+public RecoveredElement updateOnOpeningBrace(int braceStart, int braceEnd){
+       bracketBalance++;
+       return this; // request to restart
+}
+/*
+ * Update the declarationSourceEnd of the corresponding parse node
+ */
+public void updateSourceEndIfNecessary(int braceStart, int braceEnd){
+       if (this.fieldDeclaration.declarationSourceEnd == 0) {
+               Initializer initializer = (Initializer)fieldDeclaration;
+               if(parser().rBraceSuccessorStart >= braceEnd) {
+                       if (initializer.bodyStart < parser().rBraceEnd) {
+                               initializer.declarationSourceEnd = parser().rBraceEnd;
+                       } else {
+                               initializer.declarationSourceEnd = initializer.bodyStart;
+                       }
+                       if (initializer.bodyStart < parser().rBraceStart) {
+                               initializer.bodyEnd = parser().rBraceStart;
+                       } else {
+                               initializer.bodyEnd = initializer.bodyStart;
+                       }
+               } else {
+                       initializer.declarationSourceEnd = braceEnd;
+                       initializer.bodyEnd  = braceStart - 1;
+               }
+               if(initializer.block != null) {
+                       initializer.block.sourceEnd = initializer.declarationSourceEnd;
+               }
+       }
+}
+}