Skip to content

Commit

Permalink
CodeLens, References, Rename support for XML references
Browse files Browse the repository at this point in the history
Signed-off-by: azerr <azerr@redhat.com>
  • Loading branch information
angelozerr committed Jan 11, 2023
1 parent 1663001 commit fa8f51b
Show file tree
Hide file tree
Showing 47 changed files with 3,048 additions and 848 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,10 @@
import org.eclipse.lsp4j.LinkedEditingRanges;
import org.eclipse.lsp4j.Location;
import org.eclipse.lsp4j.LocationLink;
import org.eclipse.lsp4j.PrepareRenameParams;
import org.eclipse.lsp4j.PrepareRenameResult;
import org.eclipse.lsp4j.PublishDiagnosticsParams;
import org.eclipse.lsp4j.Range;
import org.eclipse.lsp4j.ReferenceParams;
import org.eclipse.lsp4j.RenameParams;
import org.eclipse.lsp4j.SelectionRange;
Expand Down Expand Up @@ -349,10 +352,18 @@ public CompletableFuture<List<? extends TextEdit>> rangeFormatting(DocumentRange
});
}

@Override
public CompletableFuture<Either<Range, PrepareRenameResult>> prepareRename(PrepareRenameParams params) {
return computeDOMAsync(params.getTextDocument(), (xmlDocument, cancelChecker) -> {
return getXMLLanguageService().prepareRename(xmlDocument, params.getPosition(), cancelChecker);
});
}

@Override
public CompletableFuture<WorkspaceEdit> rename(RenameParams params) {
return computeDOMAsync(params.getTextDocument(), (xmlDocument, cancelChecker) -> {
return getXMLLanguageService().doRename(xmlDocument, params.getPosition(), params.getNewName());
return getXMLLanguageService().doRename(xmlDocument, params.getPosition(), params.getNewName(),
cancelChecker);
});
}

Expand Down Expand Up @@ -563,14 +574,14 @@ public CompletableFuture<List<ColorInformation>> documentColor(DocumentColorPara
return getXMLLanguageService().findDocumentColors(xmlDocument, cancelChecker);
});
}

@Override
public CompletableFuture<List<ColorPresentation>> colorPresentation(ColorPresentationParams params) {
return computeDOMAsync(params.getTextDocument(), (xmlDocument, cancelChecker) -> {
return getXMLLanguageService().getColorPresentations(xmlDocument, params, cancelChecker);
});
}

@Override
public void didSave(DidSaveTextDocumentParams params) {
computeAsync((monitor) -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -631,15 +631,6 @@ public DOMText findTextAt(int offset) {
text.parent = this;
return text;
}
DOMNode node = super.findNodeAt(offset);
if (node != null) {
if (node.isText()) {
return (DOMText) node;
}
if (node.isElement() && node != this) {
return ((DOMElement) node).findTextAt(offset);
}
}
return null;
return findTextAt(this, offset);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,17 @@ public static DOMAttr findAttrAt(DOMNode node, int offset) {
return null;
}

public static DOMText findTextAt(DOMNode node, int offset) {
if (node != null && node.hasChildNodes()) {
for (DOMNode child : node.getChildren()) {
if (child.isText() && isIncluded(child, offset)) {
return (DOMText) child;
}
}
}
return null;
}

public static DOMNode findNodeOrAttrAt(DOMDocument document, int offset) {
DOMNode node = document.findNodeAt(offset);
if (node != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,22 @@
*******************************************************************************/
package org.eclipse.lemminx.extensions.references;

import org.eclipse.lemminx.extensions.references.participants.XMLReferencesCodeLensParticipant;
import org.eclipse.lemminx.extensions.references.participants.XMLReferencesCompletionParticipant;
import org.eclipse.lemminx.extensions.references.participants.XMLReferencesDefinitionParticipant;
import org.eclipse.lemminx.extensions.references.participants.XMLReferencesHighlightingParticipant;
import org.eclipse.lemminx.extensions.references.participants.XMLReferencesLinkedEditingRangesParticipant;
import org.eclipse.lemminx.extensions.references.participants.XMLReferencesReferenceParticipant;
import org.eclipse.lemminx.extensions.references.participants.XMLReferencesRenameParticipant;
import org.eclipse.lemminx.extensions.references.settings.XMLReferencesSettings;
import org.eclipse.lemminx.services.extensions.IDefinitionParticipant;
import org.eclipse.lemminx.services.extensions.IHighlightingParticipant;
import org.eclipse.lemminx.services.extensions.ILinkedEditingRangesParticipant;
import org.eclipse.lemminx.services.extensions.IReferenceParticipant;
import org.eclipse.lemminx.services.extensions.IRenameParticipant;
import org.eclipse.lemminx.services.extensions.IXMLExtension;
import org.eclipse.lemminx.services.extensions.XMLExtensionsRegistry;
import org.eclipse.lemminx.services.extensions.codelens.ICodeLensParticipant;
import org.eclipse.lemminx.services.extensions.completion.ICompletionParticipant;
import org.eclipse.lemminx.services.extensions.save.ISaveContext;
import org.eclipse.lsp4j.InitializeParams;
Expand Down Expand Up @@ -66,14 +74,22 @@ public class XMLReferencesPlugin implements IXMLExtension {

private final ICompletionParticipant completionParticipant;
private final IDefinitionParticipant definitionParticipant;
private final IReferenceParticipant referenceParticipant;
private final ICodeLensParticipant codeLensParticipant;
private final IHighlightingParticipant highlightingParticipant;
private final IRenameParticipant renameParticipant;
private final ILinkedEditingRangesParticipant linkedEditingRangesParticipant;

private XMLReferencesSettings referencesSettings;

public XMLReferencesPlugin() {
completionParticipant = new XMLReferencesCompletionParticipant(this);
definitionParticipant = new XMLReferencesDefinitionParticipant(this);
referenceParticipant = new XMLReferencesReferenceParticipant(this);
codeLensParticipant = new XMLReferencesCodeLensParticipant(this);
highlightingParticipant = new XMLReferencesHighlightingParticipant(this);
renameParticipant = new XMLReferencesRenameParticipant(this);
linkedEditingRangesParticipant = new XMLReferencesLinkedEditingRangesParticipant(this);
}

@Override
Expand All @@ -99,14 +115,22 @@ private void updateSettings(XMLReferencesSettings settings, ISaveContext context
public void start(InitializeParams params, XMLExtensionsRegistry registry) {
registry.registerCompletionParticipant(completionParticipant);
registry.registerDefinitionParticipant(definitionParticipant);
registry.registerReferenceParticipant(referenceParticipant);
registry.registerCodeLensParticipant(codeLensParticipant);
registry.registerHighlightingParticipant(highlightingParticipant);
registry.registerRenameParticipant(renameParticipant);
registry.registerLinkedEditingRangesParticipants(linkedEditingRangesParticipant);
}

@Override
public void stop(XMLExtensionsRegistry registry) {
registry.unregisterCompletionParticipant(completionParticipant);
registry.unregisterDefinitionParticipant(definitionParticipant);
registry.unregisterReferenceParticipant(referenceParticipant);
registry.unregisterCodeLensParticipant(codeLensParticipant);
registry.unregisterHighlightingParticipant(highlightingParticipant);
registry.unregisterRenameParticipant(renameParticipant);
registry.unregisterLinkedEditingRangesParticipants(linkedEditingRangesParticipant);
}

public XMLReferencesSettings getReferencesSettings() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
/*******************************************************************************
* Copyright (c) 2023 Red Hat Inc. and others.
* All rights reserved. This program and the accompanying materials
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v20.html
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat Inc. - initial API and implementation
*******************************************************************************/
package org.eclipse.lemminx.extensions.references.participants;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.lemminx.client.CodeLensKind;
import org.eclipse.lemminx.dom.DOMAttr;
import org.eclipse.lemminx.dom.DOMDocument;
import org.eclipse.lemminx.dom.DOMElement;
import org.eclipse.lemminx.dom.DOMNode;
import org.eclipse.lemminx.extensions.references.XMLReferencesPlugin;
import org.eclipse.lemminx.extensions.references.search.SearchEngine;
import org.eclipse.lemminx.extensions.references.search.SearchNode;
import org.eclipse.lemminx.extensions.references.search.SearchQuery;
import org.eclipse.lemminx.extensions.references.search.SearchQuery.Direction;
import org.eclipse.lemminx.extensions.references.search.SearchQueryFactory;
import org.eclipse.lemminx.extensions.references.settings.XMLReferenceExpression;
import org.eclipse.lemminx.services.extensions.codelens.ICodeLensParticipant;
import org.eclipse.lemminx.services.extensions.codelens.ICodeLensRequest;
import org.eclipse.lemminx.services.extensions.codelens.ReferenceCommand;
import org.eclipse.lemminx.utils.XMLPositionUtility;
import org.eclipse.lsp4j.CodeLens;
import org.eclipse.lsp4j.Range;
import org.eclipse.lsp4j.jsonrpc.CancelChecker;

/**
* XML references codelens support.
*
*/
public class XMLReferencesCodeLensParticipant implements ICodeLensParticipant {

private static class Link {

public final List<SearchNode> froms;
public final List<SearchNode> tos;

public Link() {
froms = new ArrayList<>();
tos = new ArrayList<>();
}

public void addTo(SearchNode to) {
tos.add(to);
}

public void addFrom(SearchNode from) {
froms.add(from);
}
}

private final XMLReferencesPlugin plugin;

public XMLReferencesCodeLensParticipant(XMLReferencesPlugin plugin) {
this.plugin = plugin;
}

@Override
public void doCodeLens(ICodeLensRequest request, List<CodeLens> lenses, CancelChecker cancelChecker) {
DOMDocument document = request.getDocument();
SearchQuery query = SearchQueryFactory.createQuery(document,
plugin.getReferencesSettings(), Direction.BOTH);
if (query != null) {
final Map<XMLReferenceExpression, Link> linksMap = new HashMap<>();
SearchEngine.getInstance().search(query,
(fromSearchNode, toSearchNode, expression) -> {
Link link = linksMap.get(expression);
if (link == null) {
link = new Link();
linksMap.put(expression, link);
}
if (fromSearchNode != null) {
link.addFrom(fromSearchNode);
}
if (toSearchNode != null) {
link.addTo(toSearchNode);
}
}, cancelChecker);
if (!linksMap.isEmpty()) {
boolean supportedByClient = request.isSupportedByClient(CodeLensKind.References);
Map<DOMElement, CodeLens> cache = new HashMap<>();
Collection<Link> links = linksMap.values();
for (Link link : links) {
for (SearchNode to : link.tos) {
// Increment references count Codelens for the given target element
DOMNode toNode = to.getNode();
DOMElement toElement = toNode.isAttribute() ? ((DOMAttr) toNode).getOwnerElement()
: toNode.getParentElement();
if (toElement != null) {
for (SearchNode from : link.froms) {
if (from.matchesValue(to)) {

CodeLens codeLens = cache.get(toElement);
if (codeLens == null) {
Range range = XMLPositionUtility.createRange(toNode);
codeLens = new CodeLens(range);
codeLens.setCommand(
new ReferenceCommand(document.getDocumentURI(), range.getStart(),
supportedByClient));
cache.put(toElement, codeLens);
lenses.add(codeLens);
} else {
((ReferenceCommand) codeLens.getCommand()).increment();
}

}
}
}
}
}
}
}
}

}
Loading

0 comments on commit fa8f51b

Please sign in to comment.