sysml-v2-lsp 0.36.0 → 0.37.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/CHANGELOG.md +13 -0
- package/README.md +13 -0
- package/dist/server/browserServerMain.js +652 -467
- package/dist/server/mcpServer.js +339 -121
- package/dist/server/parseWorker.js +20 -0
- package/dist/server/server.js +654 -469
- package/package.json +1 -1
package/dist/server/mcpServer.js
CHANGED
|
@@ -20332,6 +20332,7 @@ __export(util_exports, {
|
|
|
20332
20332
|
required: () => required,
|
|
20333
20333
|
safeExtend: () => safeExtend,
|
|
20334
20334
|
shallowClone: () => shallowClone,
|
|
20335
|
+
sizeCaps: () => sizeCaps,
|
|
20335
20336
|
slugify: () => slugify,
|
|
20336
20337
|
stringifyPrimitive: () => stringifyPrimitive,
|
|
20337
20338
|
toZod: () => toZod,
|
|
@@ -20851,6 +20852,18 @@ function prefixIssues(path, issues) {
|
|
|
20851
20852
|
function unwrapMessage(message) {
|
|
20852
20853
|
return typeof message === "string" ? message : message?.message;
|
|
20853
20854
|
}
|
|
20855
|
+
function sizeCaps(defChecks) {
|
|
20856
|
+
const caps = [];
|
|
20857
|
+
for (const ch of defChecks ?? []) {
|
|
20858
|
+
const d = ch._zod.def;
|
|
20859
|
+
if (!/_(length|size)$|_equals$/.test(d.check))
|
|
20860
|
+
break;
|
|
20861
|
+
const max = d.maximum ?? d.length ?? d.size;
|
|
20862
|
+
if (max >= 0)
|
|
20863
|
+
caps.push([max, ch]);
|
|
20864
|
+
}
|
|
20865
|
+
return caps;
|
|
20866
|
+
}
|
|
20854
20867
|
function attachSchema(issues, start, inst) {
|
|
20855
20868
|
var _a3;
|
|
20856
20869
|
for (let i = start; i < issues.length; i++) {
|
|
@@ -22271,7 +22284,7 @@ ${content.join("\n")}
|
|
|
22271
22284
|
var version = {
|
|
22272
22285
|
major: 4,
|
|
22273
22286
|
minor: 6,
|
|
22274
|
-
patch:
|
|
22287
|
+
patch: 6
|
|
22275
22288
|
};
|
|
22276
22289
|
|
|
22277
22290
|
// node_modules/zod/v4/core/schemas.js
|
|
@@ -23027,6 +23040,31 @@ var $ZodDate = /* @__PURE__ */ $constructor("$ZodDate", (inst, def) => {
|
|
|
23027
23040
|
return payload;
|
|
23028
23041
|
};
|
|
23029
23042
|
});
|
|
23043
|
+
function capSize(inst, size) {
|
|
23044
|
+
const caps = sizeCaps(inst._zod.def.checks);
|
|
23045
|
+
if (!caps.length)
|
|
23046
|
+
return;
|
|
23047
|
+
const cap = Math.min(...caps.map((c) => c[0]));
|
|
23048
|
+
const parse4 = inst._zod.parse;
|
|
23049
|
+
inst._zod.parse = (payload, ctx2) => {
|
|
23050
|
+
const n2 = size(payload.value);
|
|
23051
|
+
if (n2 > cap && !ctx2?.skipChecks && ctx2?.direction !== "backward") {
|
|
23052
|
+
for (const [max, ch] of sizeCaps(inst._zod.def.checks)) {
|
|
23053
|
+
if (n2 > max && ch._zod.def.when(payload)) {
|
|
23054
|
+
const start = payload.issues.length;
|
|
23055
|
+
ch._zod.check(payload);
|
|
23056
|
+
payload.issues[start].continue = false;
|
|
23057
|
+
attachSchema(payload.issues, start, inst);
|
|
23058
|
+
return payload;
|
|
23059
|
+
}
|
|
23060
|
+
}
|
|
23061
|
+
}
|
|
23062
|
+
return parse4(payload, ctx2);
|
|
23063
|
+
};
|
|
23064
|
+
}
|
|
23065
|
+
var arraySize = (input2) => Array.isArray(input2) ? input2.length : -1;
|
|
23066
|
+
var mapSize = (input2) => input2 instanceof Map ? input2.size : -1;
|
|
23067
|
+
var setSize = (input2) => input2 instanceof Set ? input2.size : -1;
|
|
23030
23068
|
function handleArrayResult(result, final, index2) {
|
|
23031
23069
|
if (result.issues.length) {
|
|
23032
23070
|
final.issues.push(...prefixIssues(index2, result.issues));
|
|
@@ -23070,6 +23108,7 @@ var $ZodArray = /* @__PURE__ */ $constructor("$ZodArray", (inst, def) => {
|
|
|
23070
23108
|
}
|
|
23071
23109
|
return payload;
|
|
23072
23110
|
};
|
|
23111
|
+
capSize(inst, arraySize);
|
|
23073
23112
|
});
|
|
23074
23113
|
function handlePropertyResult(result, final, key, input2, optin, optout) {
|
|
23075
23114
|
const isPresent = key in input2;
|
|
@@ -24026,6 +24065,7 @@ var $ZodMap = /* @__PURE__ */ $constructor("$ZodMap", (inst, def) => {
|
|
|
24026
24065
|
return Promise.all(proms).then(() => payload);
|
|
24027
24066
|
return payload;
|
|
24028
24067
|
};
|
|
24068
|
+
capSize(inst, mapSize);
|
|
24029
24069
|
});
|
|
24030
24070
|
function handleMapResult(keyResult, valueResult, final, key, input2, inst, ctx2) {
|
|
24031
24071
|
if (keyResult.issues.length) {
|
|
@@ -24092,6 +24132,7 @@ var $ZodSet = /* @__PURE__ */ $constructor("$ZodSet", (inst, def) => {
|
|
|
24092
24132
|
return Promise.all(proms).then(() => payload);
|
|
24093
24133
|
return payload;
|
|
24094
24134
|
};
|
|
24135
|
+
capSize(inst, setSize);
|
|
24095
24136
|
});
|
|
24096
24137
|
function handleSetResult(result, final) {
|
|
24097
24138
|
if (result.issues.length) {
|
|
@@ -33622,9 +33663,15 @@ function generateNullableCheck(doc, ctx2, schema, accessor, buildsValue = true)
|
|
|
33622
33663
|
doc.write(`}`);
|
|
33623
33664
|
return outputVar;
|
|
33624
33665
|
}
|
|
33666
|
+
function generateSizeGate(doc, schema, size) {
|
|
33667
|
+
for (const [max, check2] of sizeCaps(schema._zod.def.checks)) {
|
|
33668
|
+
doc.write(`if (${size} > ${numericOperand(max, check2._zod.def.check)}) return INVALID;`);
|
|
33669
|
+
}
|
|
33670
|
+
}
|
|
33625
33671
|
function generateArrayCheck(doc, ctx2, schema, accessor, buildsValue = true) {
|
|
33626
33672
|
const def = schema._zod.def;
|
|
33627
33673
|
doc.write(`if (!Array.isArray(${accessor})) return INVALID;`);
|
|
33674
|
+
generateSizeGate(doc, schema, `${accessor}.length`);
|
|
33628
33675
|
const outputVar = buildsValue ? newVar(ctx2) : null;
|
|
33629
33676
|
const iVar = newVar(ctx2);
|
|
33630
33677
|
const elemVar = newVar(ctx2);
|
|
@@ -34024,6 +34071,7 @@ function literalPropertyKey(ctx2, key) {
|
|
|
34024
34071
|
function generateMapCheck(doc, ctx2, schema, accessor) {
|
|
34025
34072
|
const def = schema._zod.def;
|
|
34026
34073
|
doc.write(`if (!(${accessor} instanceof Map)) return INVALID;`);
|
|
34074
|
+
generateSizeGate(doc, schema, `${accessor}.size`);
|
|
34027
34075
|
const outputVar = newVar(ctx2);
|
|
34028
34076
|
const kVar = newVar(ctx2);
|
|
34029
34077
|
const valVar = newVar(ctx2);
|
|
@@ -34040,6 +34088,7 @@ function generateMapCheck(doc, ctx2, schema, accessor) {
|
|
|
34040
34088
|
function generateSetCheck(doc, ctx2, schema, accessor) {
|
|
34041
34089
|
const def = schema._zod.def;
|
|
34042
34090
|
doc.write(`if (!(${accessor} instanceof Set)) return INVALID;`);
|
|
34091
|
+
generateSizeGate(doc, schema, `${accessor}.size`);
|
|
34043
34092
|
const outputVar = newVar(ctx2);
|
|
34044
34093
|
const valVar = newVar(ctx2);
|
|
34045
34094
|
doc.write(`const ${outputVar} = new Set();`);
|
|
@@ -158824,18 +158873,71 @@ var SysMLErrorListener = class extends BaseErrorListener {
|
|
|
158824
158873
|
}
|
|
158825
158874
|
};
|
|
158826
158875
|
|
|
158876
|
+
// server/src/parser/positionUtils.ts
|
|
158877
|
+
function normalizeUtf16Columns(text, tokens, errors) {
|
|
158878
|
+
if (!/[\uD800-\uDBFF][\uDC00-\uDFFF]/.test(text)) return;
|
|
158879
|
+
const columns = /* @__PURE__ */ new Map();
|
|
158880
|
+
const lines = text.split("\n");
|
|
158881
|
+
for (let line = 0; line < lines.length; line++) {
|
|
158882
|
+
if (!/[\uD800-\uDBFF][\uDC00-\uDFFF]/.test(lines[line])) continue;
|
|
158883
|
+
const offsets = [0];
|
|
158884
|
+
for (const character of lines[line]) offsets.push(offsets[offsets.length - 1] + character.length);
|
|
158885
|
+
columns.set(line, offsets);
|
|
158886
|
+
}
|
|
158887
|
+
for (const token of tokens) {
|
|
158888
|
+
token.column = columns.get(token.line - 1)?.[token.column] ?? token.column;
|
|
158889
|
+
}
|
|
158890
|
+
for (const error62 of errors) {
|
|
158891
|
+
error62.column = columns.get(error62.line)?.[error62.column] ?? error62.column;
|
|
158892
|
+
}
|
|
158893
|
+
}
|
|
158894
|
+
function tokenToPosition(token) {
|
|
158895
|
+
return {
|
|
158896
|
+
line: (token.line ?? 1) - 1,
|
|
158897
|
+
character: token.column ?? 0
|
|
158898
|
+
};
|
|
158899
|
+
}
|
|
158900
|
+
function tokenToRange(token) {
|
|
158901
|
+
const start = tokenToPosition(token);
|
|
158902
|
+
const length = token.text?.length ?? 1;
|
|
158903
|
+
return {
|
|
158904
|
+
start,
|
|
158905
|
+
end: { line: start.line, character: start.character + length }
|
|
158906
|
+
};
|
|
158907
|
+
}
|
|
158908
|
+
function contextToRange(ctx2) {
|
|
158909
|
+
const startToken = ctx2.start;
|
|
158910
|
+
const stopToken = ctx2.stop ?? ctx2.start;
|
|
158911
|
+
if (!startToken) {
|
|
158912
|
+
return { start: { line: 0, character: 0 }, end: { line: 0, character: 0 } };
|
|
158913
|
+
}
|
|
158914
|
+
const start = {
|
|
158915
|
+
line: (startToken.line ?? 1) - 1,
|
|
158916
|
+
character: startToken.column ?? 0
|
|
158917
|
+
};
|
|
158918
|
+
const end = stopToken ? {
|
|
158919
|
+
line: (stopToken.line ?? 1) - 1,
|
|
158920
|
+
character: (stopToken.column ?? 0) + (stopToken.text?.length ?? 1)
|
|
158921
|
+
} : { line: start.line, character: start.character + 1 };
|
|
158922
|
+
return { start, end };
|
|
158923
|
+
}
|
|
158924
|
+
|
|
158827
158925
|
// server/src/parser/parseDocument.ts
|
|
158926
|
+
function withUtf16Columns(text, result) {
|
|
158927
|
+
normalizeUtf16Columns(text, result.tokenStream.getTokens(), result.errors);
|
|
158928
|
+
return result;
|
|
158929
|
+
}
|
|
158828
158930
|
function parseDocument(text) {
|
|
158829
158931
|
const result = parseDocumentCore(text);
|
|
158830
158932
|
if (result.errors.length > 0 && hasStaleDfaStates()) {
|
|
158831
158933
|
markDfaNotPreSeeded();
|
|
158832
158934
|
clearAllDFAStates();
|
|
158833
|
-
return parseDocumentLL(text, result.lexer, result.tokenStream);
|
|
158935
|
+
return withUtf16Columns(text, parseDocumentLL(text, result.lexer, result.tokenStream));
|
|
158834
158936
|
}
|
|
158835
158937
|
if (isDfaPreSeeded()) {
|
|
158836
158938
|
markDfaNotPreSeeded();
|
|
158837
158939
|
}
|
|
158838
|
-
return result;
|
|
158940
|
+
return withUtf16Columns(text, result);
|
|
158839
158941
|
}
|
|
158840
158942
|
function parseDocumentCore(text) {
|
|
158841
158943
|
const inputStream = CharStream.fromString(text);
|
|
@@ -158924,10 +159026,152 @@ var _batchDefaultStrategy = new DefaultErrorStrategy();
|
|
|
158924
159026
|
// server/src/providers/semanticValidator.ts
|
|
158925
159027
|
var import_node = __toESM(require_node3());
|
|
158926
159028
|
|
|
159029
|
+
// server/src/utils/sysmlKeywords.ts
|
|
159030
|
+
var SYSML_KEYWORDS_ARRAY = SysMLv2Lexer.literalNames.filter((n2) => n2 != null).map((n2) => n2.replace(/^'|'$/g, "")).filter((n2) => /^[a-z]+$/.test(n2)).sort();
|
|
159031
|
+
var SYSML_KEYWORDS = new Set(SYSML_KEYWORDS_ARRAY);
|
|
159032
|
+
|
|
158927
159033
|
// server/src/utils/identUtils.ts
|
|
159034
|
+
function isIdentStart(c) {
|
|
159035
|
+
return c >= 65 && c <= 90 || c >= 97 && c <= 122 || c === 95;
|
|
159036
|
+
}
|
|
158928
159037
|
function isIdentPart(c) {
|
|
158929
159038
|
return c >= 65 && c <= 90 || c >= 97 && c <= 122 || c >= 48 && c <= 57 || c === 95;
|
|
158930
159039
|
}
|
|
159040
|
+
var ESCAPES = {
|
|
159041
|
+
b: "\b",
|
|
159042
|
+
t: " ",
|
|
159043
|
+
n: "\n",
|
|
159044
|
+
f: "\f",
|
|
159045
|
+
r: "\r",
|
|
159046
|
+
"'": "'",
|
|
159047
|
+
'"': '"',
|
|
159048
|
+
"\\": "\\"
|
|
159049
|
+
};
|
|
159050
|
+
function unquoteName(text) {
|
|
159051
|
+
if (!text.startsWith("'") || !text.endsWith("'")) return text;
|
|
159052
|
+
return text.slice(1, -1).replace(/\\([btnfr'"\\])/g, (_, ch) => ESCAPES[ch]);
|
|
159053
|
+
}
|
|
159054
|
+
function quoteName(name) {
|
|
159055
|
+
if (/^[A-Za-z_][A-Za-z_0-9]*$/.test(name) && !SYSML_KEYWORDS.has(name)) return name;
|
|
159056
|
+
const escaped = name.replace(/[\\'\b\t\n\f\r]/g, (ch) => {
|
|
159057
|
+
const entry = Object.entries(ESCAPES).find(([, value]) => value === ch);
|
|
159058
|
+
return `\\${entry[0]}`;
|
|
159059
|
+
});
|
|
159060
|
+
return `'${escaped}'`;
|
|
159061
|
+
}
|
|
159062
|
+
function splitQualifiedName(text) {
|
|
159063
|
+
const parts = [];
|
|
159064
|
+
let start = 0;
|
|
159065
|
+
let quoted = false;
|
|
159066
|
+
for (let i = 0; i < text.length; i++) {
|
|
159067
|
+
if (quoted && text[i] === "\\") {
|
|
159068
|
+
i++;
|
|
159069
|
+
continue;
|
|
159070
|
+
}
|
|
159071
|
+
if (text[i] === "'" && (quoted || i === start)) quoted = !quoted;
|
|
159072
|
+
if (!quoted && text.startsWith("::", i)) {
|
|
159073
|
+
parts.push(unquoteName(text.slice(start, i).trim()));
|
|
159074
|
+
start = i + 2;
|
|
159075
|
+
i++;
|
|
159076
|
+
}
|
|
159077
|
+
}
|
|
159078
|
+
parts.push(unquoteName(text.slice(start).trim()));
|
|
159079
|
+
return parts;
|
|
159080
|
+
}
|
|
159081
|
+
function joinQualifiedName(parts) {
|
|
159082
|
+
return parts.map((part) => /::|['\\\r\n\t\b\f]/.test(part) ? quoteName(part) : part).join("::");
|
|
159083
|
+
}
|
|
159084
|
+
function readNameAt(text, start, allowIncomplete = false) {
|
|
159085
|
+
if (text[start] === "'") {
|
|
159086
|
+
let end2 = start + 1;
|
|
159087
|
+
while (end2 < text.length && text[end2] !== "'") {
|
|
159088
|
+
if (text[end2] === "\r" || text[end2] === "\n") return void 0;
|
|
159089
|
+
if (text[end2] === "\\") {
|
|
159090
|
+
if (!Object.hasOwn(ESCAPES, text[end2 + 1])) return void 0;
|
|
159091
|
+
end2++;
|
|
159092
|
+
}
|
|
159093
|
+
end2++;
|
|
159094
|
+
}
|
|
159095
|
+
if (end2 >= text.length) {
|
|
159096
|
+
return allowIncomplete ? { name: unquoteName(`${text.slice(start)}'`), start, end: text.length } : void 0;
|
|
159097
|
+
}
|
|
159098
|
+
if (end2 === start + 1 && !allowIncomplete) return void 0;
|
|
159099
|
+
return { name: unquoteName(text.slice(start, end2 + 1)), start, end: end2 + 1 };
|
|
159100
|
+
}
|
|
159101
|
+
if (!isIdentStart(text.charCodeAt(start))) return void 0;
|
|
159102
|
+
let end = start + 1;
|
|
159103
|
+
while (end < text.length && isIdentPart(text.charCodeAt(end))) end++;
|
|
159104
|
+
return { name: text.slice(start, end), start, end };
|
|
159105
|
+
}
|
|
159106
|
+
function readQualifiedNameAt(text, start, allowIncomplete = false) {
|
|
159107
|
+
const first = readNameAt(text, start, allowIncomplete);
|
|
159108
|
+
if (!first) return void 0;
|
|
159109
|
+
const segments = [first];
|
|
159110
|
+
let end = first.end;
|
|
159111
|
+
while (end < text.length) {
|
|
159112
|
+
let next = end;
|
|
159113
|
+
while (/\s/.test(text[next] ?? "") && next < text.length) next++;
|
|
159114
|
+
if (!text.startsWith("::", next)) break;
|
|
159115
|
+
next += 2;
|
|
159116
|
+
while (/\s/.test(text[next] ?? "") && next < text.length) next++;
|
|
159117
|
+
const segment = readNameAt(text, next, allowIncomplete);
|
|
159118
|
+
if (!segment) break;
|
|
159119
|
+
segments.push(segment);
|
|
159120
|
+
end = segment.end;
|
|
159121
|
+
}
|
|
159122
|
+
return { name: joinQualifiedName(segments.map((s) => s.name)), start, end, segments };
|
|
159123
|
+
}
|
|
159124
|
+
function* scanQualifiedNames(text, allowIncomplete = false) {
|
|
159125
|
+
let i = 0;
|
|
159126
|
+
while (i < text.length) {
|
|
159127
|
+
if (text.startsWith("//", i)) {
|
|
159128
|
+
const end = text.indexOf("\n", i + 2);
|
|
159129
|
+
i = end < 0 ? text.length : end + 1;
|
|
159130
|
+
} else if (text.startsWith("/*", i)) {
|
|
159131
|
+
const end = text.indexOf("*/", i + 2);
|
|
159132
|
+
i = end < 0 ? text.length : end + 2;
|
|
159133
|
+
} else if (text[i] === '"') {
|
|
159134
|
+
i++;
|
|
159135
|
+
while (i < text.length && text[i] !== '"') i += text[i] === "\\" ? 2 : 1;
|
|
159136
|
+
i++;
|
|
159137
|
+
} else if (/\d/.test(text[i]) || text[i] === "." && /\d/.test(text[i + 1] ?? "")) {
|
|
159138
|
+
const number4 = text.slice(i).match(/^(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?/);
|
|
159139
|
+
i += number4[0].length;
|
|
159140
|
+
} else {
|
|
159141
|
+
const name = readQualifiedNameAt(text, i, allowIncomplete);
|
|
159142
|
+
if (name) {
|
|
159143
|
+
yield name;
|
|
159144
|
+
i = name.end;
|
|
159145
|
+
} else if (text[i] === "'") {
|
|
159146
|
+
i++;
|
|
159147
|
+
while (i < text.length && text[i] !== "'" && text[i] !== "\n") {
|
|
159148
|
+
i += text[i] === "\\" ? 2 : 1;
|
|
159149
|
+
}
|
|
159150
|
+
if (text[i] === "'") i++;
|
|
159151
|
+
} else {
|
|
159152
|
+
i++;
|
|
159153
|
+
}
|
|
159154
|
+
}
|
|
159155
|
+
}
|
|
159156
|
+
}
|
|
159157
|
+
function* scanFeaturePaths(text) {
|
|
159158
|
+
const names = [...scanQualifiedNames(text)];
|
|
159159
|
+
for (let i = 0; i < names.length; i++) {
|
|
159160
|
+
const first = names[i];
|
|
159161
|
+
const parts = [first.name];
|
|
159162
|
+
const qualifiedNames = [first];
|
|
159163
|
+
let end = first.end;
|
|
159164
|
+
while (i + 1 < names.length && /^\s*\.\s*$/.test(text.slice(end, names[i + 1].start))) {
|
|
159165
|
+
parts.push(names[++i].name);
|
|
159166
|
+
qualifiedNames.push(names[i]);
|
|
159167
|
+
end = names[i].end;
|
|
159168
|
+
}
|
|
159169
|
+
yield { name: parts.join("."), start: first.start, end, qualifiedNames, parts: parts.map((part) => {
|
|
159170
|
+
const segments = splitQualifiedName(part);
|
|
159171
|
+
return segments.length === 1 ? segments[0] : part;
|
|
159172
|
+
}) };
|
|
159173
|
+
}
|
|
159174
|
+
}
|
|
158931
159175
|
function stripComments(text) {
|
|
158932
159176
|
return text.replace(/\/\*[\s\S]*?\*\//g, (m2) => m2.replace(/[^\n]/g, " ")).replace(/\/\/[^\n]*/g, (m2) => " ".repeat(m2.length));
|
|
158933
159177
|
}
|
|
@@ -158937,10 +159181,12 @@ var index;
|
|
|
158937
159181
|
var typeIndex;
|
|
158938
159182
|
function resolveLibraryType(name) {
|
|
158939
159183
|
if (!typeIndex) return void 0;
|
|
159184
|
+
const segments = splitQualifiedName(name);
|
|
159185
|
+
name = segments.length === 1 ? segments[0] : joinQualifiedName(segments);
|
|
158940
159186
|
const exact = typeIndex.get(name);
|
|
158941
159187
|
if (exact) return exact;
|
|
158942
|
-
if (
|
|
158943
|
-
const member =
|
|
159188
|
+
if (segments.length > 1) {
|
|
159189
|
+
const member = segments[segments.length - 1];
|
|
158944
159190
|
return typeIndex.get(member);
|
|
158945
159191
|
}
|
|
158946
159192
|
return void 0;
|
|
@@ -159144,6 +159390,10 @@ var NamespaceResolver = class {
|
|
|
159144
159390
|
resolveNameFrom(symbol2, name, indexes) {
|
|
159145
159391
|
return this.resolveQualifiedNameFrom(ownerKeyOf(symbol2, indexes.byId), name, indexes);
|
|
159146
159392
|
}
|
|
159393
|
+
/** Resolve an editor reference within its enclosing namespace, including the root. */
|
|
159394
|
+
resolveNameIn(namespace, name, indexes) {
|
|
159395
|
+
return this.resolveQualifiedNameFrom(namespace ? namespaceKeyOf(namespace) : "", name, indexes);
|
|
159396
|
+
}
|
|
159147
159397
|
/**
|
|
159148
159398
|
* Resolve a (possibly qualified) name to its symbol per §7.5.1, searching
|
|
159149
159399
|
* outward from namespace `start` and its enclosing namespaces (its own resolved
|
|
@@ -159155,7 +159405,7 @@ var NamespaceResolver = class {
|
|
|
159155
159405
|
* its own enclosing package already imported, per §7.5.1/§7.5.3).
|
|
159156
159406
|
*/
|
|
159157
159407
|
resolveQualifiedNameFrom(start, name, indexes) {
|
|
159158
|
-
const [first, ...rest] = name
|
|
159408
|
+
const [first, ...rest] = splitQualifiedName(name);
|
|
159159
159409
|
let resolved;
|
|
159160
159410
|
for (const ancestor of this.namespaceAncestorsOf(start, indexes)) {
|
|
159161
159411
|
const candidates = this.getResolvedMembers(ancestor, indexes).get(first);
|
|
@@ -159322,6 +159572,9 @@ var NamespaceResolver = class {
|
|
|
159322
159572
|
};
|
|
159323
159573
|
for (const owned of indexes.byParent.get(namespace) ?? []) {
|
|
159324
159574
|
addMember(owned.name, { symbol: owned, visibility: owned.visibility ?? "public" });
|
|
159575
|
+
if (owned.shortName) {
|
|
159576
|
+
addMember(owned.shortName, { symbol: owned, visibility: owned.visibility ?? "public" });
|
|
159577
|
+
}
|
|
159325
159578
|
}
|
|
159326
159579
|
perIndexesCache.set(namespace, members2);
|
|
159327
159580
|
const owner = typeof namespace === "string" ? indexes.byQualifiedName.get(namespace) : namespace;
|
|
@@ -159357,13 +159610,17 @@ var NamespaceResolver = class {
|
|
|
159357
159610
|
switch (imp.kind) {
|
|
159358
159611
|
case "membership": {
|
|
159359
159612
|
const target = this.resolveQualifiedNameFrom(importingNamespace, imp.target, indexes);
|
|
159360
|
-
if (target)
|
|
159613
|
+
if (target) {
|
|
159614
|
+
addMember(target.name, { symbol: target, visibility: imp.visibility });
|
|
159615
|
+
if (target.shortName) addMember(target.shortName, { symbol: target, visibility: imp.visibility });
|
|
159616
|
+
}
|
|
159361
159617
|
break;
|
|
159362
159618
|
}
|
|
159363
159619
|
case "membership-deep": {
|
|
159364
159620
|
const target = this.resolveQualifiedNameFrom(importingNamespace, imp.target, indexes);
|
|
159365
159621
|
if (target) {
|
|
159366
159622
|
addMember(target.name, { symbol: target, visibility: imp.visibility });
|
|
159623
|
+
if (target.shortName) addMember(target.shortName, { symbol: target, visibility: imp.visibility });
|
|
159367
159624
|
this.importVisibleMembers(namespaceKeyOf(target), imp.visibility, indexes, addMember, true);
|
|
159368
159625
|
}
|
|
159369
159626
|
break;
|
|
@@ -159419,42 +159676,6 @@ var NamespaceResolver = class {
|
|
|
159419
159676
|
}
|
|
159420
159677
|
};
|
|
159421
159678
|
|
|
159422
|
-
// server/src/parser/positionUtils.ts
|
|
159423
|
-
function tokenToPosition(token) {
|
|
159424
|
-
return {
|
|
159425
|
-
line: (token.line ?? 1) - 1,
|
|
159426
|
-
character: token.column ?? 0
|
|
159427
|
-
};
|
|
159428
|
-
}
|
|
159429
|
-
function tokenToRange(token) {
|
|
159430
|
-
const start = tokenToPosition(token);
|
|
159431
|
-
const length = token.text?.length ?? 1;
|
|
159432
|
-
return {
|
|
159433
|
-
start,
|
|
159434
|
-
end: { line: start.line, character: start.character + length }
|
|
159435
|
-
};
|
|
159436
|
-
}
|
|
159437
|
-
function contextToRange(ctx2) {
|
|
159438
|
-
const startToken = ctx2.start;
|
|
159439
|
-
const stopToken = ctx2.stop ?? ctx2.start;
|
|
159440
|
-
if (!startToken) {
|
|
159441
|
-
return { start: { line: 0, character: 0 }, end: { line: 0, character: 0 } };
|
|
159442
|
-
}
|
|
159443
|
-
const start = {
|
|
159444
|
-
line: (startToken.line ?? 1) - 1,
|
|
159445
|
-
character: startToken.column ?? 0
|
|
159446
|
-
};
|
|
159447
|
-
const end = stopToken ? {
|
|
159448
|
-
line: (stopToken.line ?? 1) - 1,
|
|
159449
|
-
character: (stopToken.column ?? 0) + (stopToken.text?.length ?? 1)
|
|
159450
|
-
} : { line: start.line, character: start.character + 1 };
|
|
159451
|
-
return { start, end };
|
|
159452
|
-
}
|
|
159453
|
-
|
|
159454
|
-
// server/src/utils/sysmlKeywords.ts
|
|
159455
|
-
var SYSML_KEYWORDS_ARRAY = SysMLv2Lexer.literalNames.filter((n2) => n2 != null).map((n2) => n2.replace(/^'|'$/g, "")).filter((n2) => /^[a-z]+$/.test(n2)).sort();
|
|
159456
|
-
var SYSML_KEYWORDS = new Set(SYSML_KEYWORDS_ARRAY);
|
|
159457
|
-
|
|
159458
159679
|
// server/src/utils/names.ts
|
|
159459
159680
|
var BASIC_NAME = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
159460
159681
|
function escapeName(name) {
|
|
@@ -160068,7 +160289,7 @@ var RE_SPEC_WITH_SUBSETS = /(?:specializes|subsets|:>|:>>)\s*('[^']+'|[A-Za-z_]\
|
|
|
160068
160289
|
var RE_DEFINED_BY = /definedby\s*([A-Za-z_]\w*(?:::\w+)*(?:\s*,\s*[A-Za-z_]\w*(?:::\w+)*)*)/;
|
|
160069
160290
|
var MAX_RULE_SEARCH_DEPTH = 6;
|
|
160070
160291
|
var RE_TYPING = /:(?![:>])\s*('[^']+'|[A-Za-z_]\w*(?:::\w+)*)/;
|
|
160071
|
-
var RE_QUOTED_NAME =
|
|
160292
|
+
var RE_QUOTED_NAME = /^\s*(?:\$::)?(?:(?:[A-Za-z_]\w*|'\d+')::)*'(\d+)'/;
|
|
160072
160293
|
var RE_IDENT_START = /^([A-Za-z_]\w*(?:::\w+)*)/;
|
|
160073
160294
|
var SymbolTable = class {
|
|
160074
160295
|
/** All symbols indexed by qualified name */
|
|
@@ -160135,7 +160356,12 @@ var SymbolTable = class {
|
|
|
160135
160356
|
* Find a symbol by name (simple name, not qualified).
|
|
160136
160357
|
*/
|
|
160137
160358
|
findByName(name) {
|
|
160138
|
-
|
|
160359
|
+
const exact = this.symbolsByName.get(name);
|
|
160360
|
+
if (exact) return exact;
|
|
160361
|
+
const segments = splitQualifiedName(name);
|
|
160362
|
+
if (segments.length === 1) return this.symbolsByName.get(segments[0]) ?? [];
|
|
160363
|
+
const qualified = this.getSymbol(joinQualifiedName(segments));
|
|
160364
|
+
return qualified ? [qualified] : [];
|
|
160139
160365
|
}
|
|
160140
160366
|
/**
|
|
160141
160367
|
* Find all symbols in a given URI.
|
|
@@ -160642,7 +160868,7 @@ var SymbolTable = class {
|
|
|
160642
160868
|
const anonymous = !declaredName;
|
|
160643
160869
|
const name = declaredName ?? "";
|
|
160644
160870
|
const shortName = transition || isFlowUsage(kind) && !declaredName ? void 0 : this.extractShortName(ctx2);
|
|
160645
|
-
const qualifiedName = anonymous || owner && owner.qualifiedName === void 0 ? void 0 : owner ? `${owner.qualifiedName}::${name}` : name;
|
|
160871
|
+
const qualifiedName = anonymous || owner && owner.qualifiedName === void 0 ? void 0 : owner ? `${owner.qualifiedName}::${joinQualifiedName([name])}` : joinQualifiedName([name]);
|
|
160646
160872
|
const selectionRange = anonymous ? ctx2.start ? tokenToRange(ctx2.start) : range : this.extractNameRange(ctx2) ?? range;
|
|
160647
160873
|
const typeNames = isFlowUsage(kind) ? this.extractFlowTypeNames(ctx2) : transition ? this.extractTransitionTypeNames(ctx2) : this.extractTypeNames(ctx2);
|
|
160648
160874
|
const specializationNames = this.extractSpecializationNames(ctx2);
|
|
@@ -160802,7 +161028,10 @@ var SymbolTable = class {
|
|
|
160802
161028
|
}
|
|
160803
161029
|
/** Remove SysML quoting while retaining qualified and dotted references. */
|
|
160804
161030
|
cleanTransitionText(text) {
|
|
160805
|
-
const cleaned = text.replace(
|
|
161031
|
+
const cleaned = text.replace(
|
|
161032
|
+
/'(?:\\.|[^'\\])*'/g,
|
|
161033
|
+
(name) => joinQualifiedName([unquoteName(name)])
|
|
161034
|
+
).trim();
|
|
160806
161035
|
return cleaned || void 0;
|
|
160807
161036
|
}
|
|
160808
161037
|
/** Extract explicit first/then successions owned by an action body. */
|
|
@@ -160975,8 +161204,8 @@ var SymbolTable = class {
|
|
|
160975
161204
|
}
|
|
160976
161205
|
/** The name of the feature a reference such as `a.b` or `P::a` ends at (`b`, `a`). */
|
|
160977
161206
|
lastNameSegment(reference) {
|
|
160978
|
-
const
|
|
160979
|
-
return
|
|
161207
|
+
const names = [...scanQualifiedNames(reference.getText())];
|
|
161208
|
+
return names.at(-1)?.segments.at(-1)?.name;
|
|
160980
161209
|
}
|
|
160981
161210
|
declarationTokens(ctx2) {
|
|
160982
161211
|
const tokens = [];
|
|
@@ -161112,6 +161341,16 @@ var SymbolTable = class {
|
|
|
161112
161341
|
* Extract the range of just the name token.
|
|
161113
161342
|
*/
|
|
161114
161343
|
extractNameRange(ctx2) {
|
|
161344
|
+
if (ctx2.ruleIndex === SysMLv2Parser.RULE_identification || ctx2.ruleIndex === SysMLv2Parser.RULE_featureIdentification) {
|
|
161345
|
+
let name;
|
|
161346
|
+
for (let i = 0; i < ctx2.getChildCount(); i++) {
|
|
161347
|
+
const child = ctx2.getChild(i);
|
|
161348
|
+
if (child instanceof ParserRuleContext && child.ruleIndex === SysMLv2Parser.RULE_name) {
|
|
161349
|
+
name = child;
|
|
161350
|
+
}
|
|
161351
|
+
}
|
|
161352
|
+
if (name) return contextToRange(name);
|
|
161353
|
+
}
|
|
161115
161354
|
for (let i = 0; i < ctx2.getChildCount(); i++) {
|
|
161116
161355
|
const child = ctx2.getChild(i);
|
|
161117
161356
|
if (child instanceof TerminalNode && this.isNameTerminal(child)) {
|
|
@@ -161152,7 +161391,7 @@ var SymbolTable = class {
|
|
|
161152
161391
|
for (const part of specStr.split(",")) {
|
|
161153
161392
|
const quoted = quotedName(part);
|
|
161154
161393
|
if (quoted !== void 0) {
|
|
161155
|
-
names.push(quoted);
|
|
161394
|
+
names.push(joinQualifiedName([quoted]));
|
|
161156
161395
|
continue;
|
|
161157
161396
|
}
|
|
161158
161397
|
const m2 = part.trim().match(RE_IDENT_START);
|
|
@@ -161175,7 +161414,7 @@ var SymbolTable = class {
|
|
|
161175
161414
|
for (const part of afterColon.split(",")) {
|
|
161176
161415
|
const quoted = quotedName(part);
|
|
161177
161416
|
if (quoted !== void 0) {
|
|
161178
|
-
names.push(quoted);
|
|
161417
|
+
names.push(joinQualifiedName([quoted]));
|
|
161179
161418
|
continue;
|
|
161180
161419
|
}
|
|
161181
161420
|
const m2 = part.trim().match(RE_IDENT_START);
|
|
@@ -161186,18 +161425,20 @@ var SymbolTable = class {
|
|
|
161186
161425
|
return names;
|
|
161187
161426
|
}
|
|
161188
161427
|
/**
|
|
161189
|
-
* The declaration tokens before the body, with each lexer STRING token
|
|
161428
|
+
* The declaration tokens before the value or body, with each lexer STRING token
|
|
161190
161429
|
* replaced by a numbered placeholder (`'0'`, `'1'`, ...), and
|
|
161191
161430
|
* `quotedName`, which turns a placeholder in a part of that text back into
|
|
161192
|
-
* the name
|
|
161193
|
-
*
|
|
161194
|
-
*
|
|
161431
|
+
* the name, when it ends the qualified name the part starts with. SysML
|
|
161432
|
+
* 2.0 section 7.2.2 permits punctuation in unrestricted names (the STRING
|
|
161433
|
+
* lexer production), so fallback regexes must never see their `:`, `:>`,
|
|
161434
|
+
* `{` or keywords. Documentation is not a name token.
|
|
161195
161435
|
*/
|
|
161196
161436
|
maskedDeclaration(ctx2) {
|
|
161197
161437
|
const quoted = [];
|
|
161198
|
-
const
|
|
161438
|
+
const valueStart = this.findOwnHeaderRule(ctx2, SysMLv2Parser.RULE_valuePart)?.start?.tokenIndex;
|
|
161439
|
+
const masked = this.declarationTokens(ctx2).filter((token) => valueStart === void 0 || token.tokenIndex < valueStart).map((token) => {
|
|
161199
161440
|
const text = token.text ?? "";
|
|
161200
|
-
return token.type === SysMLv2Lexer.STRING ? `'${quoted.push(text
|
|
161441
|
+
return token.type === SysMLv2Lexer.STRING ? `'${quoted.push(unquoteName(text)) - 1}'` : text;
|
|
161201
161442
|
}).join("");
|
|
161202
161443
|
return {
|
|
161203
161444
|
text: masked,
|
|
@@ -161225,7 +161466,7 @@ var SymbolTable = class {
|
|
|
161225
161466
|
for (const part of specStr.split(",")) {
|
|
161226
161467
|
const quoted = quotedName(part);
|
|
161227
161468
|
if (quoted !== void 0) {
|
|
161228
|
-
names.push(quoted);
|
|
161469
|
+
names.push(joinQualifiedName([quoted]));
|
|
161229
161470
|
continue;
|
|
161230
161471
|
}
|
|
161231
161472
|
const m2 = part.trim().match(RE_IDENT_START);
|
|
@@ -161254,17 +161495,7 @@ var SymbolTable = class {
|
|
|
161254
161495
|
if (!(child instanceof ParserRuleContext)) continue;
|
|
161255
161496
|
const ri = child.ruleIndex;
|
|
161256
161497
|
if (extractionRules.has(ri)) {
|
|
161257
|
-
|
|
161258
|
-
const stripped = childText.replace(/^(specializes|:>>|:>|:|definedby|subsets|redefines|references|conjugates|disjoints)/i, "");
|
|
161259
|
-
for (const part of stripped.split(",")) {
|
|
161260
|
-
const qm = part.match(/'([^']+)'/);
|
|
161261
|
-
if (qm) {
|
|
161262
|
-
names.push(qm[1]);
|
|
161263
|
-
} else {
|
|
161264
|
-
const m2 = part.match(/([A-Za-z_]\w*(?:::\w+)*)/);
|
|
161265
|
-
if (m2) names.push(m2[1]);
|
|
161266
|
-
}
|
|
161267
|
-
}
|
|
161498
|
+
this.collectQualifiedTypeNames(child, names);
|
|
161268
161499
|
} else if (
|
|
161269
161500
|
// Recurse into declaration / part / body wrappers that may
|
|
161270
161501
|
// contain nested typing rules (but NOT into body rules that
|
|
@@ -161277,6 +161508,17 @@ var SymbolTable = class {
|
|
|
161277
161508
|
}
|
|
161278
161509
|
}
|
|
161279
161510
|
}
|
|
161511
|
+
collectQualifiedTypeNames(ctx2, names) {
|
|
161512
|
+
if (ctx2.ruleIndex === SysMLv2Parser.RULE_qualifiedName) {
|
|
161513
|
+
const name = this.extractTextFromSubtree(ctx2);
|
|
161514
|
+
if (name) names.push(name);
|
|
161515
|
+
return;
|
|
161516
|
+
}
|
|
161517
|
+
for (let i = 0; i < ctx2.getChildCount(); i++) {
|
|
161518
|
+
const child = ctx2.getChild(i);
|
|
161519
|
+
if (child instanceof ParserRuleContext) this.collectQualifiedTypeNames(child, names);
|
|
161520
|
+
}
|
|
161521
|
+
}
|
|
161280
161522
|
/**
|
|
161281
161523
|
* Extract documentation owned by this element.
|
|
161282
161524
|
*
|
|
@@ -161437,10 +161679,7 @@ var SymbolTable = class {
|
|
|
161437
161679
|
* Returns the text unchanged if not quoted.
|
|
161438
161680
|
*/
|
|
161439
161681
|
unquoteName(text) {
|
|
161440
|
-
|
|
161441
|
-
return text.slice(1, -1);
|
|
161442
|
-
}
|
|
161443
|
-
return text;
|
|
161682
|
+
return unquoteName(text);
|
|
161444
161683
|
}
|
|
161445
161684
|
/**
|
|
161446
161685
|
* Check if a text is a SysML keyword.
|
|
@@ -161728,7 +161967,7 @@ var SymbolTable = class {
|
|
|
161728
161967
|
const child = ctx2.getChild(i);
|
|
161729
161968
|
if (child instanceof TerminalNode) {
|
|
161730
161969
|
const text = child.symbol.text;
|
|
161731
|
-
if (text) parts.push(text);
|
|
161970
|
+
if (text) parts.push(child.symbol.type === SysMLv2Lexer.STRING ? joinQualifiedName([unquoteName(text)]) : text);
|
|
161732
161971
|
} else if (child instanceof ParserRuleContext) {
|
|
161733
161972
|
this.collectExposeText(child, parts);
|
|
161734
161973
|
}
|
|
@@ -161790,17 +162029,18 @@ var SymbolTable = class {
|
|
|
161790
162029
|
* Extract all text content from a subtree (concatenate terminal nodes).
|
|
161791
162030
|
*/
|
|
161792
162031
|
extractTextFromSubtree(ctx2) {
|
|
162032
|
+
if (ctx2.ruleIndex === SysMLv2Parser.RULE_name) return unquoteName(ctx2.getText());
|
|
161793
162033
|
const parts = [];
|
|
161794
162034
|
for (let i = 0; i < ctx2.getChildCount(); i++) {
|
|
161795
162035
|
const child = ctx2.getChild(i);
|
|
161796
162036
|
if (child instanceof TerminalNode) {
|
|
161797
162037
|
const text = child.symbol.text;
|
|
161798
162038
|
if (text && this.isNameTerminal(child)) {
|
|
161799
|
-
parts.push(this.unquoteName(text));
|
|
162039
|
+
parts.push(joinQualifiedName([this.unquoteName(text)]));
|
|
161800
162040
|
}
|
|
161801
162041
|
} else if (child instanceof ParserRuleContext) {
|
|
161802
162042
|
const sub = this.extractTextFromSubtree(child);
|
|
161803
|
-
if (sub) parts.push(sub);
|
|
162043
|
+
if (sub) parts.push(child.ruleIndex === SysMLv2Parser.RULE_name ? joinQualifiedName([sub]) : sub);
|
|
161804
162044
|
}
|
|
161805
162045
|
}
|
|
161806
162046
|
return parts.length > 0 ? parts.join("::") : void 0;
|
|
@@ -161916,7 +162156,7 @@ function isISQValueType(name) {
|
|
|
161916
162156
|
function resolveTypeName(typeName, symbol2, resolver, indexes, libraryNames) {
|
|
161917
162157
|
const kwMatch = typeName.match(/^([A-Z][A-Za-z_0-9]*?)(redefines|subsets|references|connect|bind|default|via|accept|send|flow|allocate|assign|decide|merge|join|fork)([A-Z])/);
|
|
161918
162158
|
const strippedTypeName = kwMatch ? kwMatch[1] : typeName;
|
|
161919
|
-
const rootSegment = strippedTypeName
|
|
162159
|
+
const rootSegment = splitQualifiedName(strippedTypeName)[0];
|
|
161920
162160
|
const resolved = resolver.isLocallyVisible(symbol2, strippedTypeName, indexes) || STANDARD_LIBRARY_TYPES.has(strippedTypeName) || STANDARD_LIBRARY_TYPES.has(rootSegment) || libraryNames.has(rootSegment) || isISQValueType(strippedTypeName) || resolveLibraryType(strippedTypeName) !== void 0 || resolveLibraryType(rootSegment) !== void 0 || // Names starting with lowercase are feature references (subsettings
|
|
161921
162161
|
// via :>), not type references — don't flag them as unresolved types.
|
|
161922
162162
|
strippedTypeName.charCodeAt(0) >= 97 && strippedTypeName.charCodeAt(0) <= 122;
|
|
@@ -163637,19 +163877,19 @@ var SemanticValidator = class _SemanticValidator {
|
|
|
163637
163877
|
);
|
|
163638
163878
|
const defsInScope = targetUri ? defs.filter((def) => def.uri === targetUri) : defs;
|
|
163639
163879
|
const referencedTypes = new Set(
|
|
163640
|
-
symbols.filter((s) => s.kind !== "package" /* Package */).flatMap((s) => s.typeNames)
|
|
163880
|
+
symbols.filter((s) => s.kind !== "package" /* Package */).flatMap((s) => s.typeNames.flatMap((name) => [name, splitQualifiedName(name).at(-1)]))
|
|
163641
163881
|
);
|
|
163642
163882
|
for (const s of symbols) {
|
|
163643
163883
|
if (s.exposeTargets) {
|
|
163644
163884
|
for (const target of s.exposeTargets) {
|
|
163645
|
-
const simpleName = target.replace(/::\*{1,2}$/, "")
|
|
163885
|
+
const simpleName = splitQualifiedName(target.replace(/::\*{1,2}$/, "")).pop();
|
|
163646
163886
|
if (simpleName) referencedTypes.add(simpleName);
|
|
163647
163887
|
}
|
|
163648
163888
|
}
|
|
163649
163889
|
}
|
|
163650
163890
|
const diagnostics = [];
|
|
163651
163891
|
for (const def of defsInScope) {
|
|
163652
|
-
const isReferenced = referencedTypes.has(def.name);
|
|
163892
|
+
const isReferenced = referencedTypes.has(def.name) || def.shortName !== void 0 && referencedTypes.has(def.shortName);
|
|
163653
163893
|
const hasBaseType = (def.typeNames?.length ?? 0) > 0;
|
|
163654
163894
|
if (!isReferenced && !hasBaseType) {
|
|
163655
163895
|
diagnostics.push({
|
|
@@ -164075,14 +164315,15 @@ var SemanticValidator = class _SemanticValidator {
|
|
|
164075
164315
|
if (!text) return [];
|
|
164076
164316
|
const diagnostics = [];
|
|
164077
164317
|
const lines = text.split("\n");
|
|
164078
|
-
const
|
|
164079
|
-
let
|
|
164080
|
-
|
|
164081
|
-
|
|
164082
|
-
const
|
|
164318
|
+
const paths = [...scanFeaturePaths(text)];
|
|
164319
|
+
for (let i = 0; i + 3 < paths.length; i++) {
|
|
164320
|
+
const [connect, leftEnd, to, rightEnd] = paths.slice(i, i + 4);
|
|
164321
|
+
if (text.slice(connect.start, connect.end) !== "connect" || text.slice(to.start, to.end) !== "to" || !/^\s+$/.test(text.slice(connect.end, leftEnd.start)) || !/^\s+$/.test(text.slice(leftEnd.end, to.start)) || !/^\s+$/.test(text.slice(to.end, rightEnd.start))) continue;
|
|
164322
|
+
const leftPath = [...leftEnd.parts];
|
|
164323
|
+
const rightPath = [...rightEnd.parts];
|
|
164083
164324
|
const left = leftPath[leftPath.length - 1];
|
|
164084
164325
|
const right = rightPath[rightPath.length - 1];
|
|
164085
|
-
const scope = this.connectorScope(symbolsInUri, this.indexToRange(text,
|
|
164326
|
+
const scope = this.connectorScope(symbolsInUri, this.indexToRange(text, connect.start, 0).start, indexes);
|
|
164086
164327
|
const lSym = this.resolveConnectorEnd(leftPath, scope, indexes);
|
|
164087
164328
|
const rSym = this.resolveConnectorEnd(rightPath, scope, indexes);
|
|
164088
164329
|
if (!lSym || !rSym) continue;
|
|
@@ -164092,10 +164333,10 @@ var SemanticValidator = class _SemanticValidator {
|
|
|
164092
164333
|
if (lType === "~" + rType || rType === "~" + lType) continue;
|
|
164093
164334
|
if (lType.startsWith("~") && lType.slice(1) === rType) continue;
|
|
164094
164335
|
if (rType.startsWith("~") && rType.slice(1) === lType) continue;
|
|
164095
|
-
const matchLine = text.substring(0,
|
|
164336
|
+
const matchLine = text.substring(0, connect.start).split("\n").length - 1;
|
|
164096
164337
|
let insideInterfaceDef = false;
|
|
164097
|
-
for (let
|
|
164098
|
-
const line = (lines[
|
|
164338
|
+
for (let i2 = matchLine; i2 >= 0 && i2 >= matchLine - 30; i2--) {
|
|
164339
|
+
const line = (lines[i2] || "").trim();
|
|
164099
164340
|
if (/\binterface\s+def\b/.test(line)) {
|
|
164100
164341
|
insideInterfaceDef = true;
|
|
164101
164342
|
break;
|
|
@@ -164103,7 +164344,7 @@ var SemanticValidator = class _SemanticValidator {
|
|
|
164103
164344
|
if (/^\s*package\b/.test(line)) break;
|
|
164104
164345
|
}
|
|
164105
164346
|
if (insideInterfaceDef) continue;
|
|
164106
|
-
const precedingText = text.substring(Math.max(0,
|
|
164347
|
+
const precedingText = text.substring(Math.max(0, connect.start - 300), connect.start);
|
|
164107
164348
|
if (/\binterface\s+\w[\w']*(:\w[\w']*)?\s*$/m.test(precedingText)) continue;
|
|
164108
164349
|
const lDefSyms = indexes.byName.get(lType) ?? [];
|
|
164109
164350
|
const rDefSyms = indexes.byName.get(rType) ?? [];
|
|
@@ -164122,14 +164363,14 @@ var SemanticValidator = class _SemanticValidator {
|
|
|
164122
164363
|
const hasSharedFeature = rChildren.some((c) => lChildNames.has(c.name));
|
|
164123
164364
|
if (hasSharedFeature) continue;
|
|
164124
164365
|
}
|
|
164125
|
-
const range = this.indexToRange(text,
|
|
164366
|
+
const range = this.indexToRange(text, connect.start, rightEnd.end - connect.start);
|
|
164126
164367
|
diagnostics.push({
|
|
164127
164368
|
severity: import_node.DiagnosticSeverity.Warning,
|
|
164128
164369
|
range,
|
|
164129
164370
|
message: `Port compatibility issue: '${left}' (${lType}) is connected to '${right}' (${rType})`,
|
|
164130
164371
|
source: "sysml",
|
|
164131
164372
|
code: "incompatible-port-types",
|
|
164132
|
-
data: { uri }
|
|
164373
|
+
data: { uri, left, right, leftType: lType }
|
|
164133
164374
|
});
|
|
164134
164375
|
}
|
|
164135
164376
|
return diagnostics;
|
|
@@ -164232,15 +164473,11 @@ var SemanticValidator = class _SemanticValidator {
|
|
|
164232
164473
|
if (!parent) continue;
|
|
164233
164474
|
const parentMembers = this.getConstraintScopeMembers(parent, indexes);
|
|
164234
164475
|
if (parentMembers.length === 0) continue;
|
|
164235
|
-
const
|
|
164236
|
-
|
|
164237
|
-
let im;
|
|
164238
|
-
while ((im = idRe.exec(b.body)) !== null) {
|
|
164239
|
-
if (this.isIndexInRanges(im.index, ignoredRanges)) continue;
|
|
164240
|
-
const expr = im[1];
|
|
164476
|
+
for (const reference of scanFeaturePaths(b.body)) {
|
|
164477
|
+
const expr = reference.name;
|
|
164241
164478
|
if (this.isConstraintKeyword(expr)) continue;
|
|
164242
164479
|
if (/^\d/.test(expr)) continue;
|
|
164243
|
-
const path =
|
|
164480
|
+
const path = [...reference.parts];
|
|
164244
164481
|
const ok = this.resolvePathFromParent(path, parentMembers, indexes);
|
|
164245
164482
|
if (ok) continue;
|
|
164246
164483
|
if (path.length === 1) {
|
|
@@ -164249,14 +164486,14 @@ var SemanticValidator = class _SemanticValidator {
|
|
|
164249
164486
|
continue;
|
|
164250
164487
|
}
|
|
164251
164488
|
}
|
|
164252
|
-
const absoluteStart = b.bodyOffset +
|
|
164489
|
+
const absoluteStart = b.bodyOffset + reference.start;
|
|
164253
164490
|
diagnostics.push({
|
|
164254
164491
|
severity: import_node.DiagnosticSeverity.Warning,
|
|
164255
|
-
range: this.indexToRange(text, absoluteStart,
|
|
164492
|
+
range: this.indexToRange(text, absoluteStart, reference.end - reference.start),
|
|
164256
164493
|
message: `Unresolved constraint reference '${expr}' in scope '${displayName(parent)}'`,
|
|
164257
164494
|
source: "sysml",
|
|
164258
164495
|
code: "unresolved-constraint-reference",
|
|
164259
|
-
data: { uri }
|
|
164496
|
+
data: { uri, scopeName: parent.name }
|
|
164260
164497
|
});
|
|
164261
164498
|
}
|
|
164262
164499
|
}
|
|
@@ -164450,25 +164687,6 @@ var SemanticValidator = class _SemanticValidator {
|
|
|
164450
164687
|
isConstraintKeyword(value) {
|
|
164451
164688
|
return CONSTRAINT_KEYWORDS.has(value);
|
|
164452
164689
|
}
|
|
164453
|
-
getIgnoredBodyRanges(body) {
|
|
164454
|
-
const ranges = [];
|
|
164455
|
-
const blockRe = /\/\*[\s\S]*?\*\//g;
|
|
164456
|
-
let m2;
|
|
164457
|
-
while ((m2 = blockRe.exec(body)) !== null) {
|
|
164458
|
-
ranges.push({ start: m2.index, end: m2.index + m2[0].length });
|
|
164459
|
-
}
|
|
164460
|
-
const lineRe = /\/\/[^\n\r]*/g;
|
|
164461
|
-
while ((m2 = lineRe.exec(body)) !== null) {
|
|
164462
|
-
ranges.push({ start: m2.index, end: m2.index + m2[0].length });
|
|
164463
|
-
}
|
|
164464
|
-
return ranges;
|
|
164465
|
-
}
|
|
164466
|
-
isIndexInRanges(index2, ranges) {
|
|
164467
|
-
for (const r of ranges) {
|
|
164468
|
-
if (index2 >= r.start && index2 < r.end) return true;
|
|
164469
|
-
}
|
|
164470
|
-
return false;
|
|
164471
|
-
}
|
|
164472
164690
|
hasDocumentationOnlyConstraintBody(body) {
|
|
164473
164691
|
const trimmed = body.trim();
|
|
164474
164692
|
if (!trimmed) return false;
|