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

Collapse All | Expand All

(-)compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java (-3 / +2 lines)
Lines 2932-2941 Link Here
2932
 * @param codegenBinding
2932
 * @param codegenBinding
2933
 * @param actualReceiverType
2933
 * @param actualReceiverType
2934
 * @param isImplicitThisReceiver
2934
 * @param isImplicitThisReceiver
2935
 * @param hasGenericCast
2936
 * @return the receiver type to use in constant pool
2935
 * @return the receiver type to use in constant pool
2937
 */
2936
 */
2938
public static TypeBinding getConstantPoolDeclaringClass(Scope currentScope, MethodBinding codegenBinding, TypeBinding actualReceiverType, boolean isImplicitThisReceiver, boolean hasGenericCast) {
2937
public static TypeBinding getConstantPoolDeclaringClass(Scope currentScope, MethodBinding codegenBinding, TypeBinding actualReceiverType, boolean isImplicitThisReceiver) {
2939
	TypeBinding constantPoolDeclaringClass = codegenBinding.declaringClass;
2938
	TypeBinding constantPoolDeclaringClass = codegenBinding.declaringClass;
2940
	// Post 1.4.0 target, array clone() invocations are qualified with array type
2939
	// Post 1.4.0 target, array clone() invocations are qualified with array type
2941
	// This is handled in array type #clone method binding resolution (see Scope and UpdatedMethodBinding)
2940
	// This is handled in array type #clone method binding resolution (see Scope and UpdatedMethodBinding)
Lines 2949-2955 Link Here
2949
		// for runtime compatibility on 1.2 VMs : change the declaring class of the binding
2948
		// for runtime compatibility on 1.2 VMs : change the declaring class of the binding
2950
		// NOTE: from target 1.2 on, method's declaring class is touched if any different from receiver type
2949
		// NOTE: from target 1.2 on, method's declaring class is touched if any different from receiver type
2951
		// and not from Object or implicit static method call.
2950
		// and not from Object or implicit static method call.
2952
		if (constantPoolDeclaringClass != actualReceiverType.erasure() && !hasGenericCast && !actualReceiverType.isArrayType()) {
2951
		if (constantPoolDeclaringClass != actualReceiverType.erasure() && !actualReceiverType.isArrayType()) {
2953
			CompilerOptions options = currentScope.compilerOptions();
2952
			CompilerOptions options = currentScope.compilerOptions();
2954
			if ((options.targetJDK >= ClassFileConstants.JDK1_2
2953
			if ((options.targetJDK >= ClassFileConstants.JDK1_2
2955
						&& (options.complianceLevel >= ClassFileConstants.JDK1_4 || !(isImplicitThisReceiver && codegenBinding.isStatic()))
2954
						&& (options.complianceLevel >= ClassFileConstants.JDK1_4 || !(isImplicitThisReceiver && codegenBinding.isStatic()))
(-)eval/org/eclipse/jdt/internal/eval/CodeSnippetMessageSend.java (-6 / +16 lines)
Lines 51-57 Link Here
51
public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
51
public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
52
	int pc = codeStream.position;
52
	int pc = codeStream.position;
53
	MethodBinding codegenBinding = this.binding.original();
53
	MethodBinding codegenBinding = this.binding.original();
54
	if (codegenBinding.canBeSeenBy(this.actualReceiverType, this, currentScope)) {
54
	TypeBinding codeGenReceiverType = this.actualReceiverType;
55
	if (codegenBinding.canBeSeenBy(codeGenReceiverType, this, currentScope)) {
55
		// generate receiver/enclosing instance access
56
		// generate receiver/enclosing instance access
56
		boolean isStatic = codegenBinding.isStatic();
57
		boolean isStatic = codegenBinding.isStatic();
57
		// outer access ?
58
		// outer access ?
Lines 67-80 Link Here
67
			}
68
			}
68
		} else {
69
		} else {
69
			this.receiver.generateCode(currentScope, codeStream, !isStatic);
70
			this.receiver.generateCode(currentScope, codeStream, !isStatic);
70
			if (this.receiverGenericCast != null)
71
			// compute generic cast if necessary
71
				codeStream.checkcast(this.receiverGenericCast);
72
			TypeBinding upperBound = ((ReferenceBinding) codeGenReceiverType).getReceiverTypeErasure(this.binding.declaringClass);
73
			if (upperBound != null && upperBound != codeGenReceiverType.erasure()) {
74
				codeStream.checkcast(upperBound); // handle indirect inheritance thru variable secondary bound
75
				codeGenReceiverType = upperBound;
76
			}
72
			codeStream.recordPositionsFrom(pc, this.sourceStart);
77
			codeStream.recordPositionsFrom(pc, this.sourceStart);
73
		}
78
		}
74
		// generate arguments
79
		// generate arguments
75
		generateArguments(this.binding, this.arguments, currentScope, codeStream);
80
		generateArguments(this.binding, this.arguments, currentScope, codeStream);
76
		// actual message invocation
81
		// actual message invocation
77
		TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, codegenBinding, this.actualReceiverType, this.receiver.isImplicitThis(), this.receiverGenericCast != null);
82
		TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, codegenBinding, codeGenReceiverType, this.receiver.isImplicitThis());
78
		if (isStatic) {
83
		if (isStatic) {
79
			codeStream.invoke(Opcodes.OPC_invokestatic, codegenBinding, constantPoolDeclaringClass);
84
			codeStream.invoke(Opcodes.OPC_invokestatic, codegenBinding, constantPoolDeclaringClass);
80
		} else if( (this.receiver.isSuper()) || codegenBinding.isPrivate()){
85
		} else if( (this.receiver.isSuper()) || codegenBinding.isPrivate()){
Lines 96-103 Link Here
96
			currentScope.problemReporter().needImplementation(this);
101
			currentScope.problemReporter().needImplementation(this);
97
		} else {
102
		} else {
98
			this.receiver.generateCode(currentScope, codeStream, !isStatic);
103
			this.receiver.generateCode(currentScope, codeStream, !isStatic);
99
			if (this.receiverGenericCast != null)
104
			// compute generic cast if necessary
100
				codeStream.checkcast(this.receiverGenericCast);
105
			TypeBinding upperBound = codeGenReceiverType.getReceiverTypeErasure(this.binding.declaringClass);
106
			if (upperBound != null && upperBound != codeGenReceiverType.erasure()) {
107
				codeStream.checkcast(upperBound); // handle indirect inheritance thru variable secondary bound
108
				codeGenReceiverType = upperBound;
109
			}
110
101
			codeStream.recordPositionsFrom(pc, this.sourceStart);
111
			codeStream.recordPositionsFrom(pc, this.sourceStart);
102
		}
112
		}
103
		if (isStatic) {
113
		if (isStatic) {
(-)compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java (-13 / +8 lines)
Lines 50-56 Link Here
50
	public long nameSourcePosition ; //(start<<32)+end
50
	public long nameSourcePosition ; //(start<<32)+end
51
51
52
	public TypeBinding actualReceiverType;
52
	public TypeBinding actualReceiverType;
53
	public TypeBinding receiverGenericCast; // extra reference type cast to perform on generic receiver
54
	public TypeBinding valueCast; // extra reference type cast to perform on method returned value
53
	public TypeBinding valueCast; // extra reference type cast to perform on method returned value
55
	public TypeReference[] typeArguments;
54
	public TypeReference[] typeArguments;
56
	public TypeBinding[] genericTypeArguments;
55
	public TypeBinding[] genericTypeArguments;
Lines 123-134 Link Here
123
 * @param valueRequired boolean
122
 * @param valueRequired boolean
124
 */
123
 */
125
public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
124
public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
126
127
	int pc = codeStream.position;
125
	int pc = codeStream.position;
128
129
	// generate receiver/enclosing instance access
126
	// generate receiver/enclosing instance access
130
	MethodBinding codegenBinding = this.binding.original();
127
	MethodBinding codegenBinding = this.binding.original();
131
	boolean isStatic = codegenBinding.isStatic();
128
	boolean isStatic = codegenBinding.isStatic();
129
	TypeBinding codeGenReceiverType = this.actualReceiverType;
132
	if (isStatic) {
130
	if (isStatic) {
133
		this.receiver.generateCode(currentScope, codeStream, false);
131
		this.receiver.generateCode(currentScope, codeStream, false);
134
		codeStream.recordPositionsFrom(pc, this.sourceStart);
132
		codeStream.recordPositionsFrom(pc, this.sourceStart);
Lines 139-146 Link Here
139
		codeStream.generateOuterAccess(path, this, targetType, currentScope);
137
		codeStream.generateOuterAccess(path, this, targetType, currentScope);
140
	} else {
138
	} else {
141
		this.receiver.generateCode(currentScope, codeStream, true);
139
		this.receiver.generateCode(currentScope, codeStream, true);
142
		if (this.receiverGenericCast != null)
140
		// compute generic cast if necessary
143
			codeStream.checkcast(this.receiverGenericCast);
141
		TypeBinding upperBound = codeGenReceiverType.getReceiverTypeErasure(this.binding.declaringClass);
142
		if (upperBound != null && upperBound != codeGenReceiverType.erasure()) {
143
			codeStream.checkcast(upperBound); // handle indirect inheritance thru variable secondary bound
144
			codeGenReceiverType = upperBound;
145
		}
144
		codeStream.recordPositionsFrom(pc, this.sourceStart);
146
		codeStream.recordPositionsFrom(pc, this.sourceStart);
145
147
146
	}
148
	}
Lines 149-155 Link Here
149
151
150
	// actual message invocation
152
	// actual message invocation
151
	if (this.syntheticAccessor == null){
153
	if (this.syntheticAccessor == null){
152
		TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, codegenBinding, this.actualReceiverType, this.receiver.isImplicitThis(), this.receiverGenericCast != null);
154
		TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, codegenBinding, codeGenReceiverType, this.receiver.isImplicitThis());
153
		if (isStatic){
155
		if (isStatic){
154
			codeStream.invoke(Opcodes.OPC_invokestatic, codegenBinding, constantPoolDeclaringClass);
156
			codeStream.invoke(Opcodes.OPC_invokestatic, codegenBinding, constantPoolDeclaringClass);
155
		} else if( (this.receiver.isSuper()) || codegenBinding.isPrivate()){
157
		} else if( (this.receiver.isSuper()) || codegenBinding.isPrivate()){
Lines 455-467 Link Here
455
			}
457
			}
456
		} else {
458
		} else {
457
			this.receiver.computeConversion(scope, this.actualReceiverType, this.actualReceiverType);
459
			this.receiver.computeConversion(scope, this.actualReceiverType, this.actualReceiverType);
458
			// compute generic cast if necessary
459
			TypeBinding receiverErasure = this.actualReceiverType.erasure();
460
			if (receiverErasure instanceof ReferenceBinding) {
461
				if (receiverErasure.findSuperTypeOriginatingFrom(this.binding.declaringClass) == null) {
462
					this.receiverGenericCast = this.binding.declaringClass; // handle indirect inheritance thru variable secondary bound
463
				}
464
			}
465
		}
460
		}
466
	} else {
461
	} else {
467
		// static message invoked through receiver? legal but unoptimal (optional warning).
462
		// static message invoked through receiver? legal but unoptimal (optional warning).
(-)compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBinding.java (+39 lines)
Lines 358-363 Link Here
358
	return signature();
358
	return signature();
359
}
359
}
360
360
361
/**
362
 * Return erasure for the receiver type which is compatible with a given declaring class.
363
 * This is different from standard erasure when dealing with types with multiple upper bounds where
364
 * the first compatible bound is to be considered.
365
 * NOTE: the declaringClass is already know to be compatible with the receiver
366
 * @param declaringClass to look for
367
 * @return the first compatible bound, or null if none found
368
 */
369
public TypeBinding getReceiverTypeErasure(TypeBinding declaringClass) {
370
	switch(kind()) {
371
		case Binding.TYPE_PARAMETER :
372
			TypeVariableBinding variable = (TypeVariableBinding) this;
373
			if (variable.superclass != null && variable.superclass.findSuperTypeOriginatingFrom(declaringClass) != null) {
374
				return variable.superclass.getReceiverTypeErasure(declaringClass);
375
			}
376
			for (int i = 0, otherLength = variable.superInterfaces.length; i < otherLength; i++) {
377
				ReferenceBinding superInterface = variable.superInterfaces[i];
378
				if (superInterface.findSuperTypeOriginatingFrom(declaringClass) != null) {
379
					return superInterface.getReceiverTypeErasure(declaringClass);
380
				}
381
			}
382
			return null; // cannot happen if declaringClass is compatible
383
		case Binding.INTERSECTION_TYPE :
384
			WildcardBinding intersection = (WildcardBinding) this;
385
			if (intersection.superclass != null && intersection.superclass.findSuperTypeOriginatingFrom(declaringClass) != null) {
386
				return intersection.superclass.getReceiverTypeErasure(declaringClass);
387
			}
388
			for (int i = 0, otherLength = intersection.superInterfaces.length; i < otherLength; i++) {
389
				ReferenceBinding superInterface = intersection.superInterfaces[i];
390
				if (superInterface.findSuperTypeOriginatingFrom(declaringClass) != null) {
391
					return superInterface.getReceiverTypeErasure(declaringClass);
392
				}
393
			}
394
			return null; // cannot happen if declaringClass is compatible
395
		default :
396
			return erasure(); 
397
	}
398
}
399
361
public abstract PackageBinding getPackage();
400
public abstract PackageBinding getPackage();
362
401
363
void initializeForStaticImports() {
402
void initializeForStaticImports() {
(-)src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java (-24 / +22 lines)
Lines 46336-46342 Link Here
46336
			"----------\n");
46336
			"----------\n");
46337
}
46337
}
46338
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=247953
46338
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=247953
46339
public void _test1381()  throws Exception {
46339
public void test1381()  throws Exception {
46340
	this.runConformTest(
46340
	this.runConformTest(
46341
		new String[] {
46341
		new String[] {
46342
			"X.java",
46342
			"X.java",
Lines 46361-46390 Link Here
46361
			"}\n",
46361
			"}\n",
46362
			"p/IB.java", // =====================
46362
			"p/IB.java", // =====================
46363
			"package p;\n" +
46363
			"package p;\n" +
46364
			"interface IA {\n" + 
46364
			"interface IA {\n" + // non visible
46365
			"	void baz();\n" + 
46365
			"	void baz();\n" + 
46366
			"}\n" + 
46366
			"}\n" + 
46367
			"public interface IB extends IA {\n" + 
46367
			"public interface IB extends IA {\n" + 
46368
			"}\n",
46368
			"}\n",
46369
		},
46369
		},
46370
		"done");
46370
		"done");
46371
	// check #baz() invocation declaring class is IA
46371
	// check #baz() invocation declaring class is IB
46372
	String expectedOutput =
46372
	String expectedOutput =
46373
		"  // Method descriptor #21 (LX;)V\n" + 
46373
		"  // Method descriptor #10 ()V\n" + 
46374
		"  // Signature: (LX<TT;>;)V\n" + 
46374
		"  // Stack: 1, Locals: 1\n" + 
46375
		"  // Stack: 1, Locals: 2\n" + 
46375
		"  void foo();\n" + 
46376
		"  void foo(X xt);\n" + 
46376
		"     0  aload_0 [this]\n" + 
46377
		"     0  aload_1 [xt]\n" + 
46377
		"     1  getfield X.t : AA [21]\n" + 
46378
		"     1  invokevirtual X.get() : AA [23]\n" + 
46378
		"     4  checkcast p.IB [23]\n" + 
46379
		"     4  checkcast p.IA [25]\n" + 
46379
		"     7  invokeinterface p.IB.baz() : void [25] [nargs: 1]\n" + 
46380
		"     7  invokeinterface p.IA.baz() : void [27] [nargs: 1]\n" + 
46381
		"    12  return\n" + 
46380
		"    12  return\n" + 
46382
		"      Line numbers:\n" + 
46381
		"      Line numbers:\n" + 
46383
		"        [pc: 0, line: 5]\n" + 
46382
		"        [pc: 0, line: 4]\n" + 
46384
		"        [pc: 12, line: 6]\n" + 
46383
		"        [pc: 12, line: 5]\n" + 
46385
		"      Local variable table:\n" + 
46384
		"      Local variable table:\n" + 
46386
		"        [pc: 0, pc: 13] local: this index: 0 type: X\n" + 
46385
		"        [pc: 0, pc: 13] local: this index: 0 type: X\n";
46387
		"        [pc: 0, pc: 13] local: xt index: 1 type: X\n";
46388
46386
46389
	File f = new File(OUTPUT_DIR + File.separator + "X.class");
46387
	File f = new File(OUTPUT_DIR + File.separator + "X.class");
46390
	byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(f);
46388
	byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(f);
Lines 46399-46405 Link Here
46399
	}
46397
	}
46400
}
46398
}
46401
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=247953 - variation
46399
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=247953 - variation
46402
public void _test1382()  throws Exception {
46400
public void test1382()  throws Exception {
46403
	this.runConformTest(
46401
	this.runConformTest(
46404
		new String[] {
46402
		new String[] {
46405
			"X.java",
46403
			"X.java",
Lines 46452-46458 Link Here
46452
	}
46450
	}
46453
}
46451
}
46454
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=247953 - variation
46452
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=247953 - variation
46455
public void _test1383()  throws Exception {
46453
public void test1383()  throws Exception {
46456
	this.runConformTest(
46454
	this.runConformTest(
46457
		new String[] {
46455
		new String[] {
46458
			"X.java",
46456
			"X.java",
Lines 46507-46513 Link Here
46507
	}
46505
	}
46508
}
46506
}
46509
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=247953 - variation
46507
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=247953 - variation
46510
public void _test1384()  throws Exception {
46508
public void test1384()  throws Exception {
46511
	this.runConformTest(
46509
	this.runConformTest(
46512
		new String[] {
46510
		new String[] {
46513
			"X.java",
46511
			"X.java",
Lines 46561-46567 Link Here
46561
	}
46559
	}
46562
}
46560
}
46563
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=247953 - variation
46561
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=247953 - variation
46564
public void _test1385()  throws Exception {
46562
public void test1385()  throws Exception {
46565
	this.runConformTest(
46563
	this.runConformTest(
46566
		new String[] {
46564
		new String[] {
46567
			"X.java",
46565
			"X.java",
Lines 46613-46619 Link Here
46613
	}
46611
	}
46614
}
46612
}
46615
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=247953 - variation
46613
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=247953 - variation
46616
public void _test1386()  throws Exception {
46614
public void test1386()  throws Exception {
46617
	this.runConformTest(
46615
	this.runConformTest(
46618
		new String[] {
46616
		new String[] {
46619
			"X.java",
46617
			"X.java",
Lines 46635-46641 Link Here
46635
			"public interface IB extends IA {\n" + 
46633
			"public interface IB extends IA {\n" + 
46636
			"}\n",
46634
			"}\n",
46637
		},
46635
		},
46638
		"111");
46636
		"");
46639
	// check #baz() invocation declaring class is not IA
46637
	// check #baz() invocation declaring class is not IA
46640
	String expectedOutput =
46638
	String expectedOutput =
46641
		"  // Method descriptor #21 (LX;)V\n" + 
46639
		"  // Method descriptor #21 (LX;)V\n" + 
Lines 46667-46673 Link Here
46667
	}
46665
	}
46668
}
46666
}
46669
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=247953 - variation
46667
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=247953 - variation
46670
public void _test1387()  throws Exception {
46668
public void testONLY_1387()  throws Exception {
46671
	this.runConformTest(
46669
	this.runConformTest(
46672
		new String[] {
46670
		new String[] {
46673
			"X.java",
46671
			"X.java",
Lines 46727-46733 Link Here
46727
	}
46725
	}
46728
}
46726
}
46729
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=247953 - variation
46727
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=247953 - variation
46730
public void _test1388()  throws Exception {
46728
public void test1388()  throws Exception {
46731
	this.runConformTest(
46729
	this.runConformTest(
46732
		new String[] {
46730
		new String[] {
46733
			"X.java",
46731
			"X.java",
Lines 46787-46793 Link Here
46787
	}
46785
	}
46788
}
46786
}
46789
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=247953 - variation
46787
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=247953 - variation
46790
public void _test1389()  throws Exception {
46788
public void test1389()  throws Exception {
46791
	this.runConformTest(
46789
	this.runConformTest(
46792
		new String[] {
46790
		new String[] {
46793
			"X.java",
46791
			"X.java",

Return to bug 247953