import eclipse 3.1 M4 compiler
[org.ibex.tool.git] / src / org / eclipse / jdt / internal / compiler / parser / RecoveredType.java
index 9ac355e..c93242e 100644 (file)
@@ -12,12 +12,15 @@ package org.eclipse.jdt.internal.compiler.parser;
 
 import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
 import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration;
 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.Statement;
 import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.TypeParameter;
 import org.eclipse.jdt.internal.compiler.ast.TypeReference;
+import org.eclipse.jdt.internal.compiler.env.IGenericType;
 import org.eclipse.jdt.internal.compiler.lookup.CompilerModifiers;
 
 /**
@@ -37,10 +40,13 @@ public class RecoveredType extends RecoveredStatement implements TerminalTokens,
        public boolean preserveContent = false; // only used for anonymous types
        public int bodyEnd;
        
+       public boolean insideEnumConstantPart = false;
+       
 public RecoveredType(TypeDeclaration typeDeclaration, RecoveredElement parent, int bracketBalance){
        super(typeDeclaration, parent, bracketBalance);
        this.typeDeclaration = typeDeclaration;
        this.foundOpeningBrace = !bodyStartsAtHeaderEnd();
+       this.insideEnumConstantPart = typeDeclaration.kind() == IGenericType.ENUM_DECL;
        if(this.foundOpeningBrace) {
                this.bracketBalance++;
        }
@@ -69,6 +75,8 @@ public RecoveredElement add(AbstractMethodDeclaration methodDeclaration, int bra
        }
        RecoveredMethod element = new RecoveredMethod(methodDeclaration, this, bracketBalanceValue, this.recoveringParser);
        methods[methodCount++] = element;
+       
+       this.insideEnumConstantPart = false;
 
        /* consider that if the opening brace was not found, it is there */
        if (!foundOpeningBrace){
@@ -107,9 +115,19 @@ public RecoveredElement add(FieldDeclaration fieldDeclaration, int bracketBalanc
                                fieldCount); 
                }
        }
-       RecoveredField element = fieldDeclaration.isField() 
-                                                               ? new RecoveredField(fieldDeclaration, this, bracketBalanceValue)
-                                                               : new RecoveredInitializer(fieldDeclaration, this, bracketBalanceValue);
+       RecoveredField element;
+       switch (fieldDeclaration.getKind()) {
+               case AbstractVariableDeclaration.FIELD:
+               case AbstractVariableDeclaration.ENUM_CONSTANT:
+                       element = new RecoveredField(fieldDeclaration, this, bracketBalanceValue);
+                       break;
+               case AbstractVariableDeclaration.INITIALIZER:
+                       element = new RecoveredInitializer(fieldDeclaration, this, bracketBalanceValue);
+                       break;
+               default:
+                       // never happens, as field is always identified
+                       return this;
+       }
        fields[fieldCount++] = element;
 
        /* consider that if the opening brace was not found, it is there */
@@ -130,6 +148,8 @@ public RecoveredElement add(TypeDeclaration memberTypeDeclaration, int bracketBa
                return this.parent.add(memberTypeDeclaration, bracketBalanceValue);
        }
        
+       this.insideEnumConstantPart = false;
+       
        if ((memberTypeDeclaration.bits & ASTNode.IsAnonymousTypeMASK) != 0){
                if (this.methodCount > 0) {
                        // add it to the last method body
@@ -179,7 +199,11 @@ public int bodyEnd(){
 public boolean bodyStartsAtHeaderEnd(){
        if (typeDeclaration.superInterfaces == null){
                if (typeDeclaration.superclass == null){
-                       return typeDeclaration.bodyStart == typeDeclaration.sourceEnd+1;
+                       if(typeDeclaration.typeParameters == null) {
+                               return typeDeclaration.bodyStart == typeDeclaration.sourceEnd+1;
+                       } else {
+                               return typeDeclaration.bodyStart == typeDeclaration.typeParameters[typeDeclaration.typeParameters.length-1].sourceEnd+1;
+                       }
                } else {
                        return typeDeclaration.bodyStart == typeDeclaration.superclass.sourceEnd+1;
                }
@@ -306,12 +330,14 @@ public TypeDeclaration updatedTypeDeclaration(){
        /* update methods */
        int existingCount = typeDeclaration.methods == null ? 0 : typeDeclaration.methods.length;
        boolean hasConstructor = false, hasRecoveredConstructor = false;
+       boolean hasAbstractMethods = false;
        int defaultConstructorIndex = -1;
        if (methodCount > 0){
                AbstractMethodDeclaration[] methodDeclarations = new AbstractMethodDeclaration[existingCount + methodCount];
                for (int i = 0; i < existingCount; i++){
                        AbstractMethodDeclaration m = typeDeclaration.methods[i];
                        if (m.isDefaultConstructor()) defaultConstructorIndex = i;
+                       if (m.isAbstract()) hasAbstractMethods = true;
                        methodDeclarations[i] = m;
                }
                // may need to update the declarationSourceEnd of the last method
@@ -323,9 +349,11 @@ public TypeDeclaration updatedTypeDeclaration(){
                for (int i = 0; i < methodCount; i++){
                        AbstractMethodDeclaration updatedMethod = methods[i].updatedMethodDeclaration();                        
                        if (updatedMethod.isConstructor()) hasRecoveredConstructor = true;
+                       if (updatedMethod.isAbstract()) hasAbstractMethods = true;
                        methodDeclarations[existingCount + i] = updatedMethod;                  
                }
                typeDeclaration.methods = methodDeclarations;
+               if (hasAbstractMethods) typeDeclaration.bits |= ASTNode.HasAbstractMethods;
                hasConstructor = typeDeclaration.checkConstructors(this.parser());
        } else {
                for (int i = 0; i < existingCount; i++){
@@ -360,7 +388,7 @@ public TypeDeclaration updatedTypeDeclaration(){
                }
                typeDeclaration.methods = methodDeclarations;
        } else {
-               if (!hasConstructor && !typeDeclaration.isInterface()) {// if was already reduced, then constructor
+               if (!hasConstructor && typeDeclaration.kind() != IGenericType.INTERFACE_DECL && typeDeclaration.kind() != IGenericType.ANNOTATION_TYPE_DECL) {// if was already reduced, then constructor
                        boolean insideFieldInitializer = false;
                        RecoveredElement parentElement = this.parent; 
                        while (parentElement != null){
@@ -370,7 +398,7 @@ public TypeDeclaration updatedTypeDeclaration(){
                                }
                                parentElement = parentElement.parent;
                        }
-                       typeDeclaration.createsInternalConstructor(!parser().diet || insideFieldInitializer, true);
+                       typeDeclaration.createDefaultConstructor(!parser().diet || insideFieldInitializer, true);
                } 
        }
        if (parent instanceof RecoveredType){
@@ -409,6 +437,30 @@ public void updateFromParserState(){
                                // will reset typeListLength to zero
                                // thus this check will only be performed on first errorCheck after class X implements Y,Z,
                        }
+               } else if (parser.listTypeParameterLength > 0) {
+                       int length = parser.listTypeParameterLength;
+                       int genericsPtr = parser.genericsPtr;
+                       boolean canConsume = genericsPtr + 1 >= length && parser.astPtr > -1;
+                       if(canConsume) {
+                               if (!(parser.astStack[parser.astPtr] instanceof TypeDeclaration)) {
+                                       canConsume = false;
+                               }
+                               while(genericsPtr + 1 > length && !(parser.genericsStack[genericsPtr] instanceof TypeParameter)) {
+                                       genericsPtr--;
+                               }
+                               for (int i = 0; i < length; i++) {
+                                       if(!(parser.genericsStack[genericsPtr - i] instanceof TypeParameter)) {
+                                               canConsume = false;
+                                       }
+                               }
+                       }
+                       if(canConsume) {
+                               TypeDeclaration typeDecl = (TypeDeclaration)parser.astStack[parser.astPtr];
+                               System.arraycopy(parser.genericsStack, genericsPtr - length + 1, typeDecl.typeParameters = new TypeParameter[length], 0, length);
+                               typeDecl.bodyStart = typeDecl.typeParameters[length-1].declarationSourceEnd + 1;
+                               parser.listTypeParameterLength = 0;
+                               parser.lastCheckPoint = typeDecl.bodyStart;
+                       }
                }
        }
 }
@@ -440,6 +492,9 @@ public RecoveredElement updateOnOpeningBrace(int braceStart, int braceEnd){
                        case -1 :
                        case TokenNameextends :
                        case TokenNameimplements :
+                       case TokenNameGREATER :
+                       case TokenNameRIGHT_SHIFT :
+                       case TokenNameUNSIGNED_RIGHT_SHIFT :
                                if (parser.recoveredStaticInitializerStart == 0) break;
                        default:
                                this.foundOpeningBrace = true;