import eclipse 3.1 M4 compiler
[org.ibex.tool.git] / src / org / eclipse / jdt / internal / compiler / ast / Clinit.java
index 2bbac9c..22dbe6d 100644 (file)
@@ -13,6 +13,7 @@ package org.eclipse.jdt.internal.compiler.ast;
 import org.eclipse.jdt.internal.compiler.ASTVisitor;
 import org.eclipse.jdt.internal.compiler.*;
 import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.env.IGenericType;
 import org.eclipse.jdt.internal.compiler.flow.*;
 import org.eclipse.jdt.internal.compiler.lookup.*;
 import org.eclipse.jdt.internal.compiler.parser.*;
@@ -20,15 +21,13 @@ import org.eclipse.jdt.internal.compiler.problem.*;
 
 public class Clinit extends AbstractMethodDeclaration {
        
-       public final static char[] ConstantPoolName = "<clinit>".toCharArray(); //$NON-NLS-1$
-
        private FieldBinding assertionSyntheticFieldBinding = null;
        private FieldBinding classLiteralSyntheticField = null;
 
        public Clinit(CompilationResult compilationResult) {
                super(compilationResult);
                modifiers = 0;
-               selector = ConstantPoolName;
+               selector = TypeConstants.CLINIT;
        }
 
        public void analyseCode(
@@ -60,7 +59,7 @@ public class Clinit extends AbstractMethodDeclaration {
                                        && (!flowInfo.isDefinitelyAssigned(fields[i]))) {
                                        scope.problemReporter().uninitializedBlankFinalField(
                                                field,
-                                               scope.referenceType().declarationOf(field));
+                                               scope.referenceType().declarationOf(field.original()));
                                        // can complain against the field decl, since only one <clinit>
                                }
                        }
@@ -150,7 +149,7 @@ public class Clinit extends AbstractMethodDeclaration {
                if (this.assertionSyntheticFieldBinding != null) {
                        // generate code related to the activation of assertion for this class
                        codeStream.generateClassLiteralAccessForType(
-                               classScope.enclosingSourceType(),
+                                       classScope.enclosingSourceType(),
                                classLiteralSyntheticField);
                        codeStream.invokeJavaLangClassDesiredAssertionStatus();
                        Label falseLabel = new Label(codeStream);
@@ -163,15 +162,63 @@ public class Clinit extends AbstractMethodDeclaration {
                        jumpLabel.place();
                        codeStream.putstatic(this.assertionSyntheticFieldBinding);
                }
-               // generate initializers
-               if (declaringType.fields != null) {
-                       for (int i = 0, max = declaringType.fields.length; i < max; i++) {
-                               FieldDeclaration fieldDecl;
-                               if ((fieldDecl = declaringType.fields[i]).isStatic()) {
-                                       fieldDecl.generateCode(staticInitializerScope, codeStream);
+               // generate static fields/initializers/enum constants
+               final FieldDeclaration[] fieldDeclarations = declaringType.fields;
+               if (declaringType.kind() == IGenericType.ENUM_DECL) {
+                       int enumCount = 0;
+                       int notEnumConstants = 0;
+                       if (fieldDeclarations != null) {
+                               for (int i = 0, max = fieldDeclarations.length; i < max; i++) {
+                                       FieldDeclaration fieldDecl = fieldDeclarations[i];
+                                       if (fieldDecl.isStatic()) {
+                                               if (fieldDecl.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT) {
+                                                       fieldDecl.generateCode(staticInitializerScope, codeStream);
+                                                       enumCount++;
+                                               } else {
+                                                       notEnumConstants++;
+                                               }
+                                       }
+                               }
+                       }
+                       // enum need to initialize $VALUES synthetic cache of enum constants
+                       if (enumCount > 0) {
+                               if (fieldDeclarations != null) {
+                                       // $VALUES := new <EnumType>[<enumCount>]
+                                       codeStream.generateInlinedValue(enumCount);
+                                       codeStream.anewarray(declaringType.binding);
+                                       for (int i = 0, max = fieldDeclarations.length; i < max; i++) {
+                                               FieldDeclaration fieldDecl = fieldDeclarations[i];
+                                               // $VALUES[i] = <enum-constant-i>
+                                               if (fieldDecl.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT) {
+                                                       codeStream.dup();
+                                                       codeStream.generateInlinedValue(fieldDecl.binding.id);
+                                                       codeStream.getstatic(fieldDecl.binding);
+                                                       codeStream.aastore();
+                                               }
+                                       }
+                                       codeStream.putstatic(declaringType.enumValuesSyntheticfield);
+                               }
+                       }
+                       if (notEnumConstants != 0) {
+                               // if fields that are not enum constants need to be generated (static initializer/static field)
+                               for (int i = 0, max = fieldDeclarations.length; i < max; i++) {
+                                       FieldDeclaration fieldDecl = fieldDeclarations[i];
+                                       if (fieldDecl.isStatic() && fieldDecl.getKind() != AbstractVariableDeclaration.ENUM_CONSTANT) {
+                                               fieldDecl.generateCode(staticInitializerScope, codeStream);
+                                       }
+                               }
+                       }
+               } else {
+                       if (fieldDeclarations != null) {
+                               for (int i = 0, max = fieldDeclarations.length; i < max; i++) {
+                                       FieldDeclaration fieldDecl = fieldDeclarations[i];
+                                       if (fieldDecl.isStatic()) {
+                                               fieldDecl.generateCode(staticInitializerScope, codeStream);
+                                       }
                                }
                        }
                }
+               
                if (codeStream.position == 0) {
                        // do not need to output a Clinit if no bytecodes
                        // so we reset the offset inside the byte array contents.
@@ -231,16 +278,17 @@ public class Clinit extends AbstractMethodDeclaration {
                visitor.endVisit(this, classScope);
        }
 
-       // 1.4 feature
-       public void setAssertionSupport(FieldBinding assertionSyntheticFieldBinding) {
+       public void setAssertionSupport(FieldBinding assertionSyntheticFieldBinding, boolean needClassLiteralField) {
 
                this.assertionSyntheticFieldBinding = assertionSyntheticFieldBinding;
 
                // we need to add the field right now, because the field infos are generated before the methods
                SourceTypeBinding sourceType =
                        this.scope.outerMostMethodScope().enclosingSourceType();
-               this.classLiteralSyntheticField =
-                       sourceType.addSyntheticField(sourceType, scope);
+               if (needClassLiteralField) {
+                       this.classLiteralSyntheticField =
+                               sourceType.addSyntheticFieldForClassLiteral(sourceType, scope);
+               }
        }
 
 }