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
1212package com .microsoft .java .debug .plugin .internal ;
1313
1414import java .util .ArrayList ;
15+ import java .util .Arrays ;
1516import java .util .Collection ;
1617import java .util .Collections ;
1718import java .util .Comparator ;
2122import java .util .logging .Level ;
2223import java .util .logging .Logger ;
2324import java .util .stream .Collectors ;
25+ import java .util .stream .Stream ;
2426
2527import 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