Skip to content

Commit

Permalink
Implement <?xml completion in DTD files
Browse files Browse the repository at this point in the history
Signed-off-by: David Kwon <[email protected]>
  • Loading branch information
dkwon17 authored and fbricon committed Jun 4, 2019
1 parent f58872a commit a8bb969
Show file tree
Hide file tree
Showing 7 changed files with 227 additions and 89 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
package org.eclipse.lsp4xml.dom;

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


/**
Expand All @@ -33,7 +34,7 @@ public class DTDDeclNode extends DOMNode{
public DTDDeclParameter unrecognized; // holds all content after parsing goes wrong in a DTD declaration (ENTITY, ATTLIST, ...).
public DTDDeclParameter declType; // represents the actual name of the decl eg: ENTITY, ATTLIST, ...

ArrayList<DTDDeclParameter> parameters;
private List<DTDDeclParameter> parameters;

public DTDDeclNode(int start, int end, DOMDocumentType parentDocumentType) {
super(start, end);
Expand Down Expand Up @@ -84,7 +85,7 @@ public void updateLastParameterEnd(int end) {
}
}

public ArrayList<DTDDeclParameter> getParameters() {
public List<DTDDeclParameter> getParameters() {
if(parameters == null) {
parameters = new ArrayList<DTDDeclParameter>();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ TokenType internalScan() {

case PrologOrPI:
if (stream.advanceIfChars(_QMA, _RAN)) { // ?>
state = ScannerState.WithinContent;
state = getWithinContentState();
return finishToken(offset, TokenType.PIEnd);
}
if (stream.advanceUntilAnyOfChars(_NWL, _CAR, _WSP, _QMA, _RAN) || stream.eos()) { // \n or \r or ' ' or '?'
Expand Down Expand Up @@ -156,12 +156,12 @@ TokenType internalScan() {
}

if (stream.advanceIfChars(_QMA, _RAN)) {
state = ScannerState.WithinContent;
state = getWithinContentState();
return finishToken(offset, TokenType.PIEnd);
}
if (stream.advanceUntilCharsOrNewTag(_QMA, _RAN)) { // ?>
if (stream.peekChar() == _LAN) {
state = ScannerState.WithinContent;
state = getWithinContentState();
}
if (getTokenTextFromOffset(offset).length() == 0) {
return finishToken(offset, TokenType.PIEnd);
Expand Down Expand Up @@ -268,7 +268,7 @@ TokenType internalScan() {
return finishToken(offset, TokenType.Whitespace);
}
if (stream.advanceIfChars(_QMA, _RAN)) { // ?>
state = ScannerState.WithinContent;
state = getWithinContentState();
return finishToken(offset, TokenType.PrologEnd);
}

Expand Down Expand Up @@ -467,6 +467,10 @@ TokenType internalScan() {
}
if(isDTDFile) {
if(startsWithLessThanBracket) {
if (stream.advanceIfChar(_QMA)) { // ?
state = ScannerState.PrologOrPI;
return finishToken(offset, TokenType.StartPrologOrPI);
}
if(stream.advanceUntilCharOrNewTag(_RAN)){ // >
if(stream.peekChar() == _RAN) {
stream.advance(1); //consume '>'
Expand Down Expand Up @@ -875,6 +879,13 @@ private String localize(String string, String string2) {
return string;
}

private ScannerState getWithinContentState() {
if (isDTDFile) {
return ScannerState.DTDWithinContent;
}
return ScannerState.WithinContent;
}

public int getLastNonWhitespaceOffset() {
return stream.getLastNonWhitespaceOffset();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,26 +181,12 @@ private void format(DOMNode node, int level, int end, XMLBuilder xml) {
xml.linefeed();
}
} else if (node.isProcessingInstruction()) {
DOMProcessingInstruction processingInstruction = (DOMProcessingInstruction) node;
xml.startPrologOrPI(processingInstruction.getTarget());
if(processingInstruction.hasAttributes()) {
addAttributes(processingInstruction, xml);
}
else {
xml.addContentPI(processingInstruction.getData());
}

xml.endPrologOrPI();
addPIToXMLBuilder(node, xml);
if (level == 0) {
xml.linefeed();
}
} else if (node.isProlog()) {
DOMProcessingInstruction processingInstruction = (DOMProcessingInstruction) node;
xml.startPrologOrPI(processingInstruction.getTarget());
if (node.hasAttributes()) {
addAttributes(node, xml);
}
xml.endPrologOrPI();
addPrologToXMLBuilder(node, xml);
xml.linefeed();
} else if (node.isText()) {
DOMText textNode = (DOMText) node;
Expand All @@ -214,7 +200,7 @@ private void format(DOMNode node, int level, int end, XMLBuilder xml) {
DOMDocumentType documentType = (DOMDocumentType) node;
if(!isDTD) {
xml.startDoctype();
ArrayList<DTDDeclParameter> params = documentType.getParameters();
List<DTDDeclParameter> params = documentType.getParameters();
for (DTDDeclParameter param : params) {
if(!documentType.isInternalSubset(param)) {
xml.addParameter(param.getParameter());
Expand Down Expand Up @@ -253,82 +239,79 @@ private static boolean formatDTD(DOMDocumentType doctype, int level, int end, XM

xml.indent(level);

if(node.isText()) {
if (node.isText()) {
xml.addContent(((DOMText)node).getData().trim());
}
else {
if(node.isComment()) {
DOMComment comment = (DOMComment) node;
xml.startComment(comment);
xml.addContentComment(comment.getData());
xml.endComment();
}
else {
boolean setEndBracketOnNewLine = false;
DTDDeclNode decl = (DTDDeclNode) node;
xml.addDeclTagStart(decl);
} else if (node.isComment()) {
DOMComment comment = (DOMComment) node;
xml.startComment(comment);
xml.addContentComment(comment.getData());
xml.endComment();
} else if (node.isProcessingInstruction()) {
addPIToXMLBuilder(node, xml);
} else if (node.isProlog()) {
addPrologToXMLBuilder(node, xml);
} else {
boolean setEndBracketOnNewLine = false;
DTDDeclNode decl = (DTDDeclNode) node;
xml.addDeclTagStart(decl);

if(decl.isDTDAttListDecl()) {
DTDAttlistDecl attlist = (DTDAttlistDecl) decl;
ArrayList<DTDAttlistDecl> internalDecls = attlist.getInternalChildren();
if (decl.isDTDAttListDecl()) {
DTDAttlistDecl attlist = (DTDAttlistDecl) decl;
List<DTDAttlistDecl> internalDecls = attlist.getInternalChildren();

if(internalDecls == null) {
for (DTDDeclParameter param : decl.getParameters()) {
xml.addParameter(param.getParameter());
if (internalDecls == null) {
for (DTDDeclParameter param : decl.getParameters()) {
xml.addParameter(param.getParameter());
}
} else {
boolean multipleInternalAttlistDecls = false;
List<DTDDeclParameter> params = attlist.getParameters();
DTDDeclParameter param;
for(int i = 0; i < params.size(); i++) {
param = params.get(i);
if(attlist.elementName.equals(param)) {
xml.addParameter(param.getParameter());
if(attlist.getParameters().size() > 1) { //has parameters after elementName
xml.linefeed();
xml.indent(level + 1);
setEndBracketOnNewLine = true;
multipleInternalAttlistDecls = true;
}
} else {
if(multipleInternalAttlistDecls && i == 1) {
xml.addUnindentedParameter(param.getParameter());
} else {
xml.addParameter(param.getParameter());
}
}
}
else {
boolean multipleInternalAttlistDecls = false;

ArrayList<DTDDeclParameter> params = attlist.getParameters();
DTDDeclParameter param;
for (DTDAttlistDecl attlistDecl : internalDecls) {
xml.linefeed();
xml.indent(level + 1);
params = attlistDecl.getParameters();
for(int i = 0; i < params.size(); i++) {
param = params.get(i);
if(attlist.elementName.equals(param)) {
xml.addParameter(param.getParameter());
if(attlist.getParameters().size() > 1) { //has parameters after elementName
xml.linefeed();
xml.indent(level + 1);
setEndBracketOnNewLine = true;
multipleInternalAttlistDecls = true;
}
if(i == 0) {
xml.addUnindentedParameter(param.getParameter());
} else {
if(multipleInternalAttlistDecls && i == 1) {
xml.addUnindentedParameter(param.getParameter());
} else {
xml.addParameter(param.getParameter());
}

xml.addParameter(param.getParameter());
}
}

for (DTDAttlistDecl attlistDecl : internalDecls) {
xml.linefeed();
xml.indent(level + 1);
params = attlistDecl.getParameters();
for(int i = 0; i < params.size(); i++) {
param = params.get(i);
if(i == 0) {
xml.addUnindentedParameter(param.getParameter());
} else {
xml.addParameter(param.getParameter());
}
}
}
}
} else {
for (DTDDeclParameter param : decl.getParameters()) {
xml.addParameter(param.getParameter());
}
}
if(setEndBracketOnNewLine) {
xml.linefeed();
xml.indent(level);
}
if(decl.isClosed()) {
xml.closeStartElement();
} else {
for (DTDDeclParameter param : decl.getParameters()) {
xml.addParameter(param.getParameter());
}
}
if(setEndBracketOnNewLine) {
xml.linefeed();
xml.indent(level);
}
if(decl.isClosed()) {
xml.closeStartElement();
}
}
previous = node;
}
Expand All @@ -344,6 +327,29 @@ private static boolean isPreviousSiblingNodeType(DOMNode node, short nodeType) {
return previousNode != null && previousNode.getNodeType() == nodeType;
}

private static void addPIToXMLBuilder(DOMNode node, XMLBuilder xml) {
DOMProcessingInstruction processingInstruction = (DOMProcessingInstruction) node;
xml.startPrologOrPI(processingInstruction.getTarget());

String content = processingInstruction.getData();
if (content.length() > 0) {
xml.addContentPI(content);
} else {
xml.addContent(" ");
}

xml.endPrologOrPI();
}

private static void addPrologToXMLBuilder(DOMNode node, XMLBuilder xml) {
DOMProcessingInstruction processingInstruction = (DOMProcessingInstruction) node;
xml.startPrologOrPI(processingInstruction.getTarget());
if (node.hasAttributes()) {
addAttributes(node, xml);
}
xml.endPrologOrPI();
}

/**
* Will add all attributes, to the given builder, on a single line
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@ public static Range getLastValidDTDDeclParameter(int offset, DOMDocument documen
DOMNode node = document.findNodeAt(offset);
if (node instanceof DTDDeclNode) {
DTDDeclNode decl = (DTDDeclNode) node;
ArrayList<DTDDeclParameter> params = decl.getParameters();
List<DTDDeclParameter> params = decl.getParameters();
DTDDeclParameter finalParam;
if(params == null || params.isEmpty()) {
return createRange(decl.declType.getStart(), decl.declType.getEnd(), document);
Expand Down Expand Up @@ -477,7 +477,7 @@ public static Range getLastValidDTDDeclParameterOrUnrecognized(int offset, DOMDo
decl = internal.get(internal.size() - 1); //get last internal decl
}
}
ArrayList<DTDDeclParameter> params = decl.getParameters();
List<DTDDeclParameter> params = decl.getParameters();
if(params == null || params.isEmpty()) {
return createRange(decl.declType.getStart(), decl.declType.getEnd(), document);
}
Expand All @@ -501,7 +501,7 @@ public static Range getLastDTDDeclParameter(int offset, DOMDocument document) {
DOMNode node = document.findNodeAt(offset);
if (node instanceof DTDDeclNode) {
DTDDeclNode decl = (DTDDeclNode) node;
ArrayList<DTDDeclParameter> params = decl.getParameters();
List<DTDDeclParameter> params = decl.getParameters();
DTDDeclParameter lastParam;
if(params != null && !params.isEmpty()) {
lastParam = params.get(params.size() - 1);
Expand Down Expand Up @@ -532,7 +532,7 @@ public static Range getElementDeclMissingContentOrCategory(int offset, DOMDocume
DOMNode node = document.findNodeAt(offset);
if (node instanceof DTDElementDecl) {
DTDElementDecl declNode = (DTDElementDecl) node;
ArrayList<DTDDeclParameter> params = declNode.getParameters();
List<DTDDeclParameter> params = declNode.getParameters();
if(params.isEmpty()) {
return null;
}
Expand Down
Loading

0 comments on commit a8bb969

Please sign in to comment.