Skip to content

Commit cb208fb

Browse files
committed
Fix object parsing
1 parent 969bda2 commit cb208fb

File tree

3 files changed

+52
-24
lines changed

3 files changed

+52
-24
lines changed

Sources/JSONPatcher/JSONCParser.swift

+15-14
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ class JSONCParser {
1010
try scanNext()
1111
let value = try parseValue()
1212
guard scanner.token.kind == .eof else {
13-
throw ParsingError.eofExpected(loc: scanner.token.loc)
13+
throw ParsingError.unexpectedToken(loc: scanner.token.loc,
14+
got: scanner.token.kind,
15+
wanted: .eof)
1416
}
1517
return value
1618
}
@@ -35,7 +37,7 @@ class JSONCParser {
3537
case .unknown:
3638
fatalError()
3739
case .eof:
38-
throw ParsingError.valueExpected(loc: token.loc)
40+
throw ParsingError.valueExpected(loc: token.loc, got: .eof)
3941
case .leftBrace:
4042
return try parseObject()
4143
case .leftBracket:
@@ -56,7 +58,7 @@ class JSONCParser {
5658
try scanNext()
5759
return .null(token)
5860
default:
59-
throw ParsingError.unexpectedToken(loc: token.loc, kind: token.kind)
61+
throw ParsingError.unexpectedToken(loc: token.loc, got: token.kind)
6062
}
6163
}
6264

@@ -74,23 +76,22 @@ class JSONCParser {
7476
break parseMembers
7577
case .comma:
7678
if !needsComma {
77-
throw ParsingError.valueExpected(loc: scanner.token.loc)
79+
throw ParsingError.valueExpected(loc: scanner.token.loc, got: .comma)
7880
}
7981
try scanNext() // ,
80-
default:
82+
case let kind:
8183
if needsComma {
82-
throw ParsingError.commaExpected(loc: scanner.token.loc)
84+
throw ParsingError.unexpectedToken(loc: scanner.token.loc, got: kind, wanted: .comma)
8385
}
8486
}
8587

8688
parseMember: do {
8789
guard scanner.token.kind == .string else {
88-
throw ParsingError.memberNameExpected(loc: scanner.token.loc)
90+
throw ParsingError.memberNameExpected(loc: scanner.token.loc, got: scanner.token.kind)
8991
}
9092
let memberName = try parseValue()
91-
try scanNext() // memberName
9293
guard scanner.token.kind == .colon else {
93-
throw ParsingError.colonExpected(loc: scanner.token.loc)
94+
throw ParsingError.unexpectedToken(loc: scanner.token.loc, got: scanner.token.kind, wanted: .colon)
9495
}
9596
try scanNext() // :
9697
let memberValue = try parseValue()
@@ -102,7 +103,7 @@ class JSONCParser {
102103

103104
let rightBrace = scanner.token
104105
guard rightBrace.kind == .rightBrace else {
105-
throw ParsingError.rightBraceExpected(loc: rightBrace.loc)
106+
throw ParsingError.unexpectedToken(loc: rightBrace.loc, got: rightBrace.kind, wanted: .rightBrace)
106107
}
107108
try scanNext() // }
108109

@@ -123,12 +124,12 @@ class JSONCParser {
123124
break parseElements
124125
case .comma:
125126
if !needsComma {
126-
throw ParsingError.valueExpected(loc: scanner.token.loc)
127+
throw ParsingError.valueExpected(loc: scanner.token.loc, got: .comma)
127128
}
128129
try scanNext() // ,
129-
default:
130+
case let kind:
130131
if needsComma {
131-
throw ParsingError.commaExpected(loc: scanner.token.loc)
132+
throw ParsingError.unexpectedToken(loc: scanner.token.loc, got: kind, wanted: .comma)
132133
}
133134
}
134135

@@ -142,7 +143,7 @@ class JSONCParser {
142143

143144
let rightBracket = scanner.token
144145
guard rightBracket.kind == .rightBracket else {
145-
throw ParsingError.rightBracketExpected(loc: rightBracket.loc)
146+
throw ParsingError.unexpectedToken(loc: rightBracket.loc, got: rightBracket.kind, wanted: .rightBracket)
146147
}
147148
try scanNext() // ]
148149

Sources/JSONPatcher/Scanner.swift

+3-8
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,7 @@ enum ParsingError: Error {
6262
case invalidCharacter(loc: Loc, character: Character)
6363
case unexpectedEndOfString(loc: Loc)
6464
case invalidNumberDigit(loc: Loc, character: Character)
65-
case valueExpected(loc: Loc)
66-
case unexpectedToken(loc: Loc, kind: JSONCScanner.Token.Kind)
67-
case commaExpected(loc: Loc)
68-
case memberNameExpected(loc: Loc)
69-
case colonExpected(loc: Loc)
70-
case rightBraceExpected(loc: Loc)
71-
case rightBracketExpected(loc: Loc)
72-
case eofExpected(loc: Loc)
65+
case unexpectedToken(loc: Loc, got: JSONCScanner.Token.Kind, wanted: JSONCScanner.Token.Kind? = nil)
66+
case valueExpected(loc: Loc, got: JSONCScanner.Token.Kind)
67+
case memberNameExpected(loc: Loc, got: JSONCScanner.Token.Kind)
7368
}

Tests/JSONPatcherTests/JSONCParserTests.swift

+34-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,39 @@ final class JSONCParserTests: XCTestCase {
66
continueAfterFailure = false
77
}
88

9-
func testParse() throws {
10-
XCTAssertEqual(try JSONCParser(jsoncString: "//comment\n[1, 42.0, /*\"Hello\", */\"World\"]").parse().encode(), "[1,42.0,\"World\"]")
9+
// https://github.com/microsoft/node-jsonc-parser/blob/main/src/test/json.test.ts
10+
func testParseLiterals() throws {
11+
try assertValidParse("true", "true")
12+
try assertValidParse("false", "false")
13+
try assertValidParse("null", "null")
14+
try assertValidParse("\"foo\"", "\"foo\"")
15+
try assertValidParse("9//comment", "9")
16+
}
17+
18+
func testParseObjects() throws {
19+
try assertValidParse("{}", "{}")
20+
try assertValidParse(#"{ "foo": true }"#, #"{"foo":true}"#)
21+
try assertValidParse(#"{ "bar": 8, "xoo": "foo" }"#, #"{"bar":8,"xoo":"foo"}"#)
22+
try assertValidParse(#"{ "hello": [], "world": {} }"#, #"{"hello":[],"world":{}}"#)
23+
try assertValidParse(#"{ "a": false, "b": true, "c": [ 7.4 ] }"#, #"{"a":false,"b":true,"c":[7.4]}"#)
24+
try assertValidParse(#"{ "lineComment": "//", "blockComment": ["/*", "*/"], "brackets": [ ["{", "}"], ["[", "]"], ["(", ")"] ] }"#, #"{"lineComment":"//","blockComment":["/*","*/"],"brackets":[["{","}"],["[","]"],["(",")"]]}"#)
25+
try assertValidParse(#"{ "hello": [], "world": {} }"#, #"{"hello":[],"world":{}}"#)
26+
try assertValidParse(#"{ "hello": { "again": { "inside": 5 }, "world": 1 }}"#, #"{"hello":{"again":{"inside":5},"world":1}}"#)
27+
try assertValidParse(#"{ "foo": /*hello*/true }"#, #"{"foo":true}"#)
28+
try assertValidParse(#"{ "": true }"#, #"{"":true}"#)
29+
}
30+
31+
func testParseArrays() throws {
32+
try assertValidParse("[]", "[]");
33+
try assertValidParse("[ [], [ [] ]]", "[[],[[]]]");
34+
try assertValidParse("[ 1, 2, 3 ]", "[1,2,3]");
35+
try assertValidParse(#"[ { "a": null } ]"#, #"[{"a":null}]"#);
36+
}
37+
38+
private func assertValidParse(_ jsoncString: String, _ expected: String,
39+
in file: StaticString = #file,
40+
line: UInt = #line) throws {
41+
let value = try JSONCParser(jsoncString: jsoncString).parse()
42+
XCTAssertEqual(value.encode(), expected, file: file, line: line)
1143
}
1244
}

0 commit comments

Comments
 (0)