View | Details | Raw Unified | Return to bug 61946 | Differences between
and this patch

Collapse All | Expand All

(-)compiler/org/eclipse/jdt/internal/compiler/ClassFile.java (-7 / +2 lines)
Lines 134-144 Link Here
134
		// add its fields
134
		// add its fields
135
		FieldBinding[] fields = typeBinding.fields;
135
		FieldBinding[] fields = typeBinding.fields;
136
		if ((fields != null) && (fields != NoFields)) {
136
		if ((fields != null) && (fields != NoFields)) {
137
			for (int i = 0, max = fields.length; i < max; i++) {
138
				if (fields[i].constant() == null) {
139
					FieldReference.getConstantFor(fields[i], null, false, null);
140
				}
141
			}
142
			classFile.addFieldInfos();
137
			classFile.addFieldInfos();
143
		} else {
138
		} else {
144
			// we have to set the number of fields to be equals to 0
139
			// we have to set the number of fields to be equals to 0
Lines 680-686 Link Here
680
		int attributesNumber = 0;
675
		int attributesNumber = 0;
681
		// 4.7.2 only static constant fields get a ConstantAttribute
676
		// 4.7.2 only static constant fields get a ConstantAttribute
682
		// Generate the constantValueAttribute
677
		// Generate the constantValueAttribute
683
		if (fieldBinding.isConstantValue()){
678
		Constant fieldConstant = fieldBinding.constant();
679
		if (fieldConstant != Constant.NotAConstant){
684
			if (contentsOffset + 8 >= contents.length) {
680
			if (contentsOffset + 8 >= contents.length) {
685
				resizeContents(8);
681
				resizeContents(8);
686
			}
682
			}
Lines 696-702 Link Here
696
			contents[contentsOffset++] = 2;
692
			contents[contentsOffset++] = 2;
697
			attributesNumber++;
693
			attributesNumber++;
698
			// Need to add the constant_value_index
694
			// Need to add the constant_value_index
699
			Constant fieldConstant = fieldBinding.constant();
700
			switch (fieldConstant.typeID()) {
695
			switch (fieldConstant.typeID()) {
701
				case T_boolean :
696
				case T_boolean :
702
					int booleanValueIndex =
697
					int booleanValueIndex =
(-)compiler/org/eclipse/jdt/internal/compiler/ast/FieldDeclaration.java (-2 / +2 lines)
Lines 69-75 Link Here
69
		if (this.binding != null
69
		if (this.binding != null
70
				&& this.binding.isValidBinding()
70
				&& this.binding.isValidBinding()
71
				&& this.binding.isStatic()
71
				&& this.binding.isStatic()
72
				&& !this.binding.isConstantValue()
72
				&& this.binding.constant() == Constant.NotAConstant
73
				&& this.binding.declaringClass.isNestedType()
73
				&& this.binding.declaringClass.isNestedType()
74
				&& !this.binding.declaringClass.isStatic()) {
74
				&& !this.binding.declaringClass.isStatic()) {
75
			initializationScope.problemReporter().unexpectedStaticModifierForField(
75
			initializationScope.problemReporter().unexpectedStaticModifierForField(
Lines 104-110 Link Here
104
		int pc = codeStream.position;
104
		int pc = codeStream.position;
105
		boolean isStatic;
105
		boolean isStatic;
106
		if (this.initialization != null
106
		if (this.initialization != null
107
			&& !((isStatic = this.binding.isStatic()) && this.binding.isConstantValue())) {
107
			&& !((isStatic = this.binding.isStatic()) && this.binding.constant() != Constant.NotAConstant)) {
108
			// non-static field, need receiver
108
			// non-static field, need receiver
109
			if (!isStatic)
109
			if (!isStatic)
110
				codeStream.aload_0();
110
				codeStream.aload_0();
(-)compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.java (-63 / +6 lines)
Lines 192-205 Link Here
192
			}
192
			}
193
		} else {
193
		} else {
194
			boolean isStatic = this.codegenBinding.isStatic();
194
			boolean isStatic = this.codegenBinding.isStatic();
195
			if (this.codegenBinding.isConstantValue()) {
195
			Constant fieldConstant = this.codegenBinding.constant();
196
			if (fieldConstant != Constant.NotAConstant) {			
196
				receiver.generateCode(currentScope, codeStream, !isStatic);
197
				receiver.generateCode(currentScope, codeStream, !isStatic);
197
				if (!isStatic){
198
				if (!isStatic){
198
					codeStream.invokeObjectGetClass();
199
					codeStream.invokeObjectGetClass();
199
					codeStream.pop();
200
					codeStream.pop();
200
				}
201
				}
201
				if (valueRequired) {
202
				if (valueRequired) {
202
					codeStream.generateConstant(this.codegenBinding.constant(), implicitConversion);
203
					codeStream.generateConstant(fieldConstant, implicitConversion);
203
				}
204
				}
204
			} else {
205
			} else {
205
				receiver.generateCode(currentScope, codeStream, !isStatic);
206
				receiver.generateCode(currentScope, codeStream, !isStatic);
Lines 365-425 Link Here
365
	public TypeBinding[] genericTypeArguments() {
366
	public TypeBinding[] genericTypeArguments() {
366
		return null;
367
		return null;
367
	}
368
	}
368
	public static final Constant getConstantFor(
369
		FieldBinding binding,
370
		Reference reference,
371
		boolean isImplicit,
372
		Scope referenceScope) {
373
374
		//propagation of the constant.
375
376
		//ref can be a FieldReference, a SingleNameReference or a QualifiedNameReference
377
		//indexInQualification may have a value greater than zero only for QualifiednameReference
378
		//if ref==null then indexInQualification==0 AND implicitReceiver == false. This case is a 
379
		//degenerated case where a fake reference field (null) 
380
		//is associted to a real FieldBinding in order 
381
		//to allow its constant computation using the regular path (in other words, find the fieldDeclaration
382
		//and proceed to its type resolution). As implicitReceiver is false, no error reporting
383
		//against ref will be used ==> no nullPointerException risk .... 
384
385
		//special treatment for langage-built-in  field (their declaring class is null)
386
		if (binding.declaringClass == null) {
387
			//currently only one field "length" : the constant computation is never done
388
			return NotAConstant;
389
		}
390
		if (!binding.isFinal()) {
391
			binding.setConstant(NotAConstant);
392
			return NotAConstant;
393
		}
394
		Constant fieldConstant = binding.constant();
395
		if (fieldConstant != null) {
396
			if (isImplicit || (reference instanceof QualifiedNameReference
397
					&& binding == ((QualifiedNameReference)reference).binding)) {
398
				return fieldConstant;
399
			}
400
			return NotAConstant;
401
		}
402
403
		//The field has not been yet type checked.
404
		//It also means that the field is not coming from a class that
405
		//has already been compiled. It can only be from a class within
406
		//compilation units to process. Thus the field is NOT from a BinaryTypeBinbing
407
408
		FieldBinding originalField = binding.original();
409
		SourceTypeBinding sourceType = (SourceTypeBinding) originalField.declaringClass;
410
		TypeDeclaration typeDecl = sourceType.scope.referenceContext;
411
		FieldDeclaration fieldDecl = typeDecl.declarationOf(originalField);
412
413
		fieldDecl.resolve(originalField.isStatic() //side effect on binding 
414
				? typeDecl.staticInitializerScope
415
				: typeDecl.initializerScope); 
416
417
		if (isImplicit || (reference instanceof QualifiedNameReference
418
				&& binding == ((QualifiedNameReference)reference).binding)) {
419
			return binding.constant();
420
		}
421
		return NotAConstant;
422
	}
423
369
424
	public boolean isSuperAccess() {
370
	public boolean isSuperAccess() {
425
371
Lines 441-447 Link Here
441
		this.codegenBinding = this.binding.original();
387
		this.codegenBinding = this.binding.original();
442
		
388
		
443
		if (binding.isPrivate()) {
389
		if (binding.isPrivate()) {
444
			if ((currentScope.enclosingSourceType() != this.codegenBinding.declaringClass) && !binding.isConstantValue()) {
390
			if ((currentScope.enclosingSourceType() != this.codegenBinding.declaringClass) && binding.constant() == Constant.NotAConstant) {
445
				if (syntheticAccessors == null)
391
				if (syntheticAccessors == null)
446
					syntheticAccessors = new MethodBinding[2];
392
					syntheticAccessors = new MethodBinding[2];
447
				syntheticAccessors[isReadAccess ? READ : WRITE] = 
393
				syntheticAccessors[isReadAccess ? READ : WRITE] = 
Lines 486-492 Link Here
486
		if (this.binding.declaringClass != this.receiverType
432
		if (this.binding.declaringClass != this.receiverType
487
				&& !this.receiverType.isArrayType()
433
				&& !this.receiverType.isArrayType()
488
				&& this.binding.declaringClass != null // array.length
434
				&& this.binding.declaringClass != null // array.length
489
				&& !this.binding.isConstantValue()) {
435
				&& binding.constant() == Constant.NotAConstant) {
490
			CompilerOptions options = currentScope.compilerOptions();
436
			CompilerOptions options = currentScope.compilerOptions();
491
			if ((options.targetJDK >= ClassFileConstants.JDK1_2
437
			if ((options.targetJDK >= ClassFileConstants.JDK1_2
492
					&& (options.complianceLevel >= ClassFileConstants.JDK1_4 || !receiver.isImplicitThis() || !this.codegenBinding.isStatic())
438
					&& (options.complianceLevel >= ClassFileConstants.JDK1_4 || !receiver.isImplicitThis() || !this.codegenBinding.isStatic())
Lines 549-558 Link Here
549
			scope.problemReporter().deprecatedField(fieldBinding, this);
495
			scope.problemReporter().deprecatedField(fieldBinding, this);
550
		}
496
		}
551
		boolean isImplicitThisRcv = receiver.isImplicitThis();
497
		boolean isImplicitThisRcv = receiver.isImplicitThis();
552
		constant = FieldReference.getConstantFor(fieldBinding, this, isImplicitThisRcv, scope);
498
		constant = isImplicitThisRcv ? fieldBinding.constant() : Constant.NotAConstant;
553
		if (!isImplicitThisRcv) {
554
			constant = NotAConstant;
555
		}
556
		if (fieldBinding.isStatic()) {
499
		if (fieldBinding.isStatic()) {
557
			// static field accessed through receiver? legal but unoptimal (optional warning)
500
			// static field accessed through receiver? legal but unoptimal (optional warning)
558
			if (!(isImplicitThisRcv
501
			if (!(isImplicitThisRcv
(-)compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java (-16 / +16 lines)
Lines 366-378 Link Here
366
			FieldBinding lastFieldBinding = generateReadSequence(currentScope, codeStream);
366
			FieldBinding lastFieldBinding = generateReadSequence(currentScope, codeStream);
367
			if (lastFieldBinding != null) {
367
			if (lastFieldBinding != null) {
368
				boolean isStatic = lastFieldBinding.isStatic();
368
				boolean isStatic = lastFieldBinding.isStatic();
369
				if (lastFieldBinding.isConstantValue()) {
369
				Constant fieldConstant = lastFieldBinding.constant();
370
				if (fieldConstant != Constant.NotAConstant) {
370
					if (!isStatic){
371
					if (!isStatic){
371
						codeStream.invokeObjectGetClass();
372
						codeStream.invokeObjectGetClass();
372
						codeStream.pop();
373
						codeStream.pop();
373
					}
374
					}
374
					if (valueRequired) { // inline the last field constant
375
					if (valueRequired) { // inline the last field constant
375
						codeStream.generateConstant(lastFieldBinding.constant(), implicitConversion);
376
						codeStream.generateConstant(fieldConstant, implicitConversion);
376
					}
377
					}
377
				} else {
378
				} else {
378
					if (valueRequired  || currentScope.compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4) {
379
					if (valueRequired  || currentScope.compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4) {
Lines 554-560 Link Here
554
				lastFieldBinding = (FieldBinding) this.codegenBinding;
555
				lastFieldBinding = (FieldBinding) this.codegenBinding;
555
				lastGenericCast = this.genericCast;
556
				lastGenericCast = this.genericCast;
556
				// if first field is actually constant, we can inline it
557
				// if first field is actually constant, we can inline it
557
				if (lastFieldBinding.isConstantValue()) {
558
				if (lastFieldBinding.constant() != Constant.NotAConstant) {
558
					break;
559
					break;
559
				}
560
				}
560
				if ((needValue || complyTo14) && !lastFieldBinding.isStatic()) {
561
				if ((needValue || complyTo14) && !lastFieldBinding.isStatic()) {
Lines 573-580 Link Here
573
				if (!needValue) break; // no value needed
574
				if (!needValue) break; // no value needed
574
				LocalVariableBinding localBinding = (LocalVariableBinding) this.codegenBinding;
575
				LocalVariableBinding localBinding = (LocalVariableBinding) this.codegenBinding;
575
				// regular local variable read
576
				// regular local variable read
576
				if (localBinding.isConstantValue()) {
577
				Constant localConstant = localBinding.constant();
577
					codeStream.generateConstant(localBinding.constant(), 0);
578
				if (localConstant != Constant.NotAConstant) {
579
					codeStream.generateConstant(localConstant, 0);
578
					// no implicit conversion
580
					// no implicit conversion
579
				} else {
581
				} else {
580
					// outer local?
582
					// outer local?
Lines 596-608 Link Here
596
				TypeBinding nextGenericCast = this.otherGenericCasts == null ? null : this.otherGenericCasts[i];
598
				TypeBinding nextGenericCast = this.otherGenericCasts == null ? null : this.otherGenericCasts[i];
597
				if (lastFieldBinding != null) {
599
				if (lastFieldBinding != null) {
598
					needValue = !nextField.isStatic();
600
					needValue = !nextField.isStatic();
599
					if (lastFieldBinding.isConstantValue()) {
601
					Constant fieldConstant = lastFieldBinding.constant();
602
					if (fieldConstant != Constant.NotAConstant) {
600
						if (lastFieldBinding != this.codegenBinding && !lastFieldBinding.isStatic()) {
603
						if (lastFieldBinding != this.codegenBinding && !lastFieldBinding.isStatic()) {
601
							codeStream.invokeObjectGetClass(); // perform null check
604
							codeStream.invokeObjectGetClass(); // perform null check
602
							codeStream.pop();
605
							codeStream.pop();
603
						}
606
						}
604
						if (needValue) {
607
						if (needValue) {
605
							codeStream.generateConstant(lastFieldBinding.constant(), 0);
608
							codeStream.generateConstant(fieldConstant, 0);
606
						}
609
						}
607
					} else {
610
					} else {
608
						if (needValue || complyTo14) {
611
						if (needValue || complyTo14) {
Lines 694-700 Link Here
694
		TypeBinding type = ((VariableBinding) binding).type;
697
		TypeBinding type = ((VariableBinding) binding).type;
695
		int index = indexOfFirstFieldBinding;
698
		int index = indexOfFirstFieldBinding;
696
		if (index == length) { //	restrictiveFlag == FIELD
699
		if (index == length) { //	restrictiveFlag == FIELD
697
			this.constant = FieldReference.getConstantFor((FieldBinding) binding, this, false, scope);
700
			this.constant = ((FieldBinding) binding).constant();
698
			// perform capture conversion if read access
701
			// perform capture conversion if read access
699
			return (type != null && (this.bits & IsStrictlyAssignedMASK) == 0)
702
			return (type != null && (this.bits & IsStrictlyAssignedMASK) == 0)
700
					? type.capture(scope, this.sourceEnd)
703
					? type.capture(scope, this.sourceEnd)
Lines 706-714 Link Here
706
		otherDepths = new int[otherBindingsLength];
709
		otherDepths = new int[otherBindingsLength];
707
		
710
		
708
		// fill the first constant (the one of the binding)
711
		// fill the first constant (the one of the binding)
709
		this.constant = field != null
712
		this.constant = ((VariableBinding) binding).constant();
710
				? FieldReference.getConstantFor((FieldBinding) binding, this, false, scope)
711
				: ((VariableBinding) binding).constant();
712
		// save first depth, since will be updated by visibility checks of other bindings
713
		// save first depth, since will be updated by visibility checks of other bindings
713
		int firstDepth = (bits & DepthMASK) >> DepthSHIFT;
714
		int firstDepth = (bits & DepthMASK) >> DepthSHIFT;
714
		// iteration on each field	
715
		// iteration on each field	
Lines 743-752 Link Here
743
				if (isFieldUseDeprecated(field, scope, (this.bits & IsStrictlyAssignedMASK) !=0 && index+1 == length)) {
744
				if (isFieldUseDeprecated(field, scope, (this.bits & IsStrictlyAssignedMASK) !=0 && index+1 == length)) {
744
					scope.problemReporter().deprecatedField(field, this);
745
					scope.problemReporter().deprecatedField(field, this);
745
				}
746
				}
746
				Constant someConstant = FieldReference.getConstantFor(field, this, false, scope);
747
				// constant propagation can only be performed as long as the previous one is a constant too.
747
				// constant propagation can only be performed as long as the previous one is a constant too.
748
				if (this.constant != NotAConstant) {
748
				if (this.constant != Constant.NotAConstant) {
749
					this.constant = someConstant;					
749
					this.constant = field.constant();					
750
				}
750
				}
751
751
752
				if (field.isStatic()) {
752
				if (field.isStatic()) {
Lines 795-801 Link Here
795
	    
795
	    
796
		if (!flowInfo.isReachable()) return;
796
		if (!flowInfo.isReachable()) return;
797
		// index == 0 denotes the first fieldBinding, index > 0 denotes one of the 'otherBindings', index < 0 denotes a write access (to last binding)
797
		// index == 0 denotes the first fieldBinding, index > 0 denotes one of the 'otherBindings', index < 0 denotes a write access (to last binding)
798
		if (fieldBinding.isConstantValue())
798
		if (fieldBinding.constant() != Constant.NotAConstant)
799
			return;
799
			return;
800
800
801
		// if field from parameterized type got found, use the original field at codegen time
801
		// if field from parameterized type got found, use the original field at codegen time
Lines 833-839 Link Here
833
		if (fieldBinding.declaringClass != lastReceiverType
833
		if (fieldBinding.declaringClass != lastReceiverType
834
				&& !lastReceiverType.isArrayType()
834
				&& !lastReceiverType.isArrayType()
835
				&& fieldBinding.declaringClass != null // array.length
835
				&& fieldBinding.declaringClass != null // array.length
836
				&& !fieldBinding.isConstantValue()) {
836
				&& fieldBinding.constant() == Constant.NotAConstant) {
837
			CompilerOptions options = currentScope.compilerOptions();
837
			CompilerOptions options = currentScope.compilerOptions();
838
			if ((options.targetJDK >= ClassFileConstants.JDK1_2
838
			if ((options.targetJDK >= ClassFileConstants.JDK1_2
839
					&& (options.complianceLevel >= ClassFileConstants.JDK1_4 || !(index <= 1 &&  indexOfFirstFieldBinding == 1 && fieldBinding.isStatic()))
839
					&& (options.complianceLevel >= ClassFileConstants.JDK1_4 || !(index <= 1 &&  indexOfFirstFieldBinding == 1 && fieldBinding.isStatic()))
(-)compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java (-4 / +5 lines)
Lines 188-194 Link Here
188
				return fieldBinding.type;
188
				return fieldBinding.type;
189
			}
189
			}
190
		}
190
		}
191
		this.constant = FieldReference.getConstantFor(fieldBinding, this, true, scope);
191
		this.constant = fieldBinding.constant();
192
	
192
	
193
		if (isFieldUseDeprecated(fieldBinding, scope, (this.bits & IsStrictlyAssignedMASK) !=0))
193
		if (isFieldUseDeprecated(fieldBinding, scope, (this.bits & IsStrictlyAssignedMASK) !=0))
194
			scope.problemReporter().deprecatedField(fieldBinding, this);
194
			scope.problemReporter().deprecatedField(fieldBinding, this);
Lines 334-343 Link Here
334
			switch (bits & RestrictiveFlagMASK) {
334
			switch (bits & RestrictiveFlagMASK) {
335
				case Binding.FIELD : // reading a field
335
				case Binding.FIELD : // reading a field
336
					FieldBinding fieldBinding = (FieldBinding) this.codegenBinding;
336
					FieldBinding fieldBinding = (FieldBinding) this.codegenBinding;
337
					if (fieldBinding.isConstantValue()) {
337
					Constant fieldConstant = fieldBinding.constant();
338
					if (fieldConstant != Constant.NotAConstant) {
338
						// directly use inlined value for constant fields
339
						// directly use inlined value for constant fields
339
						if (valueRequired) {
340
						if (valueRequired) {
340
							codeStream.generateConstant(fieldBinding.constant(), implicitConversion);
341
							codeStream.generateConstant(fieldConstant, implicitConversion);
341
						}
342
						}
342
					} else {
343
					} else {
343
						if (valueRequired) {
344
						if (valueRequired) {
Lines 659-665 Link Here
659
			if (fieldBinding.declaringClass != this.actualReceiverType
660
			if (fieldBinding.declaringClass != this.actualReceiverType
660
					&& !this.actualReceiverType.isArrayType()
661
					&& !this.actualReceiverType.isArrayType()
661
					&& fieldBinding.declaringClass != null // array.length
662
					&& fieldBinding.declaringClass != null // array.length
662
					&& !fieldBinding.isConstantValue()) {
663
					&& fieldBinding.constant() == Constant.NotAConstant) {
663
				CompilerOptions options = currentScope.compilerOptions();
664
				CompilerOptions options = currentScope.compilerOptions();
664
				if ((options.targetJDK >= ClassFileConstants.JDK1_2
665
				if ((options.targetJDK >= ClassFileConstants.JDK1_2
665
						&& (options.complianceLevel >= ClassFileConstants.JDK1_4 || !fieldBinding.isStatic())
666
						&& (options.complianceLevel >= ClassFileConstants.JDK1_4 || !fieldBinding.isStatic())
(-)compiler/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo.java (-3 / +4 lines)
Lines 10-15 Link Here
10
 *******************************************************************************/
10
 *******************************************************************************/
11
package org.eclipse.jdt.internal.compiler.flow;
11
package org.eclipse.jdt.internal.compiler.flow;
12
12
13
import org.eclipse.jdt.internal.compiler.impl.Constant;
13
import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
14
import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
14
import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
15
import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
15
import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
16
import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
Lines 385-391 Link Here
385
			return true;
386
			return true;
386
387
387
		// final constants are inlined, and thus considered as always initialized
388
		// final constants are inlined, and thus considered as always initialized
388
		if (local.isConstantValue()) {
389
		if (local.constant() != Constant.NotAConstant) {
389
			return true;
390
			return true;
390
		}
391
		}
391
		return isDefinitelyAssigned(local.id + maxFieldCount);
392
		return isDefinitelyAssigned(local.id + maxFieldCount);
Lines 413-419 Link Here
413
		if ((this.reachMode & UNREACHABLE) != 0)
414
		if ((this.reachMode & UNREACHABLE) != 0)
414
			return false;
415
			return false;
415
		// final constants are inlined, and thus considered as always initialized
416
		// final constants are inlined, and thus considered as always initialized
416
		if (local.isConstantValue()) {
417
		if (local.constant() != Constant.NotAConstant) {
417
			return true;
418
			return true;
418
		}
419
		}
419
		return isDefinitelyNonNull(local.id + maxFieldCount);
420
		return isDefinitelyNonNull(local.id + maxFieldCount);
Lines 483-489 Link Here
483
	final public boolean isPotentiallyAssigned(LocalVariableBinding local) {
484
	final public boolean isPotentiallyAssigned(LocalVariableBinding local) {
484
		
485
		
485
		// final constants are inlined, and thus considered as always initialized
486
		// final constants are inlined, and thus considered as always initialized
486
		if (local.isConstantValue()) {
487
		if (local.constant() != Constant.NotAConstant) {
487
			return true;
488
			return true;
488
		}
489
		}
489
		return isPotentiallyAssigned(local.id + maxFieldCount);
490
		return isPotentiallyAssigned(local.id + maxFieldCount);
(-)compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java (-1 / +2 lines)
Lines 14-19 Link Here
14
import org.eclipse.jdt.internal.compiler.ast.*;
14
import org.eclipse.jdt.internal.compiler.ast.*;
15
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
15
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
16
import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
16
import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
17
import org.eclipse.jdt.internal.compiler.impl.Constant;
17
import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
18
import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
18
19
19
public class BlockScope extends Scope {
20
public class BlockScope extends Scope {
Lines 221-227 Link Here
221
				LocalVariableBinding local = locals[ilocal]; // if no local at all, will be locals[ilocal]==null
222
				LocalVariableBinding local = locals[ilocal]; // if no local at all, will be locals[ilocal]==null
222
				
223
				
223
				// check if variable is actually used, and may force it to be preserved
224
				// check if variable is actually used, and may force it to be preserved
224
				boolean generateCurrentLocalVar = (local.useFlag == LocalVariableBinding.USED && !local.isConstantValue());
225
				boolean generateCurrentLocalVar = (local.useFlag == LocalVariableBinding.USED && local.constant() == Constant.NotAConstant);
225
					
226
					
226
				// do not report fake used variable
227
				// do not report fake used variable
227
				if (local.useFlag == LocalVariableBinding.UNUSED
228
				if (local.useFlag == LocalVariableBinding.UNUSED
(-)compiler/org/eclipse/jdt/internal/compiler/lookup/FieldBinding.java (+33 lines)
Lines 179-184 Link Here
179
	System.arraycopy(returnTypeKey, 0, uniqueKey, index, returnTypeLength);
179
	System.arraycopy(returnTypeKey, 0, uniqueKey, index, returnTypeLength);
180
	return uniqueKey;
180
	return uniqueKey;
181
}
181
}
182
183
public Constant constant() {
184
	Constant fieldConstant = this.constant;
185
	if (fieldConstant == null) {
186
		if (this.isFinal()) {
187
			//The field has not been yet type checked.
188
			//It also means that the field is not coming from a class that
189
			//has already been compiled. It can only be from a class within
190
			//compilation units to process. Thus the field is NOT from a BinaryTypeBinbing
191
			FieldBinding originalField = this.original();
192
			if (originalField.declaringClass instanceof SourceTypeBinding) {
193
				SourceTypeBinding sourceType = (SourceTypeBinding) originalField.declaringClass;
194
				if (sourceType.scope != null) {
195
					TypeDeclaration typeDecl = sourceType.scope.referenceContext;
196
					FieldDeclaration fieldDecl = typeDecl.declarationOf(originalField);
197
					fieldDecl.resolve(originalField.isStatic() //side effect on binding 
198
							? typeDecl.staticInitializerScope
199
							: typeDecl.initializerScope);
200
					fieldConstant = originalField.constant();
201
				} else {
202
					fieldConstant = Constant.NotAConstant; // shouldn't occur per construction (paranoid null check)
203
				} 
204
			} else {
205
				fieldConstant = Constant.NotAConstant; // shouldn't occur per construction (paranoid null check)
206
			}
207
		} else {
208
			fieldConstant = Constant.NotAConstant;
209
		}
210
		this.constant = fieldConstant;
211
	}
212
	return fieldConstant;
213
}
214
182
/**
215
/**
183
 * X<T> t   -->  LX<TT;>;
216
 * X<T> t   -->  LX<TT;>;
184
 */
217
 */
(-)compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedFieldBinding.java (-6 / +1 lines)
Lines 42-53 Link Here
42
	public Constant constant() {
42
	public Constant constant() {
43
		return this.originalField.constant();
43
		return this.originalField.constant();
44
	}
44
	}
45
	/**
45
46
	 * @see org.eclipse.jdt.internal.compiler.lookup.VariableBinding#isConstantValue()
47
	 */
48
	public boolean isConstantValue() {
49
		return this.originalField.isConstantValue();
50
	}
51
	/**
46
	/**
52
	 * @see org.eclipse.jdt.internal.compiler.lookup.FieldBinding#original()
47
	 * @see org.eclipse.jdt.internal.compiler.lookup.FieldBinding#original()
53
	 */
48
	 */
(-)compiler/org/eclipse/jdt/internal/compiler/lookup/VariableBinding.java (-7 / +1 lines)
Lines 17-23 Link Here
17
	public int modifiers;
17
	public int modifiers;
18
	public TypeBinding type;
18
	public TypeBinding type;
19
	public char[] name;
19
	public char[] name;
20
	private Constant constant;
20
	protected Constant constant;
21
	public int id; // for flow-analysis (position in flowInfo bit vector)
21
	public int id; // for flow-analysis (position in flowInfo bit vector)
22
	public long tagBits;
22
	public long tagBits;
23
23
Lines 35-46 Link Here
35
	public final boolean isBlankFinal(){
35
	public final boolean isBlankFinal(){
36
		return (modifiers & AccBlankFinal) != 0;
36
		return (modifiers & AccBlankFinal) != 0;
37
	}
37
	}
38
	/* Answer true if the receiver is final and cannot be changed
39
	*/
40
	
41
	public boolean isConstantValue() {
42
		return constant != Constant.NotAConstant;
43
	}
44
	
38
	
45
	public final boolean isFinal() {
39
	public final boolean isFinal() {
46
		return (modifiers & AccFinal) != 0;
40
		return (modifiers & AccFinal) != 0;
(-)dom/org/eclipse/jdt/core/dom/VariableBinding.java (-2 / +1 lines)
Lines 46-54 Link Here
46
	 * @since 3.0
46
	 * @since 3.0
47
	 */
47
	 */
48
	public Object getConstantValue() {
48
	public Object getConstantValue() {
49
		if (!this.binding.isConstantValue()) return null;
50
		Constant c = this.binding.constant();
49
		Constant c = this.binding.constant();
51
		if (c == null) return null;
50
		if (c == null || c == Constant.NotAConstant) return null;
52
		switch (c.typeID()) {
51
		switch (c.typeID()) {
53
			case TypeIds.T_boolean:
52
			case TypeIds.T_boolean:
54
				return Boolean.valueOf(c.booleanValue());
53
				return Boolean.valueOf(c.booleanValue());
(-)eval/org/eclipse/jdt/internal/eval/CodeSnippetClassFile.java (-6 lines)
Lines 14-20 Link Here
14
import org.eclipse.jdt.internal.compiler.ClassFile;
14
import org.eclipse.jdt.internal.compiler.ClassFile;
15
import org.eclipse.jdt.internal.compiler.CompilationResult;
15
import org.eclipse.jdt.internal.compiler.CompilationResult;
16
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
16
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
17
import org.eclipse.jdt.internal.compiler.ast.FieldReference;
18
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
17
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
19
import org.eclipse.jdt.internal.compiler.codegen.ConstantPool;
18
import org.eclipse.jdt.internal.compiler.codegen.ConstantPool;
20
import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
19
import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
Lines 140-150 Link Here
140
	// add its fields
139
	// add its fields
141
	FieldBinding[] fields = typeBinding.fields;
140
	FieldBinding[] fields = typeBinding.fields;
142
	if ((fields != null) && (fields != NoFields)) {
141
	if ((fields != null) && (fields != NoFields)) {
143
		for (int i = 0, max = fields.length; i < max; i++) {
144
			if (fields[i].constant() == null) {
145
				FieldReference.getConstantFor(fields[i], null, false, null);
146
			}
147
		}
148
		classFile.addFieldInfos();
142
		classFile.addFieldInfos();
149
	} else {
143
	} else {
150
		// we have to set the number of fields to be equals to 0
144
		// we have to set the number of fields to be equals to 0
(-)eval/org/eclipse/jdt/internal/eval/CodeSnippetFieldReference.java (-4 / +6 lines)
Lines 19-24 Link Here
19
import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
19
import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
20
import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
20
import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
21
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
21
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
22
import org.eclipse.jdt.internal.compiler.impl.Constant;
22
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
23
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
23
import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
24
import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
24
import org.eclipse.jdt.internal.compiler.lookup.ParameterizedFieldBinding;
25
import org.eclipse.jdt.internal.compiler.lookup.ParameterizedFieldBinding;
Lines 85-91 Link Here
85
		boolean isStatic = this.codegenBinding.isStatic();
86
		boolean isStatic = this.codegenBinding.isStatic();
86
		this.receiver.generateCode(currentScope, codeStream, !isStatic);
87
		this.receiver.generateCode(currentScope, codeStream, !isStatic);
87
		if (valueRequired) {
88
		if (valueRequired) {
88
			if (!this.codegenBinding.isConstantValue()) {
89
			Constant fieldConstant = this.codegenBinding.constant();
90
			if (fieldConstant == Constant.NotAConstant) {
89
				if (this.codegenBinding.declaringClass == null) { // array length
91
				if (this.codegenBinding.declaringClass == null) { // array length
90
					codeStream.arraylength();
92
					codeStream.arraylength();
91
				} else {
93
				} else {
Lines 109-115 Link Here
109
					codeStream.invokeObjectGetClass(); // perform null check
111
					codeStream.invokeObjectGetClass(); // perform null check
110
					codeStream.pop();
112
					codeStream.pop();
111
				}
113
				}
112
				codeStream.generateConstant(this.codegenBinding.constant(), this.implicitConversion);
114
				codeStream.generateConstant(fieldConstant, this.implicitConversion);
113
			}
115
			}
114
		} else {
116
		} else {
115
			if (!isStatic){
117
			if (!isStatic){
Lines 313-319 Link Here
313
	if (this.binding.declaringClass != someReceiverType
315
	if (this.binding.declaringClass != someReceiverType
314
			&& !someReceiverType.isArrayType()
316
			&& !someReceiverType.isArrayType()
315
			&& this.binding.declaringClass != null // array.length
317
			&& this.binding.declaringClass != null // array.length
316
			&& !this.binding.isConstantValue()) {
318
			&& this.binding.constant() == Constant.NotAConstant) {
317
	
319
	
318
		CompilerOptions options = currentScope.compilerOptions();
320
		CompilerOptions options = currentScope.compilerOptions();
319
		if ((options.targetJDK >= ClassFileConstants.JDK1_2
321
		if ((options.targetJDK >= ClassFileConstants.JDK1_2
Lines 377-383 Link Here
377
		scope.problemReporter().deprecatedField(this.binding, this);
379
		scope.problemReporter().deprecatedField(this.binding, this);
378
	}
380
	}
379
	// check for this.x in static is done in the resolution of the receiver
381
	// check for this.x in static is done in the resolution of the receiver
380
	this.constant = FieldReference.getConstantFor(this.binding, this, this.receiver.isImplicitThis(), scope);
382
	this.constant = this.receiver.isImplicitThis() ? this.binding.constant() : Constant.NotAConstant;
381
	if (!this.receiver.isThis()) {
383
	if (!this.receiver.isThis()) {
382
		this.constant = NotAConstant;
384
		this.constant = NotAConstant;
383
	}
385
	}
(-)eval/org/eclipse/jdt/internal/eval/CodeSnippetQualifiedNameReference.java (-17 / +15 lines)
Lines 13-19 Link Here
13
import org.eclipse.jdt.internal.compiler.ast.Assignment;
13
import org.eclipse.jdt.internal.compiler.ast.Assignment;
14
import org.eclipse.jdt.internal.compiler.ast.CompoundAssignment;
14
import org.eclipse.jdt.internal.compiler.ast.CompoundAssignment;
15
import org.eclipse.jdt.internal.compiler.ast.Expression;
15
import org.eclipse.jdt.internal.compiler.ast.Expression;
16
import org.eclipse.jdt.internal.compiler.ast.FieldReference;
17
import org.eclipse.jdt.internal.compiler.ast.IntLiteral;
16
import org.eclipse.jdt.internal.compiler.ast.IntLiteral;
18
import org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference;
17
import org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference;
19
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
18
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
Lines 95-107 Link Here
95
				codeStream.arraylength();
94
				codeStream.arraylength();
96
				codeStream.generateImplicitConversion(this.implicitConversion);
95
				codeStream.generateImplicitConversion(this.implicitConversion);
97
			} else {
96
			} else {
98
				if (lastFieldBinding.isConstantValue()) {
97
				Constant fieldConstant = lastFieldBinding.constant();
98
				if (fieldConstant != Constant.NotAConstant) {
99
					if (!lastFieldBinding.isStatic()){
99
					if (!lastFieldBinding.isStatic()){
100
						codeStream.invokeObjectGetClass();
100
						codeStream.invokeObjectGetClass();
101
						codeStream.pop();
101
						codeStream.pop();
102
					}
102
					}
103
					// inline the last field constant
103
					// inline the last field constant
104
					codeStream.generateConstant(lastFieldBinding.constant(), this.implicitConversion);
104
					codeStream.generateConstant(fieldConstant, this.implicitConversion);
105
				} else {	
105
				} else {	
106
					if (lastFieldBinding.canBeSeenBy(getReceiverType(currentScope), this, currentScope)) {
106
					if (lastFieldBinding.canBeSeenBy(getReceiverType(currentScope), this, currentScope)) {
107
						if (lastFieldBinding.isStatic()) {
107
						if (lastFieldBinding.isStatic()) {
Lines 294-300 Link Here
294
			lastFieldBinding = (FieldBinding) this.codegenBinding;
294
			lastFieldBinding = (FieldBinding) this.codegenBinding;
295
			lastGenericCast = this.genericCast;
295
			lastGenericCast = this.genericCast;
296
			// if first field is actually constant, we can inline it
296
			// if first field is actually constant, we can inline it
297
			if (lastFieldBinding.isConstantValue()) {
297
			if (lastFieldBinding.constant() != Constant.NotAConstant) {
298
				break;
298
				break;
299
			}
299
			}
300
			if (needValue) {
300
			if (needValue) {
Lines 327-334 Link Here
327
			if (!needValue) break; // no value needed
327
			if (!needValue) break; // no value needed
328
			LocalVariableBinding localBinding = (LocalVariableBinding) this.codegenBinding;
328
			LocalVariableBinding localBinding = (LocalVariableBinding) this.codegenBinding;
329
			// regular local variable read
329
			// regular local variable read
330
			if (localBinding.isConstantValue()) {
330
			Constant localConstant = localBinding.constant();
331
				codeStream.generateConstant(localBinding.constant(), 0);
331
			if (localConstant != Constant.NotAConstant) {
332
				codeStream.generateConstant(localConstant, 0);
332
				// no implicit conversion
333
				// no implicit conversion
333
			} else {
334
			} else {
334
				// outer local?
335
				// outer local?
Lines 352-363 Link Here
352
				needValue = !nextField.isStatic();
353
				needValue = !nextField.isStatic();
353
				if (needValue) {
354
				if (needValue) {
354
					if (lastFieldBinding.canBeSeenBy(getReceiverType(currentScope), this, currentScope)) {
355
					if (lastFieldBinding.canBeSeenBy(getReceiverType(currentScope), this, currentScope)) {
355
						if (lastFieldBinding.isConstantValue()) {
356
						Constant fieldConstant = lastFieldBinding.constant();
357
						if (fieldConstant != Constant.NotAConstant) {
356
							if (lastFieldBinding != this.codegenBinding && !lastFieldBinding.isStatic()) {
358
							if (lastFieldBinding != this.codegenBinding && !lastFieldBinding.isStatic()) {
357
								codeStream.invokeObjectGetClass(); // perform null check
359
								codeStream.invokeObjectGetClass(); // perform null check
358
								codeStream.pop();
360
								codeStream.pop();
359
							}
361
							}
360
							codeStream.generateConstant(lastFieldBinding.constant(), 0);
362
							codeStream.generateConstant(fieldConstant, 0);
361
						} else if (lastFieldBinding.isStatic()) {
363
						} else if (lastFieldBinding.isStatic()) {
362
							codeStream.getstatic(lastFieldBinding);
364
							codeStream.getstatic(lastFieldBinding);
363
						} else {
365
						} else {
Lines 418-424 Link Here
418
	TypeBinding type = ((VariableBinding) this.binding).type;
420
	TypeBinding type = ((VariableBinding) this.binding).type;
419
	int index = this.indexOfFirstFieldBinding;
421
	int index = this.indexOfFirstFieldBinding;
420
	if (index == length) { //	restrictiveFlag == FIELD
422
	if (index == length) { //	restrictiveFlag == FIELD
421
		this.constant = FieldReference.getConstantFor((FieldBinding) this.binding, this, false, scope);
423
		this.constant = ((FieldBinding) this.binding).constant();
422
		return type;
424
		return type;
423
	}
425
	}
424
426
Lines 427-436 Link Here
427
	this.otherCodegenBindings = this.otherBindings = new FieldBinding[otherBindingsLength];
429
	this.otherCodegenBindings = this.otherBindings = new FieldBinding[otherBindingsLength];
428
	
430
	
429
	// fill the first constant (the one of the binding)
431
	// fill the first constant (the one of the binding)
430
	this.constant =
432
	this.constant =((VariableBinding) this.binding).constant();
431
		((this.bits & Binding.FIELD) != 0)
432
			? FieldReference.getConstantFor((FieldBinding) this.binding, this, false, scope)
433
			: ((VariableBinding) this.binding).constant();
434
433
435
	// iteration on each field	
434
	// iteration on each field	
436
	while (index < length) {
435
	while (index < length) {
Lines 462-471 Link Here
462
			if (isFieldUseDeprecated(field, scope, (this.bits & IsStrictlyAssignedMASK) !=0 && index+1 == length)) {
461
			if (isFieldUseDeprecated(field, scope, (this.bits & IsStrictlyAssignedMASK) !=0 && index+1 == length)) {
463
				scope.problemReporter().deprecatedField(field, this);
462
				scope.problemReporter().deprecatedField(field, this);
464
			}
463
			}
465
			Constant someConstant = FieldReference.getConstantFor(field, this, false, scope);
466
			// constant propagation can only be performed as long as the previous one is a constant too.
464
			// constant propagation can only be performed as long as the previous one is a constant too.
467
			if (this.constant != NotAConstant){
465
			if (this.constant != Constant.NotAConstant){
468
				this.constant = someConstant;
466
				this.constant = field.constant();
469
			}
467
			}
470
			type = field.type;
468
			type = field.type;
471
			index++;
469
			index++;
Lines 523-529 Link Here
523
		if (fieldBinding.declaringClass != lastReceiverType
521
		if (fieldBinding.declaringClass != lastReceiverType
524
				&& !lastReceiverType.isArrayType()
522
				&& !lastReceiverType.isArrayType()
525
				&& fieldBinding.declaringClass != null // array.length
523
				&& fieldBinding.declaringClass != null // array.length
526
				&& !fieldBinding.isConstantValue()) {
524
				&& fieldBinding.constant() == Constant.NotAConstant) {
527
			CompilerOptions options = currentScope.compilerOptions();
525
			CompilerOptions options = currentScope.compilerOptions();
528
			if ((options.targetJDK >= ClassFileConstants.JDK1_2
526
			if ((options.targetJDK >= ClassFileConstants.JDK1_2
529
					&& (options.complianceLevel >= ClassFileConstants.JDK1_4 || (index < 0 ? fieldBinding != binding : index > 0) || this.indexOfFirstFieldBinding > 1 || !fieldBinding.isStatic())
527
					&& (options.complianceLevel >= ClassFileConstants.JDK1_4 || (index < 0 ? fieldBinding != binding : index > 0) || this.indexOfFirstFieldBinding > 1 || !fieldBinding.isStatic())
(-)eval/org/eclipse/jdt/internal/eval/CodeSnippetSingleNameReference.java (-6 / +6 lines)
Lines 14-20 Link Here
14
import org.eclipse.jdt.internal.compiler.ast.BinaryExpression;
14
import org.eclipse.jdt.internal.compiler.ast.BinaryExpression;
15
import org.eclipse.jdt.internal.compiler.ast.CompoundAssignment;
15
import org.eclipse.jdt.internal.compiler.ast.CompoundAssignment;
16
import org.eclipse.jdt.internal.compiler.ast.Expression;
16
import org.eclipse.jdt.internal.compiler.ast.Expression;
17
import org.eclipse.jdt.internal.compiler.ast.FieldReference;
18
import org.eclipse.jdt.internal.compiler.ast.IntLiteral;
17
import org.eclipse.jdt.internal.compiler.ast.IntLiteral;
19
import org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
18
import org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
20
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
19
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
Lines 97-103 Link Here
97
			return null;
96
			return null;
98
		}
97
		}
99
	}
98
	}
100
	this.constant = FieldReference.getConstantFor(fieldBinding, this, true, scope);
99
	this.constant = fieldBinding.constant();
101
100
102
	if (isFieldUseDeprecated(fieldBinding, scope, (this.bits & IsStrictlyAssignedMASK) !=0)) {
101
	if (isFieldUseDeprecated(fieldBinding, scope, (this.bits & IsStrictlyAssignedMASK) !=0)) {
103
		scope.problemReporter().deprecatedField(fieldBinding, this);
102
		scope.problemReporter().deprecatedField(fieldBinding, this);
Lines 225-233 Link Here
225
	} else {
224
	} else {
226
		switch (this.bits & RestrictiveFlagMASK) {
225
		switch (this.bits & RestrictiveFlagMASK) {
227
			case Binding.FIELD : // reading a field
226
			case Binding.FIELD : // reading a field
228
				FieldBinding fieldBinding;
229
				if (valueRequired) {
227
				if (valueRequired) {
230
					if (!(fieldBinding = (FieldBinding) this.codegenBinding).isConstantValue()) { // directly use inlined value for constant fields
228
					FieldBinding fieldBinding = (FieldBinding) this.codegenBinding;
229
					Constant fieldConstant = fieldBinding.constant();
230
					if (fieldConstant == Constant.NotAConstant) { // directly use inlined value for constant fields
231
						if (fieldBinding.canBeSeenBy(getReceiverType(currentScope), this, currentScope)) {
231
						if (fieldBinding.canBeSeenBy(getReceiverType(currentScope), this, currentScope)) {
232
							 // directly use inlined value for constant fields
232
							 // directly use inlined value for constant fields
233
							boolean isStatic;
233
							boolean isStatic;
Lines 264-270 Link Here
264
						if (this.genericCast != null) codeStream.checkcast(this.genericCast);		
264
						if (this.genericCast != null) codeStream.checkcast(this.genericCast);		
265
						codeStream.generateImplicitConversion(this.implicitConversion);
265
						codeStream.generateImplicitConversion(this.implicitConversion);
266
					} else { // directly use the inlined value
266
					} else { // directly use the inlined value
267
						codeStream.generateConstant(fieldBinding.constant(), this.implicitConversion);
267
						codeStream.generateConstant(fieldConstant, this.implicitConversion);
268
					}
268
					}
269
				}
269
				}
270
				break;
270
				break;
Lines 589-595 Link Here
589
		// and not from Object or implicit static field access.	
589
		// and not from Object or implicit static field access.	
590
		if (fieldBinding.declaringClass != this.delegateThis.type
590
		if (fieldBinding.declaringClass != this.delegateThis.type
591
				&& fieldBinding.declaringClass != null // array.length
591
				&& fieldBinding.declaringClass != null // array.length
592
				&& !fieldBinding.isConstantValue()) {
592
				&& fieldBinding.constant() == Constant.NotAConstant) {
593
			CompilerOptions options = currentScope.compilerOptions();
593
			CompilerOptions options = currentScope.compilerOptions();
594
			if ((options.targetJDK >= ClassFileConstants.JDK1_2
594
			if ((options.targetJDK >= ClassFileConstants.JDK1_2
595
					&& (options.complianceLevel >= ClassFileConstants.JDK1_4 || !fieldBinding.isStatic())
595
					&& (options.complianceLevel >= ClassFileConstants.JDK1_4 || !fieldBinding.isStatic())

Return to bug 61946