diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests.java index b01651704d0..5cd0f50e384 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests.java @@ -15678,7 +15678,83 @@ void methodHelper() { "src/issue3308b/Test.java void issue3308b.Test$OriginalClass$NestedOriginalClass.setup():#1.j [j] EXACT_MATCH" ); } +public void testGH4677() throws Exception { + String reproducer = "reproducer"; + String reproducer2 = "reproducer2"; + try { + IJavaProject reproducerPrj = createJavaProject("reproducer", new String[] {"src"}, new String[] {"JCL11_LIB"}, "bin", "11"); + IJavaProject reproducer2Prj = createJavaProject("reproducer2", new String[] {"src"}, new String[] {"JCL11_LIB"}, "bin", "11"); + + createFolder("/" + reproducer2 + "/src/reproducer2/"); + createFile("/" + reproducer2 + "/src/reproducer2/I18NKEY.java", + """ + package reproducer2; + public interface I18NKEY {} + """); + createFile("/" + reproducer2 + "/src/module-info.java", + """ + module reproducer2 {} + """); + + createFolder("/" + reproducer + "/src/reproducer/"); + createFile("/" + reproducer + "/src/reproducer/ERROR.java", + """ + package reproducer; + import reproducer2.I18NKEY; + public enum ERROR implements I18NKEY { + A, + B; + } + """); + createFile("/" + reproducer + "/src/reproducer/Foo.java", + """ + package reproducer; + import reproducer2.I18NKEY; + public class Foo { + public void addSuccessNotification(I18NKEY code, + String defaultMessage, + Object... params) { + } + } + """); + createFolder("/" + reproducer + "/src/otherpackage/"); + createFile("/" + reproducer + "/src/otherpackage/Bar.java", + """ + package otherpackage; + import reproducer.ERROR; + import reproducer.Foo; + public class Bar { + public void bar() { + Foo foo = new Foo(); + call(foo); + } + public void call(Foo foo) { + foo.addSuccessNotification(ERROR.A, "some message", ""); + } + public void call2(Foo foo) { + foo.addSuccessNotification(ERROR.B, "some message"); + } + public void call3(Foo foo) { + foo.addSuccessNotification(ERROR.B, "some message", "", ""); + } + } + """); + addClasspathEntry(reproducerPrj, JavaCore.newProjectEntry(reproducer2Prj.getPath())); + buildAndExpectNoProblems(reproducer2Prj, reproducerPrj); + + IType type = reproducerPrj.findType("reproducer.Foo"); + IMethod method = type.getMethod("addSuccessNotification", new String [] {"QI18NKEY;", "QString;", "[QObject;"}); + search(method, REFERENCES, EXACT_RULE, SearchEngine.createWorkspaceScope(), this.resultCollector); + assertSearchResults( + "src/otherpackage/Bar.java void otherpackage.Bar.call(Foo) [addSuccessNotification(ERROR.A, \"some message\", \"\")] EXACT_MATCH\n" + + "src/otherpackage/Bar.java void otherpackage.Bar.call2(Foo) [addSuccessNotification(ERROR.B, \"some message\")] EXACT_MATCH\n" + + "src/otherpackage/Bar.java void otherpackage.Bar.call3(Foo) [addSuccessNotification(ERROR.B, \"some message\", \"\", \"\")] EXACT_MATCH"); + } finally { + deleteProject(reproducer); + deleteProject(reproducer2); + } +} private static String toString(char[][] modules) { StringBuilder sb = new StringBuilder(); for (char[] m : modules) { diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/ClasspathSourceDirectory.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/ClasspathSourceDirectory.java index cc22b0eda86..5554b5fb72e 100644 --- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/ClasspathSourceDirectory.java +++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/ClasspathSourceDirectory.java @@ -26,6 +26,7 @@ import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.JavaCore; +import org.eclipse.jdt.internal.compiler.env.IModule; import org.eclipse.jdt.internal.compiler.env.IModulePathEntry; import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer; import org.eclipse.jdt.internal.core.JavaModelManager; @@ -40,18 +41,27 @@ public class ClasspathSourceDirectory extends ClasspathLocation implements IModu private static final Map missingPackageHolder = new HashMap<>(); final char[][] fullExclusionPatternChars; final char[][] fulInclusionPatternChars; + private boolean isOnModulePath = false; -ClasspathSourceDirectory(IContainer sourceFolder, char[][] fullExclusionPatternChars, char[][] fulInclusionPatternChars) { +ClasspathSourceDirectory(IContainer sourceFolder, + char[][] fullExclusionPatternChars, + char[][] fulInclusionPatternChars, + boolean isOnModulePath) { this.sourceFolder = sourceFolder; this.fullExclusionPatternChars = fullExclusionPatternChars; this.fulInclusionPatternChars = fulInclusionPatternChars; + this.isOnModulePath = isOnModulePath; } @Override public void cleanup() { this.directoryCache.clear(); } - +@Override +public void setModule (IModule mod) { + if (this.isOnModulePath) + this.module = mod; +} Map directoryTable(String qualifiedPackageName) { Map dirTable = this.directoryCache.get(qualifiedPackageName); if (dirTable == missingPackageHolder) return null; // package exists in another classpath directory or jar diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/JavaSearchNameEnvironment.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/JavaSearchNameEnvironment.java index 112ffa01393..654951c4840 100644 --- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/JavaSearchNameEnvironment.java +++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/JavaSearchNameEnvironment.java @@ -283,11 +283,11 @@ private ClasspathLocation mapToClassPathLocation(JavaModelManager manager, Packa ClasspathLocation.forLibrary(manager.getZipFile(path), rawClasspathEntry.getAccessRuleSet(), rawClasspathEntry.isModular(), compliance) ; } else { Object target = JavaModel.getTarget(root, true); + ClasspathEntry rawClasspathEntry = (ClasspathEntry) root.getRawClasspathEntry(); if (target != null) { if (root.getKind() == IPackageFragmentRoot.K_SOURCE) { - cp = new ClasspathSourceDirectory((IContainer)target, root.fullExclusionPatternChars(), root.fullInclusionPatternChars()); + cp = new ClasspathSourceDirectory((IContainer)target, root.fullExclusionPatternChars(), root.fullInclusionPatternChars(), defaultModule != null); } else { - ClasspathEntry rawClasspathEntry = (ClasspathEntry) root.getRawClasspathEntry(); cp = ClasspathLocation.forBinaryFolder((IContainer) target, false, rawClasspathEntry.getAccessRuleSet(), null, rawClasspathEntry.isModular()); }