diff options
author | Jay Arthanareeswaran | 2017-09-07 05:44:20 +0000 |
---|---|---|
committer | Jay Arthanareeswaran | 2017-09-08 17:52:53 +0000 |
commit | 68640a1ceae6bddcdd1ba7a60e1aa3feddb7585a (patch) | |
tree | c76be72e0fc78b994ea507db77919414b51c27ec | |
parent | 87fa7ba2c662b410b996b3cb751bc23551d1d4c6 (diff) | |
download | eclipse.jdt.core-68640a1ceae6bddcdd1ba7a60e1aa3feddb7585a.tar.gz eclipse.jdt.core-68640a1ceae6bddcdd1ba7a60e1aa3feddb7585a.tar.xz eclipse.jdt.core-68640a1ceae6bddcdd1ba7a60e1aa3feddb7585a.zip |
Bug 520874: [compiler] difference in behavior in single static import
and on-demand
Fix to report nested types being part of a inheritance cycle.
Change-Id: Ib29993c77e532bd96ceb77d123305e8dc6f9e6ae
Signed-off-by: Jay Arthanareeswaran <jarthana@in.ibm.com>
3 files changed, 315 insertions, 17 deletions
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java index 0fcfba7f8f..94b05400cf 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2016 IBM Corporation and others. + * Copyright (c) 2000, 2017 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -34424,11 +34424,16 @@ public void test1021b() { // should this case be allowed? " }\n" + "}\n", }, - "----------\n" + - "1. ERROR in p\\SomeClass2.java (at line 3)\n" + - " public abstract class SomeClass2<T> extends M {\n" + - " ^\n" + - "Cycle detected: the type SomeClass2<T> cannot extend/implement itself or one of its own member types\n" + + "----------\n" + + "1. ERROR in p\\SomeClass2.java (at line 3)\n" + + " public abstract class SomeClass2<T> extends M {\n" + + " ^\n" + + "M cannot be resolved to a type\n" + + "----------\n" + + "2. ERROR in p\\SomeClass2.java (at line 4)\n" + + " public static class M1 extends M2 {}\n" + + " ^^\n" + + "Cycle detected: a cycle exists in the type hierarchy between SomeClass2.M1 and SomeClass2<T>\n" + "----------\n" ); } diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/InnerClass15Test.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/InnerClass15Test.java index bd0ae63e80..a30af63428 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/InnerClass15Test.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/InnerClass15Test.java @@ -1,10 +1,14 @@ /******************************************************************************* - * Copyright (c) 2010, 2014 IBM Corporation and others. + * Copyright (c) 2010, 2017 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ @@ -14,21 +18,22 @@ import java.util.Map; import junit.framework.Test; +import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; -@SuppressWarnings({ "unchecked", "rawtypes" }) public class InnerClass15Test extends AbstractRegressionTest { public InnerClass15Test(String name) { super(name); } static { // TESTS_NUMBERS = new int[] { 2 }; + //TESTS_NAMES = new String[] {"testBug520874"}; } public static Test suite() { return buildMinimalComplianceTestSuite(testClass(), F_1_5); } -protected Map getCompilerOptions() { - Map options = super.getCompilerOptions(); +protected Map<String, String> getCompilerOptions() { + Map<String, String> options = super.getCompilerOptions(); options.put(CompilerOptions.OPTION_ReportRawTypeReference, CompilerOptions.IGNORE); return options; } @@ -424,7 +429,290 @@ public void test0014() { "Cycle detected: a cycle exists in the type hierarchy between C and X\n" + "----------\n"); } -public static Class testClass() { +public void testBug520874a() { + if (this.complianceLevel < ClassFileConstants.JDK9) + return; // Limit the new tests to newer levels + this.runNegativeTest(new String[] { + "cycle/A.java", + "package p;\n" + + "class A extends C {\n" + + " static class B {}\n" + + "}\n", + "cycle/X.java", + "package p;\n" + + "import p.A.B;\n" + + "class C extends B {}\n" + + "public class X {\n" + + " public static void main(String argv[]) {\n" + + " new C();\n" + + " }\n" + + "}\n", + }, + "----------\n" + + "1. ERROR in cycle\\A.java (at line 2)\n" + + " class A extends C {\n" + + " ^\n" + + "The hierarchy of the type A is inconsistent\n" + + "----------\n" + + "----------\n" + + "1. ERROR in cycle\\X.java (at line 3)\n" + + " class C extends B {}\n" + + " ^\n" + + "Cycle detected: a cycle exists in the type hierarchy between C and A\n" + + "----------\n"); +} +public void testBug520874b() { + if (this.complianceLevel < ClassFileConstants.JDK9) + return; // Limit the new tests to newer levels + this.runNegativeTest(new String[] { + "cycle/X.java", + "package p;\n" + + "import p.A.*;\n" + + "class C extends B {}\n" + + "public class X {\n" + + " public static void main(String argv[]) {\n" + + " new C();\n" + + " }\n" + + "}\n", + "cycle/A.java", + "package p;\n" + + "class A extends C {\n" + + " static class B {}\n" + + "}\n" + }, + "----------\n" + + "1. ERROR in cycle\\X.java (at line 3)\n" + + " class C extends B {}\n" + + " ^\n" + + "The hierarchy of the type C is inconsistent\n" + + "----------\n" + + "----------\n" + + "1. ERROR in cycle\\A.java (at line 2)\n" + + " class A extends C {\n" + + " ^\n" + + "Cycle detected: a cycle exists in the type hierarchy between A and C\n" + + "----------\n"); +} +public void testBug520874c() { + if (this.complianceLevel < ClassFileConstants.JDK1_8) + return; // Limit the new tests to newer levels + this.runNegativeTest(new String[] { + "cycle/X.java", + "package cycle;\n" + + "import cycle.A.B;\n" + + "class C implements B {}\n" + + "public class X {\n" + + " public static void main(String argv[]) {\n" + + " new C();\n" + + " }\n" + + "}\n", + "cycle/A.java", + "package cycle;\n" + + "class A extends C {\n" + + " static interface B {}\n" + + "}\n" + }, + "----------\n" + + "1. ERROR in cycle\\X.java (at line 3)\n" + + " class C implements B {}\n" + + " ^\n" + + "The hierarchy of the type C is inconsistent\n" + + "----------\n" + + "----------\n" + + "1. ERROR in cycle\\A.java (at line 2)\n" + + " class A extends C {\n" + + " ^\n" + + "Cycle detected: a cycle exists in the type hierarchy between A and C\n" + + "----------\n"); +} +public void testBug520874d() { + if (this.complianceLevel < ClassFileConstants.JDK1_8) + return; // Limit the new tests to newer levels + this.runNegativeTest(new String[] { + "cycle/X.java", + "package cycle;\n" + + "import cycle.A.*;\n" + + "class C implements B {}\n" + + "public class X {\n" + + " public static void main(String argv[]) {\n" + + " new C();\n" + + " }\n" + + "}\n", + "cycle/A.java", + "package cycle;\n" + + "class A extends C {\n" + + " static interface B {}\n" + + "}\n" + }, + "----------\n" + + "1. ERROR in cycle\\X.java (at line 3)\n" + + " class C implements B {}\n" + + " ^\n" + + "The hierarchy of the type C is inconsistent\n" + + "----------\n" + + "----------\n" + + "1. ERROR in cycle\\A.java (at line 2)\n" + + " class A extends C {\n" + + " ^\n" + + "Cycle detected: a cycle exists in the type hierarchy between A and C\n" + + "----------\n"); +} +public void testBug520874e() { + if (this.complianceLevel < ClassFileConstants.JDK1_8) + return; // Limit the new tests to newer levels + this.runNegativeTest(new String[] { + "cycle/X.java", + "package cycle;\n" + + "import cycle.A.B;\n" + + "interface C extends B {}\n" + + "public class X {\n" + + " public static void main(String argv[]) {\n" + + " }\n" + + "}\n", + "cycle/A.java", + "package cycle;\n" + + "class A extends C {\n" + + " static interface B {}\n" + + "}\n" + }, + "----------\n" + + "1. ERROR in cycle\\X.java (at line 3)\n" + + " interface C extends B {}\n" + + " ^\n" + + "The hierarchy of the type C is inconsistent\n" + + "----------\n" + + "----------\n" + + "1. ERROR in cycle\\A.java (at line 2)\n" + + " class A extends C {\n" + + " ^\n" + + "Cycle detected: a cycle exists in the type hierarchy between A and C\n" + + "----------\n"); +} +public void testBug520874f() { + if (this.complianceLevel < ClassFileConstants.JDK1_8) + return; // Limit the new tests to newer levels + this.runNegativeTest(new String[] { + "cycle/X.java", + "package cycle;\n" + + "import cycle.A.*;\n" + + "interface C extends B {}\n" + + "public class X {\n" + + " public static void main(String argv[]) {\n" + + " }\n" + + "}\n", + "cycle/A.java", + "package cycle;\n" + + "class A extends C {\n" + + " static interface B {}\n" + + "}\n" + }, + "----------\n" + + "1. ERROR in cycle\\X.java (at line 3)\n" + + " interface C extends B {}\n" + + " ^\n" + + "The hierarchy of the type C is inconsistent\n" + + "----------\n" + + "----------\n" + + "1. ERROR in cycle\\A.java (at line 2)\n" + + " class A extends C {\n" + + " ^\n" + + "Cycle detected: a cycle exists in the type hierarchy between A and C\n" + + "----------\n"); +} +public void testBug520874g() { + if (this.complianceLevel < ClassFileConstants.JDK1_8) + return; // Limit the new tests to newer levels + this.runNegativeTest(new String[] { + "cycle/X.java", + "package cycle;\n" + + "import cycle.A.B;\n" + + "interface C extends B {}\n" + + "public class X {\n" + + " public static void main(String argv[]) {\n" + + " }\n" + + "}\n", + "cycle/A.java", + "package cycle;\n" + + "interface A extends C {\n" + + " static interface B {}\n" + + "}\n" + }, + "----------\n" + + "1. ERROR in cycle\\X.java (at line 3)\n" + + " interface C extends B {}\n" + + " ^\n" + + "The hierarchy of the type C is inconsistent\n" + + "----------\n" + + "----------\n" + + "1. ERROR in cycle\\A.java (at line 2)\n" + + " interface A extends C {\n" + + " ^\n" + + "Cycle detected: a cycle exists in the type hierarchy between A and C\n" + + "----------\n"); +} +public void testBug520874h() { + if (this.complianceLevel < ClassFileConstants.JDK1_8) + return; // Limit the new tests to newer levels + this.runNegativeTest(new String[] { + "cycle/X.java", + "package cycle;\n" + + "import cycle.A.*;\n" + + "interface C extends B {}\n" + + "public class X {\n" + + " public static void main(String argv[]) {\n" + + " }\n" + + "}\n", + "cycle/A.java", + "package cycle;\n" + + "interface A extends C {\n" + + " static interface B {}\n" + + "}\n" + }, + "----------\n" + + "1. ERROR in cycle\\X.java (at line 3)\n" + + " interface C extends B {}\n" + + " ^\n" + + "The hierarchy of the type C is inconsistent\n" + + "----------\n" + + "----------\n" + + "1. ERROR in cycle\\A.java (at line 2)\n" + + " interface A extends C {\n" + + " ^\n" + + "Cycle detected: a cycle exists in the type hierarchy between A and C\n" + + "----------\n"); +} +public void testBug520874i() { + if (this.complianceLevel < ClassFileConstants.JDK1_8) + return; // Limit the new tests to newer levels + this.runNegativeTest(new String[] { + "cycle/X.java", + "package cycle;\n" + + "import cycle.A.*;\n" + + "interface C extends A {}\n" + + "public class X {\n" + + " public static void main(String argv[]) {\n" + + " }\n" + + "}\n", + "cycle/A.java", + "package cycle;\n" + + "interface A extends C {\n" + + " static interface B {}\n" + + "}\n" + }, + "----------\n" + + "1. ERROR in cycle\\X.java (at line 3)\n" + + " interface C extends A {}\n" + + " ^\n" + + "The hierarchy of the type C is inconsistent\n" + + "----------\n" + + "----------\n" + + "1. ERROR in cycle\\A.java (at line 2)\n" + + " interface A extends C {\n" + + " ^\n" + + "Cycle detected: a cycle exists in the type hierarchy between A and C\n" + + "----------\n"); +} +public static Class<InnerClass15Test> testClass() { return InnerClass15Test.class; } } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java index 8a7a560561..23db9de1fb 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java @@ -1228,7 +1228,7 @@ public class ClassScope extends Scope { if (superType.isMemberType()) { ReferenceBinding current = superType.enclosingType(); do { - if (current.isHierarchyBeingActivelyConnected() && TypeBinding.equalsEquals(current, sourceType)) { + if (current.isHierarchyBeingActivelyConnected()) { problemReporter().hierarchyCircularity(sourceType, current, reference); sourceType.tagBits |= TagBits.HierarchyHasProblems; current.tagBits |= TagBits.HierarchyHasProblems; @@ -1290,11 +1290,16 @@ public class ClassScope extends Scope { org.eclipse.jdt.internal.compiler.ast.TypeReference ref = ((SourceTypeBinding) superType).scope.superTypeReference; // https://bugs.eclipse.org/bugs/show_bug.cgi?id=133071 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=121734 - if (ref != null && ref.resolvedType != null && ((ReferenceBinding) ref.resolvedType).isHierarchyBeingActivelyConnected()) { - problemReporter().hierarchyCircularity(sourceType, superType, reference); - sourceType.tagBits |= TagBits.HierarchyHasProblems; - superType.tagBits |= TagBits.HierarchyHasProblems; - return true; + if (ref != null && ref.resolvedType != null) { + ReferenceBinding s = (ReferenceBinding) ref.resolvedType; + do { + if (s.isHierarchyBeingActivelyConnected()) { + problemReporter().hierarchyCircularity(sourceType, superType, reference); + sourceType.tagBits |= TagBits.HierarchyHasProblems; + superType.tagBits |= TagBits.HierarchyHasProblems; + return true; + } + } while ((s = s.enclosingType()) != null); } if (ref != null && ref.resolvedType == null) { // https://bugs.eclipse.org/bugs/show_bug.cgi?id=319885 Don't cry foul prematurely. |