Skip to content

Commit

Permalink
OpenQuoteExpected error for ATTLIST breaks DTD validation
Browse files Browse the repository at this point in the history
Fixes #943

Signed-off-by: azerr <[email protected]>
  • Loading branch information
angelozerr committed Nov 14, 2023
1 parent d1d67ec commit f4b2d4e
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -355,9 +355,11 @@ public CompletableFuture<List<? extends TextEdit>> rangeFormatting(DocumentRange
}

@Override
public CompletableFuture<Either3<Range, PrepareRenameResult, PrepareRenameDefaultBehavior>> prepareRename(PrepareRenameParams params) {
public CompletableFuture<Either3<Range, PrepareRenameResult, PrepareRenameDefaultBehavior>> prepareRename(
PrepareRenameParams params) {
return computeDOMAsync(params.getTextDocument(), (xmlDocument, cancelChecker) -> {
Either<Range, PrepareRenameResult> either = getXMLLanguageService().prepareRename(xmlDocument, params.getPosition(), cancelChecker);
Either<Range, PrepareRenameResult> either = getXMLLanguageService().prepareRename(xmlDocument,
params.getPosition(), cancelChecker);
if (either != null) {
if (either.isLeft()) {
return Either3.forFirst((Range) either.get());
Expand Down Expand Up @@ -550,15 +552,17 @@ private XMLFormattingOptions getIndentationSettings(@NonNull String uri) {
List<Object> indentationSettings = xmlLanguageServer.getLanguageClient()
.configuration(new ConfigurationParams(Arrays.asList( //
insertSpaces, tabSize //
))).join();
))).getNow(Collections.emptyList());

newOptions = new XMLFormattingOptions();
newOptions.merge(sharedSettings.getFormattingSettings());
if (indentationSettings.get(0) != null && (indentationSettings.get(0) instanceof JsonPrimitive)) {
newOptions.setInsertSpaces(((JsonPrimitive) indentationSettings.get(0)).getAsBoolean());
}
if (indentationSettings.get(1) != null && (indentationSettings.get(1) instanceof JsonPrimitive)) {
newOptions.setTabSize(((JsonPrimitive) indentationSettings.get(1)).getAsInt());
if (!indentationSettings.isEmpty()) {
if (indentationSettings.get(0) != null && (indentationSettings.get(0) instanceof JsonPrimitive)) {
newOptions.setInsertSpaces(((JsonPrimitive) indentationSettings.get(0)).getAsBoolean());
}
if (indentationSettings.get(1) != null && (indentationSettings.get(1) instanceof JsonPrimitive)) {
newOptions.setTabSize(((JsonPrimitive) indentationSettings.get(1)).getAsInt());
}
}
} catch (Exception e) {
LOGGER.log(Level.SEVERE, "Error while processing getting indentation settings for code actions'.", e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,23 @@ public static DOMAttr findAttrAt(DOMNode node, int offset) {
return null;
}

public DTDDeclParameter findParameterAt(int offset) {
DOMNode node = findNodeAt(offset);
return findParameterAt(node, offset);
}

public static DTDDeclParameter findParameterAt(DOMNode node, int offset) {
if (node != null && (node.isDTDAttListDecl() || node.isDTDElementDecl() || node.isDTDEntityDecl()
|| node.isDTDNotationDecl())) {
for (DTDDeclParameter parameter : ((DTDDeclNode) node).getParameters()) {
if (isIncluded(parameter, offset)) {
return parameter;
}
}
}
return null;
}

public static DOMText findTextAt(DOMNode node, int offset) {
if (node != null && node.hasChildNodes()) {
for (DOMNode child : node.getChildren()) {
Expand All @@ -299,7 +316,7 @@ public static DOMText findTextAt(DOMNode node, int offset) {
}
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 @@ -25,6 +25,8 @@
import org.eclipse.lemminx.dom.DOMDocumentType;
import org.eclipse.lemminx.dom.DOMElement;
import org.eclipse.lemminx.dom.DOMNode;
import org.eclipse.lemminx.dom.DTDDeclNode;
import org.eclipse.lemminx.dom.DTDDeclParameter;
import org.eclipse.lemminx.extensions.contentmodel.participants.codeactions.ETagRequiredCodeAction;
import org.eclipse.lemminx.extensions.contentmodel.participants.codeactions.ETagUnterminatedCodeAction;
import org.eclipse.lemminx.extensions.contentmodel.participants.codeactions.ElementUnterminatedCodeAction;
Expand Down Expand Up @@ -283,6 +285,11 @@ public static Range toLSPRange(XMLLocator location, XMLSyntaxErrorCode code, Obj
case NameRequiredInReference:
break;
case OpenQuoteExpected: {
DOMNode node = document.findNodeAt(offset);
if (node instanceof DTDDeclNode) {
String parameterName = getString(arguments[1]);
return XMLPositionUtility.selectParameterNameFromGivenName(parameterName, (DTDDeclNode) node);
}
return XMLPositionUtility.selectAttributeNameAt(offset - 1, document);
}
case DoctypeNotAllowed:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import org.eclipse.lemminx.dom.DOMAttr;
import org.eclipse.lemminx.dom.DOMDocument;
import org.eclipse.lemminx.dom.DOMNode;
import org.eclipse.lemminx.dom.DTDDeclParameter;
import org.eclipse.lemminx.services.extensions.codeaction.ICodeActionParticipant;
import org.eclipse.lemminx.services.extensions.codeaction.ICodeActionRequest;
import org.eclipse.lemminx.settings.SharedSettings;
Expand All @@ -43,10 +44,20 @@ public void doCodeAction(ICodeActionRequest request, List<CodeAction> codeAction
} catch (BadLocationException e) {
return;
}
DOMAttr attr = document.findAttrAt(offset);
if (attr == null || !attr.isAttribute()) {
return;
DOMNode attr = document.findAttrAt(offset);
if (attr != null && !attr.isAttribute()) {
insertQuotationForAttr(attr, document, request, diagnostic, codeActions);
} else {
DTDDeclParameter parameter = document.findParameterAt(offset);
if (parameter != null) {
insertQuotationForParameter(parameter, document, request, diagnostic, codeActions);
}
}

}

private static void insertQuotationForAttr(DOMNode attr, DOMDocument document, ICodeActionRequest request,
Diagnostic diagnostic, List<CodeAction> codeActions) {
SharedSettings sharedSettings = request.getSharedSettings();
String q = sharedSettings.getPreferences().getQuotationAsString();
Position codeactionPosition;
Expand Down Expand Up @@ -77,4 +88,14 @@ public void doCodeAction(ICodeActionRequest request, List<CodeAction> codeAction
codeActions.add(removeContentAction);
}

private static void insertQuotationForParameter(DTDDeclParameter parameter, DOMDocument document,
ICodeActionRequest request, Diagnostic diagnostic, List<CodeAction> codeActions) {
SharedSettings sharedSettings = request.getSharedSettings();
String q = sharedSettings.getPreferences().getQuotationAsString();
CodeAction insertQuotationsAction = CodeActionFactory.replace("Insert quotations",
parameter.getTargetRange(), q + parameter.getParameter() + q,
document.getTextDocument(), diagnostic);
codeActions.add(insertQuotationsAction);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -923,6 +923,16 @@ public static Range getElementDeclMissingContentOrCategory(int offset, DOMDocume
}
return null;
}

public static Range selectParameterNameFromGivenName(String parameterName, DTDDeclNode declNode) {
List<DTDDeclParameter> parameters = declNode.getParameters();
for (DTDDeclParameter parameter : parameters) {
if (parameterName.equals(parameter.getParameter())) {
return createRange(parameter.getStart(), parameter.getEnd(), declNode.getOwnerDocument());
}
}
return null;
}

// ------------ Other selection

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,12 @@ public void EntityDeclUnterminated() throws Exception {
testDiagnosticsFor(xml, "test.dtd", d(0, 41, 42, DTDErrorCode.EntityDeclUnterminated));
}

@Test
public void OpenQuoteExpected() throws Exception {
String xml = "<!ATTLIST dadesadministratives idinstitut ID >";
testDiagnosticsFor(xml, "test.dtd", d(0, 31, 41, DTDErrorCode.OpenQuoteExpected));
}

@Test
public void entityRefInvalidUri() throws Exception {

Expand Down

0 comments on commit f4b2d4e

Please sign in to comment.