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

Collapse All | Expand All

(-)compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier.java (-26 / +29 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2009 IBM Corporation and others.
2
 * Copyright (c) 2000, 2010 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 550-557 Link Here
550
*/
550
*/
551
void computeInheritedMethods(ReferenceBinding superclass, ReferenceBinding[] superInterfaces) {
551
void computeInheritedMethods(ReferenceBinding superclass, ReferenceBinding[] superInterfaces) {
552
	// only want to remember inheritedMethods that can have an impact on the current type
552
	// only want to remember inheritedMethods that can have an impact on the current type
553
	// if an inheritedMethod has been 'replaced' by a supertype's method then skip it
553
	// if an inheritedMethod has been 'replaced' by a supertype's method then skip it, however
554
554
    // see usage of canOverridingMethodDifferInErasure below.
555
	this.inheritedMethods = new HashtableOfObject(51); // maps method selectors to an array of methods... must search to match paramaters & return type
555
	this.inheritedMethods = new HashtableOfObject(51); // maps method selectors to an array of methods... must search to match paramaters & return type
556
	ReferenceBinding[] interfacesToVisit = null;
556
	ReferenceBinding[] interfacesToVisit = null;
557
	int nextPosition = 0;
557
	int nextPosition = 0;
Lines 563-592 Link Here
563
563
564
	ReferenceBinding superType = superclass;
564
	ReferenceBinding superType = superclass;
565
	HashtableOfObject nonVisibleDefaultMethods = new HashtableOfObject(3); // maps method selectors to an array of methods
565
	HashtableOfObject nonVisibleDefaultMethods = new HashtableOfObject(3); // maps method selectors to an array of methods
566
	boolean allSuperclassesAreAbstract = true;
567
566
568
	while (superType != null && superType.isValidBinding()) {
567
	while (superType != null && superType.isValidBinding()) {
569
	    if (allSuperclassesAreAbstract) {
568
		// We used to only include superinterfaces if immediate superclasses are abstract
570
		    if (superType.isAbstract()) {
569
		// but that is problematic. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=302358
571
				// only need to include superinterfaces if immediate superclasses are abstract
570
		if ((itsInterfaces = superType.superInterfaces()) != Binding.NO_SUPERINTERFACES) {
572
				if ((itsInterfaces = superType.superInterfaces()) != Binding.NO_SUPERINTERFACES) {
571
			if (interfacesToVisit == null) {
573
					if (interfacesToVisit == null) {
572
				interfacesToVisit = itsInterfaces;
574
						interfacesToVisit = itsInterfaces;
573
				nextPosition = interfacesToVisit.length;
575
						nextPosition = interfacesToVisit.length;
576
					} else {
577
						int itsLength = itsInterfaces.length;
578
						if (nextPosition + itsLength >= interfacesToVisit.length)
579
							System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
580
						nextInterface : for (int a = 0; a < itsLength; a++) {
581
							ReferenceBinding next = itsInterfaces[a];
582
							for (int b = 0; b < nextPosition; b++)
583
								if (next == interfacesToVisit[b]) continue nextInterface;
584
							interfacesToVisit[nextPosition++] = next;
585
						}
586
					}
587
				}
588
			} else {
574
			} else {
589
			    allSuperclassesAreAbstract = false;
575
				int itsLength = itsInterfaces.length;
576
				if (nextPosition + itsLength >= interfacesToVisit.length)
577
					System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
578
				nextInterface : for (int a = 0; a < itsLength; a++) {
579
					ReferenceBinding next = itsInterfaces[a];
580
					for (int b = 0; b < nextPosition; b++)
581
						if (next == interfacesToVisit[b]) continue nextInterface;
582
					interfacesToVisit[nextPosition++] = next;
583
				}
590
			}
584
			}
591
		}
585
		}
592
586
Lines 599-605 Link Here
599
			if (existingMethods != null) {
593
			if (existingMethods != null) {
600
				existing : for (int i = 0, length = existingMethods.length; i < length; i++) {
594
				existing : for (int i = 0, length = existingMethods.length; i < length; i++) {
601
					MethodBinding existingMethod = existingMethods[i];
595
					MethodBinding existingMethod = existingMethods[i];
602
					if (existingMethod.declaringClass != inheritedMethod.declaringClass && areMethodsCompatible(existingMethod, inheritedMethod)) {
596
					// https://bugs.eclipse.org/bugs/show_bug.cgi?id=302358, skip inherited method only if any overriding version
597
					// in a subclass is guaranteed to have the same erasure as an existing method.
598
					if (existingMethod.declaringClass != inheritedMethod.declaringClass && areMethodsCompatible(existingMethod, inheritedMethod) && !canOverridingMethodDifferInErasure(existingMethod, inheritedMethod)) {
603
						if (inheritedMethod.isDefault()) {
599
						if (inheritedMethod.isDefault()) {
604
							if (inheritedMethod.isAbstract()) {
600
							if (inheritedMethod.isAbstract()) {
605
								checkPackagePrivateAbstractMethod(inheritedMethod);
601
								checkPackagePrivateAbstractMethod(inheritedMethod);
Lines 681-688 Link Here
681
				} else {
677
				} else {
682
					int length = existingMethods.length;
678
					int length = existingMethods.length;
683
					// look to see if any of the existingMethods implement this inheritedMethod
679
					// look to see if any of the existingMethods implement this inheritedMethod
680
					// https://bugs.eclipse.org/bugs/show_bug.cgi?id=302358, skip inherited method only if any overriding version
681
					// in a subclass is guaranteed to have the same erasure as an existing method.
684
					for (int e = 0; e < length; e++)
682
					for (int e = 0; e < length; e++)
685
						if (isInterfaceMethodImplemented(inheritedMethod, existingMethods[e], superType))
683
						if (isInterfaceMethodImplemented(inheritedMethod, existingMethods[e], superType) && !canOverridingMethodDifferInErasure(existingMethods[e], inheritedMethod))
686
							continue nextMethod; // skip interface method with the same signature if visible to its declaringClass
684
							continue nextMethod; // skip interface method with the same signature if visible to its declaringClass
687
					System.arraycopy(existingMethods, 0, existingMethods = new MethodBinding[length + 1], 0, length);
685
					System.arraycopy(existingMethods, 0, existingMethods = new MethodBinding[length + 1], 0, length);
688
					existingMethods[length] = inheritedMethod;
686
					existingMethods[length] = inheritedMethod;
Lines 693-698 Link Here
693
	}
691
	}
694
}
692
}
695
693
694
// Given `overridingMethod' which overrides `inheritedMethod' answer whether some subclass method that
695
// differs in erasure from overridingMethod could override `inheritedMethod'
696
protected boolean canOverridingMethodDifferInErasure(MethodBinding overridingMethod, MethodBinding inheritedMethod) {
697
	return false;   // the case for <= 1.4  (cannot differ)
698
}
696
void computeMethods() {
699
void computeMethods() {
697
	MethodBinding[] methods = this.type.methods();
700
	MethodBinding[] methods = this.type.methods();
698
	int size = methods.length;
701
	int size = methods.length;
(-)compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java (-3 / +30 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2009 IBM Corporation and others.
2
 * Copyright (c) 2000, 2010 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 96-101 Link Here
96
	//		return ((UnresolvedReferenceBinding) two).resolvedType == one;
96
	//		return ((UnresolvedReferenceBinding) two).resolvedType == one;
97
	return false; // all other type bindings are identical
97
	return false; // all other type bindings are identical
98
}
98
}
99
// Given `overridingMethod' which overrides `inheritedMethod' answer whether some subclass method that
100
// differs in erasure from overridingMethod could override `inheritedMethod'
101
protected boolean canOverridingMethodDifferInErasure(MethodBinding overridingMethod, MethodBinding inheritedMethod) {
102
	if (overridingMethod.areParameterErasuresEqual(inheritedMethod))
103
		return false;  // no further change in signature is possible due to parameterization.
104
	if (overridingMethod.declaringClass.isRawType())
105
		return false;  // no parameterization is happening anyways.
106
	return true;
107
}
99
boolean canSkipInheritedMethods() {
108
boolean canSkipInheritedMethods() {
100
	if (this.type.superclass() != null)
109
	if (this.type.superclass() != null)
101
		if (this.type.superclass().isAbstract() || this.type.superclass().isParameterizedType())
110
		if (this.type.superclass().isAbstract() || this.type.superclass().isParameterizedType())
Lines 447-452 Link Here
447
					continue; // both inherited methods matched the same currentMethod
456
					continue; // both inherited methods matched the same currentMethod
448
				if (canSkipInheritedMethods(inheritedMethod, otherInheritedMethod))
457
				if (canSkipInheritedMethods(inheritedMethod, otherInheritedMethod))
449
					continue;
458
					continue;
459
				// Skip the otherInheritedMethod if it is completely replaced by inheritedMethod
460
				// This elimination used to happen rather eagerly in computeInheritedMethods step
461
				// itself earlier. (https://bugs.eclipse.org/bugs/show_bug.cgi?id=302358)
462
				if (inheritedMethod.declaringClass != otherInheritedMethod.declaringClass) {
463
					if (otherInheritedMethod.declaringClass.isInterface()) {
464
						if (isInterfaceMethodImplemented(otherInheritedMethod, inheritedMethod, otherInheritedMethod.declaringClass)) {
465
							skip[j] = true;
466
							continue;
467
						}
468
					} else if (areMethodsCompatible(inheritedMethod, otherInheritedMethod)) {
469
						skip[j] = true;
470
						continue;
471
					}
472
				}
450
				otherInheritedMethod = computeSubstituteMethod(otherInheritedMethod, inheritedMethod);
473
				otherInheritedMethod = computeSubstituteMethod(otherInheritedMethod, inheritedMethod);
451
				if (otherInheritedMethod != null) {
474
				if (otherInheritedMethod != null) {
452
					if (inheritedMethod.declaringClass != otherInheritedMethod.declaringClass
475
					if (inheritedMethod.declaringClass != otherInheritedMethod.declaringClass
Lines 577-586 Link Here
577
boolean detectInheritedNameClash(MethodBinding inherited, MethodBinding otherInherited) {
600
boolean detectInheritedNameClash(MethodBinding inherited, MethodBinding otherInherited) {
578
	if (!inherited.areParameterErasuresEqual(otherInherited))
601
	if (!inherited.areParameterErasuresEqual(otherInherited))
579
		return false;
602
		return false;
580
	// skip it if otherInherited is defined by a subtype of inherited's declaringClass
603
	// skip it if otherInherited is defined by a subtype of inherited's declaringClass or vice versa.
581
	if (inherited.declaringClass.erasure() != otherInherited.declaringClass.erasure())
604
	// avoid being order sensitive and check with the roles reversed also.
605
	if (inherited.declaringClass.erasure() != otherInherited.declaringClass.erasure()) {
582
		if (inherited.declaringClass.findSuperTypeOriginatingFrom(otherInherited.declaringClass) != null)
606
		if (inherited.declaringClass.findSuperTypeOriginatingFrom(otherInherited.declaringClass) != null)
583
			return false;
607
			return false;
608
		if (otherInherited.declaringClass.findSuperTypeOriginatingFrom(inherited.declaringClass) != null)
609
			return false;
610
	}
584
611
585
	problemReporter().inheritedMethodsHaveNameClash(this.type, inherited, otherInherited);
612
	problemReporter().inheritedMethodsHaveNameClash(this.type, inherited, otherInherited);
586
	return true;
613
	return true;
(-)src/org/eclipse/jdt/core/tests/compiler/regression/AmbiguousMethodTest.java (+318 lines)
Lines 3528-3531 Link Here
3528
		},
3528
		},
3529
		"SUCCESS");
3529
		"SUCCESS");
3530
}
3530
}
3531
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=302358
3532
public void test081() {
3533
	this.runConformTest(
3534
		new String[] {
3535
			"C.java",
3536
			"class A<ModelType extends D, ValueType> implements I<ModelType, ValueType> {\n" +
3537
			"    public void doSet(ModelType valueGetter) {\n" +
3538
			"        this.set((ValueType) valueGetter.getObject());\n" +
3539
			"    }\n" +
3540
			"    public void set(Object object) {\n" +
3541
			"        System.out.println(\"In A.set(Object)\");\n" +
3542
			"    }\n" +
3543
			"}\n" +
3544
			"class B extends A<E, CharSequence> {\n" +
3545
			"	public void set(CharSequence string) {\n" +
3546
			"        System.out.println(\"In B.set(CharSequence)\");\n" +
3547
			"    }\n" +
3548
			"}\n" +
3549
			"public class C extends B {\n" +
3550
			"    static public void main(String[] args) {\n" +
3551
			"        C c = new C();\n" +
3552
			"        c.run();\n" +
3553
			"    }\n" +
3554
			"    public void run() {\n" +
3555
			"        E e = new E<String>(String.class);\n" +
3556
			"        this.doSet(e);\n" +
3557
			"    }\n" +
3558
			"}\n" +
3559
			"class D {\n" +
3560
			"    public Object getObject() {\n" +
3561
			"        return null;\n" +
3562
			"    }\n" +
3563
			"}\n" +
3564
			"class E<Type extends CharSequence> extends D {\n" +
3565
			"    private Class<Type> typeClass;\n" +
3566
			"    public E(Class<Type> typeClass) {\n" +
3567
			"        this.typeClass = typeClass;\n" +
3568
			"    }\n" +
3569
			"    public Type getObject() {\n" +
3570
			"        try {\n" +
3571
			"            return (Type) typeClass.newInstance();\n" +
3572
			"        } catch (Exception e) {\n" +
3573
			"            throw new RuntimeException(e);\n" +
3574
			"        }\n" +
3575
			"    }\n" +
3576
			"}\n" +
3577
			"interface I<ModelType, ValueType> {\n" +
3578
			"    public void doSet(ModelType model);\n" +
3579
			"    public void set(ValueType value);\n" +
3580
			"}\n"
3581
3582
		},
3583
		"In B.set(CharSequence)");
3584
}
3585
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=302358
3586
public void test082() {
3587
	this.runConformTest(
3588
		new String[] {
3589
			"C.java",
3590
			"class A<ModelType extends D, ValueType> extends I<ModelType, ValueType> {\n" +
3591
			"    public void doSet(ModelType valueGetter) {\n" +
3592
			"        this.set((ValueType) valueGetter.getObject());\n" +
3593
			"    }\n" +
3594
			"    public void set(Object object) {\n" +
3595
			"        System.out.println(\"In A.set(Object)\");\n" +
3596
			"    }\n" +
3597
			"}\n" +
3598
			"class B extends A<E, CharSequence> {\n" +
3599
			"	public void set(CharSequence string) {\n" +
3600
			"        System.out.println(\"In B.set(CharSequence)\");\n" +
3601
			"    }\n" +
3602
			"}\n" +
3603
			"public class C extends B {\n" +
3604
			"    static public void main(String[] args) {\n" +
3605
			"        C c = new C();\n" +
3606
			"        c.run();\n" +
3607
			"    }\n" +
3608
			"    public void run() {\n" +
3609
			"        E e = new E<String>(String.class);\n" +
3610
			"        this.doSet(e);\n" +
3611
			"    }\n" +
3612
			"}\n" +
3613
			"class D {\n" +
3614
			"    public Object getObject() {\n" +
3615
			"        return null;\n" +
3616
			"    }\n" +
3617
			"}\n" +
3618
			"class E<Type extends CharSequence> extends D {\n" +
3619
			"    private Class<Type> typeClass;\n" +
3620
			"    public E(Class<Type> typeClass) {\n" +
3621
			"        this.typeClass = typeClass;\n" +
3622
			"    }\n" +
3623
			"    public Type getObject() {\n" +
3624
			"        try {\n" +
3625
			"            return (Type) typeClass.newInstance();\n" +
3626
			"        } catch (Exception e) {\n" +
3627
			"            throw new RuntimeException(e);\n" +
3628
			"        }\n" +
3629
			"    }\n" +
3630
			"}\n" +
3631
			"abstract class I<ModelType, ValueType> {\n" +
3632
			"    public abstract void doSet(ModelType model);\n" +
3633
			"    public abstract void set(ValueType value);\n" +
3634
			"}\n"
3635
3636
		},
3637
		"In B.set(CharSequence)");
3638
}
3639
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=302358
3640
public void test083() {
3641
	this.runConformTest(
3642
		new String[] {
3643
			"C.java",
3644
			"class A<ModelType extends D, ValueType> implements I<ModelType, ValueType> {\n" +
3645
			"    public void doSet(ModelType valueGetter) {\n" +
3646
			"        this.set((ValueType) valueGetter.getObject());\n" +
3647
			"    }\n" +
3648
			"    public void set(Object object) {\n" +
3649
			"        System.out.println(\"In A.set(Object)\");\n" +
3650
			"    }\n" +
3651
			"}\n" +
3652
			"class B extends A<E, CharSequence> implements I<E, CharSequence> {\n" +
3653
			"	public void set(CharSequence string) {\n" +
3654
			"        System.out.println(\"In B.set(CharSequence)\");\n" +
3655
			"    }\n" +
3656
			"}\n" +
3657
			"public class C extends B {\n" +
3658
			"    static public void main(String[] args) {\n" +
3659
			"        C c = new C();\n" +
3660
			"        c.run();\n" +
3661
			"    }\n" +
3662
			"    public void run() {\n" +
3663
			"        E e = new E<String>(String.class);\n" +
3664
			"        this.doSet(e);\n" +
3665
			"    }\n" +
3666
			"}\n" +
3667
			"class D {\n" +
3668
			"    public Object getObject() {\n" +
3669
			"        return null;\n" +
3670
			"    }\n" +
3671
			"}\n" +
3672
			"class E<Type extends CharSequence> extends D {\n" +
3673
			"    private Class<Type> typeClass;\n" +
3674
			"    public E(Class<Type> typeClass) {\n" +
3675
			"        this.typeClass = typeClass;\n" +
3676
			"    }\n" +
3677
			"    public Type getObject() {\n" +
3678
			"        try {\n" +
3679
			"            return (Type) typeClass.newInstance();\n" +
3680
			"        } catch (Exception e) {\n" +
3681
			"            throw new RuntimeException(e);\n" +
3682
			"        }\n" +
3683
			"    }\n" +
3684
			"}\n" +
3685
			"interface I<ModelType, ValueType> {\n" +
3686
			"    public void doSet(ModelType model);\n" +
3687
			"    public void set(ValueType value);\n" +
3688
			"}\n"
3689
3690
		},
3691
		"In B.set(CharSequence)");
3692
}
3693
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=302358
3694
public void test084() {
3695
	this.runConformTest(
3696
		new String[] {
3697
			"C.java",
3698
			"abstract class A<ModelType extends D, ValueType> implements I<ModelType, ValueType> {\n" +
3699
			"    public void doSet(ModelType valueGetter) {\n" +
3700
			"        this.set((ValueType) valueGetter.getObject());\n" +
3701
			"    }\n" +
3702
			"    public void set(Object object) {\n" +
3703
			"        System.out.println(\"In A.set(Object)\");\n" +
3704
			"    }\n" +
3705
			"}\n" +
3706
			"class B extends A<E, CharSequence> {\n" +
3707
			"}\n" +
3708
			"public class C extends B {\n" +
3709
			"    static public void main(String[] args) {\n" +
3710
			"        C c = new C();\n" +
3711
			"        c.run();\n" +
3712
			"    }\n" +
3713
			"    public void run() {\n" +
3714
			"        E e = new E<String>(String.class);\n" +
3715
			"        this.doSet(e);\n" +
3716
			"    }\n" +
3717
			"}\n" +
3718
			"class D {\n" +
3719
			"    public Object getObject() {\n" +
3720
			"        return null;\n" +
3721
			"    }\n" +
3722
			"}\n" +
3723
			"class E<Type extends CharSequence> extends D {\n" +
3724
			"    private Class<Type> typeClass;\n" +
3725
			"    public E(Class<Type> typeClass) {\n" +
3726
			"        this.typeClass = typeClass;\n" +
3727
			"    }\n" +
3728
			"    public Type getObject() {\n" +
3729
			"        try {\n" +
3730
			"            return (Type) typeClass.newInstance();\n" +
3731
			"        } catch (Exception e) {\n" +
3732
			"            throw new RuntimeException(e);\n" +
3733
			"        }\n" +
3734
			"    }\n" +
3735
			"}\n" +
3736
			"interface I<ModelType, ValueType> {\n" +
3737
			"    public void doSet(ModelType model);\n" +
3738
			"    public void set(ValueType value);\n" +
3739
			"}\n"
3740
3741
		},
3742
		"In A.set(Object)");
3743
}
3744
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=302358
3745
public void test085() {
3746
	this.runConformTest(
3747
		new String[] {
3748
			"C.java",
3749
			"class A<ModelType extends D, ValueType> implements I<ModelType, ValueType> {\n" +
3750
			"    public void doSet(ModelType valueGetter) {\n" +
3751
			"        this.set((ValueType) valueGetter.getObject());\n" +
3752
			"    }\n" +
3753
			"    public void set(Object object) {\n" +
3754
			"        System.out.println(\"In A.set(Object)\");\n" +
3755
			"    }\n" +
3756
			"}\n" +
3757
			"class B extends A<E, CharSequence> {\n" +
3758
			"}\n" +
3759
			"public class C extends B {\n" +
3760
			"    static public void main(String[] args) {\n" +
3761
			"        C c = new C();\n" +
3762
			"        c.run();\n" +
3763
			"    }\n" +
3764
			"    public void run() {\n" +
3765
			"        E e = new E<String>(String.class);\n" +
3766
			"        this.doSet(e);\n" +
3767
			"    }\n" +
3768
			"}\n" +
3769
			"class D {\n" +
3770
			"    public Object getObject() {\n" +
3771
			"        return null;\n" +
3772
			"    }\n" +
3773
			"}\n" +
3774
			"class E<Type extends CharSequence> extends D {\n" +
3775
			"    private Class<Type> typeClass;\n" +
3776
			"    public E(Class<Type> typeClass) {\n" +
3777
			"        this.typeClass = typeClass;\n" +
3778
			"    }\n" +
3779
			"    public Type getObject() {\n" +
3780
			"        try {\n" +
3781
			"            return (Type) typeClass.newInstance();\n" +
3782
			"        } catch (Exception e) {\n" +
3783
			"            throw new RuntimeException(e);\n" +
3784
			"        }\n" +
3785
			"    }\n" +
3786
			"}\n" +
3787
			"interface I<ModelType, ValueType> {\n" +
3788
			"    public void doSet(ModelType model);\n" +
3789
			"    public void set(ValueType value);\n" +
3790
			"}\n"
3791
3792
		},
3793
		"In A.set(Object)");
3794
}
3795
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=302358
3796
public void test086() {
3797
	this.runConformTest(
3798
		new String[] {
3799
			"C.java",
3800
			"class A<ModelType extends D, ValueType> {\n" +
3801
			"    public void doSet(ModelType valueGetter) {\n" +
3802
			"        this.set((ValueType) valueGetter.getObject());\n" +
3803
			"    }\n" +
3804
			"    public void set(Object object) {\n" +
3805
			"        System.out.println(\"In A.set(Object)\");\n" +
3806
			"    }\n" +
3807
			"}\n" +
3808
			"class B extends A<E, CharSequence> {\n" +
3809
			"	public void set(CharSequence string) {\n" +
3810
			"        System.out.println(\"In B.set(CharSequence)\");\n" +
3811
			"    }\n" +
3812
			"}\n" +
3813
			"public class C extends B {\n" +
3814
			"    static public void main(String[] args) {\n" +
3815
			"        C c = new C();\n" +
3816
			"        c.run();\n" +
3817
			"    }\n" +
3818
			"    public void run() {\n" +
3819
			"        E e = new E<String>(String.class);\n" +
3820
			"        this.doSet(e);\n" +
3821
			"    }\n" +
3822
			"}\n" +
3823
			"class D {\n" +
3824
			"    public Object getObject() {\n" +
3825
			"        return null;\n" +
3826
			"    }\n" +
3827
			"}\n" +
3828
			"class E<Type extends CharSequence> extends D {\n" +
3829
			"    private Class<Type> typeClass;\n" +
3830
			"    public E(Class<Type> typeClass) {\n" +
3831
			"        this.typeClass = typeClass;\n" +
3832
			"    }\n" +
3833
			"    public Type getObject() {\n" +
3834
			"        try {\n" +
3835
			"            return (Type) typeClass.newInstance();\n" +
3836
			"        } catch (Exception e) {\n" +
3837
			"            throw new RuntimeException(e);\n" +
3838
			"        }\n" +
3839
			"    }\n" +
3840
			"}\n" +
3841
			"interface I<ModelType, ValueType> {\n" +
3842
			"    public void doSet(ModelType model);\n" +
3843
			"    public void set(ValueType value);\n" +
3844
			"}\n"
3845
3846
		},
3847
		"In A.set(Object)");
3848
}
3531
}
3849
}

Return to bug 302358