UNPKG

4.62 kBJavaScriptView Raw
1/**
2 * @fileoverview Lint JSON files
3 * @author Azeem Bande-Ali
4 * @copyright 2015 Azeem Bande-Ali. All rights reserved.
5 * See LICENSE file in root directory for full license.
6 */
7"use strict";
8
9//------------------------------------------------------------------------------
10// Requirements
11//------------------------------------------------------------------------------
12
13var jsonService = require("vscode-json-languageservice");
14
15var jsonServiceHandle = jsonService.getLanguageService({});
16jsonServiceHandle.configure({
17 "validate": true,
18 "allowComments": true // setting doesn't seem to matter
19});
20
21//------------------------------------------------------------------------------
22// Plugin Definition
23//------------------------------------------------------------------------------
24
25var ErrorCode = {
26 Undefined: 0,
27 EnumValueMismatch: 1,
28 UnexpectedEndOfComment: 0x101,
29 UnexpectedEndOfString: 0x102,
30 UnexpectedEndOfNumber: 0x103,
31 InvalidUnicode: 0x104,
32 InvalidEscapeCharacter: 0x105,
33 InvalidCharacter: 0x106,
34 PropertyExpected: 0x201,
35 CommaExpected: 0x202,
36 ColonExpected: 0x203,
37 ValueExpected: 0x204,
38 CommaOrCloseBacketExpected: 0x205,
39 CommaOrCloseBraceExpected: 0x206,
40 TrailingComma: 0x207,
41 DuplicateKey: 0x208,
42 CommentNotPermitted: 0x209,
43 SchemaResolveError: 0x300
44};
45
46function getCodeRuleName(code) {
47 for (var codeName in ErrorCode) {
48 if (ErrorCode.hasOwnProperty(codeName)) {
49 if (ErrorCode[codeName] === code) {
50 return 'json/' + codeName.toLowerCase();
51 }
52 }
53 }
54
55 return 'json/unknown';
56}
57
58var fileContents = {};
59var fileDocuments = {};
60
61function toDiagnosticSeverity(severityLevel) {
62 switch (severityLevel) {
63 case "error": return 1;
64 case "warning": return 2;
65 case "ignore": return 0;
66 }
67 return 0;
68}
69
70function makeDiagnostic(c, message, severity, errorCode) {
71 return {
72 range: c,
73 message: message,
74 severity: severity,
75 code: errorCode
76 };
77}
78
79var getDiagnostics = function(textDocument, jsonDocument) {
80 var diagnostics = [];
81 var added = {};
82 var addProblem = function(problem) {
83 // remove duplicated messages
84 var signature = problem.range.start.line + " " + problem.range.start.character + " " + problem.message;
85 if (!added[signature]) {
86 added[signature] = true;
87 diagnostics.push(problem);
88 }
89 };
90 var trailingCommaSeverity = 1; // ERROR
91 var commentSeverity = 1; // ERROR
92
93 jsonDocument.syntaxErrors.forEach(function(p) {
94 if (p.code === ErrorCode.TrailingComma) {
95 if (typeof commentSeverity !== "number") {
96 return;
97 }
98 p.severity = trailingCommaSeverity;
99 }
100 addProblem(p);
101 });
102
103 // if (typeof commentSeverity === "number") {
104 // var message = "InvalidCommentToken: Comments are not permitted in JSON.";
105 // jsonDocument.comments.forEach(function(c) {
106 // addProblem(makeDiagnostic(c, message, commentSeverity, ErrorCode.CommentNotPermitted));
107 // });
108 // }
109 return diagnostics;
110};
111
112// import processors
113module.exports.processors = {
114 // add your processors here
115 ".json": {
116 preprocess: function(text, fileName) {
117 var textDocument = jsonService.TextDocument.create(fileName, "json", 1, text);
118 var parsed = jsonServiceHandle.parseJSONDocument(textDocument);
119 fileContents[fileName] = getDiagnostics(textDocument, parsed);
120 fileDocuments[fileName] = textDocument;
121 return [text];
122 },
123 postprocess: function(messages, fileName) {
124 var errors = fileContents[fileName];
125 if (errors === undefined) {
126 return [];
127 }
128 var textDocument = fileDocuments[fileName];
129 delete fileContents[fileName];
130 delete fileDocuments[fileName];
131 var formattedErrors = errors.map(function(error) {
132 return {
133 ruleId: getCodeRuleName(error.code),
134 severity: (error.severity == 1) ? 2 : 1,
135 message: error.message,
136 line: error.range.start.line + 1,
137 column: error.range.start.character + 1,
138 endLine: error.range.end.line + 1,
139 endColumn: error.range.end.character + 1,
140 source: textDocument.getText(error.range)
141 };
142 });
143 return formattedErrors;
144 }
145 }
146};