mirror of
https://github.com/plexusorg/toml4j.git
synced 2024-10-31 17:29:14 +00:00
Improved error message reporting
This commit is contained in:
parent
c4027ed2d5
commit
c0e78db681
|
@ -1,6 +1,5 @@
|
|||
package com.moandjiezana.toml;
|
||||
|
||||
import static com.moandjiezana.toml.ValueConverterUtils.INVALID;
|
||||
import static com.moandjiezana.toml.ValueConverters.CONVERTERS;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -17,34 +16,15 @@ class ArrayConverter implements ValueConverter {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Object convert(String s) {
|
||||
AtomicInteger sharedIndex = new AtomicInteger();
|
||||
Object converted = convert(s, sharedIndex);
|
||||
|
||||
char[] chars = s.toCharArray();
|
||||
|
||||
for (int i = sharedIndex.incrementAndGet(); i < chars.length; i++) {
|
||||
char c = chars[i];
|
||||
|
||||
if (c == '#') {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!Character.isWhitespace(c)) {
|
||||
return INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
return converted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convert(String s, AtomicInteger index) {
|
||||
public Object convert(String s, AtomicInteger index, Context context) {
|
||||
AtomicInteger line = context.line;
|
||||
int startLine = line.get();
|
||||
int startIndex = index.get();
|
||||
char[] chars = s.toCharArray();
|
||||
List<Object> arrayItems = new ArrayList<Object>();
|
||||
boolean terminated = false;
|
||||
boolean inComment = false;
|
||||
Results.Errors errors = new Results.Errors();
|
||||
|
||||
for (int i = index.incrementAndGet(); i < chars.length; i = index.incrementAndGet()) {
|
||||
|
||||
|
@ -54,31 +34,40 @@ class ArrayConverter implements ValueConverter {
|
|||
inComment = true;
|
||||
} else if (c == '\n') {
|
||||
inComment = false;
|
||||
line.incrementAndGet();
|
||||
} else if (inComment || Character.isWhitespace(c) || c == ',') {
|
||||
continue;
|
||||
} else if (c == '[') {
|
||||
arrayItems.add(convert(s, index));
|
||||
Object converted = convert(s, index, context);
|
||||
if (converted instanceof Results.Errors) {
|
||||
errors.add((Results.Errors) converted);
|
||||
} else if (!isHomogenousArray(converted, arrayItems)) {
|
||||
errors.heterogenous(context.identifier.getName(), line.get());
|
||||
} else {
|
||||
arrayItems.add(converted);
|
||||
}
|
||||
continue;
|
||||
} else if (c == ']') {
|
||||
terminated = true;
|
||||
break;
|
||||
} else {
|
||||
arrayItems.add(CONVERTERS.convert(s, index));
|
||||
Object converted = CONVERTERS.convert(s, index, context);
|
||||
if (converted instanceof Results.Errors) {
|
||||
errors.add((Results.Errors) converted);
|
||||
} else if (!isHomogenousArray(converted, arrayItems)) {
|
||||
errors.heterogenous(context.identifier.getName(), line.get());
|
||||
} else {
|
||||
arrayItems.add(converted);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!terminated) {
|
||||
return ValueConverterUtils.unterminated(s.substring(startIndex, s.length()));
|
||||
errors.unterminated(context.identifier.getName(), s.substring(startIndex, s.length()), startLine);
|
||||
}
|
||||
|
||||
for (Object arrayItem : arrayItems) {
|
||||
if (arrayItem == INVALID) {
|
||||
return INVALID;
|
||||
}
|
||||
|
||||
if (!isHomogenousArray(arrayItem, arrayItems)) {
|
||||
return INVALID;
|
||||
}
|
||||
if (errors.hasErrors()) {
|
||||
return errors;
|
||||
}
|
||||
|
||||
return arrayItems;
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
package com.moandjiezana.toml;
|
||||
|
||||
import static com.moandjiezana.toml.ValueConverterUtils.INVALID;
|
||||
import static com.moandjiezana.toml.ValueConverterUtils.isComment;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
|
||||
|
@ -16,19 +13,7 @@ class BooleanConverter implements ValueConverter {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Object convert(String s) {
|
||||
AtomicInteger index = new AtomicInteger();
|
||||
Object converted = convert(s, index);
|
||||
|
||||
if (!isComment(s.substring(index.incrementAndGet()))) {
|
||||
return INVALID;
|
||||
}
|
||||
|
||||
return converted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convert(String s, AtomicInteger index) {
|
||||
public Object convert(String s, AtomicInteger index, Context context) {
|
||||
s = s.substring(index.get());
|
||||
Boolean b = s.startsWith("true") ? Boolean.TRUE : Boolean.FALSE;
|
||||
|
||||
|
|
13
src/main/java/com/moandjiezana/toml/Context.java
Normal file
13
src/main/java/com/moandjiezana/toml/Context.java
Normal file
|
@ -0,0 +1,13 @@
|
|||
package com.moandjiezana.toml;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
class Context {
|
||||
final Identifier identifier;
|
||||
final AtomicInteger line;
|
||||
|
||||
public Context(Identifier identifier, AtomicInteger line) {
|
||||
this.identifier = identifier;
|
||||
this.line = line;
|
||||
}
|
||||
}
|
|
@ -1,8 +1,5 @@
|
|||
package com.moandjiezana.toml;
|
||||
|
||||
import static com.moandjiezana.toml.ValueConverterUtils.INVALID;
|
||||
import static com.moandjiezana.toml.ValueConverterUtils.isComment;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.regex.Matcher;
|
||||
|
@ -37,40 +34,7 @@ class DateConverter implements ValueConverter {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Object convert(String s) {
|
||||
Matcher matcher = DATE_REGEX.matcher(s);
|
||||
matcher.matches();
|
||||
|
||||
if (!isComment(matcher.group(4))) {
|
||||
return INVALID;
|
||||
}
|
||||
|
||||
s = matcher.group(1);
|
||||
String zone = matcher.group(3);
|
||||
String fractionalSeconds = matcher.group(2);
|
||||
String format = "yyyy-MM-dd'T'HH:mm:ss";
|
||||
if (fractionalSeconds != null && !fractionalSeconds.isEmpty()) {
|
||||
format += ".SSS";
|
||||
s += fractionalSeconds;
|
||||
}
|
||||
format += "Z";
|
||||
if ("Z".equals(zone)) {
|
||||
s += "+0000";
|
||||
} else if (zone.contains(":")) {
|
||||
s += zone.replace(":", "");
|
||||
}
|
||||
|
||||
try {
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat(format);
|
||||
dateFormat.setLenient(false);
|
||||
return dateFormat.parse(s);
|
||||
} catch (Exception e) {
|
||||
return INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convert(String original, AtomicInteger index) {
|
||||
public Object convert(String original, AtomicInteger index, Context context) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
for (int i = index.get(); i < original.length(); i = index.incrementAndGet()) {
|
||||
|
@ -87,7 +51,9 @@ class DateConverter implements ValueConverter {
|
|||
Matcher matcher = DATE_REGEX.matcher(s);
|
||||
|
||||
if (!matcher.matches()) {
|
||||
return INVALID;
|
||||
Results.Errors errors = new Results.Errors();
|
||||
errors.invalidValue(context.identifier.getName(), s, context.line.get());
|
||||
return errors;
|
||||
}
|
||||
|
||||
String dateString = matcher.group(1);
|
||||
|
@ -110,7 +76,9 @@ class DateConverter implements ValueConverter {
|
|||
dateFormat.setLenient(false);
|
||||
return dateFormat.parse(dateString);
|
||||
} catch (Exception e) {
|
||||
return INVALID;
|
||||
Results.Errors errors = new Results.Errors();
|
||||
errors.invalidValue(context.identifier.getName(), s, context.line.get());
|
||||
return errors;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package com.moandjiezana.toml;
|
||||
|
||||
import static com.moandjiezana.toml.ValueConverterUtils.INVALID;
|
||||
import static com.moandjiezana.toml.ValueConverters.CONVERTERS;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
@ -16,20 +15,10 @@ class InlineTableConverter implements ValueConverter {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Object convert(String s) {
|
||||
AtomicInteger index = new AtomicInteger();
|
||||
Object converted = convert(s, index);
|
||||
|
||||
String substring = s.substring(index.incrementAndGet());
|
||||
if (converted == INVALID || !ValueConverterUtils.isComment(substring)) {
|
||||
return INVALID;
|
||||
}
|
||||
|
||||
return converted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convert(String s, AtomicInteger sharedIndex) {
|
||||
public Object convert(String s, AtomicInteger sharedIndex, Context context) {
|
||||
AtomicInteger line = context.line;
|
||||
int startLine = line.get();
|
||||
int startIndex = sharedIndex.get();
|
||||
char[] chars = s.toCharArray();
|
||||
boolean inKey = true;
|
||||
boolean inValue = false;
|
||||
|
@ -37,6 +26,7 @@ class InlineTableConverter implements ValueConverter {
|
|||
boolean terminated = false;
|
||||
StringBuilder currentKey = new StringBuilder();
|
||||
HashMap<String, Object> results = new HashMap<String, Object>();
|
||||
Results.Errors errors = new Results.Errors();
|
||||
|
||||
for (int i = sharedIndex.incrementAndGet(); sharedIndex.get() < chars.length; i = sharedIndex.incrementAndGet()) {
|
||||
char c = chars[i];
|
||||
|
@ -47,10 +37,11 @@ class InlineTableConverter implements ValueConverter {
|
|||
} else if (quoted) {
|
||||
currentKey.append(c);
|
||||
} else if (inValue && !Character.isWhitespace(c)) {
|
||||
Object converted = CONVERTERS.convert(s, sharedIndex);
|
||||
Object converted = CONVERTERS.convert(s, sharedIndex, new Context(new Identifier(currentKey.toString()), context.line));
|
||||
|
||||
if (converted == INVALID) {
|
||||
return INVALID;
|
||||
if (converted instanceof Results.Errors) {
|
||||
errors.add((Results.Errors) converted);
|
||||
return errors;
|
||||
}
|
||||
|
||||
results.put(currentKey.toString().trim(), converted);
|
||||
|
@ -58,10 +49,11 @@ class InlineTableConverter implements ValueConverter {
|
|||
inValue = false;
|
||||
} else if (c == '{') {
|
||||
sharedIndex.incrementAndGet();
|
||||
Object converted = convert(s, sharedIndex);
|
||||
Object converted = convert(s, sharedIndex, new Context(new Identifier(currentKey.toString()), context.line));
|
||||
|
||||
if (converted == INVALID) {
|
||||
return INVALID;
|
||||
if (converted instanceof Results.Errors) {
|
||||
errors.add((Results.Errors) converted);
|
||||
return errors;
|
||||
}
|
||||
|
||||
results.put(currentKey.toString().trim(), converted);
|
||||
|
@ -85,7 +77,11 @@ class InlineTableConverter implements ValueConverter {
|
|||
}
|
||||
|
||||
if (!terminated) {
|
||||
return INVALID;
|
||||
errors.unterminated(context.identifier.getName(), s.substring(startIndex), startLine);
|
||||
}
|
||||
|
||||
if (errors.hasErrors()) {
|
||||
return errors;
|
||||
}
|
||||
|
||||
return results;
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
package com.moandjiezana.toml;
|
||||
|
||||
import static com.moandjiezana.toml.ValueConverterUtils.INVALID;
|
||||
import static com.moandjiezana.toml.ValueConverterUtils.isComment;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
|
||||
|
@ -16,19 +13,8 @@ class LiteralStringConverter implements ValueConverter {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Object convert(String s) {
|
||||
AtomicInteger index = new AtomicInteger();
|
||||
Object converted = convert(s, index);
|
||||
|
||||
if (converted == INVALID || !isComment(s.substring(index.incrementAndGet()))) {
|
||||
return INVALID;
|
||||
}
|
||||
|
||||
return converted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convert(String s, AtomicInteger index) {
|
||||
public Object convert(String s, AtomicInteger index, Context context) {
|
||||
int startLine = context.line.get();
|
||||
char[] chars = s.toCharArray();
|
||||
boolean terminated = false;
|
||||
int startIndex = index.incrementAndGet();
|
||||
|
@ -43,7 +29,9 @@ class LiteralStringConverter implements ValueConverter {
|
|||
}
|
||||
|
||||
if (!terminated) {
|
||||
return INVALID;
|
||||
Results.Errors errors = new Results.Errors();
|
||||
errors.unterminated(context.identifier.getName(), s.substring(startIndex), startLine);
|
||||
return errors;
|
||||
}
|
||||
|
||||
String substring = s.substring(startIndex, index.get());
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
package com.moandjiezana.toml;
|
||||
|
||||
import static com.moandjiezana.toml.ValueConverterUtils.INVALID;
|
||||
import static com.moandjiezana.toml.ValueConverterUtils.isComment;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
class MultilineLiteralStringConverter implements ValueConverter {
|
||||
|
@ -15,19 +12,9 @@ class MultilineLiteralStringConverter implements ValueConverter {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Object convert(String s) {
|
||||
AtomicInteger index = new AtomicInteger();
|
||||
Object converted = convert(s, index);
|
||||
|
||||
if (converted == INVALID || !isComment(s.substring(index.incrementAndGet()))) {
|
||||
return INVALID;
|
||||
}
|
||||
|
||||
return converted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convert(String s, AtomicInteger index) {
|
||||
public Object convert(String s, AtomicInteger index, Context context) {
|
||||
AtomicInteger line = context.line;
|
||||
int startLine = line.get();
|
||||
char[] chars = s.toCharArray();
|
||||
int originalStartIndex = index.get();
|
||||
int startIndex = index.addAndGet(3);
|
||||
|
@ -35,11 +22,16 @@ class MultilineLiteralStringConverter implements ValueConverter {
|
|||
|
||||
if (chars[startIndex] == '\n') {
|
||||
startIndex = index.incrementAndGet();
|
||||
line.incrementAndGet();
|
||||
}
|
||||
|
||||
for (int i = startIndex; i < chars.length; i = index.incrementAndGet()) {
|
||||
char c = chars[i];
|
||||
|
||||
if (c == '\n') {
|
||||
line.incrementAndGet();
|
||||
}
|
||||
|
||||
if (c == '\'' && chars.length > i + 2 && chars[i + 1] == '\'' && chars[i + 2] == '\'') {
|
||||
endIndex = i;
|
||||
index.addAndGet(2);
|
||||
|
@ -48,7 +40,9 @@ class MultilineLiteralStringConverter implements ValueConverter {
|
|||
}
|
||||
|
||||
if (endIndex == -1) {
|
||||
return ValueConverterUtils.unterminated(s.substring(originalStartIndex, s.length()));
|
||||
Results.Errors errors = new Results.Errors();
|
||||
errors.unterminated(context.identifier.getName(), s.substring(originalStartIndex), startLine);
|
||||
return errors;
|
||||
}
|
||||
|
||||
return s.substring(startIndex, endIndex);
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
package com.moandjiezana.toml;
|
||||
|
||||
import static com.moandjiezana.toml.ValueConverterUtils.INVALID;
|
||||
import static com.moandjiezana.toml.ValueConverterUtils.isComment;
|
||||
import static com.moandjiezana.toml.ValueConverterUtils.unterminated;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
class MultilineStringConverter implements ValueConverter {
|
||||
|
@ -16,19 +12,9 @@ class MultilineStringConverter implements ValueConverter {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Object convert(String s) {
|
||||
AtomicInteger index = new AtomicInteger();
|
||||
Object converted = convert(s, index);
|
||||
|
||||
if (converted == INVALID || !isComment(s.substring(index.incrementAndGet()))) {
|
||||
return INVALID;
|
||||
}
|
||||
|
||||
return converted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convert(String s, AtomicInteger index) {
|
||||
public Object convert(String s, AtomicInteger index, Context context) {
|
||||
AtomicInteger line = context.line;
|
||||
int startLine = line.get();
|
||||
char[] chars = s.toCharArray();
|
||||
int originalStartIndex = index.get();
|
||||
int startIndex = index.addAndGet(3);
|
||||
|
@ -36,12 +22,15 @@ class MultilineStringConverter implements ValueConverter {
|
|||
|
||||
if (chars[startIndex] == '\n') {
|
||||
startIndex = index.incrementAndGet();
|
||||
line.incrementAndGet();
|
||||
}
|
||||
|
||||
for (int i = startIndex; i < chars.length; i = index.incrementAndGet()) {
|
||||
char c = chars[i];
|
||||
|
||||
if (c == '"' && chars.length > i + 2 && chars[i + 1] == '"' && chars[i + 2] == '"') {
|
||||
if (c == '\n') {
|
||||
line.incrementAndGet();
|
||||
} else if (c == '"' && chars.length > i + 2 && chars[i + 1] == '"' && chars[i + 2] == '"') {
|
||||
endIndex = i;
|
||||
index.addAndGet(2);
|
||||
break;
|
||||
|
@ -49,7 +38,9 @@ class MultilineStringConverter implements ValueConverter {
|
|||
}
|
||||
|
||||
if (endIndex == -1) {
|
||||
return unterminated(s.substring(originalStartIndex, s.length()));
|
||||
Results.Errors errors = new Results.Errors();
|
||||
errors.unterminated(context.identifier.getName(), s.substring(originalStartIndex), startLine);
|
||||
return errors;
|
||||
}
|
||||
|
||||
s = s.substring(startIndex, endIndex);
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
package com.moandjiezana.toml;
|
||||
|
||||
import static com.moandjiezana.toml.ValueConverterUtils.INVALID;
|
||||
import static com.moandjiezana.toml.ValueConverterUtils.isComment;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
class NumberConverter implements ValueConverter {
|
||||
|
@ -16,19 +13,7 @@ class NumberConverter implements ValueConverter {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Object convert(String s) {
|
||||
AtomicInteger index = new AtomicInteger();
|
||||
Object converted = convert(s, index);
|
||||
|
||||
if (converted == INVALID || (s.length() > index.get() + 1 && !isComment(s.substring(index.incrementAndGet())))) {
|
||||
return INVALID;
|
||||
}
|
||||
|
||||
return converted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convert(String s, AtomicInteger index) {
|
||||
public Object convert(String s, AtomicInteger index, Context context) {
|
||||
char[] chars = s.toCharArray();
|
||||
boolean signable = true;
|
||||
boolean dottable = false;
|
||||
|
@ -86,7 +71,9 @@ class NumberConverter implements ValueConverter {
|
|||
|
||||
return Double.parseDouble(exponentString[0]) * Math.pow(10, Double.parseDouble(exponentString[1]));
|
||||
} else {
|
||||
return INVALID;
|
||||
Results.Errors errors = new Results.Errors();
|
||||
errors.invalidValue(context.identifier.getName(), sb.toString(), context.line.get());
|
||||
return errors;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -116,6 +116,13 @@ class Results {
|
|||
.append('\n');
|
||||
}
|
||||
|
||||
public void heterogenous(String key, int line) {
|
||||
sb.append(key)
|
||||
.append(" becomes a heterogeneous array on line ")
|
||||
.append(line)
|
||||
.append('\n');
|
||||
}
|
||||
|
||||
boolean hasErrors() {
|
||||
return sb.length() > 0;
|
||||
}
|
||||
|
@ -124,6 +131,10 @@ class Results {
|
|||
public String toString() {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public void add(Errors other) {
|
||||
sb.append(other.sb);
|
||||
}
|
||||
}
|
||||
Set<String> tables = new HashSet<String>();
|
||||
final Errors errors = new Errors();
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
package com.moandjiezana.toml;
|
||||
|
||||
import static com.moandjiezana.toml.ValueConverterUtils.INVALID;
|
||||
import static com.moandjiezana.toml.ValueConverterUtils.isComment;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
@ -18,19 +15,7 @@ class StringConverter implements ValueConverter {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Object convert(String value) {
|
||||
AtomicInteger index = new AtomicInteger();
|
||||
Object converted = convert(value, index);
|
||||
|
||||
if (converted == INVALID || !isComment(value.substring(index.incrementAndGet()))) {
|
||||
return INVALID;
|
||||
}
|
||||
|
||||
return converted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convert(String value, AtomicInteger sharedIndex) {
|
||||
public Object convert(String value, AtomicInteger sharedIndex, Context context) {
|
||||
int startIndex = sharedIndex.incrementAndGet();
|
||||
int endIndex = -1;
|
||||
char[] chars = value.toCharArray();
|
||||
|
@ -44,15 +29,19 @@ class StringConverter implements ValueConverter {
|
|||
}
|
||||
|
||||
if (endIndex == -1) {
|
||||
return INVALID;
|
||||
Results.Errors errors = new Results.Errors();
|
||||
errors.unterminated(context.identifier.getName(), value.substring(startIndex - 1), context.line.get());
|
||||
return errors;
|
||||
}
|
||||
|
||||
value = value.substring(startIndex, endIndex);
|
||||
value = replaceUnicodeCharacters(value);
|
||||
String raw = value.substring(startIndex, endIndex);
|
||||
value = replaceUnicodeCharacters(raw);
|
||||
value = replaceSpecialCharacters(value);
|
||||
|
||||
if (value == null) {
|
||||
return INVALID;
|
||||
Results.Errors errors = new Results.Errors();
|
||||
errors.invalidValue(context.identifier.getName(), raw, context.line.get());
|
||||
return errors;
|
||||
}
|
||||
|
||||
return value;
|
||||
|
|
|
@ -1,12 +1,9 @@
|
|||
package com.moandjiezana.toml;
|
||||
|
||||
import static com.moandjiezana.toml.IdentifierConverter.IDENTIFIER_CONVERTER;
|
||||
import static com.moandjiezana.toml.ValueConverterUtils.INVALID;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import com.moandjiezana.toml.ValueConverterUtils.Unterminated;
|
||||
|
||||
class TomlParser {
|
||||
|
||||
Results run(String tomlString) {
|
||||
|
@ -52,14 +49,11 @@ class TomlParser {
|
|||
value = null;
|
||||
line.incrementAndGet();
|
||||
} else if (!inComment && identifier != null && identifier.isKey() && value == null && !Character.isWhitespace(c)) {
|
||||
int startIndex = index.get();
|
||||
Object converted = ValueConverters.CONVERTERS.convert(tomlString, index);
|
||||
Object converted = ValueConverters.CONVERTERS.convert(tomlString, index, new Context(identifier, line));
|
||||
value = converted;
|
||||
|
||||
if (converted == INVALID) {
|
||||
results.errors.invalidValue(identifier.getName(), tomlString.substring(startIndex, Math.min(index.get(), tomlString.length() - 1)), line.get());
|
||||
} else if (converted instanceof Unterminated) {
|
||||
results.errors.unterminated(identifier.getName(), ((Unterminated) converted).payload, line.get());
|
||||
if (converted instanceof Results.Errors) {
|
||||
results.errors.add((Results.Errors) converted);
|
||||
} else {
|
||||
results.addValue(identifier.getName(), converted);
|
||||
}
|
||||
|
|
|
@ -9,18 +9,13 @@ interface ValueConverter {
|
|||
*/
|
||||
boolean canConvert(String s);
|
||||
|
||||
/**
|
||||
* @param s must already have been validated by {@link #canConvert(String)}
|
||||
* @return a value or {@link ValueConverterUtils#INVALID}
|
||||
*/
|
||||
Object convert(String s);
|
||||
|
||||
/**
|
||||
* Partial validation. Stops after type terminator, rather than at EOI.
|
||||
*
|
||||
* @param s must already have been validated by {@link #canConvert(String)}
|
||||
* @param index where to start in s
|
||||
* @return a value or {@link ValueConverterUtils#INVALID}
|
||||
* @param line current line number, used for error reporting
|
||||
* @return a value or a {@link Results.Errors}
|
||||
*/
|
||||
Object convert(String s, AtomicInteger index);
|
||||
Object convert(String s, AtomicInteger index, Context context);
|
||||
}
|
||||
|
|
|
@ -2,19 +2,6 @@ package com.moandjiezana.toml;
|
|||
|
||||
|
||||
class ValueConverterUtils {
|
||||
static final Object INVALID = new Object();
|
||||
|
||||
static Unterminated unterminated(String payload) {
|
||||
return new Unterminated(payload);
|
||||
}
|
||||
|
||||
static class Unterminated {
|
||||
final String payload;
|
||||
|
||||
private Unterminated(String payload) {
|
||||
this.payload = payload;
|
||||
}
|
||||
}
|
||||
|
||||
static boolean isComment(String line) {
|
||||
if (line == null || line.isEmpty()) {
|
||||
|
|
|
@ -9,7 +9,6 @@ import static com.moandjiezana.toml.MultilineLiteralStringConverter.MULTILINE_LI
|
|||
import static com.moandjiezana.toml.MultilineStringConverter.MULTILINE_STRING_PARSER;
|
||||
import static com.moandjiezana.toml.NumberConverter.NUMBER_PARSER;
|
||||
import static com.moandjiezana.toml.StringConverter.STRING_PARSER;
|
||||
import static com.moandjiezana.toml.ValueConverterUtils.INVALID;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
|
@ -21,15 +20,17 @@ class ValueConverters {
|
|||
MULTILINE_STRING_PARSER, MULTILINE_LITERAL_STRING_CONVERTER, LITERAL_STRING_PARSER, STRING_PARSER, DATE_PARSER, NUMBER_PARSER, BOOLEAN_PARSER, ARRAY_PARSER, INLINE_TABLE_PARSER
|
||||
};
|
||||
|
||||
Object convert(String value, AtomicInteger index) {
|
||||
Object convert(String value, AtomicInteger index, Context context) {
|
||||
String substring = value.substring(index.get());
|
||||
for (ValueConverter valueParser : PARSERS) {
|
||||
if (valueParser.canConvert(substring)) {
|
||||
return valueParser.convert(value, index);
|
||||
return valueParser.convert(value, index, context);
|
||||
}
|
||||
}
|
||||
|
||||
return INVALID;
|
||||
Results.Errors errors = new Results.Errors();
|
||||
errors.invalidValue(context.identifier.getName(), substring, context.line.get());
|
||||
return errors;
|
||||
}
|
||||
|
||||
private ValueConverters() {}
|
||||
|
|
|
@ -85,4 +85,32 @@ public class ErrorMessagesTest {
|
|||
|
||||
new Toml().parse("\nk\n=3");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_display_correct_line_number_with_literal_multiline_string() throws Exception {
|
||||
e.expectMessage("on line 7");
|
||||
|
||||
new Toml().parse("[table]\n\n k = '''abc\n\ndef\n'''\n # comment \n j = 4.\n l = 5");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_display_correct_line_number_with_multiline_string() throws Exception {
|
||||
e.expectMessage("on line 8");
|
||||
|
||||
new Toml().parse("[table]\n\n k = \"\"\"\nabc\n\ndef\n\"\"\"\n # comment \n j = 4.\n l = 5");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_display_correct_line_number_with_array() throws Exception {
|
||||
e.expectMessage("on line 9");
|
||||
|
||||
new Toml().parse("[table]\n\n k = [\"\"\"\nabc\n\ndef\n\"\"\"\n, \n # comment \n j = 4.,\n l = 5\n]");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_message_heterogeneous_array() throws Exception {
|
||||
e.expectMessage("k becomes a heterogeneous array on line 2");
|
||||
|
||||
new Toml().parse("k = [ 1,\n 1.1 ]");
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue