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.*;
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(
&& (!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>
}
}
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);
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.
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);
+ }
}
}