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

Collapse All | Expand All

(-)compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java (-1 / +1 lines)
Lines 1065-1071 Link Here
1065
public ReferenceBinding[] memberTypes() {
1065
public ReferenceBinding[] memberTypes() {
1066
	return this.memberTypes;
1066
	return this.memberTypes;
1067
}
1067
}
1068
///** @deprecated */
1068
/** @deprecated */
1069
public FieldBinding getUpdatedFieldBinding(FieldBinding targetField, ReferenceBinding newDeclaringClass) {
1069
public FieldBinding getUpdatedFieldBinding(FieldBinding targetField, ReferenceBinding newDeclaringClass) {
1070
	if (this.synthetics == null)
1070
	if (this.synthetics == null)
1071
		this.synthetics = new HashMap[MAX_SYNTHETICS];
1071
		this.synthetics = new HashMap[MAX_SYNTHETICS];
(-)compiler/org/eclipse/jdt/internal/compiler/ast/Clinit.java (-3 / +4 lines)
Lines 16-21 Link Here
16
import org.eclipse.jdt.internal.compiler.codegen.BranchLabel;
16
import org.eclipse.jdt.internal.compiler.codegen.BranchLabel;
17
import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
17
import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
18
import org.eclipse.jdt.internal.compiler.codegen.ConstantPool;
18
import org.eclipse.jdt.internal.compiler.codegen.ConstantPool;
19
import org.eclipse.jdt.internal.compiler.codegen.Opcodes;
19
import org.eclipse.jdt.internal.compiler.flow.ExceptionHandlingFlowContext;
20
import org.eclipse.jdt.internal.compiler.flow.ExceptionHandlingFlowContext;
20
import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
21
import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
21
import org.eclipse.jdt.internal.compiler.flow.InitializationFlowContext;
22
import org.eclipse.jdt.internal.compiler.flow.InitializationFlowContext;
Lines 173-179 Link Here
173
			falseLabel.place();
174
			falseLabel.place();
174
			codeStream.iconst_0();
175
			codeStream.iconst_0();
175
			jumpLabel.place();
176
			jumpLabel.place();
176
			codeStream.putstatic(this.assertionSyntheticFieldBinding);
177
			codeStream.fieldAccess0(Opcodes.OPC_putstatic, this.assertionSyntheticFieldBinding, null /* default declaringClass */);
177
		}
178
		}
178
		// generate static fields/initializers/enum constants
179
		// generate static fields/initializers/enum constants
179
		final FieldDeclaration[] fieldDeclarations = declaringType.fields;
180
		final FieldDeclaration[] fieldDeclarations = declaringType.fields;
Lines 206-218 Link Here
206
						if (fieldDecl.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT) {
207
						if (fieldDecl.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT) {
207
							codeStream.dup();
208
							codeStream.dup();
208
							codeStream.generateInlinedValue(fieldDecl.binding.id);
209
							codeStream.generateInlinedValue(fieldDecl.binding.id);
209
							codeStream.getstatic(fieldDecl.binding);
210
							codeStream.fieldAccess0(Opcodes.OPC_getstatic, fieldDecl.binding, null /* default declaringClass */);
210
							codeStream.aastore();
211
							codeStream.aastore();
211
						}
212
						}
212
					}
213
					}
213
				}
214
				}
214
			}
215
			}
215
			codeStream.putstatic(declaringType.enumValuesSyntheticfield);
216
			codeStream.fieldAccess0(Opcodes.OPC_putstatic, declaringType.enumValuesSyntheticfield, null /* default declaringClass */);
216
			if (remainingFieldCount != 0) {
217
			if (remainingFieldCount != 0) {
217
				// if fields that are not enum constants need to be generated (static initializer/static field)
218
				// if fields that are not enum constants need to be generated (static initializer/static field)
218
				for (int i = 0, max = fieldDeclarations.length; i < max; i++) {
219
				for (int i = 0, max = fieldDeclarations.length; i < max; i++) {
(-)compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java (-2 / +2 lines)
Lines 228-234 Link Here
228
		if ((syntheticArg = syntheticArgs[i]).matchingField != null) {
228
		if ((syntheticArg = syntheticArgs[i]).matchingField != null) {
229
			codeStream.aload_0();
229
			codeStream.aload_0();
230
			codeStream.load(syntheticArg);
230
			codeStream.load(syntheticArg);
231
			codeStream.putfield(syntheticArg.matchingField);
231
			codeStream.fieldAccess0(Opcodes.OPC_putfield, syntheticArg.matchingField, null /* default declaringClass */);
232
		}
232
		}
233
	}
233
	}
234
	syntheticArgs = nestedType.syntheticOuterLocalVariables();
234
	syntheticArgs = nestedType.syntheticOuterLocalVariables();
Lines 237-243 Link Here
237
		if ((syntheticArg = syntheticArgs[i]).matchingField != null) {
237
		if ((syntheticArg = syntheticArgs[i]).matchingField != null) {
238
			codeStream.aload_0();
238
			codeStream.aload_0();
239
			codeStream.load(syntheticArg);
239
			codeStream.load(syntheticArg);
240
			codeStream.putfield(syntheticArg.matchingField);
240
			codeStream.fieldAccess0(Opcodes.OPC_putfield, syntheticArg.matchingField, null /* default declaringClass */);
241
		}
241
		}
242
	}
242
	}
243
}
243
}
(-)compiler/org/eclipse/jdt/internal/compiler/ast/AssertStatement.java (-1 / +1 lines)
Lines 101-107 Link Here
101
101
102
		if (this.assertionSyntheticFieldBinding != null) {
102
		if (this.assertionSyntheticFieldBinding != null) {
103
			BranchLabel assertionActivationLabel = new BranchLabel(codeStream);
103
			BranchLabel assertionActivationLabel = new BranchLabel(codeStream);
104
			codeStream.getstatic(this.assertionSyntheticFieldBinding);
104
			codeStream.fieldAccess0(Opcodes.OPC_getstatic, this.assertionSyntheticFieldBinding, null /* default declaringClass */);
105
			codeStream.ifne(assertionActivationLabel);
105
			codeStream.ifne(assertionActivationLabel);
106
106
107
			BranchLabel falseLabel;
107
			BranchLabel falseLabel;
(-)compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.java (-83 / +67 lines)
Lines 17-23 Link Here
17
import org.eclipse.jdt.internal.compiler.codegen.Opcodes;
17
import org.eclipse.jdt.internal.compiler.codegen.Opcodes;
18
import org.eclipse.jdt.internal.compiler.flow.FlowContext;
18
import org.eclipse.jdt.internal.compiler.flow.FlowContext;
19
import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
19
import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
20
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
21
import org.eclipse.jdt.internal.compiler.impl.Constant;
20
import org.eclipse.jdt.internal.compiler.impl.Constant;
22
import org.eclipse.jdt.internal.compiler.lookup.Binding;
21
import org.eclipse.jdt.internal.compiler.lookup.Binding;
23
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
22
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
Lines 41-51 Link Here
41
	public Expression receiver;
40
	public Expression receiver;
42
	public char[] token;
41
	public char[] token;
43
	public FieldBinding binding;															// exact binding resulting from lookup
42
	public FieldBinding binding;															// exact binding resulting from lookup
44
	protected FieldBinding codegenBinding;									// actual binding used for code generation (if no synthetic accessor)
45
	public MethodBinding[] syntheticAccessors; // [0]=read accessor [1]=write accessor
43
	public MethodBinding[] syntheticAccessors; // [0]=read accessor [1]=write accessor
46
44
47
	public long nameSourcePosition; //(start<<32)+end
45
	public long nameSourcePosition; //(start<<32)+end
48
	public TypeBinding receiverType;
46
	public TypeBinding actualReceiverType;
49
	public TypeBinding genericCast;
47
	public TypeBinding genericCast;
50
48
51
public FieldReference(char[] source, long pos) {
49
public FieldReference(char[] source, long pos) {
Lines 162-176 Link Here
162
160
163
public void generateAssignment(BlockScope currentScope, CodeStream codeStream, Assignment assignment, boolean valueRequired) {
161
public void generateAssignment(BlockScope currentScope, CodeStream codeStream, Assignment assignment, boolean valueRequired) {
164
	int pc = codeStream.position;
162
	int pc = codeStream.position;
163
	FieldBinding codegenBinding = this.binding.original();
165
	this.receiver.generateCode(
164
	this.receiver.generateCode(
166
		currentScope,
165
		currentScope,
167
		codeStream,
166
		codeStream,
168
		!this.codegenBinding.isStatic());
167
		!codegenBinding.isStatic());
169
	codeStream.recordPositionsFrom(pc, this.sourceStart);
168
	codeStream.recordPositionsFrom(pc, this.sourceStart);
170
	assignment.expression.generateCode(currentScope, codeStream, true);
169
	assignment.expression.generateCode(currentScope, codeStream, true);
171
	fieldStore(
170
	fieldStore(
172
		codeStream,
171
		codeStream,
173
		this.codegenBinding,
172
		codegenBinding,
174
		this.syntheticAccessors == null ? null : this.syntheticAccessors[FieldReference.WRITE],
173
		this.syntheticAccessors == null ? null : this.syntheticAccessors[FieldReference.WRITE],
175
		valueRequired);
174
		valueRequired);
176
	if (valueRequired) {
175
	if (valueRequired) {
Lines 195-203 Link Here
195
		codeStream.recordPositionsFrom(pc, this.sourceStart);
194
		codeStream.recordPositionsFrom(pc, this.sourceStart);
196
		return;
195
		return;
197
	}
196
	}
198
	boolean isStatic = this.codegenBinding.isStatic();
197
	FieldBinding codegenBinding = this.binding.original();
198
	boolean isStatic = codegenBinding.isStatic();
199
	boolean isThisReceiver = this.receiver instanceof ThisReference;
199
	boolean isThisReceiver = this.receiver instanceof ThisReference;
200
	Constant fieldConstant = this.codegenBinding.constant();
200
	Constant fieldConstant = codegenBinding.constant();
201
	if (fieldConstant != Constant.NotAConstant) {
201
	if (fieldConstant != Constant.NotAConstant) {
202
		if (!isThisReceiver) {
202
		if (!isThisReceiver) {
203
			this.receiver.generateCode(currentScope, codeStream, !isStatic);
203
			this.receiver.generateCode(currentScope, codeStream, !isStatic);
Lines 218-224 Link Here
218
			|| (this.genericCast != null)) {
218
			|| (this.genericCast != null)) {
219
		this.receiver.generateCode(currentScope, codeStream, !isStatic);
219
		this.receiver.generateCode(currentScope, codeStream, !isStatic);
220
		pc = codeStream.position;
220
		pc = codeStream.position;
221
		if (this.codegenBinding.declaringClass == null) { // array length
221
		if (codegenBinding.declaringClass == null) { // array length
222
			codeStream.arraylength();
222
			codeStream.arraylength();
223
			if (valueRequired) {
223
			if (valueRequired) {
224
				codeStream.generateImplicitConversion(this.implicitConversion);
224
				codeStream.generateImplicitConversion(this.implicitConversion);
Lines 228-237 Link Here
228
			}
228
			}
229
		} else {
229
		} else {
230
			if (this.syntheticAccessors == null || this.syntheticAccessors[FieldReference.READ] == null) {
230
			if (this.syntheticAccessors == null || this.syntheticAccessors[FieldReference.READ] == null) {
231
				TypeBinding constantPoolDeclaringClass = getConstantPoolDeclaringClass(currentScope, codegenBinding, this.actualReceiverType, this.receiver.isImplicitThis());
231
				if (isStatic) {
232
				if (isStatic) {
232
					codeStream.getstatic(this.codegenBinding);
233
					codeStream.fieldAccess0(Opcodes.OPC_getstatic, codegenBinding, constantPoolDeclaringClass);
233
				} else {
234
				} else {
234
					codeStream.getfield(this.codegenBinding);
235
					codeStream.fieldAccess0(Opcodes.OPC_getfield, codegenBinding, constantPoolDeclaringClass);
235
				}
236
				}
236
			} else {
237
			} else {
237
				codeStream.invoke(Opcodes.OPC_invokestatic, this.syntheticAccessors[FieldReference.READ], null /* default declaringClass */);
238
				codeStream.invoke(Opcodes.OPC_invokestatic, this.syntheticAccessors[FieldReference.READ], null /* default declaringClass */);
Lines 244-250 Link Here
244
				boolean isUnboxing = (this.implicitConversion & TypeIds.UNBOXING) != 0;
245
				boolean isUnboxing = (this.implicitConversion & TypeIds.UNBOXING) != 0;
245
				// conversion only generated if unboxing
246
				// conversion only generated if unboxing
246
				if (isUnboxing) codeStream.generateImplicitConversion(this.implicitConversion);
247
				if (isUnboxing) codeStream.generateImplicitConversion(this.implicitConversion);
247
				switch (isUnboxing ? postConversionType(currentScope).id : this.codegenBinding.type.id) {
248
				switch (isUnboxing ? postConversionType(currentScope).id : codegenBinding.type.id) {
248
					case T_long :
249
					case T_long :
249
					case T_double :
250
					case T_double :
250
						codeStream.pop2();
251
						codeStream.pop2();
Lines 258-271 Link Here
258
		if (isThisReceiver) {
259
		if (isThisReceiver) {
259
			if (isStatic){
260
			if (isStatic){
260
				// if no valueRequired, still need possible side-effects of <clinit> invocation, if field belongs to different class
261
				// if no valueRequired, still need possible side-effects of <clinit> invocation, if field belongs to different class
261
				if (this.binding.original().declaringClass != this.receiverType.erasure()) {
262
				if (this.binding.original().declaringClass != this.actualReceiverType.erasure()) {
262
					MethodBinding accessor = this.syntheticAccessors == null ? null : this.syntheticAccessors[FieldReference.READ];
263
					MethodBinding accessor = this.syntheticAccessors == null ? null : this.syntheticAccessors[FieldReference.READ];
263
					if (accessor == null) {
264
					if (accessor == null) {
264
						codeStream.getstatic(this.codegenBinding);
265
						TypeBinding constantPoolDeclaringClass = getConstantPoolDeclaringClass(currentScope, codegenBinding, this.actualReceiverType, this.receiver.isImplicitThis());
266
						codeStream.fieldAccess0(Opcodes.OPC_getstatic, codegenBinding, constantPoolDeclaringClass);
265
					} else {
267
					} else {
266
						codeStream.invoke(Opcodes.OPC_invokestatic, accessor, null /* default declaringClass */);
268
						codeStream.invoke(Opcodes.OPC_invokestatic, accessor, null /* default declaringClass */);
267
					}
269
					}
268
					switch (this.codegenBinding.type.id) {
270
					switch (codegenBinding.type.id) {
269
						case T_long :
271
						case T_long :
270
						case T_double :
272
						case T_double :
271
							codeStream.pop2();
273
							codeStream.pop2();
Lines 288-307 Link Here
288
290
289
public void generateCompoundAssignment(BlockScope currentScope, CodeStream codeStream, Expression expression, int operator, int assignmentImplicitConversion, boolean valueRequired) {
291
public void generateCompoundAssignment(BlockScope currentScope, CodeStream codeStream, Expression expression, int operator, int assignmentImplicitConversion, boolean valueRequired) {
290
	boolean isStatic;
292
	boolean isStatic;
291
	this.receiver.generateCode(
293
	FieldBinding codegenBinding = this.binding.original();
292
		currentScope,
294
	this.receiver.generateCode(currentScope, codeStream, !(isStatic = codegenBinding.isStatic()));
293
		codeStream,
294
		!(isStatic = this.codegenBinding.isStatic()));
295
	if (isStatic) {
295
	if (isStatic) {
296
		if (this.syntheticAccessors == null || this.syntheticAccessors[FieldReference.READ] == null) {
296
		if (this.syntheticAccessors == null || this.syntheticAccessors[FieldReference.READ] == null) {
297
			codeStream.getstatic(this.codegenBinding);
297
			TypeBinding constantPoolDeclaringClass = getConstantPoolDeclaringClass(currentScope, codegenBinding, this.actualReceiverType, this.receiver.isImplicitThis());
298
			codeStream.fieldAccess0(Opcodes.OPC_getstatic, codegenBinding, constantPoolDeclaringClass);
298
		} else {
299
		} else {
299
			codeStream.invoke(Opcodes.OPC_invokestatic, this.syntheticAccessors[FieldReference.READ], null /* default declaringClass */);
300
			codeStream.invoke(Opcodes.OPC_invokestatic, this.syntheticAccessors[FieldReference.READ], null /* default declaringClass */);
300
		}
301
		}
301
	} else {
302
	} else {
302
		codeStream.dup();
303
		codeStream.dup();
303
		if (this.syntheticAccessors == null || this.syntheticAccessors[FieldReference.READ] == null) {
304
		if (this.syntheticAccessors == null || this.syntheticAccessors[FieldReference.READ] == null) {
304
			codeStream.getfield(this.codegenBinding);
305
			TypeBinding constantPoolDeclaringClass = getConstantPoolDeclaringClass(currentScope, codegenBinding, this.actualReceiverType, this.receiver.isImplicitThis());
306
			codeStream.fieldAccess0(Opcodes.OPC_getfield, codegenBinding, constantPoolDeclaringClass);
305
		} else {
307
		} else {
306
			codeStream.invoke(Opcodes.OPC_invokestatic, this.syntheticAccessors[FieldReference.READ], null /* default declaringClass */);
308
			codeStream.invoke(Opcodes.OPC_invokestatic, this.syntheticAccessors[FieldReference.READ], null /* default declaringClass */);
307
		}
309
		}
Lines 329-358 Link Here
329
			// cast the value back to the array reference type
331
			// cast the value back to the array reference type
330
			codeStream.generateImplicitConversion(assignmentImplicitConversion);
332
			codeStream.generateImplicitConversion(assignmentImplicitConversion);
331
	}
333
	}
332
	fieldStore(
334
	fieldStore(codeStream, codegenBinding, this.syntheticAccessors == null ? null : this.syntheticAccessors[FieldReference.WRITE], valueRequired);
333
		codeStream,
334
		this.codegenBinding,
335
		this.syntheticAccessors == null ? null : this.syntheticAccessors[FieldReference.WRITE],
336
		valueRequired);
337
	// no need for generic cast as value got dupped
335
	// no need for generic cast as value got dupped
338
}
336
}
339
337
340
public void generatePostIncrement(BlockScope currentScope, CodeStream codeStream, CompoundAssignment postIncrement, boolean valueRequired) {
338
public void generatePostIncrement(BlockScope currentScope, CodeStream codeStream, CompoundAssignment postIncrement, boolean valueRequired) {
341
	boolean isStatic;
339
	boolean isStatic;
342
	this.receiver.generateCode(
340
	FieldBinding codegenBinding = this.binding.original();
343
		currentScope,
341
	this.receiver.generateCode(currentScope, codeStream, !(isStatic = codegenBinding.isStatic()));
344
		codeStream,
345
		!(isStatic = this.codegenBinding.isStatic()));
346
	if (isStatic) {
342
	if (isStatic) {
347
		if (this.syntheticAccessors == null || this.syntheticAccessors[FieldReference.READ] == null) {
343
		if (this.syntheticAccessors == null || this.syntheticAccessors[FieldReference.READ] == null) {
348
			codeStream.getstatic(this.codegenBinding);
344
			TypeBinding constantPoolDeclaringClass = getConstantPoolDeclaringClass(currentScope, codegenBinding, this.actualReceiverType, this.receiver.isImplicitThis());
345
			codeStream.fieldAccess0(Opcodes.OPC_getstatic, codegenBinding, constantPoolDeclaringClass);
349
		} else {
346
		} else {
350
			codeStream.invoke(Opcodes.OPC_invokestatic, this.syntheticAccessors[FieldReference.READ], null /* default declaringClass */);
347
			codeStream.invoke(Opcodes.OPC_invokestatic, this.syntheticAccessors[FieldReference.READ], null /* default declaringClass */);
351
		}
348
		}
352
	} else {
349
	} else {
353
		codeStream.dup();
350
		codeStream.dup();
354
		if (this.syntheticAccessors == null || this.syntheticAccessors[FieldReference.READ] == null) {
351
		if (this.syntheticAccessors == null || this.syntheticAccessors[FieldReference.READ] == null) {
355
			codeStream.getfield(this.codegenBinding);
352
			TypeBinding constantPoolDeclaringClass = getConstantPoolDeclaringClass(currentScope, codegenBinding, this.actualReceiverType, this.receiver.isImplicitThis());
353
			codeStream.fieldAccess0(Opcodes.OPC_getfield, codegenBinding, constantPoolDeclaringClass);
356
		} else {
354
		} else {
357
			codeStream.invoke(Opcodes.OPC_invokestatic, this.syntheticAccessors[FieldReference.READ], null /* default declaringClass */);
355
			codeStream.invoke(Opcodes.OPC_invokestatic, this.syntheticAccessors[FieldReference.READ], null /* default declaringClass */);
358
		}
356
		}
Lines 362-384 Link Here
362
		codeStream.checkcast(this.genericCast);
360
		codeStream.checkcast(this.genericCast);
363
		operandType = this.genericCast;
361
		operandType = this.genericCast;
364
	} else {
362
	} else {
365
		operandType = this.codegenBinding.type;
363
		operandType = codegenBinding.type;
366
	}	
364
	}	
367
	if (valueRequired) {
365
	if (valueRequired) {
368
		if (isStatic) {
366
		if (isStatic) {
369
			if ((operandType == TypeBinding.LONG)
367
			switch (operandType.id) {
370
				|| (operandType == TypeBinding.DOUBLE)) {
368
				case TypeIds.T_long :
371
				codeStream.dup2();
369
				case TypeIds.T_double :
372
			} else {
370
					codeStream.dup2();
373
				codeStream.dup();
371
					break;
374
			}
372
				default :
373
					codeStream.dup();
374
					break;
375
			}			
375
		} else { // Stack:  [owner][old field value]  ---> [old field value][owner][old field value]
376
		} else { // Stack:  [owner][old field value]  ---> [old field value][owner][old field value]
376
			if ((operandType == TypeBinding.LONG)
377
			switch (operandType.id) {
377
				|| (operandType == TypeBinding.DOUBLE)) {
378
				case TypeIds.T_long :
378
				codeStream.dup2_x1();
379
				case TypeIds.T_double :
379
			} else {
380
					codeStream.dup2_x1();
380
				codeStream.dup_x1();
381
					break;
381
			}
382
				default :
383
					codeStream.dup_x1();
384
					break;
385
			}			
382
		}
386
		}
383
	}
387
	}
384
	codeStream.generateImplicitConversion(this.implicitConversion);		
388
	codeStream.generateImplicitConversion(this.implicitConversion);		
Lines 388-394 Link Here
388
	codeStream.sendOperator(postIncrement.operator, this.implicitConversion & TypeIds.COMPILE_TYPE_MASK);
392
	codeStream.sendOperator(postIncrement.operator, this.implicitConversion & TypeIds.COMPILE_TYPE_MASK);
389
	codeStream.generateImplicitConversion(
393
	codeStream.generateImplicitConversion(
390
		postIncrement.preAssignImplicitConversion);
394
		postIncrement.preAssignImplicitConversion);
391
	fieldStore(codeStream, this.codegenBinding, this.syntheticAccessors == null ? null : this.syntheticAccessors[FieldReference.WRITE], false);
395
	fieldStore(codeStream, codegenBinding, this.syntheticAccessors == null ? null : this.syntheticAccessors[FieldReference.WRITE], false);
392
}
396
}
393
397
394
/**
398
/**
Lines 412-427 Link Here
412
	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) != 0)	return;
416
	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) != 0)	return;
413
417
414
	// if field from parameterized type got found, use the original field at codegen time
418
	// if field from parameterized type got found, use the original field at codegen time
415
	this.codegenBinding = this.binding.original();
419
	FieldBinding codegenBinding = this.binding.original();
416
420
417
	if (this.binding.isPrivate()) {
421
	if (this.binding.isPrivate()) {
418
		if ((currentScope.enclosingSourceType() != this.codegenBinding.declaringClass)
422
		if ((currentScope.enclosingSourceType() != codegenBinding.declaringClass)
419
				&& this.binding.constant() == Constant.NotAConstant) {
423
				&& this.binding.constant() == Constant.NotAConstant) {
420
			if (this.syntheticAccessors == null)
424
			if (this.syntheticAccessors == null)
421
				this.syntheticAccessors = new MethodBinding[2];
425
				this.syntheticAccessors = new MethodBinding[2];
422
			this.syntheticAccessors[isReadAccess ? FieldReference.READ : FieldReference.WRITE] =
426
			this.syntheticAccessors[isReadAccess ? FieldReference.READ : FieldReference.WRITE] =
423
				((SourceTypeBinding) this.codegenBinding.declaringClass).addSyntheticMethod(this.codegenBinding, isReadAccess);
427
				((SourceTypeBinding) codegenBinding.declaringClass).addSyntheticMethod(codegenBinding, isReadAccess);
424
			currentScope.problemReporter().needToEmulateFieldAccess(this.codegenBinding, this, isReadAccess);
428
			currentScope.problemReporter().needToEmulateFieldAccess(codegenBinding, this, isReadAccess);
425
			return;
429
			return;
426
		}
430
		}
427
431
Lines 433-440 Link Here
433
				.currentCompatibleType);
437
				.currentCompatibleType);
434
		if (this.syntheticAccessors == null)
438
		if (this.syntheticAccessors == null)
435
			this.syntheticAccessors = new MethodBinding[2];
439
			this.syntheticAccessors = new MethodBinding[2];
436
		this.syntheticAccessors[isReadAccess ? FieldReference.READ : FieldReference.WRITE] = destinationType.addSyntheticMethod(this.codegenBinding, isReadAccess);
440
		this.syntheticAccessors[isReadAccess ? FieldReference.READ : FieldReference.WRITE] = destinationType.addSyntheticMethod(codegenBinding, isReadAccess);
437
		currentScope.problemReporter().needToEmulateFieldAccess(this.codegenBinding, this, isReadAccess);
441
		currentScope.problemReporter().needToEmulateFieldAccess(codegenBinding, this, isReadAccess);
438
		return;
442
		return;
439
443
440
	} else if (this.binding.isProtected()) {
444
	} else if (this.binding.isProtected()) {
Lines 449-479 Link Here
449
					(this.bits & ASTNode.DepthMASK) >> ASTNode.DepthSHIFT);
453
					(this.bits & ASTNode.DepthMASK) >> ASTNode.DepthSHIFT);
450
			if (this.syntheticAccessors == null)
454
			if (this.syntheticAccessors == null)
451
				this.syntheticAccessors = new MethodBinding[2];
455
				this.syntheticAccessors = new MethodBinding[2];
452
			this.syntheticAccessors[isReadAccess ? FieldReference.READ : FieldReference.WRITE] = currentCompatibleType.addSyntheticMethod(this.codegenBinding, isReadAccess);
456
			this.syntheticAccessors[isReadAccess ? FieldReference.READ : FieldReference.WRITE] = currentCompatibleType.addSyntheticMethod(codegenBinding, isReadAccess);
453
			currentScope.problemReporter().needToEmulateFieldAccess(this.codegenBinding, this, isReadAccess);
457
			currentScope.problemReporter().needToEmulateFieldAccess(codegenBinding, this, isReadAccess);
454
			return;
458
			return;
455
		}
459
		}
456
	}
460
	}
457
	// if the binding declaring class is not visible, need special action
458
	// for runtime compatibility on 1.2 VMs : change the declaring class of the binding
459
	// NOTE: from target 1.2 on, field's declaring class is touched if any different from receiver type
460
	// and not from Object or implicit static field access.
461
	if (this.binding.declaringClass != this.receiverType
462
			&& !this.receiverType.isArrayType()
463
			&& this.binding.declaringClass != null // array.length
464
			&& this.binding.constant() == Constant.NotAConstant) {
465
		CompilerOptions options = currentScope.compilerOptions();
466
		if ((options.targetJDK >= ClassFileConstants.JDK1_2
467
				&& (options.complianceLevel >= ClassFileConstants.JDK1_4 || !(this.receiver.isImplicitThis() && this.codegenBinding.isStatic()))
468
				&& this.binding.declaringClass.id != TypeIds.T_JavaLangObject) // no change for Object fields
469
			|| !this.binding.declaringClass.canBeSeenBy(currentScope)) {
470
471
			this.codegenBinding =
472
				currentScope.enclosingSourceType().getUpdatedFieldBinding(
473
					this.codegenBinding,
474
					(ReferenceBinding) this.receiverType.erasure());
475
		}
476
	}
477
}
461
}
478
462
479
public int nullStatus(FlowInfo flowInfo) {
463
public int nullStatus(FlowInfo flowInfo) {
Lines 546-580 Link Here
546
		this.receiver.bits |= ASTNode.DisableUnnecessaryCastCheck; // will check later on
530
		this.receiver.bits |= ASTNode.DisableUnnecessaryCastCheck; // will check later on
547
		receiverCast = true;
531
		receiverCast = true;
548
	}
532
	}
549
	this.receiverType = this.receiver.resolveType(scope);
533
	this.actualReceiverType = this.receiver.resolveType(scope);
550
	if (this.receiverType == null) {
534
	if (this.actualReceiverType == null) {
551
		this.constant = Constant.NotAConstant;
535
		this.constant = Constant.NotAConstant;
552
		return null;
536
		return null;
553
	}
537
	}
554
	if (receiverCast) {
538
	if (receiverCast) {
555
		 // due to change of declaring class with receiver type, only identity cast should be notified
539
		 // due to change of declaring class with receiver type, only identity cast should be notified
556
		if (((CastExpression)this.receiver).expression.resolvedType == this.receiverType) {
540
		if (((CastExpression)this.receiver).expression.resolvedType == this.actualReceiverType) {
557
				scope.problemReporter().unnecessaryCast((CastExpression)this.receiver);
541
				scope.problemReporter().unnecessaryCast((CastExpression)this.receiver);
558
		}
542
		}
559
	}
543
	}
560
	// the case receiverType.isArrayType and token = 'length' is handled by the scope API
544
	// the case receiverType.isArrayType and token = 'length' is handled by the scope API
561
	FieldBinding fieldBinding = this.codegenBinding = this.binding = scope.getField(this.receiverType, this.token, this);
545
	FieldBinding fieldBinding = this.binding = scope.getField(this.actualReceiverType, this.token, this);
562
	if (!fieldBinding.isValidBinding()) {
546
	if (!fieldBinding.isValidBinding()) {
563
		this.constant = Constant.NotAConstant;
547
		this.constant = Constant.NotAConstant;
564
		if (this.receiver.resolvedType instanceof ProblemReferenceBinding) {
548
		if (this.receiver.resolvedType instanceof ProblemReferenceBinding) {
565
			// problem already got signaled on receiver, do not report secondary problem
549
			// problem already got signaled on receiver, do not report secondary problem
566
			return null;
550
			return null;
567
		}
551
		}
568
		scope.problemReporter().invalidField(this, this.receiverType);
552
		scope.problemReporter().invalidField(this, this.actualReceiverType);
569
		return null;
553
		return null;
570
	}
554
	}
571
	TypeBinding receiverErasure = this.receiverType.erasure();
555
	TypeBinding receiverErasure = this.actualReceiverType.erasure();
572
	if (receiverErasure instanceof ReferenceBinding) {
556
	if (receiverErasure instanceof ReferenceBinding) {
573
		if (receiverErasure.findSuperTypeOriginatingFrom(fieldBinding.declaringClass) == null) {
557
		if (receiverErasure.findSuperTypeOriginatingFrom(fieldBinding.declaringClass) == null) {
574
			this.receiverType = fieldBinding.declaringClass; // handle indirect inheritance thru variable secondary bound
558
			this.actualReceiverType = fieldBinding.declaringClass; // handle indirect inheritance thru variable secondary bound
575
		}
559
		}
576
	}
560
	}
577
	this.receiver.computeConversion(scope, this.receiverType, this.receiverType);
561
	this.receiver.computeConversion(scope, this.actualReceiverType, this.actualReceiverType);
578
	if (isFieldUseDeprecated(fieldBinding, scope, (this.bits & ASTNode.IsStrictlyAssigned) !=0)) {
562
	if (isFieldUseDeprecated(fieldBinding, scope, (this.bits & ASTNode.IsStrictlyAssigned) !=0)) {
579
		scope.problemReporter().deprecatedField(fieldBinding, this);
563
		scope.problemReporter().deprecatedField(fieldBinding, this);
580
	}
564
	}
Lines 589-595 Link Here
589
		}
573
		}
590
		ReferenceBinding declaringClass = this.binding.declaringClass;
574
		ReferenceBinding declaringClass = this.binding.declaringClass;
591
		if (!isImplicitThisRcv
575
		if (!isImplicitThisRcv
592
				&& declaringClass != this.receiverType
576
				&& declaringClass != this.actualReceiverType
593
				&& declaringClass.canBeSeenBy(scope)) {
577
				&& declaringClass.canBeSeenBy(scope)) {
594
			scope.problemReporter().indirectAccessToStaticField(this, fieldBinding);
578
			scope.problemReporter().indirectAccessToStaticField(this, fieldBinding);
595
		}
579
		}
Lines 620-626 Link Here
620
}
604
}
621
605
622
public void setActualReceiverType(ReferenceBinding receiverType) {
606
public void setActualReceiverType(ReferenceBinding receiverType) {
623
	// ignored
607
	this.actualReceiverType = receiverType;
624
}
608
}
625
609
626
public void setDepth(int depth) {
610
public void setDepth(int depth) {
(-)compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java (-26 / +12 lines)
Lines 376-382 Link Here
376
					}
376
					}
377
					// managing private access
377
					// managing private access
378
					if ((this.syntheticAccessors == null) || (this.syntheticAccessors[SingleNameReference.READ] == null)) {
378
					if ((this.syntheticAccessors == null) || (this.syntheticAccessors[SingleNameReference.READ] == null)) {
379
						codeStream.getstatic(fieldBinding);
379
						TypeBinding constantPoolDeclaringClass = getConstantPoolDeclaringClass(currentScope, fieldBinding, this.actualReceiverType, true /* implicit this */);
380
						codeStream.fieldAccess0(Opcodes.OPC_getstatic, fieldBinding, constantPoolDeclaringClass);
380
					} else {
381
					} else {
381
						codeStream.invoke(Opcodes.OPC_invokestatic, this.syntheticAccessors[SingleNameReference.READ], null /* default declaringClass */);
382
						codeStream.invoke(Opcodes.OPC_invokestatic, this.syntheticAccessors[SingleNameReference.READ], null /* default declaringClass */);
382
					}
383
					}
Lines 398-404 Link Here
398
					}
399
					}
399
					// managing private access
400
					// managing private access
400
					if ((this.syntheticAccessors == null) || (this.syntheticAccessors[SingleNameReference.READ] == null)) {
401
					if ((this.syntheticAccessors == null) || (this.syntheticAccessors[SingleNameReference.READ] == null)) {
401
						codeStream.getfield(fieldBinding);
402
						TypeBinding constantPoolDeclaringClass = getConstantPoolDeclaringClass(currentScope, fieldBinding, this.actualReceiverType, true /* implicit this */);
403
						codeStream.fieldAccess0(Opcodes.OPC_getfield, fieldBinding, constantPoolDeclaringClass);
402
					} else {
404
					} else {
403
						codeStream.invoke(Opcodes.OPC_invokestatic, this.syntheticAccessors[SingleNameReference.READ], null /* default declaringClass */);
405
						codeStream.invoke(Opcodes.OPC_invokestatic, this.syntheticAccessors[SingleNameReference.READ], null /* default declaringClass */);
404
					}
406
					}
Lines 473-479 Link Here
473
			FieldBinding fieldBinding;
475
			FieldBinding fieldBinding;
474
			if ((fieldBinding = (FieldBinding) this.codegenBinding).isStatic()) {
476
			if ((fieldBinding = (FieldBinding) this.codegenBinding).isStatic()) {
475
				if ((this.syntheticAccessors == null) || (this.syntheticAccessors[SingleNameReference.READ] == null)) {
477
				if ((this.syntheticAccessors == null) || (this.syntheticAccessors[SingleNameReference.READ] == null)) {
476
					codeStream.getstatic(fieldBinding);
478
					TypeBinding constantPoolDeclaringClass = getConstantPoolDeclaringClass(currentScope, fieldBinding, this.actualReceiverType, true /* implicit this */);					
479
					codeStream.fieldAccess0(Opcodes.OPC_getstatic, fieldBinding, constantPoolDeclaringClass);
477
				} else {
480
				} else {
478
					codeStream.invoke(Opcodes.OPC_invokestatic, this.syntheticAccessors[SingleNameReference.READ], null /* default declaringClass */);
481
					codeStream.invoke(Opcodes.OPC_invokestatic, this.syntheticAccessors[SingleNameReference.READ], null /* default declaringClass */);
479
				}
482
				}
Lines 487-493 Link Here
487
				}
490
				}
488
				codeStream.dup();
491
				codeStream.dup();
489
				if ((this.syntheticAccessors == null) || (this.syntheticAccessors[SingleNameReference.READ] == null)) {
492
				if ((this.syntheticAccessors == null) || (this.syntheticAccessors[SingleNameReference.READ] == null)) {
490
					codeStream.getfield(fieldBinding);
493
					TypeBinding constantPoolDeclaringClass = getConstantPoolDeclaringClass(currentScope, fieldBinding, this.actualReceiverType, true /* implicit this */);
494
					codeStream.fieldAccess0(Opcodes.OPC_getfield, fieldBinding, constantPoolDeclaringClass);
491
				} else {
495
				} else {
492
					codeStream.invoke(Opcodes.OPC_invokestatic, this.syntheticAccessors[SingleNameReference.READ], null /* default declaringClass */);
496
					codeStream.invoke(Opcodes.OPC_invokestatic, this.syntheticAccessors[SingleNameReference.READ], null /* default declaringClass */);
493
				}
497
				}
Lines 586-592 Link Here
586
			FieldBinding fieldBinding;
590
			FieldBinding fieldBinding;
587
			if ((fieldBinding = (FieldBinding) this.codegenBinding).isStatic()) {
591
			if ((fieldBinding = (FieldBinding) this.codegenBinding).isStatic()) {
588
				if ((this.syntheticAccessors == null) || (this.syntheticAccessors[SingleNameReference.READ] == null)) {
592
				if ((this.syntheticAccessors == null) || (this.syntheticAccessors[SingleNameReference.READ] == null)) {
589
					codeStream.getstatic(fieldBinding);
593
					TypeBinding constantPoolDeclaringClass = getConstantPoolDeclaringClass(currentScope, fieldBinding, this.actualReceiverType, true /* implicit this */);
594
					codeStream.fieldAccess0(Opcodes.OPC_getstatic, fieldBinding, constantPoolDeclaringClass);
590
				} else {
595
				} else {
591
					codeStream.invoke(Opcodes.OPC_invokestatic, this.syntheticAccessors[SingleNameReference.READ], null /* default declaringClass */);
596
					codeStream.invoke(Opcodes.OPC_invokestatic, this.syntheticAccessors[SingleNameReference.READ], null /* default declaringClass */);
592
				}
597
				}
Lines 600-606 Link Here
600
				}
605
				}
601
				codeStream.dup();
606
				codeStream.dup();
602
				if ((this.syntheticAccessors == null) || (this.syntheticAccessors[SingleNameReference.READ] == null)) {
607
				if ((this.syntheticAccessors == null) || (this.syntheticAccessors[SingleNameReference.READ] == null)) {
603
					codeStream.getfield(fieldBinding);
608
					TypeBinding constantPoolDeclaringClass = getConstantPoolDeclaringClass(currentScope, fieldBinding, this.actualReceiverType, true /* implicit this */);
609
					codeStream.fieldAccess0(Opcodes.OPC_getfield, fieldBinding, constantPoolDeclaringClass);
604
				} else {
610
				} else {
605
					codeStream.invoke(Opcodes.OPC_invokestatic, this.syntheticAccessors[SingleNameReference.READ], null /* default declaringClass */);
611
					codeStream.invoke(Opcodes.OPC_invokestatic, this.syntheticAccessors[SingleNameReference.READ], null /* default declaringClass */);
606
				}
612
				}
Lines 723-748 Link Here
723
			currentScope.problemReporter().needToEmulateFieldAccess(codegenField, this, isReadAccess);
729
			currentScope.problemReporter().needToEmulateFieldAccess(codegenField, this, isReadAccess);
724
			return;
730
			return;
725
		}
731
		}
726
		// if the binding declaring class is not visible, need special action
727
		// for runtime compatibility on 1.2 VMs : change the declaring class of the binding
728
		// NOTE: from target 1.2 on, field's declaring class is touched if any different from receiver type
729
		// and not from Object or implicit static field access.
730
		if (fieldBinding.declaringClass != this.actualReceiverType
731
				&& !this.actualReceiverType.isArrayType()
732
				&& fieldBinding.declaringClass != null // array.length
733
				&& fieldBinding.constant() == Constant.NotAConstant) {
734
			CompilerOptions options = currentScope.compilerOptions();
735
			if ((options.targetJDK >= ClassFileConstants.JDK1_2
736
					&& (options.complianceLevel >= ClassFileConstants.JDK1_4 || !fieldBinding.isStatic())
737
					&& fieldBinding.declaringClass.id != TypeIds.T_JavaLangObject) // no change for Object fields
738
					|| !fieldBinding.declaringClass.canBeSeenBy(currentScope)) {
739
740
					this.codegenBinding =
741
					    currentScope.enclosingSourceType().getUpdatedFieldBinding(
742
						       codegenField,
743
						        (ReferenceBinding)this.actualReceiverType.erasure());
744
			}
745
		}
746
	}
732
	}
747
}
733
}
748
734
(-)compiler/org/eclipse/jdt/internal/compiler/ast/Reference.java (-10 / +24 lines)
Lines 10-17 Link Here
10
 *******************************************************************************/
10
 *******************************************************************************/
11
package org.eclipse.jdt.internal.compiler.ast;
11
package org.eclipse.jdt.internal.compiler.ast;
12
12
13
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
13
import org.eclipse.jdt.internal.compiler.codegen.*;
14
import org.eclipse.jdt.internal.compiler.codegen.*;
14
import org.eclipse.jdt.internal.compiler.flow.*;
15
import org.eclipse.jdt.internal.compiler.flow.*;
16
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
17
import org.eclipse.jdt.internal.compiler.impl.Constant;
15
import org.eclipse.jdt.internal.compiler.lookup.*;
18
import org.eclipse.jdt.internal.compiler.lookup.*;
16
19
17
public abstract class Reference extends Expression  {
20
public abstract class Reference extends Expression  {
Lines 26-67 Link Here
26
public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
29
public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
27
	return flowInfo;
30
	return flowInfo;
28
}
31
}
32
29
public FieldBinding fieldBinding() {
33
public FieldBinding fieldBinding() {
30
	//this method should be sent one FIELD-tagged references
34
	//this method should be sent one FIELD-tagged references
31
	//  (ref.bits & BindingIds.FIELD != 0)()
35
	//  (ref.bits & BindingIds.FIELD != 0)()
32
	return null ;
36
	return null ;
33
}
37
}
38
34
public void fieldStore(CodeStream codeStream, FieldBinding fieldBinding, MethodBinding syntheticWriteAccessor, boolean valueRequired) {
39
public void fieldStore(CodeStream codeStream, FieldBinding fieldBinding, MethodBinding syntheticWriteAccessor, boolean valueRequired) {
35
	int pc = codeStream.position;
40
	int pc = codeStream.position;
36
	if (fieldBinding.isStatic()) {
41
	if (fieldBinding.isStatic()) {
37
		if (valueRequired) {
42
		if (valueRequired) {
38
			if ((fieldBinding.type == TypeBinding.LONG) || (fieldBinding.type == TypeBinding.DOUBLE)) {
43
			switch (fieldBinding.type.id) {
39
				codeStream.dup2();
44
				case TypeIds.T_long :
40
			} else {
45
				case TypeIds.T_double :
41
				codeStream.dup();
46
					codeStream.dup2();
47
					break;
48
				default : 
49
					codeStream.dup();
50
					break;
42
			}
51
			}
43
		}
52
		}
44
		if (syntheticWriteAccessor == null) {
53
		if (syntheticWriteAccessor == null) {
45
			codeStream.putstatic(fieldBinding);
54
			codeStream.fieldAccess0(Opcodes.OPC_putstatic, fieldBinding, null /* default declaringClass */);
46
		} else {
55
		} else {
47
			codeStream.invoke(Opcodes.OPC_invokestatic, syntheticWriteAccessor, null /* default declaringClass */);
56
			codeStream.invoke(Opcodes.OPC_invokestatic, syntheticWriteAccessor, null /* default declaringClass */);
48
		}
57
		}
49
	} else { // Stack:  [owner][new field value]  ---> [new field value][owner][new field value]
58
	} else { // Stack:  [owner][new field value]  ---> [new field value][owner][new field value]
50
		if (valueRequired) {
59
		if (valueRequired) {
51
			if ((fieldBinding.type == TypeBinding.LONG) || (fieldBinding.type == TypeBinding.DOUBLE)) {
60
			switch (fieldBinding.type.id) {
52
				codeStream.dup2_x1();
61
				case TypeIds.T_long :
53
			} else {
62
				case TypeIds.T_double :
54
				codeStream.dup_x1();
63
					codeStream.dup2_x1();
64
					break;
65
				default : 
66
					codeStream.dup_x1();
67
					break;
55
			}
68
			}
56
		}
69
		}
57
		if (syntheticWriteAccessor == null) {
70
		if (syntheticWriteAccessor == null) {
58
			codeStream.putfield(fieldBinding);
71
			codeStream.fieldAccess0(Opcodes.OPC_putfield, fieldBinding, null /* default declaringClass */);
59
		} else {
72
		} else {
60
			codeStream.invoke(Opcodes.OPC_invokestatic, syntheticWriteAccessor, null /* default declaringClass */);
73
			codeStream.invoke(Opcodes.OPC_invokestatic, syntheticWriteAccessor, null /* default declaringClass */);
61
		}
74
		}
62
	}
75
	}
63
	codeStream.recordPositionsFrom(pc, this.sourceStart);
76
	codeStream.recordPositionsFrom(pc, this.sourceStart);
64
}
77
}
78
65
public abstract void generateAssignment(BlockScope currentScope, CodeStream codeStream, Assignment assignment, boolean valueRequired);
79
public abstract void generateAssignment(BlockScope currentScope, CodeStream codeStream, Assignment assignment, boolean valueRequired);
66
80
67
public abstract void generateCompoundAssignment(BlockScope currentScope, CodeStream codeStream, Expression expression, int operator, int assignmentImplicitConversion, boolean valueRequired);
81
public abstract void generateCompoundAssignment(BlockScope currentScope, CodeStream codeStream, Expression expression, int operator, int assignmentImplicitConversion, boolean valueRequired);
(-)compiler/org/eclipse/jdt/internal/compiler/ast/Javadoc.java (-5 / +5 lines)
Lines 373-383 Link Here
373
					if (scopeModifiers == -1) scopeModifiers = scope.getDeclarationModifiers();
373
					if (scopeModifiers == -1) scopeModifiers = scope.getDeclarationModifiers();
374
					scope.problemReporter().javadocInvalidValueReference(fieldRef.sourceStart, fieldRef.sourceEnd, scopeModifiers);
374
					scope.problemReporter().javadocInvalidValueReference(fieldRef.sourceStart, fieldRef.sourceEnd, scopeModifiers);
375
				}
375
				}
376
				else if (fieldRef.receiverType != null) {
376
				else if (fieldRef.actualReceiverType != null) {
377
					if (scope.enclosingSourceType().isCompatibleWith(fieldRef.receiverType)) {
377
					if (scope.enclosingSourceType().isCompatibleWith(fieldRef.actualReceiverType)) {
378
						fieldRef.bits |= ASTNode.SuperAccess;
378
						fieldRef.bits |= ASTNode.SuperAccess;
379
					}
379
					}
380
					fieldRef.methodBinding = scope.findMethod((ReferenceBinding)fieldRef.receiverType, fieldRef.token, new TypeBinding[0], fieldRef);
380
					fieldRef.methodBinding = scope.findMethod((ReferenceBinding)fieldRef.actualReceiverType, fieldRef.token, new TypeBinding[0], fieldRef);
381
				}
381
				}
382
			}
382
			}
383
383
Lines 390-397 Link Here
390
			}
390
			}
391
391
392
			// Verify type references
392
			// Verify type references
393
			if (!hasProblems && fieldRef.binding != null && fieldRef.binding.isValidBinding() && fieldRef.receiverType instanceof ReferenceBinding) {
393
			if (!hasProblems && fieldRef.binding != null && fieldRef.binding.isValidBinding() && fieldRef.actualReceiverType instanceof ReferenceBinding) {
394
				ReferenceBinding resolvedType = (ReferenceBinding) fieldRef.receiverType;
394
				ReferenceBinding resolvedType = (ReferenceBinding) fieldRef.actualReceiverType;
395
				verifyTypeReference(fieldRef, fieldRef.receiver, scope, source15, resolvedType, fieldRef.binding.modifiers);
395
				verifyTypeReference(fieldRef, fieldRef.receiver, scope, source15, resolvedType, fieldRef.binding.modifiers);
396
			}
396
			}
397
397
(-)compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java (-2 / +2 lines)
Lines 193-199 Link Here
193
	return this.genericTypeArguments;
193
	return this.genericTypeArguments;
194
}
194
}
195
195
196
protected TypeBinding getConstantPoolDeclaringClass(BlockScope currentScope) {
196
public static TypeBinding getConstantPoolDeclaringClass(BlockScope currentScope, MethodBinding methodBinding, TypeBinding actualReceiverType, boolean isReceiverImplicitThis, boolean hasGenericCast) {
197
	// constantpool declaringClass
197
	// constantpool declaringClass
198
	MethodBinding codegenBinding = this.binding.original();
198
	MethodBinding codegenBinding = this.binding.original();
199
	TypeBinding constantPoolDeclaringClass = codegenBinding.declaringClass;
199
	TypeBinding constantPoolDeclaringClass = codegenBinding.declaringClass;
Lines 209-215 Link Here
209
		// for runtime compatibility on 1.2 VMs : change the declaring class of the binding
209
		// for runtime compatibility on 1.2 VMs : change the declaring class of the binding
210
		// NOTE: from target 1.2 on, method's declaring class is touched if any different from receiver type
210
		// NOTE: from target 1.2 on, method's declaring class is touched if any different from receiver type
211
		// and not from Object or implicit static method call.
211
		// and not from Object or implicit static method call.
212
		if (constantPoolDeclaringClass != this.actualReceiverType && this.receiverGenericCast == null && !this.actualReceiverType.isArrayType()) {
212
		if (constantPoolDeclaringClass != this.actualReceiverType.erasure() && this.receiverGenericCast == null && !this.actualReceiverType.isArrayType()) {
213
			CompilerOptions options = currentScope.compilerOptions();
213
			CompilerOptions options = currentScope.compilerOptions();
214
			if ((options.targetJDK >= ClassFileConstants.JDK1_2
214
			if ((options.targetJDK >= ClassFileConstants.JDK1_2
215
						&& (options.complianceLevel >= ClassFileConstants.JDK1_4 || !(this.receiver.isImplicitThis() && codegenBinding.isStatic()))
215
						&& (options.complianceLevel >= ClassFileConstants.JDK1_4 || !(this.receiver.isImplicitThis() && codegenBinding.isStatic()))
(-)compiler/org/eclipse/jdt/internal/compiler/ast/JavadocFieldReference.java (-8 / +8 lines)
Lines 41-59 Link Here
41
41
42
		this.constant = Constant.NotAConstant;
42
		this.constant = Constant.NotAConstant;
43
		if (this.receiver == null) {
43
		if (this.receiver == null) {
44
			this.receiverType = scope.enclosingReceiverType();
44
			this.actualReceiverType = scope.enclosingReceiverType();
45
		} else if (scope.kind == Scope.CLASS_SCOPE) {
45
		} else if (scope.kind == Scope.CLASS_SCOPE) {
46
			this.receiverType = this.receiver.resolveType((ClassScope) scope);
46
			this.actualReceiverType = this.receiver.resolveType((ClassScope) scope);
47
		} else {
47
		} else {
48
			this.receiverType = this.receiver.resolveType((BlockScope)scope);
48
			this.actualReceiverType = this.receiver.resolveType((BlockScope)scope);
49
		}
49
		}
50
		if (this.receiverType == null) {
50
		if (this.actualReceiverType == null) {
51
			return null;
51
			return null;
52
		}
52
		}
53
53
54
		Binding fieldBinding = (this.receiver != null && this.receiver.isThis())
54
		Binding fieldBinding = (this.receiver != null && this.receiver.isThis())
55
			? scope.classScope().getBinding(this.token, this.bits & RestrictiveFlagMASK, this, true /*resolve*/)
55
			? scope.classScope().getBinding(this.token, this.bits & RestrictiveFlagMASK, this, true /*resolve*/)
56
			: scope.getField(this.receiverType, this.token, this);
56
			: scope.getField(this.actualReceiverType, this.token, this);
57
		if (!fieldBinding.isValidBinding()) {
57
		if (!fieldBinding.isValidBinding()) {
58
			// implicit lookup may discover issues due to static/constructor contexts. javadoc must be resilient
58
			// implicit lookup may discover issues due to static/constructor contexts. javadoc must be resilient
59
			switch (fieldBinding.problemId()) {
59
			switch (fieldBinding.problemId()) {
Lines 72-79 Link Here
72
				// problem already got signaled on receiver, do not report secondary problem
72
				// problem already got signaled on receiver, do not report secondary problem
73
				return null;
73
				return null;
74
			}
74
			}
75
			if (this.receiverType instanceof ReferenceBinding) {
75
			if (this.actualReceiverType instanceof ReferenceBinding) {
76
				ReferenceBinding refBinding = (ReferenceBinding) this.receiverType;
76
				ReferenceBinding refBinding = (ReferenceBinding) this.actualReceiverType;
77
				MethodBinding possibleMethod = this.receiver.isThis()
77
				MethodBinding possibleMethod = this.receiver.isThis()
78
					? scope.getImplicitMethod(this.token, Binding.NO_TYPES, this)
78
					? scope.getImplicitMethod(this.token, Binding.NO_TYPES, this)
79
					: scope.getMethod(refBinding, this.token, Binding.NO_TYPES, this);
79
					: scope.getMethod(refBinding, this.token, Binding.NO_TYPES, this);
Lines 82-88 Link Here
82
				} else {
82
				} else {
83
					ProblemMethodBinding problemMethodBinding = (ProblemMethodBinding) possibleMethod;
83
					ProblemMethodBinding problemMethodBinding = (ProblemMethodBinding) possibleMethod;
84
					if (problemMethodBinding.closestMatch == null) {
84
					if (problemMethodBinding.closestMatch == null) {
85
						scope.problemReporter().javadocInvalidField(this, fieldBinding, this.receiverType, scope.getDeclarationModifiers());
85
						scope.problemReporter().javadocInvalidField(this, fieldBinding, this.actualReceiverType, scope.getDeclarationModifiers());
86
					} else {
86
					} else {
87
						this.methodBinding = problemMethodBinding.closestMatch;
87
						this.methodBinding = problemMethodBinding.closestMatch;
88
					}
88
					}
(-)compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java (-13 / +10 lines)
Lines 391-405 Link Here
391
							codeStream.pop();
391
							codeStream.pop();
392
						}
392
						}
393
					} else {
393
					} else {
394
						SyntheticMethodBinding accessor =
394
						SyntheticMethodBinding accessor = this.syntheticReadAccessors == null ? null : this.syntheticReadAccessors[this.syntheticReadAccessors.length - 1];
395
							this.syntheticReadAccessors == null
396
								? null
397
								: this.syntheticReadAccessors[this.syntheticReadAccessors.length - 1];
398
						if (accessor == null) {
395
						if (accessor == null) {
399
							if (isStatic) {
396
							if (isStatic) {
400
								codeStream.getstatic(lastFieldBinding);
397
								codeStream.fieldAccess(Opcodes.OPC_getstatic, lastFieldBinding, null /* default declaringClass */);
401
							} else {
398
							} else {
402
								codeStream.getfield(lastFieldBinding);
399
								codeStream.fieldAccess(Opcodes.OPC_getfield, lastFieldBinding, null /* default declaringClass */);
403
							}
400
							}
404
						} else {
401
						} else {
405
							codeStream.invoke(Opcodes.OPC_invokestatic, accessor, null /* default declaringClass */);
402
							codeStream.invoke(Opcodes.OPC_invokestatic, accessor, null /* default declaringClass */);
Lines 451-464 Link Here
451
			: this.syntheticReadAccessors[this.syntheticReadAccessors.length - 1];
448
			: this.syntheticReadAccessors[this.syntheticReadAccessors.length - 1];
452
	if (lastFieldBinding.isStatic()) {
449
	if (lastFieldBinding.isStatic()) {
453
		if (accessor == null) {
450
		if (accessor == null) {
454
			codeStream.getstatic(lastFieldBinding);
451
			codeStream.fieldAccess(Opcodes.OPC_getstatic, lastFieldBinding, null /* default declaringClass */);
455
		} else {
452
		} else {
456
			codeStream.invoke(Opcodes.OPC_invokestatic, accessor, null /* default declaringClass */);
453
			codeStream.invoke(Opcodes.OPC_invokestatic, accessor, null /* default declaringClass */);
457
		}
454
		}
458
	} else {
455
	} else {
459
		codeStream.dup();
456
		codeStream.dup();
460
		if (accessor == null) {
457
		if (accessor == null) {
461
			codeStream.getfield(lastFieldBinding);
458
			codeStream.fieldAccess(Opcodes.OPC_getfield, lastFieldBinding, null /* default declaringClass */);
462
		} else {
459
		} else {
463
			codeStream.invoke(Opcodes.OPC_invokestatic, accessor, null /* default declaringClass */);
460
			codeStream.invoke(Opcodes.OPC_invokestatic, accessor, null /* default declaringClass */);
464
		}
461
		}
Lines 500-513 Link Here
500
			: this.syntheticReadAccessors[this.syntheticReadAccessors.length - 1];
497
			: this.syntheticReadAccessors[this.syntheticReadAccessors.length - 1];
501
	if (lastFieldBinding.isStatic()) {
498
	if (lastFieldBinding.isStatic()) {
502
		if (accessor == null) {
499
		if (accessor == null) {
503
			codeStream.getstatic(lastFieldBinding);
500
			codeStream.fieldAccess(Opcodes.OPC_getstatic, lastFieldBinding, null /* default declaringClass */);
504
		} else {
501
		} else {
505
			codeStream.invoke(Opcodes.OPC_invokestatic, accessor, null /* default declaringClass */);
502
			codeStream.invoke(Opcodes.OPC_invokestatic, accessor, null /* default declaringClass */);
506
		}
503
		}
507
	} else {
504
	} else {
508
		codeStream.dup();
505
		codeStream.dup();
509
		if (accessor == null) {
506
		if (accessor == null) {
510
			codeStream.getfield(lastFieldBinding);
507
			codeStream.fieldAccess(Opcodes.OPC_getfield, lastFieldBinding, null /* default declaringClass */);
511
		} else {
508
		} else {
512
			codeStream.invoke(Opcodes.OPC_invokestatic, accessor, null /* default declaringClass */);
509
			codeStream.invoke(Opcodes.OPC_invokestatic, accessor, null /* default declaringClass */);
513
		}
510
		}
Lines 624-632 Link Here
624
						MethodBinding accessor = this.syntheticReadAccessors == null ? null : this.syntheticReadAccessors[i];
621
						MethodBinding accessor = this.syntheticReadAccessors == null ? null : this.syntheticReadAccessors[i];
625
						if (accessor == null) {
622
						if (accessor == null) {
626
							if (lastFieldBinding.isStatic()) {
623
							if (lastFieldBinding.isStatic()) {
627
								codeStream.getstatic(lastFieldBinding);
624
								codeStream.fieldAccess(Opcodes.OPC_getstatic, lastFieldBinding, null /* default declaringClass */);
628
							} else {
625
							} else {
629
								codeStream.getfield(lastFieldBinding);
626
								codeStream.fieldAccess(Opcodes.OPC_getfield, lastFieldBinding, null /* default declaringClass */);
630
							}
627
							}
631
						} else {
628
						} else {
632
							codeStream.invoke(Opcodes.OPC_invokestatic, accessor, null /* default declaringClass */);
629
							codeStream.invoke(Opcodes.OPC_invokestatic, accessor, null /* default declaringClass */);
Lines 640-646 Link Here
640
								if (((FieldBinding)this.binding).original().declaringClass != this.actualReceiverType.erasure()) {
637
								if (((FieldBinding)this.binding).original().declaringClass != this.actualReceiverType.erasure()) {
641
									MethodBinding accessor = this.syntheticReadAccessors == null ? null : this.syntheticReadAccessors[i];
638
									MethodBinding accessor = this.syntheticReadAccessors == null ? null : this.syntheticReadAccessors[i];
642
									if (accessor == null) {
639
									if (accessor == null) {
643
										codeStream.getstatic(lastFieldBinding);
640
										codeStream.fieldAccess(Opcodes.OPC_getstatic, lastFieldBinding, null /* default declaringClass */);
644
									} else {
641
									} else {
645
										codeStream.invoke(Opcodes.OPC_invokestatic, accessor, null /* default declaringClass */);
642
										codeStream.invoke(Opcodes.OPC_invokestatic, accessor, null /* default declaringClass */);
646
									}
643
									}
(-)compiler/org/eclipse/jdt/internal/compiler/ast/FieldDeclaration.java (-2 / +2 lines)
Lines 104-112 Link Here
104
		this.initialization.generateCode(currentScope, codeStream, true);
104
		this.initialization.generateCode(currentScope, codeStream, true);
105
		// store into field
105
		// store into field
106
		if (isStatic) {
106
		if (isStatic) {
107
			codeStream.putstatic(this.binding);
107
			codeStream.fieldAccess0(Opcodes.OPC_putstatic, this.binding, null /* default declaringClass */);
108
		} else {
108
		} else {
109
			codeStream.putfield(this.binding);
109
			codeStream.fieldAccess0(Opcodes.OPC_putfield, this.binding, null /* default declaringClass */);
110
		}
110
		}
111
	}
111
	}
112
	codeStream.recordPositionsFrom(pc, this.sourceStart);
112
	codeStream.recordPositionsFrom(pc, this.sourceStart);
(-)compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java (-165 / +143 lines)
Lines 21-26 Link Here
21
import org.eclipse.jdt.internal.compiler.ast.OperatorIds;
21
import org.eclipse.jdt.internal.compiler.ast.OperatorIds;
22
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
22
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
23
import org.eclipse.jdt.internal.compiler.flow.UnconditionalFlowInfo;
23
import org.eclipse.jdt.internal.compiler.flow.UnconditionalFlowInfo;
24
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
24
import org.eclipse.jdt.internal.compiler.impl.Constant;
25
import org.eclipse.jdt.internal.compiler.impl.Constant;
25
import org.eclipse.jdt.internal.compiler.lookup.*;
26
import org.eclipse.jdt.internal.compiler.lookup.*;
26
import org.eclipse.jdt.internal.compiler.problem.AbortMethod;
27
import org.eclipse.jdt.internal.compiler.problem.AbortMethod;
Lines 1214-1219 Link Here
1214
	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_fdiv;
1215
	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_fdiv;
1215
}
1216
}
1216
1217
1218
public void fieldAccess0(byte opcode, FieldBinding fieldBinding, TypeBinding declaringClass) {
1219
	if (declaringClass == null) declaringClass = fieldBinding.declaringClass;
1220
	if (declaringClass.leafComponentType().isNestedType()) {
1221
		this.classFile.recordInnerClasses(declaringClass);
1222
	}
1223
	TypeBinding returnType = fieldBinding.type;
1224
	int returnTypeSize;
1225
	switch (returnType.id) {
1226
		case TypeIds.T_long :
1227
		case TypeIds.T_double :
1228
			returnTypeSize = 2;
1229
			break;
1230
		default :
1231
			returnTypeSize = 1;
1232
			break;
1233
	}
1234
	this.fieldAccess(opcode, returnTypeSize, declaringClass.constantPoolName(), fieldBinding.name, returnType.signature());
1235
}
1236
1237
private void fieldAccess(byte opcode, int returnTypeSize, char[] declaringClass, char[] fieldName, char[] signature) {
1238
	this.countLabels = 0;
1239
	switch(opcode) {
1240
		case Opcodes.OPC_getfield :
1241
			if (returnTypeSize == 2) {
1242
				this.stackDepth++;
1243
			}
1244
			break;
1245
		case Opcodes.OPC_getstatic :
1246
			if (returnTypeSize == 2) {
1247
				this.stackDepth += 2;
1248
			} else {
1249
				this.stackDepth++;
1250
			}
1251
			break;
1252
		case Opcodes.OPC_putfield :
1253
			if (returnTypeSize == 2) {
1254
				this.stackDepth -= 3;
1255
			} else {
1256
				this.stackDepth -= 2;
1257
			}
1258
			break;
1259
		case Opcodes.OPC_putstatic :
1260
			if (returnTypeSize == 2) {
1261
				this.stackDepth -= 2;
1262
			} else {
1263
				this.stackDepth--;
1264
			}
1265
	}
1266
	if (this.stackDepth > this.stackMax) {
1267
		this.stackMax = this.stackDepth;
1268
	}
1269
	if (this.classFileOffset + 2 >= this.bCodeStream.length) {
1270
		resizeByteArray();
1271
	}
1272
	this.position++;
1273
	this.bCodeStream[this.classFileOffset++] = opcode;
1274
	writeUnsignedShort(this.constantPool.literalIndexForField(declaringClass, fieldName, signature));
1275
}
1276
1217
public void fload(int iArg) {
1277
public void fload(int iArg) {
1218
	this.countLabels = 0;
1278
	this.countLabels = 0;
1219
	this.stackDepth++;
1279
	this.stackDepth++;
Lines 1641-1647 Link Here
1641
	} else {
1701
	} else {
1642
		BranchLabel endLabel = new BranchLabel(this);
1702
		BranchLabel endLabel = new BranchLabel(this);
1643
		if (syntheticFieldBinding != null) { // non interface case
1703
		if (syntheticFieldBinding != null) { // non interface case
1644
			getstatic(syntheticFieldBinding);
1704
			fieldAccess0(Opcodes.OPC_getstatic, syntheticFieldBinding, null /* default declaringClass */);
1645
			dup();
1705
			dup();
1646
			ifnonnull(endLabel);
1706
			ifnonnull(endLabel);
1647
			pop();
1707
			pop();
Lines 1684-1690 Link Here
1684
1744
1685
		if (syntheticFieldBinding != null) { // non interface case
1745
		if (syntheticFieldBinding != null) { // non interface case
1686
			dup();
1746
			dup();
1687
			putstatic(syntheticFieldBinding);
1747
			fieldAccess0(Opcodes.OPC_putstatic, syntheticFieldBinding, null /* default declaringClass */);
1688
		}
1748
		}
1689
		goto_(endLabel);
1749
		goto_(endLabel);
1690
1750
Lines 1877-1933 Link Here
1877
	invokeAccessibleObjectSetAccessible();
1937
	invokeAccessibleObjectSetAccessible();
1878
}
1938
}
1879
1939
1880
private void generateFieldAccess(byte opcode, int returnTypeSize, char[] declaringClass, char[] name, char[] signature) {
1881
	this.countLabels = 0;
1882
	switch(opcode) {
1883
		case Opcodes.OPC_getfield :
1884
			if (returnTypeSize == 2) {
1885
				this.stackDepth++;
1886
			}
1887
			break;
1888
		case Opcodes.OPC_getstatic :
1889
			if (returnTypeSize == 2) {
1890
				this.stackDepth += 2;
1891
			} else {
1892
				this.stackDepth++;
1893
			}
1894
			break;
1895
		case Opcodes.OPC_putfield :
1896
			if (returnTypeSize == 2) {
1897
				this.stackDepth -= 3;
1898
			} else {
1899
				this.stackDepth -= 2;
1900
			}
1901
			break;
1902
		case Opcodes.OPC_putstatic :
1903
			if (returnTypeSize == 2) {
1904
				this.stackDepth -= 2;
1905
			} else {
1906
				this.stackDepth--;
1907
			}
1908
	}
1909
	if (this.stackDepth > this.stackMax) {
1910
		this.stackMax = this.stackDepth;
1911
	}
1912
	if (this.classFileOffset + 2 >= this.bCodeStream.length) {
1913
		resizeByteArray();
1914
	}
1915
	this.position++;
1916
	this.bCodeStream[this.classFileOffset++] = opcode;
1917
	writeUnsignedShort(this.constantPool.literalIndexForField(declaringClass, name, signature));
1918
}
1919
1920
private void generateFieldAccess(byte opcode, int returnTypeSize, ReferenceBinding binding, char[] name, TypeBinding type) {
1921
	if (binding.isNestedType()) {
1922
		this.classFile.recordInnerClasses(binding);
1923
	}
1924
	TypeBinding leafComponentType = type.leafComponentType();
1925
	if (leafComponentType.isNestedType()) {
1926
		this.classFile.recordInnerClasses(leafComponentType);
1927
	}
1928
	this.generateFieldAccess(opcode, returnTypeSize, binding.constantPoolName(), name, type.signature());
1929
}
1930
1931
/**
1940
/**
1932
 * Generates the sequence of instructions which will perform the conversion of the expression
1941
 * Generates the sequence of instructions which will perform the conversion of the expression
1933
 * on the stack into a different type (e.g. long l = someInt; --> i2l must be inserted).
1942
 * on the stack into a different type (e.g. long l = someInt; --> i2l must be inserted).
Lines 2251-2264 Link Here
2251
	} else if (mappingSequence[0] instanceof FieldBinding) {
2260
	} else if (mappingSequence[0] instanceof FieldBinding) {
2252
		FieldBinding fieldBinding = (FieldBinding) mappingSequence[0];
2261
		FieldBinding fieldBinding = (FieldBinding) mappingSequence[0];
2253
		aload_0();
2262
		aload_0();
2254
		getfield(fieldBinding);
2263
		fieldAccess0(Opcodes.OPC_getfield, fieldBinding, null /* default declaringClass */);
2255
	} else {
2264
	} else {
2256
		load((LocalVariableBinding) mappingSequence[0]);
2265
		load((LocalVariableBinding) mappingSequence[0]);
2257
	}
2266
	}
2258
	for (int i = 1, length = mappingSequence.length; i < length; i++) {
2267
	for (int i = 1, length = mappingSequence.length; i < length; i++) {
2259
		if (mappingSequence[i] instanceof FieldBinding) {
2268
		if (mappingSequence[i] instanceof FieldBinding) {
2260
			FieldBinding fieldBinding = (FieldBinding) mappingSequence[i];
2269
			FieldBinding fieldBinding = (FieldBinding) mappingSequence[i];
2261
			getfield(fieldBinding);
2270
			fieldAccess0(Opcodes.OPC_getfield, fieldBinding, null /* default declaringClass */);
2262
		} else {
2271
		} else {
2263
			invoke(Opcodes.OPC_invokestatic, (MethodBinding) mappingSequence[i], null /* default declaringClass */);
2272
			invoke(Opcodes.OPC_invokestatic, (MethodBinding) mappingSequence[i], null /* default declaringClass */);
2264
		}
2273
		}
Lines 2400-2410 Link Here
2400
//}
2409
//}
2401
public void generateSyntheticBodyForEnumValues(SyntheticMethodBinding methodBinding) {
2410
public void generateSyntheticBodyForEnumValues(SyntheticMethodBinding methodBinding) {
2402
	ClassScope scope = ((SourceTypeBinding)methodBinding.declaringClass).scope;
2411
	ClassScope scope = ((SourceTypeBinding)methodBinding.declaringClass).scope;
2403
	FieldBinding enumValuesSyntheticfield = scope.referenceContext.enumValuesSyntheticfield;
2404
	initializeMaxLocals(methodBinding);
2412
	initializeMaxLocals(methodBinding);
2405
	TypeBinding enumArray = methodBinding.returnType;
2413
	TypeBinding enumArray = methodBinding.returnType;
2406
2414
	fieldAccess0(Opcodes.OPC_getstatic, scope.referenceContext.enumValuesSyntheticfield, null /* default declaringClass */);
2407
	getstatic(enumValuesSyntheticfield);
2408
	dup();
2415
	dup();
2409
	astore_0();
2416
	astore_0();
2410
	iconst_0();
2417
	iconst_0();
Lines 2425-2435 Link Here
2425
public void generateSyntheticBodyForFieldReadAccess(SyntheticMethodBinding accessBinding) {
2432
public void generateSyntheticBodyForFieldReadAccess(SyntheticMethodBinding accessBinding) {
2426
	initializeMaxLocals(accessBinding);
2433
	initializeMaxLocals(accessBinding);
2427
	FieldBinding fieldBinding = accessBinding.targetReadField;
2434
	FieldBinding fieldBinding = accessBinding.targetReadField;
2428
	if (fieldBinding.isStatic())
2435
	if (fieldBinding.isStatic()) {
2429
		getstatic(fieldBinding);
2436
		fieldAccess0(Opcodes.OPC_getstatic, fieldBinding, null /* default declaringClass */);
2430
	else {
2437
	} else {
2431
		aload_0();
2438
		aload_0();
2432
		getfield(fieldBinding);
2439
		fieldAccess0(Opcodes.OPC_getfield, fieldBinding, null /* default declaringClass */);
2433
	}
2440
	}
2434
	switch (fieldBinding.type.id) {
2441
	switch (fieldBinding.type.id) {
2435
//		case T_void :
2442
//		case T_void :
Lines 2461-2471 Link Here
2461
	FieldBinding fieldBinding = accessBinding.targetWriteField;
2468
	FieldBinding fieldBinding = accessBinding.targetWriteField;
2462
	if (fieldBinding.isStatic()) {
2469
	if (fieldBinding.isStatic()) {
2463
		load(fieldBinding.type, 0);
2470
		load(fieldBinding.type, 0);
2464
		putstatic(fieldBinding);
2471
		fieldAccess0(Opcodes.OPC_putstatic, fieldBinding, null /* default declaringClass */);
2465
	} else {
2472
	} else {
2466
		aload_0();
2473
		aload_0();
2467
		load(fieldBinding.type, 1);
2474
		load(fieldBinding.type, 1);
2468
		putfield(fieldBinding);
2475
		fieldAccess0(Opcodes.OPC_putfield, fieldBinding, null /* default declaringClass */);
2469
	}
2476
	}
2470
	return_();
2477
	return_();
2471
}
2478
}
Lines 2551-2557 Link Here
2551
	initializeMaxLocals(methodBinding);
2558
	initializeMaxLocals(methodBinding);
2552
	final BranchLabel nullLabel = new BranchLabel(this);
2559
	final BranchLabel nullLabel = new BranchLabel(this);
2553
	FieldBinding syntheticFieldBinding = methodBinding.targetReadField;
2560
	FieldBinding syntheticFieldBinding = methodBinding.targetReadField;
2554
	getstatic(syntheticFieldBinding);
2561
	fieldAccess0(Opcodes.OPC_getstatic, syntheticFieldBinding, null /* default declaringClass */);
2555
	dup();
2562
	dup();
2556
	ifnull(nullLabel);
2563
	ifnull(nullLabel);
2557
	areturn();
2564
	areturn();
Lines 2575-2581 Link Here
2575
				final ExceptionLabel anyExceptionHandler = new ExceptionLabel(this, TypeBinding.LONG /* represents NoSuchFieldError*/);
2582
				final ExceptionLabel anyExceptionHandler = new ExceptionLabel(this, TypeBinding.LONG /* represents NoSuchFieldError*/);
2576
				anyExceptionHandler.placeStart();
2583
				anyExceptionHandler.placeStart();
2577
				aload_0();
2584
				aload_0();
2578
				getstatic(fieldBinding);
2585
				fieldAccess0(Opcodes.OPC_getstatic, fieldBinding, null /* default declaringClass */);
2579
				invokeEnumOrdinal(enumBinding.constantPoolName());
2586
				invokeEnumOrdinal(enumBinding.constantPoolName());
2580
				this.generateInlinedValue(fieldBinding.id + 1); // zero should not be returned see bug 141810
2587
				this.generateInlinedValue(fieldBinding.id + 1); // zero should not be returned see bug 141810
2581
				iastore();
2588
				iastore();
Lines 2591-2597 Link Here
2591
	}
2598
	}
2592
	aload_0();
2599
	aload_0();
2593
	dup();
2600
	dup();
2594
	putstatic(syntheticFieldBinding);
2601
	fieldAccess0(Opcodes.OPC_putstatic, syntheticFieldBinding, null /* default declaringClass */);
2595
	areturn();
2602
	areturn();
2596
	removeVariable(localVariableBinding);
2603
	removeVariable(localVariableBinding);
2597
}
2604
}
Lines 2868-2983 Link Here
2868
	return contents;
2875
	return contents;
2869
}
2876
}
2870
2877
2871
public void getfield(FieldBinding fieldBinding) {
2878
protected static TypeBinding getConstantPoolDeclaringClass(BlockScope currentScope, FieldBinding fieldBinding, TypeBinding actualReceiverType, boolean isImplicitThisReceiver) {
2872
	int returnTypeSize = 1;
2879
	FieldBinding codegenBinding = fieldBinding.original();
2873
	if ((fieldBinding.type.id == TypeIds.T_double) || (fieldBinding.type.id == TypeIds.T_long)) {
2880
	ReferenceBinding constantPoolDeclaringClass = codegenBinding.declaringClass;
2874
		returnTypeSize = 2;
2881
	// if the binding declaring class is not visible, need special action
2875
	}
2882
	// for runtime compatibility on 1.2 VMs : change the declaring class of the binding
2876
	generateFieldAccess(
2883
	// NOTE: from target 1.2 on, field's declaring class is touched if any different from receiver type
2877
			Opcodes.OPC_getfield,
2884
	// and not from Object or implicit static field access.
2878
			returnTypeSize,
2885
	if (constantPoolDeclaringClass != actualReceiverType.erasure()
2879
			fieldBinding.declaringClass,
2886
			&& !actualReceiverType.isArrayType()
2880
			fieldBinding.name,
2887
			&& constantPoolDeclaringClass != null // array.length
2881
			fieldBinding.type);
2888
			&& codegenBinding.constant() == Constant.NotAConstant) {
2889
		CompilerOptions options = currentScope.compilerOptions();
2890
		if ((options.targetJDK >= ClassFileConstants.JDK1_2
2891
					&& (options.complianceLevel >= ClassFileConstants.JDK1_4 || !(isImplicitThisReceiver && codegenBinding.isStatic()))
2892
					&& constantPoolDeclaringClass.id != TypeIds.T_JavaLangObject) // no change for Object fields
2893
				|| !constantPoolDeclaringClass.canBeSeenBy(currentScope)) {
2894
2895
			return actualReceiverType.erasure();
2896
		}
2897
	}	
2898
	return constantPoolDeclaringClass;
2882
}
2899
}
2883
2900
2884
protected int getPosition() {
2901
protected int getPosition() {
2885
	return this.position;
2902
	return this.position;
2886
}
2903
}
2887
2904
2888
public void getstatic(FieldBinding fieldBinding) {
2889
	int returnTypeSize = 1;
2890
	if ((fieldBinding.type.id == TypeIds.T_double) || (fieldBinding.type.id == TypeIds.T_long)) {
2891
		returnTypeSize = 2;
2892
	}
2893
	generateFieldAccess(
2894
			Opcodes.OPC_getstatic,
2895
			returnTypeSize,
2896
			fieldBinding.declaringClass,
2897
			fieldBinding.name,
2898
			fieldBinding.type);
2899
}
2900
2901
public void getTYPE(int baseTypeID) {
2905
public void getTYPE(int baseTypeID) {
2902
	this.countLabels = 0;
2906
	this.countLabels = 0;
2903
	switch (baseTypeID) {
2907
	switch (baseTypeID) {
2904
		case TypeIds.T_byte :
2908
		case TypeIds.T_byte :
2905
			// getstatic: java.lang.Byte.TYPE
2909
			// getstatic: java.lang.Byte.TYPE
2906
			generateFieldAccess(
2910
			fieldAccess(
2907
					Opcodes.OPC_getstatic,
2911
					Opcodes.OPC_getstatic,
2908
					1,
2912
					1, // return type size
2909
					ConstantPool.JavaLangByteConstantPoolName,
2913
					ConstantPool.JavaLangByteConstantPoolName,
2910
					ConstantPool.TYPE,
2914
					ConstantPool.TYPE,
2911
					ConstantPool.JavaLangClassSignature);
2915
					ConstantPool.JavaLangClassSignature);
2912
			break;
2916
			break;
2913
		case TypeIds.T_short :
2917
		case TypeIds.T_short :
2914
			// getstatic: java.lang.Short.TYPE
2918
			// getstatic: java.lang.Short.TYPE
2915
			generateFieldAccess(
2919
			fieldAccess(
2916
					Opcodes.OPC_getstatic,
2920
					Opcodes.OPC_getstatic,
2917
					1,
2921
					1, // return type size
2918
					ConstantPool.JavaLangShortConstantPoolName,
2922
					ConstantPool.JavaLangShortConstantPoolName,
2919
					ConstantPool.TYPE,
2923
					ConstantPool.TYPE,
2920
					ConstantPool.JavaLangClassSignature);
2924
					ConstantPool.JavaLangClassSignature);
2921
			break;
2925
			break;
2922
		case TypeIds.T_char :
2926
		case TypeIds.T_char :
2923
			// getstatic: java.lang.Character.TYPE
2927
			// getstatic: java.lang.Character.TYPE
2924
			generateFieldAccess(
2928
			fieldAccess(
2925
					Opcodes.OPC_getstatic,
2929
					Opcodes.OPC_getstatic,
2926
					1,
2930
					1, // return type size
2927
					ConstantPool.JavaLangCharacterConstantPoolName,
2931
					ConstantPool.JavaLangCharacterConstantPoolName,
2928
					ConstantPool.TYPE,
2932
					ConstantPool.TYPE,
2929
					ConstantPool.JavaLangClassSignature);
2933
					ConstantPool.JavaLangClassSignature);
2930
			break;
2934
			break;
2931
		case TypeIds.T_int :
2935
		case TypeIds.T_int :
2932
			// getstatic: java.lang.Integer.TYPE
2936
			// getstatic: java.lang.Integer.TYPE
2933
			generateFieldAccess(
2937
			fieldAccess(
2934
					Opcodes.OPC_getstatic,
2938
					Opcodes.OPC_getstatic,
2935
					1,
2939
					1, // return type size
2936
					ConstantPool.JavaLangIntegerConstantPoolName,
2940
					ConstantPool.JavaLangIntegerConstantPoolName,
2937
					ConstantPool.TYPE,
2941
					ConstantPool.TYPE,
2938
					ConstantPool.JavaLangClassSignature);
2942
					ConstantPool.JavaLangClassSignature);
2939
			break;
2943
			break;
2940
		case TypeIds.T_long :
2944
		case TypeIds.T_long :
2941
			// getstatic: java.lang.Long.TYPE
2945
			// getstatic: java.lang.Long.TYPE
2942
			generateFieldAccess(
2946
			fieldAccess(
2943
					Opcodes.OPC_getstatic,
2947
					Opcodes.OPC_getstatic,
2944
					1,
2948
					1, // return type size
2945
					ConstantPool.JavaLangLongConstantPoolName,
2949
					ConstantPool.JavaLangLongConstantPoolName,
2946
					ConstantPool.TYPE,
2950
					ConstantPool.TYPE,
2947
					ConstantPool.JavaLangClassSignature);
2951
					ConstantPool.JavaLangClassSignature);
2948
			break;
2952
			break;
2949
		case TypeIds.T_float :
2953
		case TypeIds.T_float :
2950
			// getstatic: java.lang.Float.TYPE
2954
			// getstatic: java.lang.Float.TYPE
2951
			generateFieldAccess(
2955
			fieldAccess(
2952
					Opcodes.OPC_getstatic,
2956
					Opcodes.OPC_getstatic,
2953
					1,
2957
					1, // return type size
2954
					ConstantPool.JavaLangFloatConstantPoolName,
2958
					ConstantPool.JavaLangFloatConstantPoolName,
2955
					ConstantPool.TYPE,
2959
					ConstantPool.TYPE,
2956
					ConstantPool.JavaLangClassSignature);
2960
					ConstantPool.JavaLangClassSignature);
2957
			break;
2961
			break;
2958
		case TypeIds.T_double :
2962
		case TypeIds.T_double :
2959
			// getstatic: java.lang.Double.TYPE
2963
			// getstatic: java.lang.Double.TYPE
2960
			generateFieldAccess(
2964
			fieldAccess(
2961
					Opcodes.OPC_getstatic,
2965
					Opcodes.OPC_getstatic,
2962
					1,
2966
					1, // return type size
2963
					ConstantPool.JavaLangDoubleConstantPoolName,
2967
					ConstantPool.JavaLangDoubleConstantPoolName,
2964
					ConstantPool.TYPE,
2968
					ConstantPool.TYPE,
2965
					ConstantPool.JavaLangClassSignature);
2969
					ConstantPool.JavaLangClassSignature);
2966
			break;
2970
			break;
2967
		case TypeIds.T_boolean :
2971
		case TypeIds.T_boolean :
2968
			// getstatic: java.lang.Boolean.TYPE
2972
			// getstatic: java.lang.Boolean.TYPE
2969
			generateFieldAccess(
2973
			fieldAccess(
2970
					Opcodes.OPC_getstatic,
2974
					Opcodes.OPC_getstatic,
2971
					1,
2975
					1, // return type size
2972
					ConstantPool.JavaLangBooleanConstantPoolName,
2976
					ConstantPool.JavaLangBooleanConstantPoolName,
2973
					ConstantPool.TYPE,
2977
					ConstantPool.TYPE,
2974
					ConstantPool.JavaLangClassSignature);
2978
					ConstantPool.JavaLangClassSignature);
2975
			break;
2979
			break;
2976
		case TypeIds.T_void :
2980
		case TypeIds.T_void :
2977
			// getstatic: java.lang.Void.TYPE
2981
			// getstatic: java.lang.Void.TYPE
2978
			generateFieldAccess(
2982
			fieldAccess(
2979
					Opcodes.OPC_getstatic,
2983
					Opcodes.OPC_getstatic,
2980
					1,
2984
					1, // return type size
2981
					ConstantPool.JavaLangVoidConstantPoolName,
2985
					ConstantPool.JavaLangVoidConstantPoolName,
2982
					ConstantPool.TYPE,
2986
					ConstantPool.TYPE,
2983
					ConstantPool.JavaLangClassSignature);
2987
					ConstantPool.JavaLangClassSignature);
Lines 3740-3745 Link Here
3740
	writeUnsignedShort(this.constantPool.literalIndexForType(typeBinding));
3744
	writeUnsignedShort(this.constantPool.literalIndexForType(typeBinding));
3741
}
3745
}
3742
3746
3747
protected void invoke(byte opcode, int receiverAndArgsSize, int returnTypeSize, char[] declaringClass, char[] selector, char[] signature) {
3748
	this.countLabels = 0;
3749
	if (opcode == Opcodes.OPC_invokeinterface) {
3750
		// invokeinterface
3751
		if (this.classFileOffset + 4 >= this.bCodeStream.length) {
3752
			resizeByteArray();
3753
		}
3754
		this.position +=3;
3755
		this.bCodeStream[this.classFileOffset++] = opcode;
3756
		writeUnsignedShort(this.constantPool.literalIndexForMethod(declaringClass, selector, signature, true));
3757
		this.bCodeStream[this.classFileOffset++] = (byte) receiverAndArgsSize;
3758
		this.bCodeStream[this.classFileOffset++] = 0;
3759
	} else {
3760
		// invokespecial
3761
		// invokestatic
3762
		// invokevirtual
3763
		if (this.classFileOffset + 2 >= this.bCodeStream.length) {
3764
			resizeByteArray();
3765
		}
3766
		this.position++;
3767
		this.bCodeStream[this.classFileOffset++] = opcode;
3768
		writeUnsignedShort(this.constantPool.literalIndexForMethod(declaringClass, selector, signature, false));
3769
	}
3770
	this.stackDepth += returnTypeSize - receiverAndArgsSize;
3771
	if (this.stackDepth > this.stackMax) {
3772
		this.stackMax = this.stackDepth;
3773
	}
3774
}
3775
3743
public void invoke(byte opcode, MethodBinding methodBinding, TypeBinding declaringClass) {
3776
public void invoke(byte opcode, MethodBinding methodBinding, TypeBinding declaringClass) {
3744
	if (declaringClass == null) declaringClass = methodBinding.declaringClass;
3777
	if (declaringClass == null) declaringClass = methodBinding.declaringClass;
3745
    if (declaringClass.isNestedType()) {
3778
    if (declaringClass.isNestedType()) {
Lines 3835-3869 Link Here
3835
			methodBinding.signature(this.classFile));
3868
			methodBinding.signature(this.classFile));
3836
}
3869
}
3837
3870
3838
protected void invoke(byte opcode, int receiverAndArgsSize, int returnTypeSize, char[] declaringClass, char[] selector, char[] signature) {
3839
	this.countLabels = 0;
3840
	if (opcode == Opcodes.OPC_invokeinterface) {
3841
		// invokeinterface
3842
		if (this.classFileOffset + 4 >= this.bCodeStream.length) {
3843
			resizeByteArray();
3844
		}
3845
		this.position +=3;
3846
		this.bCodeStream[this.classFileOffset++] = opcode;
3847
		writeUnsignedShort(this.constantPool.literalIndexForMethod(declaringClass, selector, signature, true));
3848
		this.bCodeStream[this.classFileOffset++] = (byte) receiverAndArgsSize;
3849
		this.bCodeStream[this.classFileOffset++] = 0;
3850
	} else {
3851
		// invokespecial
3852
		// invokestatic
3853
		// invokevirtual
3854
		if (this.classFileOffset + 2 >= this.bCodeStream.length) {
3855
			resizeByteArray();
3856
		}
3857
		this.position++;
3858
		this.bCodeStream[this.classFileOffset++] = opcode;
3859
		writeUnsignedShort(this.constantPool.literalIndexForMethod(declaringClass, selector, signature, false));
3860
	}
3861
	this.stackDepth += returnTypeSize - receiverAndArgsSize;
3862
	if (this.stackDepth > this.stackMax) {
3863
		this.stackMax = this.stackDepth;
3864
	}
3865
}
3866
3867
protected void invokeAccessibleObjectSetAccessible() {
3871
protected void invokeAccessibleObjectSetAccessible() {
3868
	// invokevirtual: java.lang.reflect.AccessibleObject.setAccessible(Z)V;
3872
	// invokevirtual: java.lang.reflect.AccessibleObject.setAccessible(Z)V;
3869
	invoke(
3873
	invoke(
Lines 5142-5148 Link Here
5142
	load(localBinding.type, localBinding.resolvedPosition);
5146
	load(localBinding.type, localBinding.resolvedPosition);
5143
}
5147
}
5144
5148
5145
public final void load(TypeBinding typeBinding, int resolvedPosition) {
5149
protected final void load(TypeBinding typeBinding, int resolvedPosition) {
5146
	this.countLabels = 0;
5150
	this.countLabels = 0;
5147
	// Using dedicated int bytecode
5151
	// Using dedicated int bytecode
5148
	switch(typeBinding.id) {
5152
	switch(typeBinding.id) {
Lines 5685-5716 Link Here
5685
		this.stackMax = this.stackDepth;
5689
		this.stackMax = this.stackDepth;
5686
}
5690
}
5687
5691
5688
public void putfield(FieldBinding fieldBinding) {
5689
	int returnTypeSize = 1;
5690
	if ((fieldBinding.type.id == TypeIds.T_double) || (fieldBinding.type.id == TypeIds.T_long)) {
5691
		returnTypeSize = 2;
5692
	}
5693
	generateFieldAccess(
5694
			Opcodes.OPC_putfield,
5695
			returnTypeSize,
5696
			fieldBinding.declaringClass,
5697
			fieldBinding.name,
5698
			fieldBinding.type);
5699
}
5700
5701
public void putstatic(FieldBinding fieldBinding) {
5702
	int returnTypeSize = 1;
5703
	if ((fieldBinding.type.id == TypeIds.T_double) || (fieldBinding.type.id == TypeIds.T_long)) {
5704
		returnTypeSize = 2;
5705
	}
5706
	generateFieldAccess(
5707
			Opcodes.OPC_putstatic,
5708
			returnTypeSize,
5709
			fieldBinding.declaringClass,
5710
			fieldBinding.name,
5711
			fieldBinding.type);
5712
}
5713
5714
public void record(LocalVariableBinding local) {
5692
public void record(LocalVariableBinding local) {
5715
	if ((this.generateAttributes & (ClassFileConstants.ATTR_VARS
5693
	if ((this.generateAttributes & (ClassFileConstants.ATTR_VARS
5716
			| ClassFileConstants.ATTR_STACK_MAP_TABLE
5694
			| ClassFileConstants.ATTR_STACK_MAP_TABLE
(-)compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrameCodeStream.java (-2 / +2 lines)
Lines 273-279 Link Here
273
		// use in CLDC mode
273
		// use in CLDC mode
274
		BranchLabel endLabel = new BranchLabel(this);
274
		BranchLabel endLabel = new BranchLabel(this);
275
		if (syntheticFieldBinding != null) { // non interface case
275
		if (syntheticFieldBinding != null) { // non interface case
276
			getstatic(syntheticFieldBinding);
276
			fieldAccess0(Opcodes.OPC_getstatic, syntheticFieldBinding, null /* default declaringClass */);
277
			dup();
277
			dup();
278
			ifnonnull(endLabel);
278
			ifnonnull(endLabel);
279
			pop();
279
			pop();
Lines 316-322 Link Here
316
316
317
		if (syntheticFieldBinding != null) { // non interface case
317
		if (syntheticFieldBinding != null) { // non interface case
318
			dup();
318
			dup();
319
			putstatic(syntheticFieldBinding);
319
			fieldAccess0(Opcodes.OPC_putstatic, syntheticFieldBinding, null /* default declaringClass */);
320
		}
320
		}
321
		int fromPC = this.position;
321
		int fromPC = this.position;
322
		goto_(endLabel);
322
		goto_(endLabel);
(-)eval/org/eclipse/jdt/internal/eval/CodeSnippetFieldReference.java (-112 / +88 lines)
Lines 15-33 Link Here
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;
16
import org.eclipse.jdt.internal.compiler.ast.FieldReference;
17
import org.eclipse.jdt.internal.compiler.ast.IntLiteral;
17
import org.eclipse.jdt.internal.compiler.ast.IntLiteral;
18
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
19
import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
18
import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
19
import org.eclipse.jdt.internal.compiler.codegen.Opcodes;
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;
22
import org.eclipse.jdt.internal.compiler.impl.Constant;
21
import org.eclipse.jdt.internal.compiler.impl.Constant;
23
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
22
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
24
import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
23
import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
25
import org.eclipse.jdt.internal.compiler.lookup.ParameterizedFieldBinding;
26
import org.eclipse.jdt.internal.compiler.lookup.ProblemFieldBinding;
24
import org.eclipse.jdt.internal.compiler.lookup.ProblemFieldBinding;
27
import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons;
25
import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons;
28
import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
29
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
26
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
30
import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding;
27
import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
31
28
32
public class CodeSnippetFieldReference extends FieldReference implements ProblemReasons, EvaluationConstants {
29
public class CodeSnippetFieldReference extends FieldReference implements ProblemReasons, EvaluationConstants {
33
30
Lines 43-68 Link Here
43
	this.evaluationContext = evaluationContext;
40
	this.evaluationContext = evaluationContext;
44
}
41
}
45
public void generateAssignment(BlockScope currentScope, CodeStream codeStream, Assignment assignment, boolean valueRequired) {
42
public void generateAssignment(BlockScope currentScope, CodeStream codeStream, Assignment assignment, boolean valueRequired) {
46
43
	FieldBinding codegenBinding = this.binding.original();
47
	if (this.codegenBinding.canBeSeenBy(this.receiverType, this, currentScope)) {
44
	if (codegenBinding.canBeSeenBy(this.actualReceiverType, this, currentScope)) {
48
		this.receiver.generateCode(currentScope, codeStream, !this.codegenBinding.isStatic());
45
		this.receiver.generateCode(currentScope, codeStream, !codegenBinding.isStatic());
49
		assignment.expression.generateCode(currentScope, codeStream, true);
46
		assignment.expression.generateCode(currentScope, codeStream, true);
50
		fieldStore(codeStream, this.codegenBinding, null, valueRequired);
47
		fieldStore(codeStream, codegenBinding, null, valueRequired);
51
	} else {
48
	} else {
52
		codeStream.generateEmulationForField(this.codegenBinding);
49
		codeStream.generateEmulationForField(codegenBinding);
53
		this.receiver.generateCode(currentScope, codeStream, !this.codegenBinding.isStatic());
50
		this.receiver.generateCode(currentScope, codeStream, !codegenBinding.isStatic());
54
		if (this.codegenBinding.isStatic()) { // need a receiver?
51
		if (codegenBinding.isStatic()) { // need a receiver?
55
			codeStream.aconst_null();
52
			codeStream.aconst_null();
56
		}
53
		}
57
		assignment.expression.generateCode(currentScope, codeStream, true);
54
		assignment.expression.generateCode(currentScope, codeStream, true);
58
		if (valueRequired) {
55
		if (valueRequired) {
59
			if ((this.codegenBinding.type == TypeBinding.LONG) || (this.codegenBinding.type == TypeBinding.DOUBLE)) {
56
			switch (codegenBinding.type.id) {
60
				codeStream.dup2_x2();
57
				case TypeIds.T_long :
61
			} else {
58
				case TypeIds.T_double :
62
				codeStream.dup_x2();
59
					codeStream.dup2_x2();
63
			}
60
					break;
61
				default :
62
					codeStream.dup_x2();
63
					break;
64
			}			
64
		}
65
		}
65
		codeStream.generateEmulatedWriteAccessForField(this.codegenBinding);
66
		codeStream.generateEmulatedWriteAccessForField(codegenBinding);
66
	}
67
	}
67
	if (valueRequired){
68
	if (valueRequired){
68
		codeStream.generateImplicitConversion(assignment.implicitConversion);
69
		codeStream.generateImplicitConversion(assignment.implicitConversion);
Lines 76-108 Link Here
76
 * @param valueRequired boolean
77
 * @param valueRequired boolean
77
 */
78
 */
78
public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
79
public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
79
80
	int pc = codeStream.position;
80
	int pc = codeStream.position;
81
	if (this.constant != Constant.NotAConstant) {
81
	if (this.constant != Constant.NotAConstant) {
82
		if (valueRequired) {
82
		if (valueRequired) {
83
			codeStream.generateConstant(this.constant, this.implicitConversion);
83
			codeStream.generateConstant(this.constant, this.implicitConversion);
84
		}
84
		}
85
	} else {
85
	} else {
86
		boolean isStatic = this.codegenBinding.isStatic();
86
		FieldBinding codegenBinding = this.binding.original();
87
		boolean isStatic = codegenBinding.isStatic();
87
		this.receiver.generateCode(currentScope, codeStream, !isStatic);
88
		this.receiver.generateCode(currentScope, codeStream, !isStatic);
88
		if (valueRequired) {
89
		if (valueRequired) {
89
			Constant fieldConstant = this.codegenBinding.constant();
90
			Constant fieldConstant = codegenBinding.constant();
90
			if (fieldConstant == Constant.NotAConstant) {
91
			if (fieldConstant == Constant.NotAConstant) {
91
				if (this.codegenBinding.declaringClass == null) { // array length
92
				if (codegenBinding.declaringClass == null) { // array length
92
					codeStream.arraylength();
93
					codeStream.arraylength();
93
				} else {
94
				} else {
94
					if (this.codegenBinding.canBeSeenBy(this.receiverType, this, currentScope)) {
95
					if (codegenBinding.canBeSeenBy(this.actualReceiverType, this, currentScope)) {
96
						TypeBinding someReceiverType = this.delegateThis != null ? this.delegateThis.type : this.actualReceiverType;
97
						TypeBinding constantPoolDeclaringClass = getConstantPoolDeclaringClass(currentScope, codegenBinding, someReceiverType, this.receiver.isImplicitThis());
95
						if (isStatic) {
98
						if (isStatic) {
96
							codeStream.getstatic(this.codegenBinding);
99
							codeStream.fieldAccess0(Opcodes.OPC_getstatic , codegenBinding, constantPoolDeclaringClass);
97
						} else {
100
						} else {
98
							codeStream.getfield(this.codegenBinding);
101
							codeStream.fieldAccess0(Opcodes.OPC_getfield, codegenBinding, constantPoolDeclaringClass);
99
						}
102
						}
100
					} else {
103
					} else {
101
						if (isStatic) {
104
						if (isStatic) {
102
							// we need a null on the stack to use the reflect emulation
105
							// we need a null on the stack to use the reflect emulation
103
							codeStream.aconst_null();
106
							codeStream.aconst_null();
104
						}
107
						}
105
						codeStream.generateEmulatedReadAccessForField(this.codegenBinding);
108
						codeStream.generateEmulatedReadAccessForField(codegenBinding);
106
					}
109
					}
107
				}
110
				}
108
				codeStream.generateImplicitConversion(this.implicitConversion);
111
				codeStream.generateImplicitConversion(this.implicitConversion);
Lines 124-138 Link Here
124
}
127
}
125
128
126
public void generateCompoundAssignment(BlockScope currentScope, CodeStream codeStream, Expression expression, int operator, int assignmentImplicitConversion, boolean valueRequired) {
129
public void generateCompoundAssignment(BlockScope currentScope, CodeStream codeStream, Expression expression, int operator, int assignmentImplicitConversion, boolean valueRequired) {
127
128
	boolean isStatic;
130
	boolean isStatic;
129
	if (this.codegenBinding.canBeSeenBy(this.receiverType, this, currentScope)) {
131
	FieldBinding codegenBinding = this.binding.original();
130
		this.receiver.generateCode(currentScope, codeStream, !(isStatic = this.codegenBinding.isStatic()));
132
	if (codegenBinding.canBeSeenBy(this.actualReceiverType, this, currentScope)) {
133
		this.receiver.generateCode(currentScope, codeStream, !(isStatic = codegenBinding.isStatic()));
134
		TypeBinding someReceiverType = this.delegateThis != null ? this.delegateThis.type : this.actualReceiverType;
135
		TypeBinding constantPoolDeclaringClass = getConstantPoolDeclaringClass(currentScope, codegenBinding, someReceiverType, this.receiver.isImplicitThis());
131
		if (isStatic) {
136
		if (isStatic) {
132
			codeStream.getstatic(this.codegenBinding);
137
			codeStream.fieldAccess0(Opcodes.OPC_getstatic, codegenBinding, constantPoolDeclaringClass);
133
		} else {
138
		} else {
134
			codeStream.dup();
139
			codeStream.dup();
135
			codeStream.getfield(this.codegenBinding);
140
			codeStream.fieldAccess0(Opcodes.OPC_getfield, codegenBinding, constantPoolDeclaringClass);
136
		}
141
		}
137
		int operationTypeID;
142
		int operationTypeID;
138
		switch(operationTypeID = (this.implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4) {
143
		switch(operationTypeID = (this.implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4) {
Lines 155-171 Link Here
155
				// cast the value back to the array reference type
160
				// cast the value back to the array reference type
156
				codeStream.generateImplicitConversion(assignmentImplicitConversion);
161
				codeStream.generateImplicitConversion(assignmentImplicitConversion);
157
		}
162
		}
158
		fieldStore(codeStream, this.codegenBinding, null, valueRequired);
163
		fieldStore(codeStream, codegenBinding, null, valueRequired);
159
	} else {
164
	} else {
160
		this.receiver.generateCode(currentScope, codeStream, !(isStatic = this.codegenBinding.isStatic()));
165
		this.receiver.generateCode(currentScope, codeStream, !(isStatic = codegenBinding.isStatic()));
161
		if (isStatic) {
166
		if (isStatic) {
162
			// used to store the value
167
			// used to store the value
163
			codeStream.generateEmulationForField(this.codegenBinding);
168
			codeStream.generateEmulationForField(codegenBinding);
164
			codeStream.aconst_null();
169
			codeStream.aconst_null();
165
170
166
			// used to retrieve the actual value
171
			// used to retrieve the actual value
167
			codeStream.aconst_null();
172
			codeStream.aconst_null();
168
			codeStream.generateEmulatedReadAccessForField(this.codegenBinding);
173
			codeStream.generateEmulatedReadAccessForField(codegenBinding);
169
		} else {
174
		} else {
170
			// used to store the value
175
			// used to store the value
171
			codeStream.generateEmulationForField(this.binding);
176
			codeStream.generateEmulationForField(this.binding);
Lines 173-179 Link Here
173
178
174
			// used to retrieve the actual value
179
			// used to retrieve the actual value
175
			codeStream.dup();
180
			codeStream.dup();
176
			codeStream.generateEmulatedReadAccessForField(this.codegenBinding);
181
			codeStream.generateEmulatedReadAccessForField(codegenBinding);
177
		}
182
		}
178
		int operationTypeID;
183
		int operationTypeID;
179
		if ((operationTypeID = (this.implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4) == T_JavaLangString) {
184
		if ((operationTypeID = (this.implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4) == T_JavaLangString) {
Lines 195-201 Link Here
195
		// current stack is:
200
		// current stack is:
196
		// field receiver value
201
		// field receiver value
197
		if (valueRequired) {
202
		if (valueRequired) {
198
			if ((this.codegenBinding.type == TypeBinding.LONG) || (this.codegenBinding.type == TypeBinding.DOUBLE)) {
203
			if ((codegenBinding.type == TypeBinding.LONG) || (codegenBinding.type == TypeBinding.DOUBLE)) {
199
				codeStream.dup2_x2();
204
				codeStream.dup2_x2();
200
			} else {
205
			} else {
201
				codeStream.dup_x2();
206
				codeStream.dup_x2();
Lines 203-263 Link Here
203
		}
208
		}
204
		// current stack is:
209
		// current stack is:
205
		// value field receiver value
210
		// value field receiver value
206
		codeStream.generateEmulatedWriteAccessForField(this.codegenBinding);
211
		codeStream.generateEmulatedWriteAccessForField(codegenBinding);
207
	}
212
	}
208
}
213
}
209
public void generatePostIncrement(BlockScope currentScope, CodeStream codeStream, CompoundAssignment postIncrement, boolean valueRequired) {
214
public void generatePostIncrement(BlockScope currentScope, CodeStream codeStream, CompoundAssignment postIncrement, boolean valueRequired) {
210
	boolean isStatic;
215
	boolean isStatic;
211
	if (this.codegenBinding.canBeSeenBy(this.receiverType, this, currentScope)) {
216
	FieldBinding codegenBinding = this.binding.original();
217
	if (codegenBinding.canBeSeenBy(this.actualReceiverType, this, currentScope)) {
212
		super.generatePostIncrement(currentScope, codeStream, postIncrement, valueRequired);
218
		super.generatePostIncrement(currentScope, codeStream, postIncrement, valueRequired);
213
	} else {
219
	} else {
214
		this.receiver.generateCode(currentScope, codeStream, !(isStatic = this.codegenBinding.isStatic()));
220
		this.receiver.generateCode(currentScope, codeStream, !(isStatic = codegenBinding.isStatic()));
215
		if (isStatic) {
221
		if (isStatic) {
216
			codeStream.aconst_null();
222
			codeStream.aconst_null();
217
		}
223
		}
218
		// the actual stack is: receiver
224
		// the actual stack is: receiver
219
		codeStream.dup();
225
		codeStream.dup();
220
		// the actual stack is: receiver receiver
226
		// the actual stack is: receiver receiver
221
		codeStream.generateEmulatedReadAccessForField(this.codegenBinding);
227
		codeStream.generateEmulatedReadAccessForField(codegenBinding);
222
		// the actual stack is: receiver value
228
		// the actual stack is: receiver value
223
		// receiver value
229
		// receiver value
224
		// value receiver value 							dup_x1 or dup2_x1 if value required
230
		// value receiver value 							dup_x1 or dup2_x1 if value required
225
		// value value receiver value						dup_x1 or dup2_x1
231
		// value value receiver value					dup_x1 or dup2_x1
226
		// value value receiver								pop or pop2
232
		// value value receiver							pop or pop2
227
		// value value receiver field						generateEmulationForField
233
		// value value receiver field						generateEmulationForField
228
		// value value field receiver 						swap
234
		// value value field receiver 					swap
229
		// value field receiver value field receiver 		dup2_x1 or dup2_x2
235
		// value field receiver value field receiver 	dup2_x1 or dup2_x2
230
		// value field receiver value 				 		pop2
236
		// value field receiver value 				 	pop2
231
		// value field receiver newvalue 				 	generate constant + op
237
		// value field receiver newvalue 				generate constant + op
232
		// value 											store
238
		// value 												store
233
		if (valueRequired) {
239
		int typeID;
234
			if ((this.codegenBinding.type == TypeBinding.LONG) || (this.codegenBinding.type == TypeBinding.DOUBLE)) {
240
		switch (typeID = codegenBinding.type.id) {
241
			case TypeIds.T_long :
242
			case TypeIds.T_double :
243
				if (valueRequired) {
244
					codeStream.dup2_x1();
245
				}
235
				codeStream.dup2_x1();
246
				codeStream.dup2_x1();
236
			} else {
247
				codeStream.pop2();
248
				break;
249
			default :
250
				if (valueRequired) {
251
					codeStream.dup_x1();
252
				}
237
				codeStream.dup_x1();
253
				codeStream.dup_x1();
238
			}
254
				codeStream.pop();
239
		}
255
				break;
240
		if ((this.codegenBinding.type == TypeBinding.LONG) || (this.codegenBinding.type == TypeBinding.DOUBLE)) {
241
			codeStream.dup2_x1();
242
			codeStream.pop2();
243
		} else {
244
			codeStream.dup_x1();
245
			codeStream.pop();
246
		}
256
		}
247
		codeStream.generateEmulationForField(this.codegenBinding);
257
		codeStream.generateEmulationForField(codegenBinding);
248
		codeStream.swap();
258
		codeStream.swap();
249
259
		switch (typeID) {
250
		if ((this.codegenBinding.type == TypeBinding.LONG) || (this.codegenBinding.type == TypeBinding.DOUBLE)) {
260
			case TypeIds.T_long :
251
			codeStream.dup2_x2();
261
			case TypeIds.T_double :
252
		} else {
262
				codeStream.dup2_x2();
253
			codeStream.dup2_x1();
263
				break;
264
			default :
265
				codeStream.dup2_x1();
266
				break;
254
		}
267
		}
255
		codeStream.pop2();
268
		codeStream.pop2();
256
269
257
		codeStream.generateConstant(postIncrement.expression.constant, this.implicitConversion);
270
		codeStream.generateConstant(postIncrement.expression.constant, this.implicitConversion);
258
		codeStream.sendOperator(postIncrement.operator, this.codegenBinding.type.id);
271
		codeStream.sendOperator(postIncrement.operator, codegenBinding.type.id);
259
		codeStream.generateImplicitConversion(postIncrement.preAssignImplicitConversion);
272
		codeStream.generateImplicitConversion(postIncrement.preAssignImplicitConversion);
260
		codeStream.generateEmulatedWriteAccessForField(this.codegenBinding);
273
		codeStream.generateEmulatedWriteAccessForField(codegenBinding);
261
	}
274
	}
262
}
275
}
263
/*
276
/*
Lines 267-309 Link Here
267
	// The private access will be managed through the code generation
280
	// The private access will be managed through the code generation
268
281
269
	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) != 0) return;
282
	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) != 0) return;
270
271
	// if field from parameterized type got found, use the original field at codegen time
272
	if (this.binding instanceof ParameterizedFieldBinding) {
273
	    ParameterizedFieldBinding parameterizedField = (ParameterizedFieldBinding) this.binding;
274
	    this.codegenBinding = parameterizedField.originalField;
275
	    // extra cast needed if field type was type variable
276
	    if (this.codegenBinding.type.isTypeVariable()) {
277
	        TypeVariableBinding variableReturnType = (TypeVariableBinding) this.codegenBinding.type;
278
	        if (variableReturnType.firstBound != parameterizedField.type) { // no need for extra cast if same as first bound anyway
279
			    this.genericCast = parameterizedField.type.erasure();
280
	        }
281
	    }
282
	} else {
283
	    this.codegenBinding = this.binding;
284
	}
285
286
	// if the binding declaring class is not visible, need special action
287
	// for runtime compatibility on 1.2 VMs : change the declaring class of the binding
288
	// NOTE: from target 1.2 on, field's declaring class is touched if any different from receiver type
289
	TypeBinding someReceiverType = this.delegateThis != null ? this.delegateThis.type : this.receiverType;
290
	if (this.binding.declaringClass != someReceiverType
291
			&& !someReceiverType.isArrayType()
292
			&& this.binding.declaringClass != null // array.length
293
			&& this.binding.constant() == Constant.NotAConstant) {
294
295
		CompilerOptions options = currentScope.compilerOptions();
296
		if ((options.targetJDK >= ClassFileConstants.JDK1_2
297
				&& (options.complianceLevel >= ClassFileConstants.JDK1_4 || !this.receiver.isImplicitThis() || !this.codegenBinding.isStatic())
298
				&& this.binding.declaringClass.id != T_JavaLangObject) // no change for Object fields
299
			|| !this.binding.declaringClass.canBeSeenBy(currentScope)) {
300
301
			this.codegenBinding =
302
				currentScope.enclosingSourceType().getUpdatedFieldBinding(
303
					this.codegenBinding,
304
					(ReferenceBinding) someReceiverType.erasure());
305
		}
306
	}
307
}
283
}
308
public TypeBinding resolveType(BlockScope scope) {
284
public TypeBinding resolveType(BlockScope scope) {
309
	// Answer the signature type of the field.
285
	// Answer the signature type of the field.
Lines 311-323 Link Here
311
	// and initialized with a (compile time) constant
287
	// and initialized with a (compile time) constant
312
288
313
	// regular receiver reference
289
	// regular receiver reference
314
	this.receiverType = this.receiver.resolveType(scope);
290
	this.actualReceiverType = this.receiver.resolveType(scope);
315
	if (this.receiverType == null){
291
	if (this.actualReceiverType == null){
316
		this.constant = Constant.NotAConstant;
292
		this.constant = Constant.NotAConstant;
317
		return null;
293
		return null;
318
	}
294
	}
319
	// the case receiverType.isArrayType and token = 'length' is handled by the scope API
295
	// the case receiverType.isArrayType and token = 'length' is handled by the scope API
320
	this.codegenBinding = this.binding = scope.getField(this.receiverType, this.token, this);
296
	this.binding = scope.getField(this.actualReceiverType, this.token, this);
321
	FieldBinding firstAttempt = this.binding;
297
	FieldBinding firstAttempt = this.binding;
322
	boolean isNotVisible = false;
298
	boolean isNotVisible = false;
323
	if (!this.binding.isValidBinding()) {
299
	if (!this.binding.isValidBinding()) {
Lines 328-352 Link Here
328
					this.delegateThis = scope.getField(scope.enclosingSourceType(), DELEGATE_THIS, this);
304
					this.delegateThis = scope.getField(scope.enclosingSourceType(), DELEGATE_THIS, this);
329
					if (this.delegateThis == null){  // if not found then internal error, field should have been found
305
					if (this.delegateThis == null){  // if not found then internal error, field should have been found
330
						this.constant = Constant.NotAConstant;
306
						this.constant = Constant.NotAConstant;
331
						scope.problemReporter().invalidField(this, this.receiverType);
307
						scope.problemReporter().invalidField(this, this.actualReceiverType);
332
						return null;
308
						return null;
333
					}
309
					}
334
				} else {
310
				} else {
335
					this.constant = Constant.NotAConstant;
311
					this.constant = Constant.NotAConstant;
336
					scope.problemReporter().invalidField(this, this.receiverType);
312
					scope.problemReporter().invalidField(this, this.actualReceiverType);
337
					return null;
313
					return null;
338
				}
314
				}
339
			CodeSnippetScope localScope = new CodeSnippetScope(scope);
315
			CodeSnippetScope localScope = new CodeSnippetScope(scope);
340
			this.codegenBinding = this.binding = localScope.getFieldForCodeSnippet(this.delegateThis.type, this.token, this);
316
			this.binding = localScope.getFieldForCodeSnippet(this.delegateThis.type, this.token, this);
341
		}
317
		}
342
	}
318
	}
343
319
344
	if (!this.binding.isValidBinding()) {
320
	if (!this.binding.isValidBinding()) {
345
		this.constant = Constant.NotAConstant;
321
		this.constant = Constant.NotAConstant;
346
		if (isNotVisible) {
322
		if (isNotVisible) {
347
			this.codegenBinding = this.binding = firstAttempt;
323
			this.binding = firstAttempt;
348
		}
324
		}
349
		scope.problemReporter().invalidField(this, this.receiverType);
325
		scope.problemReporter().invalidField(this, this.actualReceiverType);
350
		return null;
326
		return null;
351
	}
327
	}
352
328
(-)eval/org/eclipse/jdt/internal/eval/CodeSnippetSingleNameReference.java (-13 / +25 lines)
Lines 18-28 Link Here
18
import org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
18
import org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
19
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
19
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
20
import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
20
import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
21
import org.eclipse.jdt.internal.compiler.codegen.Opcodes;
21
import org.eclipse.jdt.internal.compiler.flow.FlowContext;
22
import org.eclipse.jdt.internal.compiler.flow.FlowContext;
22
import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
23
import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
23
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
24
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
24
import org.eclipse.jdt.internal.compiler.impl.Constant;
25
import org.eclipse.jdt.internal.compiler.impl.Constant;
25
import org.eclipse.jdt.internal.compiler.lookup.*;
26
import org.eclipse.jdt.internal.compiler.lookup.Binding;
27
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
28
import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
29
import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
30
import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
31
import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
32
import org.eclipse.jdt.internal.compiler.lookup.ParameterizedFieldBinding;
33
import org.eclipse.jdt.internal.compiler.lookup.ProblemBinding;
34
import org.eclipse.jdt.internal.compiler.lookup.ProblemFieldBinding;
35
import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons;
36
import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
37
import org.eclipse.jdt.internal.compiler.lookup.Scope;
38
import org.eclipse.jdt.internal.compiler.lookup.TagBits;
39
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
40
import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
41
import org.eclipse.jdt.internal.compiler.lookup.VariableBinding;
26
42
27
/**
43
/**
28
 * A single name reference inside a code snippet can denote a field of a remote
44
 * A single name reference inside a code snippet can denote a field of a remote
Lines 218-226 Link Here
218
				Constant fieldConstant = fieldBinding.constant();
234
				Constant fieldConstant = fieldBinding.constant();
219
				if (fieldConstant == Constant.NotAConstant) { // directly use inlined value for constant fields
235
				if (fieldConstant == Constant.NotAConstant) { // directly use inlined value for constant fields
220
					if (fieldBinding.canBeSeenBy(getReceiverType(currentScope), this, currentScope)) {
236
					if (fieldBinding.canBeSeenBy(getReceiverType(currentScope), this, currentScope)) {
221
						 // directly use inlined value for constant fields
237
						TypeBinding constantPoolDeclaringClass = getConstantPoolDeclaringClass(currentScope, fieldBinding, this.actualReceiverType, true /* implicit this */);
222
						boolean isStatic;
238
						if (fieldBinding.isStatic()) {
223
						if (!(isStatic = fieldBinding.isStatic())) {
239
							codeStream.fieldAccess0(Opcodes.OPC_getstatic, fieldBinding, constantPoolDeclaringClass);
240
						} else {
224
							if ((this.bits & DepthMASK) != 0) {
241
							if ((this.bits & DepthMASK) != 0) {
225
								ReferenceBinding targetType = currentScope.enclosingSourceType().enclosingTypeAt((this.bits & DepthMASK) >> DepthSHIFT);
242
								ReferenceBinding targetType = currentScope.enclosingSourceType().enclosingTypeAt((this.bits & DepthMASK) >> DepthSHIFT);
226
								Object[] emulationPath = currentScope.getEmulationPath(targetType, true /*only exact match*/, false/*consider enclosing arg*/);
243
								Object[] emulationPath = currentScope.getEmulationPath(targetType, true /*only exact match*/, false/*consider enclosing arg*/);
Lines 228-239 Link Here
228
							} else {
245
							} else {
229
								generateReceiver(codeStream);
246
								generateReceiver(codeStream);
230
							}
247
							}
231
						}
248
							codeStream.fieldAccess0(Opcodes.OPC_getfield, fieldBinding, constantPoolDeclaringClass);
232
						// managing private access
233
						if (isStatic) {
234
							codeStream.getstatic(fieldBinding);
235
						} else {
236
							codeStream.getfield(fieldBinding);
237
						}
249
						}
238
					} else {
250
					} else {
239
						// managing private access
251
						// managing private access
Lines 285-291 Link Here
285
			FieldBinding fieldBinding = (FieldBinding) this.codegenBinding;
297
			FieldBinding fieldBinding = (FieldBinding) this.codegenBinding;
286
			if (fieldBinding.isStatic()) {
298
			if (fieldBinding.isStatic()) {
287
				if (fieldBinding.canBeSeenBy(getReceiverType(currentScope), this, currentScope)) {
299
				if (fieldBinding.canBeSeenBy(getReceiverType(currentScope), this, currentScope)) {
288
					codeStream.getstatic(fieldBinding);
300
					codeStream.fieldAccess(Opcodes.OPC_getstatic, fieldBinding, null /* default declaringClass */);
289
				} else {
301
				} else {
290
					// used to store the value
302
					// used to store the value
291
					codeStream.generateEmulationForField(fieldBinding);
303
					codeStream.generateEmulationForField(fieldBinding);
Lines 305-311 Link Here
305
						generateReceiver(codeStream);
317
						generateReceiver(codeStream);
306
					}
318
					}
307
					codeStream.dup();
319
					codeStream.dup();
308
					codeStream.getfield(fieldBinding);
320
					codeStream.fieldAccess(Opcodes.OPC_getfield, fieldBinding, null /* default declaringClass */);
309
				} else {
321
				} else {
310
					if ((this.bits & DepthMASK) != 0) {
322
					if ((this.bits & DepthMASK) != 0) {
311
						// internal error, per construction we should have found it
323
						// internal error, per construction we should have found it
Lines 478-484 Link Here
478
public void generateReceiver(CodeStream codeStream) {
490
public void generateReceiver(CodeStream codeStream) {
479
	codeStream.aload_0();
491
	codeStream.aload_0();
480
	if (this.delegateThis != null) {
492
	if (this.delegateThis != null) {
481
		codeStream.getfield(this.delegateThis); // delegated field access
493
		codeStream.fieldAccess0(Opcodes.OPC_getfield, this.delegateThis, null /* default declaringClass */); // delegate field access
482
	}
494
	}
483
}
495
}
484
/**
496
/**
(-)eval/org/eclipse/jdt/internal/eval/CodeSnippetThisReference.java (-1 / +2 lines)
Lines 12-17 Link Here
12
12
13
import org.eclipse.jdt.internal.compiler.ast.ThisReference;
13
import org.eclipse.jdt.internal.compiler.ast.ThisReference;
14
import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
14
import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
15
import org.eclipse.jdt.internal.compiler.codegen.Opcodes;
15
import org.eclipse.jdt.internal.compiler.impl.Constant;
16
import org.eclipse.jdt.internal.compiler.impl.Constant;
16
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
17
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
17
import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
18
import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
Lines 58-64 Link Here
58
		int pc = codeStream.position;
59
		int pc = codeStream.position;
59
		if (valueRequired) {
60
		if (valueRequired) {
60
			codeStream.aload_0();
61
			codeStream.aload_0();
61
			codeStream.getfield(this.delegateThis);
62
			codeStream.fieldAccess0(Opcodes.OPC_getfield, this.delegateThis, null /* default declaringClass */); // delegate field access
62
		}
63
		}
63
		codeStream.recordPositionsFrom(pc, this.sourceStart);
64
		codeStream.recordPositionsFrom(pc, this.sourceStart);
64
	}
65
	}
(-)eval/org/eclipse/jdt/internal/eval/CodeSnippetQualifiedNameReference.java (-19 / +13 lines)
Lines 107-115 Link Here
107
				} else {
107
				} else {
108
					if (lastFieldBinding.canBeSeenBy(getReceiverType(currentScope), this, currentScope)) {
108
					if (lastFieldBinding.canBeSeenBy(getReceiverType(currentScope), this, currentScope)) {
109
						if (lastFieldBinding.isStatic()) {
109
						if (lastFieldBinding.isStatic()) {
110
							codeStream.getstatic(lastFieldBinding);
110
							codeStream.fieldAccess0(Opcodes.OPC_getstatic, lastFieldBinding, null /* default declaringClass */);
111
						} else {
111
						} else {
112
							codeStream.getfield(lastFieldBinding);
112
							codeStream.fieldAccess0(Opcodes.OPC_getfield, lastFieldBinding, null /* default declaringClass */);
113
						}
113
						}
114
					} else {
114
					} else {
115
						codeStream.generateEmulatedReadAccessForField(lastFieldBinding);
115
						codeStream.generateEmulatedReadAccessForField(lastFieldBinding);
Lines 131-140 Link Here
131
	FieldBinding lastFieldBinding = generateReadSequence(currentScope, codeStream);
131
	FieldBinding lastFieldBinding = generateReadSequence(currentScope, codeStream);
132
	if (lastFieldBinding.canBeSeenBy(getReceiverType(currentScope), this, currentScope)) {
132
	if (lastFieldBinding.canBeSeenBy(getReceiverType(currentScope), this, currentScope)) {
133
		if (lastFieldBinding.isStatic()){
133
		if (lastFieldBinding.isStatic()){
134
			codeStream.getstatic(lastFieldBinding);
134
			codeStream.fieldAccess0(Opcodes.OPC_getstatic, lastFieldBinding, null /* default declaringClass */);
135
		} else {
135
		} else {
136
			codeStream.dup();
136
			codeStream.dup();
137
			codeStream.getfield(lastFieldBinding);
137
			codeStream.fieldAccess0(Opcodes.OPC_getfield, lastFieldBinding, null /* default declaringClass */);
138
		}
138
		}
139
		// the last field access is a write access
139
		// the last field access is a write access
140
		// perform the actual compound operation
140
		// perform the actual compound operation
Lines 162-181 Link Here
162
		// actual assignment
162
		// actual assignment
163
		fieldStore(codeStream, lastFieldBinding, null, valueRequired);
163
		fieldStore(codeStream, lastFieldBinding, null, valueRequired);
164
	} else {
164
	} else {
165
		codeStream.generateEmulationForField(lastFieldBinding);
166
		codeStream.swap();
165
		if (lastFieldBinding.isStatic()){
167
		if (lastFieldBinding.isStatic()){
166
			codeStream.generateEmulationForField(lastFieldBinding);
167
			codeStream.swap();
168
			codeStream.aconst_null();
168
			codeStream.aconst_null();
169
			codeStream.swap();
169
			codeStream.swap();
170
171
			codeStream.generateEmulatedReadAccessForField(lastFieldBinding);
172
		} else {
170
		} else {
173
			codeStream.generateEmulationForField(lastFieldBinding);
174
			codeStream.swap();
175
			codeStream.dup();
171
			codeStream.dup();
176
177
			codeStream.generateEmulatedReadAccessForField(lastFieldBinding);
178
		}
172
		}
173
		codeStream.generateEmulatedReadAccessForField(lastFieldBinding);
179
		// the last field access is a write access
174
		// the last field access is a write access
180
		// perform the actual compound operation
175
		// perform the actual compound operation
181
		int operationTypeID;
176
		int operationTypeID;
Lines 215-234 Link Here
215
210
216
    FieldBinding lastFieldBinding = generateReadSequence(currentScope, codeStream);
211
    FieldBinding lastFieldBinding = generateReadSequence(currentScope, codeStream);
217
	if (lastFieldBinding.canBeSeenBy(getReceiverType(currentScope), this, currentScope)) {
212
	if (lastFieldBinding.canBeSeenBy(getReceiverType(currentScope), this, currentScope)) {
218
		SyntheticMethodBinding accessor =
213
		SyntheticMethodBinding accessor = this.syntheticReadAccessors == null
219
			this.syntheticReadAccessors == null
220
				? null
214
				? null
221
				: this.syntheticReadAccessors[this.syntheticReadAccessors.length - 1];
215
				: this.syntheticReadAccessors[this.syntheticReadAccessors.length - 1];
222
		if (lastFieldBinding.isStatic()) {
216
		if (lastFieldBinding.isStatic()) {
223
			if (accessor == null) {
217
			if (accessor == null) {
224
				codeStream.getstatic(lastFieldBinding);
218
				codeStream.fieldAccess0(Opcodes.OPC_getstatic, lastFieldBinding, null /* default declaringClass */);
225
			} else {
219
			} else {
226
				codeStream.invoke(Opcodes.OPC_invokestatic, accessor, null /* default declaringClass */);
220
				codeStream.invoke(Opcodes.OPC_invokestatic, accessor, null /* default declaringClass */);
227
			}
221
			}
228
		} else {
222
		} else {
229
			codeStream.dup();
223
			codeStream.dup();
230
			if (accessor == null) {
224
			if (accessor == null) {
231
				codeStream.getfield(lastFieldBinding);
225
				codeStream.fieldAccess0(Opcodes.OPC_getfield, lastFieldBinding, null /* default declaringClass */);
232
			} else {
226
			} else {
233
				codeStream.invoke(Opcodes.OPC_invokestatic, accessor, null /* default declaringClass */);
227
				codeStream.invoke(Opcodes.OPC_invokestatic, accessor, null /* default declaringClass */);
234
			}
228
			}
Lines 380-388 Link Here
380
							}
374
							}
381
							codeStream.generateConstant(fieldConstant, 0);
375
							codeStream.generateConstant(fieldConstant, 0);
382
						} else if (lastFieldBinding.isStatic()) {
376
						} else if (lastFieldBinding.isStatic()) {
383
							codeStream.getstatic(lastFieldBinding);
377
							codeStream.fieldAccess0(Opcodes.OPC_getstatic, lastFieldBinding, null /* default declaringClass */);
384
						} else {
378
						} else {
385
							codeStream.getfield(lastFieldBinding);
379
							codeStream.fieldAccess0(Opcodes.OPC_getfield, lastFieldBinding, null /* default declaringClass */);
386
						}
380
						}
387
					} else {
381
					} else {
388
						codeStream.generateEmulatedReadAccessForField(lastFieldBinding);
382
						codeStream.generateEmulatedReadAccessForField(lastFieldBinding);
Lines 410-416 Link Here
410
public void generateReceiver(CodeStream codeStream) {
404
public void generateReceiver(CodeStream codeStream) {
411
	codeStream.aload_0();
405
	codeStream.aload_0();
412
	if (this.delegateThis != null) {
406
	if (this.delegateThis != null) {
413
		codeStream.getfield(this.delegateThis); // delegated field access
407
		codeStream.fieldAccess0(Opcodes.OPC_getfield, this.delegateThis, null /* default declaringClass */); // delegated field access
414
	}
408
	}
415
}
409
}
416
public TypeBinding getOtherFieldBindings(BlockScope scope) {
410
public TypeBinding getOtherFieldBindings(BlockScope scope) {
(-)codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMemberAccess.java (-4 / +4 lines)
Lines 53-61 Link Here
53
53
54
	public TypeBinding resolveType(BlockScope scope) {
54
	public TypeBinding resolveType(BlockScope scope) {
55
55
56
		this.receiverType = this.receiver.resolveType(scope);
56
		this.actualReceiverType = this.receiver.resolveType(scope);
57
57
58
		if ((this.receiverType == null || !this.receiverType.isValidBinding()) && this.receiver instanceof MessageSend) {
58
		if ((this.actualReceiverType == null || !this.actualReceiverType.isValidBinding()) && this.receiver instanceof MessageSend) {
59
			MessageSend messageSend = (MessageSend) this.receiver;
59
			MessageSend messageSend = (MessageSend) this.receiver;
60
			if(messageSend.receiver instanceof ThisReference) {
60
			if(messageSend.receiver instanceof ThisReference) {
61
				Expression[] arguments = messageSend.arguments;
61
				Expression[] arguments = messageSend.arguments;
Lines 73-82 Link Here
73
			}
73
			}
74
		}
74
		}
75
75
76
		if (this.receiverType == null || this.receiverType.isBaseType() || !this.receiverType.isValidBinding())
76
		if (this.actualReceiverType == null || this.actualReceiverType.isBaseType() || !this.actualReceiverType.isValidBinding())
77
			throw new CompletionNodeFound();
77
			throw new CompletionNodeFound();
78
		else
78
		else
79
			throw new CompletionNodeFound(this, this.receiverType, scope);
79
			throw new CompletionNodeFound(this, this.actualReceiverType, scope);
80
		// array types are passed along to find the length field
80
		// array types are passed along to find the length field
81
	}
81
	}
82
}
82
}
(-)codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnJavadocFieldReference.java (-3 / +3 lines)
Lines 93-103 Link Here
93
93
94
		// Resolve only receiver
94
		// Resolve only receiver
95
		if (this.receiver == null) {
95
		if (this.receiver == null) {
96
			this.receiverType = scope.enclosingSourceType();
96
			this.actualReceiverType = scope.enclosingSourceType();
97
		} else if (scope.kind == Scope.CLASS_SCOPE) {
97
		} else if (scope.kind == Scope.CLASS_SCOPE) {
98
			this.receiverType = this.receiver.resolveType((ClassScope) scope);
98
			this.actualReceiverType = this.receiver.resolveType((ClassScope) scope);
99
		} else {
99
		} else {
100
			this.receiverType = this.receiver.resolveType((BlockScope)scope);
100
			this.actualReceiverType = this.receiver.resolveType((BlockScope)scope);
101
		}
101
		}
102
		return null;
102
		return null;
103
	}
103
	}
(-)codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java (-4 / +4 lines)
Lines 1927-1934 Link Here
1927
				long completionPosition = fieldRef.nameSourcePosition;
1927
				long completionPosition = fieldRef.nameSourcePosition;
1928
				this.javadocTagPosition = fieldRef.tagSourceStart;
1928
				this.javadocTagPosition = fieldRef.tagSourceStart;
1929
1929
1930
				if (fieldRef.receiverType != null && fieldRef.receiverType.isValidBinding()) {
1930
				if (fieldRef.actualReceiverType != null && fieldRef.actualReceiverType.isValidBinding()) {
1931
					ReferenceBinding receiverType = (ReferenceBinding) fieldRef.receiverType;
1931
					ReferenceBinding receiverType = (ReferenceBinding) fieldRef.actualReceiverType;
1932
					int rangeStart = (int) (completionPosition >>> 32);
1932
					int rangeStart = (int) (completionPosition >>> 32);
1933
					if (fieldRef.receiver.isThis()) {
1933
					if (fieldRef.receiver.isThis()) {
1934
						if (fieldRef.completeInText()) {
1934
						if (fieldRef.completeInText()) {
Lines 1984-1991 Link Here
1984
							null,
1984
							null,
1985
							-1,
1985
							-1,
1986
							-1);
1986
							-1);
1987
						if (fieldRef.receiverType instanceof ReferenceBinding) {
1987
						if (fieldRef.actualReceiverType instanceof ReferenceBinding) {
1988
							ReferenceBinding refBinding = (ReferenceBinding)fieldRef.receiverType;
1988
							ReferenceBinding refBinding = (ReferenceBinding)fieldRef.actualReceiverType;
1989
							if (this.completionToken == null
1989
							if (this.completionToken == null
1990
									|| CharOperation.prefixEquals(this.completionToken, refBinding.sourceName)
1990
									|| CharOperation.prefixEquals(this.completionToken, refBinding.sourceName)
1991
									|| (this.options.camelCaseMatch && CharOperation.camelCaseMatch(this.completionToken, refBinding.sourceName))) {
1991
									|| (this.options.camelCaseMatch && CharOperation.camelCaseMatch(this.completionToken, refBinding.sourceName))) {

Return to bug 247612