diff --git a/src/main/java/com/moandjiezana/toml/ArrayConverter.java b/src/main/java/com/moandjiezana/toml/ArrayConverter.java index 770b7e5..c5abc85 100644 --- a/src/main/java/com/moandjiezana/toml/ArrayConverter.java +++ b/src/main/java/com/moandjiezana/toml/ArrayConverter.java @@ -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 arrayItems = new ArrayList(); 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; diff --git a/src/main/java/com/moandjiezana/toml/BooleanConverter.java b/src/main/java/com/moandjiezana/toml/BooleanConverter.java index ef1a781..82f73d2 100644 --- a/src/main/java/com/moandjiezana/toml/BooleanConverter.java +++ b/src/main/java/com/moandjiezana/toml/BooleanConverter.java @@ -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; diff --git a/src/main/java/com/moandjiezana/toml/Context.java b/src/main/java/com/moandjiezana/toml/Context.java new file mode 100644 index 0000000..1f41208 --- /dev/null +++ b/src/main/java/com/moandjiezana/toml/Context.java @@ -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; + } +} diff --git a/src/main/java/com/moandjiezana/toml/DateConverter.java b/src/main/java/com/moandjiezana/toml/DateConverter.java index 0f79071..9b92dc5 100644 --- a/src/main/java/com/moandjiezana/toml/DateConverter.java +++ b/src/main/java/com/moandjiezana/toml/DateConverter.java @@ -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; } } diff --git a/src/main/java/com/moandjiezana/toml/InlineTableConverter.java b/src/main/java/com/moandjiezana/toml/InlineTableConverter.java index bcfda23..e72472f 100644 --- a/src/main/java/com/moandjiezana/toml/InlineTableConverter.java +++ b/src/main/java/com/moandjiezana/toml/InlineTableConverter.java @@ -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 results = new HashMap(); + 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; diff --git a/src/main/java/com/moandjiezana/toml/LiteralStringConverter.java b/src/main/java/com/moandjiezana/toml/LiteralStringConverter.java index c758814..291a8ad 100644 --- a/src/main/java/com/moandjiezana/toml/LiteralStringConverter.java +++ b/src/main/java/com/moandjiezana/toml/LiteralStringConverter.java @@ -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()); diff --git a/src/main/java/com/moandjiezana/toml/MultilineLiteralStringConverter.java b/src/main/java/com/moandjiezana/toml/MultilineLiteralStringConverter.java index 5210727..9920cd3 100644 --- a/src/main/java/com/moandjiezana/toml/MultilineLiteralStringConverter.java +++ b/src/main/java/com/moandjiezana/toml/MultilineLiteralStringConverter.java @@ -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,10 +22,15 @@ 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; @@ -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); diff --git a/src/main/java/com/moandjiezana/toml/MultilineStringConverter.java b/src/main/java/com/moandjiezana/toml/MultilineStringConverter.java index 631e964..7dd0bab 100644 --- a/src/main/java/com/moandjiezana/toml/MultilineStringConverter.java +++ b/src/main/java/com/moandjiezana/toml/MultilineStringConverter.java @@ -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); diff --git a/src/main/java/com/moandjiezana/toml/NumberConverter.java b/src/main/java/com/moandjiezana/toml/NumberConverter.java index 56221b5..b1b7b94 100644 --- a/src/main/java/com/moandjiezana/toml/NumberConverter.java +++ b/src/main/java/com/moandjiezana/toml/NumberConverter.java @@ -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; } } } diff --git a/src/main/java/com/moandjiezana/toml/Results.java b/src/main/java/com/moandjiezana/toml/Results.java index a08660b..779372c 100644 --- a/src/main/java/com/moandjiezana/toml/Results.java +++ b/src/main/java/com/moandjiezana/toml/Results.java @@ -115,6 +115,13 @@ class Results { .append(value.trim()) .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 tables = new HashSet(); final Errors errors = new Errors(); diff --git a/src/main/java/com/moandjiezana/toml/StringConverter.java b/src/main/java/com/moandjiezana/toml/StringConverter.java index fdedd1b..068e463 100644 --- a/src/main/java/com/moandjiezana/toml/StringConverter.java +++ b/src/main/java/com/moandjiezana/toml/StringConverter.java @@ -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; diff --git a/src/main/java/com/moandjiezana/toml/TomlParser.java b/src/main/java/com/moandjiezana/toml/TomlParser.java index eeb3bc9..3506bd7 100644 --- a/src/main/java/com/moandjiezana/toml/TomlParser.java +++ b/src/main/java/com/moandjiezana/toml/TomlParser.java @@ -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); } diff --git a/src/main/java/com/moandjiezana/toml/ValueConverter.java b/src/main/java/com/moandjiezana/toml/ValueConverter.java index 5d9fe6a..06f8216 100644 --- a/src/main/java/com/moandjiezana/toml/ValueConverter.java +++ b/src/main/java/com/moandjiezana/toml/ValueConverter.java @@ -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); } diff --git a/src/main/java/com/moandjiezana/toml/ValueConverterUtils.java b/src/main/java/com/moandjiezana/toml/ValueConverterUtils.java index 5603d69..28bf6ec 100644 --- a/src/main/java/com/moandjiezana/toml/ValueConverterUtils.java +++ b/src/main/java/com/moandjiezana/toml/ValueConverterUtils.java @@ -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()) { diff --git a/src/main/java/com/moandjiezana/toml/ValueConverters.java b/src/main/java/com/moandjiezana/toml/ValueConverters.java index 2800188..8a2454c 100644 --- a/src/main/java/com/moandjiezana/toml/ValueConverters.java +++ b/src/main/java/com/moandjiezana/toml/ValueConverters.java @@ -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() {} diff --git a/src/test/java/com/moandjiezana/toml/ErrorMessagesTest.java b/src/test/java/com/moandjiezana/toml/ErrorMessagesTest.java index 2ea7fe7..834e6dc 100644 --- a/src/test/java/com/moandjiezana/toml/ErrorMessagesTest.java +++ b/src/test/java/com/moandjiezana/toml/ErrorMessagesTest.java @@ -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 ]"); + } }