### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.core.tests.builder 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.43 diff -u -r1.43 MultiProjectTests.java --- src/org/eclipse/jdt/core/tests/builder/MultiProjectTests.java 5 Oct 2006 11:42:05 -0000 1.43 +++ src/org/eclipse/jdt/core/tests/builder/MultiProjectTests.java 10 Nov 2006 13:00:13 -0000 @@ -783,7 +783,7 @@ // 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 { +public void testCycle6() throws JavaModelException { Hashtable options = JavaCore.getOptions(); Hashtable newOptions = JavaCore.getOptions(); newOptions.put(JavaCore.CORE_CIRCULAR_CLASSPATH, JavaCore.WARNING); #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.103 diff -u -r1.103 ASTConverterTestAST3_2.java --- src/org/eclipse/jdt/core/tests/dom/ASTConverterTestAST3_2.java 9 Nov 2006 22:07:11 -0000 1.103 +++ src/org/eclipse/jdt/core/tests/dom/ASTConverterTestAST3_2.java 10 Nov 2006 13:00:16 -0000 @@ -6081,6 +6081,7 @@ 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); compilationUnit.accept(new ASTVisitor() { #P org.eclipse.jdt.core 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.99 diff -u -r1.99 BinaryTypeBinding.java --- compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java 6 Sep 2006 18:14:13 -0000 1.99 +++ compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java 10 Nov 2006 13:00:18 -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; @@ -133,6 +133,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(); @@ -252,7 +265,7 @@ if (superclassName != null) { // attempt to find the superclass if it exists in the cache (otherwise - resolve it when requested) this.superclass = environment.getTypeFromConstantPoolName(superclassName, 0, -1, false); - this.tagBits |= TagBits.HasUnresolvedSuperclass; + this.tagBits |= TagBits.HasUnresolvedSuperclass; } this.superInterfaces = Binding.NO_SUPERINTERFACES; @@ -264,7 +277,7 @@ for (int i = 0; i < size; i++) // attempt to find each superinterface if it exists in the cache (otherwise - resolve it when requested) this.superInterfaces[i] = environment.getTypeFromConstantPoolName(interfaceNames[i], 0, -1, false); - this.tagBits |= TagBits.HasUnresolvedSuperinterfaces; + this.tagBits |= TagBits.HasUnresolvedSuperinterfaces; } } } else { @@ -281,7 +294,7 @@ // attempt to find the superclass if it exists in the cache (otherwise - resolve it when requested) this.superclass = (ReferenceBinding) environment.getTypeFromTypeSignature(wrapper, Binding.NO_TYPE_VARIABLES, this); - this.tagBits |= TagBits.HasUnresolvedSuperclass; + this.tagBits |= TagBits.HasUnresolvedSuperclass; this.superInterfaces = Binding.NO_SUPERINTERFACES; if (!wrapper.atEnd()) { @@ -292,7 +305,7 @@ } while (!wrapper.atEnd()); this.superInterfaces = new ReferenceBinding[types.size()]; types.toArray(this.superInterfaces); - this.tagBits |= TagBits.HasUnresolvedSuperinterfaces; + this.tagBits |= TagBits.HasUnresolvedSuperinterfaces; } } @@ -893,8 +906,8 @@ } return this.storedAnnotations; } + /* Answer the receiver's superclass... null if the receiver is Object or an interface. -* * NOTE: superclass of a binary type is resolved when needed */ public ReferenceBinding superclass() { @@ -902,17 +915,24 @@ return this.superclass; // finish resolving the type - this.superclass = resolveType(this.superclass, this.environment, true); + ReferenceBinding superType = resolveType(this.superclass, this.environment, true); this.tagBits &= ~TagBits.HasUnresolvedSuperclass; - return this.superclass; + if (superType.problemId() == ProblemReasons.NotFound) { + this.tagBits |= TagBits.HierarchyHasProblems; // propagate type inconsistency + } + return this.superclass = superType; } // NOTE: superInterfaces of binary types are resolved when needed public ReferenceBinding[] superInterfaces() { if ((this.tagBits & TagBits.HasUnresolvedSuperinterfaces) == 0) return this.superInterfaces; - - for (int i = this.superInterfaces.length; --i >= 0;) - this.superInterfaces[i] = resolveType(this.superInterfaces[i], this.environment, true); + for (int i = this.superInterfaces.length; --i >= 0;) { + ReferenceBinding superType = resolveType(this.superInterfaces[i], this.environment, true); + if (superType.problemId() == ProblemReasons.NotFound) { + this.tagBits |= TagBits.HierarchyHasProblems; // propagate type inconsistency + } + this.superInterfaces[i] = superType; + } this.tagBits &= ~TagBits.HasUnresolvedSuperinterfaces; return this.superInterfaces; } 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.73 diff -u -r1.73 LookupEnvironment.java --- compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java 20 Oct 2006 11:02:03 -0000 1.73 +++ compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java 10 Nov 2006 13:00:19 -0000 @@ -16,6 +16,7 @@ import org.eclipse.jdt.core.compiler.CharOperation; import org.eclipse.jdt.internal.compiler.ClassFilePool; import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration; +import org.eclipse.jdt.internal.compiler.ast.TypeReference; import org.eclipse.jdt.internal.compiler.ast.Wildcard; import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; import org.eclipse.jdt.internal.compiler.env.*; @@ -64,7 +65,8 @@ private SimpleLookupTable uniqueParameterizedGenericMethodBindings; public CompilationUnitDeclaration unitBeingCompleted = null; // only set while completing units - + public TypeReference typeReferenceBeingResolved = null; // only set when resolving certain type references, to help locating problems + private CompilationUnitDeclaration[] units = new CompilationUnitDeclaration[4]; private MethodVerifier verifier; @@ -172,6 +174,35 @@ return createBinaryTypeFrom(binaryType, computePackageFrom(compoundName), needFieldsAndMethods, accessRestriction); return null; // the type already exists & can be retrieved from the cache } + +public BinaryTypeBinding cacheMissingBinaryType(char[][] compoundName) { + PackageBinding packageBinding = getPackage0(compoundName[0]); + if (packageBinding == null || packageBinding == TheNotFoundPackage) { + packageBinding = new PackageBinding(compoundName[0], this); + knownPackages.put(compoundName[0], packageBinding); + } + for (int i = 1, packageLength = compoundName.length - 1; i < packageLength; i++) { + PackageBinding subPackageBinding = packageBinding.getPackage0(compoundName[i]); + if (subPackageBinding == null || subPackageBinding == TheNotFoundPackage) { + char[][] subName = CharOperation.subarray(compoundName, 0, i + 1); + subPackageBinding = new PackageBinding(subName, packageBinding, this); + packageBinding.addPackage(subPackageBinding); + packageBinding = subPackageBinding; + } + } + // 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); // 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 @@ -858,8 +889,12 @@ 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 + ClassScope classScope = scope == null ? null : scope.enclosingClassScope(); + problemReporter.isClassPathCorrect( + compoundName, + scope == null ? this.unitBeingCompleted : scope.referenceCompilationUnit(), + classScope == null ? this.typeReferenceBeingResolved : classScope.superTypeReference); + return cacheMissingBinaryType(compoundName); // create a proxy for the missing BinaryType } /* Answer the top level package named name. * Ask the oracle for the package if its not in the cache. @@ -956,14 +991,15 @@ 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 + problemReporter.isClassPathCorrect(compoundName, this.unitBeingCompleted, this.typeReferenceBeingResolved); + return cacheMissingBinaryType(compoundName); // create a proxy for the missing BinaryType } else if (!isParameterized) { // check raw type, only for resolved types binding = (ReferenceBinding)convertUnresolvedBinaryToRawType(binding); } return binding; } + /* Answer the type corresponding to the name from the binary file. * Does not ask the oracle for the type if its not found in the cache... instead an * unresolved type is returned which must be resolved before used. 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.102 diff -u -r1.102 CompilationUnitScope.java --- compiler/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java 6 Jul 2006 11:20:36 -0000 1.102 +++ compiler/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java 10 Nov 2006 13:00:18 -0000 @@ -551,9 +551,12 @@ 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()) { + problemReporter().isClassPathCorrect(JAVA_LANG_OBJECT, referenceCompilationUnit(), null); + BinaryTypeBinding missingObject = environment.cacheMissingBinaryType(JAVA_LANG_OBJECT); // create a proxy for the missing BinaryType + importBinding = missingObject.fPackage; + } return environment.defaultImports = new ImportBinding[] {new ImportBinding(JAVA_LANG, true, importBinding, null)}; } // NOT Public API 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 10 Nov 2006 13:00:19 -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 + environment.problemReporter.isClassPathCorrect(this.compoundName, environment.unitBeingCompleted, environment.typeReferenceBeingResolved); + targetType = environment.cacheMissingBinaryType(this.compoundName); // create a proxy for the missing BinaryType } + setResolvedType(targetType, environment); } if (convertGenericToRawType) { targetType = (ReferenceBinding) environment.convertUnresolvedBinaryToRawType(targetType); 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.141 diff -u -r1.141 ClassScope.java --- compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java 23 Oct 2006 08:01:16 -0000 1.141 +++ compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java 10 Nov 2006 13:00:18 -0000 @@ -1099,19 +1099,23 @@ } private ReferenceBinding findSupertype(TypeReference typeReference) { + LookupEnvironment environment = environment(); try { typeReference.aboutToResolve(this); // allows us to trap completion & selection nodes compilationUnitScope().recordQualifiedReference(typeReference.getTypeName()); this.superTypeReference = typeReference; + environment.typeReferenceBeingResolved = 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 { + environment.typeReferenceBeingResolved = null; + this.superTypeReference = null; + } } /* Answer the problem reporter to use for raising new problems. 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.326 diff -u -r1.326 ProblemReporter.java --- compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java 9 Nov 2006 21:15:04 -0000 1.326 +++ compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java 10 Nov 2006 13:00:21 -0000 @@ -3405,16 +3405,15 @@ argument.type.sourceStart, argument.sourceEnd); } -public void isClassPathCorrect(char[][] wellKnownTypeName, CompilationUnitDeclaration compUnitDecl) { +public void isClassPathCorrect(char[][] wellKnownTypeName, CompilationUnitDeclaration compUnitDecl, ASTNode location) { this.referenceContext = compUnitDecl; String[] arguments = new String[] {CharOperation.toString(wellKnownTypeName)}; this.handle( IProblem.IsClassPathCorrect, arguments, arguments, - ProblemSeverities.AbortCompilation | ProblemSeverities.Error | ProblemSeverities.Fatal, - 0, - 0); + location == null ? 0 : location.sourceStart, + location == null ? 0 : location.sourceEnd); } private boolean isIdentifier(int token) { return token == TerminalTokens.TokenNameIdentifier; 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.71 diff -u -r1.71 HierarchyResolver.java --- model/org/eclipse/jdt/internal/core/hierarchy/HierarchyResolver.java 20 Oct 2006 11:02:03 -0000 1.71 +++ model/org/eclipse/jdt/internal/core/hierarchy/HierarchyResolver.java 10 Nov 2006 13:00:22 -0000 @@ -166,30 +166,36 @@ 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: 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: 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.99 diff -u -r1.99 AbstractImageBuilder.java --- model/org/eclipse/jdt/internal/core/builder/AbstractImageBuilder.java 13 Sep 2006 18:41:05 -0000 1.99 +++ model/org/eclipse/jdt/internal/core/builder/AbstractImageBuilder.java 10 Nov 2006 13:00:21 -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; @@ -546,24 +548,39 @@ */ 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); + // if not keeping more markers, still fall through rest of the problem reporting, so that offending IsClassPathCorrect + // problem gets recorded since it may help locating the offending reference } - + String markerType = problem.getMarkerType(); - if (IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER.equals(markerType) - || managedMarkerTypes.contains(markerType)) { + if (IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER.equals(markerType) || managedMarkerTypes.contains(markerType)) { IMarker marker = resource.createMarker(markerType); - + // standard attributes marker.setAttributes( JAVA_PROBLEM_MARKER_ATTRIBUTE_NAMES, @@ -584,9 +601,9 @@ 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/JavaBuilder.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/JavaBuilder.java,v retrieving revision 1.123 diff -u -r1.123 JavaBuilder.java --- model/org/eclipse/jdt/internal/core/builder/JavaBuilder.java 13 Jun 2006 13:00:44 -0000 1.123 +++ model/org/eclipse/jdt/internal/core/builder/JavaBuilder.java 10 Nov 2006 13:00:21 -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) 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,57 @@ +/******************************************************************************* + * 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.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[][]) + */ +void setMissingSuperclass(ReferenceBinding missingSuperclass) { + this.superclass = missingSuperclass; +} +}