Skip to content

Commit f982a19

Browse files
committed
Use JSON record line & character details in validation
1 parent 02ccb3b commit f982a19

File tree

3 files changed

+88
-24
lines changed

3 files changed

+88
-24
lines changed

package-lock.json

Lines changed: 23 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@
9898
"har-validator": "^5.1.3",
9999
"http-encoding": "^2.0.1",
100100
"js-beautify": "^1.8.8",
101+
"jsonc-parser": "^3.3.1",
101102
"jsonwebtoken": "^8.4.0",
102103
"localforage": "^1.7.3",
103104
"lodash": "^4.17.21",

src/components/editor/json-records-validation.ts

Lines changed: 64 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,28 +11,24 @@ export function setupJsonRecordsValidation(monaco: typeof MonacoTypes) {
1111
if (text) {
1212
const separator = text[text.length - 1];
1313
const splits = text.split(separator);
14-
let offset = 0;
14+
1515
for (let i = 0; i < splits.length; i++) {
1616
const part = splits[i];
1717
if (part) {
18-
let errors: json_parser.ParseError[] = []
19-
json_parser.parse(part, errors, { allowTrailingComma: false, disallowComments: true });
20-
console.log(`Validating JSON record part [${i}] `, part, `error ${JSON.stringify(errors)}`);
21-
if (errors) {
22-
errors.forEach((err) => {
23-
markers.push({
24-
severity: monaco.MarkerSeverity.Error,
25-
startLineNumber: i,
26-
startColumn: offset,
27-
endLineNumber: i,
28-
endColumn: offset + err.length,
29-
message: err.error.toString(),
30-
})
18+
let errors: ParserError[] = [];
19+
parseJson(part, errors, { allowTrailingComma: false, disallowComments: true });
20+
if (errors.length) {
21+
const firstError = errors[0];
22+
markers.push({
23+
severity: monaco.MarkerSeverity.Error,
24+
startLineNumber: i + 1,
25+
startColumn: firstError.startCharacter + 1,
26+
endLineNumber: i + 1,
27+
endColumn: firstError.startCharacter + firstError.length + 1,
28+
message: json_parser.printParseErrorCode(firstError.error)
3129
});
3230
}
3331
}
34-
35-
offset += part.length + 1; // +1 for the separator
3632
}
3733
}
3834

@@ -67,3 +63,55 @@ export function setupJsonRecordsValidation(monaco: typeof MonacoTypes) {
6763
manageContentChangeListener(model)
6864
})
6965
}
66+
67+
68+
interface ParserError extends json_parser.ParseError {
69+
startLine: number;
70+
startCharacter: number;
71+
}
72+
73+
function parseJson(text: string, errors: ParserError[] = [], options: json_parser.ParseOptions = {}): any {
74+
let currentProperty: string | null = null;
75+
let currentParent: any = [];
76+
const previousParents: any[] = [];
77+
78+
function onValue(value: any) {
79+
if (Array.isArray(currentParent)) {
80+
(<any[]>currentParent).push(value);
81+
} else if (currentProperty !== null) {
82+
currentParent[currentProperty] = value;
83+
}
84+
}
85+
86+
const visitor: json_parser.JSONVisitor = {
87+
onObjectBegin: () => {
88+
const object = {};
89+
onValue(object);
90+
previousParents.push(currentParent);
91+
currentParent = object;
92+
currentProperty = null;
93+
},
94+
onObjectProperty: (name: string) => {
95+
currentProperty = name;
96+
},
97+
onObjectEnd: () => {
98+
currentParent = previousParents.pop();
99+
},
100+
onArrayBegin: () => {
101+
const array: any[] = [];
102+
onValue(array);
103+
previousParents.push(currentParent);
104+
currentParent = array;
105+
currentProperty = null;
106+
},
107+
onArrayEnd: () => {
108+
currentParent = previousParents.pop();
109+
},
110+
onLiteralValue: onValue,
111+
onError: (error: json_parser.ParseErrorCode, offset: number, length: number, startLine: number, startCharacter: number) => {
112+
errors.push({ error, offset, length, startLine, startCharacter });
113+
}
114+
};
115+
json_parser.visit(text, visitor, options);
116+
return currentParent[0];
117+
}

0 commit comments

Comments
 (0)