bash_lsp 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +13 -0
- package/README.md +210 -0
- package/package.json +48 -0
- package/server/bin/shell-language-server.js +2 -0
- package/server/out/interfaces/completion.js +61 -0
- package/server/out/interfaces/completion.js.map +1 -0
- package/server/out/interfaces/diagnostics.js +16 -0
- package/server/out/interfaces/diagnostics.js.map +1 -0
- package/server/out/interfaces/documents.js +5 -0
- package/server/out/interfaces/documents.js.map +1 -0
- package/server/out/interfaces/location.js +3 -0
- package/server/out/interfaces/location.js.map +1 -0
- package/server/out/interfaces/workspace.js +37 -0
- package/server/out/interfaces/workspace.js.map +1 -0
- package/server/out/log.js +16 -0
- package/server/out/log.js.map +1 -0
- package/server/out/methods/initialize.js +45 -0
- package/server/out/methods/initialize.js.map +1 -0
- package/server/out/methods/textDocument/codeAction.js +45 -0
- package/server/out/methods/textDocument/codeAction.js.map +1 -0
- package/server/out/methods/textDocument/completion.js +46 -0
- package/server/out/methods/textDocument/completion.js.map +1 -0
- package/server/out/methods/textDocument/definition.js +154 -0
- package/server/out/methods/textDocument/definition.js.map +1 -0
- package/server/out/methods/textDocument/diagnostic/bracketDiagnostics.js +319 -0
- package/server/out/methods/textDocument/diagnostic/bracketDiagnostics.js.map +1 -0
- package/server/out/methods/textDocument/diagnostic/diagnostic.js +27 -0
- package/server/out/methods/textDocument/diagnostic/diagnostic.js.map +1 -0
- package/server/out/methods/textDocument/diagnostic/structureSemicolonDiagnostics.js +248 -0
- package/server/out/methods/textDocument/diagnostic/structureSemicolonDiagnostics.js.map +1 -0
- package/server/out/methods/textDocument/didChange.js +10 -0
- package/server/out/methods/textDocument/didChange.js.map +1 -0
- package/server/out/methods/textDocument/didClose.js +10 -0
- package/server/out/methods/textDocument/didClose.js.map +1 -0
- package/server/out/methods/textDocument/didOpen.js +10 -0
- package/server/out/methods/textDocument/didOpen.js.map +1 -0
- package/server/out/methods/textDocument/hover.js +102 -0
- package/server/out/methods/textDocument/hover.js.map +1 -0
- package/server/out/methods/textDocument/rename.js +99 -0
- package/server/out/methods/textDocument/rename.js.map +1 -0
- package/server/out/server.js +60 -0
- package/server/out/server.js.map +1 -0
- package/server/out/wordList.js +39 -0
- package/server/out/wordList.js.map +1 -0
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.definition = void 0;
|
|
4
|
+
const fs = require("fs");
|
|
5
|
+
const url_1 = require("url");
|
|
6
|
+
const documents_1 = require("../../interfaces/documents");
|
|
7
|
+
const workspace_1 = require("../../interfaces/workspace");
|
|
8
|
+
const functionKeywordPattern = /^(\s*function\s+)([A-Za-z_][A-Za-z0-9_]*)\s*(?:\(\s*\))?\s*(?:\{|$)/;
|
|
9
|
+
const nameParenthesisPattern = /^(\s*)([A-Za-z_][A-Za-z0-9_]*)\s*\(\s*\)\s*(?:\{|$)/;
|
|
10
|
+
/**
|
|
11
|
+
* Returns whether a character can be part of a shell symbol token.
|
|
12
|
+
*/
|
|
13
|
+
const isWordChar = (char) => /[A-Za-z0-9_]/.test(char);
|
|
14
|
+
/**
|
|
15
|
+
* Gets the symbol under (or immediately before) the provided cursor position.
|
|
16
|
+
*
|
|
17
|
+
* @param line Current line content.
|
|
18
|
+
* @param character Cursor character index.
|
|
19
|
+
* @returns The detected symbol or null when no valid token exists at the position.
|
|
20
|
+
*/
|
|
21
|
+
const wordAtPosition = (line, character) => {
|
|
22
|
+
if (!line.length) {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
// checks if the current position is a valid symbol
|
|
26
|
+
let index = Math.min(character, line.length - 1);
|
|
27
|
+
if (!isWordChar(line[index])) {
|
|
28
|
+
// if it is not a valid symbol, check one character to the left to take empty spaces into account
|
|
29
|
+
if (character > 0 && isWordChar(line[character - 1])) {
|
|
30
|
+
index = character - 1;
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
// sets lower limit of symbol
|
|
37
|
+
let start = index;
|
|
38
|
+
while (start > 0 && isWordChar(line[start - 1])) {
|
|
39
|
+
start -= 1;
|
|
40
|
+
}
|
|
41
|
+
// sets upper limit of symbol
|
|
42
|
+
let end = index + 1;
|
|
43
|
+
while (end < line.length && isWordChar(line[end])) {
|
|
44
|
+
end += 1;
|
|
45
|
+
}
|
|
46
|
+
// returns the characters between start and end
|
|
47
|
+
return line.slice(start, end);
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Finds the first matching function-style definition for a symbol in a document.
|
|
51
|
+
*
|
|
52
|
+
* Supports both `function name()` and `name()` styles while ignoring commented
|
|
53
|
+
* lines that start with `#`.
|
|
54
|
+
*
|
|
55
|
+
* @param uri Document URI.
|
|
56
|
+
* @param content Full document content.
|
|
57
|
+
* @param symbol Symbol to locate.
|
|
58
|
+
* @returns Definition location or null if no match is found.
|
|
59
|
+
*/
|
|
60
|
+
const findDefinitionInContent = (uri, content, symbol) => {
|
|
61
|
+
const lines = content.split("\n");
|
|
62
|
+
for (let lineNumber = 0; lineNumber < lines.length; lineNumber += 1) {
|
|
63
|
+
const line = lines[lineNumber];
|
|
64
|
+
// if line is a comment, skip
|
|
65
|
+
if (/^\s*#/.test(line)) {
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
// checks for "function name (...)" pattern
|
|
69
|
+
const functionKeywordMatch = line.match(functionKeywordPattern);
|
|
70
|
+
if (functionKeywordMatch) {
|
|
71
|
+
const functionName = functionKeywordMatch[2]; // at 0 returns full text, at 1 returns "function " part
|
|
72
|
+
if (functionName === symbol) {
|
|
73
|
+
const startCharacter = functionKeywordMatch[1].length;
|
|
74
|
+
return {
|
|
75
|
+
uri,
|
|
76
|
+
range: {
|
|
77
|
+
start: { line: lineNumber, character: startCharacter },
|
|
78
|
+
end: {
|
|
79
|
+
line: lineNumber,
|
|
80
|
+
character: startCharacter + symbol.length,
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
// checks for "name (...)" pattern
|
|
87
|
+
const nameParenthesisMatch = line.match(nameParenthesisPattern);
|
|
88
|
+
if (nameParenthesisMatch) {
|
|
89
|
+
const functionName = nameParenthesisMatch[2]; // at 0 returns full text, at 1 returns indentation
|
|
90
|
+
if (functionName === symbol) {
|
|
91
|
+
const startCharacter = nameParenthesisMatch[1].length;
|
|
92
|
+
return {
|
|
93
|
+
uri,
|
|
94
|
+
range: {
|
|
95
|
+
start: { line: lineNumber, character: startCharacter },
|
|
96
|
+
end: {
|
|
97
|
+
line: lineNumber,
|
|
98
|
+
character: startCharacter + symbol.length,
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return null;
|
|
106
|
+
};
|
|
107
|
+
const definition = (message) => {
|
|
108
|
+
const params = message.params;
|
|
109
|
+
const content = documents_1.documents.get(params.textDocument.uri);
|
|
110
|
+
if (!content) {
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
const line = content.split("\n")[params.position.line];
|
|
114
|
+
if (line === undefined) {
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
const symbol = wordAtPosition(line, params.position.character);
|
|
118
|
+
if (!symbol) {
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
const currentDocumentDefinition = findDefinitionInContent(params.textDocument.uri, content, symbol);
|
|
122
|
+
if (currentDocumentDefinition) {
|
|
123
|
+
return currentDocumentDefinition;
|
|
124
|
+
}
|
|
125
|
+
// search other open documents
|
|
126
|
+
for (const [uri, documentContent] of documents_1.documents.entries()) {
|
|
127
|
+
if (uri === params.textDocument.uri)
|
|
128
|
+
continue;
|
|
129
|
+
const definitionInOpenDocument = findDefinitionInContent(uri, documentContent, symbol);
|
|
130
|
+
if (definitionInOpenDocument)
|
|
131
|
+
return definitionInOpenDocument;
|
|
132
|
+
}
|
|
133
|
+
// search workspace .sh files not already open
|
|
134
|
+
if (workspace_1.workspaceRoot) {
|
|
135
|
+
for (const filePath of (0, workspace_1.collectShellFiles)(workspace_1.workspaceRoot)) {
|
|
136
|
+
const fileUri = (0, url_1.pathToFileURL)(filePath).href;
|
|
137
|
+
if (documents_1.documents.has(fileUri))
|
|
138
|
+
continue;
|
|
139
|
+
let fileContent;
|
|
140
|
+
try {
|
|
141
|
+
fileContent = fs.readFileSync(filePath, "utf-8");
|
|
142
|
+
}
|
|
143
|
+
catch {
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
const definitionInWorkspace = findDefinitionInContent(fileUri, fileContent, symbol);
|
|
147
|
+
if (definitionInWorkspace)
|
|
148
|
+
return definitionInWorkspace;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return null;
|
|
152
|
+
};
|
|
153
|
+
exports.definition = definition;
|
|
154
|
+
//# sourceMappingURL=definition.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"definition.js","sourceRoot":"","sources":["../../../src/methods/textDocument/definition.ts"],"names":[],"mappings":";;;AAAA,yBAAyB;AACzB,6BAAoC;AACpC,0DAAmF;AAGnF,0DAA8E;AAI9E,MAAM,sBAAsB,GAC1B,qEAAqE,CAAC;AACxE,MAAM,sBAAsB,GAAG,qDAAqD,CAAC;AAErF;;GAEG;AACH,MAAM,UAAU,GAAG,CAAC,IAAY,EAAW,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAExE;;;;;;GAMG;AACH,MAAM,cAAc,GAAG,CAAC,IAAY,EAAE,SAAiB,EAAiB,EAAE;IACxE,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;QACjB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,mDAAmD;IACnD,IAAI,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACjD,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;QAC7B,iGAAiG;QACjG,IAAI,SAAS,GAAG,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YACrD,KAAK,GAAG,SAAS,GAAG,CAAC,CAAC;QACxB,CAAC;aAAM,CAAC;YACN,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,6BAA6B;IAC7B,IAAI,KAAK,GAAG,KAAK,CAAC;IAClB,OAAO,KAAK,GAAG,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QAChD,KAAK,IAAI,CAAC,CAAC;IACb,CAAC;IAED,6BAA6B;IAC7B,IAAI,GAAG,GAAG,KAAK,GAAG,CAAC,CAAC;IACpB,OAAO,GAAG,GAAG,IAAI,CAAC,MAAM,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;QAClD,GAAG,IAAI,CAAC,CAAC;IACX,CAAC;IAED,+CAA+C;IAC/C,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;AAChC,CAAC,CAAC;AAEF;;;;;;;;;;GAUG;AACH,MAAM,uBAAuB,GAAG,CAAC,GAAW,EAAE,OAAe,EAAE,MAAc,EAAmB,EAAE;IAChG,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAElC,KAAK,IAAI,UAAU,GAAG,CAAC,EAAE,UAAU,GAAG,KAAK,CAAC,MAAM,EAAE,UAAU,IAAI,CAAC,EAAE,CAAC;QACpE,MAAM,IAAI,GAAG,KAAK,CAAC,UAAU,CAAC,CAAC;QAC/B,6BAA6B;QAC7B,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACvB,SAAS;QACX,CAAC;QAED,2CAA2C;QAC3C,MAAM,oBAAoB,GAAG,IAAI,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;QAChE,IAAI,oBAAoB,EAAE,CAAC;YACzB,MAAM,YAAY,GAAG,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAAC,wDAAwD;YACtG,IAAI,YAAY,KAAK,MAAM,EAAE,CAAC;gBAC5B,MAAM,cAAc,GAAG,oBAAoB,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;gBACtD,OAAO;oBACL,GAAG;oBACH,KAAK,EAAE;wBACL,KAAK,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,cAAc,EAAE;wBACtD,GAAG,EAAE;4BACH,IAAI,EAAE,UAAU;4BAChB,SAAS,EAAE,cAAc,GAAG,MAAM,CAAC,MAAM;yBAC1C;qBACF;iBACF,CAAC;YACJ,CAAC;QACH,CAAC;QAED,kCAAkC;QAClC,MAAM,oBAAoB,GAAG,IAAI,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;QAChE,IAAI,oBAAoB,EAAE,CAAC;YACzB,MAAM,YAAY,GAAG,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAAC,mDAAmD;YACjG,IAAI,YAAY,KAAK,MAAM,EAAE,CAAC;gBAC5B,MAAM,cAAc,GAAG,oBAAoB,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;gBACtD,OAAO;oBACL,GAAG;oBACH,KAAK,EAAE;wBACL,KAAK,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,cAAc,EAAE;wBACtD,GAAG,EAAE;4BACH,IAAI,EAAE,UAAU;4BAChB,SAAS,EAAE,cAAc,GAAG,MAAM,CAAC,MAAM;yBAC1C;qBACF;iBACF,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AAEK,MAAM,UAAU,GAAG,CAAC,OAAuB,EAAmB,EAAE;IACrE,MAAM,MAAM,GAAG,OAAO,CAAC,MAA0B,CAAC;IAClD,MAAM,OAAO,GAAG,qBAAS,CAAC,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;IAEvD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IACvD,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,MAAM,GAAG,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;IAC/D,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,yBAAyB,GAAG,uBAAuB,CACvD,MAAM,CAAC,YAAY,CAAC,GAAG,EACvB,OAAO,EACP,MAAM,CACP,CAAC;IAEF,IAAI,yBAAyB,EAAE,CAAC;QAC9B,OAAO,yBAAyB,CAAC;IACnC,CAAC;IAED,8BAA8B;IAC9B,KAAK,MAAM,CAAC,GAAG,EAAE,eAAe,CAAC,IAAI,qBAAS,CAAC,OAAO,EAAE,EAAE,CAAC;QACzD,IAAI,GAAG,KAAK,MAAM,CAAC,YAAY,CAAC,GAAG;YAAE,SAAS;QAE9C,MAAM,wBAAwB,GAAG,uBAAuB,CAAC,GAAG,EAAE,eAAe,EAAE,MAAM,CAAC,CAAC;QACvF,IAAI,wBAAwB;YAAE,OAAO,wBAAwB,CAAC;IAChE,CAAC;IAED,8CAA8C;IAC9C,IAAI,yBAAa,EAAE,CAAC;QAClB,KAAK,MAAM,QAAQ,IAAI,IAAA,6BAAiB,EAAC,yBAAa,CAAC,EAAE,CAAC;YACxD,MAAM,OAAO,GAAG,IAAA,mBAAa,EAAC,QAAQ,CAAC,CAAC,IAAI,CAAC;YAC7C,IAAI,qBAAS,CAAC,GAAG,CAAC,OAAO,CAAC;gBAAE,SAAS;YAErC,IAAI,WAAmB,CAAC;YACxB,IAAI,CAAC;gBACH,WAAW,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YACnD,CAAC;YAAC,MAAM,CAAC;gBACP,SAAS;YACX,CAAC;YAED,MAAM,qBAAqB,GAAG,uBAAuB,CAAC,OAAO,EAAE,WAAW,EAAE,MAAM,CAAC,CAAC;YACpF,IAAI,qBAAqB;gBAAE,OAAO,qBAAqB,CAAC;QAC1D,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AAvDW,QAAA,UAAU,cAuDrB"}
|
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.bracketDiagnostics = void 0;
|
|
4
|
+
const diagnostics_1 = require("../../../interfaces/diagnostics");
|
|
5
|
+
/**
|
|
6
|
+
* Maps opening brackets to their expected closing counterparts.
|
|
7
|
+
*/
|
|
8
|
+
const openingToClosingBracket = {
|
|
9
|
+
"(": ")",
|
|
10
|
+
"[": "]",
|
|
11
|
+
"{": "}",
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Maps closing brackets to their expected opening counterparts.
|
|
15
|
+
*/
|
|
16
|
+
const closingToOpeningBracket = {
|
|
17
|
+
")": "(",
|
|
18
|
+
"]": "[",
|
|
19
|
+
"}": "{",
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Produces diagnostics for unmatched or mismatched brackets in shell content.
|
|
23
|
+
*
|
|
24
|
+
* Brackets inside comments and quoted strings are ignored. Inside `case` blocks,
|
|
25
|
+
* pattern headers are ignored until `)` is reached, then bracket checks run for
|
|
26
|
+
* the clause body until `;;`.
|
|
27
|
+
*
|
|
28
|
+
* @param content Full document text.
|
|
29
|
+
* @returns Diagnostic list for detected bracket issues.
|
|
30
|
+
*/
|
|
31
|
+
const bracketDiagnostics = (content) => {
|
|
32
|
+
const diagnostics = [];
|
|
33
|
+
const bracketStack = [];
|
|
34
|
+
const lines = content.split("\n");
|
|
35
|
+
const parserState = {
|
|
36
|
+
inSingleQuotes: false,
|
|
37
|
+
inDoubleQuotes: false,
|
|
38
|
+
inCaseBlock: false,
|
|
39
|
+
inCaseClauseBody: false,
|
|
40
|
+
};
|
|
41
|
+
for (let lineNumber = 0; lineNumber < lines.length; lineNumber += 1) {
|
|
42
|
+
processLineForBracketDiagnostics(lines[lineNumber], lineNumber, parserState, bracketStack, diagnostics);
|
|
43
|
+
}
|
|
44
|
+
emitUnmatchedOpeningBracketDiagnostics(bracketStack, diagnostics);
|
|
45
|
+
return diagnostics;
|
|
46
|
+
};
|
|
47
|
+
exports.bracketDiagnostics = bracketDiagnostics;
|
|
48
|
+
/**
|
|
49
|
+
* Parses one line and updates bracket diagnostics and parser state.
|
|
50
|
+
*
|
|
51
|
+
* @param line Current line text.
|
|
52
|
+
* @param lineNumber Zero-based line index.
|
|
53
|
+
* @param parserState Mutable parser state shared across lines.
|
|
54
|
+
* @param bracketStack Stack of unmatched opening brackets.
|
|
55
|
+
* @param diagnostics Collected diagnostics.
|
|
56
|
+
*/
|
|
57
|
+
const processLineForBracketDiagnostics = (line, lineNumber, parserState, bracketStack, diagnostics) => {
|
|
58
|
+
let currentWord = "";
|
|
59
|
+
for (let character = 0; character < line.length; character += 1) {
|
|
60
|
+
const currentChar = line[character];
|
|
61
|
+
// check if current line is a comment
|
|
62
|
+
if (isCommentStart(currentChar, parserState)) {
|
|
63
|
+
processWordForCaseState(currentWord, parserState);
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
66
|
+
// check if current word starts with an escaped character, if it does, skip it
|
|
67
|
+
if (isEscapedCharacter(currentChar, parserState)) {
|
|
68
|
+
processWordForCaseState(currentWord, parserState);
|
|
69
|
+
currentWord = "";
|
|
70
|
+
character += 1;
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
// check if current word is starting or ending a single-quoted string
|
|
74
|
+
if (isSingleQuoteToggle(currentChar, parserState)) {
|
|
75
|
+
processWordForCaseState(currentWord, parserState);
|
|
76
|
+
currentWord = "";
|
|
77
|
+
parserState.inSingleQuotes = !parserState.inSingleQuotes;
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
// check if current word is starting or ending a double-quoted string
|
|
81
|
+
if (isDoubleQuoteToggle(currentChar, parserState)) {
|
|
82
|
+
processWordForCaseState(currentWord, parserState);
|
|
83
|
+
currentWord = "";
|
|
84
|
+
parserState.inDoubleQuotes = !parserState.inDoubleQuotes;
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
// if inside quoted string, skip character
|
|
88
|
+
if (isInsideQuotedString(parserState)) {
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
currentWord = updateCurrentWord(currentWord, currentChar, parserState);
|
|
92
|
+
if (isEnteringCaseClause(currentChar, parserState)) {
|
|
93
|
+
parserState.inCaseClauseBody = true;
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
if (isLeavingCaseClause(line, character, parserState)) {
|
|
97
|
+
parserState.inCaseClauseBody = false;
|
|
98
|
+
character += 1;
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
if (shouldIgnoreBracketInCaseHeader(currentChar, parserState)) {
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
if (isOpeningBracket(currentChar)) {
|
|
105
|
+
pushOpeningBracket(bracketStack, currentChar, lineNumber, character);
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
if (isClosingBracket(currentChar)) {
|
|
109
|
+
processClosingBracket(bracketStack, currentChar, lineNumber, character, diagnostics);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
processWordForCaseState(currentWord, parserState);
|
|
113
|
+
};
|
|
114
|
+
/**
|
|
115
|
+
* Returns whether a character starts a comment in the current parser state.
|
|
116
|
+
*
|
|
117
|
+
* @param char Character to inspect.
|
|
118
|
+
* @param parserState Current parser state.
|
|
119
|
+
*/
|
|
120
|
+
const isCommentStart = (char, parserState) => {
|
|
121
|
+
return !isInsideQuotedString(parserState) && char === "#";
|
|
122
|
+
};
|
|
123
|
+
/**
|
|
124
|
+
* Updates case-related parser state when a shell word boundary is reached.
|
|
125
|
+
*
|
|
126
|
+
* @param word Parsed shell word.
|
|
127
|
+
* @param parserState Mutable parser state.
|
|
128
|
+
*/
|
|
129
|
+
const processWordForCaseState = (word, parserState) => {
|
|
130
|
+
if (word === "case") {
|
|
131
|
+
parserState.inCaseBlock = true;
|
|
132
|
+
parserState.inCaseClauseBody = false;
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
if (word === "esac") {
|
|
136
|
+
parserState.inCaseBlock = false;
|
|
137
|
+
parserState.inCaseClauseBody = false;
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
/**
|
|
141
|
+
* Returns whether the character begins an escaped sequence that should be skipped.
|
|
142
|
+
*
|
|
143
|
+
* @param char Character to inspect.
|
|
144
|
+
* @param parserState Current parser state.
|
|
145
|
+
*/
|
|
146
|
+
const isEscapedCharacter = (char, parserState) => {
|
|
147
|
+
return char === "\\" && !parserState.inSingleQuotes;
|
|
148
|
+
};
|
|
149
|
+
/**
|
|
150
|
+
* Returns whether the character toggles single-quote string mode.
|
|
151
|
+
*
|
|
152
|
+
* @param char Character to inspect.
|
|
153
|
+
* @param parserState Current parser state.
|
|
154
|
+
*/
|
|
155
|
+
const isSingleQuoteToggle = (char, parserState) => {
|
|
156
|
+
return char === "'" && !parserState.inDoubleQuotes;
|
|
157
|
+
};
|
|
158
|
+
/**
|
|
159
|
+
* Returns whether the character toggles double-quote string mode.
|
|
160
|
+
*
|
|
161
|
+
* @param char Character to inspect.
|
|
162
|
+
* @param parserState Current parser state.
|
|
163
|
+
*/
|
|
164
|
+
const isDoubleQuoteToggle = (char, parserState) => {
|
|
165
|
+
return char === '"' && !parserState.inSingleQuotes;
|
|
166
|
+
};
|
|
167
|
+
/**
|
|
168
|
+
* Returns whether parsing is currently inside a quoted string.
|
|
169
|
+
*
|
|
170
|
+
* @param parserState Current parser state.
|
|
171
|
+
*/
|
|
172
|
+
const isInsideQuotedString = (parserState) => {
|
|
173
|
+
return parserState.inSingleQuotes || parserState.inDoubleQuotes;
|
|
174
|
+
};
|
|
175
|
+
/**
|
|
176
|
+
* Returns whether a character is part of a shell word token.
|
|
177
|
+
*
|
|
178
|
+
* @param char Character to inspect.
|
|
179
|
+
*/
|
|
180
|
+
const isWordCharacter = (char) => /[A-Za-z0-9_]/.test(char);
|
|
181
|
+
/**
|
|
182
|
+
* Appends to the current shell word or flushes it into case-state processing.
|
|
183
|
+
*
|
|
184
|
+
* @param currentWord Current accumulated word.
|
|
185
|
+
* @param currentChar Current character.
|
|
186
|
+
* @param parserState Mutable parser state.
|
|
187
|
+
* @returns Updated accumulated word.
|
|
188
|
+
*/
|
|
189
|
+
const updateCurrentWord = (currentWord, currentChar, parserState) => {
|
|
190
|
+
if (isWordCharacter(currentChar)) {
|
|
191
|
+
return currentWord + currentChar;
|
|
192
|
+
}
|
|
193
|
+
processWordForCaseState(currentWord, parserState);
|
|
194
|
+
return "";
|
|
195
|
+
};
|
|
196
|
+
/**
|
|
197
|
+
* Returns whether the current character enters the body of a case clause.
|
|
198
|
+
*
|
|
199
|
+
* @param currentChar Character to inspect.
|
|
200
|
+
* @param parserState Current parser state.
|
|
201
|
+
*/
|
|
202
|
+
const isEnteringCaseClause = (currentChar, parserState) => {
|
|
203
|
+
return parserState.inCaseBlock && !parserState.inCaseClauseBody && currentChar === ")";
|
|
204
|
+
};
|
|
205
|
+
/**
|
|
206
|
+
* Returns whether parsing is currently leaving a case clause body.
|
|
207
|
+
*
|
|
208
|
+
* @param line Current line text.
|
|
209
|
+
* @param character Zero-based character index.
|
|
210
|
+
* @param parserState Current parser state.
|
|
211
|
+
*/
|
|
212
|
+
const isLeavingCaseClause = (line, character, parserState) => {
|
|
213
|
+
return (parserState.inCaseBlock && parserState.inCaseClauseBody && line.startsWith(";;", character));
|
|
214
|
+
};
|
|
215
|
+
/**
|
|
216
|
+
* Returns whether bracket tokens should be ignored in a case pattern header.
|
|
217
|
+
*
|
|
218
|
+
* @param currentChar Character to inspect.
|
|
219
|
+
* @param parserState Current parser state.
|
|
220
|
+
*/
|
|
221
|
+
const shouldIgnoreBracketInCaseHeader = (currentChar, parserState) => {
|
|
222
|
+
return (parserState.inCaseBlock &&
|
|
223
|
+
!parserState.inCaseClauseBody &&
|
|
224
|
+
(isOpeningBracket(currentChar) || isClosingBracket(currentChar)));
|
|
225
|
+
};
|
|
226
|
+
/**
|
|
227
|
+
* Returns whether a character is one of the supported opening brackets.
|
|
228
|
+
*
|
|
229
|
+
* @param char Character to inspect.
|
|
230
|
+
*/
|
|
231
|
+
const isOpeningBracket = (char) => {
|
|
232
|
+
return char === "(" || char === "[" || char === "{";
|
|
233
|
+
};
|
|
234
|
+
/**
|
|
235
|
+
* Pushes an opening bracket position onto the stack.
|
|
236
|
+
*
|
|
237
|
+
* @param bracketStack Stack of unmatched opening brackets.
|
|
238
|
+
* @param openingBracket Opening bracket token.
|
|
239
|
+
* @param lineNumber Zero-based line index.
|
|
240
|
+
* @param character Zero-based character index.
|
|
241
|
+
*/
|
|
242
|
+
const pushOpeningBracket = (bracketStack, openingBracket, lineNumber, character) => {
|
|
243
|
+
bracketStack.push({
|
|
244
|
+
char: openingBracket,
|
|
245
|
+
line: lineNumber,
|
|
246
|
+
character,
|
|
247
|
+
});
|
|
248
|
+
};
|
|
249
|
+
/**
|
|
250
|
+
* Returns whether a character is one of the supported closing brackets.
|
|
251
|
+
*
|
|
252
|
+
* @param char Character to inspect.
|
|
253
|
+
*/
|
|
254
|
+
const isClosingBracket = (char) => {
|
|
255
|
+
return char === ")" || char === "]" || char === "}";
|
|
256
|
+
};
|
|
257
|
+
/**
|
|
258
|
+
* Processes a closing bracket and emits diagnostics for unmatched/mismatched pairs.
|
|
259
|
+
*
|
|
260
|
+
* @param bracketStack Stack of unmatched opening brackets.
|
|
261
|
+
* @param closingBracket Closing bracket token.
|
|
262
|
+
* @param lineNumber Zero-based line index.
|
|
263
|
+
* @param character Zero-based character index.
|
|
264
|
+
* @param diagnostics Collected diagnostics.
|
|
265
|
+
*/
|
|
266
|
+
const processClosingBracket = (bracketStack, closingBracket, lineNumber, character, diagnostics) => {
|
|
267
|
+
const expectedMatchingOpeningBracket = closingToOpeningBracket[closingBracket];
|
|
268
|
+
const openingBracket = bracketStack.at(-1);
|
|
269
|
+
if (!openingBracket) {
|
|
270
|
+
diagnostics.push(buildBracketDiagnostic(`Unmatched closing bracket "${closingBracket}".`, lineNumber, character));
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
if (openingBracket.char !== expectedMatchingOpeningBracket) {
|
|
274
|
+
const expectedMatchingClosingBracket = openingToClosingBracket[openingBracket.char];
|
|
275
|
+
diagnostics.push(buildBracketDiagnostic(`Mismatched closing bracket "${closingBracket}". Expected "${expectedMatchingClosingBracket}" to match "${openingBracket.char}".`, lineNumber, character));
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
278
|
+
bracketStack.pop();
|
|
279
|
+
};
|
|
280
|
+
/**
|
|
281
|
+
* Emits diagnostics for any opening brackets left unmatched in the stack.
|
|
282
|
+
*
|
|
283
|
+
* @param bracketStack Stack of unmatched opening brackets.
|
|
284
|
+
* @param diagnostics Collected diagnostics.
|
|
285
|
+
*/
|
|
286
|
+
const emitUnmatchedOpeningBracketDiagnostics = (bracketStack, diagnostics) => {
|
|
287
|
+
while (bracketStack.length > 0) {
|
|
288
|
+
const openingBracket = bracketStack.pop();
|
|
289
|
+
diagnostics.push(buildBracketDiagnostic(`Unmatched opening bracket "${openingBracket.char}".`, openingBracket.line, openingBracket.character));
|
|
290
|
+
}
|
|
291
|
+
};
|
|
292
|
+
/**
|
|
293
|
+
* Builds a diagnostic for a bracket parsing error at one character position.
|
|
294
|
+
*
|
|
295
|
+
* @param message Diagnostic error message.
|
|
296
|
+
* @param line Zero-based line index.
|
|
297
|
+
* @param character Zero-based character index.
|
|
298
|
+
*/
|
|
299
|
+
const buildBracketDiagnostic = (message, line, character) => {
|
|
300
|
+
return {
|
|
301
|
+
severity: diagnostics_1.DiagnosticSeverity.Error,
|
|
302
|
+
message,
|
|
303
|
+
source: "shell-language-server",
|
|
304
|
+
range: singleCharacterRange(line, character),
|
|
305
|
+
data: { type: diagnostics_1.DiagnosticType.MissingBracket },
|
|
306
|
+
};
|
|
307
|
+
};
|
|
308
|
+
/**
|
|
309
|
+
* Builds a single-character range at a specific line/column location.
|
|
310
|
+
*
|
|
311
|
+
* @param line Zero-based line index.
|
|
312
|
+
* @param character Zero-based character index.
|
|
313
|
+
* @returns LSP range covering one character.
|
|
314
|
+
*/
|
|
315
|
+
const singleCharacterRange = (line, character) => ({
|
|
316
|
+
start: { line, character },
|
|
317
|
+
end: { line, character: character + 1 },
|
|
318
|
+
});
|
|
319
|
+
//# sourceMappingURL=bracketDiagnostics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bracketDiagnostics.js","sourceRoot":"","sources":["../../../../src/methods/textDocument/diagnostic/bracketDiagnostics.ts"],"names":[],"mappings":";;;AACA,iEAAiG;AAWjG;;GAEG;AACH,MAAM,uBAAuB,GAAG;IAC9B,GAAG,EAAE,GAAG;IACR,GAAG,EAAE,GAAG;IACR,GAAG,EAAE,GAAG;CACA,CAAC;AAEX;;GAEG;AACH,MAAM,uBAAuB,GAAG;IAC9B,GAAG,EAAE,GAAG;IACR,GAAG,EAAE,GAAG;IACR,GAAG,EAAE,GAAG;CACA,CAAC;AASX;;;;;;;;;GASG;AACI,MAAM,kBAAkB,GAAG,CAAC,OAAe,EAAgB,EAAE;IAClE,MAAM,WAAW,GAAiB,EAAE,CAAC;IACrC,MAAM,YAAY,GAAmB,EAAE,CAAC;IACxC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAClC,MAAM,WAAW,GAAgB;QAC/B,cAAc,EAAE,KAAK;QACrB,cAAc,EAAE,KAAK;QACrB,WAAW,EAAE,KAAK;QAClB,gBAAgB,EAAE,KAAK;KACxB,CAAC;IAEF,KAAK,IAAI,UAAU,GAAG,CAAC,EAAE,UAAU,GAAG,KAAK,CAAC,MAAM,EAAE,UAAU,IAAI,CAAC,EAAE,CAAC;QACpE,gCAAgC,CAC9B,KAAK,CAAC,UAAU,CAAC,EACjB,UAAU,EACV,WAAW,EACX,YAAY,EACZ,WAAW,CACZ,CAAC;IACJ,CAAC;IAED,sCAAsC,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;IAElE,OAAO,WAAW,CAAC;AACrB,CAAC,CAAC;AAxBW,QAAA,kBAAkB,sBAwB7B;AAEF;;;;;;;;GAQG;AACH,MAAM,gCAAgC,GAAG,CACvC,IAAY,EACZ,UAAkB,EAClB,WAAwB,EACxB,YAA4B,EAC5B,WAAyB,EACnB,EAAE;IACR,IAAI,WAAW,GAAG,EAAE,CAAC;IAErB,KAAK,IAAI,SAAS,GAAG,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC,MAAM,EAAE,SAAS,IAAI,CAAC,EAAE,CAAC;QAChE,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC;QAEpC,qCAAqC;QACrC,IAAI,cAAc,CAAC,WAAW,EAAE,WAAW,CAAC,EAAE,CAAC;YAC7C,uBAAuB,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;YAClD,MAAM;QACR,CAAC;QAED,8EAA8E;QAC9E,IAAI,kBAAkB,CAAC,WAAW,EAAE,WAAW,CAAC,EAAE,CAAC;YACjD,uBAAuB,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;YAClD,WAAW,GAAG,EAAE,CAAC;YACjB,SAAS,IAAI,CAAC,CAAC;YACf,SAAS;QACX,CAAC;QAED,qEAAqE;QACrE,IAAI,mBAAmB,CAAC,WAAW,EAAE,WAAW,CAAC,EAAE,CAAC;YAClD,uBAAuB,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;YAClD,WAAW,GAAG,EAAE,CAAC;YACjB,WAAW,CAAC,cAAc,GAAG,CAAC,WAAW,CAAC,cAAc,CAAC;YACzD,SAAS;QACX,CAAC;QAED,qEAAqE;QACrE,IAAI,mBAAmB,CAAC,WAAW,EAAE,WAAW,CAAC,EAAE,CAAC;YAClD,uBAAuB,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;YAClD,WAAW,GAAG,EAAE,CAAC;YACjB,WAAW,CAAC,cAAc,GAAG,CAAC,WAAW,CAAC,cAAc,CAAC;YACzD,SAAS;QACX,CAAC;QAED,0CAA0C;QAC1C,IAAI,oBAAoB,CAAC,WAAW,CAAC,EAAE,CAAC;YACtC,SAAS;QACX,CAAC;QAED,WAAW,GAAG,iBAAiB,CAAC,WAAW,EAAE,WAAW,EAAE,WAAW,CAAC,CAAC;QAEvE,IAAI,oBAAoB,CAAC,WAAW,EAAE,WAAW,CAAC,EAAE,CAAC;YACnD,WAAW,CAAC,gBAAgB,GAAG,IAAI,CAAC;YACpC,SAAS;QACX,CAAC;QAED,IAAI,mBAAmB,CAAC,IAAI,EAAE,SAAS,EAAE,WAAW,CAAC,EAAE,CAAC;YACtD,WAAW,CAAC,gBAAgB,GAAG,KAAK,CAAC;YACrC,SAAS,IAAI,CAAC,CAAC;YACf,SAAS;QACX,CAAC;QAED,IAAI,+BAA+B,CAAC,WAAW,EAAE,WAAW,CAAC,EAAE,CAAC;YAC9D,SAAS;QACX,CAAC;QAED,IAAI,gBAAgB,CAAC,WAAW,CAAC,EAAE,CAAC;YAClC,kBAAkB,CAAC,YAAY,EAAE,WAA6B,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;YACvF,SAAS;QACX,CAAC;QAED,IAAI,gBAAgB,CAAC,WAAW,CAAC,EAAE,CAAC;YAClC,qBAAqB,CACnB,YAAY,EACZ,WAA6B,EAC7B,UAAU,EACV,SAAS,EACT,WAAW,CACZ,CAAC;QACJ,CAAC;IACH,CAAC;IAED,uBAAuB,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;AACpD,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,cAAc,GAAG,CAAC,IAAY,EAAE,WAAwB,EAAW,EAAE;IACzE,OAAO,CAAC,oBAAoB,CAAC,WAAW,CAAC,IAAI,IAAI,KAAK,GAAG,CAAC;AAC5D,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,uBAAuB,GAAG,CAAC,IAAY,EAAE,WAAwB,EAAQ,EAAE;IAC/E,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;QACpB,WAAW,CAAC,WAAW,GAAG,IAAI,CAAC;QAC/B,WAAW,CAAC,gBAAgB,GAAG,KAAK,CAAC;QACrC,OAAO;IACT,CAAC;IAED,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;QACpB,WAAW,CAAC,WAAW,GAAG,KAAK,CAAC;QAChC,WAAW,CAAC,gBAAgB,GAAG,KAAK,CAAC;IACvC,CAAC;AACH,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,kBAAkB,GAAG,CAAC,IAAY,EAAE,WAAwB,EAAW,EAAE;IAC7E,OAAO,IAAI,KAAK,IAAI,IAAI,CAAC,WAAW,CAAC,cAAc,CAAC;AACtD,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,mBAAmB,GAAG,CAAC,IAAY,EAAE,WAAwB,EAAW,EAAE;IAC9E,OAAO,IAAI,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,cAAc,CAAC;AACrD,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,mBAAmB,GAAG,CAAC,IAAY,EAAE,WAAwB,EAAW,EAAE;IAC9E,OAAO,IAAI,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,cAAc,CAAC;AACrD,CAAC,CAAC;AAEF;;;;GAIG;AACH,MAAM,oBAAoB,GAAG,CAAC,WAAwB,EAAW,EAAE;IACjE,OAAO,WAAW,CAAC,cAAc,IAAI,WAAW,CAAC,cAAc,CAAC;AAClE,CAAC,CAAC;AAEF;;;;GAIG;AACH,MAAM,eAAe,GAAG,CAAC,IAAY,EAAW,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAE7E;;;;;;;GAOG;AACH,MAAM,iBAAiB,GAAG,CACxB,WAAmB,EACnB,WAAmB,EACnB,WAAwB,EAChB,EAAE;IACV,IAAI,eAAe,CAAC,WAAW,CAAC,EAAE,CAAC;QACjC,OAAO,WAAW,GAAG,WAAW,CAAC;IACnC,CAAC;IAED,uBAAuB,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;IAClD,OAAO,EAAE,CAAC;AACZ,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,oBAAoB,GAAG,CAAC,WAAmB,EAAE,WAAwB,EAAW,EAAE;IACtF,OAAO,WAAW,CAAC,WAAW,IAAI,CAAC,WAAW,CAAC,gBAAgB,IAAI,WAAW,KAAK,GAAG,CAAC;AACzF,CAAC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,mBAAmB,GAAG,CAC1B,IAAY,EACZ,SAAiB,EACjB,WAAwB,EACf,EAAE;IACX,OAAO,CACL,WAAW,CAAC,WAAW,IAAI,WAAW,CAAC,gBAAgB,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,SAAS,CAAC,CAC5F,CAAC;AACJ,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,+BAA+B,GAAG,CACtC,WAAmB,EACnB,WAAwB,EACf,EAAE;IACX,OAAO,CACL,WAAW,CAAC,WAAW;QACvB,CAAC,WAAW,CAAC,gBAAgB;QAC7B,CAAC,gBAAgB,CAAC,WAAW,CAAC,IAAI,gBAAgB,CAAC,WAAW,CAAC,CAAC,CACjE,CAAC;AACJ,CAAC,CAAC;AAEF;;;;GAIG;AACH,MAAM,gBAAgB,GAAG,CAAC,IAAY,EAAW,EAAE;IACjD,OAAO,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,GAAG,CAAC;AACtD,CAAC,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,kBAAkB,GAAG,CACzB,YAA4B,EAC5B,cAA8B,EAC9B,UAAkB,EAClB,SAAiB,EACX,EAAE;IACR,YAAY,CAAC,IAAI,CAAC;QAChB,IAAI,EAAE,cAAc;QACpB,IAAI,EAAE,UAAU;QAChB,SAAS;KACV,CAAC,CAAC;AACL,CAAC,CAAC;AAEF;;;;GAIG;AACH,MAAM,gBAAgB,GAAG,CAAC,IAAY,EAAW,EAAE;IACjD,OAAO,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,GAAG,CAAC;AACtD,CAAC,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,qBAAqB,GAAG,CAC5B,YAA4B,EAC5B,cAA8B,EAC9B,UAAkB,EAClB,SAAiB,EACjB,WAAyB,EACnB,EAAE;IACR,MAAM,8BAA8B,GAAG,uBAAuB,CAAC,cAAc,CAAC,CAAC;IAC/E,MAAM,cAAc,GAAG,YAAY,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAE3C,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,WAAW,CAAC,IAAI,CACd,sBAAsB,CACpB,8BAA8B,cAAc,IAAI,EAChD,UAAU,EACV,SAAS,CACV,CACF,CAAC;QACF,OAAO;IACT,CAAC;IAED,IAAI,cAAc,CAAC,IAAI,KAAK,8BAA8B,EAAE,CAAC;QAC3D,MAAM,8BAA8B,GAClC,uBAAuB,CAAC,cAAc,CAAC,IAAsB,CAAC,CAAC;QAEjE,WAAW,CAAC,IAAI,CACd,sBAAsB,CACpB,+BAA+B,cAAc,gBAAgB,8BAA8B,eAAe,cAAc,CAAC,IAAI,IAAI,EACjI,UAAU,EACV,SAAS,CACV,CACF,CAAC;QACF,OAAO;IACT,CAAC;IAED,YAAY,CAAC,GAAG,EAAE,CAAC;AACrB,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,sCAAsC,GAAG,CAC7C,YAA4B,EAC5B,WAAyB,EACnB,EAAE;IACR,OAAO,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/B,MAAM,cAAc,GAAG,YAAY,CAAC,GAAG,EAAkB,CAAC;QAC1D,WAAW,CAAC,IAAI,CACd,sBAAsB,CACpB,8BAA8B,cAAc,CAAC,IAAI,IAAI,EACrD,cAAc,CAAC,IAAI,EACnB,cAAc,CAAC,SAAS,CACzB,CACF,CAAC;IACJ,CAAC;AACH,CAAC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,sBAAsB,GAAG,CAAC,OAAe,EAAE,IAAY,EAAE,SAAiB,EAAc,EAAE;IAC9F,OAAO;QACL,QAAQ,EAAE,gCAAkB,CAAC,KAAK;QAClC,OAAO;QACP,MAAM,EAAE,uBAAuB;QAC/B,KAAK,EAAE,oBAAoB,CAAC,IAAI,EAAE,SAAS,CAAC;QAC5C,IAAI,EAAE,EAAE,IAAI,EAAE,4BAAc,CAAC,cAAc,EAAE;KAC9C,CAAC;AACJ,CAAC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,oBAAoB,GAAG,CAAC,IAAY,EAAE,SAAiB,EAAS,EAAE,CAAC,CAAC;IACxE,KAAK,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;IAC1B,GAAG,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,GAAG,CAAC,EAAE;CACxC,CAAC,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.diagnostic = void 0;
|
|
4
|
+
const documents_1 = require("../../../interfaces/documents");
|
|
5
|
+
const bracketDiagnostics_1 = require("./bracketDiagnostics");
|
|
6
|
+
const structureSemicolonDiagnostics_1 = require("./structureSemicolonDiagnostics");
|
|
7
|
+
/**
|
|
8
|
+
* Handles `textDocument/diagnostic` requests and returns full-document
|
|
9
|
+
* diagnostics for bracket matching errors and control structure semicolon
|
|
10
|
+
* checks.
|
|
11
|
+
*
|
|
12
|
+
* @param message JSON-RPC request containing document diagnostic params.
|
|
13
|
+
* @returns Full diagnostic report for the requested document.
|
|
14
|
+
*/
|
|
15
|
+
const diagnostic = (message) => {
|
|
16
|
+
const params = message.params;
|
|
17
|
+
const content = documents_1.documents.get(params.textDocument.uri);
|
|
18
|
+
if (!content) {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
return {
|
|
22
|
+
kind: "full",
|
|
23
|
+
items: [...(0, bracketDiagnostics_1.bracketDiagnostics)(content), ...(0, structureSemicolonDiagnostics_1.structureSemicolonDiagnostics)(content)],
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
exports.diagnostic = diagnostic;
|
|
27
|
+
//# sourceMappingURL=diagnostic.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diagnostic.js","sourceRoot":"","sources":["../../../../src/methods/textDocument/diagnostic/diagnostic.ts"],"names":[],"mappings":";;;AACA,6DAA0D;AAK1D,6DAA0D;AAC1D,mFAAgF;AAEhF;;;;;;;GAOG;AACI,MAAM,UAAU,GAAG,CAAC,OAAuB,EAAuC,EAAE;IACzF,MAAM,MAAM,GAAG,OAAO,CAAC,MAAkC,CAAC;IAC1D,MAAM,OAAO,GAAG,qBAAS,CAAC,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;IAEvD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO;QACL,IAAI,EAAE,MAAM;QACZ,KAAK,EAAE,CAAC,GAAG,IAAA,uCAAkB,EAAC,OAAO,CAAC,EAAE,GAAG,IAAA,6DAA6B,EAAC,OAAO,CAAC,CAAC;KACnF,CAAC;AACJ,CAAC,CAAC;AAZW,QAAA,UAAU,cAYrB"}
|