Skip to content

Commit

Permalink
Preference to convert single quote attribute values to double quote o…
Browse files Browse the repository at this point in the history
…n format.

Fixes eclipse-lemminx#263, eclipse-lemminx#294

Signed-off-by: Nikolas <nikolaskomonen@gmail.com>
  • Loading branch information
NikolasKomonen committed Feb 27, 2019
1 parent 458d491 commit 2656767
Show file tree
Hide file tree
Showing 15 changed files with 473 additions and 58 deletions.
28 changes: 28 additions & 0 deletions .vscode/java.test.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"run": {
"default": "",
"items": [
{
"name": "lsp4xml",
"projectName": "lsp4xml",
"workingDirectory": "",
"args": [],
"vmargs": [],
"preLaunchTask": ""
}
]
},
"debug": {
"default": "",
"items": [
{
"name": "lsp4xml",
"projectName": "lsp4xml",
"workingDirectory": "",
"args": [],
"vmargs": [],
"preLaunchTask": ""
}
]
}
}
34 changes: 33 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,38 @@
//Use consistent indentation
"editor.detectIndentation": false,
"editor.tabSize": 4,
"editor.insertSpaces": false
"editor.insertSpaces": false,
"java.test.defaultConfig": "config-41b2e8",
"java.test.config": [
{
"run": {
"default": "",
"items": [
{
"name": "lsp4xml",
"projectName": "lsp4xml",
"workingDirectory": "",
"args": [],
"vmargs": [],
"preLaunchTask": ""
}
]
},
"debug": {
"default": "",
"items": [
{
"name": "lsp4xml",
"projectName": "lsp4xml",
"workingDirectory": "",
"args": [],
"vmargs": [],
"preLaunchTask": ""
}
]
},
"name": "config-41b2e8"
}
]

}
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,14 @@ public class DOMAttr extends DOMNode implements org.w3c.dom.Attr {

private DOMNode nodeAttrValue;

private String value;
private String quotelessValue;//Value without quotes

private String originalValue;//Exact value from document

private final DOMNode ownerElement;

private boolean hasDelimiter; // has '='

class AttrNameOrValue extends DOMNode {

private final DOMAttr ownerAttr;
Expand Down Expand Up @@ -110,7 +114,7 @@ public DOMElement getOwnerElement() {
*/
@Override
public String getValue() {
return value;
return quotelessValue;
}

/*
Expand Down Expand Up @@ -157,23 +161,71 @@ public DOMNode getNodeAttrName() {
return nodeAttrName;
}

public void setDelimiter(boolean hasDelimiter) {
this.hasDelimiter = hasDelimiter;
}

public boolean hasDelimiter() {
return this.hasDelimiter;
}

/**
* Get original attribute value from the document.
*
* This will include quotations (", ').
* @return attribute value with quotations if it had them.
*/
public String getOriginalValue() {
return originalValue;
}

public void setValue(String value, int start, int end) {
this.value = getValue(value);
this.originalValue = value;
this.quotelessValue = convertToQuotelessValue(value);
this.nodeAttrValue = start != -1 ? new AttrNameOrValue(start, end, this) : null;
}

private static String getValue(String value) {
/**
* Returns a String of 'value' without surrounding quotes if it had them.
* @param value
* @return
*/
public static String convertToQuotelessValue(String value) {
if (value == null) {
return null;
}
if (value.isEmpty()) {
return value;
}
int start = value.charAt(0) == '\"' ? 1 : 0;
int end = value.charAt(value.length() - 1) == '\"' ? value.length() - 1 : value.length();
char quoteValue = value.charAt(0);
int start = quoteValue == '\"' || quoteValue == '\'' ? 1 : 0;
quoteValue = value.charAt(value.length() - 1);
int end = quoteValue == '\"' || quoteValue == '\'' ? value.length() - 1 : value.length();
return value.substring(start, end);
}

/**
* Checks if 'value' has matching surrounding quotations.
* @param value
* @return
*/
public static boolean isQuoted(String value) {
if (value == null) {
return false;
}
if (value.isEmpty()) {
return false;
}
char quoteValueStart = value.charAt(0);
boolean start = quoteValueStart == '\"' || quoteValueStart == '\'' ? true : false;
if(start == false) {
return false;
}
char quoteValueEnd = value.charAt(value.length() - 1);
boolean end = (quoteValueEnd == '\"' || quoteValueEnd == '\'') && quoteValueEnd == quoteValueStart ? true : false;
return end;
}

public DOMNode getNodeAttrValue() {
return nodeAttrValue;
}
Expand Down Expand Up @@ -201,7 +253,7 @@ public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((value == null) ? 0 : value.hashCode());
result = prime * result + ((quotelessValue == null) ? 0 : quotelessValue.hashCode());
return result;
}

Expand All @@ -219,10 +271,10 @@ public boolean equals(Object obj) {
return false;
} else if (!name.equals(other.name))
return false;
if (value == null) {
if (other.value != null)
if (quotelessValue == null) {
if (other.quotelessValue != null)
return false;
} else if (!value.equals(other.value))
} else if (!quotelessValue.equals(other.quotelessValue))
return false;
return true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,15 @@ public DOMDocument parse(TextDocument document, URIResolverExtensionManager reso
break;
}

case DelimiterAssign: {
if(attr != null) {
//Sets the value to the '=' position in case there is no AttributeValue
attr.setValue(null, scanner.getTokenOffset(), scanner.getTokenEnd());
attr.setDelimiter(true);
}
break;
}

case AttributeValue: {
String value = scanner.getTokenText();
if (curr.hasAttributes() && attr != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public class Constants {

public static final Pattern ATTRIBUTE_NAME_REGEX = Pattern.compile("^[^\\s\"'<>/=\\x00-\\x0F\\x7F\\x80-\\x9F]*");

public static final Pattern ATTRIBUTE_VALUE_REGEX = Pattern.compile("^[^\\s\"'`=<>\\/]+");
public static final Pattern ATTRIBUTE_VALUE_REGEX = Pattern.compile("^(\"[^\"]*\"?)|(\'[^\']*\'?)");

public static final Pattern URL_VALUE_REGEX = Pattern.compile("^(\"|\')[^<>\"]*(\"|\')");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,8 @@ private Matcher getCachedMatcher(Pattern regex) {
if (matcher == null) {
matcher = regex.matcher(source);
regexpCache.put(regex, matcher);
} else {
matcher.reset(); // Cached regex caused issues, needed to reset it.
}
return matcher;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public class XMLScanner implements Scanner {
TokenType tokenType;
String tokenError;

boolean hasSpaceAfterTag;

String lastTag;
String lastAttributeName;
String lastTypeValue;
Expand Down Expand Up @@ -243,7 +243,6 @@ TokenType internalScan() {
lastTypeValue = null;
lastAttributeName = null;
if (lastTag.length() > 0) {
hasSpaceAfterTag = false;
state = ScannerState.WithinTag;
return finishToken(offset, TokenType.StartTag);
}
Expand All @@ -262,21 +261,19 @@ TokenType internalScan() {

case WithinTag:
if (stream.skipWhitespace()) {
hasSpaceAfterTag = true; // remember that we have seen a whitespace
return finishToken(offset, TokenType.Whitespace);
}
if (stream.advanceIfChars(_QMA, _RAN)) { // ?>
state = ScannerState.WithinContent;
return finishToken(offset, TokenType.PrologEnd);
}
if (hasSpaceAfterTag) {

lastAttributeName = nextAttributeName();
if (lastAttributeName.length() > 0) {
state = ScannerState.AfterAttributeName;
hasSpaceAfterTag = false;
return finishToken(offset, TokenType.AttributeName);
}
}

if (stream.advanceIfChars(_FSL, _RAN)) { // />
state = ScannerState.WithinContent;
return finishToken(offset, TokenType.StartTagSelfClose);
Expand All @@ -294,7 +291,6 @@ TokenType internalScan() {

case AfterAttributeName:
if (stream.skipWhitespace()) {
hasSpaceAfterTag = true;
return finishToken(offset, TokenType.Whitespace);
}

Expand All @@ -315,25 +311,10 @@ TokenType internalScan() {
lastTypeValue = attributeValue;
}
state = ScannerState.WithinTag;
hasSpaceAfterTag = false;
return finishToken(offset, TokenType.AttributeValue);
}
int ch = stream.peekChar();
if (ch == _SQO || ch == _DQO || ch == _SIQ) { // " || " || '
stream.advance(1); // consume quote
if (stream.advanceUntilChar(ch)) {
stream.advance(1); // consume quote
}
if ("type".equals(lastAttributeName)) {
lastTypeValue = stream.getSource().substring(offset + 1, stream.pos() - 1);
}
state = ScannerState.WithinTag;
hasSpaceAfterTag = false;
return finishToken(offset, TokenType.AttributeValue);
}
state = ScannerState.WithinTag;
hasSpaceAfterTag = false;
return internalScan(); // no advance yet - jump to WithinTag
return internalScan();

// DTD

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,9 +154,9 @@ private int generate(Collection<CMAttributeDeclaration> attributes, int level, i
String value = generateAttributeValue(defaultValue, enumerationValues, canSupportSnippets, snippetIndex,
false);
if (attributesSize != 1) {
xml.addAttribute(attributeDeclaration.getName(), value, attributeIndex, level, tagName);
xml.addAttribute(attributeDeclaration.getName(), value, level, true);
} else {
xml.addSingleAttribute(attributeDeclaration.getName(), value);
xml.addSingleAttribute(attributeDeclaration.getName(), value, true);
}
attributeIndex++;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,12 +119,12 @@ private void format(DOMNode node, int level, int end, XMLBuilder xml) {
List<DOMAttr> attributes = element.getAttributeNodes();
if (attributes.size() == 1) {
DOMAttr singleAttribute = attributes.get(0);
xml.addSingleAttribute(singleAttribute.getName(), singleAttribute.getValue());
xml.addSingleAttribute(singleAttribute.getName(), singleAttribute.getOriginalValue());
} else {
int attributeIndex = 0;
for (DOMAttr attr : attributes) {
String attributeName = attr.getName();
xml.addAttribute(attributeName, attr.getValue(), attributeIndex, level, tag);
xml.addAttribute(attr, level);
attributeIndex++;
}
}
Expand Down Expand Up @@ -205,7 +205,7 @@ private void format(DOMNode node, int level, int end, XMLBuilder xml) {
if (value == null) {
continue;
}
xml.addSingleAttribute(name, value);
xml.addSingleAttribute(name, value, true);
}
}
xml.endPrologOrPI();
Expand Down
Loading

0 comments on commit 2656767

Please sign in to comment.