Skip to content

Commit

Permalink
Replace the JSON.parse and JSON.stringify error messages with inl…
Browse files Browse the repository at this point in the history
…ine comments. Closes bestiejs#5.
  • Loading branch information
Kit Cambridge committed Apr 19, 2012
1 parent 54ad5b5 commit 67ccecb
Showing 1 changed file with 61 additions and 44 deletions.
105 changes: 61 additions & 44 deletions lib/json3.js
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@
for (property in members) {
// Ignore all other properties inherited from `Object.prototype`.
if (isPropertyOf.call(members, property)) {
size += 1;
size++;
}
}
Properties = members = null;
Expand Down Expand Up @@ -278,7 +278,7 @@
// `Quote(value)` operation defined in ES 5.1 section 15.12.3.
quote = function (value) {
var result = '"', index = 0, symbol;
for (; symbol = value.charAt(index); index += 1) {
for (; symbol = value.charAt(index); index++) {
// Escape the reverse solidus, double quote, backspace, form feed, line
// feed, carriage return, and tab characters.
result += '\\"\b\f\n\r\t'.indexOf(symbol) > -1 ? Escapes[symbol] :
Expand All @@ -304,8 +304,8 @@
// methods are buggy. Adapted from @Yaffle's `date-shim`
// project.
date = floor(value / 864e5);
for (year = floor(date / 365.2425) + 1970 - 1; getDay(year + 1, 0) <= date; year += 1);
for (month = floor((date - getDay(year, 0)) / 30.42); getDay(year, month + 1) <= date; month += 1);
for (year = floor(date / 365.2425) + 1970 - 1; getDay(year + 1, 0) <= date; year++);
for (month = floor((date - getDay(year, 0)) / 30.42); getDay(year, month + 1) <= date; month++);
date = 1 + date - getDay(year, month);
} else {
year = value.getUTCFullYear();
Expand Down Expand Up @@ -354,7 +354,8 @@
// is inversely proportional to the number of unique nested objects.
for (length = stack.length; length--;) {
if (stack[length] == value) {
throw TypeError("Cyclic structures cannot be serialized.");
// Cyclic structures cannot be serialized by `JSON.stringify`.
throw TypeError();
}
}
// Add the object to the stack of traversed objects.
Expand Down Expand Up @@ -460,7 +461,7 @@
case "\r":
case "\n":
case " ":
this.index += 1;
this.index++;
break;
// Parse a punctuator token at the current position.
case "{":
Expand All @@ -469,43 +470,45 @@
case "]":
case ":":
case ",":
this.index += 1;
this.index++;
return symbol;
// Parse a JSON string token at the current position. String tokens
// are prefixed with the sentinel `@` character to distinguish them
// from punctuators.
case '"':
// Advance to the first character.
for (value = "@", this.index += 1; this.index < length;) {
for (value = "@", this.index++; this.index < length;) {
symbol = source.charAt(this.index);
if (symbol < " ") {
// Unescaped ASCII control characters are not permitted.
throw SyntaxError("Unescaped control character in string.");
throw SyntaxError();
} else if (symbol == "\\") {
// Parse escaped JSON control characters, `"`, `\`, `/`, and
// Unicode escape sequences.
this.index += 1;
this.index++;
symbol = source.charAt(this.index);
if ('\\"/btnfr'.indexOf(symbol) > -1) {
// Revive escaped control characters.
value += Unescapes[symbol];
this.index += 1;
this.index++;
} else if (symbol == "u") {
// Advance to the first character of the escape sequence.
begin = this.index += 1;
begin = ++this.index;
// Validate the Unicode escape sequence.
for (position = this.index + 4; this.index < position; this.index += 1) {
for (position = this.index + 4; this.index < position; this.index++) {
symbol = source.charAt(this.index);
// A valid sequence comprises four hexdigits that form a
// single hexadecimal value.
if (!(symbol >= "0" && symbol <= "9" || symbol >= "a" && symbol <= "f" || symbol >= "A" && symbol <= "F")) {
throw SyntaxError("Invalid Unicode escape sequence in string.");
// Invalid Unicode escape sequence.
throw SyntaxError();
}
}
// Revive the escaped character.
value += fromCharCode("0x" + source.slice(begin, this.index));
} else {
throw SyntaxError("Invalid escape sequence in string.");
// Invalid escape sequence.
throw SyntaxError();
}
} else {
if (symbol == '"') {
Expand All @@ -515,41 +518,44 @@
}
// Append the original character as-is.
value += symbol;
this.index += 1;
this.index++;
}
}
if (source.charAt(this.index) == '"') {
this.index += 1;
this.index++;
// Return the revived string.
return value;
}
throw SyntaxError("Unterminated string.");
// Unterminated string.
throw SyntaxError();
// Parse numbers and literals.
default:
begin = this.index;
// Advance the scanner's position past the sign, if one is
// specified.
if (symbol == "-") {
sign = true;
symbol = source.charAt(this.index += 1);
symbol = source.charAt(++this.index);
}
// Parse an integer or floating-point value.
if (symbol >= "0" && symbol <= "9") {
// Leading zeroes are interpreted as octal literals.
if (symbol == "0" && (symbol = source.charAt(this.index + 1), symbol >= "0" && symbol <= "9")) {
throw SyntaxError("Illegal octal literal.");
// Illegal octal literal.
throw SyntaxError();
}
sign = false;
// Parse the integer component.
for (; this.index < length && (symbol = source.charAt(this.index), symbol >= "0" && symbol <= "9"); this.index += 1);
for (; this.index < length && (symbol = source.charAt(this.index), symbol >= "0" && symbol <= "9"); this.index++);
// Floats cannot contain a leading decimal point; however, this
// case is already accounted for by the parser.
if (source.charAt(this.index) == ".") {
position = this.index += 1;
position = ++this.index;
// Parse the decimal component.
for (; position < length && (symbol = source.charAt(position), symbol >= "0" && symbol <= "9"); position += 1);
for (; position < length && (symbol = source.charAt(position), symbol >= "0" && symbol <= "9"); position++);
if (position == this.index) {
throw SyntaxError("Illegal trailing decimal.");
// Illegal trailing decimal.
throw SyntaxError();
}
this.index = position;
}
Expand All @@ -558,14 +564,15 @@
if (symbol == "e" || symbol == "E") {
// Skip past the sign following the exponent, if one is
// specified.
symbol = source.charAt(this.index += 1);
symbol = source.charAt(++this.index);
if (symbol == "+" || symbol == "-") {
this.index += 1;
this.index++;
}
// Parse the exponential component.
for (position = this.index; position < length && (symbol = source.charAt(position), symbol >= "0" && symbol <= "9"); position += 1);
for (position = this.index; position < length && (symbol = source.charAt(position), symbol >= "0" && symbol <= "9"); position++);
if (position == this.index) {
throw SyntaxError("Illegal empty exponent.");
// Illegal empty exponent.
throw SyntaxError();
}
this.index = position;
}
Expand All @@ -574,20 +581,21 @@
}
// A negative sign may only precede numbers.
if (sign) {
throw SyntaxError("Unexpected `-`.");
throw SyntaxError();
}
// `true`, `false`, and `null` literals.
if (symbol == "t" && source.slice(this.index, this.index + 4) == "true") {
if (source.slice(this.index, this.index + 4) == "true") {
this.index += 4;
return true;
} else if (symbol == "f" && source.slice(this.index, this.index + 5) == "false") {
} else if (source.slice(this.index, this.index + 5) == "false") {
this.index += 5;
return false;
} else if (symbol == "n" && source.slice(this.index, this.index + 4) == "null") {
} else if (source.slice(this.index, this.index + 4) == "null") {
this.index += 4;
return null;
}
throw SyntaxError("Unrecognized token.");
// Unrecognized token.
throw SyntaxError();
}
}
// Return the sentinel `$` character if the parser has reached the end
Expand All @@ -599,7 +607,8 @@
Parser.prototype.get = function (value) {
var results, any, key;
if (value == "$") {
throw SyntaxError("Unexpected end-of-file.");
// Unexpected end of input.
throw SyntaxError();
}
if (typeof value == "string") {
if (value.charAt(0) == "@") {
Expand All @@ -624,15 +633,17 @@
if (value == ",") {
value = this.lex();
if (value == "]") {
throw SyntaxError("Unexpected trailing `,` in array literal.");
// Unexpected trailing `,` in array literal.
throw SyntaxError();
}
} else {
throw SyntaxError("A comma (`,`) must separate the previous array element from the next.");
// A `,` must separate each array element.
throw SyntaxError();
}
}
// Elisions and leading commas are not permitted.
if (value == ",") {
throw SyntaxError("Unexpected `,` in array literal.");
throw SyntaxError();
}
results.push(this.get(value));
}
Expand All @@ -652,27 +663,32 @@
if (value == ",") {
value = this.lex();
if (value == "}") {
throw SyntaxError("Unexpected trailing `,`. in object literal.");
// Unexpected trailing `,` in object literal.
throw SyntaxError();
}
} else {
throw SyntaxError("A comma (`,`) must separate the previous object member from the next.");
// A `,` must separate each object member.
throw SyntaxError();
}
}
// Leading commas are not permitted.
if (value == ",") {
throw SyntaxError("Unexpected `,` in object literal.");
throw SyntaxError();
}
if (typeof value != "string" || value.charAt(0) != "@") {
throw SyntaxError("Object property names must be double-quoted strings.");
// Object property names must be double-quoted strings.
throw SyntaxError();
}
if (this.lex() != ":") {
throw SyntaxError("A single colon (`:`) must separate each object property name from the value.");
// A `:` must separate each object property name and value.
throw SyntaxError();
}
results[value.slice(1)] = this.get(this.lex());
}
return results;
}
throw SyntaxError("Expected `[` or `{`.");
// Unexpected token.
throw SyntaxError();
}
return value;
};
Expand Down Expand Up @@ -711,7 +727,8 @@
var parser = new Parser("" + source), result = parser.get(parser.lex()), value;
// If a JSON string contains multiple tokens, it is invalid.
if (parser.lex() != "$") {
throw SyntaxError("Expected end-of-file.");
// Expected end of input.
throw SyntaxError();
}
return callback && getClass.call(callback) == "[object Function]" ? walk((value = {}, value[""] = result, value), "", callback) : result;
};
Expand Down

0 comments on commit 67ccecb

Please sign in to comment.