Skip to content

Commit

Permalink
Provide error range for src-annotation (eclipse#1581)
Browse files Browse the repository at this point in the history
* fix error range
* Add code action

Signed-off-by: Omar Farag <[email protected]>
  • Loading branch information
o-farag authored Sep 7, 2023
1 parent 0fa027c commit d1d67ec
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/**
* Copyright (c) 2023 Omar Farag.
* 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
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Omar Farag <[email protected]> - initial API and implementation
*/
package org.eclipse.lemminx.extensions.contentmodel.participants.codeactions;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.lsp4j.CodeAction;
import org.eclipse.lsp4j.Diagnostic;
import org.eclipse.lsp4j.Range;
import org.eclipse.lsp4j.TextEdit;
import org.eclipse.lsp4j.jsonrpc.CancelChecker;
import org.eclipse.lemminx.commons.BadLocationException;
import org.eclipse.lemminx.commons.CodeActionFactory;
import org.eclipse.lemminx.dom.DOMDocument;
import org.eclipse.lemminx.dom.DOMElement;
import org.eclipse.lemminx.dom.DOMNode;
import org.eclipse.lemminx.utils.XMLPositionUtility;
import org.eclipse.lemminx.services.extensions.codeaction.ICodeActionParticipant;
import org.eclipse.lemminx.services.extensions.codeaction.ICodeActionRequest;

/**
* Code action to fix invalid src-annotation elements
*/
public class src_annotationCodeAction implements ICodeActionParticipant {

private static List<String> potentialTags = new ArrayList<String>() {
{
add("xs:appinfo");
add("xs:documentation");
}
};

@Override
public void doCodeAction(ICodeActionRequest request, List<CodeAction> codeActions, CancelChecker cancelChecker) {
Diagnostic diagnostic = request.getDiagnostic();
DOMDocument document = request.getDocument();
Range diagnosticRange = diagnostic.getRange();
String codeActionText;
Range closeRange = null;
// Attempt to get tag name
try {
int startOffset = document.offsetAt(diagnosticRange.getStart()) + 1;
DOMNode node = document.findNodeAt(startOffset);
DOMElement element = (DOMElement) node;
String tagName = element.getTagName();
codeActionText = "Replace '" + tagName + "' with ";
closeRange = XMLPositionUtility.selectEndTagName(element);
} catch (BadLocationException e) {
codeActionText = "Replace with ";
}

for (String potentialTag : potentialTags) {
List<TextEdit> edits = new ArrayList<>();
TextEdit replaceOpen = new TextEdit(diagnosticRange, potentialTag);
edits.add(replaceOpen);
if (closeRange != null) {
TextEdit replaceClose = new TextEdit(closeRange, potentialTag);
edits.add(replaceClose);
}
CodeAction replaceAction = CodeActionFactory.replace(codeActionText + "'" + potentialTag + "'", edits,
document.getTextDocument(), diagnostic);
codeActions.add(replaceAction);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import org.eclipse.lemminx.dom.DOMNode;
import org.eclipse.lemminx.extensions.contentmodel.participants.codeactions.s4s_elt_invalid_content_3CodeAction;
import org.eclipse.lemminx.extensions.contentmodel.participants.codeactions.src_import_1_2CodeAction;
import org.eclipse.lemminx.extensions.contentmodel.participants.codeactions.src_annotationCodeAction;
import org.eclipse.lemminx.extensions.xsd.utils.XSDUtils;
import org.eclipse.lemminx.services.extensions.codeaction.ICodeActionParticipant;
import org.eclipse.lemminx.services.extensions.diagnostics.IXMLErrorCode;
Expand Down Expand Up @@ -138,6 +139,7 @@ public static Range toLSPRange(XMLLocator location, XSDErrorCode code, Object[]
case s4s_elt_invalid_content_3:
case src_element_2_1:
case src_element_3:
case src_annotation:
case src_import_1_2:
return XMLPositionUtility.selectStartTagName(offset, document);
case s4s_att_not_allowed: {
Expand Down Expand Up @@ -194,5 +196,6 @@ public static Range toLSPRange(XMLLocator location, XSDErrorCode code, Object[]
public static void registerCodeActionParticipants(Map<String, ICodeActionParticipant> codeActions) {
codeActions.put(s4s_elt_invalid_content_3.getCode(), new s4s_elt_invalid_content_3CodeAction());
codeActions.put(src_import_1_2.getCode(), new src_import_1_2CodeAction());
codeActions.put(src_annotation.getCode(), new src_annotationCodeAction());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ public void disableXMLSchemaValidationFilter() throws Exception {
// test.xsd doesn't matches the validation filter
XMLAssert.testPublishDiagnosticsFor(xml, fileURI, validation, ls, pd(fileURI, //
// XML schema error code
new Diagnostic(r(2, 15, 2, 15),
new Diagnostic(r(2, 7, 2, 14),
"src-annotation: <annotation> elements can only contain <appinfo> and <documentation> elements, but 'appInfo' was found.",
DiagnosticSeverity.Error, "xsd", XSDErrorCode.src_annotation.getCode())));

Expand Down Expand Up @@ -173,7 +173,7 @@ public void defaultDisableXMLSchemaValidationFilter() throws Exception {
// test.xsd doesn't matches the validation filter
XMLAssert.testPublishDiagnosticsFor(xml, fileURI, validation, ls, pd(fileURI, //
// XML schema error code
new Diagnostic(r(2, 15, 2, 15),
new Diagnostic(r(2, 7, 2, 14),
"src-annotation: <annotation> elements can only contain <appinfo> and <documentation> elements, but 'appInfo' was found.",
DiagnosticSeverity.Error, "xsd", XSDErrorCode.src_annotation.getCode())));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,28 @@ public void s4s_elt_invalid_content_3WithSelfClosingTag() throws BadLocationExce
testCodeActionsFor(xml, d, ca(d, te(2, 1, 2, 13, "")));
}

@Test
public void src_annotation_invalid_tag_() throws BadLocationException {
String xml = "<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">\r\n" + //
" <xs:annotation>\r\n" + //
" <xs:appInfo>\r\n" + //
" </xs:appInfo>\r\n" + //
" </xs:annotation>\r\n" + //
"</xs:schema>";
Diagnostic d = d(2, 9, 2, 19, XSDErrorCode.src_annotation);
testDiagnosticsFor(xml, d);
testCodeActionsFor(xml, d,
ca(d,
te(2, 9, 2, 19, "xs:appinfo"),
te(3, 10, 3, 20,"xs:appinfo")
),
ca(d,
te(2, 9, 2, 19, "xs:documentation"),
te(3, 10, 3, 20,"xs:documentation")
)
);
}

@Test
public void sch_props_correct_2() throws BadLocationException {
String xml = "<?xml version=\"1.1\" ?>\r\n" + //
Expand Down

0 comments on commit d1d67ec

Please sign in to comment.