umple-lsp-server 0.2.1 → 0.2.4
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/completions.scm +21 -6
- package/definitions.scm +4 -0
- package/out/completionAnalysis.d.ts +44 -0
- package/out/completionAnalysis.js +391 -0
- package/out/completionAnalysis.js.map +1 -0
- package/out/completionBuilder.d.ts +28 -0
- package/out/completionBuilder.js +251 -0
- package/out/completionBuilder.js.map +1 -0
- package/out/documentSymbolBuilder.d.ts +13 -0
- package/out/documentSymbolBuilder.js +95 -0
- package/out/documentSymbolBuilder.js.map +1 -0
- package/out/formatRules.d.ts +27 -0
- package/out/formatRules.js +114 -0
- package/out/formatRules.js.map +1 -0
- package/out/formatter.d.ts +53 -0
- package/out/formatter.js +380 -0
- package/out/formatter.js.map +1 -0
- package/out/hoverBuilder.d.ts +21 -0
- package/out/hoverBuilder.js +308 -0
- package/out/hoverBuilder.js.map +1 -0
- package/out/importGraph.d.ts +28 -0
- package/out/importGraph.js +91 -0
- package/out/importGraph.js.map +1 -0
- package/out/referenceSearch.d.ts +22 -0
- package/out/referenceSearch.js +271 -0
- package/out/referenceSearch.js.map +1 -0
- package/out/resolver.d.ts +21 -0
- package/out/resolver.js +174 -0
- package/out/resolver.js.map +1 -0
- package/out/server.js +560 -327
- package/out/server.js.map +1 -1
- package/out/symbolIndex.d.ts +100 -94
- package/out/symbolIndex.js +392 -399
- package/out/symbolIndex.js.map +1 -1
- package/out/symbolTypes.d.ts +34 -0
- package/out/symbolTypes.js +9 -0
- package/out/symbolTypes.js.map +1 -0
- package/out/tokenAnalysis.d.ts +24 -0
- package/out/tokenAnalysis.js +195 -0
- package/out/tokenAnalysis.js.map +1 -0
- package/out/tokenTypes.d.ts +46 -0
- package/out/tokenTypes.js +28 -0
- package/out/tokenTypes.js.map +1 -0
- package/out/treeUtils.d.ts +32 -0
- package/out/treeUtils.js +89 -0
- package/out/treeUtils.js.map +1 -0
- package/package.json +4 -2
- package/references.scm +78 -10
- package/tree-sitter-umple.wasm +0 -0
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Shared completion-item assembly logic.
|
|
4
|
+
*
|
|
5
|
+
* Extracted from server.ts so both the LSP server and the test harness
|
|
6
|
+
* exercise the same production code path.
|
|
7
|
+
*
|
|
8
|
+
* Scope: keyword filtering, operator suppression, built-in types, and
|
|
9
|
+
* symbol-based completions. Does NOT handle use-path file completions,
|
|
10
|
+
* trigger-character gating, or comment/definition-name suppression —
|
|
11
|
+
* those stay in server.ts.
|
|
12
|
+
*/
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.symbolKindToCompletionKind = symbolKindToCompletionKind;
|
|
15
|
+
exports.buildSemanticCompletionItems = buildSemanticCompletionItems;
|
|
16
|
+
const node_1 = require("vscode-languageserver/node");
|
|
17
|
+
const keywords_1 = require("./keywords");
|
|
18
|
+
const path = require("path");
|
|
19
|
+
// ── Constraint keyword blocklist ────────────────────────────────────────────
|
|
20
|
+
const CONSTRAINT_BLOCKLIST = new Set([
|
|
21
|
+
"ERROR",
|
|
22
|
+
// Top-level definition keywords
|
|
23
|
+
"namespace", "class", "interface", "trait", "abstract",
|
|
24
|
+
"association", "associationClass", "statemachine",
|
|
25
|
+
"enum", "external", "mixset",
|
|
26
|
+
// Generate statement + all targets
|
|
27
|
+
"generate", "Java", "Nothing", "Php", "RTCpp", "SimpleCpp",
|
|
28
|
+
"Ruby", "Python", "Cpp", "Json", "StructureDiagram", "Yuml",
|
|
29
|
+
"Violet", "Umlet", "Simulate", "TextUml", "Scxml",
|
|
30
|
+
"GvStateDiagram", "GvClassDiagram", "GvFeatureDiagram",
|
|
31
|
+
"GvClassTraitDiagram", "GvEntityRelationshipDiagram",
|
|
32
|
+
"Alloy", "NuSMV", "NuSMVOptimizer", "Papyrus", "Ecore", "Xmi",
|
|
33
|
+
"Xtext", "Sql", "StateTables", "EventSequence", "InstanceDiagram",
|
|
34
|
+
"Umple", "UmpleSelf", "USE", "Test", "SimpleMetrics",
|
|
35
|
+
"PlainRequirementsDoc", "Uigu2", "ExternalGrammar", "Mermaid",
|
|
36
|
+
// Other top-level directives
|
|
37
|
+
"use", "strictness",
|
|
38
|
+
// Class-level keywords invalid inside constraints
|
|
39
|
+
"isA", "req", "require", "subfeature", "isFeature",
|
|
40
|
+
"depend", "singleton", "displayColor", "displayColour",
|
|
41
|
+
"implementsReq", "filter", "includeFilter",
|
|
42
|
+
// Trace/SM/attribute keywords that can't appear in expressions
|
|
43
|
+
"trace", "tracecase", "activate", "deactivate",
|
|
44
|
+
"onAllObjects", "onThisThreadOnly", "onThisObject",
|
|
45
|
+
"where", "until", "giving", "record",
|
|
46
|
+
"queued", "pooled", "as",
|
|
47
|
+
"key", "immutable", "unique", "lazy", "settable",
|
|
48
|
+
"internal", "defaulted", "autounique",
|
|
49
|
+
"entry", "exit", "do",
|
|
50
|
+
"emit", "around", "custom", "generated",
|
|
51
|
+
"include", "hops", "super", "sub",
|
|
52
|
+
]);
|
|
53
|
+
// ── Kind → CompletionItemKind mapping ───────────────────────────────────────
|
|
54
|
+
function symbolKindToCompletionKind(kind) {
|
|
55
|
+
switch (kind) {
|
|
56
|
+
case "class":
|
|
57
|
+
return node_1.CompletionItemKind.Class;
|
|
58
|
+
case "interface":
|
|
59
|
+
return node_1.CompletionItemKind.Interface;
|
|
60
|
+
case "trait":
|
|
61
|
+
return node_1.CompletionItemKind.Class;
|
|
62
|
+
case "enum":
|
|
63
|
+
return node_1.CompletionItemKind.Enum;
|
|
64
|
+
case "state":
|
|
65
|
+
return node_1.CompletionItemKind.EnumMember;
|
|
66
|
+
case "statemachine":
|
|
67
|
+
return node_1.CompletionItemKind.Enum;
|
|
68
|
+
case "attribute":
|
|
69
|
+
return node_1.CompletionItemKind.Field;
|
|
70
|
+
case "const":
|
|
71
|
+
return node_1.CompletionItemKind.Constant;
|
|
72
|
+
case "method":
|
|
73
|
+
return node_1.CompletionItemKind.Method;
|
|
74
|
+
case "association":
|
|
75
|
+
return node_1.CompletionItemKind.Reference;
|
|
76
|
+
case "mixset":
|
|
77
|
+
return node_1.CompletionItemKind.Module;
|
|
78
|
+
case "requirement":
|
|
79
|
+
return node_1.CompletionItemKind.Reference;
|
|
80
|
+
case "template":
|
|
81
|
+
return node_1.CompletionItemKind.Property;
|
|
82
|
+
default:
|
|
83
|
+
return node_1.CompletionItemKind.Text;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
// ── Main builder ────────────────────────────────────────────────────────────
|
|
87
|
+
/**
|
|
88
|
+
* Build semantic completion items from a CompletionInfo + SymbolIndex.
|
|
89
|
+
*
|
|
90
|
+
* Handles: keyword filtering, operator suppression, built-in types,
|
|
91
|
+
* own-attribute completion, guard/trace attribute+method completion,
|
|
92
|
+
* and array-based symbol completions.
|
|
93
|
+
*
|
|
94
|
+
* Does NOT handle: use-path file completions, trigger-character gating,
|
|
95
|
+
* dotted-state dot-trigger fast path, or comment/definition-name suppression.
|
|
96
|
+
*
|
|
97
|
+
* @param symbolKinds - the normalized symbolKinds (after use_path → mixset conversion).
|
|
98
|
+
* Caller should not pass "suppress", "use_path", isComment, or isDefinitionName states.
|
|
99
|
+
*/
|
|
100
|
+
function buildSemanticCompletionItems(info, symbolKinds, symbolIndex, reachableFiles) {
|
|
101
|
+
const items = [];
|
|
102
|
+
const seen = new Set();
|
|
103
|
+
// 1. Keywords from LookaheadIterator (filtered in constraint contexts)
|
|
104
|
+
let keywords = info.keywords;
|
|
105
|
+
if (symbolKinds === "own_attribute" ||
|
|
106
|
+
symbolKinds === "guard_attribute_method" ||
|
|
107
|
+
symbolKinds === "trace_attribute_method") {
|
|
108
|
+
keywords = keywords.filter((kw) => !CONSTRAINT_BLOCKLIST.has(kw));
|
|
109
|
+
}
|
|
110
|
+
for (const kw of keywords) {
|
|
111
|
+
if (!seen.has(kw)) {
|
|
112
|
+
seen.add(kw);
|
|
113
|
+
items.push({ label: kw, kind: node_1.CompletionItemKind.Keyword });
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
// 2. Operators (skip in guard/constraint/trace contexts)
|
|
117
|
+
if (symbolKinds !== "own_attribute" &&
|
|
118
|
+
symbolKinds !== "guard_attribute_method" &&
|
|
119
|
+
symbolKinds !== "trace_attribute_method") {
|
|
120
|
+
for (const op of info.operators) {
|
|
121
|
+
if (!seen.has(op)) {
|
|
122
|
+
seen.add(op);
|
|
123
|
+
items.push({ label: op, kind: node_1.CompletionItemKind.Operator });
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
// 3. Built-in types (when in type-compatible scope)
|
|
128
|
+
if (Array.isArray(symbolKinds) &&
|
|
129
|
+
symbolKinds.some((k) => ["class", "interface", "trait", "enum"].includes(k))) {
|
|
130
|
+
for (const typ of keywords_1.BUILTIN_TYPES) {
|
|
131
|
+
if (!seen.has(typ)) {
|
|
132
|
+
seen.add(typ);
|
|
133
|
+
items.push({
|
|
134
|
+
label: typ,
|
|
135
|
+
kind: node_1.CompletionItemKind.TypeParameter,
|
|
136
|
+
detail: "type",
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
// 4. Constraint scope: only own attributes (Umple E28)
|
|
142
|
+
if (symbolKinds === "own_attribute" && info.enclosingClass) {
|
|
143
|
+
const symbols = symbolIndex
|
|
144
|
+
.getSymbols({ container: info.enclosingClass, kind: "attribute" })
|
|
145
|
+
.filter((s) => reachableFiles.has(path.normalize(s.file)));
|
|
146
|
+
for (const sym of symbols) {
|
|
147
|
+
if (!seen.has(sym.name)) {
|
|
148
|
+
seen.add(sym.name);
|
|
149
|
+
items.push({
|
|
150
|
+
label: sym.name,
|
|
151
|
+
kind: symbolKindToCompletionKind("attribute"),
|
|
152
|
+
detail: "attribute",
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
return items;
|
|
157
|
+
}
|
|
158
|
+
// 5. Guard/trace scope: attributes + methods from enclosing class (with inheritance)
|
|
159
|
+
if ((symbolKinds === "guard_attribute_method" ||
|
|
160
|
+
symbolKinds === "trace_attribute_method") &&
|
|
161
|
+
info.enclosingClass) {
|
|
162
|
+
for (const kind of ["attribute", "method"]) {
|
|
163
|
+
const symbols = symbolIndex
|
|
164
|
+
.getSymbols({ container: info.enclosingClass, kind, inherited: true })
|
|
165
|
+
.filter((s) => reachableFiles.has(path.normalize(s.file)));
|
|
166
|
+
for (const sym of symbols) {
|
|
167
|
+
if (!seen.has(sym.name)) {
|
|
168
|
+
seen.add(sym.name);
|
|
169
|
+
items.push({
|
|
170
|
+
label: sym.name,
|
|
171
|
+
kind: symbolKindToCompletionKind(kind),
|
|
172
|
+
detail: kind,
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return items;
|
|
178
|
+
}
|
|
179
|
+
// 6. Symbol completions from index (scoped to reachable files)
|
|
180
|
+
if (Array.isArray(symbolKinds)) {
|
|
181
|
+
for (const symKind of symbolKinds) {
|
|
182
|
+
let symbols;
|
|
183
|
+
// Scoped lookups for container-aware kinds
|
|
184
|
+
if (symKind === "attribute" && info.enclosingClass) {
|
|
185
|
+
symbols = symbolIndex
|
|
186
|
+
.getSymbols({
|
|
187
|
+
container: info.enclosingClass,
|
|
188
|
+
kind: "attribute",
|
|
189
|
+
inherited: true,
|
|
190
|
+
})
|
|
191
|
+
.filter((s) => reachableFiles.has(path.normalize(s.file)));
|
|
192
|
+
}
|
|
193
|
+
else if (symKind === "state" && info.enclosingStateMachine) {
|
|
194
|
+
if (info.dottedStatePrefix) {
|
|
195
|
+
const childNames = symbolIndex.getChildStateNames(info.dottedStatePrefix, info.enclosingStateMachine, reachableFiles);
|
|
196
|
+
for (const name of childNames) {
|
|
197
|
+
if (!seen.has(name)) {
|
|
198
|
+
seen.add(name);
|
|
199
|
+
items.push({
|
|
200
|
+
label: name,
|
|
201
|
+
kind: symbolKindToCompletionKind("state"),
|
|
202
|
+
detail: "state",
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
208
|
+
symbols = symbolIndex
|
|
209
|
+
.getSymbols({ container: info.enclosingStateMachine, kind: "state" })
|
|
210
|
+
.filter((s) => reachableFiles.has(path.normalize(s.file)));
|
|
211
|
+
}
|
|
212
|
+
else if (symKind === "statemachine" && info.enclosingClass) {
|
|
213
|
+
symbols = symbolIndex
|
|
214
|
+
.getSymbols({ kind: "statemachine" })
|
|
215
|
+
.filter((s) => s.container?.startsWith(info.enclosingClass + ".") &&
|
|
216
|
+
reachableFiles.has(path.normalize(s.file)));
|
|
217
|
+
}
|
|
218
|
+
else if (symKind === "template" && info.enclosingClass) {
|
|
219
|
+
symbols = symbolIndex
|
|
220
|
+
.getSymbols({ container: info.enclosingClass, kind: "template" })
|
|
221
|
+
.filter((s) => reachableFiles.has(path.normalize(s.file)));
|
|
222
|
+
}
|
|
223
|
+
else if (symKind === "method" && info.enclosingClass) {
|
|
224
|
+
symbols = symbolIndex
|
|
225
|
+
.getSymbols({
|
|
226
|
+
container: info.enclosingClass,
|
|
227
|
+
kind: "method",
|
|
228
|
+
inherited: true,
|
|
229
|
+
})
|
|
230
|
+
.filter((s) => reachableFiles.has(path.normalize(s.file)));
|
|
231
|
+
}
|
|
232
|
+
else {
|
|
233
|
+
symbols = symbolIndex
|
|
234
|
+
.getSymbols({ kind: symKind })
|
|
235
|
+
.filter((s) => reachableFiles.has(path.normalize(s.file)));
|
|
236
|
+
}
|
|
237
|
+
for (const sym of symbols) {
|
|
238
|
+
if (!seen.has(sym.name)) {
|
|
239
|
+
seen.add(sym.name);
|
|
240
|
+
items.push({
|
|
241
|
+
label: sym.name,
|
|
242
|
+
kind: symbolKindToCompletionKind(symKind),
|
|
243
|
+
detail: symKind,
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
return items;
|
|
250
|
+
}
|
|
251
|
+
//# sourceMappingURL=completionBuilder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"completionBuilder.js","sourceRoot":"","sources":["../src/completionBuilder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Document symbol (outline) builder.
|
|
3
|
+
*
|
|
4
|
+
* Converts flat SymbolEntry[] into hierarchical DocumentSymbol[] tree
|
|
5
|
+
* using definition range containment. No LSP connection dependency.
|
|
6
|
+
*/
|
|
7
|
+
import { DocumentSymbol } from "vscode-languageserver/node";
|
|
8
|
+
import type { SymbolEntry } from "./symbolTypes";
|
|
9
|
+
/**
|
|
10
|
+
* Convert a flat list of SymbolEntry[] (single file) into a hierarchical
|
|
11
|
+
* DocumentSymbol[] tree using range containment.
|
|
12
|
+
*/
|
|
13
|
+
export declare function buildDocumentSymbolTree(symbols: SymbolEntry[]): DocumentSymbol[];
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Document symbol (outline) builder.
|
|
4
|
+
*
|
|
5
|
+
* Converts flat SymbolEntry[] into hierarchical DocumentSymbol[] tree
|
|
6
|
+
* using definition range containment. No LSP connection dependency.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.buildDocumentSymbolTree = buildDocumentSymbolTree;
|
|
10
|
+
const node_1 = require("vscode-languageserver/node");
|
|
11
|
+
function umpleKindToLspSymbolKind(kind) {
|
|
12
|
+
switch (kind) {
|
|
13
|
+
case "class":
|
|
14
|
+
return node_1.SymbolKind.Class;
|
|
15
|
+
case "interface":
|
|
16
|
+
return node_1.SymbolKind.Interface;
|
|
17
|
+
case "trait":
|
|
18
|
+
return node_1.SymbolKind.Interface;
|
|
19
|
+
case "enum":
|
|
20
|
+
return node_1.SymbolKind.Enum;
|
|
21
|
+
case "enum_value":
|
|
22
|
+
return node_1.SymbolKind.EnumMember;
|
|
23
|
+
case "attribute":
|
|
24
|
+
return node_1.SymbolKind.Field;
|
|
25
|
+
case "const":
|
|
26
|
+
return node_1.SymbolKind.Constant;
|
|
27
|
+
case "method":
|
|
28
|
+
return node_1.SymbolKind.Method;
|
|
29
|
+
case "template":
|
|
30
|
+
return node_1.SymbolKind.Field;
|
|
31
|
+
case "statemachine":
|
|
32
|
+
return node_1.SymbolKind.Struct;
|
|
33
|
+
case "state":
|
|
34
|
+
return node_1.SymbolKind.EnumMember;
|
|
35
|
+
case "association":
|
|
36
|
+
return node_1.SymbolKind.Property;
|
|
37
|
+
case "mixset":
|
|
38
|
+
return node_1.SymbolKind.Module;
|
|
39
|
+
case "requirement":
|
|
40
|
+
return node_1.SymbolKind.String;
|
|
41
|
+
default:
|
|
42
|
+
return node_1.SymbolKind.Variable;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/** Check if outer's definition range strictly contains inner's. */
|
|
46
|
+
function defRangeContains(outer, inner) {
|
|
47
|
+
const os = outer.defLine * 1e6 + outer.defColumn;
|
|
48
|
+
const oe = outer.defEndLine * 1e6 + outer.defEndColumn;
|
|
49
|
+
const is_ = inner.defLine * 1e6 + inner.defColumn;
|
|
50
|
+
const ie = inner.defEndLine * 1e6 + inner.defEndColumn;
|
|
51
|
+
return os <= is_ && oe >= ie && (os < is_ || oe > ie);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Convert a flat list of SymbolEntry[] (single file) into a hierarchical
|
|
55
|
+
* DocumentSymbol[] tree using range containment.
|
|
56
|
+
*/
|
|
57
|
+
function buildDocumentSymbolTree(symbols) {
|
|
58
|
+
const entries = symbols.filter((s) => s.defLine !== undefined && s.defEndLine !== undefined);
|
|
59
|
+
// Sort by body range start, then largest first (parents before children)
|
|
60
|
+
entries.sort((a, b) => {
|
|
61
|
+
const lineDiff = a.defLine - b.defLine;
|
|
62
|
+
if (lineDiff !== 0)
|
|
63
|
+
return lineDiff;
|
|
64
|
+
const colDiff = a.defColumn - b.defColumn;
|
|
65
|
+
if (colDiff !== 0)
|
|
66
|
+
return colDiff;
|
|
67
|
+
// Same start: larger range first
|
|
68
|
+
const aEnd = a.defEndLine * 1e6 + a.defEndColumn;
|
|
69
|
+
const bEnd = b.defEndLine * 1e6 + b.defEndColumn;
|
|
70
|
+
return bEnd - aEnd;
|
|
71
|
+
});
|
|
72
|
+
const roots = [];
|
|
73
|
+
const stack = [];
|
|
74
|
+
for (const entry of entries) {
|
|
75
|
+
const docSym = node_1.DocumentSymbol.create(entry.name, entry.kind, umpleKindToLspSymbolKind(entry.kind), node_1.Range.create(node_1.Position.create(entry.defLine, entry.defColumn), node_1.Position.create(entry.defEndLine, entry.defEndColumn)), node_1.Range.create(node_1.Position.create(entry.line, entry.column), node_1.Position.create(entry.endLine, entry.endColumn)));
|
|
76
|
+
// Pop stack until we find a parent that contains this entry
|
|
77
|
+
while (stack.length > 0) {
|
|
78
|
+
if (defRangeContains(stack[stack.length - 1].entry, entry))
|
|
79
|
+
break;
|
|
80
|
+
stack.pop();
|
|
81
|
+
}
|
|
82
|
+
if (stack.length === 0) {
|
|
83
|
+
roots.push(docSym);
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
const parent = stack[stack.length - 1].sym;
|
|
87
|
+
if (!parent.children)
|
|
88
|
+
parent.children = [];
|
|
89
|
+
parent.children.push(docSym);
|
|
90
|
+
}
|
|
91
|
+
stack.push({ sym: docSym, entry });
|
|
92
|
+
}
|
|
93
|
+
return roots;
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=documentSymbolBuilder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"documentSymbolBuilder.js","sourceRoot":"","sources":["../src/documentSymbolBuilder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Formatting rule definitions for the syntax-aware formatter.
|
|
3
|
+
*
|
|
4
|
+
* Node-type classification for indentation and skip regions.
|
|
5
|
+
* All node names are verified against the actual tree-sitter grammar.
|
|
6
|
+
*/
|
|
7
|
+
declare const TreeSitter: any;
|
|
8
|
+
type Tree = InstanceType<typeof TreeSitter.Tree>;
|
|
9
|
+
/** Node types whose body content gets +1 indent level. */
|
|
10
|
+
export declare const INDENT_NODES: Set<string>;
|
|
11
|
+
/** Top-level declaration node types that should be separated by blank lines. */
|
|
12
|
+
export declare const TOP_LEVEL_DECL_NODES: Set<string>;
|
|
13
|
+
/** Node types whose content is verbatim (embedded code — do not reindent). */
|
|
14
|
+
export declare const SKIP_NODES: Set<string>;
|
|
15
|
+
/**
|
|
16
|
+
* Check if a line falls strictly inside a verbatim/skip node.
|
|
17
|
+
* Boundary lines (the line with opening `{` and closing `}`) are NOT skipped —
|
|
18
|
+
* they're Umple-structural and should be formatted normally.
|
|
19
|
+
*/
|
|
20
|
+
export declare function isVerbatimLine(tree: Tree, line: number): boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Compute the structural indent depth for a line from its AST ancestors.
|
|
23
|
+
* Only counts indent-contributing ancestors whose body starts ABOVE this line
|
|
24
|
+
* (so the opening line of `class A {` doesn't get +1 from its own node).
|
|
25
|
+
*/
|
|
26
|
+
export declare function computeStructuralDepth(tree: Tree, line: number, column: number): number;
|
|
27
|
+
export {};
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Formatting rule definitions for the syntax-aware formatter.
|
|
4
|
+
*
|
|
5
|
+
* Node-type classification for indentation and skip regions.
|
|
6
|
+
* All node names are verified against the actual tree-sitter grammar.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.SKIP_NODES = exports.TOP_LEVEL_DECL_NODES = exports.INDENT_NODES = void 0;
|
|
10
|
+
exports.isVerbatimLine = isVerbatimLine;
|
|
11
|
+
exports.computeStructuralDepth = computeStructuralDepth;
|
|
12
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
13
|
+
const TreeSitter = require("web-tree-sitter");
|
|
14
|
+
/** Node types whose body content gets +1 indent level. */
|
|
15
|
+
exports.INDENT_NODES = new Set([
|
|
16
|
+
"class_definition",
|
|
17
|
+
"interface_definition",
|
|
18
|
+
"trait_definition",
|
|
19
|
+
"association_class_definition",
|
|
20
|
+
"enum_definition",
|
|
21
|
+
"association_definition",
|
|
22
|
+
"mixset_definition",
|
|
23
|
+
"state_machine",
|
|
24
|
+
"statemachine_definition",
|
|
25
|
+
"state",
|
|
26
|
+
"before_after",
|
|
27
|
+
"toplevel_code_injection",
|
|
28
|
+
"filter_definition",
|
|
29
|
+
"method_declaration",
|
|
30
|
+
]);
|
|
31
|
+
/** Top-level declaration node types that should be separated by blank lines. */
|
|
32
|
+
exports.TOP_LEVEL_DECL_NODES = new Set([
|
|
33
|
+
"class_definition",
|
|
34
|
+
"interface_definition",
|
|
35
|
+
"trait_definition",
|
|
36
|
+
"association_class_definition",
|
|
37
|
+
"enum_definition",
|
|
38
|
+
"association_definition",
|
|
39
|
+
"statemachine_definition",
|
|
40
|
+
"mixset_definition",
|
|
41
|
+
"toplevel_code_injection",
|
|
42
|
+
"namespace_declaration",
|
|
43
|
+
"use_statement",
|
|
44
|
+
"generate_statement",
|
|
45
|
+
"requirement_definition",
|
|
46
|
+
"external_definition",
|
|
47
|
+
]);
|
|
48
|
+
/** Node types whose content is verbatim (embedded code — do not reindent). */
|
|
49
|
+
exports.SKIP_NODES = new Set([
|
|
50
|
+
"code_content",
|
|
51
|
+
"template_body",
|
|
52
|
+
]);
|
|
53
|
+
/**
|
|
54
|
+
* Check if a line falls strictly inside a verbatim/skip node.
|
|
55
|
+
* Boundary lines (the line with opening `{` and closing `}`) are NOT skipped —
|
|
56
|
+
* they're Umple-structural and should be formatted normally.
|
|
57
|
+
*/
|
|
58
|
+
function isVerbatimLine(tree, line) {
|
|
59
|
+
// Walk the tree to find skip nodes that contain this line
|
|
60
|
+
const cursor = tree.rootNode.walk();
|
|
61
|
+
let reachedEnd = false;
|
|
62
|
+
while (!reachedEnd) {
|
|
63
|
+
const node = cursor.currentNode;
|
|
64
|
+
if (exports.SKIP_NODES.has(node.type)) {
|
|
65
|
+
// Strictly between start and end rows (boundary lines are formatted)
|
|
66
|
+
if (node.startPosition.row < line && line < node.endPosition.row) {
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
// Don't descend into skip nodes
|
|
70
|
+
if (!cursor.gotoNextSibling()) {
|
|
71
|
+
while (!cursor.gotoNextSibling()) {
|
|
72
|
+
if (!cursor.gotoParent()) {
|
|
73
|
+
reachedEnd = true;
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
else if (!cursor.gotoFirstChild()) {
|
|
80
|
+
if (!cursor.gotoNextSibling()) {
|
|
81
|
+
while (!cursor.gotoNextSibling()) {
|
|
82
|
+
if (!cursor.gotoParent()) {
|
|
83
|
+
reachedEnd = true;
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Compute the structural indent depth for a line from its AST ancestors.
|
|
94
|
+
* Only counts indent-contributing ancestors whose body starts ABOVE this line
|
|
95
|
+
* (so the opening line of `class A {` doesn't get +1 from its own node).
|
|
96
|
+
*/
|
|
97
|
+
function computeStructuralDepth(tree, line, column) {
|
|
98
|
+
const node = tree.rootNode.descendantForPosition({ row: line, column });
|
|
99
|
+
if (!node)
|
|
100
|
+
return 0;
|
|
101
|
+
let depth = 0;
|
|
102
|
+
let current = node;
|
|
103
|
+
while (current) {
|
|
104
|
+
if (exports.INDENT_NODES.has(current.type)) {
|
|
105
|
+
// Only count if this line is INSIDE the body (not the header line)
|
|
106
|
+
if (current.startPosition.row < line) {
|
|
107
|
+
depth++;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
current = current.parent;
|
|
111
|
+
}
|
|
112
|
+
return depth;
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=formatRules.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formatRules.js","sourceRoot":"","sources":["../src/formatRules.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Syntax-aware document formatter.
|
|
3
|
+
*
|
|
4
|
+
* Uses tree-sitter AST to compute structural indentation instead of
|
|
5
|
+
* naive brace counting. Preserves embedded code regions (code_content,
|
|
6
|
+
* template_body) as verbatim islands.
|
|
7
|
+
*/
|
|
8
|
+
import { TextEdit } from "vscode-languageserver/node";
|
|
9
|
+
declare const TreeSitter: any;
|
|
10
|
+
type Tree = InstanceType<typeof TreeSitter.Tree>;
|
|
11
|
+
/**
|
|
12
|
+
* Expand eligible single-line compact state blocks into multi-line format.
|
|
13
|
+
* Returns the modified text (or the original if nothing changed).
|
|
14
|
+
*/
|
|
15
|
+
export declare function expandCompactStates(text: string, tree: Tree): string;
|
|
16
|
+
/**
|
|
17
|
+
* Compute indent edits for an Umple document using syntax-aware indentation.
|
|
18
|
+
*
|
|
19
|
+
* @param text Document text
|
|
20
|
+
* @param options Formatting options (tabSize, insertSpaces)
|
|
21
|
+
* @param tree Pre-parsed tree-sitter tree
|
|
22
|
+
* @returns Array of TextEdits to apply for correct indentation
|
|
23
|
+
*/
|
|
24
|
+
export declare function computeIndentEdits(text: string, options: {
|
|
25
|
+
tabSize: number;
|
|
26
|
+
insertSpaces: boolean;
|
|
27
|
+
}, tree: Tree): TextEdit[];
|
|
28
|
+
/**
|
|
29
|
+
* Normalize whitespace around `->` in transition and standalone_transition nodes.
|
|
30
|
+
* Only handles single-line nodes. Leaves event, guard, action, and target text verbatim.
|
|
31
|
+
*/
|
|
32
|
+
export declare function fixTransitionSpacing(text: string, tree: Tree): TextEdit[];
|
|
33
|
+
/**
|
|
34
|
+
* Normalize whitespace around the arrow in association_inline and association_member nodes.
|
|
35
|
+
* Only handles single-line nodes. Same child-walking approach as fixTransitionSpacing.
|
|
36
|
+
*/
|
|
37
|
+
export declare function fixAssociationSpacing(text: string, tree: Tree): TextEdit[];
|
|
38
|
+
/**
|
|
39
|
+
* Normalize blank lines between top-level declarations in source_file.
|
|
40
|
+
* Ensures exactly 1 blank line between consecutive top-level named children.
|
|
41
|
+
* Does NOT touch interior body spacing.
|
|
42
|
+
*/
|
|
43
|
+
export declare function normalizeTopLevelBlankLines(text: string, tree: Tree): TextEdit[];
|
|
44
|
+
/**
|
|
45
|
+
* Collect line ranges of code_content and template_body nodes.
|
|
46
|
+
* Kept for backward compatibility with existing callers; the new
|
|
47
|
+
* formatter uses isVerbatimLine() from formatRules instead.
|
|
48
|
+
*/
|
|
49
|
+
export declare function getCodeContentRanges(tree: any): {
|
|
50
|
+
startLine: number;
|
|
51
|
+
endLine: number;
|
|
52
|
+
}[];
|
|
53
|
+
export {};
|