diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java index b8fec17..dc197f4 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java @@ -1530,7 +1530,7 @@ public void test_illegal_annotation_002() { }, customOptions, "----------\n" + - "1. ERROR in X.java (at line 0)\n" + + "1. ERROR in X.java (at line 1)\n" + " public class X {\n" + " ^\n" + "Cannot use the unqualified name \'NichtNull\' as an annotation name for null specification\n" + diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AllJavaModelTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AllJavaModelTests.java index d3e6b2b..537f730 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AllJavaModelTests.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AllJavaModelTests.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2010 IBM Corporation and others. + * Copyright (c) 2000, 2011 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 @@ -185,6 +185,9 @@ private static Class[] getAllTestClasses() { UtilTests.class, JavaCoreOptionsTests.class, + + // Tests regarding null-annotations: + NullAnnotationModelTests.class, }; Class[] deprecatedClasses = getDeprecatedJDOMTestClasses(); diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/NullAnnotationModelTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/NullAnnotationModelTests.java new file mode 100644 index 0000000..da0622a --- /dev/null +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/NullAnnotationModelTests.java @@ -0,0 +1,410 @@ +/******************************************************************************* + * Copyright (c) 2011 GK Software AG 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: + * Stephan Herrmann - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.core.tests.model; + +import java.io.File; +import java.io.IOException; +import java.io.StringBufferInputStream; +import java.net.URL; +import java.util.Hashtable; + +import junit.framework.Test; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IncrementalProjectBuilder; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.core.runtime.Platform; +import org.eclipse.jdt.core.ICompilationUnit; +import org.eclipse.jdt.core.IJavaModelMarker; +import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.jdt.core.JavaCore; +import org.eclipse.jdt.core.compiler.IProblem; +import org.eclipse.jdt.core.dom.AST; +import org.eclipse.jdt.core.dom.ASTParser; +import org.eclipse.jdt.core.dom.CompilationUnit; + +public class NullAnnotationModelTests extends ReconcilerTests { + + String ANNOTATION_LIB; + + public static Test suite() { + return buildModelTestSuite(NullAnnotationModelTests.class); + } + + public NullAnnotationModelTests(String name) { + super(name); + } + + static { +// TESTS_NAMES = new String[] { "testMissingAnnotation5" }; + } + + public void setUp() throws Exception { + super.setUp(); + File bundleFile = FileLocator.getBundleFile(Platform.getBundle("org.eclipse.jdt.annotation.null")); + this.ANNOTATION_LIB = bundleFile.isDirectory() ? bundleFile.getPath()+"/bin" : bundleFile.getPath(); + } + + protected String testJarPath(String jarName) throws IOException { + URL libEntry = Platform.getBundle("org.eclipse.jdt.core.tests.model").getEntry("/workspace/NullAnnotations/lib/"+jarName); + return FileLocator.toFileURL(libEntry).getPath(); + } + + + public void testConvertedSourceType1() throws CoreException, InterruptedException { + try { + // Resources creation + IJavaProject p = createJavaProject("P", new String[] {""}, new String[] {"JCL15_LIB", this.ANNOTATION_LIB}, "bin", "1.5"); + p.setOption(JavaCore.COMPILER_ANNOTATION_NULL_ANALYSIS, JavaCore.ENABLED); + p.setOption(JavaCore.COMPILER_NONNULL_IS_DEFAULT, JavaCore.ENABLED); + + this.createFolder("/P/p1"); + String c1SourceString = + "package p1;\n" + + "import org.eclipse.jdt.annotation.*;\n" + + "public class C1 {\n" + + " public String foo(@Nullable Object arg) {\n" + // this is consumed via SourceTypeConverter + " return arg == null ? \"\" : arg.toString();\n" + + " }\n" + + "}\n"; + this.createFile( + "/P/p1/C1.java", + c1SourceString); + + this.createFolder("/P/p2"); + String c2SourceString = + "package p2;\n" + + "public class C2 {\n" + + " String bar(p1.C1 c, C2 c2) {;\n" + + " return c.foo(null);\n" + // don't complain despite default nonnull, foo has explicit @Nullable + " }\n" + + " String foo(Object arg) {\n" + + " return arg == null ? null : arg.toString();\n" + + " }\n" + + "}\n"; + this.createFile( + "/P/p2/C2.java", + c2SourceString); + + char[] c2SourceChars = c2SourceString.toCharArray(); + this.problemRequestor.initialize(c2SourceChars); + + getCompilationUnit("/P/p2/C2.java").getWorkingCopy(this.wcOwner, null); + + assertProblems("Unexpected problems", "----------\n" + + "1. WARNING in /P/p2/C2.java (at line 7)\n" + + " return arg == null ? null : arg.toString();\n" + + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + + "Potential type mismatch: required \'@NonNull String\' but nullness of the provided value is unknown\n" + + "----------\n"); + } finally { + deleteProject("P"); + } + } + + public void testBinaryType1() throws CoreException, InterruptedException, IOException { + try { + // Resources creation + IJavaProject p = createJavaProject("P", new String[] {""}, + new String[] {"JCL15_LIB", this.ANNOTATION_LIB, testJarPath("example.jar")}, + "bin", "1.5"); + p.setOption(JavaCore.COMPILER_ANNOTATION_NULL_ANALYSIS, JavaCore.ENABLED); + p.setOption(JavaCore.COMPILER_NONNULL_IS_DEFAULT, JavaCore.ENABLED); + + // example.jar contains p1/C1.java just like testConvertedSourceType1() + + this.createFolder("/P/p2"); + String c2SourceString = + "package p2;\n" + + "public class C2 {\n" + + " String bar(p1.C1 c) {;\n" + + " return c.foo(null);\n" + // don't complain despite default nonnull, foo has explicit @Nullable + " }\n" + + " String foo(Object arg) {\n" + + " return arg == null ? null : arg.toString();\n" + + " }\n" + + "}\n"; + this.createFile( + "/P/p2/C2.java", + c2SourceString); + + char[] c2SourceChars = c2SourceString.toCharArray(); + this.problemRequestor.initialize(c2SourceChars); + + getCompilationUnit("/P/p2/C2.java").getWorkingCopy(this.wcOwner, null); + + assertProblems("Unexpected problems", "----------\n" + + "1. WARNING in /P/p2/C2.java (at line 7)\n" + + " return arg == null ? null : arg.toString();\n" + + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + + "Potential type mismatch: required \'@NonNull String\' but nullness of the provided value is unknown\n" + + "----------\n"); + } finally { + deleteProject("P"); + } + } + + public void testMissingAnnotation1() throws CoreException { + try { + // Resources creation + IJavaProject p = createJavaProject("P", new String[] {""}, new String[] {"JCL15_LIB", this.ANNOTATION_LIB}, "bin", "1.5"); + p.setOption(JavaCore.COMPILER_ANNOTATION_NULL_ANALYSIS, JavaCore.ENABLED); + p.setOption(JavaCore.COMPILER_NONNULL_ANNOTATION_NAME, "in.valid"); + + this.createFolder("/P/p1"); + String c1SourceString = + "package p1;\n" + + "@org.eclipse.jdt.annotation.NonNullByDefault\n" + + "public class C1 {\n" + + " public String foo(Object arg) {\n" + + " return arg == null ? \"\" : arg.toString();\n" + + " }\n" + + "}\n"; + this.createFile( + "/P/p1/C1.java", + c1SourceString); + + this.problemRequestor.initialize(c1SourceString.toCharArray()); + + getCompilationUnit("/P/p1/C1.java").getWorkingCopy(this.wcOwner, null); + + assertProblems("Unexpected problems", + "----------\n" + + "1. ERROR in /P/p1/C1.java (at line 1)\n" + + " package p1;\n" + + " ^\n" + + "Buildpath problem: the type in.valid, which is configured as a null annotation type, cannot be resolved\n" + + "----------\n"); + } finally { + deleteProject("P"); + } + } + + public void testMissingAnnotation2() throws CoreException { + Hashtable javaOptions = JavaCore.getOptions(); + try { + // Resources creation + IJavaProject p = createJavaProject("P", new String[] {""}, new String[] {"JCL15_LIB", this.ANNOTATION_LIB}, "bin", "1.5"); + IFile settings = (IFile) p.getProject().findMember(".settings/org.eclipse.jdt.core.prefs"); + settings.appendContents(new StringBufferInputStream("\norg.eclipse.jdt.core.compiler.annotation.nonnull=not.valid\n"), 0, null); + p.setOption(JavaCore.COMPILER_ANNOTATION_NULL_ANALYSIS, JavaCore.ENABLED); + + this.createFolder("/P/p1"); + String c1SourceString = + "package p1;\n" + + "@org.eclipse.jdt.annotation.NonNullByDefault\n" + + "public class C1 {\n" + + " public String foo(Object arg) {\n" + + " return arg == null ? \"\" : arg.toString();\n" + + " }\n" + + "}\n"; + this.createFile( + "/P/p1/C1.java", + c1SourceString); + + this.problemRequestor.initialize(c1SourceString.toCharArray()); + + getCompilationUnit("/P/p1/C1.java").getWorkingCopy(this.wcOwner, null); + + assertProblems("Unexpected problems", + "----------\n" + + "1. ERROR in /P/p1/C1.java (at line 1)\n" + + " package p1;\n" + + " ^\n" + + "Buildpath problem: the type not.valid, which is configured as a null annotation type, cannot be resolved\n" + + "----------\n"); + } finally { + deleteProject("P"); + JavaCore.setOptions(javaOptions); + // work against side-effect of JavaRuntime listening to change of prefs-file. + // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=302850#c25 + } + } + + // Bug 363858 - [dom] early throwing of AbortCompilation causes NPE in CompilationUnitResolver + public void testMissingAnnotation3() throws CoreException { + try { + // Resources creation + IJavaProject p = createJavaProject("P", new String[] {""}, new String[] {"JCL15_LIB", this.ANNOTATION_LIB}, "bin", "1.5"); + p.setOption(JavaCore.COMPILER_ANNOTATION_NULL_ANALYSIS, JavaCore.ENABLED); + p.setOption(JavaCore.COMPILER_NONNULL_ANNOTATION_NAME, "invalid"); + + this.createFolder("/P/p1"); + String c1SourceString = + "package p1;\n" + + "@org.eclipse.jdt.annotation.NonNullByDefault\n" + + "public class C1 {\n" + + " public String foo(Object arg) {\n" + + " return arg == null ? \"\" : arg.toString();\n" + + " }\n" + + "}\n"; + this.createFile( + "/P/p1/C1.java", + c1SourceString); + + this.problemRequestor.initialize(c1SourceString.toCharArray()); + + final ICompilationUnit unit = getCompilationUnit("/P/p1/C1.java").getWorkingCopy(this.wcOwner, null); + assertProblems("Unexpected problems", + "----------\n" + + "1. ERROR in /P/p1/C1.java (at line 0)\n" + + " package p1;\n" + + " ^\n" + + "Cannot use the unqualified name \'invalid\' as an annotation name for null specification\n" + + "----------\n"); + + ASTParser parser = ASTParser.newParser(AST.JLS4); + parser.setProject(p); + parser.setResolveBindings(true); + parser.setSource(unit); + CompilationUnit ast = (CompilationUnit) parser.createAST(null); + assertNotNull("ast should not be null", ast); + this.problemRequestor.reset(); + this.problemRequestor.beginReporting(); + IProblem[] problems = ast.getProblems(); + for (int i=0; i= 0;) { MissingTypeBinding missingType = (MissingTypeBinding) this.missingTypes.get(i); @@ -1546,8 +1558,6 @@ public void reset() { this.unitBeingCompleted = null; // in case AbortException occurred this.classFilePool.reset(); - - this.nullAnnotationsInitialized = false; // name environment has a longer life cycle, and must be reset in // the code which created it. diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/PackageBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/PackageBinding.java index 54a5397..bc6862b 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/PackageBinding.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/PackageBinding.java @@ -24,9 +24,11 @@ public class PackageBinding extends Binding implements TypeConstants { HashtableOfType knownTypes; HashtableOfPackage knownPackages; + // if this package contains configured null-annotations, store their simple names here: protected char[] nullableName = null; protected char[] nonNullName = null; protected char[] nonNullByDefaultName = null; + // annotation type binding representing the default that has been defined for this package (using @NonNullByDefault) protected TypeBinding nullnessDefaultAnnotation; protected PackageBinding() { @@ -43,6 +45,8 @@ public PackageBinding(char[][] compoundName, PackageBinding parent, LookupEnviro this.environment = environment; this.knownTypes = null; // initialized if used... class counts can be very large 300-600 this.knownPackages = new HashtableOfPackage(3); // sub-package counts are typically 0-3 + if (compoundName != CharOperation.NO_CHAR_CHAR && environment.globalOptions.isAnnotationBasedNullAnalysisEnabled) + initNullAnnotationPackage(); } public PackageBinding(LookupEnvironment environment) { @@ -213,6 +217,19 @@ public Binding getTypeOrPackage(char[] name) { return null; } + +private void initNullAnnotationPackage() { + char[][] simpleAnnotNames = this.environment.getNullAnnotationNames(this.compoundName); + if (simpleAnnotNames == null) + return; + if (simpleAnnotNames[0] != null) + this.nullableName = simpleAnnotNames[0]; + if (simpleAnnotNames[1] != null) + this.nonNullName = simpleAnnotNames[1]; + if (simpleAnnotNames[2] != null) + this.nonNullByDefaultName = simpleAnnotNames[2]; +} + public final boolean isViewedAsDeprecated() { if ((this.tagBits & TagBits.DeprecatedAnnotationResolved) == 0) { this.tagBits |= TagBits.DeprecatedAnnotationResolved; @@ -253,9 +270,9 @@ void setupNullAnnotationType(ReferenceBinding type) { type.id = id; // ensure annotations of this type are detected as standard annotations. } -public TypeBinding getNullnessDefaultAnnotation() { +public TypeBinding getNullnessDefaultAnnotation(Scope scope) { if (this.nullnessDefaultAnnotation instanceof UnresolvedReferenceBinding) - return this.nullnessDefaultAnnotation = BinaryTypeBinding.resolveType(this.nullnessDefaultAnnotation, this.environment, false); + return this.nullnessDefaultAnnotation = this.environment.getNullAnnotationResolved(this.nullnessDefaultAnnotation, scope); return this.nullnessDefaultAnnotation; } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java index 94abc4f..07ef1da 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java @@ -1640,8 +1640,7 @@ private void evaluateNullAnnotations(long annotationTagBits) { } private TypeBinding getNullnessDefaultAnnotation() { if (this.nullnessDefaultAnnotation instanceof UnresolvedReferenceBinding) - return this.nullnessDefaultAnnotation = - BinaryTypeBinding.resolveType(this.nullnessDefaultAnnotation, getPackage().environment, false); + this.nullnessDefaultAnnotation = this.scope.environment().getNullAnnotationResolved(this.nullnessDefaultAnnotation, this.scope); return this.nullnessDefaultAnnotation; } /** @@ -1671,13 +1670,14 @@ private TypeBinding findDefaultNullness(MethodBinding methodBinding, LookupEnvir } // package - annotationBinding = type.getPackage().getNullnessDefaultAnnotation(); + annotationBinding = type.getPackage().getNullnessDefaultAnnotation(this.scope); if (annotationBinding != null) return annotationBinding; // global long defaultNullness = environment.globalOptions.defaultNonNullness; if (defaultNullness != 0) { + // we have a default, so we need an annotation type to record this during compile and in the byte code annotationBinding = environment.getNullAnnotationBinding(defaultNullness, true/*resolve*/); if (annotationBinding != null) return annotationBinding; @@ -1685,8 +1685,6 @@ private TypeBinding findDefaultNullness(MethodBinding methodBinding, LookupEnvir // on this branch default was not defined using an annotation, thus annotation type can still be missing if (defaultNullness == TagBits.AnnotationNonNull) this.scope.problemReporter().missingNullAnnotationType(environment.getNonNullAnnotationName()); - else if (defaultNullness == TagBits.AnnotationNullable) - this.scope.problemReporter().missingNullAnnotationType(environment.getNullableAnnotationName()); else this.scope.problemReporter().abortDueToInternalError("Illegal default nullness value: "+defaultNullness); //$NON-NLS-1$ // reset default to avoid duplicate errors: diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java index baeb26c..4c1e8a7 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java @@ -8191,7 +8191,8 @@ public void cannotImplementIncompatibleNullness(MethodBinding currentMethod, Met sourceEnd); } -public void nullAnnotationNameMustBeQualified(char[][] typeName) { +public void nullAnnotationNameMustBeQualified(char[][] typeName, CompilationUnitDeclaration unitBeingCompleted) { + this.referenceContext = unitBeingCompleted; String[] name = {new String(typeName[0])}; this.handle(IProblem.NullAnnotationNameMustBeQualified, name, name, 0, 0); } diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CompilationUnitResolver.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CompilationUnitResolver.java index 0fdbd0a..0bd8162 100644 --- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CompilationUnitResolver.java +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CompilationUnitResolver.java @@ -99,6 +99,7 @@ class CompilationUnitResolver extends Compiler { DefaultBindingResolver.BindingTables bindingTables; boolean hasCompilationAborted; + CategorizedProblem abortProblem; private IProgressMonitor monitor; @@ -364,6 +365,7 @@ class CompilationUnitResolver extends Compiler { removeUnresolvedBindings(unit); } this.hasCompilationAborted = true; + this.abortProblem = abortException.problem; } public static void parse(ICompilationUnit[] compilationUnits, ASTRequestor astRequestor, int apiLevel, Map options, int flags, IProgressMonitor monitor) { @@ -689,11 +691,16 @@ class CompilationUnitResolver extends Compiler { // the bindings could not be resolved due to missing types in name environment // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=86541 CompilationUnitDeclaration unitDeclaration = parse(sourceUnit, nodeSearcher, options, flags); - final int problemCount = unit.compilationResult.problemCount; - if (problemCount != 0) { - unitDeclaration.compilationResult.problems = new CategorizedProblem[problemCount]; - System.arraycopy(unit.compilationResult.problems, 0, unitDeclaration.compilationResult.problems, 0, problemCount); - unitDeclaration.compilationResult.problemCount = problemCount; + if (unit != null) { + final int problemCount = unit.compilationResult.problemCount; + if (problemCount != 0) { + unitDeclaration.compilationResult.problems = new CategorizedProblem[problemCount]; + System.arraycopy(unit.compilationResult.problems, 0, unitDeclaration.compilationResult.problems, 0, problemCount); + unitDeclaration.compilationResult.problemCount = problemCount; + } + } else if (resolver.abortProblem != null) { + unitDeclaration.compilationResult.problemCount = 1; + unitDeclaration.compilationResult.problems = new CategorizedProblem[] { resolver.abortProblem }; } return unitDeclaration; } diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ReconcileWorkingCopyOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ReconcileWorkingCopyOperation.java index 8095a3d..04baf0e 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ReconcileWorkingCopyOperation.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ReconcileWorkingCopyOperation.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2008 IBM Corporation and others. + * Copyright (c) 2000, 2011 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 @@ -132,6 +132,8 @@ public class ReconcileWorkingCopyOperation extends JavaModelOperation { if (categorizedProblems == null) continue; for (int i = 0, length = categorizedProblems.length; i < length; i++) { CategorizedProblem problem = categorizedProblems[i]; + if (problem.getCategoryID() == CategorizedProblem.CAT_BUILDPATH) + continue; // don't report these problems against any CU, are already reported against the project if (JavaModelManager.VERBOSE){ System.out.println("PROBLEM FOUND while reconciling : " + problem.getMessage());//$NON-NLS-1$ } diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/AbstractImageBuilder.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/AbstractImageBuilder.java index 531b2b5..99e2651 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/AbstractImageBuilder.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/AbstractImageBuilder.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2009 IBM Corporation and others. + * Copyright (c) 2000, 2011 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 @@ -700,6 +700,9 @@ protected void storeProblemsFor(SourceFile sourceFile, CategorizedProblem[] prob ); // 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 + } else if (problem.getCategoryID() == CategorizedProblem.CAT_BUILDPATH) { + // also report other build-path problems against the project, but using a normal problem marker + resource = this.javaBuilder.currentProject; } String markerType = problem.getMarkerType();