Skip to content

Commit

Permalink
XSI attribute completion
Browse files Browse the repository at this point in the history
Fixes eclipse#163

Signed-off-by: Nikolas Komonen <[email protected]>
  • Loading branch information
NikolasKomonen committed Nov 7, 2018
1 parent 803d0b7 commit ff066df
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import org.eclipse.lsp4j.TextEdit;
import org.eclipse.lsp4xml.commons.BadLocationException;
import org.eclipse.lsp4xml.dom.Element;
import org.eclipse.lsp4xml.dom.Node;
import org.eclipse.lsp4xml.dom.XMLDocument;
import org.eclipse.lsp4xml.extensions.contentmodel.model.CMAttributeDeclaration;
import org.eclipse.lsp4xml.extensions.contentmodel.model.CMDocument;
Expand Down Expand Up @@ -99,10 +100,8 @@ private void fillWithChildrenElementDeclaration(Collection<CMElementDeclaration>
@Override
public void onAttributeName(boolean generateValue, Range fullRange, ICompletionRequest request,
ICompletionResponse response) throws Exception {
// TODO: manage xsi: completions
if(computeXSIAttribute(fullRange, request, response)) {
return;
}

computeXSIAttribute(fullRange, request, response);
// otherwise, manage completion based on XML Schema, DTD.
Element parentElement = request.getNode().isElement() ? (Element) request.getNode() : null;
if (parentElement == null) {
Expand Down Expand Up @@ -184,31 +183,38 @@ public void onAttributeValue(String valuePrefix, Range fullRange, boolean addQuo
}
}

private boolean computeXSIAttribute(Range editRange, ICompletionRequest request, ICompletionResponse response) {
private void computeXSIAttribute(Range editRange, ICompletionRequest request, ICompletionResponse response) {
int nameStart = 0;
int nameEnd = 0;

XMLDocument document = request.getXMLDocument();
Element rootElement = document.getDocumentElement();

try {
nameStart = document.offsetAt(editRange.getStart());
nameEnd = document.offsetAt(editRange.getEnd());
} catch (BadLocationException e) {

}
if(!rootElement.equals(document.findNodeAt(nameStart))) {
return false;
}
String text = document.getText();
String attName = text.substring(nameStart, nameEnd);
String attPrefix = XSISchemaModel.getPrefixFromAttName(attName);
String actualPrefix = document.getSchemaInstancePrefix();
if(XSISchemaModel.doesAttPrefixMatch(attPrefix, actualPrefix)) {
if(rootElement.equals(document.findNodeAt(nameStart))) {
String actualPrefix = document.getSchemaInstancePrefix();
boolean isSnippetsSupported = request.getCompletionSettings().isCompletionSnippetsSupported();
XSISchemaModel.computeCompletionResponses(response, isSnippetsSupported, actualPrefix, attName, editRange, document);
return true;
XSISchemaModel.computeCompletionResponses(response, isSnippetsSupported, actualPrefix, editRange, document);
}

return false;


// if(!rootElement.equals(document.findNodeAt(nameStart))) {
// return false;
// }
// String text = document.getText();
// String attName = text.substring(nameStart, nameEnd);
// String attPrefix = XSISchemaModel.getPrefixFromAttName(attName);

// if(XSISchemaModel.doesAttPrefixMatch(attPrefix, actualPrefix)) {

// return true;
// }

// return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,26 +54,30 @@ private static boolean startMatchesAttribute(String actualPrefix, String suffixC
return (actualPrefix + ":" + suffixConstant).startsWith(attName);
}

public static void computeCompletionResponses(ICompletionResponse response, boolean isSnippetsSupported, String actualPrefix, String attName, Range editRange, XMLDocument document) {
public static void computeCompletionResponses(ICompletionResponse response, boolean isSnippetsSupported, String actualPrefix, Range editRange, XMLDocument document) {
String snippet = "";
if(isSnippetsSupported) {
snippet = "$0";
}
String name;
Element root = document.getDocumentElement();
if(!attributeAlreadyExists(root, actualPrefix, "nil") && startMatchesAttribute(actualPrefix, XSI_NIL, attName)) {
boolean nilExists = attributeAlreadyExists(root, actualPrefix, "nil");
boolean typeExists = attributeAlreadyExists(root, actualPrefix, "type");
boolean schemaExists = attributeAlreadyExists(root, actualPrefix, "schemaLocation");
boolean noSchemaExists = attributeAlreadyExists(root, actualPrefix, "noNamespaceSchemaLocation");
if(!nilExists) {
name = actualPrefix + ":nil";
createCompletionItem(name, snippet, editRange, response);
}
if(!attributeAlreadyExists(root, actualPrefix, "type") && startMatchesAttribute(actualPrefix, XSI_TYPE, attName)) {
if(!typeExists) {
name = actualPrefix + ":type";
createCompletionItem(name, snippet, editRange, response);
}
if(!attributeAlreadyExists(root, actualPrefix, "schemaLocation") && startMatchesAttribute(actualPrefix, XSI_SCHEMA, attName)) {
if(!schemaExists && !noSchemaExists) {
name = actualPrefix + ":schemaLocation";
createCompletionItem(name, snippet, editRange, response);
}
if(!attributeAlreadyExists(root, actualPrefix, "noNamespaceSchemaLocation") && startMatchesAttribute(actualPrefix, XSI_NOSCHEMA, attName)) {
if(!noSchemaExists && !schemaExists) {
name = actualPrefix + ":noNamespaceSchemaLocation";
createCompletionItem(name, snippet, editRange, response);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -308,23 +308,49 @@ public void xsiCompletionTest1() throws BadLocationException {
"<project\r\n" +
" xmlns=\"http://maven.apache.org/POM/4.0.0\"\r\n" +
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\r\n" +
" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\" |>\r\n" +
" |>\r\n" +
"</project>";
XMLAssert.testCompletionFor(xml, false, c("xsi:nil", "xsi:nil=\"\""), c("xsi:type", "xsi:type=\"\""), c("xsi:noNamespaceSchemaLocation", "xsi:noNamespaceSchemaLocation=\"\""));
XMLAssert.testCompletionFor(xml, 4, c("xsi:nil", "xsi:nil=\"\""), c("xsi:type", "xsi:type=\"\""), c("xsi:noNamespaceSchemaLocation", "xsi:noNamespaceSchemaLocation=\"\""), c("xsi:schemaLocation", "xsi:schemaLocation=\"\""));
}

@Test

public void xsiCompletionTestDoesntAppear() throws BadLocationException {
public void xsiCompletionDoesntAppearInNonRootElement() throws BadLocationException {
String xml =
"<project\r\n" +
" xmlns=\"http://maven.apache.org/POM/4.0.0\"\r\n" +
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\r\n" +
" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\" |>\r\n" +
" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\r\n" +
" <modelVersion xs|></modelVersion>\r\n" +
"</project>";

XMLAssert.testCompletionFor(xml, false);
XMLAssert.testCompletionFor(xml, 0);
}


@Test
public void xsiCompletionNotUsingXSIName() throws BadLocationException {
String xml =
"<project\r\n" +
" xmlns=\"http://maven.apache.org/POM/4.0.0\"\r\n" +
" xmlns:XXY=\"http://www.w3.org/2001/XMLSchema-instance\"\r\n" +
" XXY:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\" |>\r\n" +
" <modelVersion></modelVersion>\r\n" +
"</project>";

XMLAssert.testCompletionFor(xml, 2, c("XXY:nil", "XXY:nil=\"\""), c("XXY:type", "XXY:type=\"\""));
}

@Test

public void xsiCompletionDoesntAppearSinceDoesntExist() throws BadLocationException {
String xml =
"<project\r\n" +
" xmlns=\"http://maven.apache.org/POM/4.0.0\"\r\n" +
" xsi:|>\r\n" +
" <modelVersion></modelVersion>\r\n" +
"</project>";

XMLAssert.testCompletionFor(xml, 0);
}


Expand Down

0 comments on commit ff066df

Please sign in to comment.