diff --git a/com.microsoft.java.debug.plugin/plugin.xml b/com.microsoft.java.debug.plugin/plugin.xml index 5ab528c46..3e2e9e544 100644 --- a/com.microsoft.java.debug.plugin/plugin.xml +++ b/com.microsoft.java.debug.plugin/plugin.xml @@ -5,6 +5,7 @@ + diff --git a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JavaDebugDelegateCommandHandler.java b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JavaDebugDelegateCommandHandler.java index f563111d8..b254e8d55 100644 --- a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JavaDebugDelegateCommandHandler.java +++ b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JavaDebugDelegateCommandHandler.java @@ -26,6 +26,8 @@ public class JavaDebugDelegateCommandHandler implements IDelegateCommandHandler public static String RESOLVE_CLASSPATH = "vscode.java.resolveClasspath"; + public static String RESOLVE_MAINCLASS = "vscode.java.resolveMainClass"; + public static String BUILD_WORKSPACE = "vscode.java.buildWorkspace"; public static String CONFIG_LOG_LEVEL = "vscode.java.configLogLevel"; @@ -40,6 +42,9 @@ public Object executeCommand(String commandId, List arguments, IProgress } else if (RESOLVE_CLASSPATH.equals(commandId)) { ResolveClasspathsHandler handler = new ResolveClasspathsHandler(); return handler.resolveClasspaths(arguments); + } else if (RESOLVE_MAINCLASS.equals(commandId)) { + ResolveMainClassHandler handler = new ResolveMainClassHandler(); + return handler.resolveMainClass(); } else if (BUILD_WORKSPACE.equals(commandId)) { // TODO } else if (FETCH_USER_DATA.equals(commandId)) { diff --git a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/ResolveMainClassHandler.java b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/ResolveMainClassHandler.java new file mode 100644 index 000000000..271866633 --- /dev/null +++ b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/ResolveMainClassHandler.java @@ -0,0 +1,114 @@ +/******************************************************************************* + * Copyright (c) 2017 Microsoft 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Microsoft Corporation - initial API and implementation + *******************************************************************************/ + +package com.microsoft.java.debug.plugin.internal; + +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Logger; +import java.util.stream.Collectors; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.jdt.core.IMethod; +import org.eclipse.jdt.core.JavaModelException; +import org.eclipse.jdt.core.search.IJavaSearchConstants; +import org.eclipse.jdt.core.search.IJavaSearchScope; +import org.eclipse.jdt.core.search.SearchEngine; +import org.eclipse.jdt.core.search.SearchMatch; +import org.eclipse.jdt.core.search.SearchParticipant; +import org.eclipse.jdt.core.search.SearchPattern; +import org.eclipse.jdt.core.search.SearchRequestor; +import org.eclipse.jdt.ls.core.internal.managers.ProjectsManager; + +import com.microsoft.java.debug.core.Configuration; + +public class ResolveMainClassHandler { + private static final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME); + + /** + * resolve main class and project name. + * @return an array of main class and project name + * @throws CoreException when there are errors when resolving main class. + */ + public Object resolveMainClass() throws CoreException { + return resolveMainClassCore(); + } + + private List resolveMainClassCore() throws CoreException { + IJavaSearchScope searchScope = SearchEngine.createWorkspaceScope(); + SearchPattern pattern = SearchPattern.createPattern("main(String[]) void", IJavaSearchConstants.METHOD, + IJavaSearchConstants.DECLARATIONS, SearchPattern.R_CASE_SENSITIVE | SearchPattern.R_EXACT_MATCH); + ArrayList res = new ArrayList<>(); + SearchRequestor requestor = new SearchRequestor() { + @Override + public void acceptSearchMatch(SearchMatch match) { + Object element = match.getElement(); + if (element instanceof IMethod) { + IMethod method = (IMethod) element; + try { + if (method.isMainMethod()) { + IResource resource = method.getResource(); + if (resource != null) { + IProject project = resource.getProject(); + if (project != null) { + String mainClass = method.getDeclaringType().getFullyQualifiedName(); + String projectName = ProjectsManager.DEFAULT_PROJECT_NAME.equals(project.getName()) ? null : project.getName(); + res.add(new ResolutionItem(mainClass, projectName)); + } + } + } + } catch (JavaModelException e) { + // ignore + } + } + } + }; + SearchEngine searchEngine = new SearchEngine(); + searchEngine.search(pattern, new SearchParticipant[] {SearchEngine.getDefaultSearchParticipant()}, + searchScope, requestor, null /* progress monitor */); + return res.stream().distinct().collect(Collectors.toList()); + } + + private class ResolutionItem { + private String mainClass; + private String projectName; + + public ResolutionItem(String mainClass, String projectName) { + this.mainClass = mainClass; + this.projectName = projectName; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o instanceof ResolutionItem) { + ResolutionItem item = (ResolutionItem) o; + if (mainClass != null ? !mainClass.equals(item.mainClass) : item.mainClass != null) { + return false; + } + if (projectName != null ? !projectName.equals(item.projectName) : item.projectName != null) { + return false; + } + return true; + } + return false; + } + + @Override + public int hashCode() { + return (mainClass == null ? 0 : mainClass.hashCode()) * 13 + (projectName == null ? 0 : projectName.hashCode()); + } + } +}