### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.core.tests Index: Eclipse Java Tests Compiler/org/eclipse/jdt/tests/compiler/regression/NegativeTest.java =================================================================== RCS file: /home/cvs/numbat/org.eclipse.jdt.core.tests/Eclipse Java Tests Compiler/org/eclipse/jdt/tests/compiler/regression/NegativeTest.java,v retrieving revision 1.288.4.1 diff -u -r1.288.4.1 NegativeTest.java --- Eclipse Java Tests Compiler/org/eclipse/jdt/tests/compiler/regression/NegativeTest.java 20 Dec 2006 16:14:50 -0000 1.288.4.1 +++ Eclipse Java Tests Compiler/org/eclipse/jdt/tests/compiler/regression/NegativeTest.java 22 Dec 2006 15:45:01 -0000 @@ -15478,6 +15478,11 @@ " bar().missing();\n" + " ^^^^^^^^^^^^^^^\n" + "The type plugin3.SecretClass cannot be resolved. It is indirectly referenced from required .class files\n" + + "----------\n" + + "2. ERROR in plugin1\\Main.java (at line 5)\n" + + " bar().missing();\n" + + " ^^^^^^^\n" + + "The method missing() is undefined for the type Dumbo\n" + "----------\n", null, false); #P org.eclipse.jdt.core.tests.builder Index: src/org/eclipse/jdt/core/tests/builder/DependencyTests.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/DependencyTests.java,v retrieving revision 1.18 diff -u -r1.18 DependencyTests.java --- src/org/eclipse/jdt/core/tests/builder/DependencyTests.java 29 Mar 2006 03:16:23 -0000 1.18 +++ src/org/eclipse/jdt/core/tests/builder/DependencyTests.java 22 Dec 2006 15:56:05 -0000 @@ -806,6 +806,77 @@ expectingNoProblems(); } + public void testMissingClassFile() throws JavaModelException { + IPath project1Path = env.addProject("Project1"); //$NON-NLS-1$ + env.addExternalJars(project1Path, Util.getJavaClassLibs()); + + // remove old package fragment root so that names don't collide + env.removePackageFragmentRoot(project1Path,""); //$NON-NLS-1$ + + IPath root1 = env.addPackageFragmentRoot(project1Path, "src"); //$NON-NLS-1$ + env.setOutputFolder(project1Path, "bin"); //$NON-NLS-1$ + + env.addClass(root1, "p1", "MissingClass", //$NON-NLS-1$ //$NON-NLS-2$ + "package p1;\n"+ //$NON-NLS-1$ + "public class MissingClass {}" //$NON-NLS-1$ + ); + + IPath project2Path = env.addProject("Project2"); //$NON-NLS-1$ + env.addExternalJars(project2Path, Util.getJavaClassLibs()); + env.addRequiredProject(project2Path, project1Path); + + // remove old package fragment root so that names don't collide + env.removePackageFragmentRoot(project2Path,""); //$NON-NLS-1$ + + IPath root2 = env.addPackageFragmentRoot(project2Path, "src"); //$NON-NLS-1$ + env.setOutputFolder(project2Path, "bin"); //$NON-NLS-1$ + + env.addClass(root2, "p2", "A", //$NON-NLS-1$ //$NON-NLS-2$ + "package p2;\n"+ //$NON-NLS-1$ + "import p1.MissingClass;\n" + + "public class A {\n"+ //$NON-NLS-1$ + " public void foo(MissingClass data) {}\n"+ //$NON-NLS-1$ + " public void foo(String data) {}\n"+ //$NON-NLS-1$ + "}\n" //$NON-NLS-1$ + ); + + IPath project3Path = env.addProject("Project3"); //$NON-NLS-1$ + env.addExternalJars(project3Path, Util.getJavaClassLibs()); + env.addRequiredProject(project3Path, project2Path); + // missing required Project1 so MissingClass cannot be found + + // remove old package fragment root so that names don't collide + env.removePackageFragmentRoot(project3Path,""); //$NON-NLS-1$ + + IPath root3 = env.addPackageFragmentRoot(project3Path, "src"); //$NON-NLS-1$ + env.setOutputFolder(project3Path, "bin"); //$NON-NLS-1$ + + IPath bPath = env.addClass(root3, "p3", "B", //$NON-NLS-1$ //$NON-NLS-2$ + "package p3;\n"+ //$NON-NLS-1$ + "import p2.A;\n" + + "public class B {\n"+ //$NON-NLS-1$ + " public static void main(String[] args) {\n" + //$NON-NLS-1$ + " new A().foo(new String());\n" + //$NON-NLS-1$ + " }\n" + //$NON-NLS-1$ + "}\n" //$NON-NLS-1$ + ); + + fullBuild(); + expectingOnlyProblemsFor(new IPath[] {project3Path, bPath}); + expectingSpecificProblemFor(project3Path, new Problem("Project3", "The project was not built since its build path is incomplete. Cannot find the class file for p1.MissingClass. Fix the build path then try building this project", project3Path, -1, -1, CategorizedProblem.CAT_BUILDPATH)); //$NON-NLS-1$ //$NON-NLS-2$ + expectingSpecificProblemFor(bPath, new Problem("B", "The type p1.MissingClass cannot be resolved. It is indirectly referenced from required .class files", bPath, 86, 111, CategorizedProblem.CAT_BUILDPATH)); //$NON-NLS-1$ //$NON-NLS-2$ + + env.addClass(root2, "p2", "A", //$NON-NLS-1$ //$NON-NLS-2$ + "package p2;\n"+ //$NON-NLS-1$ + "public class A {\n"+ //$NON-NLS-1$ + " public void foo(String data) {}\n"+ //$NON-NLS-1$ + "}\n" //$NON-NLS-1$ + ); + + incrementalBuild(); + expectingNoProblems(); + } + // 72468 public void testTypeDeleting() throws JavaModelException { IPath projectPath = env.addProject("Project"); //$NON-NLS-1$ Index: src/org/eclipse/jdt/core/tests/builder/MultiProjectTests.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/MultiProjectTests.java,v retrieving revision 1.41 diff -u -r1.41 MultiProjectTests.java --- src/org/eclipse/jdt/core/tests/builder/MultiProjectTests.java 6 Apr 2006 19:16:04 -0000 1.41 +++ src/org/eclipse/jdt/core/tests/builder/MultiProjectTests.java 22 Dec 2006 15:56:06 -0000 @@ -779,7 +779,179 @@ env.setBuildOrder(null); } } - + +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=114349 +// this one fails; compare with testCycle7 (only one change in Object source), +// which passes + public void testCycle6() throws JavaModelException { + Hashtable options = JavaCore.getOptions(); + Hashtable newOptions = JavaCore.getOptions(); + newOptions.put(JavaCore.CORE_CIRCULAR_CLASSPATH, JavaCore.WARNING); + + JavaCore.setOptions(newOptions); + + //---------------------------- + // Project1 + //---------------------------- + IPath p1 = env.addProject("P1"); + // remove old package fragment root so that names don't collide + env.removePackageFragmentRoot(p1, ""); + IPath root1 = env.addPackageFragmentRoot(p1, "src"); + env.setOutputFolder(p1, "bin"); + + env.addClass(root1, "java/lang", "Object", + "package java.lang;\n" + + "public class Object {\n" + + " Class getClass() { return null; }\n" + + " String toString() { return \"\"; }\n" + // the line that changes + "}\n" + ); + + //---------------------------- + // Project2 + //---------------------------- + IPath p2 = env.addProject("P2"); + // remove old package fragment root so that names don't collide + env.removePackageFragmentRoot(p2, ""); + IPath root2 = env.addPackageFragmentRoot(p2, "src"); + env.setOutputFolder(p2, "bin"); + + env.addClass(root2, "java/lang", "Class", + "package java.lang;\n" + + "public class Class {\n" + + " String getName() { return \"\"; };\n" + + "}\n" + ); + + //---------------------------- + // Project3 + //---------------------------- + IPath p3 = env.addProject("P3"); + // remove old package fragment root so that names don't collide + env.removePackageFragmentRoot(p3, ""); + IPath root3 = env.addPackageFragmentRoot(p3, "src"); + env.setOutputFolder(p3, "bin"); + + env.addClass(root3, "java/lang", "String", + "package java.lang;\n" + + "public class String {\n" + + "}\n" + ); + + // Dependencies + IPath[] accessiblePaths = new IPath[] {new Path("java/lang/*")}; + IPath[] forbiddenPaths = new IPath[] {new Path("**/*")}; + env.addRequiredProject(p1, p2, accessiblePaths, forbiddenPaths, false); + env.addRequiredProject(p1, p3, accessiblePaths, forbiddenPaths, false); + env.addRequiredProject(p2, p1, accessiblePaths, forbiddenPaths, false); + env.addRequiredProject(p2, p3, accessiblePaths, forbiddenPaths, false); + env.addRequiredProject(p3, p1, accessiblePaths, forbiddenPaths, false); + env.addRequiredProject(p3, p2, accessiblePaths, forbiddenPaths, false); + + try { + fullBuild(); + + expectingOnlySpecificProblemsFor(p1,new Problem[]{ + new Problem("p1", "A cycle was detected in the build path of project: P1", p1, -1, -1, CategorizedProblem.CAT_BUILDPATH)//$NON-NLS-1$ //$NON-NLS-2$ + }); + expectingOnlySpecificProblemsFor(p2,new Problem[]{ + new Problem("p2", "A cycle was detected in the build path of project: P2", p2, -1, -1, CategorizedProblem.CAT_BUILDPATH)//$NON-NLS-1$ //$NON-NLS-2$ + }); + expectingOnlySpecificProblemsFor(p3,new Problem[]{ + new Problem("p3", "A cycle was detected in the build path of project: P3", p3, -1, -1, CategorizedProblem.CAT_BUILDPATH)//$NON-NLS-1$ //$NON-NLS-2$ + }); + + } finally { + JavaCore.setOptions(options); + } + } + +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=114349 +// this one passes; compare with testCycle6 (only one change in Object source), +// which fails + public void testCycle7() throws JavaModelException { + Hashtable options = JavaCore.getOptions(); + Hashtable newOptions = JavaCore.getOptions(); + newOptions.put(JavaCore.CORE_CIRCULAR_CLASSPATH, JavaCore.WARNING); + + JavaCore.setOptions(newOptions); + + //---------------------------- + // Project1 + //---------------------------- + IPath p1 = env.addProject("P1"); + // remove old package fragment root so that names don't collide + env.removePackageFragmentRoot(p1, ""); + IPath root1 = env.addPackageFragmentRoot(p1, "src"); + env.setOutputFolder(p1, "bin"); + + env.addClass(root1, "java/lang", "Object", + "package java.lang;\n" + + "public class Object {\n" + + " Class getClass() { return null; }\n" + + " String toString() { return null; }\n" + // the line that changes + "}\n" + ); + + //---------------------------- + // Project2 + //---------------------------- + IPath p2 = env.addProject("P2"); + // remove old package fragment root so that names don't collide + env.removePackageFragmentRoot(p2, ""); + IPath root2 = env.addPackageFragmentRoot(p2, "src"); + env.setOutputFolder(p2, "bin"); + + env.addClass(root2, "java/lang", "Class", + "package java.lang;\n" + + "public class Class {\n" + + " String getName() { return \"\"; };\n" + + "}\n" + ); + + //---------------------------- + // Project3 + //---------------------------- + IPath p3 = env.addProject("P3"); + // remove old package fragment root so that names don't collide + env.removePackageFragmentRoot(p3, ""); + IPath root3 = env.addPackageFragmentRoot(p3, "src"); + env.setOutputFolder(p3, "bin"); + + env.addClass(root3, "java/lang", "String", + "package java.lang;\n" + + "public class String {\n" + + "}\n" + ); + + // Dependencies + IPath[] accessiblePaths = new IPath[] {new Path("java/lang/*")}; + IPath[] forbiddenPaths = new IPath[] {new Path("**/*")}; + env.addRequiredProject(p1, p2, accessiblePaths, forbiddenPaths, false); + env.addRequiredProject(p1, p3, accessiblePaths, forbiddenPaths, false); + env.addRequiredProject(p2, p1, accessiblePaths, forbiddenPaths, false); + env.addRequiredProject(p2, p3, accessiblePaths, forbiddenPaths, false); + env.addRequiredProject(p3, p1, accessiblePaths, forbiddenPaths, false); + env.addRequiredProject(p3, p2, accessiblePaths, forbiddenPaths, false); + + try { + fullBuild(); + + expectingOnlySpecificProblemsFor(p1,new Problem[]{ + new Problem("p1", "A cycle was detected in the build path of project: P1", p1, -1, -1, CategorizedProblem.CAT_BUILDPATH)//$NON-NLS-1$ //$NON-NLS-2$ + }); + expectingOnlySpecificProblemsFor(p2,new Problem[]{ + new Problem("p2", "A cycle was detected in the build path of project: P2", p2, -1, -1, CategorizedProblem.CAT_BUILDPATH)//$NON-NLS-1$ //$NON-NLS-2$ + }); + expectingOnlySpecificProblemsFor(p3,new Problem[]{ + new Problem("p3", "A cycle was detected in the build path of project: P3", p3, -1, -1, CategorizedProblem.CAT_BUILDPATH)//$NON-NLS-1$ //$NON-NLS-2$ + }); + + } finally { + JavaCore.setOptions(options); + } + } + /* * Full buid case */ #P org.eclipse.jdt.core.tests.model Index: src/org/eclipse/jdt/core/tests/dom/ASTConverterTestAST3_2.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterTestAST3_2.java,v retrieving revision 1.95.2.1 diff -u -r1.95.2.1 ASTConverterTestAST3_2.java --- src/org/eclipse/jdt/core/tests/dom/ASTConverterTestAST3_2.java 2 Jul 2006 10:06:41 -0000 1.95.2.1 +++ src/org/eclipse/jdt/core/tests/dom/ASTConverterTestAST3_2.java 22 Dec 2006 15:56:11 -0000 @@ -6080,8 +6080,9 @@ assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType()); CompilationUnit compilationUnit = (CompilationUnit) node; String expectedResult = + "The hierarchy of the type X is inconsistent\n" + "The type test0599.Zork2 cannot be resolved. It is indirectly referenced from required .class files"; - assertProblemsSize(compilationUnit, 1, expectedResult); + assertProblemsSize(compilationUnit, 2, expectedResult); compilationUnit.accept(new ASTVisitor() { public void endVisit(MethodDeclaration methodDeclaration) { Block body = methodDeclaration.getBody(); #P org.eclipse.jdt.core Index: compiler/org/eclipse/jdt/internal/compiler/ast/ArrayQualifiedTypeReference.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayQualifiedTypeReference.java,v retrieving revision 1.28 diff -u -r1.28 ArrayQualifiedTypeReference.java --- compiler/org/eclipse/jdt/internal/compiler/ast/ArrayQualifiedTypeReference.java 10 May 2006 18:03:43 -0000 1.28 +++ compiler/org/eclipse/jdt/internal/compiler/ast/ArrayQualifiedTypeReference.java 22 Dec 2006 15:56:13 -0000 @@ -54,12 +54,16 @@ if (this.dimensions > 255) { scope.problemReporter().tooManyDimensions(this); } + LookupEnvironment env = scope.environment(); try { + env.missingClassFileLocation = this; TypeBinding leafComponentType = super.getTypeBinding(scope); return this.resolvedType = scope.createArrayType(leafComponentType, dimensions); } catch (AbortCompilation e) { e.updateContext(this, scope.referenceCompilationUnit().compilationResult); throw e; + } finally { + env.missingClassFileLocation = null; } } Index: compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedTypeReference.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedTypeReference.java,v retrieving revision 1.35.4.1 diff -u -r1.35.4.1 QualifiedTypeReference.java --- compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedTypeReference.java 2 Jul 2006 10:11:31 -0000 1.35.4.1 +++ compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedTypeReference.java 22 Dec 2006 15:56:13 -0000 @@ -34,7 +34,9 @@ } protected TypeBinding findNextTypeBinding(int tokenIndex, Scope scope, PackageBinding packageBinding) { + LookupEnvironment env = scope.environment(); try { + env.missingClassFileLocation = this; if (this.resolvedType == null) { this.resolvedType = scope.getType(this.tokens[tokenIndex], packageBinding); } else { @@ -51,6 +53,8 @@ } catch (AbortCompilation e) { e.updateContext(this, scope.referenceCompilationUnit().compilationResult); throw e; + } finally { + env.missingClassFileLocation = null; } } Index: compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java,v retrieving revision 1.72 diff -u -r1.72 LookupEnvironment.java --- compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java 11 May 2006 10:14:34 -0000 1.72 +++ compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java 22 Dec 2006 15:56:13 -0000 @@ -64,6 +64,7 @@ private SimpleLookupTable uniqueParameterizedGenericMethodBindings; public CompilationUnitDeclaration unitBeingCompleted = null; // only set while completing units + public Object missingClassFileLocation = null; // only set when resolving certain references, to help locating problems private CompilationUnitDeclaration[] units = new CompilationUnitDeclaration[4]; private MethodVerifier verifier; @@ -173,6 +174,26 @@ return createBinaryTypeFrom(binaryType, computePackageFrom(compoundName), needFieldsAndMethods, accessRestriction); return null; // the type already exists & can be retrieved from the cache } +public BinaryTypeBinding cacheMissingBinaryType(char[][] compoundName, CompilationUnitDeclaration unit) { + // report the missing class file first + problemReporter.isClassPathCorrect( + compoundName, + unit == null ? this.unitBeingCompleted : unit, + this.missingClassFileLocation); + + PackageBinding packageBinding = computePackageFrom(compoundName); + // create a proxy for the missing BinaryType + MissingBinaryTypeBinding type = new MissingBinaryTypeBinding(packageBinding, compoundName, this); + if (type.id != TypeIds.T_JavaLangObject) { + // make Object be its superclass - it could in turn be missing as well + ReferenceBinding objectType = getType(TypeConstants.JAVA_LANG_OBJECT); + if (objectType == null) + objectType = cacheMissingBinaryType(TypeConstants.JAVA_LANG_OBJECT, unit); // create a proxy for the missing Object type + type.setMissingSuperclass(objectType); + } + packageBinding.addType(type); + return type; +} /* * 1. Connect the type hierarchy for the type bindings created for parsedUnits. * 2. Create the field bindings @@ -859,8 +880,10 @@ ReferenceBinding type = getType(compoundName); if (type != null) return type; - problemReporter.isClassPathCorrect(compoundName, scope == null ? null : scope.referenceCompilationUnit()); - return null; // will not get here since the above error aborts the compilation + // create a proxy for the missing BinaryType + return cacheMissingBinaryType( + compoundName, + scope == null ? this.unitBeingCompleted : scope.referenceCompilationUnit()); } /* Answer the top level package named name. * Ask the oracle for the package if its not in the cache. @@ -885,7 +908,7 @@ } /* Answer the type corresponding to the compoundName. * Ask the name environment for the type if its not in the cache. -* Answer null if the type cannot be found... likely a fatal error. +* Answer null if the type cannot be found. */ public ReferenceBinding getType(char[][] compoundName) { @@ -946,8 +969,6 @@ * unresolved type is returned which must be resolved before used. * * NOTE: Does NOT answer base types nor array types! -* -* NOTE: Aborts compilation if the class file cannot be found. */ ReferenceBinding getTypeFromCompoundName(char[][] compoundName, boolean isParameterized) { @@ -957,11 +978,11 @@ binding = new UnresolvedReferenceBinding(compoundName, packageBinding); packageBinding.addType(binding); } else if (binding == TheNotFoundType) { - problemReporter.isClassPathCorrect(compoundName, null); - return null; // will not get here since the above error aborts the compilation + // create a proxy for the missing BinaryType + binding = cacheMissingBinaryType(compoundName, this.unitBeingCompleted); } else if (!isParameterized) { // check raw type, only for resolved types - binding = (ReferenceBinding)convertUnresolvedBinaryToRawType(binding); + binding = (ReferenceBinding) convertUnresolvedBinaryToRawType(binding); } return binding; } @@ -970,8 +991,6 @@ * unresolved type is returned which must be resolved before used. * * NOTE: Does NOT answer base types nor array types! -* -* NOTE: Aborts compilation if the class file cannot be found. */ ReferenceBinding getTypeFromConstantPoolName(char[] signature, int start, int end, boolean isParameterized) { @@ -986,8 +1005,6 @@ * unresolved type is returned which must be resolved before used. * * NOTE: Does answer base types & array types. -* -* NOTE: Aborts compilation if the class file cannot be found. */ TypeBinding getTypeFromSignature(char[] signature, int start, int end, boolean isParameterized, TypeBinding enclosingType) { Index: compiler/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java,v retrieving revision 1.100.4.1 diff -u -r1.100.4.1 CompilationUnitScope.java --- compiler/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java 2 Jul 2006 10:11:49 -0000 1.100.4.1 +++ compiler/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java 22 Dec 2006 15:56:13 -0000 @@ -550,8 +550,11 @@ importBinding = ((PackageBinding) importBinding).getTypeOrPackage(JAVA_LANG[1]); // abort if java.lang cannot be found... - if (importBinding == null || !importBinding.isValidBinding()) - problemReporter().isClassPathCorrect(JAVA_LANG_OBJECT, referenceCompilationUnit()); + if (importBinding == null || !importBinding.isValidBinding()) { + // create a proxy for the missing BinaryType + BinaryTypeBinding missingObject = environment.cacheMissingBinaryType(JAVA_LANG_OBJECT, this.referenceContext); + importBinding = missingObject.fPackage; + } return environment.defaultImports = new ImportBinding[] {new ImportBinding(JAVA_LANG, true, importBinding, null)}; } Index: compiler/org/eclipse/jdt/internal/compiler/lookup/UnresolvedReferenceBinding.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/UnresolvedReferenceBinding.java,v retrieving revision 1.26 diff -u -r1.26 UnresolvedReferenceBinding.java --- compiler/org/eclipse/jdt/internal/compiler/lookup/UnresolvedReferenceBinding.java 10 May 2006 18:03:50 -0000 1.26 +++ compiler/org/eclipse/jdt/internal/compiler/lookup/UnresolvedReferenceBinding.java 22 Dec 2006 15:56:13 -0000 @@ -41,12 +41,11 @@ targetType = this.fPackage.getType0(this.compoundName[this.compoundName.length - 1]); if (targetType == this) targetType = environment.askForType(this.compoundName); - if (targetType != null && targetType != this) { // could not resolve any better, error was already reported against it - setResolvedType(targetType, environment); - } else { - environment.problemReporter.isClassPathCorrect(this.compoundName, null); - return null; // will not get here since the above error aborts the compilation + if (targetType == null || targetType == this) { // could not resolve any better, error was already reported against it + // create a proxy for the missing BinaryType + targetType = environment.cacheMissingBinaryType(this.compoundName, null); } + setResolvedType(targetType, environment); } if (convertGenericToRawType) { targetType = (ReferenceBinding) environment.convertUnresolvedBinaryToRawType(targetType); Index: compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java,v retrieving revision 1.279.2.4 diff -u -r1.279.2.4 Scope.java --- compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java 6 Sep 2006 18:11:37 -0000 1.279.2.4 +++ compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java 22 Dec 2006 15:56:13 -0000 @@ -1360,8 +1360,10 @@ * Limitations: cannot request FIELD independently of LOCAL, or vice versa */ public Binding getBinding(char[] name, int mask, InvocationSite invocationSite, boolean needResolve) { - + CompilationUnitScope unitScope = compilationUnitScope(); + LookupEnvironment env = unitScope.environment; try { + env.missingClassFileLocation = invocationSite; Binding binding = null; FieldBinding problemField = null; if ((mask & Binding.VARIABLE) != 0) { @@ -1504,7 +1506,6 @@ if (compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5) { // at this point the scope is a compilation unit scope & need to check for imported static fields - CompilationUnitScope unitScope = (CompilationUnitScope) scope; ImportBinding[] imports = unitScope.imports; if (imports != null) { // check single static imports @@ -1569,8 +1570,8 @@ return binding; // answer the problem type binding if we are only looking for a type } else if ((mask & Binding.PACKAGE) != 0) { - compilationUnitScope().recordSimpleReference(name); - if ((binding = environment().getTopLevelPackage(name)) != null) + unitScope.recordSimpleReference(name); + if ((binding = env.getTopLevelPackage(name)) != null) return binding; } if (problemField != null) return problemField; @@ -1580,12 +1581,16 @@ } catch (AbortCompilation e) { e.updateContext(invocationSite, referenceCompilationUnit().compilationResult); throw e; + } finally { + env.missingClassFileLocation = null; } } public MethodBinding getConstructor(ReferenceBinding receiverType, TypeBinding[] argumentTypes, InvocationSite invocationSite) { + CompilationUnitScope unitScope = compilationUnitScope(); + LookupEnvironment env = unitScope.environment; try { - CompilationUnitScope unitScope = compilationUnitScope(); + env.missingClassFileLocation = invocationSite; unitScope.recordTypeReference(receiverType); unitScope.recordTypeReferences(argumentTypes); MethodBinding methodBinding = receiverType.getExactConstructor(argumentTypes); @@ -1640,6 +1645,8 @@ } catch (AbortCompilation e) { e.updateContext(invocationSite, referenceCompilationUnit().compilationResult); throw e; + } finally { + env.missingClassFileLocation = null; } } @@ -1684,7 +1691,9 @@ } public FieldBinding getField(TypeBinding receiverType, char[] fieldName, InvocationSite invocationSite) { + LookupEnvironment env = environment(); try { + env.missingClassFileLocation = invocationSite; FieldBinding field = findField(receiverType, fieldName, invocationSite, true /*resolve*/); if (field != null) return field; @@ -1695,6 +1704,8 @@ } catch (AbortCompilation e) { e.updateContext(invocationSite, referenceCompilationUnit().compilationResult); throw e; + } finally { + env.missingClassFileLocation = null; } } @@ -1970,15 +1981,18 @@ } public MethodBinding getMethod(TypeBinding receiverType, char[] selector, TypeBinding[] argumentTypes, InvocationSite invocationSite) { + CompilationUnitScope unitScope = compilationUnitScope(); + LookupEnvironment env = unitScope.environment; try { + env.missingClassFileLocation = invocationSite; switch (receiverType.kind()) { case Binding.BASE_TYPE : return new ProblemMethodBinding(selector, argumentTypes, ProblemReasons.NotFound); case Binding.ARRAY_TYPE : - compilationUnitScope().recordTypeReference(receiverType); + unitScope.recordTypeReference(receiverType); return findMethodForArray((ArrayBinding) receiverType, selector, argumentTypes, invocationSite); } - compilationUnitScope().recordTypeReference(receiverType); + unitScope.recordTypeReference(receiverType); ReferenceBinding currentType = (ReferenceBinding) receiverType; if (!currentType.canBeSeenBy(this)) @@ -2005,6 +2019,8 @@ } catch (AbortCompilation e) { e.updateContext(invocationSite, referenceCompilationUnit().compilationResult); throw e; + } finally { + env.missingClassFileLocation = null; } } Index: compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java,v retrieving revision 1.95.4.3 diff -u -r1.95.4.3 BinaryTypeBinding.java --- compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java 23 Nov 2006 18:10:27 -0000 1.95.4.3 +++ compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java 22 Dec 2006 15:56:13 -0000 @@ -30,21 +30,21 @@ null is NOT a valid value for a non-public field... it just means the field is not initialized. */ -public final class BinaryTypeBinding extends ReferenceBinding { +public class BinaryTypeBinding extends ReferenceBinding { // all of these fields are ONLY guaranteed to be initialized if accessed using their public accessor method - private ReferenceBinding superclass; - private ReferenceBinding enclosingType; - private ReferenceBinding[] superInterfaces; - private FieldBinding[] fields; - private MethodBinding[] methods; - private ReferenceBinding[] memberTypes; + protected ReferenceBinding superclass; + protected ReferenceBinding enclosingType; + protected ReferenceBinding[] superInterfaces; + protected FieldBinding[] fields; + protected MethodBinding[] methods; + protected ReferenceBinding[] memberTypes; protected TypeVariableBinding[] typeVariables; // For the link with the principle structure - private LookupEnvironment environment; + protected LookupEnvironment environment; - private SimpleLookupTable storedAnnotations = null; // keys are this ReferenceBinding & its fields and methods, value is an AnnotationHolder + protected SimpleLookupTable storedAnnotations = null; // keys are this ReferenceBinding & its fields and methods, value is an AnnotationHolder static Object convertMemberValue(Object binaryValue, LookupEnvironment env) { if (binaryValue == null) return null; @@ -144,7 +144,19 @@ return type; } +/** + * Default empty constructor for subclasses only. + */ +protected BinaryTypeBinding() { + // only for subclasses +} +/** + * Standard constructor for creating binary type bindings from binary models (classfiles) + * @param packageBinding + * @param binaryType + * @param environment + */ public BinaryTypeBinding(PackageBinding packageBinding, IBinaryType binaryType, LookupEnvironment environment) { this.compoundName = CharOperation.splitOn('/', binaryType.getName()); computeId(); @@ -927,6 +939,8 @@ // finish resolving the type this.superclass = resolveType(this.superclass, this.environment, true); + if (this.superclass.problemId() == ProblemReasons.NotFound) + this.tagBits |= TagBits.HierarchyHasProblems; // propagate type inconsistency return this.superclass; } // NOTE: superInterfaces of binary types are resolved when needed @@ -938,8 +952,11 @@ this.superInterfaces[i] = resolveUnresolvedType(this.superInterfaces[i], this.environment, true); this.tagBits &= ~TagBits.HasUnresolvedSuperinterfaces; - for (int i = this.superInterfaces.length; --i >= 0;) + for (int i = this.superInterfaces.length; --i >= 0;) { this.superInterfaces[i] = resolveType(this.superInterfaces[i], this.environment, true); + if (this.superInterfaces[i].problemId() == ProblemReasons.NotFound) + this.tagBits |= TagBits.HierarchyHasProblems; // propagate type inconsistency + } return this.superInterfaces; } public TypeVariableBinding[] typeVariables() { 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.137.2.4 diff -u -r1.137.2.4 ClassScope.java --- compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java 6 Oct 2006 09:17:11 -0000 1.137.2.4 +++ compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java 22 Dec 2006 15:56:13 -0000 @@ -955,11 +955,15 @@ problemReporter().hierarchyHasProblems(sourceType); } connectMemberTypes(); + LookupEnvironment env = environment(); try { + env.missingClassFileLocation = referenceContext; checkForInheritedMemberTypes(sourceType); } catch (AbortCompilation e) { e.updateContext(referenceContext, referenceCompilationUnit().compilationResult); throw e; + } finally { + env.missingClassFileLocation = null; } } @@ -1097,19 +1101,24 @@ } private ReferenceBinding findSupertype(TypeReference typeReference) { + CompilationUnitScope unitScope = compilationUnitScope(); + LookupEnvironment env = unitScope.environment; try { + env.missingClassFileLocation = typeReference; typeReference.aboutToResolve(this); // allows us to trap completion & selection nodes - compilationUnitScope().recordQualifiedReference(typeReference.getTypeName()); + unitScope.recordQualifiedReference(typeReference.getTypeName()); this.superTypeReference = typeReference; ReferenceBinding superType = (ReferenceBinding) typeReference.resolveSuperType(this); - this.superTypeReference = null; return superType; } catch (AbortCompilation e) { SourceTypeBinding sourceType = this.referenceContext.binding; if (sourceType.superInterfaces == null) sourceType.superInterfaces = Binding.NO_SUPERINTERFACES; // be more resilient for hierarchies (144976) e.updateContext(typeReference, referenceCompilationUnit().compilationResult); throw e; - } + } finally { + env.missingClassFileLocation = null; + this.superTypeReference = null; + } } /* Answer the problem reporter to use for raising new problems. Index: model/org/eclipse/jdt/internal/core/builder/BatchImageBuilder.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/BatchImageBuilder.java,v retrieving revision 1.62.4.1 diff -u -r1.62.4.1 BatchImageBuilder.java --- model/org/eclipse/jdt/internal/core/builder/BatchImageBuilder.java 2 Jul 2006 10:11:41 -0000 1.62.4.1 +++ model/org/eclipse/jdt/internal/core/builder/BatchImageBuilder.java 22 Dec 2006 15:56:14 -0000 @@ -79,48 +79,6 @@ this.secondaryTypes.add(classFile.fileName()); } -protected void addAllSourceFiles(final ArrayList sourceFiles) throws CoreException { - for (int i = 0, l = sourceLocations.length; i < l; i++) { - final ClasspathMultiDirectory sourceLocation = sourceLocations[i]; - final char[][] exclusionPatterns = sourceLocation.exclusionPatterns; - final char[][] inclusionPatterns = sourceLocation.inclusionPatterns; - final boolean isAlsoProject = sourceLocation.sourceFolder.equals(javaBuilder.currentProject); - final int segmentCount = sourceLocation.sourceFolder.getFullPath().segmentCount(); - final IContainer outputFolder = sourceLocation.binaryFolder; - final boolean isOutputFolder = sourceLocation.sourceFolder.equals(outputFolder); - sourceLocation.sourceFolder.accept( - new IResourceProxyVisitor() { - public boolean visit(IResourceProxy proxy) throws CoreException { - switch(proxy.getType()) { - case IResource.FILE : - if (org.eclipse.jdt.internal.core.util.Util.isJavaLikeFileName(proxy.getName())) { - IResource resource = proxy.requestResource(); - if (exclusionPatterns != null || inclusionPatterns != null) - if (Util.isExcluded(resource, inclusionPatterns, exclusionPatterns)) return false; - sourceFiles.add(new SourceFile((IFile) resource, sourceLocation)); - } - return false; - case IResource.FOLDER : - if (exclusionPatterns != null && inclusionPatterns == null) // must walk children if inclusionPatterns != null - if (Util.isExcluded(proxy.requestResource(), inclusionPatterns, exclusionPatterns)) return false; - IPath folderPath = null; - if (isAlsoProject) - if (isExcludedFromProject(folderPath = proxy.requestFullPath())) return false; - if (!isOutputFolder) { - if (folderPath == null) - folderPath = proxy.requestFullPath(); - createFolder(folderPath.removeFirstSegments(segmentCount), outputFolder); - } - } - return true; - } - }, - IResource.NONE - ); - notifier.checkCancel(); - } -} - protected void cleanOutputFolders(boolean copyBack) throws CoreException { boolean deleteAll = JavaCore.CLEAN.equals( javaBuilder.javaProject.getOption(JavaCore.CORE_JAVA_BUILD_CLEAN_OUTPUT_FOLDER, true)); Index: model/org/eclipse/jdt/internal/core/builder/JavaBuilder.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/JavaBuilder.java,v retrieving revision 1.122 diff -u -r1.122 JavaBuilder.java --- model/org/eclipse/jdt/internal/core/builder/JavaBuilder.java 6 Apr 2006 19:15:52 -0000 1.122 +++ model/org/eclipse/jdt/internal/core/builder/JavaBuilder.java 22 Dec 2006 15:56:14 -0000 @@ -209,14 +209,6 @@ marker.setAttribute(IMarker.MESSAGE, Messages.bind(Messages.build_inconsistentProject, e.getLocalizedMessage())); marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR); marker.setAttribute(IJavaModelMarker.CATEGORY_ID, CategorizedProblem.CAT_BUILDPATH); - } catch (MissingClassFileException e) { - // do not log this exception since its thrown to handle aborted compiles because of missing class files - if (DEBUG) - System.out.println(Messages.bind(Messages.build_incompleteClassPath, e.missingClassFile)); - IMarker marker = currentProject.createMarker(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER); - marker.setAttribute(IMarker.MESSAGE, Messages.bind(Messages.build_incompleteClassPath, e.missingClassFile)); - marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR); - marker.setAttribute(IJavaModelMarker.CATEGORY_ID, CategorizedProblem.CAT_BUILDPATH); } catch (MissingSourceFileException e) { // do not log this exception since its thrown to handle aborted compiles because of missing source files if (DEBUG) @@ -432,6 +424,14 @@ return result; } +boolean hasBuildpathErrors() throws CoreException { + IMarker[] markers = this.currentProject.findMarkers(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_ZERO); + for (int i = 0, l = markers.length; i < l; i++) + if (markers[i].getAttribute(IJavaModelMarker.CATEGORY_ID, -1) == CategorizedProblem.CAT_BUILDPATH) + return true; + return false; +} + private boolean hasClasspathChanged() { ClasspathMultiDirectory[] newSourceLocations = nameEnvironment.sourceLocations; ClasspathMultiDirectory[] oldSourceLocations = lastState.sourceLocations; Index: model/org/eclipse/jdt/internal/core/builder/AbstractImageBuilder.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/AbstractImageBuilder.java,v retrieving revision 1.96 diff -u -r1.96 AbstractImageBuilder.java --- model/org/eclipse/jdt/internal/core/builder/AbstractImageBuilder.java 25 Apr 2006 20:39:49 -0000 1.96 +++ model/org/eclipse/jdt/internal/core/builder/AbstractImageBuilder.java 22 Dec 2006 15:56:14 -0000 @@ -50,6 +50,7 @@ private boolean inCompiler; +protected boolean keepStoringProblemMarkers; protected SimpleSet filesWithAnnotations = null; public static int MAX_AT_ONCE = 2000; // best compromise between space used and speed @@ -84,6 +85,7 @@ this.nameEnvironment = javaBuilder.nameEnvironment; this.sourceLocations = this.nameEnvironment.sourceLocations; this.notifier = javaBuilder.notifier; + this.keepStoringProblemMarkers = true; // may get disabled when missing classfiles are encountered if (buildStarting) { this.newState = newState == null ? new State(javaBuilder) : newState; @@ -199,6 +201,48 @@ // noop } +protected void addAllSourceFiles(final ArrayList sourceFiles) throws CoreException { + for (int i = 0, l = sourceLocations.length; i < l; i++) { + final ClasspathMultiDirectory sourceLocation = sourceLocations[i]; + final char[][] exclusionPatterns = sourceLocation.exclusionPatterns; + final char[][] inclusionPatterns = sourceLocation.inclusionPatterns; + final boolean isAlsoProject = sourceLocation.sourceFolder.equals(javaBuilder.currentProject); + final int segmentCount = sourceLocation.sourceFolder.getFullPath().segmentCount(); + final IContainer outputFolder = sourceLocation.binaryFolder; + final boolean isOutputFolder = sourceLocation.sourceFolder.equals(outputFolder); + sourceLocation.sourceFolder.accept( + new IResourceProxyVisitor() { + public boolean visit(IResourceProxy proxy) throws CoreException { + switch(proxy.getType()) { + case IResource.FILE : + if (org.eclipse.jdt.internal.core.util.Util.isJavaLikeFileName(proxy.getName())) { + IResource resource = proxy.requestResource(); + if (exclusionPatterns != null || inclusionPatterns != null) + if (Util.isExcluded(resource, inclusionPatterns, exclusionPatterns)) return false; + sourceFiles.add(new SourceFile((IFile) resource, sourceLocation)); + } + return false; + case IResource.FOLDER : + if (exclusionPatterns != null && inclusionPatterns == null) // must walk children if inclusionPatterns != null + if (Util.isExcluded(proxy.requestResource(), inclusionPatterns, exclusionPatterns)) return false; + IPath folderPath = null; + if (isAlsoProject) + if (isExcludedFromProject(folderPath = proxy.requestFullPath())) return false; + if (!isOutputFolder) { + if (folderPath == null) + folderPath = proxy.requestFullPath(); + createFolder(folderPath.removeFirstSegments(segmentCount), outputFolder); + } + } + return true; + } + }, + IResource.NONE + ); + notifier.checkCancel(); + } +} + protected void cleanUp() { this.nameEnvironment.cleanup(); @@ -545,24 +589,40 @@ */ protected void storeProblemsFor(SourceFile sourceFile, CategorizedProblem[] problems) throws CoreException { if (sourceFile == null || problems == null || problems.length == 0) return; + // once a classpath error is found, ignore all other problems for this project so the user can see the main error + // but still try to compile as many source files as possible to help the case when the base libraries are in source + if (!this.keepStoringProblemMarkers) return; // only want the one error recorded on this source file - String missingClassFile = null; IResource resource = sourceFile.resource; HashSet managedMarkerTypes = JavaModelManager.getJavaModelManager().compilationParticipants.managedMarkerTypes(); for (int i = 0, l = problems.length; i < l; i++) { CategorizedProblem problem = problems[i]; int id = problem.getID(); + + // handle missing classfile situation if (id == IProblem.IsClassPathCorrect) { - JavaBuilder.removeProblemsAndTasksFor(javaBuilder.currentProject); // make this the only problem for this project - String[] args = problem.getArguments(); - missingClassFile = args[0]; + String missingClassfileName = problem.getArguments()[0]; + if (JavaBuilder.DEBUG) + System.out.println(Messages.bind(Messages.build_incompleteClassPath, missingClassfileName)); + boolean isInvalidClasspathError = JavaCore.ERROR.equals(javaBuilder.javaProject.getOption(JavaCore.CORE_INCOMPLETE_CLASSPATH, true)); + // insert extra classpath problem, and make it the only problem for this project (optional) + if (isInvalidClasspathError && JavaCore.ABORT.equals(javaBuilder.javaProject.getOption(JavaCore.CORE_JAVA_BUILD_INVALID_CLASSPATH, true))) { + JavaBuilder.removeProblemsAndTasksFor(javaBuilder.currentProject); // make this the only problem for this project + this.keepStoringProblemMarkers = false; + } + IMarker marker = this.javaBuilder.currentProject.createMarker(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER); + marker.setAttribute(IMarker.MESSAGE, Messages.bind(Messages.build_incompleteClassPath, missingClassfileName)); + marker.setAttribute(IMarker.SEVERITY, isInvalidClasspathError ? IMarker.SEVERITY_ERROR : IMarker.SEVERITY_WARNING); + marker.setAttribute(IJavaModelMarker.CATEGORY_ID, CategorizedProblem.CAT_BUILDPATH); + // even if we're not keeping more markers, still fall through rest of the problem reporting, so that offending + // IsClassPathCorrect problem gets recorded since it may help locate the offending reference } - + String markerType = problem.getMarkerType(); if (IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER.equals(markerType) - || managedMarkerTypes.contains(markerType)) { + || managedMarkerTypes.contains(markerType)) { IMarker marker = resource.createMarker(markerType); - + // standard attributes marker.setAttributes( JAVA_PROBLEM_MARKER_ATTRIBUTE_NAMES, @@ -574,7 +634,7 @@ new Integer(problem.getSourceEnd() + 1), // end new Integer(problem.getSourceLineNumber()), // line Util.getProblemArgumentsForMarker(problem.getArguments()), // arguments - new Integer(problem.getCategoryID()), // category ID + new Integer(problem.getCategoryID()) // category ID } ); // optional extra attributes @@ -583,9 +643,8 @@ if (extraLength > 0) { marker.setAttributes(extraAttributeNames, problem.getExtraMarkerAttributeValues()); } + if (!this.keepStoringProblemMarkers) return; // only want the one error recorded on this source file } - if (missingClassFile != null) - throw new MissingClassFileException(missingClassFile); } } Index: model/org/eclipse/jdt/internal/core/builder/IncrementalImageBuilder.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/IncrementalImageBuilder.java,v retrieving revision 1.88.4.1 diff -u -r1.88.4.1 IncrementalImageBuilder.java --- model/org/eclipse/jdt/internal/core/builder/IncrementalImageBuilder.java 2 Jul 2006 10:11:41 -0000 1.88.4.1 +++ model/org/eclipse/jdt/internal/core/builder/IncrementalImageBuilder.java 22 Dec 2006 15:56:14 -0000 @@ -13,7 +13,7 @@ import org.eclipse.core.resources.*; import org.eclipse.core.runtime.*; -import org.eclipse.jdt.core.JavaCore; +import org.eclipse.jdt.core.*; import org.eclipse.jdt.core.compiler.*; import org.eclipse.jdt.internal.compiler.*; import org.eclipse.jdt.internal.compiler.classfmt.*; @@ -77,28 +77,38 @@ try { resetCollections(); - notifier.subTask(Messages.build_analyzingDeltas); - IResourceDelta sourceDelta = (IResourceDelta) deltas.get(javaBuilder.currentProject); - if (sourceDelta != null) - if (!findSourceFiles(sourceDelta)) return false; - notifier.updateProgressDelta(0.10f); - - Object[] keyTable = deltas.keyTable; - Object[] valueTable = deltas.valueTable; - for (int i = 0, l = valueTable.length; i < l; i++) { - IResourceDelta delta = (IResourceDelta) valueTable[i]; - if (delta != null) { - IProject p = (IProject) keyTable[i]; - ClasspathLocation[] classFoldersAndJars = (ClasspathLocation[]) javaBuilder.binaryLocationsPerProject.get(p); - if (classFoldersAndJars != null) - if (!findAffectedSourceFiles(delta, classFoldersAndJars, p)) return false; + notifier.subTask(Messages.build_analyzingDeltas); + if (javaBuilder.hasBuildpathErrors()) { + // if a mssing class file was detected in the last build, a build state was saved since its no longer fatal + // but we need to rebuild every source file since problems were not recorded + // AND to avoid the infinite build scenario if this project is involved in a cycle, see bug 160550 + // we need to avoid unnecessary deltas caused by doing a full build in this case + javaBuilder.currentProject.deleteMarkers(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_ZERO); + addAllSourceFiles(sourceFiles); + notifier.updateProgressDelta(0.25f); + } else { + IResourceDelta sourceDelta = (IResourceDelta) deltas.get(javaBuilder.currentProject); + if (sourceDelta != null) + if (!findSourceFiles(sourceDelta)) return false; + notifier.updateProgressDelta(0.10f); + + Object[] keyTable = deltas.keyTable; + Object[] valueTable = deltas.valueTable; + for (int i = 0, l = valueTable.length; i < l; i++) { + IResourceDelta delta = (IResourceDelta) valueTable[i]; + if (delta != null) { + IProject p = (IProject) keyTable[i]; + ClasspathLocation[] classFoldersAndJars = (ClasspathLocation[]) javaBuilder.binaryLocationsPerProject.get(p); + if (classFoldersAndJars != null) + if (!findAffectedSourceFiles(delta, classFoldersAndJars, p)) return false; + } } - } - notifier.updateProgressDelta(0.10f); + notifier.updateProgressDelta(0.10f); - notifier.subTask(Messages.build_analyzingSources); - addAffectedSourceFiles(); - notifier.updateProgressDelta(0.05f); + notifier.subTask(Messages.build_analyzingSources); + addAffectedSourceFiles(); + notifier.updateProgressDelta(0.05f); + } this.compileLoop = 0; float increment = 0.40f; Index: model/org/eclipse/jdt/internal/core/builder/MissingClassFileException.java =================================================================== RCS file: model/org/eclipse/jdt/internal/core/builder/MissingClassFileException.java diff -N model/org/eclipse/jdt/internal/core/builder/MissingClassFileException.java --- model/org/eclipse/jdt/internal/core/builder/MissingClassFileException.java 10 May 2006 18:03:50 -0000 1.8 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,25 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2006 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 - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.jdt.internal.core.builder; - -/** - * Exception thrown when the build should be aborted because a referenced - * class file cannot be found. - */ -public class MissingClassFileException extends RuntimeException { - - protected String missingClassFile; - private static final long serialVersionUID = 3060418973806972616L; // backward compatible - -public MissingClassFileException(String missingClassFile) { - this.missingClassFile = missingClassFile; -} -} Index: compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java,v retrieving revision 1.311.4.4 diff -u -r1.311.4.4 ProblemReporter.java --- compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java 6 Oct 2006 09:17:11 -0000 1.311.4.4 +++ compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java 22 Dec 2006 15:56:14 -0000 @@ -3262,7 +3262,8 @@ if (isRecoveredName(ref.tokens)) return; if (type instanceof ReferenceBinding) { char[][] name = ((ReferenceBinding) type).compoundName; - end = (int) ref.sourcePositions[name.length - 1]; + if (name.length <= ref.sourcePositions.length) + end = (int) ref.sourcePositions[name.length - 1]; } } else if (location instanceof ImportReference) { ImportReference ref = (ImportReference) location; @@ -3387,16 +3388,27 @@ argument.type.sourceStart, argument.sourceEnd); } -public void isClassPathCorrect(char[][] wellKnownTypeName, CompilationUnitDeclaration compUnitDecl) { +public void isClassPathCorrect(char[][] wellKnownTypeName, CompilationUnitDeclaration compUnitDecl, Object location) { this.referenceContext = compUnitDecl; String[] arguments = new String[] {CharOperation.toString(wellKnownTypeName)}; + int start = 0, end = 0; + if (location != null) { + if (location instanceof InvocationSite) { + InvocationSite site = (InvocationSite) location; + start = site.sourceStart(); + end = site.sourceEnd(); + } else if (location instanceof ASTNode) { + ASTNode node = (ASTNode) location; + start = node.sourceStart(); + end = node.sourceEnd(); + } + } this.handle( IProblem.IsClassPathCorrect, arguments, arguments, - ProblemSeverities.AbortCompilation | ProblemSeverities.Error | ProblemSeverities.Fatal, - 0, - 0); + start, + end); } private boolean isIdentifier(int token) { return token == TerminalTokens.TokenNameIdentifier; Index: compiler/org/eclipse/jdt/internal/compiler/Compiler.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/Compiler.java,v retrieving revision 1.78.4.1 diff -u -r1.78.4.1 Compiler.java --- compiler/org/eclipse/jdt/internal/compiler/Compiler.java 20 Oct 2006 14:11:49 -0000 1.78.4.1 +++ compiler/org/eclipse/jdt/internal/compiler/Compiler.java 22 Dec 2006 15:56:13 -0000 @@ -580,6 +580,7 @@ * Process a compilation unit already parsed and build. */ public void process(CompilationUnitDeclaration unit, int i) { + this.lookupEnvironment.unitBeingCompleted = unit; this.parser.getMethodBodies(unit); @@ -606,6 +607,8 @@ // refresh the total number of units known at this stage unit.compilationResult.totalUnitsKnown = totalUnits; + + this.lookupEnvironment.unitBeingCompleted = null; } public void reset() { lookupEnvironment.reset(); Index: model/org/eclipse/jdt/internal/core/hierarchy/HierarchyResolver.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/HierarchyResolver.java,v retrieving revision 1.66.4.1 diff -u -r1.66.4.1 HierarchyResolver.java --- model/org/eclipse/jdt/internal/core/hierarchy/HierarchyResolver.java 2 Jul 2006 10:11:54 -0000 1.66.4.1 +++ model/org/eclipse/jdt/internal/core/hierarchy/HierarchyResolver.java 22 Dec 2006 15:56:14 -0000 @@ -155,33 +155,39 @@ */ private IType findSuperClass(IGenericType type, ReferenceBinding typeBinding) { ReferenceBinding superBinding = typeBinding.superclass(); - + if (superBinding != null) { superBinding = (ReferenceBinding) superBinding.erasure(); - if (superBinding.id == TypeIds.T_JavaLangObject && typeBinding.isHierarchyInconsistent()) { - char[] superclassName; - char separator; - if (type instanceof IBinaryType) { - superclassName = ((IBinaryType)type).getSuperclassName(); - separator = '/'; - } else if (type instanceof ISourceType) { - superclassName = ((ISourceType)type).getSuperclassName(); - separator = '.'; - } else if (type instanceof HierarchyType) { - superclassName = ((HierarchyType)type).superclassName; - separator = '.'; - } else { + if (typeBinding.isHierarchyInconsistent()) { + if (superBinding.problemId() == ProblemReasons.NotFound) { + this.hasMissingSuperClass = true; + this.builder.hierarchy.missingTypes.add(new String(superBinding.sourceName)); // note: this could be Map$Entry return null; - } - - if (superclassName != null) { // check whether subclass of Object due to broken hierarchy (as opposed to explicitly extending it) - int lastSeparator = CharOperation.lastIndexOf(separator, superclassName); - char[] simpleName = lastSeparator == -1 ? superclassName : CharOperation.subarray(superclassName, lastSeparator+1, superclassName.length); - if (!CharOperation.equals(simpleName, TypeConstants.OBJECT)) { - this.hasMissingSuperClass = true; - this.builder.hierarchy.missingTypes.add(new String(simpleName)); + } else if ((superBinding.id == TypeIds.T_JavaLangObject)) { + char[] superclassName; + char separator; + if (type instanceof IBinaryType) { + superclassName = ((IBinaryType)type).getSuperclassName(); + separator = '/'; + } else if (type instanceof ISourceType) { + superclassName = ((ISourceType)type).getSuperclassName(); + separator = '.'; + } else if (type instanceof HierarchyType) { + superclassName = ((HierarchyType)type).superclassName; + separator = '.'; + } else { return null; } + + if (superclassName != null) { // check whether subclass of Object due to broken hierarchy (as opposed to explicitly extending it) + int lastSeparator = CharOperation.lastIndexOf(separator, superclassName); + char[] simpleName = lastSeparator == -1 ? superclassName : CharOperation.subarray(superclassName, lastSeparator+1, superclassName.length); + if (!CharOperation.equals(simpleName, TypeConstants.OBJECT)) { + this.hasMissingSuperClass = true; + this.builder.hierarchy.missingTypes.add(new String(simpleName)); + return null; + } + } } } for (int t = this.typeIndex; t >= 0; t--) { Index: compiler/org/eclipse/jdt/internal/compiler/lookup/MissingBinaryTypeBinding.java =================================================================== RCS file: compiler/org/eclipse/jdt/internal/compiler/lookup/MissingBinaryTypeBinding.java diff -N compiler/org/eclipse/jdt/internal/compiler/lookup/MissingBinaryTypeBinding.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ compiler/org/eclipse/jdt/internal/compiler/lookup/MissingBinaryTypeBinding.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 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 + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.internal.compiler.lookup; + +import org.eclipse.jdt.core.compiler.CharOperation; +import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration; +import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; + +public class MissingBinaryTypeBinding extends BinaryTypeBinding { + +/** + * Special constructor for constructing proxies of missing binary types (114349) + * @param packageBinding + * @param compoundName + * @param environment + */ +public MissingBinaryTypeBinding(PackageBinding packageBinding, char[][] compoundName, LookupEnvironment environment) { + this.compoundName = compoundName; + computeId(); + this.tagBits |= TagBits.IsBinaryBinding | TagBits.HierarchyHasProblems; + this.environment = environment; + this.fPackage = packageBinding; + this.fileName = CharOperation.concatWith(compoundName, '/'); + this.sourceName = compoundName[compoundName.length - 1]; // [java][util][Map$Entry] + this.modifiers = ClassFileConstants.AccPublic; + this.superclass = null; // will be fixed up using #setMissingSuperclass(...) + this.superInterfaces = Binding.NO_SUPERINTERFACES; + this.typeVariables = Binding.NO_TYPE_VARIABLES; + this.memberTypes = Binding.NO_MEMBER_TYPES; + this.fields = Binding.NO_FIELDS; + this.methods = Binding.NO_METHODS; +} + +/** + * Missing binary type will answer false to #isValidBinding() + * @see org.eclipse.jdt.internal.compiler.lookup.Binding#problemId() + */ +public int problemId() { + return ProblemReasons.NotFound; +} + +/** + * Only used to fixup the superclass hierarchy of proxy binary types + * @param missingSuperclass + * @see LookupEnvironment#cacheMissingBinaryType(char[][], CompilationUnitDeclaration) + */ +void setMissingSuperclass(ReferenceBinding missingSuperclass) { + this.superclass = missingSuperclass; +} +}