Bug 377850 - Error "type X collides with a package" should not be raised
if no compilation units declare the package
Change-Id: I71932eea45b72258e38f1c2ea6c0e361384f61a0
diff --git a/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/PackageTests.java b/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/PackageTests.java
index 11340bb..9663c2c 100644
--- a/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/PackageTests.java
+++ b/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/PackageTests.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2019 IBM Corporation and others.
+ * Copyright (c) 2000, 2020 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -39,7 +39,7 @@
/**
* Bugs 6564
*/
- public void testPackageProblem() throws JavaModelException {
+ public void testNoPackageProblem() throws JavaModelException {
//----------------------------
// Step 1
//----------------------------
@@ -91,7 +91,7 @@
/**
* https://bugs.eclipse.org/bugs/show_bug.cgi?id=251690
*/
- public void testNoPackageProblem() throws JavaModelException {
+ public void testPackageProblem() throws JavaModelException {
IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
env.addExternalJars(projectPath, Util.getJavaClassLibs());
env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
@@ -114,6 +114,51 @@
new Problem("", "The declared package \"\" does not match the expected package \"p.A\"", bPath, 0, 1, CategorizedProblem.CAT_INTERNAL, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
}
+ public void testNoFolderProblem() throws JavaModelException {
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+ IPath src = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ env.addClass(src, "p", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p;\n"+ //$NON-NLS-1$
+ "public class A {}" //$NON-NLS-1$
+ );
+
+ // create folder & contained non-java file (which don't establish package p.A!):
+ env.addFolder(src, "p/A"); //$NON-NLS-1$
+ env.addFile(src, "p/A/some.properties", //$NON-NLS-1$
+ "name=Some\n" //$NON-NLS-1$
+ );
+
+ fullBuild();
+ expectingNoProblems();
+ }
+
+ public void testNestedPackageProblem() throws JavaModelException {
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+ env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$
+ IPath src = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ IPath aPath = env.addClass(src, "p", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p;\n"+ //$NON-NLS-1$
+ "public class A {}\n" //$NON-NLS-1$
+ );
+
+ // a class in a sub-package of p.A seems to establish package p.A, too, causing a conflict indeed:
+ env.addClass(src, "p.A.c", "B", //$NON-NLS-1$ //$NON-NLS-2$
+ "package p.A.c;\n" +
+ "public class B {}\n" //$NON-NLS-1$
+ );
+
+ fullBuild();
+ expectingOnlySpecificProblemFor(aPath,
+ new Problem("", "The type A collides with a package", aPath, 24, 25, CategorizedProblem.CAT_TYPE, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=117092
// simplistic linked subfolder used as package, external case (not in workspace)
public void test001() throws CoreException {
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathDirectory.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathDirectory.java
index 012a927..cbbf20e 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathDirectory.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathDirectory.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2018 IBM Corporation and others.
+ * Copyright (c) 2000, 2020 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -97,6 +97,7 @@
}
return null;
}
+/** Lists all java-like files and also sub-directories (for recursive tests). */
String[] directoryList(String qualifiedPackageName) {
String[] dirList = (String[]) this.directoryCache.get(qualifiedPackageName);
if (dirList == this.missingPackageHolder) return null; // package exists in another classpath directory or jar
@@ -111,7 +112,8 @@
for (int i = 0, l = members.length; i < l; i++) {
IResource m = members[i];
String name = m.getName();
- if (m.getType() == IResource.FILE && org.eclipse.jdt.internal.compiler.util.Util.isClassFileName(name)) {
+ if (m.getType() == IResource.FOLDER || // include folders so we recognize empty parent packages
+ (m.getType() == IResource.FILE && org.eclipse.jdt.internal.compiler.util.Util.isClassFileName(name))) {
// add exclusion pattern check here if we want to hide .class files
dirList[index++] = name;
}
@@ -215,7 +217,17 @@
if (this.module == null || !moduleName.equals(String.valueOf(this.module.name())))
return false;
}
- return directoryList(qualifiedPackageName) != null;
+ String[] list = directoryList(qualifiedPackageName);
+ if (list != null) {
+ for (String entry : list) {
+ String entryLC = entry.toLowerCase();
+ if (entryLC.endsWith(SuffixConstants.SUFFIX_STRING_class) || entryLC.endsWith(SuffixConstants.SUFFIX_STRING_java))
+ return true;
+ if (entryLC.indexOf('.') == -1)
+ return isPackage(qualifiedPackageName+'/'+entry, null/*already checked*/);
+ }
+ }
+ return false;
}
@Override
public boolean hasCompilationUnit(String qualifiedPackageName, String moduleName) {
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathMultiDirectory.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathMultiDirectory.java
index fd384f2..b72832d 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathMultiDirectory.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathMultiDirectory.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2016 IBM Corporation and others.
+ * Copyright (c) 2000, 2020 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -86,7 +86,8 @@
for (int i = 0, l = members.length; i < l; i++) {
IResource m = members[i];
String name = m.getName();
- if (m.getType() == IResource.FILE && org.eclipse.jdt.internal.compiler.util.Util.isClassFileName(name)) {
+ if (m.getType() == IResource.FOLDER
+ || (m.getType() == IResource.FILE && org.eclipse.jdt.internal.compiler.util.Util.isClassFileName(name))) {
// add exclusion pattern check here if we want to hide .class files
dirList[index++] = name;
}
@@ -102,7 +103,8 @@
for (int i = 0, l = members.length; i < l; i++) {
IResource m = members[i];
String name = m.getName();
- if (m.getType() == IResource.FILE && org.eclipse.jdt.internal.compiler.util.Util.isJavaFileName(name)) {
+ if (m.getType() == IResource.FOLDER
+ || (m.getType() == IResource.FILE && org.eclipse.jdt.internal.compiler.util.Util.isJavaFileName(name))) {
// FIXME: check if .java file has any declarations?
dirList[index++] = name;
}