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) { |