Skip to content

Commit 962eaa9

Browse files
committed
Reorganise syntax errors and parse position.
This moves the parse position information into a separate class, including a toString() method for exception handling. Instead of delegating the creation of JSONParseException up to the scanner, just request parse position object instead.
1 parent e679b77 commit 962eaa9

6 files changed

Lines changed: 262 additions & 211 deletions

File tree

‎JSONParseException.java‎

Lines changed: 13 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -33,54 +33,28 @@ of this software and associated documentation files (the "Software"), to deal
3333
*/
3434
public class JSONParseException extends JSONException {
3535
private static final long serialVersionUID = 8010183095901970945L;
36+
private final ParsePosition position;
3637

37-
private final long position;
38-
private final long column;
39-
private final long line;
40-
private final char character;
41-
42-
public JSONParseException(String message, long position, long column, long line, char character) {
43-
super(message + getPositionDetails(position, column, line));
44-
this.position = position;
45-
this.column = column;
46-
this.line = line;
47-
this.character = character;
48-
}
49-
50-
public JSONParseException(String message, Throwable cause, long position, long column, long line, char character) {
51-
super(message + getPositionDetails(position, column, line), cause);
52-
this.position = position;
53-
this.column = column;
54-
this.line = line;
55-
this.character = character;
38+
public JSONParseException(String message, ParsePosition pos) {
39+
super(message + ' ' + pos.getPositionDetails());
40+
this.position = pos;
5641
}
5742

58-
public JSONParseException(Throwable cause, long position, long column, long line, char character) {
59-
super(getPositionDetails(position, column, line), cause);
60-
this.position = position;
61-
this.column = column;
62-
this.line = line;
63-
this.character = character;
43+
public JSONParseException(String message, Throwable cause, ParsePosition pos) {
44+
super(message + ' ' + pos.getPositionDetails(), cause);
45+
this.position = pos;
6446
}
6547

66-
private static String getPositionDetails(long position, long column, long line) {
67-
return " at " + position + " [character " + column + " line " +
68-
line + ']';
48+
public JSONParseException(Throwable cause, ParsePosition pos) {
49+
super(pos.getPositionDetails(), cause);
50+
this.position = pos;
6951
}
7052

71-
public long getPosition() {
53+
public ParsePosition getPosition() {
7254
return position;
7355
}
7456

75-
public long getColumn() {
76-
return column;
77-
}
78-
79-
public long getLine() {
80-
return line;
81-
}
82-
83-
public char getCharacter() {
84-
return character;
57+
public String getPositionDetails() {
58+
return position.getPositionDetails();
8559
}
8660
}

‎ParsePosition.java‎

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
package org.json;
2+
3+
/*
4+
Copyright (c) 2002 JSON.org
5+
6+
Permission is hereby granted, free of charge, to any person obtaining a copy
7+
of this software and associated documentation files (the "Software"), to deal
8+
in the Software without restriction, including without limitation the rights
9+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
copies of the Software, and to permit persons to whom the Software is
11+
furnished to do so, subject to the following conditions:
12+
13+
The above copyright notice and this permission notice shall be included in all
14+
copies or substantial portions of the Software.
15+
16+
The Software shall be used for Good, not Evil.
17+
18+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24+
SOFTWARE.
25+
*/
26+
27+
/**
28+
* Represents location information for the current location of the
29+
* {@code Scanner}. This is immutable position data, so represents a
30+
* point-in-time during the scanning process.
31+
*
32+
* @author JSON.org
33+
* @version 2016-7-12
34+
*/
35+
public class ParsePosition {
36+
37+
private final long position;
38+
private final long column;
39+
private final long line;
40+
private final char lastCharacter;
41+
42+
public ParsePosition(long position, long column, long line, char lastCharacter) {
43+
this.position = position;
44+
this.column = column;
45+
this.line = line;
46+
this.lastCharacter = lastCharacter;
47+
}
48+
49+
/**
50+
* Get the absolute position relative to the start of the parsed stream.
51+
*
52+
* @return the scanner position
53+
*/
54+
public long getPosition() {
55+
return position;
56+
}
57+
58+
/**
59+
* Get the column position for the location in the parsed stream.
60+
*
61+
* @return the scanner column position
62+
*/
63+
public long getColumn() {
64+
return column;
65+
}
66+
67+
/**
68+
* Get the line position for the location in the parsed stream.
69+
*
70+
* @return the scanner line position
71+
*/
72+
public long getLine() {
73+
return line;
74+
}
75+
76+
/**
77+
* Get the most recent character parsed by the scanner.
78+
*
79+
* @return the most recent character
80+
*/
81+
public char getLastCharacter() {
82+
return lastCharacter;
83+
}
84+
85+
/**
86+
* Get a String representation of the parse position.
87+
*
88+
* @return the parse position as a String
89+
*/
90+
public String getPositionDetails() {
91+
return "at " + this.position + " [character " + this.column + " line " +
92+
this.line + "]";
93+
}
94+
95+
/**
96+
* Returns a string representation of the parse position.
97+
*
98+
* @return a string representation of the parse position
99+
*/
100+
@Override
101+
public String toString() {
102+
return getPositionDetails();
103+
}
104+
}

‎Scanner.java‎

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ public String nextTo(String delimiters) throws JSONException {
317317
* @return A JSONException object, suitable for throwing
318318
*/
319319
public JSONException syntaxError(String message) {
320-
return new JSONParseException(message, index, character, line, previous);
320+
return new JSONParseException(message, parsePosition());
321321
}
322322

323323

@@ -328,7 +328,7 @@ public JSONException syntaxError(String message) {
328328
* @return A JSONException object, suitable for throwing
329329
*/
330330
public JSONException syntaxError(Throwable cause) {
331-
return new JSONParseException(cause, index, character, line, previous);
331+
return new JSONParseException(cause, parsePosition());
332332
}
333333

334334

@@ -340,7 +340,19 @@ public JSONException syntaxError(Throwable cause) {
340340
* @return A JSONException object, suitable for throwing
341341
*/
342342
public JSONException syntaxError(String message, Throwable cause) {
343-
return new JSONParseException(message, cause, index, character, line, previous);
343+
return new JSONParseException(message, cause, parsePosition());
344+
}
345+
346+
347+
/**
348+
* Get an object representing the current parse position. The object
349+
* represents a point-in-time during the parse.
350+
*
351+
* @return a {@code ParsePosition} representing the current location of
352+
* the scanner
353+
*/
354+
public ParsePosition parsePosition() {
355+
return new ParsePosition(index, character, line, previous);
344356
}
345357

346358

‎stream/JSONLexer.java‎

Lines changed: 22 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ of this software and associated documentation files (the "Software"), to deal
2525
*/
2626

2727
import org.json.JSONException;
28+
import org.json.JSONParseException;
29+
import org.json.ParsePosition;
2830
import org.json.Scanner;
2931

3032
import java.io.IOException;
@@ -114,7 +116,7 @@ private char nextClean() throws JSONException {
114116
if (scanner.end()) {
115117
return c;
116118
} else {
117-
throw scanner.syntaxError("Illegal control code");
119+
throw new JSONParseException("Illegal control code", scanner.parsePosition());
118120
}
119121
case (char)1:
120122
case (char)2:
@@ -144,7 +146,7 @@ private char nextClean() throws JSONException {
144146
case (char)29:
145147
case (char)30:
146148
case (char)31:
147-
throw scanner.syntaxError("Illegal control code");
149+
throw new JSONParseException("Illegal control code", scanner.parsePosition());
148150
case (char)9: // \t
149151
case (char)10: // \n
150152
case (char)13: // \r
@@ -216,7 +218,7 @@ public Token nextTokenType() throws JSONException {
216218
scanner.back();
217219
return Token.NUMBER_VALUE;
218220
default:
219-
throw scanner.syntaxError("Unexpected value");
221+
throw new JSONParseException("Unexpected value", scanner.parsePosition());
220222
}
221223
}
222224

@@ -244,7 +246,7 @@ public <T extends Appendable> T nextString(T sb) throws JSONException {
244246
case (char)0:
245247
case (char)10: // \n
246248
case (char)13: // \r
247-
throw scanner.syntaxError("Unterminated string");
249+
throw new JSONParseException("Unterminated string", scanner.parsePosition());
248250
case (char)1:
249251
case (char)2:
250252
case (char)3:
@@ -274,7 +276,7 @@ public <T extends Appendable> T nextString(T sb) throws JSONException {
274276
case (char)29:
275277
case (char)30:
276278
case (char)31:
277-
throw scanner.syntaxError("Unescaped control code");
279+
throw new JSONParseException("Unescaped control code", scanner.parsePosition());
278280
case '\\':
279281
c = scanner.next();
280282
switch (c) {
@@ -306,7 +308,7 @@ public <T extends Appendable> T nextString(T sb) throws JSONException {
306308
sb.append(c);
307309
break;
308310
default:
309-
throw scanner.syntaxError("Illegal escape");
311+
throw new JSONParseException("Illegal escape", scanner.parsePosition());
310312
}
311313
break;
312314
case '"':
@@ -352,7 +354,7 @@ public boolean nextNumber(Appendable sb) throws JSONException {
352354
c = scanner.next();
353355
}
354356
} else {
355-
throw scanner.syntaxError("Expected number");
357+
throw new JSONParseException("Expected number", scanner.parsePosition());
356358
}
357359

358360
if(c == '.') {
@@ -380,7 +382,7 @@ public boolean nextNumber(Appendable sb) throws JSONException {
380382
sb.append(c);
381383
c = scanner.next();
382384
} else {
383-
throw scanner.syntaxError("Expected exponent value");
385+
throw new JSONParseException("Expected exponent value", scanner.parsePosition());
384386
}
385387
while((c >= '0') && (c <= '9')) {
386388
sb.append(c);
@@ -446,7 +448,7 @@ public Number nextNumber() throws JSONException {
446448
// fall through
447449
}
448450
}
449-
throw scanner.syntaxError("Could not parse number");
451+
throw new JSONParseException("Could not parse number", scanner.parsePosition());
450452
}
451453

452454
/**
@@ -464,7 +466,7 @@ public BigDecimal nextBigDecimal() throws JSONException {
464466
} catch (Exception exception) {
465467
// fall through
466468
}
467-
throw scanner.syntaxError("Could not parse big decimal");
469+
throw new JSONParseException("Could not parse big decimal", scanner.parsePosition());
468470
}
469471

470472
/**
@@ -484,7 +486,7 @@ public BigInteger nextBigInteger() throws JSONException {
484486
// fall through
485487
}
486488
}
487-
throw scanner.syntaxError("Could not parse big integer");
489+
throw new JSONParseException("Could not parse big integer", scanner.parsePosition());
488490
}
489491

490492
/**
@@ -509,7 +511,7 @@ public double nextDouble() throws JSONException {
509511
} catch (Exception ignore) {
510512
// fall through
511513
}
512-
throw scanner.syntaxError("Could not parse double");
514+
throw new JSONParseException("Could not parse double", scanner.parsePosition());
513515
}
514516

515517
/**
@@ -530,7 +532,7 @@ public int nextInt() throws JSONException {
530532
} catch (Exception ignore) {
531533
// fall through
532534
}
533-
throw scanner.syntaxError("Could not parse int");
535+
throw new JSONParseException("Could not parse int", scanner.parsePosition());
534536
}
535537

536538
/**
@@ -551,47 +553,17 @@ public long nextLong() throws JSONException {
551553
} catch (Exception ignore) {
552554
// fall through
553555
}
554-
throw scanner.syntaxError("Could not parse int");
556+
throw new JSONParseException("Could not parse int", scanner.parsePosition());
555557
}
556558

557559
/**
558-
* Make a {@code JSONException} to signal a syntax error.
560+
* Indicates the current position of the scanner.
559561
*
560-
* @param message The error message.
561-
* @return A JSONException object, suitable for throwing
562+
* @return a {@code ParsePosition} representing the current location of
563+
* the scanner
562564
*/
563-
public JSONException syntaxError(String message) {
564-
return scanner.syntaxError(message);
565-
}
566-
567-
/**
568-
* Make a {@code JSONException} to signal a syntax error.
569-
*
570-
* @param message The error message.
571-
* @param cause The underlying cause.
572-
* @return A JSONException object, suitable for throwing
573-
*/
574-
public JSONException syntaxError(String message, Throwable cause) {
575-
return scanner.syntaxError(message, cause);
576-
}
577-
578-
/**
579-
* Make a {@code JSONException} to signal a syntax error.
580-
*
581-
* @param cause The underlying cause.
582-
* @return A JSONException object, suitable for throwing
583-
*/
584-
public JSONException syntaxError(Throwable cause) {
585-
return scanner.syntaxError(cause);
586-
}
587-
588-
/**
589-
* Indicates the current position of the lexer.
590-
*
591-
* @return a String of the current position
592-
*/
593-
public String position() {
594-
return scanner.toString();
565+
public ParsePosition parsePosition() {
566+
return scanner.parsePosition();
595567
}
596568

597569
/**
@@ -601,6 +573,6 @@ public String position() {
601573
*/
602574
@Override
603575
public String toString() {
604-
return "JSONLexer" + scanner.toString();
576+
return "JSONLexer " + scanner.parsePosition().getPositionDetails();
605577
}
606578
}

0 commit comments

Comments
 (0)