Skip to content

Commit 810d955

Browse files
Limit search scope of main class to source files and the specified project or paths (microsoft#395)
* Limit search scope of main class to source files and the specified project or paths
1 parent f652c8d commit 810d955

File tree

1 file changed

+84
-12
lines changed

1 file changed

+84
-12
lines changed

com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/ResolveMainClassHandler.java

Lines changed: 84 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2017-2021 Microsoft Corporation and others.
2+
* Copyright (c) 2017-2022 Microsoft Corporation and others.
33
* All rights reserved. This program and the accompanying materials
44
* are made available under the terms of the Eclipse Public License v1.0
55
* which accompanies this distribution, and is available at
@@ -12,6 +12,7 @@
1212
package com.microsoft.java.debug.plugin.internal;
1313

1414
import java.util.ArrayList;
15+
import java.util.Arrays;
1516
import java.util.Collection;
1617
import java.util.Collections;
1718
import java.util.Comparator;
@@ -21,6 +22,7 @@
2122
import java.util.logging.Level;
2223
import java.util.logging.Logger;
2324
import java.util.stream.Collectors;
25+
import java.util.stream.Stream;
2426

2527
import javax.lang.model.SourceVersion;
2628

@@ -79,15 +81,26 @@ public Object validateLaunchConfig(List<Object> arguments) throws Exception {
7981
}
8082

8183
private List<ResolutionItem> resolveMainClassCore(List<Object> arguments) {
82-
IPath rootPath = null;
8384
if (arguments != null && arguments.size() > 0 && arguments.get(0) != null) {
84-
rootPath = ResourceUtils.filePathFromURI((String) arguments.get(0));
85-
}
86-
final ArrayList<IPath> targetProjectPath = new ArrayList<>();
87-
if (rootPath != null) {
88-
targetProjectPath.add(rootPath);
85+
String argument = (String) arguments.get(0);
86+
IProject[] projects = ProjectUtils.getAllProjects();
87+
if (Stream.of(projects).anyMatch(project -> Objects.equals(project.getName(), argument))) {
88+
return resolveMainClassUnderProject(argument);
89+
}
90+
91+
IPath rootPath = ResourceUtils.filePathFromURI(argument);
92+
if (rootPath != null) {
93+
return resolveMainClassUnderPaths(Arrays.asList(rootPath));
94+
}
8995
}
90-
IJavaSearchScope searchScope = SearchEngine.createWorkspaceScope();
96+
97+
return resolveMainClassUnderPaths(Collections.emptyList());
98+
}
99+
100+
private List<ResolutionItem> resolveMainClassUnderPaths(List<IPath> parentPaths) {
101+
// Limit to search main method from source code only.
102+
IJavaSearchScope searchScope = SearchEngine.createJavaSearchScope(ProjectUtils.getJavaProjects(),
103+
IJavaSearchScope.REFERENCED_PROJECTS | IJavaSearchScope.SOURCES);
91104
SearchPattern pattern = SearchPattern.createPattern("main(String[]) void", IJavaSearchConstants.METHOD,
92105
IJavaSearchConstants.DECLARATIONS, SearchPattern.R_CASE_SENSITIVE | SearchPattern.R_EXACT_MATCH);
93106
final List<ResolutionItem> res = new ArrayList<>();
@@ -112,10 +125,9 @@ public void acceptSearchMatch(SearchMatch match) {
112125
}
113126
}
114127
String projectName = ProjectsManager.DEFAULT_PROJECT_NAME.equals(project.getName()) ? null : project.getName();
115-
if (projectName == null
116-
|| targetProjectPath.isEmpty()
117-
|| ResourceUtils.isContainedIn(project.getLocation(), targetProjectPath)
118-
|| isContainedInInvisibleProject(project, targetProjectPath)) {
128+
if (parentPaths.isEmpty()
129+
|| ResourceUtils.isContainedIn(project.getLocation(), parentPaths)
130+
|| isContainedInInvisibleProject(project, parentPaths)) {
119131
String filePath = null;
120132

121133
if (match.getResource() instanceof IFile) {
@@ -149,6 +161,66 @@ public void acceptSearchMatch(SearchMatch match) {
149161
return resolutions;
150162
}
151163

164+
private List<ResolutionItem> resolveMainClassUnderProject(final String projectName) {
165+
// Limit to search main method from source code only.
166+
IJavaProject javaProject = ProjectUtils.getJavaProject(projectName);
167+
IJavaSearchScope searchScope = SearchEngine.createJavaSearchScope(javaProject == null ? new IJavaProject[0] : new IJavaProject[] {javaProject},
168+
IJavaSearchScope.REFERENCED_PROJECTS | IJavaSearchScope.SOURCES);
169+
SearchPattern pattern = SearchPattern.createPattern("main(String[]) void", IJavaSearchConstants.METHOD,
170+
IJavaSearchConstants.DECLARATIONS, SearchPattern.R_CASE_SENSITIVE | SearchPattern.R_EXACT_MATCH);
171+
final List<ResolutionItem> res = new ArrayList<>();
172+
SearchRequestor requestor = new SearchRequestor() {
173+
@Override
174+
public void acceptSearchMatch(SearchMatch match) {
175+
Object element = match.getElement();
176+
if (element instanceof IMethod) {
177+
IMethod method = (IMethod) element;
178+
try {
179+
if (method.isMainMethod()) {
180+
IResource resource = method.getResource();
181+
if (resource != null) {
182+
IProject project = resource.getProject();
183+
if (project != null) {
184+
String mainClass = method.getDeclaringType().getFullyQualifiedName();
185+
IJavaProject javaProject = JdtUtils.getJavaProject(project);
186+
if (javaProject != null) {
187+
String moduleName = JdtUtils.getModuleName(javaProject);
188+
if (moduleName != null) {
189+
mainClass = moduleName + "/" + mainClass;
190+
}
191+
}
192+
193+
String filePath = null;
194+
if (match.getResource() instanceof IFile) {
195+
try {
196+
filePath = match.getResource().getLocation().toOSString();
197+
} catch (Exception ex) {
198+
// ignore
199+
}
200+
}
201+
res.add(new ResolutionItem(mainClass, projectName, filePath));
202+
}
203+
}
204+
}
205+
} catch (JavaModelException e) {
206+
// ignore
207+
}
208+
}
209+
}
210+
};
211+
SearchEngine searchEngine = new SearchEngine();
212+
try {
213+
searchEngine.search(pattern, new SearchParticipant[] {SearchEngine.getDefaultSearchParticipant()},
214+
searchScope, requestor, null /* progress monitor */);
215+
} catch (Exception e) {
216+
logger.log(Level.SEVERE, String.format("Searching the main class failure: %s", e.toString()), e);
217+
}
218+
219+
List<ResolutionItem> resolutions = res.stream().distinct().collect(Collectors.toList());
220+
Collections.sort(resolutions);
221+
return resolutions;
222+
}
223+
152224
private boolean isContainedInInvisibleProject(IProject project, Collection<IPath> rootPaths) {
153225
if (project == null) {
154226
return false;

0 commit comments

Comments
 (0)