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..47d2148 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
@@ -2018,8 +2018,10 @@
* 33207 - Reject output folder that coincidate with distinct source folder
*/
public void testClasspathValidation22() throws CoreException {
+ Hashtable options = JavaCore.getOptions();
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];
@@ -2033,6 +2035,7 @@
"Source folder \'src\' in project 'P' cannot output to distinct source folder \'src2\'",
status);
} finally {
+ JavaCore.setOptions(options);
this.deleteProject("P");
}
}
@@ -2043,8 +2046,10 @@
* default output scenarii is still tolerated
*/
public void testClasspathValidation23() throws CoreException {
+ Hashtable options = JavaCore.getOptions();
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];
@@ -2061,6 +2066,7 @@
// "Source folder 'P/src' cannot output to distinct source folder 'P/'.",
// status);
} finally {
+ JavaCore.setOptions(options);
this.deleteProject("P");
}
}
@@ -2305,11 +2311,14 @@
newCP[originalCP.length] = JavaCore.newSourceEntry(new Path("/P/src1"), new IPath[]{new Path("src2/")}, new Path("/P/src1/src2"));
newCP[originalCP.length+1] = JavaCore.newSourceEntry(new Path("/P/src1/src2"));
- IJavaModelStatus status = JavaConventions.validateClasspath(proj, newCP, proj.getOutputLocation());
+ proj.setRawClasspath(newCP, proj.getOutputLocation(), null);
- assertStatus(
- "Source folder \'src1\' in project 'P' cannot output to distinct source folder \'src1/src2\'",
- status);
+ assertMarkers(
+ "Unexpected markers",
+ "Project \'P\' is missing required source folder: \'src1\'\n" +
+ "Project \'P\' is missing required source folder: \'src1/src2\'\n" +
+ "Source folder \'src1\' in project \'P\' cannot output to distinct source folder \'src1/src2\'",
+ proj);
} finally {
this.deleteProject("P");
}
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..e25a8cb 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"
Status constant indicating that the default or specific output folder is overlapping
+ * with another source location.
Indicate the severity of the problem reported when a source entry's output location overlaps another + * source entry.
+ * + *"org.eclipse.jdt.core.classpath.outputOverlappingAnotherSource"
{ "error", "warning", "ignore" }
"warning"
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.
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..d51adc0 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
@@ -1788,30 +1788,39 @@
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();
+ int severity = JavaCore.ERROR.equals(option) ? IStatus.ERROR : IStatus.WARNING;
+ return new JavaModelStatus(severity, IJavaModelStatusConstants.OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE,
+ Messages.bind(Messages.classpath_cannotUseDistinctSourceFolderAsOutput, new String[] {
+ entryPathMsg, otherPathMsg, projectName }));
}
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.
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..6ba4482 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
@@ -37,7 +37,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);
// remove problems and tasks created by the builder
JavaBuilder.removeProblemsAndTasksFor(resource);
@@ -56,12 +56,15 @@
}
// update classpath format problems
- this.project.flushClasspathProblemMarkers(false/*cycle*/, true/*format*/);
+ this.project.flushClasspathProblemMarkers(false/*cycle*/, true/*format*/, false);
if (!status.isOK())
this.project.createClasspathProblemMarker(status);
+ // update overlapping output problem markers
+ this.project.flushClasspathProblemMarkers(false/*cycle*/, false/*format*/, true);
+
// update resolved classpath problems
- this.project.flushClasspathProblemMarkers(false/*cycle*/, false/*format*/);
+ this.project.flushClasspathProblemMarkers(false/*cycle*/, false/*format*/, false);
if (rawClasspath != JavaProject.INVALID_CLASSPATH && outputLocation != null) {
for (int i = 0; i < rawClasspath.length; i++) {
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 cdead40..fba912d 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
@@ -1481,7 +1481,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;
@@ -2248,7 +2249,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/JavaModelOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelOperation.java
index 08c4b60..c56ef5a 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelOperation.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelOperation.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
@@ -780,7 +780,7 @@
*/
public void runOperation(IProgressMonitor monitor) throws JavaModelException {
IJavaModelStatus status= verify();
- if (!status.isOK()) {
+ if (status.getSeverity() == IStatus.ERROR) {
throw new JavaModelException(status);
}
try {
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 42b1890..22cc082 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
@@ -433,7 +433,7 @@
new JavaModelStatus(IJavaModelStatusConstants.CLASSPATH_CYCLE, project, cycleString));
}
} else {
- project.flushClasspathProblemMarkers(true, false);
+ project.flushClasspathProblemMarkers(true, false, false);
}
}
}
@@ -803,7 +803,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 :
@@ -830,7 +830,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() };
@@ -852,6 +862,7 @@
IMarker.LOCATION,
IJavaModelMarker.CYCLE_DETECTED,
IJavaModelMarker.CLASSPATH_FILE_FORMAT,
+ IJavaModelMarker.OUTPUT_OVERLAPPING_SOURCE,
IJavaModelMarker.ID,
IJavaModelMarker.ARGUMENTS ,
IJavaModelMarker.CATEGORY_ID,
@@ -863,6 +874,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),
@@ -1356,18 +1368,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();
}
@@ -1513,6 +1527,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);
}