Skip to content

Commit

Permalink
Fix surround tag in empty document
Browse files Browse the repository at this point in the history
- Fill in grammar when invoking surround tag in an empty document
- Fix NPE that prevented surround tags from working
  in empty documents that are linked to a grammar with
  file association

Closes eclipse#1395

Signed-off-by: David Thompson <[email protected]>
  • Loading branch information
datho7561 committed Dec 8, 2022
1 parent 13f2fb4 commit fb7ed0f
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@

/**
* XML Command "xml.refactor.surround.with" to support surround:
*
*
* <ul>
* <li>Surround with Tags (Wrap)</li>
* <li>Surround with Comments</li>
Expand Down Expand Up @@ -93,7 +93,7 @@ protected Object executeCommand(DOMDocument document, ExecuteCommandParams param
Range selection = ArgumentsUtils.getArgAt(params, 1, Range.class);
SurroundWithKind kind = SurroundWithKind.get(ArgumentsUtils.getArgAt(params, 2, String.class));
boolean snippetsSupported = ArgumentsUtils.getArgAt(params, 3, Boolean.class);

// Surround process
boolean emptySelection = selection.getStart().equals(selection.getEnd());
StringBuilder startText = null;
Expand Down Expand Up @@ -160,10 +160,23 @@ protected Object executeCommand(DOMDocument document, ExecuteCommandParams param
}

private List<String> getTags(DOMNode node, String prefix, int offset) {
DOMElement parentElement = node.isElement() ? (DOMElement) node : node.getParentElement();
Collection<CMDocument> cmDocuments = parentElement != null ? contentModelManager.findCMDocument(parentElement)
: contentModelManager.findCMDocument(node.getOwnerDocument(), null);
Collection<CMDocument> cmDocuments;
DOMElement parentElement;
if (node.isOwnerDocument()) {
parentElement = null;
cmDocuments = contentModelManager.findCMDocument((DOMDocument) node, null);
} else {
parentElement = node.isElement() ? (DOMElement) node : node.getParentElement();
cmDocuments = parentElement != null ? contentModelManager.findCMDocument(parentElement)
: contentModelManager.findCMDocument(node.getOwnerDocument(), null);
}
for (CMDocument cmDocument : cmDocuments) {
if (parentElement == null) {
return cmDocument.getElements().stream() //
.map(decl -> decl.getName(prefix)) //
.sorted() //
.collect(Collectors.toList());
}
CMElementDeclaration elementDeclaration = cmDocument.findCMElement(parentElement);
if (elementDeclaration != null) {
return elementDeclaration.getPossibleElements(parentElement, offset)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,17 @@

import java.util.Arrays;
import java.util.concurrent.ExecutionException;
import java.util.function.Consumer;

import org.eclipse.lemminx.MockXMLLanguageServer;
import org.eclipse.lemminx.commons.BadLocationException;
import org.eclipse.lemminx.commons.TextDocument;
import org.eclipse.lemminx.extensions.contentmodel.BaseFileTempTest;
import org.eclipse.lemminx.extensions.contentmodel.commands.SurroundWithCommand.SurroundWithKind;
import org.eclipse.lemminx.extensions.contentmodel.commands.SurroundWithCommand.SurroundWithResponse;
import org.eclipse.lemminx.extensions.contentmodel.model.ContentModelManager;
import org.eclipse.lemminx.extensions.contentmodel.settings.XMLFileAssociation;
import org.eclipse.lemminx.services.XMLLanguageService;
import org.eclipse.lemminx.services.format.TextEditUtils;
import org.eclipse.lsp4j.Position;
import org.eclipse.lsp4j.Range;
Expand Down Expand Up @@ -94,6 +98,31 @@ public void surroundElementWithTagsWithRelaxNG() throws Exception {
assertSurroundWith(xml, SurroundWithKind.tags, true, expected);
}

@Test
public void createElementAtRootWithRelaxNG() throws Exception {
String xml = "<?xml-model href=\"relaxng/tei_all.rng\" ?>\r\n" + //
"||\r\n";
String expected = "<?xml-model href=\"relaxng/tei_all.rng\" ?>\r\n" + //
"<${1|TEI,teiCorpus|}>$2</${1:TEI}>$0\r\n";
assertSurroundWith(xml, SurroundWithKind.tags, true, expected);
}

@Test
public void createElementAtRootWithFileAssociation() throws Exception {

Consumer<XMLLanguageService> configuration = ls -> {
ls.initializeIfNeeded();
ContentModelManager contentModelManager = ls.getComponent(ContentModelManager.class);
// Use root URI which ends with slash
contentModelManager.setRootURI("src/test/resources/xsd");
contentModelManager.setFileAssociations(createXSDAssociationsNoNamespaceSchemaLocationLike(""));
};

String xml = "||\r\n";
String expected = "<${1|resources|}>$2</${1:resources}>$0\r\n";
assertSurroundWith(xml, SurroundWithKind.tags, true, configuration, "file:///test/resources.xml", expected);
}

// --------------- Surround with Comments

@Test
Expand All @@ -120,10 +149,20 @@ public void surroundTextWithCDATA() throws Exception {
assertSurroundWith(xml, SurroundWithKind.cdata, true, expected);
}


// --------------- Helper functions

private static void assertSurroundWith(String xml, SurroundWithKind kind, boolean snippetsSupported,
String expected) throws BadLocationException, InterruptedException, ExecutionException {
assertSurroundWith(xml, kind, snippetsSupported, (a) -> {}, "src/test/resources/test.xml", expected);
}

private static void assertSurroundWith(String xml, SurroundWithKind kind, boolean snippetsSupported, Consumer<XMLLanguageService> configuration, String uri,
String expected) throws BadLocationException, InterruptedException, ExecutionException {
MockXMLLanguageServer languageServer = new MockXMLLanguageServer();

configuration.accept(languageServer.getXMLLanguageService());

int rangeStart = xml.indexOf('|');
int rangeEnd = xml.lastIndexOf('|');
// remove '|'
Expand All @@ -134,7 +173,7 @@ private static void assertSurroundWith(String xml, SurroundWithKind kind, boolea
Position endPos = document.positionAt(rangeEnd - 1);
Range selection = new Range(startPos, endPos);

TextDocumentIdentifier xmlIdentifier = languageServer.didOpen("src/test/resources/test.xml", xml);
TextDocumentIdentifier xmlIdentifier = languageServer.didOpen(uri, xml);

// Execute surround with tags command
SurroundWithResponse response = (SurroundWithResponse) languageServer
Expand All @@ -145,4 +184,11 @@ private static void assertSurroundWith(String xml, SurroundWithKind kind, boolea
String actual = TextEditUtils.applyEdits(document, Arrays.asList(response.getStart(), response.getEnd()));
assertEquals(expected, actual);
}

private static XMLFileAssociation[] createXSDAssociationsNoNamespaceSchemaLocationLike(String baseSystemId) {
XMLFileAssociation resources = new XMLFileAssociation();
resources.setPattern("**/*resources*.xml");
resources.setSystemId(baseSystemId + "resources.xsd");
return new XMLFileAssociation[] { resources };
}
}

0 comments on commit fb7ed0f

Please sign in to comment.