Java tutorial
/******************************************************************************* * Copyright (c) 2016 Red Hat Inc. 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: * Red Hat Inc. - initial API and implementation *******************************************************************************/ package org.jboss.tools.vscode.java.internal.handlers; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.ISourceRange; import org.eclipse.jdt.core.ISourceReference; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.JavaCore; 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.jboss.tools.langs.CodeLens; import org.jboss.tools.langs.CodeLensParams; import org.jboss.tools.langs.Command; import org.jboss.tools.langs.Location; import org.jboss.tools.langs.base.LSPMethods; import org.jboss.tools.vscode.internal.ipc.RequestHandler; import org.jboss.tools.vscode.java.internal.JDTUtils; import org.jboss.tools.vscode.java.internal.JavaLanguageServerPlugin; public class CodeLensHandler { public class CodeLensProvider implements RequestHandler<CodeLensParams, List<CodeLens>> { @Override public boolean canHandle(String request) { return LSPMethods.DOCUMENT_CODELENS.getMethod().equals(request); } @Override public List<CodeLens> handle(CodeLensParams param) { ICompilationUnit unit = JDTUtils.resolveCompilationUnit(param.getTextDocument().getUri()); return getCodeLensSymbols(unit); } } public class CodeLensResolver implements RequestHandler<CodeLens, CodeLens> { @Override public boolean canHandle(String request) { return LSPMethods.CODELENS_RESOLVE.getMethod().equals(request); } @Override public CodeLens handle(CodeLens param) { return resolve(param); } } @SuppressWarnings("unchecked") private CodeLens resolve(CodeLens lens) { try { List<Object> data = (List<Object>) lens.getData(); String uri = (String) data.get(0); Map<String, Object> position = (Map<String, Object>) data.get(1); ICompilationUnit unit = JDTUtils.resolveCompilationUnit(uri); IJavaElement element = findElementAtSelection(unit, ((Double) position.get("line")).intValue(), ((Double) position.get("character")).intValue()); List<Location> locations = findReferences(element); int nReferences = locations.size(); lens.setCommand(new Command().withTitle(nReferences == 1 ? "1 reference" : nReferences + " references") .withCommand("java.show.references").withArguments(Arrays.asList(uri, position, locations))); } catch (CoreException e) { JavaLanguageServerPlugin.logException("Problem resolving code lens", e); } return lens; } private IJavaElement findElementAtSelection(ICompilationUnit unit, int line, int column) throws JavaModelException { IJavaElement[] elements = unit.codeSelect(JsonRpcHelpers.toOffset(unit.getBuffer(), line, column), 0); if (elements == null || elements.length != 1) return null; return elements[0]; } private List<Location> findReferences(IJavaElement element) throws JavaModelException, CoreException { SearchPattern pattern = SearchPattern.createPattern(element, IJavaSearchConstants.REFERENCES); final List<Location> result = new ArrayList<>(); SearchEngine engine = new SearchEngine(); engine.search(pattern, new SearchParticipant[] { SearchEngine.getDefaultSearchParticipant() }, createSearchScope(), new SearchRequestor() { @Override public void acceptSearchMatch(SearchMatch match) throws CoreException { Object o = match.getElement(); if (o instanceof IJavaElement) { IJavaElement element = (IJavaElement) o; ICompilationUnit compilationUnit = (ICompilationUnit) element .getAncestor(IJavaElement.COMPILATION_UNIT); if (compilationUnit == null) { return; } Location location = JDTUtils.toLocation(compilationUnit, match.getOffset(), match.getLength()); result.add(location); } } }, new NullProgressMonitor()); return result; } private List<CodeLens> getCodeLensSymbols(ICompilationUnit unit) { if (unit == null) return Collections.emptyList(); try { IJavaElement[] elements = unit.getChildren(); ArrayList<CodeLens> lenses = new ArrayList<>(elements.length); collectChildren(unit, elements, lenses); return lenses; } catch (JavaModelException e) { JavaLanguageServerPlugin.logException("Problem getting code lenses for" + unit.getElementName(), e); } return Collections.emptyList(); } private void collectChildren(ICompilationUnit unit, IJavaElement[] elements, ArrayList<CodeLens> lenses) throws JavaModelException { for (IJavaElement element : elements) { if (element.getElementType() == IJavaElement.TYPE) { collectChildren(unit, ((IType) element).getChildren(), lenses); } else if (element.getElementType() != IJavaElement.METHOD) { continue; } CodeLens lens = new CodeLens(); ISourceRange r = ((ISourceReference) element).getNameRange(); final org.jboss.tools.langs.Range range = JDTUtils.toRange(unit, r.getOffset(), r.getLength()); lens.setRange(range); lens.setData(Arrays.asList(JDTUtils.getFileURI(unit), range.getStart())); lenses.add(lens); } } private IJavaSearchScope createSearchScope() throws JavaModelException { IJavaProject[] projects = JavaCore.create(ResourcesPlugin.getWorkspace().getRoot()).getJavaProjects(); return SearchEngine.createJavaSearchScope(projects, IJavaSearchScope.SOURCES); } }