[jsemver] 88/95: Add syntax error positions to the error reporting
Alexandre Viau
reazem-guest at moszumanska.debian.org
Mon Feb 16 14:58:33 UTC 2015
This is an automated email from the git hooks/post-receive script.
reazem-guest pushed a commit to branch master
in repository jsemver.
commit 399df4d2677c709ff9c127f011835fb98e10d8d5
Author: Zafar Khaja <zafarkhaja at gmail.com>
Date: Mon Jun 30 15:28:57 2014 +0300
Add syntax error positions to the error reporting
---
.../semver/UnexpectedCharacterException.java | 37 +++++++++++---
.../github/zafarkhaja/semver/VersionParser.java | 12 ++++-
.../com/github/zafarkhaja/semver/util/Stream.java | 11 +++-
.../semver/util/UnexpectedElementException.java | 29 +++++++++--
.../zafarkhaja/semver/ParserErrorHandlingTest.java | 59 ++++++++++++----------
.../github/zafarkhaja/semver/util/StreamTest.java | 13 +++++
6 files changed, 120 insertions(+), 41 deletions(-)
diff --git a/src/main/java/com/github/zafarkhaja/semver/UnexpectedCharacterException.java b/src/main/java/com/github/zafarkhaja/semver/UnexpectedCharacterException.java
index 485d7c6..30fb99b 100644
--- a/src/main/java/com/github/zafarkhaja/semver/UnexpectedCharacterException.java
+++ b/src/main/java/com/github/zafarkhaja/semver/UnexpectedCharacterException.java
@@ -43,6 +43,11 @@ public class UnexpectedCharacterException extends ParseException {
private final Character unexpected;
/**
+ * The position of the unexpected character.
+ */
+ private final int position;
+
+ /**
* The array of expected character types.
*/
private final CharType[] expected;
@@ -54,19 +59,27 @@ public class UnexpectedCharacterException extends ParseException {
* @param cause the wrapped exception
*/
UnexpectedCharacterException(UnexpectedElementException cause) {
+ position = cause.getPosition();
unexpected = (Character) cause.getUnexpectedElement();
- expected = (CharType[]) cause.getExpectedElementTypes();
+ expected = (CharType[]) cause.getExpectedElementTypes();
}
/**
* Constructs a {@code UnexpectedCharacterException} instance
- * with the unexpected character and the expected types.
+ * with the unexpected character, its position and the expected types.
*
- * @param cause the wrapped exception
+ * @param unexpected the unexpected character
+ * @param position the position of the unexpected character
+ * @param expected an array of the expected character types
*/
- UnexpectedCharacterException(Character unexpected, CharType... expected) {
+ UnexpectedCharacterException(
+ Character unexpected,
+ int position,
+ CharType... expected
+ ) {
this.unexpected = unexpected;
- this.expected = expected;
+ this.position = position;
+ this.expected = expected;
}
/**
@@ -79,6 +92,15 @@ public class UnexpectedCharacterException extends ParseException {
}
/**
+ * Gets the position of the unexpected character.
+ *
+ * @return the position of the unexpected character
+ */
+ int getPosition() {
+ return position;
+ }
+
+ /**
* Gets the expected character types.
*
* @return an array of expected character types
@@ -97,9 +119,10 @@ public class UnexpectedCharacterException extends ParseException {
@Override
public String toString() {
String message = String.format(
- "Unexpected character '%s(%s)'",
+ "Unexpected character '%s(%s)' at position '%d'",
CharType.forCharacter(unexpected),
- unexpected
+ unexpected,
+ position
);
if (expected.length > 0) {
message += String.format(
diff --git a/src/main/java/com/github/zafarkhaja/semver/VersionParser.java b/src/main/java/com/github/zafarkhaja/semver/VersionParser.java
index facc8d4..3cba10a 100644
--- a/src/main/java/com/github/zafarkhaja/semver/VersionParser.java
+++ b/src/main/java/com/github/zafarkhaja/semver/VersionParser.java
@@ -493,7 +493,11 @@ class VersionParser implements Parser<Version> {
if (DOT.isMatchedBy(la) || PLUS.isMatchedBy(la) || EOL.isMatchedBy(la)) {
throw new ParseException(
"Identifiers MUST NOT be empty",
- new UnexpectedCharacterException(la, DIGIT, LETTER, HYPHEN)
+ new UnexpectedCharacterException(
+ la,
+ chars.currentOffset(),
+ DIGIT, LETTER, HYPHEN
+ )
);
}
}
@@ -521,7 +525,11 @@ class VersionParser implements Parser<Version> {
*/
private void ensureValidLookahead(CharType... expected) {
if (!chars.positiveLookahead(expected)) {
- throw new UnexpectedCharacterException(chars.lookahead(1), expected);
+ throw new UnexpectedCharacterException(
+ chars.lookahead(1),
+ chars.currentOffset(),
+ expected
+ );
}
}
}
diff --git a/src/main/java/com/github/zafarkhaja/semver/util/Stream.java b/src/main/java/com/github/zafarkhaja/semver/util/Stream.java
index 5b3ed77..3021c12 100644
--- a/src/main/java/com/github/zafarkhaja/semver/util/Stream.java
+++ b/src/main/java/com/github/zafarkhaja/semver/util/Stream.java
@@ -112,7 +112,7 @@ public class Stream<E> implements Iterable<E> {
return consume();
}
}
- throw new UnexpectedElementException(lookahead, expected);
+ throw new UnexpectedElementException(lookahead, offset, expected);
}
/**
@@ -150,6 +150,15 @@ public class Stream<E> implements Iterable<E> {
}
/**
+ * Returns the current offset of this stream.
+ *
+ * @return the current offset of this stream
+ */
+ public int currentOffset() {
+ return offset;
+ }
+
+ /**
* Checks if the next element in this stream is of the expected types.
*
* @param <T> represents the element type of this stream, removes the
diff --git a/src/main/java/com/github/zafarkhaja/semver/util/UnexpectedElementException.java b/src/main/java/com/github/zafarkhaja/semver/util/UnexpectedElementException.java
index f7bcaa4..30d4835 100644
--- a/src/main/java/com/github/zafarkhaja/semver/util/UnexpectedElementException.java
+++ b/src/main/java/com/github/zafarkhaja/semver/util/UnexpectedElementException.java
@@ -41,6 +41,11 @@ public class UnexpectedElementException extends RuntimeException {
private final Object unexpected;
/**
+ * The position of the unexpected element in the stream.
+ */
+ private final int position;
+
+ /**
* The array of the expected element types.
*/
private final ElementType<?>[] expected;
@@ -50,10 +55,16 @@ public class UnexpectedElementException extends RuntimeException {
* with the unexpected element and the expected types.
*
* @param element the unexpected element in the stream
+ * @param position the position of the unexpected element
* @param expected an array of the expected element types
*/
- UnexpectedElementException(Object element, ElementType<?>... expected) {
- unexpected = element;
+ UnexpectedElementException(
+ Object element,
+ int position,
+ ElementType<?>... expected
+ ) {
+ unexpected = element;
+ this.position = position;
this.expected = expected;
}
@@ -67,6 +78,15 @@ public class UnexpectedElementException extends RuntimeException {
}
/**
+ * Gets the position of the unexpected element.
+ *
+ * @return the position of the unexpected element
+ */
+ public int getPosition() {
+ return position;
+ }
+
+ /**
* Gets the expected element types.
*
* @return an array of expected element types
@@ -85,8 +105,9 @@ public class UnexpectedElementException extends RuntimeException {
@Override
public String toString() {
String message = String.format(
- "Unexpected element '%s'",
- unexpected
+ "Unexpected element '%s' at position '%d'",
+ unexpected,
+ position
);
if (expected.length > 0) {
message += String.format(
diff --git a/src/test/java/com/github/zafarkhaja/semver/ParserErrorHandlingTest.java b/src/test/java/com/github/zafarkhaja/semver/ParserErrorHandlingTest.java
index d3e0738..dc8b65b 100644
--- a/src/test/java/com/github/zafarkhaja/semver/ParserErrorHandlingTest.java
+++ b/src/test/java/com/github/zafarkhaja/semver/ParserErrorHandlingTest.java
@@ -42,15 +42,18 @@ public class ParserErrorHandlingTest {
private final String invalidVersion;
private final Character unexpected;
+ private final int position;
private final CharType[] expected;
public ParserErrorHandlingTest(
String invalidVersion,
Character unexpected,
+ int position,
CharType[] expected
) {
this.invalidVersion = invalidVersion;
this.unexpected = unexpected;
+ this.position = position;
this.expected = expected;
}
@@ -60,12 +63,14 @@ public class ParserErrorHandlingTest {
VersionParser.parseValidSemVer(invalidVersion);
} catch (UnexpectedCharacterException e) {
assertEquals(unexpected, e.getUnexpectedCharacter());
+ assertEquals(position, e.getPosition());
assertArrayEquals(expected, e.getExpectedCharTypes());
return;
} catch (ParseException e) {
if (e.getCause() != null) {
UnexpectedCharacterException cause = (UnexpectedCharacterException) e.getCause();
assertEquals(unexpected, cause.getUnexpectedCharacter());
+ assertEquals(position, cause.getPosition());
assertArrayEquals(expected, cause.getExpectedCharTypes());
}
return;
@@ -76,33 +81,33 @@ public class ParserErrorHandlingTest {
@Parameters(name = "{0}")
public static Collection<Object[]> parameters() {
return Arrays.asList(new Object[][] {
- { "1", null, new CharType[] { DOT } },
- { "1 ", ' ', new CharType[] { DOT } },
- { "1.", null, new CharType[] { DIGIT } },
- { "1.2", null, new CharType[] { DOT } },
- { "1.2.", null, new CharType[] { DIGIT } },
- { "a.b.c", 'a', new CharType[] { DIGIT } },
- { "1.b.c", 'b', new CharType[] { DIGIT } },
- { "1.2.c", 'c', new CharType[] { DIGIT } },
- { "!.2.3", '!', new CharType[] { DIGIT } },
- { "1.!.3", '!', new CharType[] { DIGIT } },
- { "1.2.!", '!', new CharType[] { DIGIT } },
- { "v1.2.3", 'v', new CharType[] { DIGIT } },
- { "1.2.3-", null, new CharType[] { DIGIT, LETTER, HYPHEN } },
- { "1.2. 3", ' ', new CharType[] { DIGIT } },
- { "1.2.3=alpha", '=', new CharType[] { HYPHEN, PLUS, EOL } },
- { "1.2.3~beta", '~', new CharType[] { HYPHEN, PLUS, EOL } },
- { "1.2.3-be$ta", '$', new CharType[] { PLUS, EOL } },
- { "1.2.3+b1+b2", '+', new CharType[] { EOL } },
- { "1.2.3-rc!", '!', new CharType[] { PLUS, EOL } },
- { "1.2.3-+", '+', new CharType[] { DIGIT, LETTER, HYPHEN } },
- { "1.2.3-@", '@', new CharType[] { DIGIT, LETTER, HYPHEN } },
- { "1.2.3+@", '@', new CharType[] { DIGIT, LETTER, HYPHEN } },
- { "1.2.3-rc1.", null, new CharType[] { DIGIT, LETTER, HYPHEN } },
- { "1.2.3+20140620.", null, new CharType[] { DIGIT, LETTER, HYPHEN } },
- { "1.2.3-b.+b", '+', new CharType[] { DIGIT, LETTER, HYPHEN } },
- { "1.2.3-rc..", '.', new CharType[] { DIGIT, LETTER, HYPHEN } },
- { "1.2.3-rc+bld..", '.', new CharType[] { DIGIT, LETTER, HYPHEN } },
+ { "1", null, 1, new CharType[] { DOT } },
+ { "1 ", ' ', 1, new CharType[] { DOT } },
+ { "1.", null, 2, new CharType[] { DIGIT } },
+ { "1.2", null, 3, new CharType[] { DOT } },
+ { "1.2.", null, 4, new CharType[] { DIGIT } },
+ { "a.b.c", 'a', 0, new CharType[] { DIGIT } },
+ { "1.b.c", 'b', 2, new CharType[] { DIGIT } },
+ { "1.2.c", 'c', 4, new CharType[] { DIGIT } },
+ { "!.2.3", '!', 0, new CharType[] { DIGIT } },
+ { "1.!.3", '!', 2, new CharType[] { DIGIT } },
+ { "1.2.!", '!', 4, new CharType[] { DIGIT } },
+ { "v1.2.3", 'v', 0, new CharType[] { DIGIT } },
+ { "1.2.3-", null, 6, new CharType[] { DIGIT, LETTER, HYPHEN } },
+ { "1.2. 3", ' ', 4, new CharType[] { DIGIT } },
+ { "1.2.3=alpha", '=', 5, new CharType[] { HYPHEN, PLUS, EOL } },
+ { "1.2.3~beta", '~', 5, new CharType[] { HYPHEN, PLUS, EOL } },
+ { "1.2.3-be$ta", '$', 8, new CharType[] { PLUS, EOL } },
+ { "1.2.3+b1+b2", '+', 8, new CharType[] { EOL } },
+ { "1.2.3-rc!", '!', 8, new CharType[] { PLUS, EOL } },
+ { "1.2.3-+", '+', 6, new CharType[] { DIGIT, LETTER, HYPHEN } },
+ { "1.2.3-@", '@', 6, new CharType[] { DIGIT, LETTER, HYPHEN } },
+ { "1.2.3+@", '@', 6, new CharType[] { DIGIT, LETTER, HYPHEN } },
+ { "1.2.3-rc.", null, 9, new CharType[] { DIGIT, LETTER, HYPHEN } },
+ { "1.2.3+b.", null, 8, new CharType[] { DIGIT, LETTER, HYPHEN } },
+ { "1.2.3-b.+b", '+', 8, new CharType[] { DIGIT, LETTER, HYPHEN } },
+ { "1.2.3-rc..", '.', 9, new CharType[] { DIGIT, LETTER, HYPHEN } },
+ { "1.2.3-a+b..", '.', 10, new CharType[] { DIGIT, LETTER, HYPHEN } },
});
}
}
diff --git a/src/test/java/com/github/zafarkhaja/semver/util/StreamTest.java b/src/test/java/com/github/zafarkhaja/semver/util/StreamTest.java
index 4a43aaa..1a00831 100644
--- a/src/test/java/com/github/zafarkhaja/semver/util/StreamTest.java
+++ b/src/test/java/com/github/zafarkhaja/semver/util/StreamTest.java
@@ -228,4 +228,17 @@ public class StreamTest {
stream.pushBack();
assertEquals(Character.valueOf('a'), stream.consume());
}
+
+ @Test
+ public void shouldKeepTrackOfCurrentOffset() {
+ Stream<Character> stream = new Stream<Character>(
+ new Character[] {'a', 'b', 'c'}
+ );
+ assertEquals(0, stream.currentOffset());
+ stream.consume();
+ assertEquals(1, stream.currentOffset());
+ stream.consume();
+ stream.consume();
+ assertEquals(3, stream.currentOffset());
+ }
}
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/jsemver.git
More information about the pkg-java-commits
mailing list