|
@@ -97,7 +97,7 @@ namespace Jint.Native.Json
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- ExceptionHelper.ThrowSyntaxError(_engine.Realm, $"Expected hexadecimal digit:{_source}");
|
|
|
+ ThrowError(_index, Messages.ExpectedHexadecimalDigit);
|
|
|
}
|
|
|
}
|
|
|
return (char)code;
|
|
@@ -142,17 +142,19 @@ namespace Jint.Native.Json
|
|
|
case 126: // ~
|
|
|
++_index;
|
|
|
|
|
|
+ string value = TypeConverter.ToString(code);
|
|
|
return new Token
|
|
|
- {
|
|
|
- Type = Tokens.Punctuator,
|
|
|
- Value = TypeConverter.ToString(code),
|
|
|
- LineNumber = _lineNumber,
|
|
|
- LineStart = _lineStart,
|
|
|
- Range = new[] {start, _index}
|
|
|
- };
|
|
|
+ {
|
|
|
+ Type = Tokens.Punctuator,
|
|
|
+ Text = value,
|
|
|
+ Value = value,
|
|
|
+ LineNumber = _lineNumber,
|
|
|
+ LineStart = _lineStart,
|
|
|
+ Range = new[] { start, _index }
|
|
|
+ };
|
|
|
}
|
|
|
|
|
|
- ExceptionHelper.ThrowSyntaxError(_engine.Realm, string.Format(Messages.UnexpectedToken, code));
|
|
|
+ ThrowError(start, Messages.UnexpectedToken, code);
|
|
|
return null;
|
|
|
}
|
|
|
|
|
@@ -182,7 +184,7 @@ namespace Jint.Native.Json
|
|
|
// decimal number starts with '0' such as '09' is illegal.
|
|
|
if (ch > 0 && IsDecimalDigit(ch))
|
|
|
{
|
|
|
- ExceptionHelper.ThrowSyntaxError(_engine.Realm, string.Format(Messages.UnexpectedToken, ch));
|
|
|
+ ThrowError(_index, Messages.UnexpectedToken, ch);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -221,13 +223,14 @@ namespace Jint.Native.Json
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- ExceptionHelper.ThrowSyntaxError(_engine.Realm, string.Format(Messages.UnexpectedToken, _source.CharCodeAt(_index)));
|
|
|
+ ThrowError(_index, Messages.UnexpectedToken, _source.CharCodeAt(_index));
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return new Token
|
|
|
{
|
|
|
Type = Tokens.Number,
|
|
|
+ Text = number,
|
|
|
Value = Double.Parse(number, NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint | NumberStyles.AllowExponent, CultureInfo.InvariantCulture),
|
|
|
LineNumber = _lineNumber,
|
|
|
LineStart = _lineStart,
|
|
@@ -250,6 +253,7 @@ namespace Jint.Native.Json
|
|
|
return new Token
|
|
|
{
|
|
|
Type = Tokens.BooleanLiteral,
|
|
|
+ Text = s,
|
|
|
Value = s == "true",
|
|
|
LineNumber = _lineNumber,
|
|
|
LineStart = _lineStart,
|
|
@@ -257,7 +261,7 @@ namespace Jint.Native.Json
|
|
|
};
|
|
|
}
|
|
|
|
|
|
- ExceptionHelper.ThrowSyntaxError(_engine.Realm, string.Format(Messages.UnexpectedToken, s));
|
|
|
+ ThrowError(start, Messages.UnexpectedToken, s);
|
|
|
return null;
|
|
|
}
|
|
|
|
|
@@ -276,6 +280,7 @@ namespace Jint.Native.Json
|
|
|
return new Token
|
|
|
{
|
|
|
Type = Tokens.NullLiteral,
|
|
|
+ Text = s,
|
|
|
Value = Null.Instance,
|
|
|
LineNumber = _lineNumber,
|
|
|
LineStart = _lineStart,
|
|
@@ -283,7 +288,7 @@ namespace Jint.Native.Json
|
|
|
};
|
|
|
}
|
|
|
|
|
|
- ExceptionHelper.ThrowSyntaxError(_engine.Realm, string.Format(Messages.UnexpectedToken, s));
|
|
|
+ ThrowError(start, Messages.UnexpectedToken, s);
|
|
|
return null;
|
|
|
}
|
|
|
|
|
@@ -308,7 +313,7 @@ namespace Jint.Native.Json
|
|
|
|
|
|
if (ch <= 31)
|
|
|
{
|
|
|
- ExceptionHelper.ThrowSyntaxError(_engine.Realm, $"Invalid character '{ch}', position:{_index}, string:{_source}");
|
|
|
+ ThrowError(_index - 1, Messages.InvalidCharacter);
|
|
|
}
|
|
|
|
|
|
if (ch == '\\')
|
|
@@ -400,16 +405,19 @@ namespace Jint.Native.Json
|
|
|
|
|
|
if (quote != 0)
|
|
|
{
|
|
|
- ExceptionHelper.ThrowSyntaxError(_engine.Realm, string.Format(Messages.UnexpectedToken, _source));
|
|
|
+ // unterminated string literal
|
|
|
+ ThrowError(_index, Messages.UnexpectedEOS);
|
|
|
}
|
|
|
|
|
|
+ string value = sb.ToString();
|
|
|
return new Token
|
|
|
- {
|
|
|
+ {
|
|
|
Type = Tokens.String,
|
|
|
- Value = sb.ToString(),
|
|
|
+ Text = value,
|
|
|
+ Value = value,
|
|
|
LineNumber = _lineNumber,
|
|
|
LineStart = _lineStart,
|
|
|
- Range = new[] {start, _index}
|
|
|
+ Range = new[] { start, _index }
|
|
|
};
|
|
|
}
|
|
|
|
|
@@ -502,6 +510,7 @@ namespace Jint.Native.Json
|
|
|
_extra.Tokens.Add(new Token
|
|
|
{
|
|
|
Type = token.Type,
|
|
|
+ Text = value,
|
|
|
Value = value,
|
|
|
Range = range,
|
|
|
});
|
|
@@ -604,17 +613,13 @@ namespace Jint.Native.Json
|
|
|
|
|
|
private void ThrowError(Token token, string messageFormat, params object[] arguments)
|
|
|
{
|
|
|
- string msg = System.String.Format(messageFormat, arguments);
|
|
|
- int lineNumber = token.LineNumber ?? _lineNumber;
|
|
|
-
|
|
|
- var error = new ParseError(
|
|
|
- description: msg,
|
|
|
- source: _source,
|
|
|
- index: token.Range[0],
|
|
|
- position: new Position(token.LineNumber ?? _lineNumber, token.Range[0] - _lineStart + 1));
|
|
|
- var exception = new ParserException("Line " + lineNumber + ": " + msg, error);
|
|
|
+ ThrowError(token.Range[0], messageFormat, arguments);
|
|
|
+ }
|
|
|
|
|
|
- throw exception;
|
|
|
+ private void ThrowError(int position, string messageFormat, params object[] arguments)
|
|
|
+ {
|
|
|
+ string msg = System.String.Format(messageFormat, arguments);
|
|
|
+ ExceptionHelper.ThrowSyntaxError(_engine.Realm, $"{msg} at position {position}");
|
|
|
}
|
|
|
|
|
|
// Throw an exception because of the token.
|
|
@@ -637,7 +642,7 @@ namespace Jint.Native.Json
|
|
|
}
|
|
|
|
|
|
// BooleanLiteral, NullLiteral, or Punctuator.
|
|
|
- ThrowError(token, Messages.UnexpectedToken, token.Value as string);
|
|
|
+ ThrowError(token, Messages.UnexpectedToken, token.Text);
|
|
|
}
|
|
|
|
|
|
// Expect the next token to match the specified punctuator.
|
|
@@ -702,10 +707,11 @@ namespace Jint.Native.Json
|
|
|
ThrowUnexpected(Lex());
|
|
|
}
|
|
|
|
|
|
- var name = Lex().Value.ToString();
|
|
|
+ var nameToken = Lex();
|
|
|
+ var name = nameToken.Value.ToString();
|
|
|
if (PropertyNameContainsInvalidCharacters(name))
|
|
|
{
|
|
|
- ExceptionHelper.ThrowSyntaxError(_engine.Realm, $"Invalid character in property name '{name}'");
|
|
|
+ ThrowError(nameToken, Messages.InvalidCharacter);
|
|
|
}
|
|
|
|
|
|
Expect(":");
|
|
@@ -828,7 +834,7 @@ namespace Jint.Native.Json
|
|
|
|
|
|
if(_lookahead.Type != Tokens.EOF)
|
|
|
{
|
|
|
- ExceptionHelper.ThrowSyntaxError(_engine.Realm, $"Unexpected {_lookahead.Type} {_lookahead.Value}");
|
|
|
+ ThrowError(_lookahead, Messages.UnexpectedToken, _lookahead.Text);
|
|
|
}
|
|
|
return jsv;
|
|
|
}
|
|
@@ -860,6 +866,7 @@ namespace Jint.Native.Json
|
|
|
{
|
|
|
public Tokens Type;
|
|
|
public object Value;
|
|
|
+ public string Text;
|
|
|
public int[] Range;
|
|
|
public int? LineNumber;
|
|
|
public int LineStart;
|
|
@@ -867,10 +874,12 @@ namespace Jint.Native.Json
|
|
|
|
|
|
static class Messages
|
|
|
{
|
|
|
- public const string UnexpectedToken = "Unexpected token '{0}'";
|
|
|
- public const string UnexpectedNumber = "Unexpected number";
|
|
|
- public const string UnexpectedString = "Unexpected string";
|
|
|
- public const string UnexpectedEOS = "Unexpected end of input";
|
|
|
+ public const string InvalidCharacter = "Invalid character in JSON";
|
|
|
+ public const string ExpectedHexadecimalDigit = "Expected hexadecimal digit in JSON";
|
|
|
+ public const string UnexpectedToken = "Unexpected token '{0}' in JSON";
|
|
|
+ public const string UnexpectedNumber = "Unexpected number in JSON";
|
|
|
+ public const string UnexpectedString = "Unexpected string in JSON";
|
|
|
+ public const string UnexpectedEOS = "Unexpected end of JSON input";
|
|
|
};
|
|
|
|
|
|
struct State
|