diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ClasspathTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ClasspathTests.java index 4166cb2..7daccdb 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ClasspathTests.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ClasspathTests.java @@ -334,6 +334,7 @@ suite.addTest(new ClasspathTests("testBug321170")); suite.addTest(new ClasspathTests("testBug229042")); suite.addTest(new ClasspathTests("testBug274737")); + suite.addTest(new ClasspathTests("testBug287164")); return suite; } public void setUpSuite() throws Exception { @@ -2020,6 +2021,7 @@ public void testClasspathValidation22() throws CoreException { try { IJavaProject proj = this.createJavaProject("P", new String[] {}, ""); + proj.setOption(JavaCore.CORE_OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE, JavaCore.ERROR); IClasspathEntry[] originalCP = proj.getRawClasspath(); IClasspathEntry[] newCP = new IClasspathEntry[originalCP.length+2]; @@ -2045,6 +2047,7 @@ public void testClasspathValidation23() throws CoreException { try { IJavaProject proj = this.createJavaProject("P", new String[] {}, ""); + proj.setOption(JavaCore.CORE_OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE, JavaCore.IGNORE); IClasspathEntry[] originalCP = proj.getRawClasspath(); IClasspathEntry[] newCP = new IClasspathEntry[originalCP.length+2]; @@ -7189,5 +7192,70 @@ deleteProject("P"); } } +/** + * @bug287164: Report build path error if source folder has other source folder as output folder + * + * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=287164" + */ +public void testBug287164() throws CoreException { + try { + IJavaProject proj = this.createJavaProject("P", new String[] {}, ""); + + // Test that with the option set to IGNORE, the Java model status returns OK + proj.setOption(JavaCore.CORE_OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE, JavaCore.IGNORE); + IClasspathEntry[] originalCP = proj.getRawClasspath(); + IClasspathEntry[] newCP = new IClasspathEntry[originalCP.length+2]; + System.arraycopy(originalCP, 0, newCP, 0, originalCP.length); + newCP[originalCP.length] = JavaCore.newSourceEntry(new Path("/P/src"), new IPath[0], new Path("/P/src2")); + newCP[originalCP.length+1] = JavaCore.newSourceEntry(new Path("/P/src2"), new IPath[0], new Path("/P/src")); + + createFolder("/P/src"); + createFolder("/P/src2"); + + IJavaModelStatus status = JavaConventions.validateClasspath(proj, newCP, proj.getOutputLocation()); + assertTrue(status.isOK()); + assertStatus( + "OK", + status); + + proj.setRawClasspath(newCP, null); + assertMarkers("Unexpected markers", "", proj); + + // Test that with the option set to WARNING, status.isOK() returns true + proj.setOption(JavaCore.CORE_OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE, JavaCore.WARNING); + + status = JavaConventions.validateClasspath(proj, newCP, proj.getOutputLocation()); + assertTrue(status.isOK()); + assertStatus( + "Source folder \'src\' in project \'P\' cannot output to distinct source folder \'src2\'", + status); + + assertMarkers("Unexpected markers", + "Source folder \'src\' in project \'P\' cannot output to distinct source folder \'src2\'", proj); + + // Test that with the option set to WARNING and the presence of a more severe error scenario, the error status + // is returned + IClasspathEntry[] newCP2 = new IClasspathEntry[newCP.length+1]; + System.arraycopy(newCP, 0, newCP2, 0, newCP.length-1); + newCP2[newCP.length] = JavaCore.newLibraryEntry(new Path("/P/lib2"), null, null); + newCP2[newCP.length-1] = JavaCore.newSourceEntry(new Path("/P/src2"), new IPath[0], new Path("/P/lib2")); + + status = JavaConventions.validateClasspath(proj, newCP2, proj.getOutputLocation()); + assertFalse(status.isOK()); + assertStatus( + "Source folder \'src2\' in project 'P' cannot output to library \'lib2\'", + status); + + proj.setOption(JavaCore.CORE_OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE, JavaCore.ERROR); + + status = JavaConventions.validateClasspath(proj, newCP, proj.getOutputLocation()); + assertStatus( + "Source folder \'src\' in project \'P\' cannot output to distinct source folder \'src2\'", + status); + + } finally { + this.deleteProject("P"); + } +} } diff --git a/org.eclipse.jdt.core/.settings/.api_filters b/org.eclipse.jdt.core/.settings/.api_filters index d4aad52..76f9c13 100644 --- a/org.eclipse.jdt.core/.settings/.api_filters +++ b/org.eclipse.jdt.core/.settings/.api_filters @@ -309,7 +309,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaModelMarker.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaModelMarker.java index dbc6e55..0c106ae 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaModelMarker.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaModelMarker.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 @@ -114,4 +114,13 @@ * @since 2.0 */ String CLASSPATH_FILE_FORMAT = "classpathFileFormat"; //$NON-NLS-1$ + + /** + * Output overlapping another source attribute (value "outputOverlappingSource"). + * Used only on buildpath problem markers. The value of this attribute is + * either "true" or "false". + * + * @since 3.8 + */ + String OUTPUT_OVERLAPPING_SOURCE = "outputOverlappingSource"; //$NON-NLS-1$ } diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaModelStatusConstants.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaModelStatusConstants.java index 4cc2f45..1fd2a84 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaModelStatusConstants.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaModelStatusConstants.java @@ -345,4 +345,11 @@ * @since 3.7 */ public static final int CANNOT_RETRIEVE_ATTACHED_JAVADOC_TIMEOUT = 1012; + + /** + *

Status constant indicating that the default or specific output folder is overlapping + * with another source location.

+ * @since 3.8 + */ + public static final int OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE = 1013; } diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaConventions.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaConventions.java index 5d80813..8ae6fdc 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaConventions.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaConventions.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 @@ -581,11 +581,13 @@ *
  • The project output location path cannot be null, must be absolute and located inside the project. *
  • Specific output locations (specified on source entries) can be null, if not they must be located inside the project, *
  • A project entry cannot refer to itself directly (that is, a project cannot prerequisite itself). - *
  • Classpath entries or output locations cannot coincidate or be nested in each other, except for the following scenarii listed below: - *
    • A source folder can coincidate with its own output location, in which case this output can then contain library archives. - * However, a specific output location cannot coincidate with any library or a distinct source folder than the one referring to it.
    • + *
    • Classpath entries or output locations cannot coincide or be nested in each other, except for the following scenarios listed below: + *
      • A source folder can coincide with its own output location, in which case this output can then contain library archives. + * However, a specific output location cannot coincide with any library or a distinct source folder than the one referring to it.
        + * Note: Since 3.8, this behavior can be overridden by configuring {@link JavaCore#CORE_OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE} + *
      • *
      • A source/library folder can be nested in any source folder as long as the nested folder is excluded from the enclosing one.
      • - *
      • An output location can be nested in a source folder, if the source folder coincidates with the project itself, or if the output + *
      • An output location can be nested in a source folder, if the source folder coincides with the project itself, or if the output * location is excluded from the source folder. *
      *
    diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java index b6a1cbf..e24e842 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java @@ -1829,6 +1829,19 @@ */ public static final String CORE_ENABLE_CLASSPATH_MULTIPLE_OUTPUT_LOCATIONS = PLUGIN_ID + ".classpath.multipleOutputLocations"; //$NON-NLS-1$ /** + * Core option ID: Reporting an output location overlapping another source location. + *

    Indicate the severity of the problem reported when a source entry's output location overlaps another + * source entry.

    + * + *
    + *
    Option id:
    "org.eclipse.jdt.core.classpath.outputOverlappingAnotherSource"
    + *
    Possible values:
    { "error", "warning", "ignore" }
    + *
    Default:
    "warning"
    + *
    + * @since 3.8 + */ + public static final String CORE_OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE = PLUGIN_ID + ".classpath.outputOverlappingAnotherSource"; //$NON-NLS-1$ + /** * Core option ID: Set the timeout value for retrieving the method's parameter names from javadoc. *

    Timeout in milliseconds to retrieve the method's parameter names from javadoc. *

    If the value is 0, the parameter names are not fetched and the raw names are returned. @@ -3684,6 +3697,7 @@ try { if (JavaBuilder.DEBUG) System.out.println("Touching " + project.getElementName()); //$NON-NLS-1$ + new ClasspathValidation((JavaProject) project).validate(); // https://bugs.eclipse.org/bugs/show_bug.cgi?id=287164 project.getProject().touch(progressMonitor2); } catch (CoreException e) { // could not touch this project: ignore diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathEntry.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathEntry.java index d8086ff..6cfc987 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathEntry.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathEntry.java @@ -1776,6 +1776,7 @@ // perform one separate iteration so as to not take precedence over previously checked scenarii (in particular should // diagnose nesting source folder issue before this one, for example, [src]"Project/", [src]"Project/source/" and output="Project/" should // first complain about missing exclusion pattern + IJavaModelStatus cachedStatus = null; for (int i = 0 ; i < length; i++) { IClasspathEntry entry = classpath[i]; if (entry == null) continue; @@ -1788,30 +1789,53 @@ if (kind == IClasspathEntry.CPE_SOURCE) { IPath output = entry.getOutputLocation(); - if (output == null) continue; // 36465 - for 2.0 backward compatibility, only check specific output locations (the default can still coincidate) - // if (output == null) output = projectOutputLocation; // if no specific output, still need to check using default output (this line would check default output) + if (output == null) output = projectOutputLocation; // if no specific output, still need to check using default output (this line would check default output) for (int j = 0; j < length; j++) { IClasspathEntry otherEntry = classpath[j]; if (otherEntry == entry) continue; - // Build some common strings for status message - boolean opStartsWithProject = projectName.equals(otherEntry.getPath().segment(0)); - String otherPathMsg = opStartsWithProject ? otherEntry.getPath().removeFirstSegments(1).toString() : otherEntry.getPath().makeRelative().toString(); - switch (otherEntry.getEntryKind()) { case IClasspathEntry.CPE_SOURCE : - if (otherEntry.getPath().equals(output)) { - return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_cannotUseDistinctSourceFolderAsOutput, new String[] {entryPathMsg, otherPathMsg, projectName})); + // Bug 287164 : Report errors of overlapping output locations only if the user sets the corresponding preference. + // The check is required for backward compatibility with bug-fix 36465. + String option = javaProject.getOption(JavaCore.CORE_OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE, true); + if (otherEntry.getPath().equals(output) + && !JavaCore.IGNORE.equals(option)) { + boolean opStartsWithProject = projectName.equals(otherEntry.getPath().segment(0)); + String otherPathMsg = opStartsWithProject ? otherEntry.getPath().removeFirstSegments(1).toString() : otherEntry.getPath().makeRelative().toString(); + if (JavaCore.ERROR.equals(option)) { + return new JavaModelStatus(IStatus.ERROR, IJavaModelStatusConstants.OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE, + Messages.bind(Messages.classpath_cannotUseDistinctSourceFolderAsOutput, new String[] { + entryPathMsg, otherPathMsg, projectName })); + } + if (cachedStatus == null) { + // Note that the isOK() is being overridden to return true. This is an exceptional scenario + cachedStatus = new JavaModelStatus(IStatus.OK, IJavaModelStatusConstants.OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE, + Messages.bind(Messages.classpath_cannotUseDistinctSourceFolderAsOutput, new String[] { + entryPathMsg, otherPathMsg, projectName })){ + public boolean isOK() { + return true; + } + }; + } } break; case IClasspathEntry.CPE_LIBRARY : - if (otherEntry.getPath().equals(output)) { + if (output != projectOutputLocation && otherEntry.getPath().equals(output)) { + boolean opStartsWithProject = projectName.equals(otherEntry.getPath().segment(0)); + String otherPathMsg = opStartsWithProject ? otherEntry.getPath().removeFirstSegments(1).toString() : otherEntry.getPath().makeRelative().toString(); return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_cannotUseLibraryAsOutput, new String[] {entryPathMsg, otherPathMsg, projectName})); } } } } } + + // NOTE: The above code that checks for IJavaModelStatusConstants.OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE, can be configured to return + // a WARNING status and hence should be at the end of this validation method. Any other code that might return a more severe ERROR should be + // inserted before the mentioned code. + if (cachedStatus != null) return cachedStatus; + return JavaModelStatus.VERIFIED_OK; } diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathValidation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathValidation.java index ea310a3..345535a 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathValidation.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathValidation.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 @@ -12,6 +12,7 @@ import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IStatus; import org.eclipse.jdt.core.IClasspathEntry; import org.eclipse.jdt.core.IJavaModelStatus; import org.eclipse.jdt.core.JavaModelException; @@ -37,7 +38,7 @@ // project doesn't exist IProject resource = this.project.getProject(); if (resource.isAccessible()) { - this.project.flushClasspathProblemMarkers(true/*flush cycle markers*/, true/*flush classpath format markers*/); + this.project.flushClasspathProblemMarkers(true/*flush cycle markers*/, true/*flush classpath format markers*/, true /*flush overlapping output markers*/); // remove problems and tasks created by the builder JavaBuilder.removeProblemsAndTasksFor(resource); @@ -56,12 +57,15 @@ } // update classpath format problems - this.project.flushClasspathProblemMarkers(false/*cycle*/, true/*format*/); + this.project.flushClasspathProblemMarkers(false/*cycle*/, true/*format*/, false/*overlapping*/); if (!status.isOK()) this.project.createClasspathProblemMarker(status); + // update overlapping output problem markers + this.project.flushClasspathProblemMarkers(false/*cycle*/, false/*format*/, true/*overlapping*/); + // update resolved classpath problems - this.project.flushClasspathProblemMarkers(false/*cycle*/, false/*format*/); + this.project.flushClasspathProblemMarkers(false/*cycle*/, false/*format*/, false/*overlapping*/); if (rawClasspath != JavaProject.INVALID_CLASSPATH && outputLocation != null) { for (int i = 0; i < rawClasspath.length; i++) { @@ -71,7 +75,7 @@ } } status = ClasspathEntry.validateClasspath(this.project, rawClasspath, outputLocation); - if (!status.isOK()) + if (status.getCode() != IStatus.OK) this.project.createClasspathProblemMarker(status); } } diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaCorePreferenceInitializer.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaCorePreferenceInitializer.java index 532ed94..835d1d6 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaCorePreferenceInitializer.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaCorePreferenceInitializer.java @@ -58,6 +58,7 @@ defaultOptionsMap.put(JavaCore.CORE_INCOMPATIBLE_JDK_LEVEL, JavaCore.IGNORE); defaultOptionsMap.put(JavaCore.CORE_ENABLE_CLASSPATH_EXCLUSION_PATTERNS, JavaCore.ENABLED); defaultOptionsMap.put(JavaCore.CORE_ENABLE_CLASSPATH_MULTIPLE_OUTPUT_LOCATIONS, JavaCore.ENABLED); + defaultOptionsMap.put(JavaCore.CORE_OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE, JavaCore.WARNING); // encoding setting comes from resource plug-in optionNames.add(JavaCore.CORE_ENCODING); diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java index b5a4870..1f39c60 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java @@ -1480,7 +1480,8 @@ propertyName.equals(JavaCore.CORE_ENABLE_CLASSPATH_MULTIPLE_OUTPUT_LOCATIONS) || propertyName.equals(JavaCore.CORE_INCOMPLETE_CLASSPATH) || propertyName.equals(JavaCore.CORE_CIRCULAR_CLASSPATH) || - propertyName.equals(JavaCore.CORE_INCOMPATIBLE_JDK_LEVEL)) { + propertyName.equals(JavaCore.CORE_INCOMPATIBLE_JDK_LEVEL) || + propertyName.equals(JavaCore.CORE_OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE)) { JavaModelManager manager = JavaModelManager.getJavaModelManager(); IJavaModel model = manager.getJavaModel(); IJavaProject[] projects; @@ -2247,7 +2248,8 @@ defaultOptionsMap.put(JavaCore.CORE_JAVA_BUILD_ORDER, JavaCore.IGNORE); defaultOptionsMap.put(JavaCore.CORE_INCOMPLETE_CLASSPATH, JavaCore.ERROR); defaultOptionsMap.put(JavaCore.CORE_CIRCULAR_CLASSPATH, JavaCore.ERROR); - defaultOptionsMap.put(JavaCore.CORE_INCOMPATIBLE_JDK_LEVEL, JavaCore.IGNORE); + defaultOptionsMap.put(JavaCore.CORE_INCOMPATIBLE_JDK_LEVEL, JavaCore.IGNORE); + defaultOptionsMap.put(JavaCore.CORE_OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE, JavaCore.WARNING); defaultOptionsMap.put(JavaCore.CORE_ENABLE_CLASSPATH_EXCLUSION_PATTERNS, JavaCore.ENABLED); defaultOptionsMap.put(JavaCore.CORE_ENABLE_CLASSPATH_MULTIPLE_OUTPUT_LOCATIONS, JavaCore.ENABLED); diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java index 463af9e..18057ac 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java @@ -431,7 +431,7 @@ new JavaModelStatus(IJavaModelStatusConstants.CLASSPATH_CYCLE, project, cycleString)); } } else { - project.flushClasspathProblemMarkers(true, false); + project.flushClasspathProblemMarkers(true, false, false); } } } @@ -801,7 +801,7 @@ IMarker marker = null; int severity; String[] arguments = CharOperation.NO_STRINGS; - boolean isCycleProblem = false, isClasspathFileFormatProblem = false; + boolean isCycleProblem = false, isClasspathFileFormatProblem = false, isOutputOverlapping = false; switch (status.getCode()) { case IJavaModelStatusConstants.CLASSPATH_CYCLE : @@ -828,7 +828,17 @@ return; // setting == IGNORE } break; - + case IJavaModelStatusConstants.OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE : + isOutputOverlapping = true; + setting = getOption(JavaCore.CORE_OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE, true); + if (JavaCore.ERROR.equals(setting)) { + severity = IMarker.SEVERITY_ERROR; + } else if (JavaCore.WARNING.equals(setting)) { + severity = IMarker.SEVERITY_WARNING; + } else { + return; // setting == IGNORE + } + break; default: IPath path = status.getPath(); if (path != null) arguments = new String[] { path.toString() }; @@ -850,6 +860,7 @@ IMarker.LOCATION, IJavaModelMarker.CYCLE_DETECTED, IJavaModelMarker.CLASSPATH_FILE_FORMAT, + IJavaModelMarker.OUTPUT_OVERLAPPING_SOURCE, IJavaModelMarker.ID, IJavaModelMarker.ARGUMENTS , IJavaModelMarker.CATEGORY_ID, @@ -861,6 +872,7 @@ Messages.classpath_buildPath, isCycleProblem ? "true" : "false",//$NON-NLS-1$ //$NON-NLS-2$ isClasspathFileFormatProblem ? "true" : "false",//$NON-NLS-1$ //$NON-NLS-2$ + isOutputOverlapping ? "true" : "false", //$NON-NLS-1$ //$NON-NLS-2$ new Integer(status.getCode()), Util.getProblemArgumentsForMarker(arguments) , new Integer(CategorizedProblem.CAT_BUILDPATH), @@ -1354,18 +1366,20 @@ /** * Remove all markers denoting classpath problems */ //TODO (philippe) should improve to use a bitmask instead of booleans (CYCLE, FORMAT, VALID) - protected void flushClasspathProblemMarkers(boolean flushCycleMarkers, boolean flushClasspathFormatMarkers) { + protected void flushClasspathProblemMarkers(boolean flushCycleMarkers, boolean flushClasspathFormatMarkers, boolean flushOverlappingOutputMarkers) { try { if (this.project.isAccessible()) { IMarker[] markers = this.project.findMarkers(IJavaModelMarker.BUILDPATH_PROBLEM_MARKER, false, IResource.DEPTH_ZERO); for (int i = 0, length = markers.length; i < length; i++) { IMarker marker = markers[i]; - if (flushCycleMarkers && flushClasspathFormatMarkers) { + if (flushCycleMarkers && flushClasspathFormatMarkers && flushOverlappingOutputMarkers) { marker.delete(); } else { String cycleAttr = (String)marker.getAttribute(IJavaModelMarker.CYCLE_DETECTED); String classpathFileFormatAttr = (String)marker.getAttribute(IJavaModelMarker.CLASSPATH_FILE_FORMAT); + String overlappingOutputAttr = (String) marker.getAttribute(IJavaModelMarker.OUTPUT_OVERLAPPING_SOURCE); if ((flushCycleMarkers == (cycleAttr != null && cycleAttr.equals("true"))) //$NON-NLS-1$ + && (flushOverlappingOutputMarkers == (overlappingOutputAttr != null && overlappingOutputAttr.equals("true"))) //$NON-NLS-1$ && (flushClasspathFormatMarkers == (classpathFileFormatAttr != null && classpathFileFormatAttr.equals("true")))){ //$NON-NLS-1$ marker.delete(); } @@ -1511,6 +1525,7 @@ propertyName.equals(JavaCore.CORE_ENABLE_CLASSPATH_MULTIPLE_OUTPUT_LOCATIONS) || propertyName.equals(JavaCore.CORE_INCOMPLETE_CLASSPATH) || propertyName.equals(JavaCore.CORE_CIRCULAR_CLASSPATH) || + propertyName.equals(JavaCore.CORE_OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE) || propertyName.equals(JavaCore.CORE_INCOMPATIBLE_JDK_LEVEL)) { manager.deltaState.addClasspathValidation(JavaProject.this); diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SetClasspathOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SetClasspathOperation.java index 9623813..ec0ccf2 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SetClasspathOperation.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SetClasspathOperation.java @@ -114,6 +114,7 @@ IJavaModelStatus status = super.verify(); if (!status.isOK()) return status; + this.project.flushClasspathProblemMarkers(false, false, true); return ClasspathEntry.validateClasspath( this.project, this.newRawClasspath, this.newOutputLocation); } diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/State.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/State.java index 682073d..434866d 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/State.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/State.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 @@ -44,7 +44,7 @@ private StringSet structurallyChangedTypes; public static int MaxStructurallyChangedTypes = 100; // keep track of ? structurally changed types, otherwise consider all to be changed -public static final byte VERSION = 0x0019; // fix for 325755 +public static final byte VERSION = 0x001A; // fix for 287164 static final byte SOURCE_FOLDER = 1; static final byte BINARY_FOLDER = 2;