sysml-validate 0.11.0 → 0.14.3

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.
Files changed (121) hide show
  1. package/LICENSE +27 -27
  2. package/README.md +200 -200
  3. package/out/main.js +598 -142
  4. package/out/main.js.map +4 -4
  5. package/package.json +57 -57
  6. package/resources/sysml.dimension-table.json +1 -1
  7. package/resources/sysml.library/Domain Libraries/Analysis/.meta.json +9 -9
  8. package/resources/sysml.library/Domain Libraries/Analysis/.project.json +26 -26
  9. package/resources/sysml.library/Domain Libraries/Analysis/AnalysisTooling.sysml +33 -33
  10. package/resources/sysml.library/Domain Libraries/Analysis/SampledFunctions.sysml +118 -118
  11. package/resources/sysml.library/Domain Libraries/Analysis/StateSpaceRepresentation.sysml +143 -143
  12. package/resources/sysml.library/Domain Libraries/Analysis/TradeStudies.sysml +170 -170
  13. package/resources/sysml.library/Domain Libraries/Cause and Effect/.meta.json +7 -7
  14. package/resources/sysml.library/Domain Libraries/Cause and Effect/.project.json +22 -22
  15. package/resources/sysml.library/Domain Libraries/Cause and Effect/CausationConnections.sysml +82 -82
  16. package/resources/sysml.library/Domain Libraries/Cause and Effect/CauseAndEffect.sysml +81 -81
  17. package/resources/sysml.library/Domain Libraries/Geometry/.meta.json +7 -7
  18. package/resources/sysml.library/Domain Libraries/Geometry/.project.json +26 -26
  19. package/resources/sysml.library/Domain Libraries/Geometry/ShapeItems.sysml +898 -898
  20. package/resources/sysml.library/Domain Libraries/Geometry/SpatialItems.sysml +167 -167
  21. package/resources/sysml.library/Domain Libraries/Metadata/.meta.json +9 -9
  22. package/resources/sysml.library/Domain Libraries/Metadata/.project.json +18 -18
  23. package/resources/sysml.library/Domain Libraries/Metadata/ImageMetadata.sysml +77 -77
  24. package/resources/sysml.library/Domain Libraries/Metadata/ModelingMetadata.sysml +142 -142
  25. package/resources/sysml.library/Domain Libraries/Metadata/ParametersOfInterestMetadata.sysml +38 -38
  26. package/resources/sysml.library/Domain Libraries/Metadata/RiskMetadata.sysml +99 -99
  27. package/resources/sysml.library/Domain Libraries/Quantities and Units/.meta.json +28 -28
  28. package/resources/sysml.library/Domain Libraries/Quantities and Units/.project.json +22 -22
  29. package/resources/sysml.library/Domain Libraries/Quantities and Units/ISQ.sysml +42 -42
  30. package/resources/sysml.library/Domain Libraries/Quantities and Units/ISQAcoustics.sysml +439 -439
  31. package/resources/sysml.library/Domain Libraries/Quantities and Units/ISQAtomicNuclear.sysml +2726 -2726
  32. package/resources/sysml.library/Domain Libraries/Quantities and Units/ISQBase.sysml +206 -206
  33. package/resources/sysml.library/Domain Libraries/Quantities and Units/ISQCharacteristicNumbers.sysml +1991 -1991
  34. package/resources/sysml.library/Domain Libraries/Quantities and Units/ISQChemistryMolecular.sysml +1353 -1353
  35. package/resources/sysml.library/Domain Libraries/Quantities and Units/ISQCondensedMatter.sysml +1223 -1223
  36. package/resources/sysml.library/Domain Libraries/Quantities and Units/ISQElectromagnetism.sysml +2333 -2333
  37. package/resources/sysml.library/Domain Libraries/Quantities and Units/ISQInformation.sysml +958 -958
  38. package/resources/sysml.library/Domain Libraries/Quantities and Units/ISQLight.sysml +1537 -1537
  39. package/resources/sysml.library/Domain Libraries/Quantities and Units/ISQMechanics.sysml +1564 -1564
  40. package/resources/sysml.library/Domain Libraries/Quantities and Units/ISQSpaceTime.sysml +1169 -1169
  41. package/resources/sysml.library/Domain Libraries/Quantities and Units/ISQThermodynamics.sysml +1256 -1256
  42. package/resources/sysml.library/Domain Libraries/Quantities and Units/MeasurementRefCalculations.sysml +30 -30
  43. package/resources/sysml.library/Domain Libraries/Quantities and Units/MeasurementReferences.sysml +526 -526
  44. package/resources/sysml.library/Domain Libraries/Quantities and Units/Quantities.sysml +107 -107
  45. package/resources/sysml.library/Domain Libraries/Quantities and Units/QuantityCalculations.sysml +70 -70
  46. package/resources/sysml.library/Domain Libraries/Quantities and Units/SI.sysml +378 -378
  47. package/resources/sysml.library/Domain Libraries/Quantities and Units/SIPrefixes.sysml +48 -48
  48. package/resources/sysml.library/Domain Libraries/Quantities and Units/TensorCalculations.sysml +49 -49
  49. package/resources/sysml.library/Domain Libraries/Quantities and Units/Time.sysml +274 -274
  50. package/resources/sysml.library/Domain Libraries/Quantities and Units/USCustomaryUnits.sysml +260 -260
  51. package/resources/sysml.library/Domain Libraries/Quantities and Units/VectorCalculations.sysml +62 -62
  52. package/resources/sysml.library/Domain Libraries/Requirement Derivation/.meta.json +7 -7
  53. package/resources/sysml.library/Domain Libraries/Requirement Derivation/.project.json +18 -18
  54. package/resources/sysml.library/Domain Libraries/Requirement Derivation/DerivationConnections.sysml +62 -62
  55. package/resources/sysml.library/Domain Libraries/Requirement Derivation/RequirementDerivation.sysml +38 -38
  56. package/resources/sysml.library/Kernel Libraries/Kernel Data Type Library/.meta.json +8 -8
  57. package/resources/sysml.library/Kernel Libraries/Kernel Data Type Library/.project.json +10 -10
  58. package/resources/sysml.library/Kernel Libraries/Kernel Data Type Library/Collections.kerml +176 -176
  59. package/resources/sysml.library/Kernel Libraries/Kernel Data Type Library/ScalarValues.kerml +23 -23
  60. package/resources/sysml.library/Kernel Libraries/Kernel Data Type Library/VectorValues.kerml +63 -63
  61. package/resources/sysml.library/Kernel Libraries/Kernel Function Library/.meta.json +22 -22
  62. package/resources/sysml.library/Kernel Libraries/Kernel Function Library/.project.json +14 -14
  63. package/resources/sysml.library/Kernel Libraries/Kernel Function Library/BaseFunctions.kerml +79 -79
  64. package/resources/sysml.library/Kernel Libraries/Kernel Function Library/BooleanFunctions.kerml +22 -22
  65. package/resources/sysml.library/Kernel Libraries/Kernel Function Library/CollectionFunctions.kerml +68 -68
  66. package/resources/sysml.library/Kernel Libraries/Kernel Function Library/ComplexFunctions.kerml +47 -47
  67. package/resources/sysml.library/Kernel Libraries/Kernel Function Library/ControlFunctions.kerml +116 -116
  68. package/resources/sysml.library/Kernel Libraries/Kernel Function Library/DataFunctions.kerml +42 -42
  69. package/resources/sysml.library/Kernel Libraries/Kernel Function Library/IntegerFunctions.kerml +43 -43
  70. package/resources/sysml.library/Kernel Libraries/Kernel Function Library/NaturalFunctions.kerml +27 -27
  71. package/resources/sysml.library/Kernel Libraries/Kernel Function Library/NumericalFunctions.kerml +42 -42
  72. package/resources/sysml.library/Kernel Libraries/Kernel Function Library/OccurrenceFunctions.kerml +153 -153
  73. package/resources/sysml.library/Kernel Libraries/Kernel Function Library/RationalFunctions.kerml +49 -49
  74. package/resources/sysml.library/Kernel Libraries/Kernel Function Library/RealFunctions.kerml +56 -56
  75. package/resources/sysml.library/Kernel Libraries/Kernel Function Library/ScalarFunctions.kerml +32 -32
  76. package/resources/sysml.library/Kernel Libraries/Kernel Function Library/SequenceFunctions.kerml +110 -110
  77. package/resources/sysml.library/Kernel Libraries/Kernel Function Library/StringFunctions.kerml +25 -25
  78. package/resources/sysml.library/Kernel Libraries/Kernel Function Library/TrigFunctions.kerml +34 -34
  79. package/resources/sysml.library/Kernel Libraries/Kernel Function Library/VectorFunctions.kerml +272 -272
  80. package/resources/sysml.library/Kernel Libraries/Kernel Semantic Library/.meta.json +21 -21
  81. package/resources/sysml.library/Kernel Libraries/Kernel Semantic Library/.project.json +14 -14
  82. package/resources/sysml.library/Kernel Libraries/Kernel Semantic Library/Base.kerml +94 -94
  83. package/resources/sysml.library/Kernel Libraries/Kernel Semantic Library/Clocks.kerml +155 -155
  84. package/resources/sysml.library/Kernel Libraries/Kernel Semantic Library/ControlPerformances.kerml +134 -134
  85. package/resources/sysml.library/Kernel Libraries/Kernel Semantic Library/FeatureReferencingPerformances.kerml +189 -189
  86. package/resources/sysml.library/Kernel Libraries/Kernel Semantic Library/KerML.kerml +483 -483
  87. package/resources/sysml.library/Kernel Libraries/Kernel Semantic Library/Links.kerml +66 -66
  88. package/resources/sysml.library/Kernel Libraries/Kernel Semantic Library/Metaobjects.kerml +57 -57
  89. package/resources/sysml.library/Kernel Libraries/Kernel Semantic Library/Objects.kerml +212 -212
  90. package/resources/sysml.library/Kernel Libraries/Kernel Semantic Library/Observation.kerml +160 -160
  91. package/resources/sysml.library/Kernel Libraries/Kernel Semantic Library/Occurrences.kerml +992 -992
  92. package/resources/sysml.library/Kernel Libraries/Kernel Semantic Library/Performances.kerml +292 -292
  93. package/resources/sysml.library/Kernel Libraries/Kernel Semantic Library/SpatialFrames.kerml +196 -196
  94. package/resources/sysml.library/Kernel Libraries/Kernel Semantic Library/StatePerformances.kerml +144 -144
  95. package/resources/sysml.library/Kernel Libraries/Kernel Semantic Library/Transfers.kerml +280 -280
  96. package/resources/sysml.library/Kernel Libraries/Kernel Semantic Library/TransitionPerformances.kerml +65 -65
  97. package/resources/sysml.library/Kernel Libraries/Kernel Semantic Library/Triggers.kerml +187 -187
  98. package/resources/sysml.library/LICENSE +276 -276
  99. package/resources/sysml.library/NOTICE.md +20 -20
  100. package/resources/sysml.library/Systems Library/Actions.sysml +556 -556
  101. package/resources/sysml.library/Systems Library/Allocations.sysml +28 -28
  102. package/resources/sysml.library/Systems Library/AnalysisCases.sysml +37 -37
  103. package/resources/sysml.library/Systems Library/Attributes.sysml +24 -24
  104. package/resources/sysml.library/Systems Library/Calculations.sysml +36 -36
  105. package/resources/sysml.library/Systems Library/Cases.sysml +70 -70
  106. package/resources/sysml.library/Systems Library/Connections.sysml +59 -59
  107. package/resources/sysml.library/Systems Library/Constraints.sysml +43 -43
  108. package/resources/sysml.library/Systems Library/Flows.sysml +125 -125
  109. package/resources/sysml.library/Systems Library/Interfaces.sysml +88 -88
  110. package/resources/sysml.library/Systems Library/Items.sysml +152 -152
  111. package/resources/sysml.library/Systems Library/Metadata.sysml +31 -31
  112. package/resources/sysml.library/Systems Library/Parts.sysml +80 -80
  113. package/resources/sysml.library/Systems Library/Ports.sysml +53 -53
  114. package/resources/sysml.library/Systems Library/Requirements.sysml +193 -193
  115. package/resources/sysml.library/Systems Library/StandardViewDefinitions.sysml +123 -123
  116. package/resources/sysml.library/Systems Library/States.sysml +102 -102
  117. package/resources/sysml.library/Systems Library/SysML.sysml +539 -539
  118. package/resources/sysml.library/Systems Library/UseCases.sysml +56 -56
  119. package/resources/sysml.library/Systems Library/VerificationCases.sysml +102 -102
  120. package/resources/sysml.library/Systems Library/Views.sysml +163 -163
  121. package/resources/sysml.library.index.json +1 -1
package/out/main.js CHANGED
@@ -57859,7 +57859,8 @@ var Formatting;
57859
57859
  // ../language/out/parser-error-performance.js
57860
57860
  var ParserErrorPerformanceModule = {
57861
57861
  parser: {
57862
- LangiumParser: (services) => boundParserErrorMessageLookahead(createLangiumParser(services))
57862
+ LangiumParser: (services) => boundParserErrorMessageLookahead(createLangiumParser(services)),
57863
+ CompletionParser: (services) => boundParserErrorMessageLookahead(createCompletionParser(services))
57863
57864
  }
57864
57865
  };
57865
57866
  function boundParserErrorMessageLookahead(langiumParser) {
@@ -57907,9 +57908,53 @@ function asDiagnosticLevel(value, fallback = "off") {
57907
57908
  }
57908
57909
 
57909
57910
  // ../language-server/out/src/services/import-visibility.js
57911
+ var GlobalDescriptionIndex = class _GlobalDescriptionIndex {
57912
+ /** Reuse an existing index; wrap a plain list. */
57913
+ static from(source) {
57914
+ return source instanceof _GlobalDescriptionIndex ? source : new _GlobalDescriptionIndex(source);
57915
+ }
57916
+ /** Exact name → descriptions carrying it (qualified and simple names alike). */
57917
+ byName = /* @__PURE__ */ new Map();
57918
+ /** Namespace path → descriptions for its DIRECT members (`A::B` → `A::B::C`). */
57919
+ directMembers = /* @__PURE__ */ new Map();
57920
+ /** Namespace path → descriptions for all its descendants (`A` → `A::B::C`). */
57921
+ nestedMembers = /* @__PURE__ */ new Map();
57922
+ constructor(descriptions) {
57923
+ for (const desc of descriptions) {
57924
+ push(this.byName, desc.name, desc);
57925
+ let sep2 = desc.name.indexOf("::");
57926
+ while (sep2 >= 0) {
57927
+ const prefix = desc.name.slice(0, sep2);
57928
+ push(this.nestedMembers, prefix, desc);
57929
+ const next = desc.name.indexOf("::", sep2 + 2);
57930
+ if (next < 0)
57931
+ push(this.directMembers, prefix, desc);
57932
+ sep2 = next;
57933
+ }
57934
+ }
57935
+ }
57936
+ named(name) {
57937
+ return this.byName.get(name) ?? EMPTY_DESCRIPTIONS;
57938
+ }
57939
+ firstNamed(name) {
57940
+ return this.byName.get(name)?.[0];
57941
+ }
57942
+ membersOf(path10, wildcard) {
57943
+ const map3 = wildcard === "shallow" ? this.directMembers : this.nestedMembers;
57944
+ return map3.get(path10) ?? EMPTY_DESCRIPTIONS;
57945
+ }
57946
+ };
57947
+ var EMPTY_DESCRIPTIONS = [];
57948
+ function push(map3, key, desc) {
57949
+ const list = map3.get(key);
57950
+ if (list)
57951
+ list.push(desc);
57952
+ else
57953
+ map3.set(key, [desc]);
57954
+ }
57910
57955
  function expandImportEntries(imp, globalDescriptions, options = {}) {
57911
57956
  const out = [];
57912
- expandImportInto(imp, globalDescriptions, out, options, /* @__PURE__ */ new Set());
57957
+ expandImportInto(imp, GlobalDescriptionIndex.from(globalDescriptions), out, options, /* @__PURE__ */ new Set());
57913
57958
  return dedupeEntries(out);
57914
57959
  }
57915
57960
  function importedPath(imp) {
@@ -57934,12 +57979,13 @@ function importVisibility(imp) {
57934
57979
  return imp.visibility ?? "private";
57935
57980
  }
57936
57981
  function resolveDescription(name, globalDescriptions) {
57982
+ const index = GlobalDescriptionIndex.from(globalDescriptions);
57937
57983
  const normalized = name.trim();
57938
- const direct = globalDescriptions.find((desc) => desc.name === normalized);
57984
+ const direct = index.firstNamed(normalized);
57939
57985
  if (direct)
57940
57986
  return direct;
57941
57987
  const simple = normalized.split(/::|\./).pop();
57942
- return simple ? globalDescriptions.find((desc) => desc.name === simple) : void 0;
57988
+ return simple ? index.firstNamed(simple) : void 0;
57943
57989
  }
57944
57990
  function descriptionKey(description) {
57945
57991
  return `${description.documentUri.toString()}#${description.path}`;
@@ -58064,7 +58110,7 @@ function qualifiedNameMatches(a2, b) {
58064
58110
  return true;
58065
58111
  }
58066
58112
  function resolveImportedDescription(path10, globalDescriptions, options, visitedNamespaces) {
58067
- const direct = globalDescriptions.find((desc) => desc.name === path10);
58113
+ const direct = globalDescriptions.firstNamed(path10);
58068
58114
  if (direct)
58069
58115
  return direct;
58070
58116
  const split = path10.lastIndexOf("::");
@@ -58077,23 +58123,17 @@ function resolveImportedDescription(path10, globalDescriptions, options, visited
58077
58123
  return exported.find((entry) => entry.name === simpleName2)?.description;
58078
58124
  }
58079
58125
  function expandNamespaceMembers(path10, wildcard, globalDescriptions, out) {
58080
- const prefix = path10 + "::";
58081
- for (const desc of globalDescriptions) {
58082
- if (!desc.name.startsWith(prefix))
58083
- continue;
58126
+ const prefixLength = path10.length + 2;
58127
+ for (const desc of globalDescriptions.membersOf(path10, wildcard)) {
58084
58128
  if (isPrivateDescription(desc))
58085
58129
  continue;
58086
- const rest = desc.name.slice(prefix.length);
58087
- if (wildcard === "shallow" && rest.includes("::"))
58088
- continue;
58130
+ const rest = desc.name.slice(prefixLength);
58089
58131
  const simple = rest.includes("::") ? rest.slice(rest.lastIndexOf("::") + 2) : rest;
58090
58132
  out.push({ name: simple, targetName: desc.name, description: desc });
58091
58133
  }
58092
58134
  }
58093
58135
  function expandNamespaceImports(path10, globalDescriptions, out, options, visitedNamespaces) {
58094
- for (const namespaceDesc of globalDescriptions) {
58095
- if (namespaceDesc.name !== path10)
58096
- continue;
58136
+ for (const namespaceDesc of globalDescriptions.named(path10)) {
58097
58137
  const key = descriptionKey(namespaceDesc);
58098
58138
  if (visitedNamespaces.has(key))
58099
58139
  continue;
@@ -58269,7 +58309,7 @@ function splitUnitFactors(symbol) {
58269
58309
  let start = 0;
58270
58310
  let quote = false;
58271
58311
  let nextOp = "*";
58272
- const push = (end) => {
58312
+ const push2 = (end) => {
58273
58313
  const text = symbol.slice(start, end).trim();
58274
58314
  if (!text)
58275
58315
  return false;
@@ -58289,13 +58329,13 @@ function splitUnitFactors(symbol) {
58289
58329
  continue;
58290
58330
  }
58291
58331
  if (ch === "*" || ch === "/" || ch === "\u22C5") {
58292
- if (!push(i))
58332
+ if (!push2(i))
58293
58333
  return void 0;
58294
58334
  nextOp = ch === "/" ? "/" : "*";
58295
58335
  start = i + 1;
58296
58336
  }
58297
58337
  }
58298
- if (quote || !push(symbol.length))
58338
+ if (quote || !push2(symbol.length))
58299
58339
  return void 0;
58300
58340
  return tokens;
58301
58341
  }
@@ -58651,6 +58691,8 @@ function nearestUnits(symbol, limit) {
58651
58691
 
58652
58692
  // ../language-server/out/src/messages.js
58653
58693
  var DIAGNOSTIC_MESSAGES = {
58694
+ // REQ-317 — expression paths diagnose the exact missing feature segment.
58695
+ RES001_FEATURE_PATH_SEGMENT: (segment, owner) => `Feature path segment '${segment}' does not exist on '${owner}'.`,
58654
58696
  LEX001_UNTERMINATED_STRING: `Unterminated string literal \u2014 missing closing '"'.`,
58655
58697
  LEX002_UNTERMINATED_BLOCK_COMMENT: "Unterminated block comment - '/*' is never closed with '*/'.",
58656
58698
  LEX003_UNTERMINATED_UNRESTRICTED_NAME: `Unterminated unrestricted name \u2014 missing closing "'".`,
@@ -58969,6 +59011,352 @@ function isLibraryDocument(doc) {
58969
59011
  return doc.isLibraryDocument === true || isStandardLibraryUri(doc.uri);
58970
59012
  }
58971
59013
 
59014
+ // ../language-server/out/src/services/escaped-name.js
59015
+ function decodeEscapes(body) {
59016
+ return body.replace(/\\(.)/gu, (_m, ch) => {
59017
+ switch (ch) {
59018
+ case "n":
59019
+ return "\n";
59020
+ case "t":
59021
+ return " ";
59022
+ case "b":
59023
+ return "\b";
59024
+ case "f":
59025
+ return "\f";
59026
+ default:
59027
+ return ch;
59028
+ }
59029
+ });
59030
+ }
59031
+ function canonicalEscapedName(token) {
59032
+ if (token.length < 2 || !token.startsWith("'") || !token.endsWith("'"))
59033
+ return token;
59034
+ return "'" + decodeEscapes(token.slice(1, -1)) + "'";
59035
+ }
59036
+ function decodeUnrestrictedName(token) {
59037
+ if (token.length >= 2 && token.startsWith("'") && token.endsWith("'")) {
59038
+ return decodeEscapes(token.slice(1, -1));
59039
+ }
59040
+ return token;
59041
+ }
59042
+ var BARE_ID = /^[_a-zA-Z]\w*$/u;
59043
+ function encodeUnrestrictedName(value) {
59044
+ const raw = value.length >= 2 && value.startsWith("'") && value.endsWith("'") ? decodeUnrestrictedName(value) : value;
59045
+ if (BARE_ID.test(raw))
59046
+ return raw;
59047
+ const escaped = raw.replace(/\r\n?/gu, "\n").replace(/[\\']/gu, (ch) => `\\${ch}`).replace(/\n/gu, "\\n").replace(/\t/gu, "\\t").replace(/[\f]/gu, "\\f").replace(/[\b]/gu, "\\b");
59048
+ return `'${escaped}'`;
59049
+ }
59050
+
59051
+ // ../language-server/out/src/services/feature-path-resolver.js
59052
+ var SPECIALIZATION_KINDS = /* @__PURE__ */ new Set([":>", ":>>", "specializes", "subsets", "redefines"]);
59053
+ function nameOf(node) {
59054
+ const name = node?.name;
59055
+ if (typeof name === "string" && name.length > 0)
59056
+ return name;
59057
+ if (node?.$type === "FeatureRedefinitionShorthand") {
59058
+ const leading = node.preRelationships?.[0]?.targets?.[0];
59059
+ return leading ? lastSegment2(leading) : void 0;
59060
+ }
59061
+ if (node?.$type === "FeatureShorthand") {
59062
+ const text = node.$cstNode?.text;
59063
+ const head2 = text?.split(/(?=\s(?::|:>|:>>|=|\[|\{|;))/u, 1)[0]?.trim();
59064
+ const tokens = head2?.match(/'(?:\\.|[^'])*'|[\p{L}_][\p{L}\p{N}_]*/gu);
59065
+ if (tokens && tokens.length > 1)
59066
+ return canonicalEscapedName(tokens.at(-1));
59067
+ }
59068
+ if (node?.$container?.$type === "EnumDecl") {
59069
+ const literal = node.$cstNode?.text.trim().replace(/;$/u, "").trim();
59070
+ if (literal && !/[\s{}[\]=:]/u.test(literal))
59071
+ return canonicalEscapedName(literal);
59072
+ }
59073
+ return void 0;
59074
+ }
59075
+ function unwrap(node) {
59076
+ if (node.$type !== "PrefixMetadataMember")
59077
+ return node;
59078
+ return node.element ?? node;
59079
+ }
59080
+ function directNamedChildren(node) {
59081
+ const result = [];
59082
+ const seen = /* @__PURE__ */ new Set();
59083
+ for (const raw of ast_utils_exports.streamContents(node)) {
59084
+ const child = unwrap(raw);
59085
+ if (!nameOf(child) || seen.has(child))
59086
+ continue;
59087
+ seen.add(child);
59088
+ result.push(child);
59089
+ }
59090
+ return result;
59091
+ }
59092
+ function isAncestor(candidate, node) {
59093
+ if (!candidate)
59094
+ return false;
59095
+ for (let current2 = node; current2; current2 = current2.$container) {
59096
+ if (current2 === candidate)
59097
+ return true;
59098
+ }
59099
+ return false;
59100
+ }
59101
+ function lastSegment2(path10) {
59102
+ return path10.split(/::|\./u).pop() ?? path10;
59103
+ }
59104
+ var FeaturePathResolver = class {
59105
+ indexManager;
59106
+ descriptions;
59107
+ documents;
59108
+ locator;
59109
+ snapshots = /* @__PURE__ */ new WeakMap();
59110
+ constructor(services) {
59111
+ this.indexManager = services?.shared.workspace.IndexManager;
59112
+ this.descriptions = services?.workspace.AstNodeDescriptionProvider;
59113
+ this.documents = services?.shared.workspace.LangiumDocuments;
59114
+ this.locator = services?.workspace.AstNodeLocator;
59115
+ services?.shared.workspace.DocumentBuilder.onBuildPhase(DocumentState.IndexedContent, () => {
59116
+ this.snapshots = /* @__PURE__ */ new WeakMap();
59117
+ });
59118
+ }
59119
+ // REQ-220/317 — resolve every independently clickable/diagnosable segment.
59120
+ resolve(node) {
59121
+ const segments = this.segmentsOf(node);
59122
+ if (segments.length === 0)
59123
+ return { segments };
59124
+ const root3 = ast_utils_exports.getDocument(node).parseResult.value;
59125
+ const snapshot = this.snapshot(root3);
59126
+ let current2 = this.resolveRoot(node, segments[0].text, snapshot);
59127
+ this.applyTarget(segments[0], current2);
59128
+ if (!current2.node && !current2.description) {
59129
+ return { segments, indeterminateIndex: 0 };
59130
+ }
59131
+ for (let index = 1; index < segments.length; index += 1) {
59132
+ const segment = segments[index];
59133
+ const next = this.resolveChild(current2, segment.text, segments, index, snapshot);
59134
+ this.applyTarget(segment, next);
59135
+ if (!next.node && !next.description) {
59136
+ if (!current2.node && current2.description || !current2.certain) {
59137
+ return { segments, indeterminateIndex: index };
59138
+ }
59139
+ return { segments, unresolvedIndex: index };
59140
+ }
59141
+ current2 = next;
59142
+ }
59143
+ return { segments };
59144
+ }
59145
+ isPathExpr(node) {
59146
+ return isPathExpr(node);
59147
+ }
59148
+ segmentsOf(node) {
59149
+ const cst = node.$cstNode;
59150
+ if (!cst)
59151
+ return [];
59152
+ const segments = [];
59153
+ let separator;
59154
+ for (const leaf of cst_utils_exports.flattenCst(cst)) {
59155
+ if (leaf.text === "$")
59156
+ continue;
59157
+ if (leaf.text === "." || leaf.text === "::") {
59158
+ separator = leaf.text;
59159
+ continue;
59160
+ }
59161
+ segments.push({
59162
+ text: canonicalEscapedName(leaf.text),
59163
+ separator: segments.length === 0 ? void 0 : separator,
59164
+ cst: leaf
59165
+ });
59166
+ separator = void 0;
59167
+ }
59168
+ return segments;
59169
+ }
59170
+ resolveRoot(node, name, snapshot) {
59171
+ if (name === "self" || name === "this" || name === "that") {
59172
+ for (let owner = node.$container; owner; owner = owner.$container) {
59173
+ if (nameOf(owner)) {
59174
+ return this.targetForNode(owner, this.memberInventoryKnown(owner, snapshot));
59175
+ }
59176
+ }
59177
+ }
59178
+ for (let owner = node.$container; owner; owner = owner.$container) {
59179
+ const local = directNamedChildren(owner).find((candidate) => nameOf(candidate) === name && !isAncestor(candidate, node));
59180
+ if (local)
59181
+ return this.targetForNode(local, this.memberInventoryKnown(local, snapshot));
59182
+ }
59183
+ return this.targetFromDescriptions(snapshot.byName.get(name), node);
59184
+ }
59185
+ resolveChild(current2, name, segments, index, snapshot) {
59186
+ const owner = this.followAlias(current2, snapshot);
59187
+ if (owner.node) {
59188
+ const direct = directNamedChildren(owner.node).find((candidate) => nameOf(candidate) === name);
59189
+ if (direct) {
59190
+ return this.targetForNode(direct, current2.certain === true && this.memberInventoryKnown(direct, snapshot));
59191
+ }
59192
+ for (const inheritedOwner of this.typedAndSpecializedOwners(owner.node, snapshot)) {
59193
+ const inherited = directNamedChildren(inheritedOwner).find((candidate) => nameOf(candidate) === name);
59194
+ if (inherited) {
59195
+ return this.targetForNode(inherited, current2.certain === true && this.memberInventoryKnown(inherited, snapshot));
59196
+ }
59197
+ }
59198
+ }
59199
+ if (segments.slice(1, index + 1).every((segment) => segment.separator === "::")) {
59200
+ const exact = segments.slice(0, index + 1).map((segment) => segment.text).join("::");
59201
+ const indexed = this.targetFromDescriptions(snapshot.byName.get(exact));
59202
+ if (indexed.node || indexed.description)
59203
+ return indexed;
59204
+ }
59205
+ return {};
59206
+ }
59207
+ typedAndSpecializedOwners(node, snapshot) {
59208
+ const result = [];
59209
+ const seen = /* @__PURE__ */ new Set();
59210
+ const visit = (candidate) => {
59211
+ if (!candidate || seen.has(candidate))
59212
+ return;
59213
+ seen.add(candidate);
59214
+ result.push(candidate);
59215
+ visit(this.typingTarget(candidate, snapshot));
59216
+ for (const specialized of this.specializationTargets(candidate, snapshot))
59217
+ visit(specialized);
59218
+ };
59219
+ visit(this.typingTarget(node, snapshot));
59220
+ for (const specialized of this.specializationTargets(node, snapshot))
59221
+ visit(specialized);
59222
+ return result;
59223
+ }
59224
+ typingTarget(node, snapshot) {
59225
+ const typing = node.typing?.type;
59226
+ let typed;
59227
+ try {
59228
+ typed = typing?.ref;
59229
+ } catch {
59230
+ typed = void 0;
59231
+ }
59232
+ if (!typed && typing?.$refText) {
59233
+ typed = this.nodeOf(this.pickDescription(snapshot.byName.get(typing.$refText))) ?? this.nodeOf(this.pickDescription(snapshot.byName.get(lastSegment2(typing.$refText))));
59234
+ }
59235
+ return typed;
59236
+ }
59237
+ specializationTargets(node, snapshot) {
59238
+ const relNode = node;
59239
+ const result = [];
59240
+ for (const relation of [...relNode.preRelationships ?? [], ...relNode.relationships ?? []]) {
59241
+ if (!relation.kind || !SPECIALIZATION_KINDS.has(relation.kind))
59242
+ continue;
59243
+ for (const target of relation.targets ?? []) {
59244
+ const description = this.pickDescription(snapshot.byName.get(target)) ?? this.pickDescription(snapshot.byName.get(lastSegment2(target)));
59245
+ const resolved = this.nodeOf(description);
59246
+ if (resolved)
59247
+ result.push(resolved);
59248
+ }
59249
+ }
59250
+ return result;
59251
+ }
59252
+ memberInventoryKnown(node, snapshot) {
59253
+ const record = node;
59254
+ if (record.isDef === true || node.$type === "ClassDecl" || node.$type === "StructDecl" || node.$type === "EnumDecl" || node.$type === "DatatypeDecl" || node.$type === "FunctionDecl" || node.$type === "PredicateDecl") {
59255
+ return true;
59256
+ }
59257
+ const typed = this.typingTarget(node, snapshot);
59258
+ if (typed) {
59259
+ const localUri = ast_utils_exports.getDocument(node).uri.toString();
59260
+ const typedUri = ast_utils_exports.getDocument(typed).uri.toString();
59261
+ if (localUri === typedUri)
59262
+ return true;
59263
+ const refText = record.typing?.type?.$refText;
59264
+ const candidates = refText ? snapshot.byName.get(refText) ?? snapshot.byName.get(lastSegment2(refText)) : void 0;
59265
+ return candidates?.length === 1;
59266
+ }
59267
+ const semanticRelationships = [...record.preRelationships ?? [], ...record.relationships ?? []].filter((relation) => relation.kind && SPECIALIZATION_KINDS.has(relation.kind));
59268
+ return semanticRelationships.length > 0 && semanticRelationships.every((relation) => (relation.targets ?? []).every((target) => Boolean(this.nodeOf(this.pickDescription(snapshot.byName.get(target))) ?? this.nodeOf(this.pickDescription(snapshot.byName.get(lastSegment2(target)))))));
59269
+ }
59270
+ followAlias(target, snapshot) {
59271
+ const node = target.node;
59272
+ if (node?.$type !== "AliasDecl")
59273
+ return target;
59274
+ const aliasTarget = node.target;
59275
+ if (!aliasTarget)
59276
+ return target;
59277
+ const exact = this.targetFromDescriptions(snapshot.byName.get(aliasTarget));
59278
+ if (exact.node || exact.description)
59279
+ return exact;
59280
+ const simple = this.targetFromDescriptions(snapshot.byName.get(lastSegment2(aliasTarget)));
59281
+ return simple.node || simple.description ? simple : target;
59282
+ }
59283
+ targetForNode(node, certain = false) {
59284
+ const name = nameOf(node);
59285
+ let description;
59286
+ if (name && this.descriptions) {
59287
+ try {
59288
+ description = this.descriptions.createDescription(node, name);
59289
+ } catch {
59290
+ description = void 0;
59291
+ }
59292
+ }
59293
+ return { node, description, certain };
59294
+ }
59295
+ targetFromDescriptions(descriptions, context) {
59296
+ const description = this.pickDescription(descriptions, context);
59297
+ return description ? { description, node: this.nodeOf(description) } : {};
59298
+ }
59299
+ pickDescription(descriptions, context) {
59300
+ if (!descriptions?.length)
59301
+ return void 0;
59302
+ if (context) {
59303
+ const uri = ast_utils_exports.getDocument(context).uri.toString();
59304
+ const local = descriptions.find((description) => description.documentUri.toString() === uri && !isAncestor(description.node, context));
59305
+ if (local)
59306
+ return local;
59307
+ }
59308
+ return descriptions.find((description) => !context || !isAncestor(description.node, context));
59309
+ }
59310
+ nodeOf(description) {
59311
+ if (!description)
59312
+ return void 0;
59313
+ if (description.node)
59314
+ return description.node;
59315
+ const root3 = this.documents?.getDocument(description.documentUri)?.parseResult.value;
59316
+ return root3 && this.locator ? this.locator.getAstNode(root3, description.path) : void 0;
59317
+ }
59318
+ applyTarget(segment, target) {
59319
+ segment.target = target.node;
59320
+ segment.description = target.description;
59321
+ }
59322
+ snapshot(root3) {
59323
+ const cached = this.snapshots.get(root3);
59324
+ if (cached)
59325
+ return cached;
59326
+ const byName = /* @__PURE__ */ new Map();
59327
+ if (this.indexManager) {
59328
+ for (const description of this.indexManager.allElements()) {
59329
+ const values2 = byName.get(description.name) ?? [];
59330
+ values2.push(description);
59331
+ byName.set(description.name, values2);
59332
+ }
59333
+ } else {
59334
+ for (const node of [root3, ...ast_utils_exports.streamAllContents(root3)]) {
59335
+ const name = nameOf(node);
59336
+ if (!name)
59337
+ continue;
59338
+ const values2 = byName.get(name) ?? [];
59339
+ const target = this.targetForNode(node);
59340
+ if (target.description)
59341
+ values2.push(target.description);
59342
+ else {
59343
+ values2.push({
59344
+ name,
59345
+ type: node.$type,
59346
+ documentUri: ast_utils_exports.getDocument(node).uri,
59347
+ path: "",
59348
+ node
59349
+ });
59350
+ }
59351
+ byName.set(name, values2);
59352
+ }
59353
+ }
59354
+ const snapshot = { byName };
59355
+ this.snapshots.set(root3, snapshot);
59356
+ return snapshot;
59357
+ }
59358
+ };
59359
+
58972
59360
  // ../language-server/out/src/services/validator.js
58973
59361
  var severityOverrides = {};
58974
59362
  function setSeverityOverrides(overrides) {
@@ -59038,7 +59426,7 @@ function maskNonCode(text) {
59038
59426
  }
59039
59427
  return out.join("");
59040
59428
  }
59041
- var SPECIALIZATION_KINDS = /* @__PURE__ */ new Set([":>", ":>>", "specializes", "subsets", "redefines"]);
59429
+ var SPECIALIZATION_KINDS2 = /* @__PURE__ */ new Set([":>", ":>>", "specializes", "subsets", "redefines"]);
59042
59430
  var CONSTRAINT_SIDE_EFFECT_TYPES = /* @__PURE__ */ new Set([
59043
59431
  "AssignNode",
59044
59432
  "SendNode",
@@ -59065,10 +59453,12 @@ var SysmlValidator = class _SysmlValidator {
59065
59453
  indexManager;
59066
59454
  langiumDocuments;
59067
59455
  astNodeLocator;
59456
+ featurePaths;
59068
59457
  constructor(services) {
59069
59458
  this.indexManager = services.shared.workspace.IndexManager;
59070
59459
  this.langiumDocuments = services.shared.workspace.LangiumDocuments;
59071
59460
  this.astNodeLocator = services.workspace.AstNodeLocator;
59461
+ this.featurePaths = new FeaturePathResolver(services);
59072
59462
  }
59073
59463
  // ══════════════════════════════════════════════════════════════════════
59074
59464
  // STYL — naming conventions (REQ-169, REQ-332)
@@ -59076,6 +59466,28 @@ var SysmlValidator = class _SysmlValidator {
59076
59466
  // REQ-330 — SSM014 support: message-endpoint root features per interaction,
59077
59467
  // computed once per interaction AST node instead of once per participant.
59078
59468
  interactionMessageRoots = /* @__PURE__ */ new WeakMap();
59469
+ // REQ-317 — PathExpr is stored as one datatype string, so the ordinary
59470
+ // Langium linker cannot diagnose a missing intermediate feature. Resolve the
59471
+ // chain here and underline only the first invalid segment.
59472
+ checkPathExpr(node, accept) {
59473
+ let declaration = node.$container;
59474
+ while (declaration && !isPartDecl(declaration))
59475
+ declaration = declaration.$container;
59476
+ const modifiers2 = declaration?.modifiers ?? [];
59477
+ if (!declaration || !modifiers2.includes("ref"))
59478
+ return;
59479
+ const resolution = this.featurePaths.resolve(node);
59480
+ if (resolution.unresolvedIndex === void 0)
59481
+ return;
59482
+ const invalid = resolution.segments[resolution.unresolvedIndex];
59483
+ const owner = resolution.unresolvedIndex > 0 ? resolution.segments[resolution.unresolvedIndex - 1].text : "the current scope";
59484
+ accept(severity("RES001", "error"), DIAGNOSTIC_MESSAGES.RES001_FEATURE_PATH_SEGMENT(invalid.text, owner), {
59485
+ node,
59486
+ range: invalid.cst.range,
59487
+ code: "RES001",
59488
+ data: { featurePathSegment: true }
59489
+ });
59490
+ }
59079
59491
  // REQ-169, REQ-329 — SSM001 def/usage mismatch for parts
59080
59492
  checkPartDecl(node, accept) {
59081
59493
  if (!node.isDef && node.name && /^[A-Z]/.test(node.name)) {
@@ -60843,6 +61255,7 @@ ${baseIndent}}`;
60843
61255
  return {
60844
61256
  Document: this.checkDocument.bind(this),
60845
61257
  PartDecl: this.checkPartDecl.bind(this),
61258
+ PathExpr: this.checkPathExpr.bind(this),
60846
61259
  RequirementDecl: this.checkRequirementDecl.bind(this),
60847
61260
  AttributeDecl: this.checkAttributeDecl.bind(this),
60848
61261
  ConstraintDecl: this.checkConstraintDecl.bind(this),
@@ -61063,7 +61476,7 @@ function specializationTargets(node) {
61063
61476
  ...node.relationships ?? []
61064
61477
  ];
61065
61478
  for (const rel of rels) {
61066
- if (rel.kind && SPECIALIZATION_KINDS.has(rel.kind))
61479
+ if (rel.kind && SPECIALIZATION_KINDS2.has(rel.kind))
61067
61480
  out.push(...rel.targets);
61068
61481
  }
61069
61482
  return out;
@@ -61303,8 +61716,17 @@ function isWithinNamespaceOf(inner, target) {
61303
61716
  }
61304
61717
  return false;
61305
61718
  }
61719
+ var globalIndexes = /* @__PURE__ */ new WeakMap();
61720
+ function globalIndexFor(index) {
61721
+ let globalIndex = globalIndexes.get(index);
61722
+ if (!globalIndex) {
61723
+ globalIndex = new GlobalDescriptionIndex(Array.from(index.values()).flat());
61724
+ globalIndexes.set(index, globalIndex);
61725
+ }
61726
+ return globalIndex;
61727
+ }
61306
61728
  function introducedNames(imp, index, nodeOf) {
61307
- const globalDescs = Array.from(index.values()).flat();
61729
+ const globalDescs = globalIndexFor(index);
61308
61730
  const protectedNamespaceKeys = protectedNamespaceKeysFor(imp.$container, globalDescs, nodeOf);
61309
61731
  return expandImportEntries(imp, globalDescs, {
61310
61732
  nodeOf,
@@ -61937,7 +62359,7 @@ function trailingBlockBody(node) {
61937
62359
  }
61938
62360
 
61939
62361
  // ../language-server/out/src/services/document-symbol-provider.js
61940
- var SPECIALIZATION_KINDS2 = /* @__PURE__ */ new Set([":>", "specializes"]);
62362
+ var SPECIALIZATION_KINDS3 = /* @__PURE__ */ new Set([":>", "specializes"]);
61941
62363
  var REDEFINITION_KINDS = /* @__PURE__ */ new Set([":>>", "redefines"]);
61942
62364
  var INHERITABLE_FEATURE_TYPES = /* @__PURE__ */ new Set([
61943
62365
  "ActionDecl",
@@ -62006,7 +62428,7 @@ function specializationTargets2(node) {
62006
62428
  const n = node;
62007
62429
  const out = [];
62008
62430
  for (const rel of [...n.preRelationships ?? [], ...n.relationships ?? []]) {
62009
- if (rel.kind && SPECIALIZATION_KINDS2.has(rel.kind))
62431
+ if (rel.kind && SPECIALIZATION_KINDS3.has(rel.kind))
62010
62432
  out.push(...rel.targets ?? []);
62011
62433
  }
62012
62434
  return out;
@@ -63841,12 +64263,17 @@ var SNIPPETS = [
63841
64263
  ];
63842
64264
  var SysmlCompletionProvider = class extends DefaultCompletionProvider {
63843
64265
  indexManager;
64266
+ // REQ-245, REQ-268 — Qualified names of every indexed element, keyed by the
64267
+ // element it names. Built once per workspace build and evicted with the rest
64268
+ // of the workspace caches; see [[qualifiedNamesByElement]].
64269
+ qualifiedNameCache;
63844
64270
  completionOptions = {
63845
64271
  triggerCharacters: COMPLETION_TRIGGER_CHARACTERS
63846
64272
  };
63847
64273
  constructor(services) {
63848
64274
  super(services);
63849
64275
  this.indexManager = services.shared.workspace.IndexManager;
64276
+ this.qualifiedNameCache = new WorkspaceCache(services.shared);
63850
64277
  }
63851
64278
  async getCompletion(document, params) {
63852
64279
  const defaultResult = await super.getCompletion(document, params);
@@ -64010,8 +64437,34 @@ var SysmlCompletionProvider = class extends DefaultCompletionProvider {
64010
64437
  qualifiedNameFor(desc) {
64011
64438
  if (desc.name.includes("::"))
64012
64439
  return desc.name;
64013
- const candidates = this.indexManager.allElements().toArray().filter((other) => other.documentUri.toString() === desc.documentUri.toString()).filter((other) => other.path === desc.path && other.type === desc.type).map((other) => other.name).filter((name) => name.includes("::") && simpleName(name) === desc.name).sort((a2, b) => a2.length - b.length || a2.localeCompare(b));
64014
- return candidates[0];
64440
+ const candidates = this.qualifiedNamesByElement().get(elementKey(desc));
64441
+ return candidates?.find((name) => simpleName(name) === desc.name);
64442
+ }
64443
+ // REQ-245, REQ-268 — An element's qualified names, shortest first, keyed by
64444
+ // the element. A type-context completion offers thousands of symbols and each
64445
+ // one needs its qualified name to plan an auto-import; looking that up by
64446
+ // scanning the whole index per candidate made the index-sized scan happen
64447
+ // thousands of times, and a single `: ` keystroke blocked the server for
64448
+ // 10 s — long enough for the editor to report the request as timed out. One
64449
+ // grouped pass per build answers all of them.
64450
+ qualifiedNamesByElement() {
64451
+ return this.qualifiedNameCache.get("all", () => {
64452
+ const byElement = /* @__PURE__ */ new Map();
64453
+ for (const desc of this.indexManager.allElements()) {
64454
+ if (!desc.name.includes("::"))
64455
+ continue;
64456
+ const key = elementKey(desc);
64457
+ const names = byElement.get(key);
64458
+ if (names)
64459
+ names.push(desc.name);
64460
+ else
64461
+ byElement.set(key, [desc.name]);
64462
+ }
64463
+ for (const names of byElement.values()) {
64464
+ names.sort((a2, b) => a2.length - b.length || a2.localeCompare(b));
64465
+ }
64466
+ return byElement;
64467
+ });
64015
64468
  }
64016
64469
  importPathItems(importPrefix) {
64017
64470
  const prefix = importPrefix.trim();
@@ -64215,6 +64668,9 @@ function isPackageBody(prefix) {
64215
64668
  return true;
64216
64669
  return /\bpackage\s+(?:<[^>]+>\s*)?[\p{L}_'][^;{}]*$/u.test(prefix.slice(Math.max(0, open - 160), open));
64217
64670
  }
64671
+ function elementKey(desc) {
64672
+ return `${desc.documentUri.toString()}#${desc.path}#${desc.type}`;
64673
+ }
64218
64674
  function isDefinitionDescription(desc) {
64219
64675
  const node = desc.node;
64220
64676
  return node?.isDef === void 0 || node.isDef === true;
@@ -64567,11 +65023,16 @@ var SysmlScopeProvider = class extends DefaultScopeProvider {
64567
65023
  // global symbol table, which made indexing the standard library O(refs ×
64568
65024
  // symbols) — minutes of unusable startup. See REQ-073/REQ-220.
64569
65025
  importCache;
65026
+ // REQ-268 — The global symbol table, indexed by name and by namespace prefix.
65027
+ // Built once per reference type per build and evicted with the same
65028
+ // `DocumentBuilder` update that evicts Langium's own global-scope cache.
65029
+ globalIndexCache;
64570
65030
  langiumDocuments;
64571
65031
  astNodeLocator;
64572
65032
  constructor(services) {
64573
65033
  super(services);
64574
65034
  this.importCache = new DocumentCache(services.shared);
65035
+ this.globalIndexCache = new WorkspaceCache(services.shared);
64575
65036
  this.langiumDocuments = services.shared.workspace.LangiumDocuments;
64576
65037
  this.astNodeLocator = services.workspace.AstNodeLocator;
64577
65038
  }
@@ -64591,8 +65052,9 @@ var SysmlScopeProvider = class extends DefaultScopeProvider {
64591
65052
  const refType = this.reflection.getReferenceType(context);
64592
65053
  const globalScope = this.getGlobalScope(refType, context);
64593
65054
  const doc = ast_utils_exports.getDocument(context.container);
64594
- const contextKey = this.importContextKey(context.container);
64595
- const imported = this.importCache.get(doc.uri, `${refType}|${contextKey}`, () => this.computeImportedDescriptions(doc, refType, context.container));
65055
+ const protectedNamespaces = this.protectedNamespacesFor(context.container, this.globalIndex(refType));
65056
+ const contextKey = this.importContextKey(context.container, protectedNamespaces);
65057
+ const imported = this.importCache.get(doc.uri, `${refType} ${contextKey}`, () => this.computeImportedDescriptions(doc, refType, context.container, protectedNamespaces));
64596
65058
  let scope = imported.length > 0 ? this.createScope(imported, globalScope) : globalScope;
64597
65059
  const localLayers = this.localScopeLayers(context.container, refType);
64598
65060
  for (let i = localLayers.length - 1; i >= 0; i--) {
@@ -64624,12 +65086,11 @@ var SysmlScopeProvider = class extends DefaultScopeProvider {
64624
65086
  // REQ-067, REQ-069 — Collect import- and alias-visible descriptions for a
64625
65087
  // document. Computed once per (document, reference type) and cached; the
64626
65088
  // global element list is scanned a single time here rather than per reference.
64627
- computeImportedDescriptions(doc, refType, contextNode) {
65089
+ computeImportedDescriptions(doc, refType, contextNode, protectedNamespaces) {
64628
65090
  const root3 = doc.parseResult?.value;
64629
65091
  if (!root3 || !isDocument(root3))
64630
65092
  return [];
64631
- const globalDescs = Array.from(this.indexManager.allElements(refType));
64632
- const protectedNamespaces = this.protectedNamespacesFor(contextNode, globalDescs);
65093
+ const globalDescs = this.globalIndex(refType);
64633
65094
  const options = {
64634
65095
  nodeOf: this.nodeOf.bind(this),
64635
65096
  protectedNamespaceKeys: protectedNamespaces.keys,
@@ -64652,6 +65113,10 @@ var SysmlScopeProvider = class extends DefaultScopeProvider {
64652
65113
  }
64653
65114
  return dedupeDescriptions(result);
64654
65115
  }
65116
+ // REQ-268 — One index over the global symbol table per reference type.
65117
+ globalIndex(refType) {
65118
+ return this.globalIndexCache.get(refType, () => new GlobalDescriptionIndex(Array.from(this.indexManager.allElements(refType))));
65119
+ }
64655
65120
  // REQ-067, REQ-068, REQ-069, REQ-323 — Expand import forms and visibility re-exports
64656
65121
  expandImport(imp, globalDescs, out, options) {
64657
65122
  for (const entry of expandImportEntries(imp, globalDescs, options)) {
@@ -64677,6 +65142,16 @@ var SysmlScopeProvider = class extends DefaultScopeProvider {
64677
65142
  }
64678
65143
  return imports;
64679
65144
  }
65145
+ // REQ-060, REQ-068 — The namespaces a context specializes (transitively) that
65146
+ // re-export their `protected` imports to it.
65147
+ //
65148
+ // REQ-268 — Only a namespace that actually OWNS a protected import can change
65149
+ // an expansion: `expandNamespaceImports` consults the key set for exactly that
65150
+ // case, and the re-export loop iterates exactly those members. Namespaces
65151
+ // without one are therefore dropped here rather than carried into the cache
65152
+ // key, so the common model — where nothing is imported `protected` — resolves
65153
+ // every reference against one cached expansion instead of one per specializing
65154
+ // element.
64680
65155
  protectedNamespacesFor(contextNode, globalDescs) {
64681
65156
  const keys3 = /* @__PURE__ */ new Set();
64682
65157
  const nodes = [];
@@ -64688,7 +65163,7 @@ var SysmlScopeProvider = class extends DefaultScopeProvider {
64688
65163
  }
64689
65164
  cur = cur.$container;
64690
65165
  }
64691
- return { keys: keys3, nodes };
65166
+ return { keys: keys3, nodes, key: keys3.size === 0 ? "" : [...keys3].sort().join(" ") };
64692
65167
  }
64693
65168
  collectProtectedNamespace(targetName, globalDescs, keys3, nodes, visitedTargets) {
64694
65169
  if (visitedTargets.has(targetName))
@@ -64698,26 +65173,43 @@ var SysmlScopeProvider = class extends DefaultScopeProvider {
64698
65173
  if (!desc)
64699
65174
  return;
64700
65175
  const key = descriptionKey(desc);
64701
- const wasNew = !keys3.has(key);
64702
- keys3.add(key);
64703
65176
  const node = this.nodeOf(desc);
64704
65177
  if (!node)
64705
65178
  return;
64706
- if (wasNew)
65179
+ if (ownsProtectedImport(node) && !keys3.has(key)) {
65180
+ keys3.add(key);
64707
65181
  nodes.push(node);
65182
+ }
64708
65183
  for (const inherited of specializationTargets3(node)) {
64709
65184
  this.collectProtectedNamespace(inherited, globalDescs, keys3, nodes, visitedTargets);
64710
65185
  }
64711
65186
  }
64712
- importContextKey(contextNode) {
65187
+ // REQ-268 — The cache key for a context's import expansion.
65188
+ //
65189
+ // The expansion is a pure function of exactly two things: the imports visible
65190
+ // from the context (innermost namespace outwards) and the protected-import
65191
+ // re-exports its specializations open up. Every import resolves its path
65192
+ // against the GLOBAL symbol table, so an import expands to the same members
65193
+ // wherever it is written; two contexts that see the same import text in the
65194
+ // same order, under the same protected re-exports, get the same result.
65195
+ //
65196
+ // Keying on those inputs rather than on the nearest enclosing namespace NODE
65197
+ // is what makes the cache useful: a model file has one or two distinct import
65198
+ // sets but hundreds of namespace nodes, so the node key missed on nearly
65199
+ // every reference and re-expanded the whole standard library each time
65200
+ // (measured on a 1 500-line model: 226 misses over 349 references, 16 s).
65201
+ importContextKey(contextNode, protectedNamespaces) {
65202
+ const parts = [];
64713
65203
  let cur = contextNode;
64714
65204
  while (cur) {
64715
- if (isDocument(cur) || namespaceMembers(cur).length > 0 || specializationTargets3(cur).length > 0) {
64716
- return this.nodeKey(cur);
65205
+ for (const member of namespaceMembers(cur)) {
65206
+ if (isImport(member))
65207
+ parts.push(importSignature(member));
64717
65208
  }
64718
65209
  cur = cur.$container;
64719
65210
  }
64720
- return "root";
65211
+ const imports = parts.length > 0 ? parts.join(" ") : "root";
65212
+ return protectedNamespaces.key ? `${imports} ${protectedNamespaces.key}` : imports;
64721
65213
  }
64722
65214
  nodeOf(desc) {
64723
65215
  if (desc.node)
@@ -64728,16 +65220,23 @@ var SysmlScopeProvider = class extends DefaultScopeProvider {
64728
65220
  return void 0;
64729
65221
  return this.astNodeLocator.getAstNode(root3, desc.path);
64730
65222
  }
64731
- nodeKey(node) {
64732
- return `${ast_utils_exports.getDocument(node).uri.toString()}#${this.astNodeLocator.getAstNodePath(node)}`;
64733
- }
64734
65223
  };
64735
- var SPECIALIZATION_KINDS3 = /* @__PURE__ */ new Set([":>", ":>>", "specializes", "subsets", "redefines"]);
65224
+ function ownsProtectedImport(node) {
65225
+ return namespaceMembers(node).some((member) => isImport(member) && importVisibility(member) === "protected");
65226
+ }
65227
+ function importSignature(imp) {
65228
+ const text = imp.$cstNode?.text;
65229
+ if (text)
65230
+ return text;
65231
+ const segments = imp.segs.map((seg) => `${seg.name ?? ""}${seg.star ? "*" : ""}${seg.recursive ? "**" : ""}`);
65232
+ return `${importVisibility(imp)} ${imp.head}::${segments.join("::")}${imp.alias ? ` as ${imp.alias}` : ""}`;
65233
+ }
65234
+ var SPECIALIZATION_KINDS4 = /* @__PURE__ */ new Set([":>", ":>>", "specializes", "subsets", "redefines"]);
64736
65235
  function specializationTargets3(node) {
64737
65236
  const n = node;
64738
65237
  const out = [];
64739
65238
  for (const rel of [...n.preRelationships ?? [], ...n.relationships ?? []]) {
64740
- if (rel.kind && SPECIALIZATION_KINDS3.has(rel.kind))
65239
+ if (rel.kind && SPECIALIZATION_KINDS4.has(rel.kind))
64741
65240
  out.push(...rel.targets ?? []);
64742
65241
  }
64743
65242
  return out;
@@ -64797,20 +65296,21 @@ var SysmlScopeComputation = class extends DefaultScopeComputation {
64797
65296
  const imports = Array.from(ast_utils_exports.streamAllContents(root3)).filter(isImport).filter((imp) => importVisibility(imp) === "public");
64798
65297
  if (imports.length === 0)
64799
65298
  return;
64800
- const physicalExports = [...exports2];
65299
+ const physicalAliases = aliasesByNode(exports2);
64801
65300
  const ownerAliases = /* @__PURE__ */ new Map();
64802
65301
  for (const imp of imports) {
64803
65302
  const owner = imp.$container;
64804
- ownerAliases.set(imp, owner ? physicalExports.filter((desc) => desc.node === owner && !desc.name.includes(".")).map((desc) => desc.name) : []);
65303
+ ownerAliases.set(imp, owner && physicalAliases.get(owner) || []);
64805
65304
  }
64806
65305
  const seen = new Set(exports2.map(exportAliasKey));
64807
65306
  for (let pass = 0; pass < imports.length + 1; pass++) {
64808
65307
  let changed = false;
65308
+ const indexed = new GlobalDescriptionIndex(exports2);
64809
65309
  for (const imp of imports) {
64810
65310
  const aliases = ownerAliases.get(imp) ?? [];
64811
65311
  if (aliases.length === 0)
64812
65312
  continue;
64813
- for (const entry of directImportEntries(imp, exports2)) {
65313
+ for (const entry of directImportEntries(imp, indexed)) {
64814
65314
  for (const ownerAlias of aliases) {
64815
65315
  const description = {
64816
65316
  ...entry.description,
@@ -64835,28 +65335,23 @@ var SysmlScopeComputation = class extends DefaultScopeComputation {
64835
65335
  // where Country owns Life). Materialize those same-document aliases so the
64836
65336
  // linker can resolve the qualified spelling without a full type evaluator.
64837
65337
  addInheritedQualifiedAliases(root3, exports2) {
64838
- const physicalExports = [...exports2];
64839
65338
  const seen = new Set(exports2.map(exportAliasKey));
64840
- const nodes = Array.from(ast_utils_exports.streamAllContents(root3));
64841
- const ownerAliases = /* @__PURE__ */ new Map();
64842
- for (const node of nodes) {
64843
- ownerAliases.set(node, physicalExports.filter((desc) => desc.node === node && !desc.name.includes(".")).map((desc) => desc.name));
64844
- }
65339
+ const nodes = Array.from(ast_utils_exports.streamAllContents(root3)).filter((node) => specializationTargets4(node).length > 0);
65340
+ if (nodes.length === 0)
65341
+ return;
65342
+ const ownerAliases = aliasesByNode(exports2);
64845
65343
  for (let pass = 0; pass < nodes.length; pass++) {
64846
- const sourceDescriptions = [...exports2];
65344
+ const sourceDescriptions = new GlobalDescriptionIndex(exports2);
64847
65345
  const additions = [];
64848
65346
  for (const node of nodes) {
64849
65347
  const targets = specializationTargets4(node);
64850
- if (targets.length === 0)
64851
- continue;
64852
65348
  const aliases = ownerAliases.get(node) ?? [];
65349
+ if (aliases.length === 0)
65350
+ continue;
64853
65351
  for (const target of targets) {
64854
- for (const inherited of sourceDescriptions) {
64855
- const prefix = `${target}::`;
64856
- if (!inherited.name.startsWith(prefix))
64857
- continue;
64858
- const suffix = inherited.name.slice(prefix.length);
64859
- if (!suffix || suffix.includes("::"))
65352
+ for (const inherited of sourceDescriptions.membersOf(target, "shallow")) {
65353
+ const suffix = inherited.name.slice(target.length + 2);
65354
+ if (!suffix)
64860
65355
  continue;
64861
65356
  for (const ownerAlias of aliases) {
64862
65357
  const description = {
@@ -64974,28 +65469,38 @@ function nodeVisibility(node) {
64974
65469
  function exportAliasKey(description) {
64975
65470
  return `${description.name}|${description.documentUri.toString()}|${description.path}`;
64976
65471
  }
65472
+ function aliasesByNode(exports2) {
65473
+ const byNode = /* @__PURE__ */ new Map();
65474
+ for (const desc of exports2) {
65475
+ if (!desc.node || desc.name.includes("."))
65476
+ continue;
65477
+ const names = byNode.get(desc.node);
65478
+ if (names)
65479
+ names.push(desc.name);
65480
+ else
65481
+ byNode.set(desc.node, [desc.name]);
65482
+ }
65483
+ return byNode;
65484
+ }
64977
65485
  function directImportEntries(imp, descriptions) {
64978
65486
  const path10 = importedPath(imp);
64979
65487
  if (!path10)
64980
65488
  return [];
64981
65489
  const wildcard = importWildcard(imp);
64982
65490
  if (wildcard === "none") {
64983
- const description = descriptions.find((candidate) => candidate.name === path10);
65491
+ const description = descriptions.firstNamed(path10);
64984
65492
  if (!description)
64985
65493
  return [];
64986
65494
  return [{ name: imp.alias ?? path10.split("::").pop() ?? path10, description }];
64987
65495
  }
64988
- const prefix = `${path10}::`;
64989
65496
  const entries = [];
64990
65497
  const seen = /* @__PURE__ */ new Set();
64991
- for (const description of descriptions) {
64992
- if (!description.name.startsWith(prefix))
64993
- continue;
65498
+ for (const description of descriptions.membersOf(path10, wildcard)) {
64994
65499
  const visibility = description;
64995
65500
  if (visibility.isPrivate || visibility.visibility === "private")
64996
65501
  continue;
64997
- const rest = description.name.slice(prefix.length);
64998
- if (!rest || wildcard === "shallow" && rest.includes("::"))
65502
+ const rest = description.name.slice(path10.length + 2);
65503
+ if (!rest)
64999
65504
  continue;
65000
65505
  const name = rest.split("::").pop();
65001
65506
  if (!name)
@@ -65008,12 +65513,12 @@ function directImportEntries(imp, descriptions) {
65008
65513
  }
65009
65514
  return entries;
65010
65515
  }
65011
- var SPECIALIZATION_KINDS4 = /* @__PURE__ */ new Set([":>", ":>>", "specializes", "subsets", "redefines"]);
65516
+ var SPECIALIZATION_KINDS5 = /* @__PURE__ */ new Set([":>", ":>>", "specializes", "subsets", "redefines"]);
65012
65517
  function specializationTargets4(node) {
65013
65518
  const value = node;
65014
65519
  const targets = [];
65015
65520
  for (const relationship of [...value.preRelationships ?? [], ...value.relationships ?? []]) {
65016
- if (relationship.kind && SPECIALIZATION_KINDS4.has(relationship.kind)) {
65521
+ if (relationship.kind && SPECIALIZATION_KINDS5.has(relationship.kind)) {
65017
65522
  targets.push(...relationship.targets ?? []);
65018
65523
  }
65019
65524
  }
@@ -65062,43 +65567,6 @@ var SysmlLinker = class extends DefaultLinker {
65062
65567
  }
65063
65568
  };
65064
65569
 
65065
- // ../language-server/out/src/services/escaped-name.js
65066
- function decodeEscapes(body) {
65067
- return body.replace(/\\(.)/gu, (_m, ch) => {
65068
- switch (ch) {
65069
- case "n":
65070
- return "\n";
65071
- case "t":
65072
- return " ";
65073
- case "b":
65074
- return "\b";
65075
- case "f":
65076
- return "\f";
65077
- default:
65078
- return ch;
65079
- }
65080
- });
65081
- }
65082
- function canonicalEscapedName(token) {
65083
- if (token.length < 2 || !token.startsWith("'") || !token.endsWith("'"))
65084
- return token;
65085
- return "'" + decodeEscapes(token.slice(1, -1)) + "'";
65086
- }
65087
- function decodeUnrestrictedName(token) {
65088
- if (token.length >= 2 && token.startsWith("'") && token.endsWith("'")) {
65089
- return decodeEscapes(token.slice(1, -1));
65090
- }
65091
- return token;
65092
- }
65093
- var BARE_ID = /^[_a-zA-Z]\w*$/u;
65094
- function encodeUnrestrictedName(value) {
65095
- const raw = value.length >= 2 && value.startsWith("'") && value.endsWith("'") ? decodeUnrestrictedName(value) : value;
65096
- if (BARE_ID.test(raw))
65097
- return raw;
65098
- const escaped = raw.replace(/\r\n?/gu, "\n").replace(/[\\']/gu, (ch) => `\\${ch}`).replace(/\n/gu, "\\n").replace(/\t/gu, "\\t").replace(/[\f]/gu, "\\f").replace(/[\b]/gu, "\\b");
65099
- return `'${escaped}'`;
65100
- }
65101
-
65102
65570
  // ../language-server/out/src/services/rename-provider.js
65103
65571
  var SysmlRenameProvider = class extends DefaultRenameProvider {
65104
65572
  langiumDocuments;
@@ -65228,7 +65696,7 @@ var SysmlCodeActionProvider = class {
65228
65696
  }
65229
65697
  });
65230
65698
  }
65231
- if (code === "RES001") {
65699
+ if (code === "RES001" && !(typeof diagnostic.data === "object" && diagnostic.data !== null && diagnostic.data.featurePathSegment === true)) {
65232
65700
  const start = diagnostic.range.start;
65233
65701
  const end = diagnostic.range.end;
65234
65702
  const name = document.textDocument.getText({ start, end });
@@ -66039,7 +66507,7 @@ function multiplicityAnchor(node) {
66039
66507
  function allAstNodes(root3) {
66040
66508
  return [root3, ...ast_utils_exports.streamAllContents(root3).toArray()];
66041
66509
  }
66042
- function lastSegment2(name) {
66510
+ function lastSegment3(name) {
66043
66511
  const idx = name.lastIndexOf("::");
66044
66512
  return (idx >= 0 ? name.slice(idx + 2) : name).replace(/^'(.*)'$/u, "$1");
66045
66513
  }
@@ -66062,7 +66530,7 @@ function typeAnchor(node, refText) {
66062
66530
  const cst = node.$cstNode;
66063
66531
  if (!cst)
66064
66532
  return void 0;
66065
- const target = lastSegment2(refText);
66533
+ const target = lastSegment3(refText);
66066
66534
  const leaves = cst_utils_exports.flattenCst(cst).toArray();
66067
66535
  for (let index = leaves.length - 1; index >= 0; index--) {
66068
66536
  const leaf = leaves[index];
@@ -66476,7 +66944,7 @@ function indexByName(root3, type) {
66476
66944
  });
66477
66945
  return map3;
66478
66946
  }
66479
- function lastSegment3(path10) {
66947
+ function lastSegment4(path10) {
66480
66948
  if (!path10)
66481
66949
  return void 0;
66482
66950
  return path10.split(/::|\./).pop();
@@ -66495,17 +66963,6 @@ function qualifiedNameOf2(node) {
66495
66963
  function isDiagramAnchor(node) {
66496
66964
  return isPackage(node) || isPartDecl(node) || isStateDecl(node) || isExhibitStateDecl(node) || isActionDecl(node) || isOccurrenceDecl(node) || isUseCaseDecl(node) || isVerificationCaseDecl(node);
66497
66965
  }
66498
- function hasDiagrammableContent(root3) {
66499
- let found = false;
66500
- walkAst(root3, (n) => {
66501
- if (found)
66502
- return;
66503
- const name = n.name;
66504
- if (typeof name === "string" && name.length > 0)
66505
- found = true;
66506
- });
66507
- return found;
66508
- }
66509
66966
  function naturalKindFor(node) {
66510
66967
  if (node.isDef)
66511
66968
  return void 0;
@@ -66552,20 +67009,6 @@ var SysmlCodeLensProvider = class {
66552
67009
  return void 0;
66553
67010
  const lenses = [];
66554
67011
  const uri = document.uri.toString();
66555
- if (hasDiagrammableContent(root3)) {
66556
- const firstLine = {
66557
- start: { line: 0, character: 0 },
66558
- end: { line: 0, character: 0 }
66559
- };
66560
- lenses.push({
66561
- range: firstLine,
66562
- command: {
66563
- title: "$(graph) Show all diagrams",
66564
- command: "sysml.preview.showDiagram",
66565
- arguments: [uri]
66566
- }
66567
- });
66568
- }
66569
67012
  const requirements = indexByName(root3, "RequirementDecl");
66570
67013
  const parts = indexByName(root3, "PartDecl");
66571
67014
  walkAst(root3, (node) => {
@@ -66574,7 +67017,7 @@ var SysmlCodeLensProvider = class {
66574
67017
  return;
66575
67018
  const range = cst.range;
66576
67019
  if (isSatisfyStmt(node)) {
66577
- const reqName = lastSegment3(node.target);
67020
+ const reqName = lastSegment4(node.target);
66578
67021
  const req = reqName ? requirements.get(reqName) : void 0;
66579
67022
  if (req) {
66580
67023
  const bound = bindingName(node.by);
@@ -66677,11 +67120,24 @@ var SysmlDocumentHighlightProvider = class {
66677
67120
  var import_vscode_languageserver22 = __toESM(require_main4(), 1);
66678
67121
  var SysmlDefinitionProvider = class extends DefaultDefinitionProvider {
66679
67122
  indexManager;
67123
+ featurePaths;
66680
67124
  constructor(services) {
66681
67125
  super(services);
66682
67126
  this.indexManager = services.shared.workspace.IndexManager;
67127
+ this.featurePaths = new FeaturePathResolver(services);
66683
67128
  }
66684
67129
  collectLocationLinks(sourceCstNode, params) {
67130
+ if (isPathExpr(sourceCstNode.astNode)) {
67131
+ const resolution = this.featurePaths.resolve(sourceCstNode.astNode);
67132
+ const segment = resolution.segments.find((candidate) => candidate.cst.offset <= sourceCstNode.offset && candidate.cst.end >= sourceCstNode.end);
67133
+ if (segment?.description) {
67134
+ const link2 = this.linkFromDescription(segment.description, segment.cst);
67135
+ if (link2)
67136
+ return [link2];
67137
+ }
67138
+ if (segment)
67139
+ return void 0;
67140
+ }
66685
67141
  const referenced = this.references.findDeclaration(sourceCstNode);
66686
67142
  if (referenced && isAliasDecl(referenced)) {
66687
67143
  const followed = this.resolveAliasTarget(referenced);
@@ -66816,7 +67272,7 @@ var SysmlDeclarationProvider = class {
66816
67272
 
66817
67273
  // ../language-server/out/src/services/references-provider.js
66818
67274
  var import_vscode_languageserver24 = __toESM(require_main4(), 1);
66819
- function lastSegment4(qualified) {
67275
+ function lastSegment5(qualified) {
66820
67276
  return qualified.split(/::|\./u).pop() ?? qualified;
66821
67277
  }
66822
67278
  function locationKey(uri, cst) {
@@ -66838,7 +67294,7 @@ var SysmlReferencesProvider = class extends DefaultReferencesProvider {
66838
67294
  const targetNames = this.namesOf(targetNode);
66839
67295
  if (targetNames.size === 0)
66840
67296
  return base;
66841
- const targetSimpleNames = new Set([...targetNames].map(lastSegment4));
67297
+ const targetSimpleNames = new Set([...targetNames].map(lastSegment5));
66842
67298
  const seen = /* @__PURE__ */ new Set();
66843
67299
  const out = [];
66844
67300
  for (const location of base) {
@@ -66880,7 +67336,7 @@ var SysmlReferencesProvider = class extends DefaultReferencesProvider {
66880
67336
  }
66881
67337
  const names = this.namesOf(targetNode);
66882
67338
  if (names.size > 0) {
66883
- const simpleNames = new Set([...names].map(lastSegment4));
67339
+ const simpleNames = new Set([...names].map(lastSegment5));
66884
67340
  for (const doc of this.langiumDocuments.all) {
66885
67341
  const root3 = doc.parseResult?.value;
66886
67342
  if (!root3)
@@ -66919,7 +67375,7 @@ var SysmlReferencesProvider = class extends DefaultReferencesProvider {
66919
67375
  resolveByName(text) {
66920
67376
  if (!text)
66921
67377
  return void 0;
66922
- const simple = lastSegment4(text);
67378
+ const simple = lastSegment5(text);
66923
67379
  const all = this.indexManager.allElements().toArray();
66924
67380
  return all.find((d) => d.name === text)?.node ?? all.find((d) => d.name === simple)?.node;
66925
67381
  }
@@ -68439,7 +68895,7 @@ async function runValidation(command) {
68439
68895
  }
68440
68896
 
68441
68897
  // src/main.ts
68442
- var VERSION2 = true ? "0.11.0" : "dev";
68898
+ var VERSION2 = true ? "0.14.3" : "dev";
68443
68899
  async function main(argv) {
68444
68900
  const command = parseArgs(argv);
68445
68901
  if (command.kind === "help") {