sysml-v2-lsp 0.40.0 → 0.41.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.
@@ -159233,7 +159233,10 @@ function splitQualifiedName(text) {
159233
159233
  return parts;
159234
159234
  }
159235
159235
  function joinQualifiedName(parts) {
159236
- return parts.map((part) => /::|['\\\r\n\t\b\f]|^\s|\s$/.test(part) ? quoteName(part) : part).join("::");
159236
+ return parts.map((part) => /::|^:|:$|['\\\r\n\t\b\f]|^\s|\s$|^\$?$/.test(part) ? quoteName(part) : part).join("::");
159237
+ }
159238
+ function joinReference(chain, conjugated = false) {
159239
+ return (conjugated ? "~" : "") + chain.map(({ global, names }) => (global ? "$::" : "") + names.map((name) => /\.|^~/.test(name) ? quoteName(name) : joinQualifiedName([name])).join("::")).join(".");
159237
159240
  }
159238
159241
  function readNameAt(text, start, allowIncomplete = false) {
159239
159242
  if (text[start] === "'") {
@@ -160461,12 +160464,44 @@ var RULE_INDEX_TO_KIND = /* @__PURE__ */ new Map([
160461
160464
  var BODY_RULE_INDICES = new Set(
160462
160465
  SysMLv2Parser.ruleNames.flatMap((ruleName, index2) => ruleName.endsWith("Body") ? [index2] : [])
160463
160466
  );
160467
+ var VALUE_DECLARATION_RULE_INDICES = /* @__PURE__ */ new Set([
160468
+ SysMLv2Parser.RULE_usage,
160469
+ SysMLv2Parser.RULE_usageCompletion,
160470
+ SysMLv2Parser.RULE_actionUsageDeclaration,
160471
+ SysMLv2Parser.RULE_performActionUsageDeclaration,
160472
+ SysMLv2Parser.RULE_constraintUsageDeclaration,
160473
+ SysMLv2Parser.RULE_interfaceUsageDeclaration,
160474
+ SysMLv2Parser.RULE_flowDeclaration,
160475
+ SysMLv2Parser.RULE_messageDeclaration
160476
+ ]);
160464
160477
  var FLOW_PART_RULE_INDICES = /* @__PURE__ */ new Set([
160465
160478
  SysMLv2Parser.RULE_payloadFeatureMember,
160466
160479
  SysMLv2Parser.RULE_flowPayloadFeatureMember,
160467
160480
  SysMLv2Parser.RULE_flowEndMember,
160468
160481
  SysMLv2Parser.RULE_messageEventMember
160469
160482
  ]);
160483
+ var SPECIALIZATION_DECLARATION_RULE_INDICES = /* @__PURE__ */ new Set([
160484
+ SysMLv2Parser.RULE_definition,
160485
+ SysMLv2Parser.RULE_definitionDeclaration,
160486
+ SysMLv2Parser.RULE_usage,
160487
+ SysMLv2Parser.RULE_usageDeclaration,
160488
+ SysMLv2Parser.RULE_featureDeclaration,
160489
+ SysMLv2Parser.RULE_featureSpecializationPart,
160490
+ SysMLv2Parser.RULE_actionUsageDeclaration,
160491
+ SysMLv2Parser.RULE_performActionUsageDeclaration,
160492
+ SysMLv2Parser.RULE_constraintUsageDeclaration,
160493
+ SysMLv2Parser.RULE_interfaceUsageDeclaration,
160494
+ SysMLv2Parser.RULE_allocationUsageDeclaration,
160495
+ SysMLv2Parser.RULE_flowDeclaration,
160496
+ SysMLv2Parser.RULE_messageDeclaration
160497
+ ]);
160498
+ var REFERENCE_SHORTHAND_RULE_INDICES = /* @__PURE__ */ new Set([
160499
+ SysMLv2Parser.RULE_variantReference,
160500
+ SysMLv2Parser.RULE_performActionUsageDeclaration,
160501
+ SysMLv2Parser.RULE_exhibitStateUsage,
160502
+ SysMLv2Parser.RULE_framedConcernUsage,
160503
+ SysMLv2Parser.RULE_includeUseCaseUsage
160504
+ ]);
160470
160505
  var FLOW_DECLARATION_RULE_INDICES = [
160471
160506
  SysMLv2Parser.RULE_flowDeclaration,
160472
160507
  SysMLv2Parser.RULE_messageDeclaration
@@ -160572,6 +160607,50 @@ var PREFIX_EXTENSION_RULE_INDICES = /* @__PURE__ */ new Set([
160572
160607
  SysMLv2Parser.RULE_endFeaturePrefix
160573
160608
  // 86
160574
160609
  ]);
160610
+ var PREFIX_KEYWORD_TOKENS = /* @__PURE__ */ new Set([
160611
+ SysMLv2Lexer.IN,
160612
+ SysMLv2Lexer.OUT,
160613
+ SysMLv2Lexer.INOUT,
160614
+ SysMLv2Lexer.ABSTRACT,
160615
+ SysMLv2Lexer.VARIATION,
160616
+ SysMLv2Lexer.INDIVIDUAL,
160617
+ SysMLv2Lexer.DERIVED,
160618
+ SysMLv2Lexer.CONSTANT,
160619
+ SysMLv2Lexer.REF,
160620
+ SysMLv2Lexer.END,
160621
+ SysMLv2Lexer.ORDERED,
160622
+ SysMLv2Lexer.NONUNIQUE
160623
+ ]);
160624
+ var PREFIX_PATH_RULE_INDICES = /* @__PURE__ */ new Set([
160625
+ SysMLv2Parser.RULE_usagePrefix,
160626
+ SysMLv2Parser.RULE_unextendedUsagePrefix,
160627
+ SysMLv2Parser.RULE_basicUsagePrefix,
160628
+ SysMLv2Parser.RULE_endUsagePrefix,
160629
+ SysMLv2Parser.RULE_refPrefix,
160630
+ SysMLv2Parser.RULE_featureDirection,
160631
+ SysMLv2Parser.RULE_occurrenceUsagePrefix,
160632
+ SysMLv2Parser.RULE_controlNodePrefix,
160633
+ SysMLv2Parser.RULE_definitionPrefix,
160634
+ SysMLv2Parser.RULE_basicDefinitionPrefix,
160635
+ SysMLv2Parser.RULE_occurrenceDefinitionPrefix,
160636
+ SysMLv2Parser.RULE_usage,
160637
+ SysMLv2Parser.RULE_usageDeclaration,
160638
+ SysMLv2Parser.RULE_featureDeclaration,
160639
+ SysMLv2Parser.RULE_featureSpecializationPart,
160640
+ SysMLv2Parser.RULE_multiplicityPart,
160641
+ SysMLv2Parser.RULE_actionUsageDeclaration,
160642
+ SysMLv2Parser.RULE_performActionUsageDeclaration,
160643
+ SysMLv2Parser.RULE_constraintUsageDeclaration,
160644
+ SysMLv2Parser.RULE_interfaceUsageDeclaration,
160645
+ SysMLv2Parser.RULE_allocationUsageDeclaration,
160646
+ SysMLv2Parser.RULE_flowDeclaration,
160647
+ SysMLv2Parser.RULE_messageDeclaration
160648
+ ]);
160649
+ var OCCURRENCE_USAGE_ELEMENT_RULE_INDICES = /* @__PURE__ */ new Set([
160650
+ SysMLv2Parser.RULE_occurrenceUsageElement,
160651
+ SysMLv2Parser.RULE_structureUsageElement,
160652
+ SysMLv2Parser.RULE_behaviorUsageElement
160653
+ ]);
160575
160654
  var TYPE_SPECIALIZATION_RULE_INDICES = /* @__PURE__ */ new Set([
160576
160655
  SysMLv2Parser.RULE_specialization,
160577
160656
  // 66
@@ -161406,6 +161485,9 @@ var SymbolTable = class {
161406
161485
  const typeName = typeNames[0];
161407
161486
  const documentation = this.extractDocumentation(ctx2);
161408
161487
  const visibility = this.extractVisibility(ctx2);
161488
+ const featureValue = this.extractFeatureValue(ctx2);
161489
+ const prefixKeywords = this.extractPrefixKeywords(ctx2);
161490
+ const ownedSpecializations = this.extractOwnedSpecializations(ctx2);
161409
161491
  const { multiplicity, multiplicityRange } = isUsage(kind) ? this.extractMultiplicity(ctx2) : {};
161410
161492
  const metadataAnnotations = this.extractPrefixMetadataAnnotations(ctx2);
161411
161493
  const isView = kind === "view" /* ViewUsage */ || kind === "view def" /* ViewDef */;
@@ -161438,6 +161520,9 @@ var SymbolTable = class {
161438
161520
  namingReference,
161439
161521
  documentation,
161440
161522
  visibility,
161523
+ featureValue,
161524
+ prefixKeywords: prefixKeywords.length > 0 ? prefixKeywords : void 0,
161525
+ ownedSpecializations: ownedSpecializations.length > 0 ? ownedSpecializations : void 0,
161441
161526
  source: transition?.source,
161442
161527
  target: transition?.target,
161443
161528
  flowDetails,
@@ -161821,7 +161906,23 @@ var SymbolTable = class {
161821
161906
  * between two of them (`connect a.p to b.p`, `connection : Conn`).
161822
161907
  */
161823
161908
  declarationText(ctx2) {
161824
- const tokens = this.declarationTokens(ctx2);
161909
+ return this.tokensText(this.declarationTokens(ctx2));
161910
+ }
161911
+ /** Every token of `ctx`, in source order: a whole expression, bodies and `;` included. */
161912
+ subtreeTokens(ctx2, tokens = []) {
161913
+ for (let i = 0; i < ctx2.getChildCount(); i++) {
161914
+ const child = ctx2.getChild(i);
161915
+ if (child instanceof TerminalNode) {
161916
+ if (child.symbol.tokenIndex >= 0) tokens.push(child.symbol);
161917
+ } else if (child instanceof ParserRuleContext) this.subtreeTokens(child, tokens);
161918
+ }
161919
+ return tokens;
161920
+ }
161921
+ /**
161922
+ * Tokens joined as written, with one space wherever the source has
161923
+ * whitespace or a comment between two of them.
161924
+ */
161925
+ tokensText(tokens) {
161825
161926
  let text = "";
161826
161927
  tokens.forEach((token, i) => {
161827
161928
  if (i > 0 && token.start > tokens[i - 1].stop + 1) text += " ";
@@ -161927,6 +162028,139 @@ var SymbolTable = class {
161927
162028
  }
161928
162029
  return void 0;
161929
162030
  }
162031
+ /**
162032
+ * `ctx`'s own feature value (SysML 7.13.4, 8.2.2.6.2 `ValuePart`, `FeatureValue`):
162033
+ * its expression as written, and whether it is a default (`default`) and an
162034
+ * initial (`:=`) value. Never a nested element's value; a cross subsetting
162035
+ * (`=> x`) is not a value. The expression is the whole `OwnedExpression`,
162036
+ * expression bodies included, with whitespace and comments as one space.
162037
+ */
162038
+ extractFeatureValue(ctx2) {
162039
+ const featureValueCtx = this.findOwnValuePart(ctx2)?.getRuleContext(0, FeatureValueContext);
162040
+ const expression = featureValueCtx?.ownedExpression();
162041
+ const text = expression && this.tokensText(this.subtreeTokens(expression));
162042
+ if (!featureValueCtx || !text) return void 0;
162043
+ return {
162044
+ expression: text,
162045
+ isDefault: featureValueCtx.DEFAULT() !== null,
162046
+ isInitial: featureValueCtx.COLON_EQ() !== null
162047
+ };
162048
+ }
162049
+ /**
162050
+ * `ctx`'s own `ValuePart`: a direct child of its element rule, or of one of
162051
+ * its declaration rules (`VALUE_DECLARATION_RULE_INDICES`). Never one of an
162052
+ * inline-owned element, e.g. a transition's accept payload or effect action.
162053
+ */
162054
+ findOwnValuePart(ctx2) {
162055
+ for (let i = 0; i < ctx2.getChildCount(); i++) {
162056
+ const child = ctx2.getChild(i);
162057
+ if (!(child instanceof ParserRuleContext)) continue;
162058
+ if (child.ruleIndex === SysMLv2Parser.RULE_valuePart) return child;
162059
+ if (!VALUE_DECLARATION_RULE_INDICES.has(child.ruleIndex)) continue;
162060
+ const valuePart = this.findOwnValuePart(child);
162061
+ if (valuePart) return valuePart;
162062
+ }
162063
+ return void 0;
162064
+ }
162065
+ /**
162066
+ * The specializations of `ctx`'s own declaration, one per target in written
162067
+ * order, read only from its `FeatureSpecialization`s (SysML v2 8.2.2.6.2),
162068
+ * `SubclassificationPart` (8.2.2.6.1) and a shorthand's reference
162069
+ * (`perform a`, `REFERENCE_SHORTHAND_RULE_INDICES`), reached through
162070
+ * `SPECIALIZATION_DECLARATION_RULE_INDICES`.
162071
+ */
162072
+ extractOwnedSpecializations(ctx2) {
162073
+ const specializations = [];
162074
+ const add = (kind, targets, notation) => {
162075
+ for (const targetCtx of targets) {
162076
+ const target = targetCtx && this.specializationTarget(targetCtx);
162077
+ if (target) specializations.push(notation ? { kind, target, notation: notation.getText() } : { kind, target });
162078
+ }
162079
+ };
162080
+ const visit2 = (node2) => {
162081
+ for (let i = 0; i < node2.getChildCount(); i++) {
162082
+ const child = node2.getChild(i);
162083
+ if (child instanceof FeatureSpecializationContext) {
162084
+ const typings = child.typings();
162085
+ const subsettings = child.subsettings();
162086
+ const references = child.references();
162087
+ const crosses = child.crosses();
162088
+ const redefinitions = child.redefinitions();
162089
+ if (typings) {
162090
+ const typedBy = typings.typedBy();
162091
+ add("typing", [typedBy?.featureTyping(), ...typings.featureTyping()].map((typing) => typing && (typing.ownedFeatureTyping() ?? typing.conjugatedPortTyping())));
162092
+ } else if (subsettings) {
162093
+ const subsets = subsettings.subsets();
162094
+ add("subsetting", [subsets?.ownedSubsetting(), ...subsettings.ownedSubsetting()], subsets && (subsets.COLON_GT() ?? subsets.SUBSETS()));
162095
+ } else if (references) {
162096
+ add("referenceSubsetting", [references.ownedReferenceSubsetting()], references.COLON_COLON_GT() ?? references.REFERENCES());
162097
+ } else if (crosses) {
162098
+ add("crossSubsetting", [crosses.ownedCrossSubsetting()], crosses.FAT_ARROW() ?? crosses.CROSSES());
162099
+ } else if (redefinitions) {
162100
+ const redefines = redefinitions.redefines();
162101
+ add("redefinition", [redefines?.ownedRedefinition(), ...redefinitions.ownedRedefinition()], redefines && (redefines.COLON_GT_GT() ?? redefines.REDEFINES()));
162102
+ }
162103
+ } else if (child instanceof OwnedReferenceSubsettingContext && REFERENCE_SHORTHAND_RULE_INDICES.has(node2.ruleIndex)) {
162104
+ add("referenceSubsetting", [child]);
162105
+ } else if (child instanceof SubclassificationPartContext) {
162106
+ add("specializes", child.ownedSubclassification(), child.COLON_GT() ?? child.SPECIALIZES());
162107
+ } else if (child instanceof ParserRuleContext && SPECIALIZATION_DECLARATION_RULE_INDICES.has(child.ruleIndex)) {
162108
+ visit2(child);
162109
+ }
162110
+ }
162111
+ };
162112
+ visit2(ctx2);
162113
+ return specializations;
162114
+ }
162115
+ /**
162116
+ * The general type or feature a specialization's target rule names: its
162117
+ * qualified name, or its feature chain (`v.engine`), with a global `$::`
162118
+ * (KerML 7.2.2) and a conjugated port typing's `~` (`~P`, SysML 8.3.12.3).
162119
+ * Its names are quoted as everywhere in the server (`joinReference`).
162120
+ * Undefined for a target missing after a syntax error.
162121
+ */
162122
+ specializationTarget(ctx2) {
162123
+ const chain = ctx2.getRuleContexts(QualifiedNameContext).map((qualifiedName) => ({
162124
+ global: qualifiedName.DOLLAR() !== null,
162125
+ names: qualifiedName.getRuleContexts(NameContext).map((name) => name.getText())
162126
+ }));
162127
+ if (chain.length === 0 || chain.some(({ names }) => names.length === 0 || names.some((name) => !name))) return void 0;
162128
+ return joinReference(
162129
+ chain.map(({ global, names }) => ({ global, names: names.map(unquoteName) })),
162130
+ ctx2 instanceof ConjugatedPortTypingContext
162131
+ );
162132
+ }
162133
+ /**
162134
+ * The keywords of `ctx`'s own prefix and multiplicity part, in written
162135
+ * order (`in`, `abstract`, `constant`, `ref`, `end`, `ordered`, ...),
162136
+ * read only from the rules in `PREFIX_PATH_RULE_INDICES`.
162137
+ */
162138
+ extractPrefixKeywords(ctx2) {
162139
+ const keywords = [];
162140
+ const visit2 = (node2) => {
162141
+ for (let i = 0; i < node2.getChildCount(); i++) {
162142
+ const child = node2.getChild(i);
162143
+ if (child instanceof TerminalNode) {
162144
+ if (PREFIX_KEYWORD_TOKENS.has(child.symbol.type)) keywords.push(child.getText());
162145
+ continue;
162146
+ }
162147
+ if (child instanceof ParserRuleContext && PREFIX_PATH_RULE_INDICES.has(child.ruleIndex)) visit2(child);
162148
+ }
162149
+ };
162150
+ visit2(ctx2);
162151
+ return this.isEndOccurrence(ctx2) ? ["end", ...keywords] : keywords;
162152
+ }
162153
+ /**
162154
+ * Whether `ctx` is the occurrence usage of an `endOccurrenceUsageElement`
162155
+ * (`end part a`), whose `end` precedes the usage's own rule.
162156
+ */
162157
+ isEndOccurrence(ctx2) {
162158
+ let current = ctx2.parent;
162159
+ while (current instanceof ParserRuleContext && OCCURRENCE_USAGE_ELEMENT_RULE_INDICES.has(current.ruleIndex)) {
162160
+ current = current.parent;
162161
+ }
162162
+ return current !== ctx2.parent && current instanceof ParserRuleContext && current.ruleIndex === SysMLv2Parser.RULE_endOccurrenceUsageElement;
162163
+ }
161930
162164
  /**
161931
162165
  * Extract the range of just the name token.
161932
162166
  */
@@ -162835,22 +163069,6 @@ function readWordAfterKeyword(text, afterPos, allowDots = false) {
162835
163069
  const start = skipWS(text, afterPos);
162836
163070
  return readIdent(text, start, allowDots);
162837
163071
  }
162838
- function readCommaSeparatedIdents(text, pos) {
162839
- const names = [];
162840
- let p = skipWS(text, pos);
162841
- while (p < text.length) {
162842
- const [name, end] = readIdent(text, p);
162843
- if (!name) break;
162844
- names.push(name);
162845
- p = skipWS(text, end);
162846
- if (p < text.length && text[p] === ",") {
162847
- p = skipWS(text, p + 1);
162848
- } else {
162849
- break;
162850
- }
162851
- }
162852
- return names;
162853
- }
162854
163072
  function symbolsById(symbols) {
162855
163073
  return new Map(symbols.map((s) => [s.symbolId, s]));
162856
163074
  }
@@ -162896,7 +163114,7 @@ var SysMLModelProvider = class {
162896
163114
  result.activityDiagrams = this.extractActivityDiagrams(symbolTable, uri, lines);
162897
163115
  }
162898
163116
  if (scopeSet.has("resolvedTypes")) {
162899
- result.resolvedTypes = this.extractResolvedTypes(symbolTable, uri, lines);
163117
+ result.resolvedTypes = this.extractResolvedTypes(symbolTable, uri);
162900
163118
  }
162901
163119
  if (scopeSet.has("diagnostics")) {
162902
163120
  result.diagnostics = this.extractSemanticDiagnostics(symbolTable, uri);
@@ -162995,44 +163213,34 @@ var SysMLModelProvider = class {
162995
163213
  if (symbol2.viewRendering) {
162996
163214
  attributes["viewRendering"] = symbol2.viewRendering;
162997
163215
  }
162998
- const direction = this.extractDirection(symbol2, lines);
162999
- if (direction) {
163000
- attributes["direction"] = direction;
163216
+ const prefix = prefixAttributesOf(symbol2);
163217
+ if (prefix.direction) {
163218
+ attributes["direction"] = prefix.direction;
163001
163219
  }
163002
163220
  if (symbol2.multiplicity) {
163003
163221
  attributes["multiplicity"] = symbol2.multiplicity;
163004
163222
  }
163005
- const modifier = this.extractModifier(symbol2, lines);
163006
- if (modifier) {
163007
- attributes["modifier"] = modifier;
163223
+ if (prefix.modifier) {
163224
+ attributes["modifier"] = prefix.modifier;
163225
+ }
163226
+ if (prefix.ordered) {
163227
+ attributes["ordered"] = true;
163228
+ }
163229
+ if (prefix.nonunique) {
163230
+ attributes["nonunique"] = true;
163008
163231
  }
163009
163232
  if (symbol2.visibility) {
163010
163233
  attributes["visibility"] = symbol2.visibility;
163011
163234
  }
163012
- const value = this.extractValue(symbol2, lines);
163013
- if (value) {
163014
- attributes["value"] = value;
163235
+ if (symbol2.featureValue) {
163236
+ attributes["value"] = symbol2.featureValue.expression;
163237
+ if (symbol2.featureValue.isDefault) attributes["isDefault"] = true;
163238
+ if (symbol2.featureValue.isInitial) attributes["isInitial"] = true;
163015
163239
  }
163016
163240
  const relationships = [];
163017
- for (const tn of symbol2.typeNames) {
163018
- relationships.push({
163019
- type: "typing",
163020
- source: symbol2.name,
163021
- sourceId: symbol2.symbolId,
163022
- target: tn
163023
- });
163024
- }
163241
+ relationships.push(...this.specializationRelationships(symbol2));
163025
163242
  const flowRelationship = this.flowRelationship(symbol2);
163026
163243
  if (flowRelationship) relationships.push(flowRelationship);
163027
- const specializations = this.extractSpecializations(symbol2, lines);
163028
- for (const spec of specializations) {
163029
- relationships.push({
163030
- type: "specializes",
163031
- source: symbol2.name,
163032
- sourceId: symbol2.symbolId,
163033
- target: spec
163034
- });
163035
- }
163036
163244
  return {
163037
163245
  type: symbol2.kind,
163038
163246
  name: symbol2.name,
@@ -163044,6 +163252,20 @@ var SysMLModelProvider = class {
163044
163252
  relationships
163045
163253
  };
163046
163254
  }
163255
+ /**
163256
+ * The typings, subclassifications, subsettings and redefinitions of the
163257
+ * element's own declaration, one per target in written order (SysML v2
163258
+ * 8.2.2.6.1, 8.2.2.6.2).
163259
+ */
163260
+ specializationRelationships(symbol2) {
163261
+ return (symbol2.ownedSpecializations ?? []).map(({ kind, target, notation }) => ({
163262
+ type: kind,
163263
+ source: symbol2.name,
163264
+ sourceId: symbol2.symbolId,
163265
+ target,
163266
+ ...notation ? { notation } : {}
163267
+ }));
163268
+ }
163047
163269
  flowRelationship(symbol2) {
163048
163270
  const details = symbol2.flowDetails;
163049
163271
  if (!isFlowUsage(symbol2.kind) || !details?.source || !details.target) return void 0;
@@ -163077,25 +163299,7 @@ var SysMLModelProvider = class {
163077
163299
  if (symbol2.kind === "package" /* Package */ || symbol2.kind === "import" /* Import */ || symbol2.kind === "comment" /* Comment */ || symbol2.kind === "doc" /* Doc */) {
163078
163300
  continue;
163079
163301
  }
163080
- if (symbol2.typeNames.length > 0 && isUsage(symbol2.kind)) {
163081
- for (const tn of symbol2.typeNames) {
163082
- relationships.push({
163083
- type: "typing",
163084
- source: symbol2.name,
163085
- sourceId: symbol2.symbolId,
163086
- target: tn
163087
- });
163088
- }
163089
- }
163090
- const specializations = this.extractSpecializations(symbol2, lines);
163091
- for (const spec of specializations) {
163092
- relationships.push({
163093
- type: "specializes",
163094
- source: symbol2.name,
163095
- sourceId: symbol2.symbolId,
163096
- target: spec
163097
- });
163098
- }
163302
+ relationships.push(...this.specializationRelationships(symbol2));
163099
163303
  if (symbol2.kind === "connection" /* ConnectionUsage */) {
163100
163304
  const connectionTargets = this.extractConnectionEndpoints(symbol2, lines);
163101
163305
  if (connectionTargets.length === 2) {
@@ -163588,41 +163792,30 @@ var SysMLModelProvider = class {
163588
163792
  * Because the LSP server doesn't yet have a full type resolver or library
163589
163793
  * index, we provide what's available from the parse tree.
163590
163794
  */
163591
- extractResolvedTypes(symbolTable, uri, lines) {
163795
+ extractResolvedTypes(symbolTable, uri) {
163592
163796
  const symbols = symbolTable.getSymbolsForUri(uri);
163593
163797
  const result = {};
163594
163798
  for (const symbol2 of symbols) {
163595
163799
  const qualifiedName = symbol2.qualifiedName;
163596
163800
  if (qualifiedName === void 0) continue;
163597
- if (!isDefinition(symbol2.kind) && symbol2.typeNames.length === 0) {
163801
+ if (!isDefinition(symbol2.kind) && !symbol2.ownedSpecializations) {
163598
163802
  continue;
163599
163803
  }
163600
- const specializes = [];
163601
- const specList = this.extractSpecializations(symbol2, lines);
163602
- for (const s of specList) {
163603
- if (!specializes.includes(s)) {
163604
- specializes.push(s);
163605
- }
163606
- }
163607
- for (const tn of symbol2.typeNames) {
163608
- if (!specializes.includes(tn)) {
163609
- specializes.push(tn);
163610
- }
163611
- }
163804
+ const specializes = [...new Set((symbol2.ownedSpecializations ?? []).map(({ target }) => target))];
163612
163805
  const specializationChain = [...specializes];
163613
163806
  const children = this.getChildSymbols(symbol2, symbolTable);
163614
163807
  const features = children.filter((c) => isUsage(c.kind)).map((c) => {
163615
- const modifier = this.extractModifier(c, lines);
163616
- const direction = this.extractDirection(c, lines);
163808
+ const prefix = prefixAttributesOf(c);
163617
163809
  return {
163618
163810
  name: c.name,
163619
163811
  kind: toMetaclassName(c.kind),
163620
163812
  type: c.typeNames.join(", ") || void 0,
163621
163813
  multiplicity: c.multiplicity,
163622
- direction,
163814
+ direction: prefix.direction,
163623
163815
  visibility: c.visibility,
163624
- isDerived: modifier?.split(", ").includes("derived") ?? false,
163625
- isReadonly: modifier?.split(", ").includes("readonly") ?? false
163816
+ isDerived: prefix.keywords.includes("derived"),
163817
+ isConstant: prefix.isConstant,
163818
+ isReadonly: prefix.isConstant
163626
163819
  };
163627
163820
  });
163628
163821
  result[qualifiedName] = {
@@ -163739,67 +163932,6 @@ var SysMLModelProvider = class {
163739
163932
  const endLine = Math.min(symbol2.range.end.line, lines.length - 1);
163740
163933
  return lines.slice(startLine, endLine + 1).join("\n");
163741
163934
  }
163742
- /** Extract port direction (in | out | inout) from source text. */
163743
- extractDirection(symbol2, lines) {
163744
- if (symbol2.kind !== "port" /* PortUsage */ && symbol2.kind !== "port def" /* PortDef */) {
163745
- return void 0;
163746
- }
163747
- const elementText = this.getElementText(symbol2, lines);
163748
- if (containsWord(elementText, "inout")) return "inout";
163749
- if (containsWord(elementText, "in")) return "in";
163750
- if (containsWord(elementText, "out")) return "out";
163751
- return void 0;
163752
- }
163753
- /** Extract modifiers (abstract, readonly, derived, etc.) from source text. */
163754
- extractModifier(symbol2, lines) {
163755
- const elementText = this.getElementText(symbol2, lines);
163756
- const modifiers = [];
163757
- if (containsWord(elementText, "abstract")) modifiers.push("abstract");
163758
- if (containsWord(elementText, "readonly")) modifiers.push("readonly");
163759
- if (containsWord(elementText, "derived")) modifiers.push("derived");
163760
- if (containsWord(elementText, "variation")) modifiers.push("variation");
163761
- if (containsWord(elementText, "individual")) modifiers.push("individual");
163762
- return modifiers.length > 0 ? modifiers.join(", ") : void 0;
163763
- }
163764
- /** Extract default/assigned value from source text. */
163765
- extractValue(symbol2, lines) {
163766
- if (symbol2.kind !== "attribute" /* AttributeUsage */) {
163767
- return void 0;
163768
- }
163769
- const elementText = this.getElementText(symbol2, lines);
163770
- const eqIdx = elementText.indexOf("=");
163771
- if (eqIdx < 0) return void 0;
163772
- let start = eqIdx + 1;
163773
- if (start < elementText.length && elementText[start] === "=") return void 0;
163774
- start = skipWS(elementText, start);
163775
- let end = start;
163776
- while (end < elementText.length) {
163777
- const ch = elementText[end];
163778
- if (ch === ";" || ch === "{" || ch === "}" || ch === "\n") break;
163779
- end++;
163780
- }
163781
- const val = elementText.substring(start, end).trim();
163782
- if (val && !val.includes("def") && val.length < 100) {
163783
- return val;
163784
- }
163785
- return void 0;
163786
- }
163787
- /** Extract all specialization targets from `:>` or `specializes` syntax. */
163788
- extractSpecializations(symbol2, lines) {
163789
- const elementText = this.getElementText(symbol2, lines);
163790
- const colonGtIdx = elementText.indexOf(":>");
163791
- if (colonGtIdx >= 0) {
163792
- if (colonGtIdx + 2 < elementText.length && elementText[colonGtIdx + 2] === ">") {
163793
- } else {
163794
- return readCommaSeparatedIdents(elementText, colonGtIdx + 2);
163795
- }
163796
- }
163797
- const specPositions = findWordPositions(elementText, "specializes");
163798
- if (specPositions.length > 0) {
163799
- return readCommaSeparatedIdents(elementText, specPositions[0].afterPos);
163800
- }
163801
- return [];
163802
- }
163803
163935
  /** Extract connection endpoints from `connect` syntax. */
163804
163936
  extractConnectionEndpoints(symbol2, lines) {
163805
163937
  const elementText = this.getElementText(symbol2, lines);
@@ -163863,16 +163995,6 @@ var SysMLModelProvider = class {
163863
163995
  const fromElement = { source: elementName, sourceId: element.symbolId };
163864
163996
  elementText = stripComments(elementText);
163865
163997
  const rels = [];
163866
- const subsetsPositions = findWordPositions(elementText, "subsets");
163867
- if (subsetsPositions.length > 0) {
163868
- const [target] = readWordAfterKeyword(elementText, subsetsPositions[0].afterPos);
163869
- if (target) rels.push({ type: "subsetting", ...fromElement, target });
163870
- }
163871
- const redefPositions = findWordPositions(elementText, "redefines");
163872
- if (redefPositions.length > 0) {
163873
- const [target] = readWordAfterKeyword(elementText, redefPositions[0].afterPos);
163874
- if (target) rels.push({ type: "redefinition", ...fromElement, target });
163875
- }
163876
163998
  const satisfyPositions = findWordPositions(elementText, "satisfy");
163877
163999
  if (satisfyPositions.length > 0) {
163878
164000
  let pos = skipWS(elementText, satisfyPositions[0].afterPos);
@@ -164166,6 +164288,21 @@ ${this.followingBranchStatements(symbol2, lines)}`;
164166
164288
  };
164167
164289
  }
164168
164290
  };
164291
+ var DIRECTIONS = /* @__PURE__ */ new Set(["in", "out", "inout"]);
164292
+ var MULTIPLICITY_KEYWORDS = /* @__PURE__ */ new Set(["ordered", "nonunique"]);
164293
+ function prefixAttributesOf(symbol2) {
164294
+ const keywords = symbol2.prefixKeywords ?? [];
164295
+ const direction = keywords.find((keyword) => DIRECTIONS.has(keyword));
164296
+ const modifiers = keywords.filter((keyword) => !DIRECTIONS.has(keyword) && !MULTIPLICITY_KEYWORDS.has(keyword));
164297
+ return {
164298
+ keywords,
164299
+ direction,
164300
+ modifier: modifiers.length > 0 ? modifiers.join(", ") : void 0,
164301
+ isConstant: keywords.includes("constant"),
164302
+ ordered: keywords.includes("ordered"),
164303
+ nonunique: keywords.includes("nonunique")
164304
+ };
164305
+ }
164169
164306
 
164170
164307
  // server/src/providers/semanticValidator.ts
164171
164308
  var CONSTRAINT_KEYWORDS = /* @__PURE__ */ new Set([