[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