Skip to content

Commit

Permalink
XSI Nil completion
Browse files Browse the repository at this point in the history
Fixes eclipse-lemminx#247

Signed-off-by: Nikolas Komonen <[email protected]>
  • Loading branch information
NikolasKomonen committed Mar 13, 2019
1 parent 4797365 commit 190d6d4
Show file tree
Hide file tree
Showing 24 changed files with 360 additions and 75 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,15 @@
import org.eclipse.lsp4j.CompletionItem;
import org.eclipse.lsp4j.CompletionList;
import org.eclipse.lsp4j.Position;
import org.eclipse.lsp4xml.XMLTextDocumentService;
import org.eclipse.lsp4xml.commons.BadLocationException;
import org.eclipse.lsp4xml.commons.TextDocument;
import org.eclipse.lsp4xml.dom.DOMDocument;
import org.eclipse.lsp4xml.dom.DOMParser;
import org.eclipse.lsp4xml.services.XMLLanguageService;
import org.eclipse.lsp4xml.services.extensions.CompletionSettings;
import org.eclipse.lsp4xml.services.extensions.ICompletionParticipant;
import org.eclipse.lsp4xml.settings.SharedSettings;
import org.eclipse.lsp4xml.settings.XMLFormattingOptions;
import org.junit.Assert;
import org.junit.Test;
Expand Down Expand Up @@ -62,8 +64,11 @@ private static void testCompletionFor(String value, List<ItemDescription> expect
DOMDocument htmlDoc = DOMParser.getInstance().parse(document, null);

XMLLanguageService xmlLanguageService = new XMLLanguageService();
CompletionList list = xmlLanguageService.doComplete(htmlDoc, position, new CompletionSettings(),
new XMLFormattingOptions(4, false));

SharedSettings sharedSettings = new SharedSettings();
sharedSettings.setFormattingSettings(new XMLFormattingOptions(4, false));

CompletionList list = xmlLanguageService.doComplete(htmlDoc, position, sharedSettings);

// no duplicate labels
List<String> labels = list.getItems().stream().map(i -> i.getLabel()).sorted().collect(Collectors.toList());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
import org.eclipse.lsp4xml.services.XMLLanguageService;
import org.eclipse.lsp4xml.services.extensions.CompletionSettings;
import org.eclipse.lsp4xml.services.extensions.save.AbstractSaveContext;
import org.eclipse.lsp4xml.settings.SharedSettings;
import org.eclipse.lsp4xml.settings.XMLFormattingOptions;

/**
Expand All @@ -82,10 +83,7 @@ public class XMLTextDocumentService implements TextDocumentService {
private final XMLLanguageServer xmlLanguageServer;
private final TextDocuments documents;
private final LanguageModelCache<DOMDocument> xmlDocuments;
private final CompletionSettings sharedCompletionSettings;
private final FoldingRangeCapabilities sharedFoldingsSettings;
private XMLFormattingOptions sharedFormattingSettings;
private XMLValidationSettings sharedValidationSettings;
private SharedSettings sharedSettings;

class BasicCancelChecker implements CancelChecker {

Expand Down Expand Up @@ -154,18 +152,15 @@ public XMLTextDocumentService(XMLLanguageServer xmlLanguageServer) {
this.xmlDocuments = new LanguageModelCache<DOMDocument>(10, 60, documents, document -> {
return parser.parse(document, getXMLLanguageService().getResolverExtensionManager());
});
this.sharedCompletionSettings = new CompletionSettings();
this.sharedFoldingsSettings = new FoldingRangeCapabilities();
this.sharedFormattingSettings = new XMLFormattingOptions(true); // to be sure that formattings options is not
// null.
this.sharedValidationSettings = new XMLValidationSettings();

this.sharedSettings = new SharedSettings();
}

public void updateClientCapabilities(ClientCapabilities capabilities) {
TextDocumentClientCapabilities textDocumentClientCapabilities = capabilities.getTextDocument();
if (textDocumentClientCapabilities != null) {
// Completion settings
sharedCompletionSettings.setCapabilities(textDocumentClientCapabilities.getCompletion());
sharedSettings.completionSettings.setCapabilities(textDocumentClientCapabilities.getCompletion());
codeActionLiteralSupport = textDocumentClientCapabilities.getCodeAction() != null
&& textDocumentClientCapabilities.getCodeAction().getCodeActionLiteralSupport() != null;
hierarchicalDocumentSymbolSupport = textDocumentClientCapabilities.getDocumentSymbol() != null
Expand All @@ -189,7 +184,7 @@ public CompletableFuture<Either<List<CompletionItem>, CompletionList>> completio
TextDocument document = getDocument(uri);
DOMDocument xmlDocument = getXMLDocument(document);
CompletionList list = getXMLLanguageService().doComplete(xmlDocument, params.getPosition(),
sharedCompletionSettings, getFormattingSettings(uri));
sharedSettings);
return Either.forRight(list);
});
}
Expand All @@ -206,7 +201,7 @@ public CompletableFuture<Hover> hover(TextDocumentPositionParams params) {
private XMLFormattingOptions getFormattingSettings(String uri) {
// TODO: manage formattings per document URI (to support .editorconfig for
// instance).
return sharedFormattingSettings;
return sharedSettings.formattingSettings;
}

@Override
Expand Down Expand Up @@ -299,7 +294,7 @@ public void didClose(DidCloseTextDocumentParams params) {
public CompletableFuture<List<FoldingRange>> foldingRange(FoldingRangeRequestParams params) {
return computeAsync((monitor) -> {
TextDocument document = getDocument(params.getTextDocument().getUri());
return getXMLLanguageService().getFoldingRanges(document, sharedFoldingsSettings);
return getXMLLanguageService().getFoldingRanges(document, sharedSettings.foldingSettings);
});
}

Expand Down Expand Up @@ -420,43 +415,37 @@ private void doTriggerValidation(String uri, int version, CancelChecker monitor)
DOMDocument xmlDocument = getXMLDocument(currDocument);
getXMLLanguageService().publishDiagnostics(xmlDocument,
params -> xmlLanguageServer.getLanguageClient().publishDiagnostics(params),
(u, v) -> triggerValidation(u, v), monitor, sharedValidationSettings);
(u, v) -> triggerValidation(u, v), monitor, sharedSettings.validationSettings);
}
}

private XMLLanguageService getXMLLanguageService() {
return xmlLanguageServer.getXMLLanguageService();
}

public void setSharedFormattingSettings(XMLFormattingOptions formattingOptions) {
this.sharedFormattingSettings = formattingOptions;
}

public void updateCompletionSettings(CompletionSettings newCompletion) {
sharedCompletionSettings.setAutoCloseTags(newCompletion.isAutoCloseTags());
sharedSettings.completionSettings.setAutoCloseTags(newCompletion.isAutoCloseTags());
}

public boolean isIncrementalSupport() {
return documents.isIncremental();
}

public XMLFormattingOptions getSharedFormattingSettings() {
return this.sharedFormattingSettings;
return sharedSettings.formattingSettings;
}

public void setIncrementalSupport(boolean incrementalSupport) {
this.documents.setIncremental(incrementalSupport);
}

public void setValidationSettings(XMLValidationSettings settings) {
this.sharedValidationSettings = settings;
public XMLValidationSettings getValidationSettings() {

return sharedSettings.validationSettings;
}

public XMLValidationSettings getValidationSettings() {
if(sharedValidationSettings == null) {
sharedValidationSettings = new XMLValidationSettings();
}
return sharedValidationSettings;
public SharedSettings getSharedSettings() {
return this.sharedSettings;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,22 @@ private static <T> int findFirst(List<T> array, Function<T, Boolean> p) {
}

public DOMAttr getAttributeNode(String name) {
return getAttributeNode(null, name);
}

/**
* Returns the attribute that matches the given name.
*
* If there is no namespace, set prefix to null.
*/
public DOMAttr getAttributeNode(String prefix, String suffix) {
StringBuilder sb = new StringBuilder();
if(prefix != null) {
sb.append(prefix);
sb.append(":");
}
sb.append(suffix);
String name = sb.toString();
if (!hasAttributes()) {
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import org.eclipse.lsp4xml.services.extensions.CompletionParticipantAdapter;
import org.eclipse.lsp4xml.services.extensions.ICompletionRequest;
import org.eclipse.lsp4xml.services.extensions.ICompletionResponse;
import org.eclipse.lsp4xml.settings.SharedSettings;
import org.eclipse.lsp4xml.uriresolver.CacheResourceDownloadingException;

/**
Expand Down Expand Up @@ -115,10 +116,6 @@ private void fillWithChildrenElementDeclaration(DOMElement element, Collection<C
@Override
public void onAttributeName(boolean generateValue, Range fullRange, ICompletionRequest request,
ICompletionResponse response) throws Exception {
if (request.getXMLDocument().hasSchemaInstancePrefix()) {
XSISchemaModel.computeCompletionResponses(request, response, fullRange, request.getXMLDocument(),
generateValue);
}
// otherwise, manage completion based on XML Schema, DTD.
DOMElement parentElement = request.getNode().isElement() ? (DOMElement) request.getNode() : null;
if (parentElement == null) {
Expand Down Expand Up @@ -166,7 +163,7 @@ private void fillAttributesWithCMAttributeDeclarations(DOMElement parentElement,

@Override
public void onAttributeValue(String valuePrefix, Range fullRange, boolean addQuotes, ICompletionRequest request,
ICompletionResponse response) throws Exception {
ICompletionResponse response, SharedSettings settings) throws Exception {
DOMElement parentElement = request.getNode().isElement() ? (DOMElement) request.getNode() : null;
if (parentElement == null) {
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,11 @@ private int generate(Collection<CMAttributeDeclaration> attributes, int level, i
return snippetIndex;
}

/**
* Creates the string value for a CompletionItem TextEdit
*
* Can create an enumerated TextEdit if given a collection of values.
*/
public static String generateAttributeValue(String defaultValue, Collection<String> enumerationValues,
boolean canSupportSnippets, int snippetIndex, boolean withQuote) {
StringBuilder value = new StringBuilder();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/**
* Copyright (c) 2019 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 v2.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v20.html
*
* Contributors:
* Red Hat Inc. - initial API and implementation
*/

package org.eclipse.lsp4xml.extensions.xsi;

import org.eclipse.lsp4j.Range;
import org.eclipse.lsp4xml.services.XSISchemaModel;
import org.eclipse.lsp4xml.services.extensions.CompletionParticipantAdapter;
import org.eclipse.lsp4xml.services.extensions.ICompletionRequest;
import org.eclipse.lsp4xml.services.extensions.ICompletionResponse;
import org.eclipse.lsp4xml.settings.SharedSettings;

/**
* XSICompletionParticipant
*/
public class XSICompletionParticipant extends CompletionParticipantAdapter {

@Override
public void onAttributeName(boolean generateValue, Range fullRange, ICompletionRequest request,
ICompletionResponse response) throws Exception {
if (request.getXMLDocument().hasSchemaInstancePrefix()) {
XSISchemaModel.computeCompletionResponses(request, response, fullRange, request.getXMLDocument(),
generateValue);
}
}

@Override
public void onAttributeValue(String valuePrefix, Range fullRange, boolean addQuotes, ICompletionRequest request,
ICompletionResponse response, SharedSettings settings) throws Exception {
XSISchemaModel.computeValueCompletionResponses(request, response, fullRange, request.getXMLDocument(), settings);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/**
* Copyright (c) 2019 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 v2.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v20.html
*
* Contributors:
* Red Hat Inc. - initial API and implementation
*/

package org.eclipse.lsp4xml.extensions.xsi;

import org.eclipse.lsp4j.InitializeParams;
import org.eclipse.lsp4xml.services.extensions.ICompletionParticipant;
import org.eclipse.lsp4xml.services.extensions.IXMLExtension;
import org.eclipse.lsp4xml.services.extensions.XMLExtensionsRegistry;
import org.eclipse.lsp4xml.services.extensions.save.ISaveContext;

/**
* Plugin to handle `xsi` attributes or a namespace with the value of:
* "http://www.w3.org/2001/XMLSchema-instance"
*
* Loaded by service loader in 'resources' folder.
*/
public class XSISchemaPlugin implements IXMLExtension {

ICompletionParticipant completionParticipant = new XSICompletionParticipant();

@Override
public void start(InitializeParams params, XMLExtensionsRegistry registry) {
registry.registerCompletionParticipant(completionParticipant);
}

@Override
public void stop(XMLExtensionsRegistry registry) {
registry.unregisterCompletionParticipant(completionParticipant);
}

@Override
public void doSave(ISaveContext context) {

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import org.eclipse.lsp4xml.services.extensions.CompletionSettings;
import org.eclipse.lsp4xml.services.extensions.ICompletionRequest;
import org.eclipse.lsp4xml.services.extensions.XMLExtensionsRegistry;
import org.eclipse.lsp4xml.settings.SharedSettings;
import org.eclipse.lsp4xml.settings.XMLFormattingOptions;

/**
Expand All @@ -39,12 +40,11 @@ class CompletionRequest extends AbstractPositionRequest implements ICompletionRe

private boolean hasOpenBracket;

public CompletionRequest(DOMDocument xmlDocument, Position position, CompletionSettings completionSettings,
XMLFormattingOptions formattingSettings, XMLExtensionsRegistry extensionsRegistry)
public CompletionRequest(DOMDocument xmlDocument, Position position, SharedSettings settings, XMLExtensionsRegistry extensionsRegistry)
throws BadLocationException {
super(xmlDocument, position);
this.formattingSettings = formattingSettings;
this.completionSettings = completionSettings;
this.formattingSettings = settings.formattingSettings;
this.completionSettings = settings.completionSettings;
this.extensionsRegistry = extensionsRegistry;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ public void addCompletionAttribute(CompletionItem completionItem) {
if (seenAttributes == null) {
seenAttributes = new ArrayList<>();
}
// TODO: Add quotations to the completion item.
seenAttributes.add(completionItem.getLabel());
addCompletionItem(completionItem);
}
Expand Down
Loading

0 comments on commit 190d6d4

Please sign in to comment.