Update after Philippe's review
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AssertStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AssertStatement.java
index e53723a..87afbee 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AssertStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AssertStatement.java
@@ -15,7 +15,6 @@
// for local variable attribute
int preAssertInitStateIndex = -1;
- private boolean activateCodeGeneration = false;
private FieldBinding assertionSyntheticFieldBinding;
public AssertStatement(
@@ -62,29 +61,7 @@
if (constant != NotAConstant && constant.booleanValue() == true) {
return flowInfo;
}
- activateCodeGeneration = true;
- SourceTypeBinding sourceTypeBinding = currentScope.outerMostMethodScope().enclosingSourceType();
- assertionSyntheticFieldBinding = sourceTypeBinding.addSyntheticField(this, currentScope);
- TypeDeclaration typeDeclaration = currentScope.outerMostClassScope().referenceType();
- typeDeclaration.emulationAssertionSupport = true;
- AbstractMethodDeclaration[] methods = typeDeclaration.methods;
- Clinit clinit = null;
- for (int i = 0, max = methods.length; i < max; i++) {
- AbstractMethodDeclaration method = methods[i];
- if (method.isClinit()) {
- // this is the clinit
- clinit = (Clinit) method;
- }
- }
- if (clinit == null) {
- typeDeclaration.addClinit();
- methods = typeDeclaration.methods;
- clinit = (Clinit) methods[0];
- // need to initialize the scope of the clinit
- clinit.resolve(currentScope.outerMostClassScope());
- clinit.needFreeReturn = true;
- }
- clinit.addSupportForAssertion(assertionSyntheticFieldBinding);
+ manageSyntheticAccessIfNecessary(currentScope);
return flowInfo;
}
@@ -95,7 +72,7 @@
int pc = codeStream.position, divergePC;
// codegen here
- if (activateCodeGeneration) {
+ if (this.assertionSyntheticFieldBinding != null) {
Label assertionActivationLabel = new Label(codeStream);
codeStream.getstatic(this.assertionSyntheticFieldBinding);
codeStream.ifne(assertionActivationLabel);
@@ -142,4 +119,24 @@
}
visitor.endVisit(this, scope);
}
+
+ public void manageSyntheticAccessIfNecessary(BlockScope currentScope) {
+ ClassScope outerMostClassScope = currentScope.outerMostClassScope();
+ SourceTypeBinding sourceTypeBinding = outerMostClassScope.enclosingSourceType();
+ this.assertionSyntheticFieldBinding = sourceTypeBinding.addSyntheticField(this, currentScope);
+ TypeDeclaration typeDeclaration = outerMostClassScope.referenceType();
+ AbstractMethodDeclaration[] methods = typeDeclaration.methods;
+ Clinit clinit = null;
+ for (int i = 0, max = methods.length; i < max; i++) {
+ AbstractMethodDeclaration method = methods[i];
+ if (method.isClinit()) {
+ // this is the clinit
+ clinit = (Clinit) method;
+ }
+ }
+ if (clinit != null) {
+ // should always be the case
+ clinit.addSupportForAssertion(assertionSyntheticFieldBinding);
+ }
+ }
}
\ No newline at end of file
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Clinit.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Clinit.java
index bf3a84a..e062786 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Clinit.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Clinit.java
@@ -16,7 +16,6 @@
public class Clinit extends AbstractMethodDeclaration {
public final static char[] ConstantPoolName = "<clinit>"/*nonNLS*/.toCharArray();
- private boolean activateAssertionEmulation = false;
private FieldBinding assertionSyntheticFieldBinding = null;
private FieldBinding classLiteralSyntheticField = null;
@@ -89,7 +88,7 @@
// 1.4 feature
// This has to be done before any other initialization
- if (this.activateAssertionEmulation) {
+ if (this.assertionSyntheticFieldBinding != null) {
// generate code related to the activation of assertion for this class
codeStream.generateClassLiteralAccessForType(classScope.enclosingSourceType(), classLiteralSyntheticField);
codeStream.invokeJavaLangClassDesiredAssertionStatus();
@@ -173,12 +172,11 @@
}
public void addSupportForAssertion(FieldBinding assertionSyntheticFieldBinding) {
- this.activateAssertionEmulation = true;
this.assertionSyntheticFieldBinding = assertionSyntheticFieldBinding;
// 1.4 feature
// we need to add the field right now, because the field infos are generated before the methods
SourceTypeBinding sourceType = this.scope.outerMostMethodScope().enclosingSourceType();
- classLiteralSyntheticField = sourceType.addSyntheticField(sourceType, scope);
+ this.classLiteralSyntheticField = sourceType.addSyntheticField(sourceType, scope);
}
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Statement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Statement.java
index 5060063..3c76018 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Statement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Statement.java
@@ -33,6 +33,9 @@
// for statements only
public static final int IsReachableMASK = 0x80000000; // highest bit
+
+ // for type declaration only
+ public static final int AddAssertionMASK = 1; // highest bit
/*
public final static int BitMask1= 0x1; // decimal 1
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java
index d496c26..c3be7fa 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java
@@ -33,7 +33,7 @@
public int declarationSourceStart ;
public int declarationSourceEnd ;
public int bodyStart;
- public boolean emulationAssertionSupport = false;
+
/*
* We cause the compilation task to abort to a given extent.
*/
@@ -651,7 +651,7 @@
return false ;}
----------------------------------------------------*/
- if (emulationAssertionSupport) {
+ if ((this.bits & AddAssertionMASK) != 0) {
return true;
}
if (fields == null)
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java
index bc4fd85..6dd312a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java
@@ -276,23 +276,57 @@
case 1:
switch(methodBinding.parameters[0].id) {
case T_String :
- return CONSTR_STRING_METHOD_NAME_AND_TYPE;
+ if (CharOperation.equals(methodBinding.signature(), QualifiedNamesConstants.StringConstructorSignature)) {
+ return CONSTR_STRING_METHOD_NAME_AND_TYPE;
+ } else {
+ return -1;
+ }
case T_Object :
- return CONSTR_OBJECT_METHOD_NAME_AND_TYPE;
+ if (CharOperation.equals(methodBinding.signature(), QualifiedNamesConstants.AssertionErrorObjectConstrSignature)) {
+ return CONSTR_OBJECT_METHOD_NAME_AND_TYPE;
+ } else {
+ return -1;
+ }
case T_int :
case T_byte :
case T_short :
- return CONSTR_INT_METHOD_NAME_AND_TYPE;
+ if (CharOperation.equals(methodBinding.signature(), QualifiedNamesConstants.AssertionErrorIntConstrSignature)
+ || CharOperation.equals(methodBinding.signature(), QualifiedNamesConstants.ShortConstrSignature)
+ || CharOperation.equals(methodBinding.signature(), QualifiedNamesConstants.ByteConstrSignature)) {
+ return CONSTR_INT_METHOD_NAME_AND_TYPE;
+ } else {
+ return -1;
+ }
case T_char :
- return CONSTR_CHAR_METHOD_NAME_AND_TYPE;
+ if (CharOperation.equals(methodBinding.signature(), QualifiedNamesConstants.AssertionErrorCharConstrSignature)) {
+ return CONSTR_CHAR_METHOD_NAME_AND_TYPE;
+ } else {
+ return -1;
+ }
case T_boolean :
- return CONSTR_BOOLEAN_METHOD_NAME_AND_TYPE;
+ if (CharOperation.equals(methodBinding.signature(), QualifiedNamesConstants.AssertionErrorBooleanConstrSignature)) {
+ return CONSTR_BOOLEAN_METHOD_NAME_AND_TYPE;
+ } else {
+ return -1;
+ }
case T_float :
- return CONSTR_FLOAT_METHOD_NAME_AND_TYPE;
+ if (CharOperation.equals(methodBinding.signature(), QualifiedNamesConstants.AssertionErrorFloatConstrSignature)) {
+ return CONSTR_FLOAT_METHOD_NAME_AND_TYPE;
+ } else {
+ return -1;
+ }
case T_double :
- return CONSTR_DOUBLE_METHOD_NAME_AND_TYPE;
+ if (CharOperation.equals(methodBinding.signature(), QualifiedNamesConstants.AssertionErrorDoubleConstrSignature)) {
+ return CONSTR_DOUBLE_METHOD_NAME_AND_TYPE;
+ } else {
+ return -1;
+ }
case T_long :
- return CONSTR_LONG_METHOD_NAME_AND_TYPE;
+ if (CharOperation.equals(methodBinding.signature(), QualifiedNamesConstants.AssertionErrorLongConstrSignature)) {
+ return CONSTR_LONG_METHOD_NAME_AND_TYPE;
+ } else {
+ return -1;
+ }
}
case 0:
if (methodBinding.signature().length == 3) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/QualifiedNamesConstants.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/QualifiedNamesConstants.java
index 64f4318..994e3c6 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/QualifiedNamesConstants.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/QualifiedNamesConstants.java
@@ -79,4 +79,6 @@
char[] AssertionErrorObjectConstrSignature = "(Ljava/lang/Object;)V"/*nonNLS*/.toCharArray();
char[] DesiredAssertionStatus = "desiredAssertionStatus"/*nonNLS*/.toCharArray();
char[] DesiredAssertionStatusSignature = "()Z"/*nonNLS*/.toCharArray();
+ char[] ShortConstrSignature = "(S)V"/*nonNLS*/.toCharArray();
+ char[] ByteConstrSignature = "(B)V"/*nonNLS*/.toCharArray();
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/ConfigurableProblems.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/ConfigurableProblems.java
index 4482fd9..ca927af 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/ConfigurableProblems.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/ConfigurableProblems.java
@@ -20,4 +20,5 @@
final int TemporaryWarning = 0x40000;
final int AccessEmulation = 0x80000;
final int NonExternalizedString = 0x100000;
+ final int AssertUsedAsAnIdentifier = 0x200000;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java
index b783f44..e292896 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java
@@ -199,17 +199,16 @@
return synthField;
}
-/* Add a new synthetic field for a class literal access.
+/* Add a new synthetic field for the emulation of the assert statement.
* Answer the new field or the existing field if one already existed.
*/
-
public FieldBinding addSyntheticField(AssertStatement assertStatement, BlockScope blockScope) {
if (synthetics == null) {
synthetics = new Hashtable[] { new Hashtable(5), new Hashtable(5), new Hashtable(5) };
}
// use a different table than FIELDS, given there might be a collision between emulation of X.this$0 and X.class.
- FieldBinding synthField = (FieldBinding) synthetics[FIELD].get(BooleanBinding);
+ FieldBinding synthField = (FieldBinding) synthetics[FIELD].get("assertionEmulation"/*nonNLS*/);
if (synthField == null) {
synthField = new SyntheticFieldBinding(
"$assertionsDisabled"/*nonNLS*/.toCharArray(),
@@ -218,7 +217,7 @@
this,
Constant.NotAConstant,
0);
- synthetics[FIELD].put(BooleanBinding, synthField);
+ synthetics[FIELD].put("assertionEmulation"/*nonNLS*/, synthField);
}
// ensure there is not already such a field defined by the user
// ensure there is not already such a field defined by the user
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeIds.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeIds.java
index 3ff5545..61b6336 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeIds.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeIds.java
@@ -41,7 +41,6 @@
final int T_JavaLangClassNotFoundException = 23;
final int T_JavaIoPrintStream = 24;
final int T_JavaLangException = 25;
- final int T_JavaLangAssertionError = 35; // 1.4 feature
// wrapper types
final int T_JavaLangByte = 26;
@@ -53,6 +52,9 @@
final int T_JavaLangDouble = 32;
final int T_JavaLangBoolean = 33;
final int T_JavaLangVoid = 34;
+
+ // 1.4 feature
+ final int T_JavaLangAssertionError = 35;
final int NoId = Integer.MAX_VALUE;
// implicit conversions: <compileType> to <runtimeType> (note: booleans are integers at runtime)
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java
index 0b5496a..2cda38c 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java
@@ -1389,6 +1389,9 @@
}
//always add <clinit> (will be remove at code gen time if empty)
+ if (this.scanner.containsAssertKeyword) {
+ typeDecl.bits |= Statement.AddAssertionMASK;
+ }
typeDecl.addClinit();
typeDecl.declarationSourceEnd = flushAnnotationsDefinedPriorTo(endStatementPosition);
}
@@ -2127,6 +2130,9 @@
typeDecl.checkConstructors(this);
//always add <clinit> (will be remove at code gen time if empty)
+ if (this.scanner.containsAssertKeyword) {
+ typeDecl.bits |= Statement.AddAssertionMASK;
+ }
typeDecl.addClinit();
typeDecl.declarationSourceEnd = flushAnnotationsDefinedPriorTo(endStatementPosition);
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java
index 7ef2d07..c91fa27 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java
@@ -21,6 +21,7 @@
// 1.4 feature
public boolean assertMode;
public boolean useAssertAsAnIndentifier = false;
+ public boolean containsAssertKeyword = false;
public boolean recordLineSeparator;
public char currentCharacter;
@@ -1988,6 +1989,7 @@
&& (data[++index] == 'r')
&& (data[++index] == 't')) {
if (assertMode) {
+ containsAssertKeyword = true;
return TokenNameassert;
} else {
useAssertAsAnIndentifier = true;
@@ -2670,6 +2672,7 @@
source = sourceString;
startPosition = -1;
initialPosition = currentPosition = 0;
+ containsAssertKeyword = false;
if (source == null) {
source = new char[0];
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
index 9e3ebf6..1f1af06 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
@@ -428,7 +428,14 @@
return Warning;
}
return Ignore;
-
+ case UseAssertAsAnIdentifier :
+ if ((errorThreshold & AssertUsedAsAnIdentifier) != 0){
+ return Error;
+ }
+ if ((warningThreshold & AssertUsedAsAnIdentifier) != 0){
+ return Warning;
+ }
+ return Ignore;
default:
return Error;
}
@@ -2160,7 +2167,6 @@
this.handle(
UseAssertAsAnIdentifier,
new String[0],
- Warning,
sourceStart,
sourceEnd);
}