### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.core Index: compiler/org/eclipse/jdt/internal/compiler/ast/TypeReference.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeReference.java,v retrieving revision 1.42 diff -u -r1.42 TypeReference.java --- compiler/org/eclipse/jdt/internal/compiler/ast/TypeReference.java 3 Nov 2009 15:12:57 -0000 1.42 +++ compiler/org/eclipse/jdt/internal/compiler/ast/TypeReference.java 1 Feb 2010 13:41:09 -0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2008 IBM Corporation and others. + * Copyright (c) 2000, 2010 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 @@ -22,6 +22,7 @@ import org.eclipse.jdt.internal.compiler.lookup.ProblemReferenceBinding; import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding; import org.eclipse.jdt.internal.compiler.lookup.Scope; +import org.eclipse.jdt.internal.compiler.lookup.TagBits; import org.eclipse.jdt.internal.compiler.lookup.TypeBinding; import org.eclipse.jdt.internal.compiler.lookup.TypeIds; import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities; @@ -210,7 +211,22 @@ } public TypeBinding resolveTypeArgument(ClassScope classScope, ReferenceBinding genericType, int rank) { - return resolveType(classScope); + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=294057, circularity is allowed when we are + // resolving type arguments i.e interface A {} interface B extends A {} + // interface D extends C {} interface C extends B {} + ReferenceBinding ref = classScope.referenceContext.binding; + boolean pauseHierarchyCheck = false; + try { + if (ref.isHierarchyBeingConnected()) { + ref.tagBits |= TagBits.PauseHierarchyCheck; + pauseHierarchyCheck = true; + } + return resolveType(classScope); + } finally { + if (pauseHierarchyCheck) { + ref.tagBits &= ~TagBits.PauseHierarchyCheck; + } + } } public abstract void traverse(ASTVisitor visitor, BlockScope scope); Index: compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java,v retrieving revision 1.174 diff -u -r1.174 ClassScope.java --- compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java 13 Jan 2010 16:35:58 -0000 1.174 +++ compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java 1 Feb 2010 13:41:10 -0000 @@ -1087,6 +1087,12 @@ compilationUnitScope().recordSuperTypeReference(superType); // to record supertypes return detectHierarchyCycle(this.referenceContext.binding, (ReferenceBinding) superType, reference); } + // Reinstate the code deleted by the fix for https://bugs.eclipse.org/bugs/show_bug.cgi?id=205235 + // For details, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=294057. + if ((superType.tagBits & TagBits.BeginHierarchyCheck) == 0 && superType instanceof SourceTypeBinding) + // ensure if this is a source superclass that it has already been checked + ((SourceTypeBinding) superType).scope.connectTypeHierarchyWithoutMembers(); + return false; } @@ -1105,7 +1111,7 @@ if (superType.isMemberType()) { ReferenceBinding current = superType.enclosingType(); do { - if (current.isHierarchyBeingConnected() && current == sourceType) { + if (current.isHierarchyBeingActivelyConnected() && current == sourceType) { problemReporter().hierarchyCircularity(sourceType, current, reference); sourceType.tagBits |= TagBits.HierarchyHasProblems; current.tagBits |= TagBits.HierarchyHasProblems; @@ -1158,11 +1164,11 @@ return hasCycle; } - if (superType.isHierarchyBeingConnected()) { + if (superType.isHierarchyBeingActivelyConnected()) { 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).isHierarchyBeingConnected())) { + if (ref != null && (ref.resolvedType == null || ((ReferenceBinding) ref.resolvedType).isHierarchyBeingActivelyConnected())) { problemReporter().hierarchyCircularity(sourceType, superType, reference); sourceType.tagBits |= TagBits.HierarchyHasProblems; superType.tagBits |= TagBits.HierarchyHasProblems; Index: compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java,v retrieving revision 1.138 diff -u -r1.138 ReferenceBinding.java --- compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java 11 Nov 2009 05:40:46 -0000 1.138 +++ compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java 1 Feb 2010 13:41:10 -0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2009 IBM Corporation and others. + * Copyright (c) 2000, 2010 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 @@ -1074,6 +1074,13 @@ public boolean isHierarchyBeingConnected() { return (this.tagBits & TagBits.EndHierarchyCheck) == 0 && (this.tagBits & TagBits.BeginHierarchyCheck) != 0; } +/** + * Returns true if the type hierarchy is being connected "actively" i.e not paused momentatrily, + * while resolving type arguments. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=294057 + */ +public boolean isHierarchyBeingActivelyConnected() { + return (this.tagBits & TagBits.EndHierarchyCheck) == 0 && (this.tagBits & TagBits.BeginHierarchyCheck) != 0 && (this.tagBits & TagBits.PauseHierarchyCheck) == 0; +} /** * Returns true if the type hierarchy is connected Index: compiler/org/eclipse/jdt/internal/compiler/lookup/TagBits.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TagBits.java,v retrieving revision 1.40 diff -u -r1.40 TagBits.java --- compiler/org/eclipse/jdt/internal/compiler/lookup/TagBits.java 3 Nov 2009 15:37:47 -0000 1.40 +++ compiler/org/eclipse/jdt/internal/compiler/lookup/TagBits.java 1 Feb 2010 13:41:10 -0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2009 IBM Corporation and others. + * Copyright (c) 2000, 2010 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 @@ -39,6 +39,7 @@ // for the type cycle hierarchy check used by ClassScope long BeginHierarchyCheck = ASTNode.Bit9; // type long EndHierarchyCheck = ASTNode.Bit10; // type + long PauseHierarchyCheck = ASTNode.Bit20; // type long HasParameterAnnotations = ASTNode.Bit11; // method/constructor #P org.eclipse.jdt.core.tests.builder Index: src/org/eclipse/jdt/core/tests/builder/Java50Tests.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/Java50Tests.java,v retrieving revision 1.17 diff -u -r1.17 Java50Tests.java --- src/org/eclipse/jdt/core/tests/builder/Java50Tests.java 27 Aug 2009 15:27:03 -0000 1.17 +++ src/org/eclipse/jdt/core/tests/builder/Java50Tests.java 1 Feb 2010 13:41:14 -0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2009 IBM Corporation and others. + * Copyright (c) 2000, 2010 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 @@ -311,5 +311,69 @@ "Problem : Unhandled exception type Exception [ resource : range : <92,132> category : <40> severity : <2>]" ); } + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=294057 + public void testHierarchyNonCycle() throws JavaModelException { + IPath projectPath = env.addProject("Project", "1.5"); + env.addExternalJars(projectPath, Util.getJavaClassLibs()); + env.setOutputFolder(projectPath, ""); + + env.addClass(projectPath, "superint", "SuperInterface", + "package superint;\n" + + "public interface SuperInterface {\n" + + " public interface SuperInterfaceGetter {}\n" + + " public interface SuperInterfaceSetter {}\n" + + "}\n" + ); + env.addClass(projectPath, "subint", "SubInterface", + "package subint;\n" + + "import superint.SuperInterface;\n" + + "public interface SubInterface extends\n" + + " SuperInterface {\n" + + " public interface SubInterfaceGetter extends SuperInterfaceGetter {}\n" + + " public interface SubInterfaceSetter extends SuperInterfaceSetter {}\n" + + "}\n" + ); + + fullBuild(projectPath); + expectingProblemsFor( + projectPath, + "Problem : Bound mismatch: The type SubInterface.SubInterfaceGetter is not a valid substitute for the bounded parameter of the type SuperInterface [ resource : range : <105,136> category : <40> severity : <2>]\n" + + "Problem : Bound mismatch: The type SubInterface.SubInterfaceSetter is not a valid substitute for the bounded parameter of the type SuperInterface [ resource : range : <157,188> category : <40> severity : <2>]\n" + + "Problem : SuperInterfaceGetter cannot be resolved to a type [ resource : range : <244,264> category : <40> severity : <2>]\n" + + "Problem : SuperInterfaceSetter cannot be resolved to a type [ resource : range : <320,340> category : <40> severity : <2>]" + ); + } + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=294057 (variation) + public void testHierarchyNonCycle2() throws JavaModelException { + IPath projectPath = env.addProject("Project", "1.5"); + env.addExternalJars(projectPath, Util.getJavaClassLibs()); + env.setOutputFolder(projectPath, ""); + + env.addClass(projectPath, "superint", "SuperInterface", + "package superint;\n" + + "public interface SuperInterface {\n" + + " public interface SuperInterfaceGetter {}\n" + + " public interface SuperInterfaceSetter {}\n" + + "}\n" + ); + env.addClass(projectPath, "subint", "SubInterface", + "package subint;\n" + + "import superint.SuperInterface;\n" + + "import superint.SuperInterface.SuperInterfaceGetter;\n" + + "import superint.SuperInterface.SuperInterfaceSetter;\n" + + "public interface SubInterface extends\n" + + " SuperInterface {\n" + + " public interface SubInterfaceGetter extends SuperInterfaceGetter {}\n" + + " public interface SubInterfaceSetter extends SuperInterfaceSetter {}\n" + + "}\n" + ); + + fullBuild(projectPath); + expectingNoProblems(); + } }