sysml-diagram 0.35.0 → 0.38.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/out/main.js CHANGED
@@ -115652,10 +115652,10 @@ function untilTokenToRegex(until) {
115652
115652
  lookahead: until.lookahead
115653
115653
  });
115654
115654
  }
115655
- function negateTokenToRegex(negate2) {
115656
- return withCardinality(`(?!${abstractElementToRegex(negate2.terminal)})${WILDCARD}*?`, {
115657
- cardinality: negate2.cardinality,
115658
- lookahead: negate2.lookahead
115655
+ function negateTokenToRegex(negate3) {
115656
+ return withCardinality(`(?!${abstractElementToRegex(negate3.terminal)})${WILDCARD}*?`, {
115657
+ cardinality: negate3.cardinality,
115658
+ lookahead: negate3.lookahead
115659
115659
  });
115660
115660
  }
115661
115661
  function characterRangeToRegex(range) {
@@ -161054,6 +161054,552 @@ var ANCHOR_KEYWORD = {
161054
161054
  bv: "package"
161055
161055
  };
161056
161056
 
161057
+ // ../language-server/out/src/services/constraint-reference.js
161058
+ var REFERENCE_KEYWORDS = {
161059
+ AssertConstraintStmt: "assert",
161060
+ RequireConstraintStmt: "require",
161061
+ AssumeConstraintStmt: "assume"
161062
+ };
161063
+ function constraintReferenceOf(node) {
161064
+ const kind = REFERENCE_KEYWORDS[node.$type];
161065
+ if (!kind)
161066
+ return void 0;
161067
+ const shape = node;
161068
+ if (shape.constraintKw)
161069
+ return void 0;
161070
+ const negated = shape.isNegated === true;
161071
+ if (kind === "assert") {
161072
+ if (!shape.name)
161073
+ return void 0;
161074
+ const links = [shape.name, ...shape.chainSegs ?? []];
161075
+ return { kind, negated, path: links.join("::"), simpleName: links[links.length - 1] };
161076
+ }
161077
+ const target = shape.target;
161078
+ if (typeof target !== "string" || target.length === 0)
161079
+ return void 0;
161080
+ return {
161081
+ kind,
161082
+ negated,
161083
+ property: "target",
161084
+ path: target,
161085
+ simpleName: lastLink(target)
161086
+ };
161087
+ }
161088
+ function lastLink(path10) {
161089
+ return path10.split(/::|\./u).filter(Boolean).pop() ?? path10;
161090
+ }
161091
+ var NON_CONSTRAINT_DECL_TYPES = /* @__PURE__ */ new Set([
161092
+ "Package",
161093
+ "NamespaceDecl",
161094
+ "Document",
161095
+ "Import",
161096
+ "PartDecl",
161097
+ "ItemDecl",
161098
+ "AttributeDecl",
161099
+ "PortDecl",
161100
+ "OccurrenceDecl",
161101
+ "InterfaceDecl",
161102
+ "ConnectionDecl",
161103
+ "AllocationDecl",
161104
+ "ConnectorDecl",
161105
+ "EnumDecl",
161106
+ "EnumValueDecl",
161107
+ "MetadataDecl",
161108
+ "MultiplicityDecl",
161109
+ "ActionDecl",
161110
+ "StateDecl",
161111
+ "CalcDecl",
161112
+ "CaseDecl",
161113
+ "UseCaseDecl",
161114
+ "AnalysisCaseDecl",
161115
+ "VerificationCaseDecl",
161116
+ "ViewDecl",
161117
+ "ViewpointDecl",
161118
+ "RenderingDecl",
161119
+ "ActorDecl",
161120
+ "StakeholderDecl",
161121
+ "StructDecl",
161122
+ "ClassDecl",
161123
+ "DatatypeDecl",
161124
+ "AssociationDecl",
161125
+ "MetaclassDecl",
161126
+ "BehaviorDecl",
161127
+ "FunctionDecl",
161128
+ "InteractionDecl"
161129
+ ]);
161130
+ var NON_CONSTRAINT_LABELS = {
161131
+ Package: "a package",
161132
+ NamespaceDecl: "a namespace",
161133
+ Document: "a file root namespace",
161134
+ Import: "an import",
161135
+ PartDecl: "a part",
161136
+ ItemDecl: "an item",
161137
+ AttributeDecl: "an attribute",
161138
+ PortDecl: "a port",
161139
+ OccurrenceDecl: "an occurrence",
161140
+ InterfaceDecl: "an interface",
161141
+ ConnectionDecl: "a connection",
161142
+ AllocationDecl: "an allocation",
161143
+ ConnectorDecl: "a connector",
161144
+ EnumDecl: "an enumeration",
161145
+ EnumValueDecl: "an enumeration value",
161146
+ MetadataDecl: "a metadata usage",
161147
+ MultiplicityDecl: "a multiplicity",
161148
+ ActionDecl: "an action",
161149
+ StateDecl: "a state",
161150
+ CalcDecl: "a calculation",
161151
+ CaseDecl: "a case",
161152
+ UseCaseDecl: "a use case",
161153
+ AnalysisCaseDecl: "an analysis case",
161154
+ VerificationCaseDecl: "a verification case",
161155
+ ViewDecl: "a view",
161156
+ ViewpointDecl: "a viewpoint",
161157
+ RenderingDecl: "a rendering",
161158
+ ActorDecl: "an actor",
161159
+ StakeholderDecl: "a stakeholder",
161160
+ StructDecl: "a structure",
161161
+ ClassDecl: "a class",
161162
+ DatatypeDecl: "a datatype",
161163
+ AssociationDecl: "an association",
161164
+ MetaclassDecl: "a metaclass",
161165
+ BehaviorDecl: "a behavior",
161166
+ FunctionDecl: "a function",
161167
+ InteractionDecl: "an interaction"
161168
+ };
161169
+ function isWrongKindConstraintTarget(node) {
161170
+ return NON_CONSTRAINT_DECL_TYPES.has(node.$type);
161171
+ }
161172
+ function wrongKindLabel(node) {
161173
+ return NON_CONSTRAINT_LABELS[node.$type] ?? "not a constraint";
161174
+ }
161175
+
161176
+ // ../language-server/out/src/services/requirement-semantics.js
161177
+ var DEFAULT_SUBJECT_TYPE = "Anything";
161178
+ var MAX_INHERITANCE_DEPTH = 16;
161179
+ var SPECIALIZATION_KINDS = /* @__PURE__ */ new Set([
161180
+ ":>",
161181
+ ":>>",
161182
+ "specializes",
161183
+ "subsets",
161184
+ "redefines"
161185
+ ]);
161186
+ var REDEFINITION_KINDS = /* @__PURE__ */ new Set([":>>", "redefines"]);
161187
+ var REQUIREMENT_SHAPED = /* @__PURE__ */ new Set([
161188
+ "RequirementDecl",
161189
+ "ConcernDecl",
161190
+ "ObjectiveDecl",
161191
+ "ViewpointDecl"
161192
+ ]);
161193
+ var CASE_SHAPED = /* @__PURE__ */ new Set([
161194
+ "CaseDecl",
161195
+ "AnalysisCaseDecl",
161196
+ "VerificationCaseDecl",
161197
+ "UseCaseDecl"
161198
+ ]);
161199
+ var SUBJECT_SHAPED = /* @__PURE__ */ new Set([
161200
+ ...REQUIREMENT_SHAPED,
161201
+ ...CASE_SHAPED
161202
+ ]);
161203
+ var CONSTRAINT_SHAPED = /* @__PURE__ */ new Set([
161204
+ "ConstraintDecl",
161205
+ "InvShorthand",
161206
+ "PredicateDecl",
161207
+ "RequirementDecl",
161208
+ "ConcernDecl",
161209
+ "ObjectiveDecl"
161210
+ ]);
161211
+ function simpleName(path10) {
161212
+ const last2 = path10.trim().split(/::|\./u).pop() ?? path10.trim();
161213
+ return last2.replace(/^'(.*)'$/u, "$1");
161214
+ }
161215
+ function* walkAll(node) {
161216
+ for (const child of [...node.elements ?? [], ...node.members ?? []]) {
161217
+ yield child;
161218
+ yield* walkAll(child);
161219
+ }
161220
+ }
161221
+ function rootOf(node) {
161222
+ let current2 = node;
161223
+ while (current2.$container)
161224
+ current2 = current2.$container;
161225
+ return current2;
161226
+ }
161227
+ function pathSegments(path10) {
161228
+ return path10.trim().split(/::|\./u).map((segment) => segment.trim().replace(/^'(.*)'$/u, "$1")).filter((segment) => segment.length > 0);
161229
+ }
161230
+ function qualifierChain(node) {
161231
+ const out = [];
161232
+ let current2 = node;
161233
+ while (current2) {
161234
+ if (current2.name)
161235
+ out.push(current2.name);
161236
+ current2 = current2.$container;
161237
+ }
161238
+ return out;
161239
+ }
161240
+ function documentResolver(from) {
161241
+ const root4 = rootOf(from);
161242
+ return (name) => {
161243
+ const segments = pathSegments(name);
161244
+ if (segments.length === 0)
161245
+ return void 0;
161246
+ const wanted = segments[segments.length - 1];
161247
+ const qualifiers = segments.slice(0, -1).reverse();
161248
+ let fallback;
161249
+ for (const candidate of walkAll(root4)) {
161250
+ if (candidate.name !== wanted)
161251
+ continue;
161252
+ if (qualifiers.length === 0)
161253
+ return candidate;
161254
+ const chain = qualifierChain(candidate).slice(1);
161255
+ let index2 = 0;
161256
+ for (const link of chain) {
161257
+ if (link === qualifiers[index2])
161258
+ index2++;
161259
+ if (index2 === qualifiers.length)
161260
+ break;
161261
+ }
161262
+ if (index2 === qualifiers.length)
161263
+ return candidate;
161264
+ fallback ??= candidate;
161265
+ }
161266
+ return fallback;
161267
+ };
161268
+ }
161269
+ function supertypesOf(node, resolve8) {
161270
+ const out = [];
161271
+ const add = (candidate) => {
161272
+ if (candidate)
161273
+ out.push(candidate);
161274
+ };
161275
+ for (const typing of [node.typing, ...node.moreTypings ?? []]) {
161276
+ if (!typing)
161277
+ continue;
161278
+ for (const ref of [typing.type, ...typing.moreTypes ?? []]) {
161279
+ if (!ref)
161280
+ continue;
161281
+ add(ref.ref ?? (ref.$refText ? resolve8(ref.$refText) : void 0));
161282
+ }
161283
+ }
161284
+ for (const rel2 of [...node.preRelationships ?? [], ...node.relationships ?? []]) {
161285
+ if (!rel2.kind || !SPECIALIZATION_KINDS.has(rel2.kind))
161286
+ continue;
161287
+ for (const target of rel2.targets ?? [])
161288
+ add(resolve8(target));
161289
+ }
161290
+ return out;
161291
+ }
161292
+ function locallyRedefinedNames(node) {
161293
+ const out = /* @__PURE__ */ new Set();
161294
+ for (const member of node.members ?? []) {
161295
+ for (const rel2 of [...member.preRelationships ?? [], ...member.relationships ?? []]) {
161296
+ if (!rel2.kind || !REDEFINITION_KINDS.has(rel2.kind))
161297
+ continue;
161298
+ for (const target of rel2.targets ?? [])
161299
+ out.add(simpleName(target));
161300
+ }
161301
+ }
161302
+ return out;
161303
+ }
161304
+ function referencePathOf(member) {
161305
+ const target = member.target;
161306
+ if (typeof target === "string")
161307
+ return target.trim() || void 0;
161308
+ if (target && typeof target === "object") {
161309
+ const text = target.$refText?.trim();
161310
+ if (text)
161311
+ return text;
161312
+ }
161313
+ return constraintReferenceOf(member)?.path;
161314
+ }
161315
+ function referenceTargetOf(member, resolve8) {
161316
+ const target = member.target;
161317
+ if (target && typeof target === "object" && target.ref)
161318
+ return target.ref;
161319
+ const path10 = referencePathOf(member);
161320
+ return path10 ? resolve8(path10) : void 0;
161321
+ }
161322
+ function constraintBodyOf(node, resolve8, depth = 0, seen = /* @__PURE__ */ new Set()) {
161323
+ if (!node || depth > MAX_INHERITANCE_DEPTH || seen.has(node))
161324
+ return void 0;
161325
+ seen.add(node);
161326
+ if (node.body)
161327
+ return node.body;
161328
+ const resolver = resolve8 ?? documentResolver(node);
161329
+ for (const supertype of supertypesOf(node, resolver)) {
161330
+ const inherited = constraintBodyOf(supertype, resolver, depth + 1, seen);
161331
+ if (inherited)
161332
+ return inherited;
161333
+ }
161334
+ return void 0;
161335
+ }
161336
+ function exprText(node) {
161337
+ return node?.$cstNode?.text?.trim() ?? "";
161338
+ }
161339
+ function labelOf(owner, kind, text) {
161340
+ const prefix = owner?.name ? `${owner.name} / ` : "";
161341
+ return `${prefix}${kind}: ${text}`;
161342
+ }
161343
+ function collect(node, origin, depth, walk) {
161344
+ if (depth > MAX_INHERITANCE_DEPTH || walk.seen.has(node))
161345
+ return;
161346
+ walk.seen.add(node);
161347
+ const redefined = locallyRedefinedNames(node);
161348
+ for (const member of node.members ?? []) {
161349
+ const kind = constraintKindOf(member);
161350
+ if (kind) {
161351
+ addConstraint(member, kind, origin, node, walk);
161352
+ continue;
161353
+ }
161354
+ if (member.$type === "InvShorthand" && member.body) {
161355
+ addBody(member, member.body, "require", origin, node, walk);
161356
+ }
161357
+ }
161358
+ for (const supertype of supertypesOf(node, walk.resolve)) {
161359
+ if (!REQUIREMENT_SHAPED.has(supertype.$type) && supertype.$type !== "ConstraintDecl")
161360
+ continue;
161361
+ const before = walk.out.length;
161362
+ collect(supertype, origin === "own" ? "inherited" : origin, depth + 1, walk);
161363
+ if (redefined.size === 0)
161364
+ continue;
161365
+ for (let i = walk.out.length - 1; i >= before; i--) {
161366
+ const host = walk.out[i].host;
161367
+ if (host.name && redefined.has(host.name))
161368
+ walk.out.splice(i, 1);
161369
+ }
161370
+ }
161371
+ for (const member of node.members ?? []) {
161372
+ if (member.$type === "RequirementDecl") {
161373
+ collect(member, origin === "own" ? "subrequirement" : origin, depth + 1, walk);
161374
+ } else if (member.$type === "FrameMember") {
161375
+ const concern = member.concernKw === true ? member : referenceTargetOf(member, walk.resolve);
161376
+ if (concern && (REQUIREMENT_SHAPED.has(concern.$type) || concern.$type === "FrameMember")) {
161377
+ collect(concern, origin === "own" ? "concern" : origin, depth + 1, walk);
161378
+ }
161379
+ }
161380
+ }
161381
+ }
161382
+ function constraintKindOf(member) {
161383
+ if (member.$type === "AssumeConstraintStmt")
161384
+ return "assume";
161385
+ if (member.$type === "RequireConstraintStmt" || member.$type === "AssertConstraintStmt")
161386
+ return "require";
161387
+ return void 0;
161388
+ }
161389
+ function addConstraint(member, kind, origin, owner, walk) {
161390
+ const negated = member.isNegated === true;
161391
+ if (member.body) {
161392
+ addBody(member, member.body, kind, origin, owner, walk, negated);
161393
+ return;
161394
+ }
161395
+ const path10 = referencePathOf(member);
161396
+ if (!path10)
161397
+ return;
161398
+ const target = referenceTargetOf(member, walk.resolve);
161399
+ const text = `${kind} ${negated ? "not " : ""}${path10}`;
161400
+ if (!target || !CONSTRAINT_SHAPED.has(target.$type)) {
161401
+ walk.out.push({
161402
+ kind,
161403
+ origin,
161404
+ host: member,
161405
+ text,
161406
+ negated,
161407
+ unresolved: true,
161408
+ label: labelOf(owner, kind, text)
161409
+ });
161410
+ return;
161411
+ }
161412
+ const body = constraintBodyOf(target, walk.resolve);
161413
+ if (!body) {
161414
+ if (REQUIREMENT_SHAPED.has(target.$type)) {
161415
+ collect(target, origin === "own" ? "subrequirement" : origin, 1, walk);
161416
+ return;
161417
+ }
161418
+ walk.out.push({
161419
+ kind,
161420
+ origin,
161421
+ host: member,
161422
+ owner: target,
161423
+ text,
161424
+ negated,
161425
+ unresolved: false,
161426
+ label: labelOf(target, kind, text)
161427
+ });
161428
+ return;
161429
+ }
161430
+ if (walk.bodies.has(body))
161431
+ return;
161432
+ walk.bodies.add(body);
161433
+ walk.out.push({
161434
+ kind,
161435
+ origin,
161436
+ host: member,
161437
+ owner: target,
161438
+ body,
161439
+ negated,
161440
+ unresolved: false,
161441
+ text,
161442
+ label: labelOf(target, kind, exprText(body))
161443
+ });
161444
+ }
161445
+ function addBody(host, body, kind, origin, owner, walk, negated = false) {
161446
+ if (walk.bodies.has(body))
161447
+ return;
161448
+ walk.bodies.add(body);
161449
+ const text = exprText(body);
161450
+ walk.out.push({
161451
+ kind,
161452
+ origin,
161453
+ host,
161454
+ owner,
161455
+ body,
161456
+ text,
161457
+ negated,
161458
+ unresolved: false,
161459
+ label: labelOf(owner, kind, text)
161460
+ });
161461
+ }
161462
+ function effectiveConstraints(req, resolve8) {
161463
+ const walk = {
161464
+ resolve: resolve8 ?? documentResolver(req),
161465
+ out: [],
161466
+ seen: /* @__PURE__ */ new Set(),
161467
+ bodies: /* @__PURE__ */ new Set()
161468
+ };
161469
+ collect(req, "own", 0, walk);
161470
+ return walk.out;
161471
+ }
161472
+ function ownSubject(node) {
161473
+ return (node.members ?? []).find((member) => member.$type === "SubjectDecl");
161474
+ }
161475
+ function subjectTypeName(subject) {
161476
+ const ref = subject?.typing?.type;
161477
+ const text = ref?.$refText?.trim() ?? ref?.ref?.name;
161478
+ return text || void 0;
161479
+ }
161480
+ function subjectInfo(subject, owner, origin) {
161481
+ return {
161482
+ declaration: subject,
161483
+ name: subject.name,
161484
+ typeName: subjectTypeName(subject) ?? DEFAULT_SUBJECT_TYPE,
161485
+ origin,
161486
+ owner
161487
+ };
161488
+ }
161489
+ function inheritedSubject(node, resolve8, depth, seen) {
161490
+ if (depth > MAX_INHERITANCE_DEPTH || seen.has(node))
161491
+ return void 0;
161492
+ seen.add(node);
161493
+ for (const supertype of supertypesOf(node, resolve8)) {
161494
+ if (!SUBJECT_SHAPED.has(supertype.$type))
161495
+ continue;
161496
+ const own = ownSubject(supertype);
161497
+ if (own)
161498
+ return subjectInfo(own, supertype, "inherited");
161499
+ const deeper = inheritedSubject(supertype, resolve8, depth + 1, seen);
161500
+ if (deeper)
161501
+ return deeper;
161502
+ }
161503
+ return void 0;
161504
+ }
161505
+ function effectiveSubject(req, resolve8) {
161506
+ const node = req;
161507
+ const resolver = resolve8 ?? documentResolver(req);
161508
+ const own = ownSubject(node);
161509
+ if (own)
161510
+ return subjectInfo(own, node, "own");
161511
+ const inherited = inheritedSubject(node, resolver, 0, /* @__PURE__ */ new Set());
161512
+ if (inherited)
161513
+ return inherited;
161514
+ let container = node.$container;
161515
+ while (container) {
161516
+ if (REQUIREMENT_SHAPED.has(container.$type)) {
161517
+ const enclosing = ownSubject(container);
161518
+ if (enclosing)
161519
+ return subjectInfo(enclosing, container, "enclosing");
161520
+ const above = inheritedSubject(container, resolver, 0, /* @__PURE__ */ new Set());
161521
+ if (above)
161522
+ return { ...above, origin: "enclosing" };
161523
+ }
161524
+ container = container.$container;
161525
+ }
161526
+ return { typeName: DEFAULT_SUBJECT_TYPE, origin: "default" };
161527
+ }
161528
+ function effectiveRequirement(req, resolve8) {
161529
+ const resolver = resolve8 ?? documentResolver(req);
161530
+ return {
161531
+ constraints: effectiveConstraints(req, resolver),
161532
+ subject: effectiveSubject(req, resolver)
161533
+ };
161534
+ }
161535
+ var SATISFIER_SHAPED = /* @__PURE__ */ new Set([
161536
+ "PartDecl",
161537
+ "ItemDecl",
161538
+ "OccurrenceDecl",
161539
+ "ActionDecl",
161540
+ "StateDecl",
161541
+ "PortDecl",
161542
+ "AttributeDecl",
161543
+ "EnumDecl",
161544
+ "ConnectionDecl",
161545
+ "InterfaceDecl",
161546
+ "AllocationDecl",
161547
+ "UseCaseDecl",
161548
+ "CaseDecl",
161549
+ "AnalysisCaseDecl",
161550
+ "VerificationCaseDecl",
161551
+ "ViewDecl",
161552
+ "CalcDecl",
161553
+ "ConstraintDecl",
161554
+ "RequirementDecl",
161555
+ "ConcernDecl",
161556
+ "ObjectiveDecl",
161557
+ "ViewpointDecl",
161558
+ "RenderingDecl",
161559
+ "EventDecl"
161560
+ ]);
161561
+ function bindingSimpleName(by) {
161562
+ const node = by;
161563
+ if (!node)
161564
+ return void 0;
161565
+ if (node.$type === "ParenExpr") {
161566
+ const items = node.items ?? [];
161567
+ return items.length === 1 ? bindingSimpleName(items[0]) : void 0;
161568
+ }
161569
+ if (node.$type !== "PathExpr")
161570
+ return void 0;
161571
+ const last2 = node.path?.split(/::|\./u).pop();
161572
+ return last2 || void 0;
161573
+ }
161574
+ function satisfyIntentOf(stmt) {
161575
+ const node = stmt;
161576
+ if (node.$type !== "SatisfyStmt")
161577
+ return void 0;
161578
+ const path10 = referencePathOf(node);
161579
+ if (!path10)
161580
+ return void 0;
161581
+ const byName = bindingSimpleName(node.by);
161582
+ let enclosing;
161583
+ let container = node.$container;
161584
+ while (container && !enclosing) {
161585
+ if (SATISFIER_SHAPED.has(container.$type) && container.isDef !== true)
161586
+ enclosing = container;
161587
+ container = container.$container;
161588
+ }
161589
+ return {
161590
+ path: path10,
161591
+ simple: simpleName(path10),
161592
+ negated: node.isNegated === true,
161593
+ byName,
161594
+ // The presence of a `by`, not whether its expression could be named,
161595
+ // decides this. A `by` this reader cannot name is still a stated
161596
+ // satisfier, and reading it as the enclosing usage would evaluate and
161597
+ // check something the model never claimed.
161598
+ enclosingSelf: node.by === void 0,
161599
+ enclosing
161600
+ };
161601
+ }
161602
+
161057
161603
  // ../language-server/out/src/services/requirement-eval.js
161058
161604
  var UNRESOLVED = { kind: "unresolved" };
161059
161605
  var INCONCLUSIVE = { kind: "inconclusive" };
@@ -161269,7 +161815,7 @@ function memberNamed(node, name, seen = /* @__PURE__ */ new Set()) {
161269
161815
  const typeRef = node.typing?.type?.ref;
161270
161816
  return typeRef ? memberNamed(typeRef, name, seen) : void 0;
161271
161817
  }
161272
- function resolveFeatureValue(root4, segments) {
161818
+ function resolveFeatureValue(root4, segments, ext) {
161273
161819
  let cur = root4;
161274
161820
  for (const seg of segments) {
161275
161821
  cur = memberNamed(cur, seg);
@@ -161277,7 +161823,7 @@ function resolveFeatureValue(root4, segments) {
161277
161823
  return UNRESOLVED;
161278
161824
  }
161279
161825
  if (cur.value)
161280
- return evaluateExpr(cur.value, () => INCONCLUSIVE);
161826
+ return evaluateExpr(cur.value, () => INCONCLUSIVE, ext);
161281
161827
  return INCONCLUSIVE;
161282
161828
  }
161283
161829
  function subjectScope(subjectName, subjectBinding) {
@@ -161294,36 +161840,40 @@ function subjectScope(subjectName, subjectBinding) {
161294
161840
  return resolveFeatureValue(binding, segments);
161295
161841
  };
161296
161842
  }
161297
- function subjectNameOf(req) {
161298
- const subject = (req.members ?? []).find((m) => m.$type === "SubjectDecl");
161299
- return subject?.name;
161300
- }
161301
- function gatherConstraints(req) {
161302
- const out = [];
161303
- for (const member of req.members ?? []) {
161304
- if (member.$type === "RequireConstraintStmt" && member.body) {
161305
- out.push({ kind: "require", body: member.body, text: exprText(member.body) });
161306
- } else if (member.$type === "AssumeConstraintStmt" && member.body) {
161307
- out.push({ kind: "assume", body: member.body, text: exprText(member.body) });
161843
+ function constraintScope(entry, evaluated, outer) {
161844
+ const owners = [entry.host, evaluated, entry.owner];
161845
+ return (segments, expression) => {
161846
+ for (const owner of owners) {
161847
+ if (!owner)
161848
+ continue;
161849
+ const value = resolveFeatureValue(owner, segments);
161850
+ if (value.kind !== "unresolved" && value.kind !== "inconclusive")
161851
+ return value;
161308
161852
  }
161309
- }
161310
- return out;
161853
+ return outer(segments, expression);
161854
+ };
161311
161855
  }
161312
- function exprText(node) {
161313
- return node.$cstNode?.text?.trim() ?? "";
161856
+ function negate2(value, negated) {
161857
+ if (!negated || value.kind !== "boolean")
161858
+ return value;
161859
+ return { kind: "boolean", value: !value.value };
161314
161860
  }
161315
- function evaluateRequirement(req, subjectBinding) {
161316
- const requirement = req;
161317
- const subjectName = subjectNameOf(requirement);
161318
- const scope = subjectScope(subjectName, subjectBinding);
161319
- const constraints = gatherConstraints(requirement);
161861
+ function evaluateRequirement(req, subjectBinding, resolve8) {
161862
+ const effective = effectiveRequirement(req, resolve8);
161863
+ const scope = subjectScope(effective.subject.name, subjectBinding);
161320
161864
  const details = [];
161321
161865
  let sawInconclusive = false;
161322
161866
  let sawUnresolved = false;
161323
161867
  let failed = false;
161324
- for (const c of constraints) {
161325
- const v = evaluateExpr(c.body, scope);
161868
+ for (const c of effective.constraints) {
161326
161869
  let status2;
161870
+ if (c.unresolved) {
161871
+ status2 = "unresolved";
161872
+ sawUnresolved = true;
161873
+ details.push({ kind: c.kind, status: status2, text: c.text, origin: c.origin, label: c.label });
161874
+ continue;
161875
+ }
161876
+ const v = negate2(evaluateExpr(c.body, constraintScope(c, req, scope)), c.negated);
161327
161877
  if (v.kind === "unresolved") {
161328
161878
  status2 = "unresolved";
161329
161879
  sawUnresolved = true;
@@ -161339,10 +161889,10 @@ function evaluateRequirement(req, subjectBinding) {
161339
161889
  status2 = "inconclusive";
161340
161890
  sawInconclusive = true;
161341
161891
  }
161342
- details.push({ kind: c.kind, status: status2, text: c.text });
161892
+ details.push({ kind: c.kind, status: status2, text: c.text, origin: c.origin, label: c.label });
161343
161893
  }
161344
161894
  let status;
161345
- if (constraints.length === 0)
161895
+ if (effective.constraints.length === 0)
161346
161896
  status = "inconclusive";
161347
161897
  else if (failed)
161348
161898
  status = "fail";
@@ -161354,6 +161904,97 @@ function evaluateRequirement(req, subjectBinding) {
161354
161904
  status = "pass";
161355
161905
  return { status, details };
161356
161906
  }
161907
+ function evaluateSatisfy(stmt, resolveRequirement, resolvePart, resolve8) {
161908
+ const intent = satisfyIntentOf(stmt);
161909
+ if (!intent)
161910
+ return { status: "unresolved" };
161911
+ const requirement = resolveRequirement(intent.simple);
161912
+ if (!requirement)
161913
+ return { status: "unresolved" };
161914
+ const satisfier = intent.enclosingSelf ? intent.enclosing : intent.byName ? resolvePart(intent.byName) : void 0;
161915
+ const result = evaluateRequirement(requirement, satisfier, resolve8);
161916
+ if (!intent.negated)
161917
+ return { status: result.status, requirement, satisfier };
161918
+ const status = result.status === "pass" ? "fail" : result.status === "fail" ? "pass" : result.status;
161919
+ return { status, requirement, satisfier };
161920
+ }
161921
+ var CONSTRAINT_SHAPED_TYPES = /* @__PURE__ */ new Set([
161922
+ "ConstraintDecl",
161923
+ "InvShorthand",
161924
+ "RequirementDecl",
161925
+ "ConcernDecl",
161926
+ "PredicateDecl",
161927
+ "AssertConstraintStmt",
161928
+ "RequireConstraintStmt",
161929
+ "AssumeConstraintStmt"
161930
+ ]);
161931
+ function exprText2(node) {
161932
+ return node?.$cstNode?.text?.trim() ?? "";
161933
+ }
161934
+ function rootOf2(node) {
161935
+ let current2 = node;
161936
+ while (current2.$container)
161937
+ current2 = current2.$container;
161938
+ return current2;
161939
+ }
161940
+ function* walkMembers(node) {
161941
+ for (const member of [...node.elements ?? [], ...node.members ?? []]) {
161942
+ yield member;
161943
+ yield* walkMembers(member);
161944
+ }
161945
+ }
161946
+ function documentConstraintResolver() {
161947
+ return (reference, member) => {
161948
+ for (const candidate of walkMembers(rootOf2(member))) {
161949
+ if (candidate.name === reference.simpleName && CONSTRAINT_SHAPED_TYPES.has(candidate.$type)) {
161950
+ return candidate;
161951
+ }
161952
+ }
161953
+ return void 0;
161954
+ };
161955
+ }
161956
+ var assertionExpression = (node) => {
161957
+ const expr = node;
161958
+ return (expr.$type === "NumericPrimary" || expr.$type === "PostfixOp") && expr.unit ? INCONCLUSIVE : void 0;
161959
+ };
161960
+ function evaluateAssertion(node, resolveConstraint = documentConstraintResolver()) {
161961
+ const member = node;
161962
+ if (member.$type !== "AssertConstraintStmt")
161963
+ return void 0;
161964
+ const reference = constraintReferenceOf(member);
161965
+ const negated = reference?.negated ?? member.isNegated === true;
161966
+ let body;
161967
+ let text;
161968
+ let target;
161969
+ if (reference) {
161970
+ text = `${reference.kind}${reference.negated ? " not" : ""} ${reference.path}`;
161971
+ target = resolveConstraint(reference, member);
161972
+ if (!target)
161973
+ return { status: "unresolved", text };
161974
+ body = member.body ?? constraintBodyOf(target, documentResolver(member));
161975
+ } else {
161976
+ body = member.body;
161977
+ text = exprText2(member.body);
161978
+ }
161979
+ if (!body)
161980
+ return { status: "inconclusive", text };
161981
+ const scope = (segments) => {
161982
+ for (const owner of [member, target]) {
161983
+ if (!owner)
161984
+ continue;
161985
+ if (memberNamed(owner, segments[0])) {
161986
+ return resolveFeatureValue(owner, segments, assertionExpression);
161987
+ }
161988
+ }
161989
+ return INCONCLUSIVE;
161990
+ };
161991
+ const value = negate2(evaluateExpr(body, scope, assertionExpression), negated);
161992
+ if (value.kind === "unresolved")
161993
+ return { status: "unresolved", text };
161994
+ if (value.kind !== "boolean")
161995
+ return { status: "inconclusive", text };
161996
+ return { status: value.value ? "pass" : "fail", text };
161997
+ }
161357
161998
  function bindingName(by) {
161358
161999
  const n2 = by;
161359
162000
  if (n2?.$type !== "PathExpr")
@@ -162533,14 +163174,14 @@ function isPublic(node) {
162533
163174
  }
162534
163175
  return true;
162535
163176
  }
162536
- var SPECIALIZATION_KINDS = /* @__PURE__ */ new Set([":>", ":>>", "specializes", "subsets", "redefines"]);
163177
+ var SPECIALIZATION_KINDS2 = /* @__PURE__ */ new Set([":>", ":>>", "specializes", "subsets", "redefines"]);
162537
163178
  var inheritanceByNode = /* @__PURE__ */ new WeakMap();
162538
163179
  function inheritanceSyntax(node) {
162539
163180
  const cached = inheritanceByNode.get(node);
162540
163181
  if (cached)
162541
163182
  return cached;
162542
163183
  const shape = node;
162543
- const relationships = [...shape.preRelationships ?? [], ...shape.relationships ?? []].filter((relation) => relation.kind && SPECIALIZATION_KINDS.has(relation.kind));
163184
+ const relationships = [...shape.preRelationships ?? [], ...shape.relationships ?? []].filter((relation) => relation.kind && SPECIALIZATION_KINDS2.has(relation.kind));
162544
163185
  const implicitVariant = implicitVariantSpecialization(node)?.target;
162545
163186
  const externalVariant = !!externalVariantPath(node);
162546
163187
  const enumUsage = node.$type === "EnumDecl" && shape.isDef !== true;
@@ -162602,6 +163243,21 @@ function unwrap(node) {
162602
163243
  }
162603
163244
  var namedChildrenByNode = /* @__PURE__ */ new WeakMap();
162604
163245
  var childrenByName = /* @__PURE__ */ new WeakMap();
163246
+ var REFERENCE_FORM_DECLARATIONS = {
163247
+ PerformStmt: "actionKw",
163248
+ EntryAction: "actionKw",
163249
+ DoAction: "actionKw",
163250
+ ExitAction: "actionKw",
163251
+ ExhibitStateDecl: "stateKw",
163252
+ AssertConstraintStmt: "constraintKw",
163253
+ EventDecl: "isOccurrence"
163254
+ };
163255
+ function isReferenceFormDeclaration(node) {
163256
+ const keyword = REFERENCE_FORM_DECLARATIONS[node.$type];
163257
+ if (!keyword)
163258
+ return false;
163259
+ return node[keyword] !== true;
163260
+ }
162605
163261
  function directNamedChildren(node) {
162606
163262
  const cached = namedChildrenByNode.get(node);
162607
163263
  if (cached)
@@ -162610,6 +163266,8 @@ function directNamedChildren(node) {
162610
163266
  const seen = /* @__PURE__ */ new Set();
162611
163267
  for (const raw of ast_utils_exports.streamContents(node)) {
162612
163268
  const child = unwrap(raw);
163269
+ if (isReferenceFormDeclaration(child))
163270
+ continue;
162613
163271
  if (!nameOf(child) || seen.has(child))
162614
163272
  continue;
162615
163273
  seen.add(child);
@@ -163091,7 +163749,7 @@ var FeaturePathResolver = class {
163091
163749
  }
163092
163750
  for (let owner = node.$container; owner; owner = owner.$container) {
163093
163751
  const declaredName3 = owner.name;
163094
- if (typeof declaredName3 === "string" && canonicalEscapedName(declaredName3) === name && !isSelfReference(owner, node)) {
163752
+ if (typeof declaredName3 === "string" && canonicalEscapedName(declaredName3) === name && !isReferenceFormDeclaration(owner) && !isSelfReference(owner, node)) {
163095
163753
  return this.targetForNode(owner, this.memberInventoryKnown(owner, snapshot));
163096
163754
  }
163097
163755
  if (boundVariableName(owner) === name) {
@@ -163162,7 +163820,7 @@ var FeaturePathResolver = class {
163162
163820
  const declared = [
163163
163821
  ...record.preRelationships ?? [],
163164
163822
  ...record.relationships ?? []
163165
- ].filter((relation) => relation !== under && relation.kind && SPECIALIZATION_KINDS.has(relation.kind));
163823
+ ].filter((relation) => relation !== under && relation.kind && SPECIALIZATION_KINDS2.has(relation.kind));
163166
163824
  if (declared.length === 0)
163167
163825
  return true;
163168
163826
  const written = declared.reduce((total, relation) => total + (relation.targets?.length ?? 0), 0);
@@ -163557,7 +164215,7 @@ function memberSeparator(owner) {
163557
164215
  function unquoteName(name) {
163558
164216
  return name.replace(/^'(.*)'$/u, "$1");
163559
164217
  }
163560
- function pathSegments(path10) {
164218
+ function pathSegments2(path10) {
163561
164219
  const segments = [];
163562
164220
  let current2 = "";
163563
164221
  let quoted = false;
@@ -163585,7 +164243,7 @@ function pathSegments(path10) {
163585
164243
  return segments;
163586
164244
  }
163587
164245
  function simpleNameOf(name) {
163588
- return pathSegments(name).at(-1) ?? name;
164246
+ return pathSegments2(name).at(-1) ?? name;
163589
164247
  }
163590
164248
  var ELEMENT_SEPARATOR = "\0";
163591
164249
  function elementKey(description) {
@@ -163595,7 +164253,7 @@ function isDeclaredSpelling(description) {
163595
164253
  const kind = description.derivedKind;
163596
164254
  if (kind === "reexport" || kind === "inherited")
163597
164255
  return false;
163598
- return pathSegments(description.name).length === 1;
164256
+ return pathSegments2(description.name).length === 1;
163599
164257
  }
163600
164258
  var SysmlNameLookup = class {
163601
164259
  shared;
@@ -163705,7 +164363,7 @@ function nameLookupFor(shared) {
163705
164363
  }
163706
164364
 
163707
164365
  // ../language-server/out/src/services/effective-name.js
163708
- var REDEFINITION_KINDS = /* @__PURE__ */ new Set([":>>", "redefines"]);
164366
+ var REDEFINITION_KINDS2 = /* @__PURE__ */ new Set([":>>", "redefines"]);
163709
164367
  var NO_CANDIDATES = [];
163710
164368
  var NO_RESOLVER = () => NO_CANDIDATES;
163711
164369
  var nameable = /* @__PURE__ */ new Map();
@@ -163739,7 +164397,7 @@ function firstRedefinitionPath(node) {
163739
164397
  for (const relationship of group) {
163740
164398
  if (typeof relationship?.kind !== "string")
163741
164399
  continue;
163742
- if (!REDEFINITION_KINDS.has(relationship.kind))
164400
+ if (!REDEFINITION_KINDS2.has(relationship.kind))
163743
164401
  continue;
163744
164402
  const targets = relationship.targets;
163745
164403
  if (!Array.isArray(targets))
@@ -164784,7 +165442,7 @@ function nearestUnits(symbol, limit) {
164784
165442
  }
164785
165443
 
164786
165444
  // ../language-server/out/src/services/conformance.js
164787
- var SPECIALIZATION_KINDS2 = /* @__PURE__ */ new Set([
165445
+ var SPECIALIZATION_KINDS3 = /* @__PURE__ */ new Set([
164788
165446
  ":>",
164789
165447
  ":>>",
164790
165448
  "specializes",
@@ -164816,7 +165474,7 @@ function specializedNamesOf(node) {
164816
165474
  const decl = node;
164817
165475
  const out = [];
164818
165476
  for (const rel2 of [...decl.preRelationships ?? [], ...decl.relationships ?? []]) {
164819
- if (!rel2.kind || !SPECIALIZATION_KINDS2.has(rel2.kind))
165477
+ if (!rel2.kind || !SPECIALIZATION_KINDS3.has(rel2.kind))
164820
165478
  continue;
164821
165479
  for (const target of rel2.targets ?? []) {
164822
165480
  const text = target.trim();
@@ -165491,7 +166149,7 @@ function owningOccurrenceOf(node) {
165491
166149
  return NON_OCCURRENCE_DECL_TYPES.has(owner.$type) ? void 0 : owner;
165492
166150
  }
165493
166151
  var MAX_ALIAS_HOPS = 8;
165494
- var SPECIALIZATION_KINDS3 = /* @__PURE__ */ new Set([
166152
+ var SPECIALIZATION_KINDS4 = /* @__PURE__ */ new Set([
165495
166153
  ":>",
165496
166154
  "subsets",
165497
166155
  ":>>",
@@ -165503,7 +166161,7 @@ function specializationTargetsOf(node) {
165503
166161
  const decl = node;
165504
166162
  const out = [];
165505
166163
  for (const rel2 of [...decl.preRelationships ?? [], ...decl.relationships ?? []]) {
165506
- if (!rel2.kind || !SPECIALIZATION_KINDS3.has(rel2.kind))
166164
+ if (!rel2.kind || !SPECIALIZATION_KINDS4.has(rel2.kind))
165507
166165
  continue;
165508
166166
  for (const target of rel2.targets ?? []) {
165509
166167
  const text = target.trim();
@@ -165907,6 +166565,16 @@ var directionOf = (node) => {
165907
166565
  return void 0;
165908
166566
  return mods.find((m) => m === "in" || m === "out" || m === "inout");
165909
166567
  };
166568
+ function parameterKeyword(node) {
166569
+ const direction = directionOf(node);
166570
+ if (!direction)
166571
+ return void 0;
166572
+ let owner = node.$container;
166573
+ while (owner?.$type === "PrefixMetadataMember" || owner?.$type === "MemberPrefixDecl") {
166574
+ owner = owner.$container;
166575
+ }
166576
+ return owner && (isConstraintDecl(owner) || isCalcDecl(owner)) ? `${direction} parameter` : void 0;
166577
+ }
165910
166578
  function keywordFor(node) {
165911
166579
  const n2 = node;
165912
166580
  if (node.$type === "VariantReference")
@@ -165968,6 +166636,9 @@ function keywordFor(node) {
165968
166636
  DoAction: "do action",
165969
166637
  ExitAction: "exit action"
165970
166638
  };
166639
+ const parameter = parameterKeyword(node);
166640
+ if (parameter)
166641
+ return parameter;
165971
166642
  if (t === "ActionDecl" && n2.inlineBody?.$type === "AcceptNode") {
165972
166643
  return "accept action";
165973
166644
  }
@@ -167445,6 +168116,19 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
167445
168116
  const all = [...ast_utils_exports.streamAllContents(scope)];
167446
168117
  const annotationNodes = all.filter(isGvAnnotationNode);
167447
168118
  const annotationNodeSet = new Set(annotationNodes);
168119
+ const declaredOwnerOf = (node) => {
168120
+ let owner = node.$container;
168121
+ while (owner?.$type === "PrefixMetadataMember" || owner?.$type === "MemberPrefixDecl") {
168122
+ owner = owner.$container;
168123
+ }
168124
+ return owner;
168125
+ };
168126
+ const isDefinitionParameter = (node) => {
168127
+ if (directionOf(node) === void 0)
168128
+ return false;
168129
+ const owner = declaredOwnerOf(node);
168130
+ return !!owner && owner.isDef === true && (isConstraintDecl(owner) || isCalcDecl(owner));
168131
+ };
167448
168132
  const usageNodes = all.filter(isGvExplicitUsage);
167449
168133
  const usageNodeSet = new Set(usageNodes);
167450
168134
  const usageDefinitions = new Map(usageNodes.map((node) => [
@@ -167483,7 +168167,20 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
167483
168167
  semanticOwners.set(member, found);
167484
168168
  return found;
167485
168169
  };
168170
+ const readsAsAttribute = (node) => isAttributeDecl(node) || isAttributeDecl(this.resolveType(node, index2));
168171
+ const implicitlyRedefined = (node) => {
168172
+ const name = nameOf2(node);
168173
+ const owner = semanticOwner(node);
168174
+ if (!name || !owner || owner.isDef === true)
168175
+ return void 0;
168176
+ const definition = usageDefinitions.get(owner);
168177
+ if (!definition)
168178
+ return void 0;
168179
+ return membersOf(definition).find((member) => nameOf2(member) === name);
168180
+ };
167486
168181
  const attributeUsages = new Set(usageNodes.filter((node) => {
168182
+ if (isDefinitionParameter(node))
168183
+ return false;
167487
168184
  if (isAttributeDecl(node))
167488
168185
  return true;
167489
168186
  const owner = semanticOwner(node);
@@ -167494,12 +168191,23 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
167494
168191
  const definition = usageDefinitions.get(node);
167495
168192
  if (definition && isAttributeDecl(definition))
167496
168193
  return true;
167497
- return redefinitionTargetsOf(node).some((target) => {
168194
+ if (redefinitionTargetsOf(node).some((target) => {
167498
168195
  const inherited = this.resolveFeatureInheritanceTarget(node, target, index2, /* @__PURE__ */ new Set());
167499
168196
  return inherited && isAttributeDecl(inherited);
167500
- });
168197
+ }))
168198
+ return true;
168199
+ const implicit = implicitlyRedefined(node);
168200
+ return !!implicit && readsAsAttribute(implicit);
167501
168201
  }));
167502
168202
  const attributeValue = (node) => valueTextOf(node) ?? node.default?.value?.$cstNode?.text ?? "";
168203
+ const returnMemberOf = (node) => membersOf(node).find((m) => m.$type === "ReturnDecl");
168204
+ const expressionBody = (node) => {
168205
+ const ret = isCalcDecl(node) ? returnMemberOf(node) : void 0;
168206
+ const text = ret ? valueTextOf(ret) ?? "" : node.body?.$cstNode?.text ?? "";
168207
+ return text.replace(/\s+/g, " ").trim();
168208
+ };
168209
+ const declaresExpression = (node) => node.body !== void 0 || isCalcDecl(node) && valueTextOf(returnMemberOf(node)) !== void 0;
168210
+ const showsExpressionField = (node) => (isConstraintDecl(node) || isCalcDecl(node)) && (node.isDef === true || declaresExpression(node));
167503
168211
  const ids = /* @__PURE__ */ new Map();
167504
168212
  const unnamedOrdinals = /* @__PURE__ */ new Map();
167505
168213
  const semanticId = (node) => {
@@ -167555,6 +168263,8 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
167555
168263
  multiplicity: this.multText(n2),
167556
168264
  type: typeText(n2) ?? (usageDefinitions.get(n2) ? nameOf2(usageDefinitions.get(n2)) : void 0),
167557
168265
  ...attributeUsages.has(n2) ? { value: attributeValue(n2) } : {},
168266
+ // REQ-208/209 — the constraint or calculation expression field.
168267
+ ...showsExpressionField(n2) ? { value: expressionBody(n2) } : {},
167558
168268
  compartments: extra?.compartments ?? this.compartmentsFor(n2, uri, index2, shape === "box"),
167559
168269
  ...packageOf2(n2),
167560
168270
  source: sourceOf2(n2, uri),
@@ -167569,9 +168279,60 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
167569
168279
  for (const usage of usageNodes) {
167570
168280
  pushNode(usage, "box", false, {
167571
168281
  compartments: this.compartmentsFor(usage, uri, index2, true, false),
167572
- ...attributeUsages.has(usage) ? { keyword: "attribute" } : {}
168282
+ // REQ-376 a parameter keeps its own banner; only an ordinary
168283
+ // attribute usage is relabelled by its value-carrying role.
168284
+ ...attributeUsages.has(usage) && !parameterKeyword(usage) ? { keyword: "attribute" } : {}
167573
168285
  });
167574
168286
  }
168287
+ for (const usage of usageNodes) {
168288
+ if (!isConstraintDecl(usage) || usage.isDef === true)
168289
+ continue;
168290
+ const definition = usageDefinitions.get(usage);
168291
+ if (!definition || !isConstraintDecl(definition))
168292
+ continue;
168293
+ const usageId = semanticId(usage);
168294
+ const local = new Set(membersOf(usage).flatMap((member) => [nameOf2(member), ...redefinitionTargetsOf(member)]).filter((name) => !!name));
168295
+ for (const member of membersOf(definition)) {
168296
+ const name = nameOf2(member);
168297
+ if (!name || local.has(name))
168298
+ continue;
168299
+ if (directionOf(member) === void 0 && !isAttributeDecl(member))
168300
+ continue;
168301
+ const id2 = `${usageId}::${name}`;
168302
+ if (nodes.some((existing) => existing.id === id2))
168303
+ continue;
168304
+ nodes.push({
168305
+ id: id2,
168306
+ name: effectiveNameOf(member) ?? name,
168307
+ keyword: "attribute",
168308
+ isDef: false,
168309
+ shape: "box",
168310
+ multiplicity: this.multText(member),
168311
+ type: typeText(member),
168312
+ value: attributeValue(member),
168313
+ compartments: [],
168314
+ parent: usageId,
168315
+ // Navigation lands on the declaration the member comes from.
168316
+ source: sourceOf2(member, uri),
168317
+ meta: {
168318
+ gvUsage: true,
168319
+ gvOwnerId: usageId,
168320
+ gvExplicit: true,
168321
+ gvDeclaredName: name,
168322
+ gvDeclaredType: typeText(member) ?? "",
168323
+ // REQ-364 — the concrete usage that owns a local edit, plus
168324
+ // the relative redefinition path to write inside it.
168325
+ localUsageId: usageId,
168326
+ localUsageName: nameOf2(usage),
168327
+ localUsageSource: sourceOf2(usage, uri),
168328
+ localUsagePath: [name],
168329
+ expandedFromDefinition: true,
168330
+ declarationId: qnameOf(member),
168331
+ declarationSource: sourceOf2(member, uri)
168332
+ }
168333
+ });
168334
+ }
168335
+ }
167575
168336
  for (const p of packageNodes) {
167576
168337
  const pn = p;
167577
168338
  pushNode(p, "package", false, {
@@ -167888,6 +168649,28 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
167888
168649
  }
167889
168650
  }
167890
168651
  }
168652
+ const CLAIM_EDGE_KINDS = {
168653
+ AssertConstraintStmt: "assert",
168654
+ AssumeConstraintStmt: "assume",
168655
+ RequireConstraintStmt: "require"
168656
+ };
168657
+ for (const owner of [...defNodes, ...usageNodes]) {
168658
+ for (const m of membersOf(owner)) {
168659
+ const claim = CLAIM_EDGE_KINDS[m.$type];
168660
+ if (!claim)
168661
+ continue;
168662
+ const negated = m.isNegated === true;
168663
+ const label = `\xAB${claim}${negated ? " not" : ""}\xBB`;
168664
+ const reference = constraintReferenceOf(m);
168665
+ if (reference) {
168666
+ linkByName(claim, owner, reference.path, label, m);
168667
+ continue;
168668
+ }
168669
+ const typed = typeText(m);
168670
+ if (typed)
168671
+ linkByName(claim, owner, typed, label, m);
168672
+ }
168673
+ }
167891
168674
  const allocPairs = [
167892
168675
  ...all.filter((m) => m.$type === "AllocateStmt").map((a2) => ({
167893
168676
  from: String(a2.source ?? ""),
@@ -168729,16 +169512,16 @@ ${node.id}`;
168729
169512
  };
168730
169513
  const performedActions = depth < 8 && !(typeQ !== void 0 && seenTypes.has(typeQ)) ? effectiveMembersOf(part).filter((m) => m.$type === "PerformStmt" && !!nameOf2(m)).map((act) => {
168731
169514
  const pinSource = this.performTargetOf(act, index2) ?? act;
168732
- const pathSegments3 = this.isAnonymousBehaviorReference(act) ? this.featurePaths.resolveDeclarationPath(act).segments.map((segment) => segment.text) : [nameOf2(act)];
169515
+ const pathSegments4 = this.isAnonymousBehaviorReference(act) ? this.featurePaths.resolveDeclarationPath(act).segments.map((segment) => segment.text) : [nameOf2(act)];
168733
169516
  return {
168734
169517
  act,
168735
169518
  pinSource,
168736
- pathSegments: pathSegments3,
168737
- name: pathSegments3.at(-1) ?? nameOf2(act),
169519
+ pathSegments: pathSegments4,
169520
+ name: pathSegments4.at(-1) ?? nameOf2(act),
168738
169521
  key: concretePerformPath(act, pinSource)
168739
169522
  };
168740
169523
  }).filter((entry, i, list) => list.findIndex((other) => other.key === entry.key) === i) : [];
168741
- const performedActionInfos = performedActions.map(({ act, pinSource, pathSegments: pathSegments3, name, key: key2 }) => {
169524
+ const performedActionInfos = performedActions.map(({ act, pinSource, pathSegments: pathSegments4, name, key: key2 }) => {
168742
169525
  const id2 = `${instanceId}::__perform_${key2}`;
168743
169526
  const inheritedFromDefinition = !!localUsage && !isAstDescendantOrSelf(act, localUsage);
168744
169527
  const syncDeclaration2 = this.synchronizationDeclarationOf(act, index2);
@@ -168746,7 +169529,7 @@ ${node.id}`;
168746
169529
  act,
168747
169530
  name,
168748
169531
  id: id2,
168749
- pathSegments: pathSegments3,
169532
+ pathSegments: pathSegments4,
168750
169533
  pins: this.actionPinPorts(pinSource, id2, index2, uri),
168751
169534
  meta: {
168752
169535
  ...ivEditMeta(act, id2, void 0, localUsage, [...localPath, name], uri),
@@ -171954,7 +172737,12 @@ ${node.id}`;
171954
172737
  idOf.set(n2, id2);
171955
172738
  nodes.push({
171956
172739
  id: id2,
171957
- name: nameOf2(n2) ?? lastSeg(typeText(n2) ?? "subject"),
172740
+ // REQ-404 — a redeclaration (`actor :>> driver = …`) writes no name
172741
+ // of its own; the name it is KNOWN BY is the one it redefines, which
172742
+ // is the same derivation the rest of the model is labelled by. The
172743
+ // last-resort fallback is the SHAPE, never the literal 'subject':
172744
+ // that string labelled every unnamed actor "subject" on the card.
172745
+ name: effectiveNameOf(n2) ?? lastSeg(typeText(n2) ?? shape),
171958
172746
  keyword: keywordFor(n2),
171959
172747
  isDef: n2.isDef === true,
171960
172748
  shape,
@@ -171998,14 +172786,15 @@ ${node.id}`;
171998
172786
  const declarationKey = (subject) => {
171999
172787
  const type = this.resolveType(subject, index2);
172000
172788
  const typeKey = (type ? qnameOf(type) : void 0) || typeText(subject) || "";
172001
- const name = nameOf2(subject) ?? "";
172789
+ const name = effectiveNameOf(subject) ?? "";
172002
172790
  return name || typeKey ? `subject:${name}|${typeKey}` : "";
172003
172791
  };
172004
172792
  const declarationText = (subject) => {
172005
172793
  const value = subjectValuePath(subject);
172006
172794
  const type = typeText(subject);
172007
- return [nameOf2(subject), type ? `: ${type}` : void 0, value ? `= ${value}` : void 0].filter((part) => !!part).join(" ");
172795
+ return [effectiveNameOf(subject), type ? `: ${type}` : void 0, value ? `= ${value}` : void 0].filter((part) => !!part).join(" ");
172008
172796
  };
172797
+ const boundKeysOfDeclaration = /* @__PURE__ */ new Map();
172009
172798
  const subjectKey = (subject, seen = /* @__PURE__ */ new Set()) => {
172010
172799
  const canonical = canonicalSubjectTarget(subject);
172011
172800
  if (canonical && isSubjectDecl(canonical) && canonical !== subject && !seen.has(canonical)) {
@@ -172014,7 +172803,14 @@ ${node.id}`;
172014
172803
  }
172015
172804
  const canonicalQName = canonical && !isSubjectDecl(canonical) ? qnameOf(canonical) : "";
172016
172805
  const value = subjectValuePath(subject);
172017
- return canonicalQName ? `target:${canonicalQName}` : value ? `value:${value}` : declarationKey(subject) || `decl:${qnameOf(subject) || `${subject.$cstNode?.offset ?? 0}:subject`}`;
172806
+ if (canonicalQName)
172807
+ return `target:${canonicalQName}`;
172808
+ if (value)
172809
+ return `value:${value}`;
172810
+ const adopted = boundKeysOfDeclaration.get(subject);
172811
+ if (adopted?.size === 1)
172812
+ return [...adopted][0];
172813
+ return declarationKey(subject) || `decl:${qnameOf(subject) || `${subject.$cstNode?.offset ?? 0}:subject`}`;
172018
172814
  };
172019
172815
  const subjectIdByKey = /* @__PURE__ */ new Map();
172020
172816
  const subjectOfCase = /* @__PURE__ */ new Map();
@@ -172025,7 +172821,7 @@ ${node.id}`;
172025
172821
  const key2 = subjectKey(subject);
172026
172822
  let sid = subjectIdByKey.get(key2);
172027
172823
  if (!sid) {
172028
- const label = nameOf2(identity6) ?? lastSeg(value || typeText(identity6) || "subject");
172824
+ const label = effectiveNameOf(identity6) ?? lastSeg(value || typeText(identity6) || "subject");
172029
172825
  add(identity6, "subject", {
172030
172826
  id: `${scopeId}::__cv_subject__::${key2}`,
172031
172827
  name: label,
@@ -172037,6 +172833,26 @@ ${node.id}`;
172037
172833
  idOf.set(subject, sid);
172038
172834
  return sid;
172039
172835
  };
172836
+ for (const c of displayedCases) {
172837
+ const declared = declaredMembers(c).filter(isSubjectDecl);
172838
+ for (const bound of declared) {
172839
+ if (!subjectValuePath(bound))
172840
+ continue;
172841
+ const name = effectiveNameOf(bound);
172842
+ if (!name)
172843
+ continue;
172844
+ for (const target of declared) {
172845
+ if (target === bound || subjectValuePath(target))
172846
+ continue;
172847
+ if (effectiveNameOf(target) !== name)
172848
+ continue;
172849
+ let keys3 = boundKeysOfDeclaration.get(target);
172850
+ if (!keys3)
172851
+ boundKeysOfDeclaration.set(target, keys3 = /* @__PURE__ */ new Set());
172852
+ keys3.add(subjectKey(bound));
172853
+ }
172854
+ }
172855
+ }
172040
172856
  const denotesSubject = (s) => !!(nameOf2(s) || typeText(s) || subjectValuePath(s));
172041
172857
  for (const c of displayedCases) {
172042
172858
  const declared = declaredMembers(c).filter(isSubjectDecl);
@@ -172079,16 +172895,47 @@ ${node.id}`;
172079
172895
  };
172080
172896
  const actorOfCase = [];
172081
172897
  const actorCasePairs = /* @__PURE__ */ new Set();
172082
- const anonymousActorId = (actor) => nameOf2(actor) ? void 0 : `${scopeId}::__cv_actor__::${qnameOf(actor)}:${actor.$cstNode?.offset ?? 0}`;
172898
+ const actorTypeKey = (actor) => {
172899
+ const type = this.resolveType(actor, index2);
172900
+ return (type ? qnameOf(type) : void 0) || typeText(actor) || "";
172901
+ };
172902
+ const actorTypeSource = (actor, siblings) => {
172903
+ if (actorTypeKey(actor))
172904
+ return actor;
172905
+ const name = effectiveNameOf(actor);
172906
+ if (!name)
172907
+ return void 0;
172908
+ return siblings.find((sibling) => sibling !== actor && effectiveNameOf(sibling) === name && !!actorTypeKey(sibling));
172909
+ };
172910
+ const actorDeclarationKey = (actor, siblings) => {
172911
+ const name = effectiveNameOf(actor) ?? "";
172912
+ const typeKey = actorTypeKey(actorTypeSource(actor, siblings) ?? actor);
172913
+ return name || typeKey ? `actor:${name}|${typeKey}` : "";
172914
+ };
172915
+ const actorKey = (actor, siblings) => actorDeclarationKey(actor, siblings) || `decl:${qnameOf(actor) || ""}:${actor.$cstNode?.offset ?? 0}`;
172916
+ const actorIdByKey = /* @__PURE__ */ new Map();
172917
+ const addActor = (actor, siblings) => {
172918
+ const canonical = actorCanonical(actor);
172919
+ const key2 = actorKey(canonical, siblings);
172920
+ let aid = actorIdByKey.get(key2);
172921
+ if (aid === void 0) {
172922
+ const typeSource = actorTypeSource(canonical, siblings);
172923
+ add(canonical, "actor", {
172924
+ id: `${scopeId}::__cv_actor__::${key2}`,
172925
+ ...typeSource && typeSource !== canonical ? { type: typeText(typeSource) } : {},
172926
+ meta: { cvAuxiliary: true }
172927
+ });
172928
+ aid = idOf.get(canonical);
172929
+ actorIdByKey.set(key2, aid);
172930
+ }
172931
+ idOf.set(actor, aid);
172932
+ return aid;
172933
+ };
172083
172934
  for (const c of displayedCases) {
172084
- for (const a2 of declaredMembers(c)) {
172085
- if (!isActorDecl(a2))
172086
- continue;
172087
- const canonical = actorCanonical(a2);
172088
- if (!idOf.has(canonical))
172089
- add(canonical, "actor", { id: anonymousActorId(canonical), meta: { cvAuxiliary: true } });
172090
- const actorId = idOf.get(canonical);
172091
- idOf.set(a2, actorId);
172935
+ const siblings = declaredMembers(c).filter(isActorDecl);
172936
+ const typeSources = siblings.some((a2) => !actorTypeKey(a2)) ? [...siblings, ...this.inheritedTypesOf(c, index2).flatMap((t) => membersOf(t).filter(isActorDecl))] : siblings;
172937
+ for (const a2 of siblings) {
172938
+ const actorId = addActor(a2, typeSources);
172092
172939
  const pair = `${actorId}\0${qnameOf(c) ?? nameOf2(c) ?? ""}`;
172093
172940
  if (!actorCasePairs.has(pair)) {
172094
172941
  actorCasePairs.add(pair);
@@ -173837,7 +174684,7 @@ ${node.id}`;
173837
174684
  const inherited = includeInherited ? this.inheritedItems(node, index2, uri) : [];
173838
174685
  const inheritedRows = (predicate, text = (member) => this.featureText(member)) => inherited.filter(({ member }) => predicate(member)).map(({ member, source }) => ({ text: `^${text(member)}`, source }));
173839
174686
  const usages = (guard) => members.filter((m) => guard(m) && m.isDef !== true && nameOf2(m) && isOrdinaryMember(m));
173840
- const exprText3 = (m) => (m.body?.$cstNode?.text ?? "").replace(/\s+/g, " ").trim();
174687
+ const exprText4 = (m) => (m.body?.$cstNode?.text ?? "").replace(/\s+/g, " ").trim();
173841
174688
  const statementText = (m) => (m.$cstNode?.text ?? this.featureText(m)).replace(/\s+/g, " ").replace(/;$/, "").trim();
173842
174689
  const canonicalFeatureText = (m) => m.$type === "FeatureShorthand" || m.$type === "FeatureRedefinitionShorthand" ? statementText(m) : this.featureText(m);
173843
174690
  const out = [];
@@ -173889,8 +174736,8 @@ ${node.id}`;
173889
174736
  add("occurrences", members.map((m) => this.thenActionMemberNode(m) ?? m).filter(isNonVariantMember).filter((m) => isEventDecl(m) && m.isOccurrence === true && nameOf2(m)).map((m) => item(m)));
173890
174737
  add("calcs", undirected(isCalcDecl).map((m) => item(m)));
173891
174738
  add("constraints", undirected(isConstraintDecl).map((m) => item(m)));
173892
- add("assume constraints", members.filter((m) => m.$type === "AssumeConstraintStmt").map((m) => item(m, exprText3(m) || "assume constraint")));
173893
- add("require constraints", members.filter((m) => m.$type === "RequireConstraintStmt").map((m) => item(m, exprText3(m) || `require ${this.featurePath(m.target) ?? ""}`.trim())));
174739
+ add("assume constraints", members.filter((m) => m.$type === "AssumeConstraintStmt").map((m) => item(m, exprText4(m) || "assume constraint")));
174740
+ add("require constraints", members.filter((m) => m.$type === "RequireConstraintStmt").map((m) => item(m, exprText4(m) || `require ${this.featurePath(m.target) ?? ""}`.trim())));
173894
174741
  add("actors", members.filter(isActorDecl).filter(isNonVariantMember).map((m) => item(m)));
173895
174742
  add("stakeholders", members.filter(isStakeholderDecl).filter(isNonVariantMember).map((m) => item(m)));
173896
174743
  add("frames", members.filter((m) => m.$type === "FrameMember").map((m) => item(m, this.refText(m.target) ?? "concern")));
@@ -173919,7 +174766,7 @@ ${node.id}`;
173919
174766
  ]);
173920
174767
  add("result", members.filter((m) => m.$type === "ReturnDecl").map((m) => item(m, `return${nameOf2(m) ? ` ${nameOf2(m)}` : ""}${typeText(m) ? ` : ${typeText(m)}` : ""}`)));
173921
174768
  if (isConstraintDecl(node))
173922
- add("expression", exprText3(node) ? [{ text: exprText3(node), source: sourceOf2(node, uri) }] : []);
174769
+ add("expression", exprText4(node) ? [{ text: exprText4(node), source: sourceOf2(node, uri) }] : []);
173923
174770
  const enumValueMembers = isEnumDecl(node) ? members.filter(isOwnedEnumerationValue) : members.filter((m) => isNonVariantMember(m) && m.$type === "EnumValueDecl" && !m.typing);
173924
174771
  add("enums", enumValueMembers.map((m) => {
173925
174772
  const nm = nameOf2(m);
@@ -173948,11 +174795,11 @@ ${node.id}`;
173948
174795
  add("state transition", members.filter((m) => m.$type === "TransitionDecl").map((m) => item(m, `${m.from ?? ""} \u2192 ${m.to ?? ""}`)));
173949
174796
  const successionText = (m) => (m.$cstNode?.text ?? "").replace(/\s+/g, " ").replace(/;$/, "").trim();
173950
174797
  add("successions", members.filter((m) => m.$type === "FirstThenChain" || m.$type === "SuccessionStmt" || m.$type === "ThenActionMember" && typeof m.target === "string" || m.$type === "ElseSuccessionMember" || (m.$type === "AcceptNode" || m.$type === "IfActionNode") && typeof m.thenTarget === "string").map((m) => item(m, successionText(m))).filter((row) => !!row.text));
173951
- add("assert constraints", members.filter((m) => m.$type === "AssertConstraintStmt").map((m) => item(m, exprText3(m) || nameOf2(m) || "assert constraint")));
174798
+ add("assert constraints", members.filter((m) => m.$type === "AssertConstraintStmt").map((m) => item(m, exprText4(m) || nameOf2(m) || "assert constraint")));
173952
174799
  add("invariants", members.filter((m) => m.$type === "InvShorthand").map((m) => {
173953
174800
  const inv = m;
173954
174801
  const head2 = `inv${inv.isNegated ? " false" : ""}${nameOf2(m) ? ` ${nameOf2(m)}` : ""}`;
173955
- const expr = exprText3(m);
174802
+ const expr = exprText4(m);
173956
174803
  return item(m, `${head2} { ${expr} }`.replace(/\s+/g, " ").trim());
173957
174804
  }));
173958
174805
  add("actions", usages(isActionDecl).map((m) => item(m)));
@@ -174209,8 +175056,12 @@ function projectGvCompartments(input) {
174209
175056
  continue;
174210
175057
  visible.add(node.id);
174211
175058
  const key2 = gvElementKey(node);
174212
- const open = gvElementIsExpanded(node, expanded2);
174213
- expandable.add(key2);
175059
+ const children2 = (index2.children.get(node.id) ?? []).filter(
175060
+ (child) => child.meta?.gvDerived !== true && child.meta?.connectionDefinitionHub !== true
175061
+ );
175062
+ const canExpand = children2.length > 0;
175063
+ const open = canExpand && gvElementIsExpanded(node, expanded2);
175064
+ if (canExpand) expandable.add(key2);
174214
175065
  nodes.push({
174215
175066
  ...node,
174216
175067
  parent,
@@ -174229,7 +175080,7 @@ function projectGvCompartments(input) {
174229
175080
  ...node.meta,
174230
175081
  gvMode: "group",
174231
175082
  gvExpansionKey: key2,
174232
- gvCanExpand: true,
175083
+ gvCanExpand: canExpand,
174233
175084
  gvExpanded: open,
174234
175085
  gvOpenContainer: open,
174235
175086
  internalsHidden: !open,
@@ -174237,7 +175088,7 @@ function projectGvCompartments(input) {
174237
175088
  }
174238
175089
  });
174239
175090
  if (open) {
174240
- for (const child of index2.children.get(node.id) ?? []) {
175091
+ for (const child of children2) {
174241
175092
  queue.push({ node: child, parent: node.id });
174242
175093
  }
174243
175094
  }
@@ -174273,10 +175124,10 @@ function projectGvTree(input) {
174273
175124
  visible.add(node.id);
174274
175125
  const isPackage2 = node.shape === "package";
174275
175126
  const children2 = (index2.children.get(node.id) ?? []).filter(
174276
- (child) => isPackage2 || isGvPartUsage(child)
175127
+ (child) => child.meta?.gvTreeExcluded !== true && !isDerivedHub(child) && (isPackage2 || isGvPartUsage(child))
174277
175128
  );
174278
175129
  const key2 = gvElementKey(node);
174279
- const canExpand = isPackage2 || children2.length > 0 || /\bpart\b/.test(node.keyword);
175130
+ const canExpand = children2.length > 0;
174280
175131
  const open = canExpand && gvElementIsExpanded(node, expanded2, true);
174281
175132
  if (canExpand) expandable.add(key2);
174282
175133
  nodes.push({
@@ -174869,8 +175720,8 @@ function outlineGroupForType(astType) {
174869
175720
  }
174870
175721
 
174871
175722
  // ../language-server/out/src/services/document-symbol-provider.js
174872
- var SPECIALIZATION_KINDS4 = /* @__PURE__ */ new Set([":>", "specializes"]);
174873
- var REDEFINITION_KINDS2 = /* @__PURE__ */ new Set([":>>", "redefines"]);
175723
+ var SPECIALIZATION_KINDS5 = /* @__PURE__ */ new Set([":>", "specializes"]);
175724
+ var REDEFINITION_KINDS3 = /* @__PURE__ */ new Set([":>>", "redefines"]);
174874
175725
  var INHERITABLE_FEATURE_TYPES = /* @__PURE__ */ new Set([
174875
175726
  "ActionDecl",
174876
175727
  "AttributeDecl",
@@ -174941,7 +175792,7 @@ function specializationTargets2(node) {
174941
175792
  const n2 = node;
174942
175793
  const out = [];
174943
175794
  for (const rel2 of [...n2.preRelationships ?? [], ...n2.relationships ?? []]) {
174944
- if (rel2.kind && SPECIALIZATION_KINDS4.has(rel2.kind))
175795
+ if (rel2.kind && SPECIALIZATION_KINDS5.has(rel2.kind))
174945
175796
  out.push(...rel2.targets ?? []);
174946
175797
  }
174947
175798
  return out;
@@ -174950,7 +175801,7 @@ function redefinitionTargets(node) {
174950
175801
  const n2 = node;
174951
175802
  const out = [];
174952
175803
  for (const rel2 of [...n2.preRelationships ?? [], ...n2.relationships ?? []]) {
174953
- if (rel2.kind && REDEFINITION_KINDS2.has(rel2.kind))
175804
+ if (rel2.kind && REDEFINITION_KINDS3.has(rel2.kind))
174954
175805
  out.push(...rel2.targets ?? []);
174955
175806
  }
174956
175807
  return out;
@@ -175305,21 +176156,21 @@ var import_vscode_languageserver13 = __toESM(require_main4(), 1);
175305
176156
  function isRequirementNode(node) {
175306
176157
  return node?.$type === "RequirementDecl";
175307
176158
  }
175308
- function ownSubject(node) {
176159
+ function ownSubject2(node) {
175309
176160
  return (node.members ?? []).find((member) => member.$type === "SubjectDecl");
175310
176161
  }
175311
176162
  function resolveEffectiveSubject(node) {
175312
176163
  if (!isRequirementNode(node))
175313
176164
  return void 0;
175314
- const own = ownSubject(node);
176165
+ const own = ownSubject2(node);
175315
176166
  if (own)
175316
176167
  return { subject: own, owner: node, inherited: false };
175317
176168
  let container = node.$container;
175318
176169
  while (container) {
175319
176170
  if (isRequirementNode(container)) {
175320
- const inheritedSubject = ownSubject(container);
175321
- if (inheritedSubject) {
175322
- return { subject: inheritedSubject, owner: container, inherited: true };
176171
+ const inheritedSubject2 = ownSubject2(container);
176172
+ if (inheritedSubject2) {
176173
+ return { subject: inheritedSubject2, owner: container, inherited: true };
175323
176174
  }
175324
176175
  }
175325
176176
  container = container.$container;
@@ -175327,6 +176178,283 @@ function resolveEffectiveSubject(node) {
175327
176178
  return void 0;
175328
176179
  }
175329
176180
 
176181
+ // ../language-server/out/src/services/case-semantics.js
176182
+ var CASE_KIND_BY_TYPE = /* @__PURE__ */ new Map([
176183
+ ["CaseDecl", "case"],
176184
+ ["AnalysisCaseDecl", "analysis"],
176185
+ ["VerificationCaseDecl", "verification"],
176186
+ ["UseCaseDecl", "use-case"]
176187
+ ]);
176188
+ var MAX_INHERITANCE_DEPTH2 = 16;
176189
+ function caseKindOf(node) {
176190
+ return node ? CASE_KIND_BY_TYPE.get(node.$type) : void 0;
176191
+ }
176192
+ function enclosingCase(node) {
176193
+ let current2 = node;
176194
+ while (current2) {
176195
+ if (CASE_SHAPED.has(current2.$type))
176196
+ return current2;
176197
+ current2 = current2.$container;
176198
+ }
176199
+ return void 0;
176200
+ }
176201
+ function writtenTypes(node, resolve8) {
176202
+ const out = [];
176203
+ for (const typing of [node.typing, ...node.moreTypings ?? []]) {
176204
+ if (!typing)
176205
+ continue;
176206
+ for (const ref of [typing.type, ...typing.moreTypes ?? []]) {
176207
+ if (!ref)
176208
+ continue;
176209
+ const name = ref.$refText?.trim() ?? ref.ref?.name;
176210
+ if (!name)
176211
+ continue;
176212
+ out.push({ name, node: ref.ref ?? resolve8(name) });
176213
+ }
176214
+ }
176215
+ return out;
176216
+ }
176217
+ function effectiveCaseDefinition(node, resolve8) {
176218
+ const kind = caseKindOf(node);
176219
+ if (!kind)
176220
+ return void 0;
176221
+ const decl = node;
176222
+ const resolver = resolve8 ?? documentResolver(node);
176223
+ const definitions = writtenTypes(decl, resolver).filter((type) => type.node === void 0 || CASE_SHAPED.has(type.node.$type));
176224
+ return {
176225
+ kind,
176226
+ isDefinition: decl.isDef === true,
176227
+ definitions,
176228
+ sole: definitions.length === 1 ? definitions[0] : void 0
176229
+ };
176230
+ }
176231
+ function hasAmbiguousDefinition(node, resolve8) {
176232
+ const effective = effectiveCaseDefinition(node, resolve8);
176233
+ if (!effective || effective.isDefinition)
176234
+ return false;
176235
+ return effective.definitions.filter((type) => type.node !== void 0).length > 1;
176236
+ }
176237
+ function isDecidedSubject(subject) {
176238
+ if (!subject)
176239
+ return false;
176240
+ return subject.origin !== "default" && subject.origin !== "ambiguous" && subject.typeName !== DEFAULT_SUBJECT_TYPE;
176241
+ }
176242
+ function effectiveCaseSubject(node, resolve8) {
176243
+ const resolver = resolve8 ?? documentResolver(node);
176244
+ if (hasAmbiguousDefinition(node, resolver)) {
176245
+ const own = ownSubject(node);
176246
+ return own ? subjectInfo(own, node, "own") : { typeName: DEFAULT_SUBJECT_TYPE, origin: "ambiguous" };
176247
+ }
176248
+ return effectiveSubject(node, resolver);
176249
+ }
176250
+ function ownActors(node) {
176251
+ return (node.members ?? []).filter((member) => member.$type === "ActorDecl");
176252
+ }
176253
+ function effectiveActors(node, resolve8) {
176254
+ const resolver = resolve8 ?? documentResolver(node);
176255
+ const ambiguous = hasAmbiguousDefinition(node, resolver);
176256
+ const out = [];
176257
+ const seenNodes = /* @__PURE__ */ new Set();
176258
+ const seenNames = /* @__PURE__ */ new Set();
176259
+ const walk = (current2, origin, depth) => {
176260
+ if (depth > MAX_INHERITANCE_DEPTH2 || seenNodes.has(current2))
176261
+ return;
176262
+ seenNodes.add(current2);
176263
+ for (const actor of ownActors(current2)) {
176264
+ if (actor.name && seenNames.has(actor.name))
176265
+ continue;
176266
+ if (actor.name)
176267
+ seenNames.add(actor.name);
176268
+ out.push({
176269
+ declaration: actor,
176270
+ name: actor.name,
176271
+ typeName: subjectTypeName(actor),
176272
+ origin,
176273
+ owner: current2
176274
+ });
176275
+ }
176276
+ if (ambiguous)
176277
+ return;
176278
+ for (const supertype of supertypesOf(current2, resolver)) {
176279
+ if (!CASE_SHAPED.has(supertype.$type))
176280
+ continue;
176281
+ walk(supertype, "inherited", depth + 1);
176282
+ }
176283
+ };
176284
+ walk(node, "own", 0);
176285
+ return out;
176286
+ }
176287
+ function caseResult(node, resolve8) {
176288
+ const resolver = resolve8 ?? documentResolver(node);
176289
+ const ambiguous = hasAmbiguousDefinition(node, resolver);
176290
+ const seen = /* @__PURE__ */ new Set();
176291
+ const walk = (current2, origin, depth) => {
176292
+ if (depth > MAX_INHERITANCE_DEPTH2 || seen.has(current2))
176293
+ return void 0;
176294
+ seen.add(current2);
176295
+ const own = (current2.members ?? []).find((member) => member.$type === "ReturnDecl");
176296
+ if (own) {
176297
+ return {
176298
+ declaration: own,
176299
+ name: own.name,
176300
+ typeName: subjectTypeName(own),
176301
+ origin,
176302
+ owner: current2
176303
+ };
176304
+ }
176305
+ if (ambiguous)
176306
+ return void 0;
176307
+ for (const supertype of supertypesOf(current2, resolver)) {
176308
+ if (!CASE_SHAPED.has(supertype.$type))
176309
+ continue;
176310
+ const inherited = walk(supertype, "inherited", depth + 1);
176311
+ if (inherited)
176312
+ return inherited;
176313
+ }
176314
+ return void 0;
176315
+ };
176316
+ return walk(node, "own", 0);
176317
+ }
176318
+ function objectiveBindingOf(objective, resolve8) {
176319
+ if (objective.$type !== "ObjectiveDecl")
176320
+ return void 0;
176321
+ const caseNode = enclosingCase(objective.$container);
176322
+ const caseKind = caseKindOf(caseNode);
176323
+ if (!caseNode || !caseKind)
176324
+ return void 0;
176325
+ const resolver = resolve8 ?? documentResolver(objective);
176326
+ const own = ownSubject(objective);
176327
+ const bindsSubject = caseKind === "verification" || caseKind === "use-case";
176328
+ if (bindsSubject) {
176329
+ const subject = effectiveCaseSubject(caseNode, resolver);
176330
+ return {
176331
+ objective,
176332
+ caseNode,
176333
+ caseKind,
176334
+ target: "case-subject",
176335
+ strength: "bind",
176336
+ boundTo: subject.declaration,
176337
+ // An undecided subject names no type: the case still binds its
176338
+ // objective to whatever its subject is, but neither hover nor
176339
+ // `SSM046` may say what that is.
176340
+ typeName: isDecidedSubject(subject) ? subject.typeName : void 0,
176341
+ own
176342
+ };
176343
+ }
176344
+ const result = caseResult(caseNode, resolver);
176345
+ return {
176346
+ objective,
176347
+ caseNode,
176348
+ caseKind,
176349
+ target: "case-result",
176350
+ strength: "default",
176351
+ boundTo: result?.declaration,
176352
+ typeName: result?.typeName,
176353
+ own
176354
+ };
176355
+ }
176356
+ function effectiveObjectiveSubject(objective, resolve8) {
176357
+ const resolver = resolve8 ?? documentResolver(objective);
176358
+ const binding = objectiveBindingOf(objective, resolver);
176359
+ const own = ownSubject(objective);
176360
+ if (!binding) {
176361
+ return own ? { declaration: own, name: own.name, typeName: subjectTypeName(own) ?? DEFAULT_SUBJECT_TYPE, origin: "own", owner: objective } : { typeName: DEFAULT_SUBJECT_TYPE, origin: "default" };
176362
+ }
176363
+ if (own && binding.strength === "default") {
176364
+ return {
176365
+ declaration: own,
176366
+ name: own.name,
176367
+ typeName: subjectTypeName(own) ?? DEFAULT_SUBJECT_TYPE,
176368
+ origin: "own",
176369
+ owner: objective
176370
+ };
176371
+ }
176372
+ return {
176373
+ declaration: binding.boundTo,
176374
+ typeName: binding.typeName ?? DEFAULT_SUBJECT_TYPE,
176375
+ origin: "enclosing",
176376
+ owner: binding.caseNode
176377
+ };
176378
+ }
176379
+ function objectiveSubrequirements(objective, resolve8) {
176380
+ if (objective.$type !== "ObjectiveDecl")
176381
+ return [];
176382
+ const resolver = resolve8 ?? documentResolver(objective);
176383
+ const subjectTypeName2 = effectiveObjectiveSubject(objective, resolver).typeName;
176384
+ const out = [];
176385
+ for (const member of objective.members ?? []) {
176386
+ if (member.$type === "VerifyStmt") {
176387
+ const path10 = referencePathOf(member);
176388
+ out.push({
176389
+ declaration: member,
176390
+ kind: "verify",
176391
+ path: path10,
176392
+ target: referenceTargetOf(member, resolver),
176393
+ subjectTypeName: subjectTypeName2
176394
+ });
176395
+ } else if (member.$type === "RequirementDecl") {
176396
+ out.push({ declaration: member, kind: "requirement", subjectTypeName: subjectTypeName2 });
176397
+ }
176398
+ }
176399
+ return out;
176400
+ }
176401
+ function valueSimpleName(value) {
176402
+ const node = value;
176403
+ if (!node)
176404
+ return void 0;
176405
+ if (node.$type === "ParenExpr") {
176406
+ const items = node.items ?? [];
176407
+ return items.length === 1 ? valueSimpleName(items[0]) : void 0;
176408
+ }
176409
+ if (node.$type !== "PathExpr")
176410
+ return void 0;
176411
+ return node.path ? simpleName(node.path) : void 0;
176412
+ }
176413
+ function includeBindingOf(stmt, resolve8) {
176414
+ if (stmt.$type !== "IncludeStmt")
176415
+ return void 0;
176416
+ const node = stmt;
176417
+ const resolver = resolve8 ?? documentResolver(stmt);
176418
+ const isUseCase = (candidate) => candidate !== void 0 && candidate.$type === "UseCaseDecl";
176419
+ const typed = writtenTypes(node, resolver).find((type) => type.node === void 0 || isUseCase(type.node));
176420
+ const path10 = referencePathOf(node);
176421
+ const named2 = typed?.node ?? (typed ? void 0 : referenceTargetOf(node, resolver));
176422
+ const target = isUseCase(named2) ? named2 : void 0;
176423
+ const form = node.useCaseKw === true || typed !== void 0 ? "declaration" : "reference";
176424
+ const containing = enclosingCase(node.$container);
176425
+ const parameters = target ? effectiveActors(target, resolver) : [];
176426
+ const actors = [];
176427
+ for (const member of node.members ?? []) {
176428
+ if (member.$type !== "ActorDecl")
176429
+ continue;
176430
+ const name = member.name;
176431
+ actors.push({
176432
+ declaration: member,
176433
+ name,
176434
+ valueName: valueSimpleName(member.value),
176435
+ typeName: subjectTypeName(member),
176436
+ parameter: name ? parameters.find((parameter) => parameter.name === name) : void 0
176437
+ });
176438
+ }
176439
+ const containingSubject = containing ? effectiveCaseSubject(containing, resolver) : void 0;
176440
+ const includedSubject = target ? effectiveCaseSubject(target, resolver) : void 0;
176441
+ const subjectOrigin = isDecidedSubject(includedSubject) ? "included" : isDecidedSubject(containingSubject) ? "containing" : "default";
176442
+ const subjectTypeName2 = subjectOrigin === "included" ? includedSubject.typeName : subjectOrigin === "containing" ? containingSubject.typeName : DEFAULT_SUBJECT_TYPE;
176443
+ return {
176444
+ statement: stmt,
176445
+ form,
176446
+ path: typed ? typed.name : path10,
176447
+ target,
176448
+ containing,
176449
+ containingSubject,
176450
+ includedSubject,
176451
+ subjectOrigin,
176452
+ subjectTypeName: subjectTypeName2,
176453
+ parameters,
176454
+ actors
176455
+ };
176456
+ }
176457
+
175330
176458
  // ../language-server/out/src/services/implicit-specialization.js
175331
176459
  var EXPLICIT_SPECIALIZATION_KINDS = /* @__PURE__ */ new Set([
175332
176460
  ":>",
@@ -176096,6 +177224,64 @@ var DIAGNOSTIC_MESSAGES = {
176096
177224
  SSM040_INDIVIDUAL_NOT_OCCURRENCE: (name, kind) => `'individual' names one occurrence with an identity of its own, and ${name} is ${kind}, which has no life to identify. Remove 'individual', or move it to the occurrence this belongs to.`,
176097
177225
  SSM041_INDIVIDUAL_MULTIPLE_DEFINITIONS: (name, first2, second) => `${name} is typed by two individual definitions, '${first2}' and '${second}'. An individual usage names ONE life, so at most one of its types may be an 'individual def'.`,
176098
177226
  SSM042_INDIVIDUAL_WITHOUT_DEFINITION: (name) => `${name} is declared 'individual' but names no individual definition. An individual usage is typed by exactly one 'individual def' - the definition that carries the identity it names.`,
177227
+ // REQ-415 — issue #164. `assert c`, `require c` and `assume c` all reach their
177228
+ // constraint through the same OwnedReferenceSubsetting, so one message covers
177229
+ // the three. The kind is named because the fix depends on it: a part or an
177230
+ // action is not something that can be true or false.
177231
+ SSM043_CONSTRAINT_REFERENCE_KIND: (keyword, path10, kind) => `'${keyword} ${path10}' must name a constraint, but '${path10}' is ${kind}. The '${keyword}' shorthand asserts the referenced constraint's Boolean body, so write 'assert constraint { \u2026 }' to state a condition here instead.`,
177232
+ // REQ-415 — the reference resolves and its constraint evaluates to a definite
177233
+ // false, so the model states something against itself. A warning, never an
177234
+ // error: the text is well formed, and only a closed constant expression is
177235
+ // decided at all - anything that depends on a binding stays silent.
177236
+ SEM014_ASSERTION_VIOLATED: (text) => `Asserted constraint '${text}' evaluates to false, so this model is inconsistent as written.`,
177237
+ // REQ-131 — a constraint is a predicate: `BooleanEvaluation` returns
177238
+ // `Boolean[1]` (Kernel Semantic Library, `Performances.kerml`). A body that is
177239
+ // demonstrably some other type can never be true or false. Only a body the
177240
+ // checker can PROVE is not Boolean is reported, so an expression whose type it
177241
+ // cannot settle stays silent.
177242
+ SEM015_CONSTRAINT_BODY_NOT_BOOLEAN: (text, kind) => `A constraint body must be a Boolean expression, but '${text}' is ${kind}. A constraint is a predicate, so its body has to be able to come out true or false.`,
177243
+ // REQ-209 — a usage inherits its definition's expression. Replacing it hides
177244
+ // what the definition says while every other usage still reads the original.
177245
+ // Advisory: the language permits the redefinition, the modelling idiom does not
177246
+ // use it, and no model in the OMG corpus does.
177247
+ STYL012_CONSTRAINT_BODY_OVERRIDES_DEFINITION: (usage, definition) => `'${usage}' replaces the expression it inherits from '${definition}', so the definition's expression no longer applies here. Bind the parameters instead, or give this usage its own constraint definition.`,
177248
+ /* REQ-376 — a parameter of a constraint or a calculation is an INPUT.
177249
+ *
177250
+ * A constraint is a predicate: its one output is its Boolean result, which
177251
+ * comes from the body, never from a parameter. A calculation produces its
177252
+ * value through `return`. Neither has anything to send back out through a
177253
+ * parameter, and the OMG corpus bears that out: 40 `in` parameters on
177254
+ * constraints and 44 on calculations, and not one `out` or `inout` on either.
177255
+ *
177256
+ * A constraint is also ACAUSAL — `StraightLineDynamicsEquations` declares even
177257
+ * the quantities it would be solved for (`x_f`, `v_f`, `a`) as `in`, because
177258
+ * which parameter is the unknown is the binding's business, not the
177259
+ * constraint's. Fixing a direction would bake in one solving order. */
177260
+ STYL014_PARAMETER_DIRECTION: (parameter, direction, kind, owner) => kind === "constraint" ? `Parameter '${parameter}' is '${direction}' on constraint '${owner}'. A constraint's only output is true or false, so everything it relates is an input: declare the parameter 'in'. Which parameter is the unknown is decided where the constraint is bound.` : `Parameter '${parameter}' is '${direction}' on calculation '${owner}'. A calculation produces its value through 'return', so declare the parameter 'in' and return the result.`,
177261
+ // REQ-376 — a directed parameter is an input to be bound by a usage, not a
177262
+ // value slot. OMG declares parameters bare on a definition and puts values on
177263
+ // `attribute` members (`StraightLineDynamicsEquations`).
177264
+ STYL013_PARAMETER_DEFAULT_ON_DEFINITION: (parameter, owner) => `Parameter '${parameter}' carries a value on the definition '${owner}'. A parameter is an input a usage binds, so declare it without a value and put the value on an attribute, or bind it where the definition is used.`,
177265
+ // issue #165 — a satisfaction binds a thing to the subject a requirement
177266
+ // constrains, so the thing has to BE one of those (OMG SysML v2 Part 1
177267
+ // §7.21.2). The message names both types because the fix is either to bind a
177268
+ // different satisfier or to widen the requirement's subject.
177269
+ SSM044_SATISFIER_SUBJECT_TYPE: (satisfier, satisfierType, requirement, subjectType) => `'${satisfier}' is a '${satisfierType}', but '${requirement}' constrains a subject of type '${subjectType}'. A satisfying element must conform to the requirement's subject.`,
177270
+ // issue #166 — a case usage performs ONE case (OMG SysML v2 Part 1 §7.22.2),
177271
+ // and every effective binding this extension derives reads through that one:
177272
+ // the subject, the actor parameters and the objective. Two definitions leave
177273
+ // all three undecided, so the message names them and asks for one.
177274
+ SSM045_CASE_MULTIPLE_DEFINITIONS: (name, first2, second) => `Case '${name}' names more than one case definition ('${first2}' and '${second}'). A case usage performs exactly one case, so keep one and subset the other.`,
177275
+ // issue #166 — an `objective` written inside a verification case or a use
177276
+ // case has its subject BOUND to the case's subject, so a `subject` of an
177277
+ // unrelated type on the objective states something the case has already
177278
+ // decided otherwise.
177279
+ SSM046_OBJECTIVE_SUBJECT_TYPE: (caseName, objectiveType, subjectType) => `This objective declares a subject of type '${objectiveType}', but '${caseName}' binds its objective's subject to its own subject of type '${subjectType}'. Remove the subject or widen the case's.`,
177280
+ // issue #166 — an `include` investigates the included use case on the
177281
+ // including case's subject (§7.25), and an `actor` written inside the
177282
+ // include binds one of the included use case's actor parameters.
177283
+ SSM047_INCLUDE_SUBJECT_TYPE: (included, includedType, containerType) => `Included use case '${included}' has a subject of type '${includedType}', which does not conform to the including case's subject of type '${containerType}'. An included use case is investigated on the same subject.`,
177284
+ SSM048_INCLUDE_ACTOR_BINDING: (actor, included, known2) => `'${actor}' is not an actor parameter of the included use case '${included}'. It declares ${known2}.`,
176099
177285
  // REQ-392 — a `sysml-format` comment the formatter cannot act on. Advisory:
176100
177286
  // the directive is inert, and saying so beats leaving the author to wonder
176101
177287
  // why their layout was reformatted anyway.
@@ -176558,7 +177744,7 @@ function nearestAncestor(node, types) {
176558
177744
  }
176559
177745
  return void 0;
176560
177746
  }
176561
- function exprText2(node) {
177747
+ function exprText3(node) {
176562
177748
  return node?.$cstNode?.text?.trim().replace(/\s+/gu, " ") ?? "";
176563
177749
  }
176564
177750
  function conditionTypeLabel(node) {
@@ -176569,7 +177755,7 @@ function conditionTypeLabel(node) {
176569
177755
  if (["AndExpr", "OrExpr", "XorExpr", "NotExpr", "CompareExpr", "ClassifyOp"].includes(node.$type)) {
176570
177756
  return "Boolean";
176571
177757
  }
176572
- const text = exprText2(node);
177758
+ const text = exprText3(node);
176573
177759
  return /\b(true|false)\b|[=!<>]=?|(?:\band\b|\bor\b|\bnot\b|\bxor\b)/u.test(text) ? "Boolean" : "Boolean (expected)";
176574
177760
  }
176575
177761
  function buildConditionalHover(node) {
@@ -176583,7 +177769,7 @@ function buildConditionalHover(node) {
176583
177769
  "",
176584
177770
  "Canonical form: `if condition ? thenExpression else elseExpression`",
176585
177771
  `Then marker: ${usesQuestion ? "canonical `?`" : "non-canonical `then`; use `?`"}`,
176586
- `Condition: \`${exprText2(n2.cond)}\``,
177772
+ `Condition: \`${exprText3(n2.cond)}\``,
176587
177773
  `Condition type: ${conditionTypeLabel(n2.cond)}`,
176588
177774
  "",
176589
177775
  sourceFooter(nodeSource(node))
@@ -176755,6 +177941,8 @@ ${headerLines.join("\n")}
176755
177941
  const subject = subjectInheritanceSection(node);
176756
177942
  if (subject)
176757
177943
  parts.push(subject);
177944
+ for (const section of caseBindingSections(node))
177945
+ parts.push(section);
176758
177946
  if (relationshipDetails)
176759
177947
  parts.push(relationshipDetails);
176760
177948
  const flip = conjugationFlipSection(node);
@@ -176791,6 +177979,62 @@ function subjectInheritanceSection(node) {
176791
177979
  const ownerName = effective.owner.name ?? "(anonymous requirement)";
176792
177980
  return `*Subject inherited from \`${ownerName}\`:* \`${subjectText}\``;
176793
177981
  }
177982
+ var CASE_KIND_LABELS = {
177983
+ "case": "Case",
177984
+ "analysis": "Analysis case",
177985
+ "verification": "Verification case",
177986
+ "use-case": "Use case"
177987
+ };
177988
+ function caseBindingSections(node) {
177989
+ const out = [];
177990
+ const kind = caseKindOf(node);
177991
+ if (kind) {
177992
+ const effective = effectiveCaseDefinition(node);
177993
+ if (effective && !effective.isDefinition && effective.sole) {
177994
+ out.push(`*${CASE_KIND_LABELS[kind]} performs:* \`${effective.sole.name}\``);
177995
+ }
177996
+ const subject = effectiveCaseSubject(node);
177997
+ if (subject.origin === "inherited") {
177998
+ const owner = subject.owner?.name;
177999
+ out.push(`*Subject inherited${owner ? ` from \`${owner}\`` : ""}:* \`${subject.name ?? "subject"} : ${subject.typeName}\``);
178000
+ } else if (subject.origin === "default") {
178001
+ out.push("*Subject:* none declared, so this case investigates `Anything`.");
178002
+ }
178003
+ const inherited = effectiveActors(node).filter((actor) => actor.origin === "inherited");
178004
+ if (inherited.length > 0) {
178005
+ const list = inherited.map((actor) => `\`${actor.name ?? "actor"}${actor.typeName ? ` : ${actor.typeName}` : ""}\``).join(", ");
178006
+ out.push(`*Actors inherited:* ${list}`);
178007
+ }
178008
+ }
178009
+ if (node.$type === "ObjectiveDecl") {
178010
+ const binding = objectiveBindingOf(node);
178011
+ if (binding) {
178012
+ const what = binding.target === "case-subject" ? "subject" : "result";
178013
+ const verb = binding.strength === "bind" ? "is bound to" : "defaults to";
178014
+ const type = binding.typeName ? ` (\`${binding.typeName}\`)` : "";
178015
+ const caseName = binding.caseNode.name;
178016
+ out.push(`*Objective subject ${verb}* the ${what} of ${caseName ? `\`${caseName}\`` : "the enclosing case"}${type}.`);
178017
+ }
178018
+ const subrequirements = objectiveSubrequirements(node);
178019
+ if (subrequirements.length > 0) {
178020
+ const list = subrequirements.map((sub) => `\`${sub.path ?? sub.declaration.name ?? "requirement"}\``).join(", ");
178021
+ out.push(`*Required subrequirements:* ${list} \u2014 each is checked on this objective's subject.`);
178022
+ }
178023
+ }
178024
+ if (node.$type === "IncludeStmt") {
178025
+ const binding = includeBindingOf(node);
178026
+ if (binding?.target) {
178027
+ const name = binding.path ? `\`${binding.path}\`` : "the included use case";
178028
+ out.push(`*Includes:* ${name}, a reference to a use case performed elsewhere. It keeps its own identity and is not copied here.`);
178029
+ if (binding.subjectOrigin === "containing") {
178030
+ out.push(`*Investigated on:* the including case's subject (\`${binding.subjectTypeName}\`).`);
178031
+ } else if (binding.subjectOrigin === "included") {
178032
+ out.push(`*Investigated on:* its own subject (\`${binding.subjectTypeName}\`).`);
178033
+ }
178034
+ }
178035
+ }
178036
+ return out;
178037
+ }
176794
178038
  function flipDirection(direction) {
176795
178039
  return direction === "in" ? "out" : direction === "out" ? "in" : direction;
176796
178040
  }
@@ -177248,8 +178492,8 @@ var SysmlHoverProvider = class {
177248
178492
  return buildOperatorHover(token, details);
177249
178493
  }
177250
178494
  async resolveLibraryFunction(qualifiedName) {
177251
- const simpleName2 = relationshipTargetKey(qualifiedName);
177252
- const descriptions = this.indexManager.allElements().toArray().filter((d) => (d.type === "FunctionDecl" || d.type === "CalcDecl" || d.type === "PredicateDecl") && (d.name === qualifiedName || d.name === simpleName2)).sort((a2, b) => Number(b.name === qualifiedName) - Number(a2.name === qualifiedName));
178495
+ const simpleName3 = relationshipTargetKey(qualifiedName);
178496
+ const descriptions = this.indexManager.allElements().toArray().filter((d) => (d.type === "FunctionDecl" || d.type === "CalcDecl" || d.type === "PredicateDecl") && (d.name === qualifiedName || d.name === simpleName3)).sort((a2, b) => Number(b.name === qualifiedName) - Number(a2.name === qualifiedName));
177253
178497
  for (const desc of descriptions) {
177254
178498
  const node = await this.nodeFromDescription(desc);
177255
178499
  if (node)
@@ -177765,6 +179009,13 @@ var TYPE_CONTEXTS = {
177765
179009
  calc: ["CalcDecl", "FunctionDecl"],
177766
179010
  constraint: ["ConstraintDecl", "PredicateDecl"]
177767
179011
  };
179012
+ var CONSTRAINT_REFERENCE_TYPES = [
179013
+ "ConstraintDecl",
179014
+ "InvShorthand",
179015
+ "PredicateDecl",
179016
+ "RequirementDecl",
179017
+ "ConcernDecl"
179018
+ ];
177768
179019
  var ALL_DEFINITION_TYPES = [
177769
179020
  "PartDecl",
177770
179021
  "PortDecl",
@@ -177950,6 +179201,10 @@ var SysmlCompletionProvider = class extends DefaultCompletionProvider {
177950
179201
  allowedLabels.add("requirement");
177951
179202
  allowedLabels.add("by");
177952
179203
  }
179204
+ if (context.kind === "constraint-reference") {
179205
+ allowedLabels.add("constraint");
179206
+ allowedLabels.add("not");
179207
+ }
177953
179208
  if (context.kind === "specialization") {
177954
179209
  allowedLabels.add("specializes");
177955
179210
  allowedLabels.add("subsets");
@@ -178024,6 +179279,14 @@ var SysmlCompletionProvider = class extends DefaultCompletionProvider {
178024
179279
  addUnique(items, this.visibleSymbolItems(["RequirementDecl"], { document: document2, offset: offset2 }));
178025
179280
  return;
178026
179281
  }
179282
+ // REQ-415 — a reference shorthand names a CONSTRAINT, so the slot
179283
+ // offers constraint usages and definitions rather than every symbol.
179284
+ // A requirement and a concern are constraints too (OMG SysML v2
179285
+ // Part 1 §7.20.2, §7.21.2), so both belong in the list.
179286
+ case "constraint-reference": {
179287
+ addUnique(items, this.visibleSymbolItems(CONSTRAINT_REFERENCE_TYPES, { document: document2, offset: offset2 }));
179288
+ return;
179289
+ }
178027
179290
  case "connect": {
178028
179291
  addUnique(items, this.connectPortItems(document2, offset2));
178029
179292
  return;
@@ -178045,6 +179308,8 @@ var SysmlCompletionProvider = class extends DefaultCompletionProvider {
178045
179308
  symbolTypesForContext(context) {
178046
179309
  if (context.kind === "verify" || context.kind === "satisfy")
178047
179310
  return ["RequirementDecl"];
179311
+ if (context.kind === "constraint-reference")
179312
+ return CONSTRAINT_REFERENCE_TYPES;
178048
179313
  const keyword = context.typingKeyword;
178049
179314
  if (!keyword)
178050
179315
  return ALL_DEFINITION_TYPES;
@@ -178058,7 +179323,7 @@ var SysmlCompletionProvider = class extends DefaultCompletionProvider {
178058
179323
  itemForDescription(desc, document2, offset2) {
178059
179324
  const importPath = document2 && offset2 !== void 0 ? this.autoImportPath(desc, document2, offset2) : void 0;
178060
179325
  return {
178061
- label: simpleName(desc.name) ?? desc.name,
179326
+ label: simpleName2(desc.name) ?? desc.name,
178062
179327
  kind: this.nodeKindProvider.getCompletionItemKind(desc),
178063
179328
  detail: desc.type,
178064
179329
  sortText: "0",
@@ -178084,7 +179349,7 @@ var SysmlCompletionProvider = class extends DefaultCompletionProvider {
178084
179349
  if (desc.name.includes("::"))
178085
179350
  return desc.name;
178086
179351
  const candidates = this.qualifiedNamesByElement().get(elementKey2(desc));
178087
- return candidates?.find((name) => simpleName(name) === desc.name);
179352
+ return candidates?.find((name) => simpleName2(name) === desc.name);
178088
179353
  }
178089
179354
  // REQ-245, REQ-268 — An element's qualified names, shortest first, keyed by
178090
179355
  // the element. A type-context completion offers thousands of symbols and each
@@ -178248,6 +179513,9 @@ function detectCompletionContext(text, offset2) {
178248
179513
  if (/\bconnect\s+(?:[\p{L}_:'.]+(?:\.[\p{L}_:']+)*\s+to\s*)?[\p{L}_:'.]*$/u.test(statement)) {
178249
179514
  return { kind: "connect", statement };
178250
179515
  }
179516
+ if (/\b(?:assert|require|assume)\s+(?:not\s+)?[\p{L}_:'.]*$/u.test(statement)) {
179517
+ return { kind: "constraint-reference", statement };
179518
+ }
178251
179519
  if (/(?:^|[^\w:])(?::>|:>>|specializes|subsets|redefines)\s*~?[\p{L}_:'.]*$/u.test(statement)) {
178252
179520
  return { kind: "specialization", statement, typingKeyword: keyword };
178253
179521
  }
@@ -178474,7 +179742,7 @@ function nearestMemberOwner(node) {
178474
179742
  }
178475
179743
  return void 0;
178476
179744
  }
178477
- function simpleName(name) {
179745
+ function simpleName2(name) {
178478
179746
  if (!name)
178479
179747
  return void 0;
178480
179748
  const parts = name.split(/::|\./u);
@@ -178674,7 +179942,7 @@ var import_vscode_languageserver16 = __toESM(require_main4(), 1);
178674
179942
 
178675
179943
  // ../language-server/out/src/services/metadata-filter.js
178676
179944
  var INCONCLUSIVE2 = { kind: "inconclusive" };
178677
- var SPECIALIZATION_KINDS5 = /* @__PURE__ */ new Set([":>", "specializes", ":>>", "redefines", "subsets"]);
179945
+ var SPECIALIZATION_KINDS6 = /* @__PURE__ */ new Set([":>", "specializes", ":>>", "redefines", "subsets"]);
178678
179946
  var MAX_SPECIALIZATION_DEPTH = 32;
178679
179947
  var MAX_VALUE_DEPTH = 16;
178680
179948
  function evaluateFilterCondition(condition, element, options) {
@@ -178777,7 +180045,7 @@ function declaresFeature2(node, name) {
178777
180045
  if (node.name === name)
178778
180046
  return true;
178779
180047
  for (const rel2 of [...node.preRelationships ?? [], ...node.relationships ?? []]) {
178780
- if (rel2.kind && SPECIALIZATION_KINDS5.has(rel2.kind) && (rel2.targets ?? []).includes(name))
180048
+ if (rel2.kind && SPECIALIZATION_KINDS6.has(rel2.kind) && (rel2.targets ?? []).includes(name))
178781
180049
  return true;
178782
180050
  }
178783
180051
  return false;
@@ -178944,7 +180212,7 @@ function nameScope(ctx, depth = 0) {
178944
180212
  function specializationTargets3(node) {
178945
180213
  const targets = [];
178946
180214
  for (const rel2 of [...node.preRelationships ?? [], ...node.relationships ?? []]) {
178947
- if (rel2.kind && SPECIALIZATION_KINDS5.has(rel2.kind))
180215
+ if (rel2.kind && SPECIALIZATION_KINDS6.has(rel2.kind))
178948
180216
  targets.push(...rel2.targets ?? []);
178949
180217
  }
178950
180218
  return targets;
@@ -179187,10 +180455,10 @@ function resolveImportedDescription(path10, globalDescriptions, options, visited
179187
180455
  if (split < 0)
179188
180456
  return void 0;
179189
180457
  const ownerPath = path10.slice(0, split);
179190
- const simpleName2 = path10.slice(split + 2);
180458
+ const simpleName3 = path10.slice(split + 2);
179191
180459
  const exported = [];
179192
180460
  expandNamespaceImports(ownerPath, globalDescriptions, exported, options, visitedNamespaces, importAll);
179193
- return exported.find((entry) => entry.name === simpleName2)?.description;
180461
+ return exported.find((entry) => entry.name === simpleName3)?.description;
179194
180462
  }
179195
180463
  function selectMemberships(path10, form, globalDescriptions) {
179196
180464
  if (form.wildcard === "none")
@@ -179641,7 +180909,7 @@ function compositionProblemsOf(node, resolve8) {
179641
180909
  }
179642
180910
 
179643
180911
  // ../language-server/out/src/services/validator.js
179644
- var REDEFINITION_KINDS3 = /* @__PURE__ */ new Set([
180912
+ var REDEFINITION_KINDS4 = /* @__PURE__ */ new Set([
179645
180913
  ":>>",
179646
180914
  "redefines",
179647
180915
  ":>",
@@ -179735,7 +181003,7 @@ function maskNonCode(text) {
179735
181003
  }
179736
181004
  return out.join("");
179737
181005
  }
179738
- var SPECIALIZATION_KINDS6 = /* @__PURE__ */ new Set([":>", ":>>", "specializes", "subsets", "redefines"]);
181006
+ var SPECIALIZATION_KINDS7 = /* @__PURE__ */ new Set([":>", ":>>", "specializes", "subsets", "redefines"]);
179739
181007
  var CONSTRAINT_SIDE_EFFECT_TYPES = /* @__PURE__ */ new Set([
179740
181008
  "AssignNode",
179741
181009
  "SendNode",
@@ -179758,6 +181026,60 @@ var CONSTRAINT_SIDE_EFFECT_TYPES = /* @__PURE__ */ new Set([
179758
181026
  "DoAction",
179759
181027
  "ExitAction"
179760
181028
  ]);
181029
+ var BOOLEAN_OPERATORS = /* @__PURE__ */ new Set([
181030
+ "or",
181031
+ "|",
181032
+ "implies",
181033
+ "xor",
181034
+ "and",
181035
+ "&",
181036
+ ">=",
181037
+ "<=",
181038
+ "===",
181039
+ "!==",
181040
+ "==",
181041
+ "!=",
181042
+ ">",
181043
+ "<",
181044
+ "hastype",
181045
+ "istype",
181046
+ "@",
181047
+ "@@"
181048
+ ]);
181049
+ var ARITHMETIC_OPERATORS = /* @__PURE__ */ new Set(["+", "-", "*", "/", "%", "**", "^", ".."]);
181050
+ function nonBooleanExpressionKind(expr) {
181051
+ const node = expr;
181052
+ switch (expr.$type) {
181053
+ case "NumericPrimary":
181054
+ return node.unit ? "a quantity" : "a number";
181055
+ case "LiteralStr":
181056
+ return "a string";
181057
+ case "UnaryMinusExpr":
181058
+ case "UnaryPlusExpr":
181059
+ return "a number";
181060
+ case "ParenExpr": {
181061
+ const items = Array.isArray(node.items) ? node.items : [];
181062
+ return items.length === 1 ? nonBooleanExpressionKind(items[0]) : void 0;
181063
+ }
181064
+ case "BinExpr": {
181065
+ const op = typeof node.op === "string" ? node.op : void 0;
181066
+ if (op && BOOLEAN_OPERATORS.has(op))
181067
+ return void 0;
181068
+ if (op && ARITHMETIC_OPERATORS.has(op)) {
181069
+ return op === ".." ? "a range" : "an arithmetic expression";
181070
+ }
181071
+ return void 0;
181072
+ }
181073
+ default:
181074
+ return void 0;
181075
+ }
181076
+ }
181077
+ function directionOfModifiers(node) {
181078
+ const modifiers2 = node.modifiers;
181079
+ if (!Array.isArray(modifiers2))
181080
+ return void 0;
181081
+ return modifiers2.find((modifier) => modifier === "in" || modifier === "out" || modifier === "inout");
181082
+ }
179761
181083
  var ACTION_BODY_TYPES = /* @__PURE__ */ new Set([
179762
181084
  "ActionDecl",
179763
181085
  "PerformStmt",
@@ -179923,7 +181245,7 @@ var SysmlValidator = class _SysmlValidator {
179923
181245
  // inventory completely. A later segment depends on the KerML semantic model
179924
181246
  // this resolver does not evaluate.
179925
181247
  checkRelationshipTargets(node, accept) {
179926
- if (!node.kind || !REDEFINITION_KINDS3.has(node.kind))
181248
+ if (!node.kind || !REDEFINITION_KINDS4.has(node.kind))
179927
181249
  return;
179928
181250
  for (let ordinal = 0; ordinal < node.targets.length; ordinal += 1) {
179929
181251
  const resolution = this.featurePaths.resolvePropertyPath(node, "targets", ordinal);
@@ -180058,7 +181380,122 @@ var SysmlValidator = class _SysmlValidator {
180058
181380
  accept(severity("SEM010", "warning"), `Constraint '${node.name ?? "(anonymous)"}' must be a pure Boolean expression - '${member.$type}' is a statement with side effects and is not allowed in a constraint body.`, { node: member, code: "SEM010" });
180059
181381
  }
180060
181382
  }
181383
+ const notBoolean = node.body ? nonBooleanExpressionKind(node.body) : void 0;
181384
+ if (node.body?.$cstNode && notBoolean) {
181385
+ accept(severity("SEM015", "error"), DIAGNOSTIC_MESSAGES.SEM015_CONSTRAINT_BODY_NOT_BOOLEAN(node.body.$cstNode.text.replace(/\s+/g, " ").trim(), notBoolean), { node, property: "body", code: "SEM015" });
181386
+ }
181387
+ if (!node.isDef && node.body) {
181388
+ const definition = this.constraintTypeOf(node);
181389
+ if (definition?.body && definition.name) {
181390
+ accept(severity("STYL012", "hint"), DIAGNOSTIC_MESSAGES.STYL012_CONSTRAINT_BODY_OVERRIDES_DEFINITION(node.name ?? "(anonymous)", definition.name), { node, property: "body", code: "STYL012" });
181391
+ }
181392
+ }
180061
181393
  }
181394
+ /** REQ-209 — the constraint definition a usage is typed by, when the link
181395
+ * resolved. Only a direct typing is followed: a deeper specialization chain
181396
+ * is not what "replaces its definition's expression" is about. */
181397
+ constraintTypeOf(node) {
181398
+ const target = node.typing?.type?.ref;
181399
+ return target?.$type === "ConstraintDecl" ? target : void 0;
181400
+ }
181401
+ /* REQ-376 (user direction 2026-09-07) — STYL014: a parameter of a constraint
181402
+ * or a calculation is an INPUT. A constraint's one output is its Boolean
181403
+ * result and a calculation's is its `return`; neither sends anything back
181404
+ * through a parameter, and no model in the OMG corpus declares one `out` or
181405
+ * `inout`.
181406
+ *
181407
+ * Reported where the parameter is DECLARED: on a definition, and on a usage
181408
+ * that declares its own (an untyped `constraint c { out x : T; … }`). A TYPED
181409
+ * usage inherits its parameters, so a direction written there is a
181410
+ * redefinition of one, and `SSM025` already reports that as an error - saying
181411
+ * it twice, once as an error and once as an advisory, helps nobody. */
181412
+ checkParameterDirection(node, accept) {
181413
+ const decl = node;
181414
+ const typed = node.typing?.type?.ref;
181415
+ if (decl.isDef !== true && typed)
181416
+ return;
181417
+ const kind = node.$type === "ConstraintDecl" ? "constraint" : "calculation";
181418
+ const owner = typeof decl.name === "string" && decl.name ? decl.name : "(anonymous)";
181419
+ for (const member of decl.members ?? []) {
181420
+ const direction = directionOfModifiers(member);
181421
+ if (direction !== "out" && direction !== "inout")
181422
+ continue;
181423
+ const name = member.name;
181424
+ if (typeof name !== "string" || !name)
181425
+ continue;
181426
+ accept(severity("STYL014", "hint"), DIAGNOSTIC_MESSAGES.STYL014_PARAMETER_DIRECTION(name, direction, kind, owner), { node: member, code: "STYL014" });
181427
+ }
181428
+ }
181429
+ // REQ-376 — STYL013: a directed parameter is an input a usage binds, not a
181430
+ // value slot. OMG declares them bare on a definition and puts values on
181431
+ // `attribute` members. Only a DEFINITION is flagged: `in x = expr;` on a usage
181432
+ // is the canonical binding form.
181433
+ checkParameterDefaultOnDefinition(node, accept) {
181434
+ const decl = node;
181435
+ if (decl.isDef !== true || typeof decl.name !== "string" || !decl.name)
181436
+ return;
181437
+ for (const member of decl.members ?? []) {
181438
+ const name = member.name;
181439
+ const value = member.value;
181440
+ if (!value || typeof name !== "string" || !name)
181441
+ continue;
181442
+ if (directionOfModifiers(member) === void 0)
181443
+ continue;
181444
+ accept(severity("STYL013", "hint"), DIAGNOSTIC_MESSAGES.STYL013_PARAMETER_DEFAULT_ON_DEFINITION(name, decl.name), { node: member, code: "STYL013" });
181445
+ }
181446
+ }
181447
+ // REQ-415 — issue #164. `assert c;`, `assert not c;`, `require c;` and
181448
+ // `assume c;` name a constraint declared elsewhere (OMG SysML v2 Part 1
181449
+ // §7.20.3, §7.21.2). Three things can go wrong with that name, and all three
181450
+ // were silent: it may resolve to nothing, it may resolve to something that is
181451
+ // not a constraint, and the constraint it resolves to may be decidably false.
181452
+ //
181453
+ // The ROOT link is judged here rather than in `checkWrittenPaths`, which
181454
+ // deliberately leaves a root alone: a root is reported absent only when the
181455
+ // resolver could enumerate the whole surrounding inventory, and that is
181456
+ // exactly the guarantee `unresolvedIndex === 0` carries. It is the same rule
181457
+ // `checkRelationshipTargets` applies to a redefinition target.
181458
+ checkConstraintReference(node, accept) {
181459
+ const reference = constraintReferenceOf(node);
181460
+ if (!reference)
181461
+ return;
181462
+ const resolution = reference.property ? this.featurePaths.resolvePropertyPath(node, reference.property) : this.featurePaths.resolveDeclarationPath(node);
181463
+ if (resolution.segments.length === 0)
181464
+ return;
181465
+ if (resolution.unresolvedIndex === 0) {
181466
+ const invalid = resolution.segments[0];
181467
+ accept(severity("RES001", "error"), DIAGNOSTIC_MESSAGES.RES001_FEATURE_PATH_SEGMENT(invalid.text, "the current scope"), { node, range: invalid.cst.range, code: "RES001", data: { featurePathSegment: true } });
181468
+ return;
181469
+ }
181470
+ if (resolution.unresolvedIndex !== void 0 || resolution.indeterminateIndex !== void 0)
181471
+ return;
181472
+ const last2 = resolution.segments[resolution.segments.length - 1];
181473
+ const target = last2.target;
181474
+ if (target && isWrongKindConstraintTarget(target)) {
181475
+ accept(severity("SSM043", "error"), DIAGNOSTIC_MESSAGES.SSM043_CONSTRAINT_REFERENCE_KIND(reference.kind, reference.path, wrongKindLabel(target)), { node, range: last2.cst.range, code: "SSM043" });
181476
+ }
181477
+ }
181478
+ // REQ-415 — SEM014. An assertion the model can DECIDE and that comes out
181479
+ // false is an inconsistency the author wrote against themselves. Only a
181480
+ // closed constant expression is decided: every feature reference is
181481
+ // inconclusive here, so an assertion that depends on a binding, on time, or
181482
+ // on anything this evaluator does not model stays silent rather than passing
181483
+ // quietly or being reported on a guess.
181484
+ checkAssertionConsistency(node, accept) {
181485
+ if (node.$type !== "AssertConstraintStmt")
181486
+ return;
181487
+ const result = evaluateAssertion(node, this.constraintResolver);
181488
+ if (result?.status !== "fail")
181489
+ return;
181490
+ accept(severity("SEM014", "warning"), DIAGNOSTIC_MESSAGES.SEM014_ASSERTION_VIOLATED(result.text), { node, code: "SEM014" });
181491
+ }
181492
+ // REQ-415 — Resolve a reference shorthand through the shared path resolver,
181493
+ // so a target in another file or in the standard library is evaluated exactly
181494
+ // as a same-file one is.
181495
+ constraintResolver = (reference, member) => {
181496
+ const resolution = reference.property ? this.featurePaths.resolvePropertyPath(member, reference.property) : this.featurePaths.resolveDeclarationPath(member);
181497
+ return resolution.segments[resolution.segments.length - 1]?.target;
181498
+ };
180062
181499
  // REQ-410 — SEM013. A `ref` feature is NON-composite: it names a feature that
180063
181500
  // is owned somewhere else. An unbound one therefore names nothing at all, and
180064
181501
  // the General View cannot draw it as anything: a box would claim the owner
@@ -181199,7 +182636,7 @@ ${baseIndent}}`;
181199
182636
  accept(severity("SYN019", "error"), DIAGNOSTIC_MESSAGES.SYN019_ABSTRACT_VARIATION, { node: child, code: "SYN019" });
181200
182637
  }
181201
182638
  for (const relation of [...decl.preRelationships ?? [], ...decl.relationships ?? []]) {
181202
- if (!relation.kind || !SPECIALIZATION_KINDS6.has(relation.kind))
182639
+ if (!relation.kind || !SPECIALIZATION_KINDS7.has(relation.kind))
181203
182640
  continue;
181204
182641
  for (let index2 = 0; index2 < (relation.targets?.length ?? 0); index2 += 1) {
181205
182642
  const resolution = this.featurePaths.resolvePropertyPath(relation, "targets", index2);
@@ -181557,6 +182994,7 @@ ${baseIndent}}`;
181557
182994
  const decls = [];
181558
182995
  const verifyStmts = [];
181559
182996
  const satisfyStmts = [];
182997
+ const includeStmts = [];
181560
182998
  const aliasMap = /* @__PURE__ */ new Map();
181561
182999
  for (const child of ast_utils_exports.streamAllContents(node)) {
181562
183000
  if (isImport(child)) {
@@ -181580,6 +183018,8 @@ ${baseIndent}}`;
181580
183018
  if (a2.name && a2.target)
181581
183019
  aliasMap.set(a2.name, a2.target);
181582
183020
  }
183021
+ if (child.$type === "IncludeStmt")
183022
+ includeStmts.push(child);
181583
183023
  }
181584
183024
  this.checkAmbiguousReferences(node, imports, index2, accept);
181585
183025
  this.checkPrivateImports(imports, index2, accept);
@@ -181615,7 +183055,7 @@ ${baseIndent}}`;
181615
183055
  this.checkInverseOfTargets(decl, index2, accept);
181616
183056
  this.checkTypeComposition(decl, index2, accept);
181617
183057
  }
181618
- this.checkTypeConformance(decls, index2, accept);
183058
+ this.checkTypeConformance(decls, satisfyStmts, includeStmts, index2, accept);
181619
183059
  }
181620
183060
  // ══════════════════════════════════════════════════════════════════════
181621
183061
  // REQ-390 — SSM017-SSM021: whole-model type conformance (issue #104)
@@ -181625,7 +183065,7 @@ ${baseIndent}}`;
181625
183065
  // the walk, so a type rooted in the unparsed standard library yields
181626
183066
  // `unknown` and no diagnostic. That is what keeps the OMG corpus clean while
181627
183067
  // still catching the workspace-local mistakes these codes exist for.
181628
- checkTypeConformance(decls, index2, accept) {
183068
+ checkTypeConformance(decls, satisfyStmts, includeStmts, index2, accept) {
181629
183069
  const model = new ConformanceModel((name) => this.resolveUnique(name, index2), (node) => this.implicit?.closureOf(node) ?? { names: /* @__PURE__ */ new Set(), complete: true });
181630
183070
  for (const decl of decls) {
181631
183071
  this.checkRedefinitionTypeConformance(decl, model, index2, accept);
@@ -181640,7 +183080,110 @@ ${baseIndent}}`;
181640
183080
  this.checkRedefinitionDirection(decl, index2, accept);
181641
183081
  this.checkInterfaceEndTypes(decl, model, index2, accept);
181642
183082
  this.checkIndividualDefinitions(decl, model, accept);
183083
+ this.checkCaseDefinitionCount(decl, index2, accept);
183084
+ this.checkObjectiveSubject(decl, model, index2, accept);
181643
183085
  }
183086
+ for (const stmt of satisfyStmts)
183087
+ this.checkSatisfierSubjectType(stmt, model, index2, accept);
183088
+ for (const stmt of includeStmts)
183089
+ this.checkIncludeBindings(stmt, model, index2, accept);
183090
+ }
183091
+ // ══════════════════════════════════════════════════════════════════════
183092
+ // REQ-417 — SSM045-SSM048: the bindings a case makes (issue #166)
183093
+ // ══════════════════════════════════════════════════════════════════════
183094
+ // SSM045 — OMG SysML v2 Part 1 §7.22.2: a CaseUsage has exactly one
183095
+ // CaseDefinition. Everything this extension derives about a case usage reads
183096
+ // through that one — its subject, its actor parameters, its objective — so
183097
+ // two leave all three undecided rather than merged. A type this validator
183098
+ // could not read is NOT counted: an unread type is not a wrong one, the same
183099
+ // three-valued rule the rest of this family follows.
183100
+ checkCaseDefinitionCount(decl, index2, accept) {
183101
+ const effective = effectiveCaseDefinition(decl, (name) => this.resolveUnique(name, index2));
183102
+ if (!effective || effective.isDefinition)
183103
+ return;
183104
+ const read = effective.definitions.filter((type) => type.node !== void 0);
183105
+ if (read.length < 2)
183106
+ return;
183107
+ accept(severity("SSM045", "error"), DIAGNOSTIC_MESSAGES.SSM045_CASE_MULTIPLE_DEFINITIONS(decl.name ?? "this case", read[0].name, read[1].name), { node: decl, code: "SSM045" });
183108
+ }
183109
+ // SSM046 — a `verification case` and a `use case` BIND their objective's
183110
+ // subject to their own (`objective obj { subject subj = VerificationCase::subj; }`
183111
+ // in `VerificationCases.sysml`), so a `subject` written on the objective with
183112
+ // an unrelated type states something the case has already decided otherwise.
183113
+ // A generic `case` and an `analysis case` only DEFAULT the objective's subject
183114
+ // to their result, which the model may override, so neither is judged here.
183115
+ checkObjectiveSubject(decl, model, index2, accept) {
183116
+ if (decl.$type !== "ObjectiveDecl")
183117
+ return;
183118
+ const binding = objectiveBindingOf(decl, (name) => this.resolveUnique(name, index2));
183119
+ if (!binding || binding.strength !== "bind" || !binding.own)
183120
+ return;
183121
+ const written = binding.own.typing?.type?.$refText?.trim();
183122
+ if (!written)
183123
+ return;
183124
+ const bound = binding.typeName;
183125
+ if (!bound || bound === DEFAULT_SUBJECT_TYPE)
183126
+ return;
183127
+ if (model.compatible(written, bound) !== "unrelated")
183128
+ return;
183129
+ const caseName = binding.caseNode.name ?? "this case";
183130
+ accept(severity("SSM046", "warning"), DIAGNOSTIC_MESSAGES.SSM046_OBJECTIVE_SUBJECT_TYPE(caseName, written, bound), { node: binding.own, code: "SSM046" });
183131
+ }
183132
+ // SSM047 / SSM048 — OMG SysML v2 Part 1 §7.25 / §8.2.2.25 IncludeUseCaseUsage.
183133
+ // An include is a REFERENCE to a use case performed elsewhere: it keeps that
183134
+ // use case's identity, is investigated on the including case's subject, and
183135
+ // binds that use case's own actor parameters. Both checks stay silent unless
183136
+ // the included use case was actually read.
183137
+ checkIncludeBindings(stmt, model, index2, accept) {
183138
+ const binding = includeBindingOf(stmt, (name) => this.resolveUnique(name, index2));
183139
+ if (!binding?.target)
183140
+ return;
183141
+ const included = binding.path ?? "the included use case";
183142
+ const includedSubject = binding.includedSubject;
183143
+ const containingSubject = binding.containingSubject;
183144
+ if (isDecidedSubject(includedSubject) && isDecidedSubject(containingSubject) && model.compatible(includedSubject.typeName, containingSubject.typeName) === "unrelated") {
183145
+ accept(severity("SSM047", "warning"), DIAGNOSTIC_MESSAGES.SSM047_INCLUDE_SUBJECT_TYPE(included, includedSubject.typeName, containingSubject.typeName), { node: stmt, code: "SSM047" });
183146
+ }
183147
+ if (binding.parameters.length === 0)
183148
+ return;
183149
+ const known2 = binding.parameters.map((parameter) => `'${parameter.name ?? "(anonymous)"}'`).join(", ");
183150
+ for (const actor of binding.actors) {
183151
+ if (!actor.name || actor.parameter)
183152
+ continue;
183153
+ accept(severity("SSM048", "warning"), DIAGNOSTIC_MESSAGES.SSM048_INCLUDE_ACTOR_BINDING(actor.name, included, known2), { node: actor.declaration, code: "SSM048" });
183154
+ }
183155
+ }
183156
+ // REQ-416 — SSM044: `satisfy MassReq by engine;` claims that `engine` is one
183157
+ // of the things `MassReq` constrains, so `engine`'s type has to conform to
183158
+ // the requirement's subject type (OMG SysML v2 Part 1 §7.21.2: the
183159
+ // satisfying feature is bound to the requirement's subject parameter).
183160
+ //
183161
+ // The subject read here is the EFFECTIVE one (issue #165): a requirement
183162
+ // usage inherits the subject its definition declares, and a subrequirement
183163
+ // shares its parent's. A requirement that declares no subject at all
183164
+ // constrains `Anything`, which every satisfier conforms to, so nothing is
183165
+ // reported for one. Like every SSM01x check this stays silent unless the
183166
+ // closure was walked COMPLETELY.
183167
+ checkSatisfierSubjectType(stmt, model, index2, accept) {
183168
+ const intent = satisfyIntentOf(stmt);
183169
+ if (!intent)
183170
+ return;
183171
+ const requirement = this.resolveUnique(intent.path, index2);
183172
+ if (!requirement || requirement.$type !== "RequirementDecl")
183173
+ return;
183174
+ const subject = effectiveSubject(requirement, (name) => this.resolveUnique(name, index2));
183175
+ if (subject.origin === "default" || subject.typeName === DEFAULT_SUBJECT_TYPE)
183176
+ return;
183177
+ const satisfier = intent.enclosingSelf ? intent.enclosing : intent.byName ? this.resolveUnique(intent.byName, index2) : void 0;
183178
+ if (!satisfier)
183179
+ return;
183180
+ const declared = soleDeclaredType(satisfier);
183181
+ if (!declared || declared.conjugated)
183182
+ return;
183183
+ if (model.conforms(declared.text, subject.typeName) !== "unrelated")
183184
+ return;
183185
+ const label = intent.byName ?? satisfier.name ?? "this usage";
183186
+ accept(severity("SSM044", "error"), DIAGNOSTIC_MESSAGES.SSM044_SATISFIER_SUBJECT_TYPE(label, declared.text, intent.path, subject.typeName), { node: stmt, code: "SSM044" });
181644
183187
  }
181645
183188
  // issue #162 — SSM041 / SSM042: the identity an individual usage names.
181646
183189
  //
@@ -182873,7 +184416,16 @@ ${baseIndent}}`;
182873
184416
  // issue #215 — the rest of the reference-form declarations. They share
182874
184417
  // `ReferenceFormPath` with `perform`/`exhibit`, so they can spell the
182875
184418
  // same defect and are judged by the same rule.
182876
- AssertConstraintStmt: this.checkChainSeparators.bind(this),
184419
+ // REQ-415 — issue #164: the constraint reference shorthands. `assert`
184420
+ // shares its `ReferenceFormPath` with the other reference forms, so it
184421
+ // also carries the RES019 separator rule above.
184422
+ AssertConstraintStmt: [
184423
+ this.checkChainSeparators.bind(this),
184424
+ this.checkConstraintReference.bind(this),
184425
+ this.checkAssertionConsistency.bind(this)
184426
+ ],
184427
+ RequireConstraintStmt: this.checkConstraintReference.bind(this),
184428
+ AssumeConstraintStmt: this.checkConstraintReference.bind(this),
182877
184429
  EntryAction: this.checkChainSeparators.bind(this),
182878
184430
  DoAction: this.checkChainSeparators.bind(this),
182879
184431
  ExitAction: this.checkChainSeparators.bind(this),
@@ -182881,7 +184433,17 @@ ${baseIndent}}`;
182881
184433
  ConnectorEnd: this.checkConnectorEndSeparators.bind(this),
182882
184434
  RequirementDecl: this.checkRequirementDecl.bind(this),
182883
184435
  AttributeDecl: this.checkAttributeDecl.bind(this),
182884
- ConstraintDecl: this.checkConstraintDecl.bind(this),
184436
+ // REQ-376 — STYL013 applies to both behavioral definitions that take
184437
+ // parameters, so the constraint check runs beside it here.
184438
+ ConstraintDecl: [
184439
+ this.checkConstraintDecl.bind(this),
184440
+ this.checkParameterDefaultOnDefinition.bind(this),
184441
+ this.checkParameterDirection.bind(this)
184442
+ ],
184443
+ CalcDecl: [
184444
+ this.checkParameterDefaultOnDefinition.bind(this),
184445
+ this.checkParameterDirection.bind(this)
184446
+ ],
182885
184447
  VerificationCaseDecl: this.checkVerificationCaseDecl.bind(this),
182886
184448
  AnalysisCaseDecl: this.checkAnalysisCaseDecl.bind(this),
182887
184449
  ViewDecl: this.checkViewDecl.bind(this),
@@ -183105,7 +184667,7 @@ function specializationTargets4(node) {
183105
184667
  ...node.relationships ?? []
183106
184668
  ];
183107
184669
  for (const rel2 of rels) {
183108
- if (rel2.kind && SPECIALIZATION_KINDS6.has(rel2.kind))
184670
+ if (rel2.kind && SPECIALIZATION_KINDS7.has(rel2.kind))
183109
184671
  out.push(...rel2.targets);
183110
184672
  }
183111
184673
  return out;
@@ -183222,6 +184784,12 @@ var USAGE_DEFINITION_DOMAINS = {
183222
184784
  AllocationDecl: { keyword: "allocation", expected: "an 'allocation def' (a 'connection def' is one)", allowed: /* @__PURE__ */ new Set(["AllocationDecl", "ConnectionDecl"]) },
183223
184785
  ViewDecl: { keyword: "view", expected: "a 'view def'", allowed: /* @__PURE__ */ new Set(["ViewDecl", "PartDecl"]) },
183224
184786
  ViewpointDecl: { keyword: "viewpoint", expected: "a 'viewpoint def' (a 'requirement def' is one)", allowed: /* @__PURE__ */ new Set(["ViewpointDecl", "RequirementDecl", "ConcernDecl"]) },
184787
+ // issue #165 — OMG SysML v2 Part 1 §7.21.1 types `actorParameter` and
184788
+ // `stakeholderParameter` as PART usages: an actor is a part that plays a
184789
+ // role, and a stakeholder is a part that holds an interest. So each names a
184790
+ // part definition, exactly as a `part` usage does.
184791
+ ActorDecl: { keyword: "actor", expected: "a 'part def' (or the 'item def' / 'occurrence def' it specializes)", allowed: /* @__PURE__ */ new Set(["PartDecl", "ItemDecl", "OccurrenceDecl"]) },
184792
+ StakeholderDecl: { keyword: "stakeholder", expected: "a 'part def' (or the 'item def' / 'occurrence def' it specializes)", allowed: /* @__PURE__ */ new Set(["PartDecl", "ItemDecl", "OccurrenceDecl"]) },
183225
184793
  RenderingDecl: { keyword: "rendering", expected: "a 'rendering def'", allowed: /* @__PURE__ */ new Set(["RenderingDecl", "PartDecl"]) },
183226
184794
  MetadataDecl: { keyword: "metadata", expected: "a 'metadata def'", allowed: /* @__PURE__ */ new Set(["MetadataDecl"]) }
183227
184795
  };
@@ -183479,7 +185047,7 @@ function introducedNames(imp, index2, nodeOf) {
183479
185047
  function protectedNamespaceKeysFor(context, globalDescs, nodeOf) {
183480
185048
  const keys3 = /* @__PURE__ */ new Set();
183481
185049
  const visitedTargets = /* @__PURE__ */ new Set();
183482
- const collect = (targetName) => {
185050
+ const collect2 = (targetName) => {
183483
185051
  if (visitedTargets.has(targetName))
183484
185052
  return;
183485
185053
  visitedTargets.add(targetName);
@@ -183491,13 +185059,13 @@ function protectedNamespaceKeysFor(context, globalDescs, nodeOf) {
183491
185059
  if (!node || !isDeclLike(node))
183492
185060
  return;
183493
185061
  for (const inherited of specializationTargets4(node))
183494
- collect(inherited);
185062
+ collect2(inherited);
183495
185063
  };
183496
185064
  let cur = context;
183497
185065
  while (cur) {
183498
185066
  if (isDeclLike(cur)) {
183499
185067
  for (const target of specializationTargets4(cur))
183500
- collect(target);
185068
+ collect2(target);
183501
185069
  }
183502
185070
  cur = cur.$container;
183503
185071
  }
@@ -183598,6 +185166,9 @@ var STYLE_ADVISORY_CODES = /* @__PURE__ */ new Set([
183598
185166
  "STYL009",
183599
185167
  "STYL010",
183600
185168
  "STYL011",
185169
+ "STYL012",
185170
+ "STYL013",
185171
+ "STYL014",
183601
185172
  "LEX009",
183602
185173
  // trailing whitespace
183603
185174
  "SYN024",
@@ -183881,12 +185452,12 @@ function importSignature(imp) {
183881
185452
  const segments = imp.segs.map((seg) => `${seg.name ?? ""}${seg.star ? "*" : ""}${seg.recursive ? "**" : ""}`);
183882
185453
  return `${importVisibility(imp)} ${imp.head}::${segments.join("::")}${imp.alias ? ` as ${imp.alias}` : ""}`;
183883
185454
  }
183884
- var SPECIALIZATION_KINDS7 = /* @__PURE__ */ new Set([":>", ":>>", "specializes", "subsets", "redefines"]);
185455
+ var SPECIALIZATION_KINDS8 = /* @__PURE__ */ new Set([":>", ":>>", "specializes", "subsets", "redefines"]);
183885
185456
  function specializationTargets5(node) {
183886
185457
  const n2 = node;
183887
185458
  const out = [];
183888
185459
  for (const rel2 of [...n2.preRelationships ?? [], ...n2.relationships ?? []]) {
183889
- if (rel2.kind && SPECIALIZATION_KINDS7.has(rel2.kind))
185460
+ if (rel2.kind && SPECIALIZATION_KINDS8.has(rel2.kind))
183890
185461
  out.push(...rel2.targets ?? []);
183891
185462
  }
183892
185463
  return out;
@@ -183920,6 +185491,8 @@ var SysmlScopeComputation = class extends DefaultScopeComputation {
183920
185491
  break;
183921
185492
  if (node.$type === "ShortName" || node.$type === "ImportSeg")
183922
185493
  continue;
185494
+ if (isReferenceFormDeclaration(node))
185495
+ continue;
183923
185496
  const aliases = this.nameAliasesOf(node);
183924
185497
  if (aliases.length === 0)
183925
185498
  continue;
@@ -184174,12 +185747,12 @@ function directImportEntries(imp, descriptions) {
184174
185747
  }
184175
185748
  return applyFilters(imp, selectMemberships(path10, form, descriptions), options);
184176
185749
  }
184177
- var SPECIALIZATION_KINDS8 = /* @__PURE__ */ new Set([":>", ":>>", "specializes", "subsets", "redefines"]);
185750
+ var SPECIALIZATION_KINDS9 = /* @__PURE__ */ new Set([":>", ":>>", "specializes", "subsets", "redefines"]);
184178
185751
  function specializationTargets6(node) {
184179
185752
  const value = node;
184180
185753
  const targets = [];
184181
185754
  for (const relationship of [...value.preRelationships ?? [], ...value.relationships ?? []]) {
184182
- if (relationship.kind && SPECIALIZATION_KINDS8.has(relationship.kind)) {
185755
+ if (relationship.kind && SPECIALIZATION_KINDS9.has(relationship.kind)) {
184183
185756
  targets.push(...relationship.targets ?? []);
184184
185757
  }
184185
185758
  }
@@ -184348,7 +185921,7 @@ var SysmlRenameProvider = class extends DefaultRenameProvider {
184348
185921
  // comparison is against `oldName` directly.
184349
185922
  *writtenPathSegments(root4, oldName) {
184350
185923
  const matching = (segments) => segments.filter((segment) => segment.text === oldName);
184351
- const spellsName = (path10) => !!path10 && pathSegments2(path10).some((step) => canonicalEscapedName(step) === oldName);
185924
+ const spellsName = (path10) => !!path10 && pathSegments3(path10).some((step) => canonicalEscapedName(step) === oldName);
184352
185925
  for (const node of [root4, ...ast_utils_exports.streamAllContents(root4)]) {
184353
185926
  if (isPathExpr(node)) {
184354
185927
  if (!spellsName(node.path))
@@ -184423,7 +185996,7 @@ var SysmlRenameProvider = class extends DefaultRenameProvider {
184423
185996
  return this.references.findDeclaration(leafNode);
184424
185997
  }
184425
185998
  };
184426
- function pathSegments2(path10) {
185999
+ function pathSegments3(path10) {
184427
186000
  const out = [];
184428
186001
  let current2 = "";
184429
186002
  let quoted = false;
@@ -186213,7 +187786,7 @@ function typeAnchor(node, refText) {
186213
187786
  }
186214
187787
  return void 0;
186215
187788
  }
186216
- var REDEFINITION_KINDS4 = /* @__PURE__ */ new Set([":>>", "redefines"]);
187789
+ var REDEFINITION_KINDS5 = /* @__PURE__ */ new Set([":>>", "redefines"]);
186217
187790
  var CONSTANT_CARRYING_KINDS = /* @__PURE__ */ new Set([
186218
187791
  ":>",
186219
187792
  "subsets",
@@ -186602,7 +188175,7 @@ var SysmlInlayHintProvider = class {
186602
188175
  const parameter = mine[index2].node;
186603
188176
  if (!parameter.name || !parameter.$cstNode)
186604
188177
  continue;
186605
- if (allRelationships3(parameter).some((rel2) => rel2.kind && REDEFINITION_KINDS4.has(rel2.kind)))
188178
+ if (allRelationships3(parameter).some((rel2) => rel2.kind && REDEFINITION_KINDS5.has(rel2.kind)))
186606
188179
  continue;
186607
188180
  const target = theirs[index2].node;
186608
188181
  if (!target.name || target.name === parameter.name)
@@ -186845,7 +188418,7 @@ var SysmlInlayHintProvider = class {
186845
188418
  function effectiveNameHint(node, resolver) {
186846
188419
  if (node.name || node.shortName?.name || !node.$cstNode)
186847
188420
  return void 0;
186848
- const redefinition = allRelationships3(node).find((rel2) => rel2.kind && REDEFINITION_KINDS4.has(rel2.kind) && (rel2.targets?.length ?? 0) > 0);
188421
+ const redefinition = allRelationships3(node).find((rel2) => rel2.kind && REDEFINITION_KINDS5.has(rel2.kind) && (rel2.targets?.length ?? 0) > 0);
186849
188422
  if (!redefinition?.targets?.[0])
186850
188423
  return void 0;
186851
188424
  const names = effectiveNamesOf(node, resolver);
@@ -186878,6 +188451,12 @@ var EVAL_LABEL = {
186878
188451
  inconclusive: "$(question) Requirement: inconclusive (values unavailable)",
186879
188452
  unresolved: "$(warning) Requirement: unresolved reference"
186880
188453
  };
188454
+ var NEGATED_EVAL_LABEL = {
188455
+ pass: "$(pass) Requirement not satisfied, as claimed",
188456
+ fail: "$(error) Requirement satisfied, against the claim",
188457
+ inconclusive: EVAL_LABEL.inconclusive,
188458
+ unresolved: EVAL_LABEL.unresolved
188459
+ };
186881
188460
  function indexByName(root4, type) {
186882
188461
  const map3 = /* @__PURE__ */ new Map();
186883
188462
  walkAst(root4, (n2) => {
@@ -186887,11 +188466,6 @@ function indexByName(root4, type) {
186887
188466
  });
186888
188467
  return map3;
186889
188468
  }
186890
- function lastSegment4(path10) {
186891
- if (!path10)
186892
- return void 0;
186893
- return path10.split(/::|\./).pop();
186894
- }
186895
188469
  function qualifiedNameOf2(node) {
186896
188470
  const parts = [];
186897
188471
  let cur = node;
@@ -186977,16 +188551,13 @@ var SysmlCodeLensProvider = class {
186977
188551
  return;
186978
188552
  const range = cst.range;
186979
188553
  if (isSatisfyStmt(node)) {
186980
- const reqName = lastSegment4(node.target);
186981
- const req = reqName ? requirements.get(reqName) : void 0;
186982
- if (req) {
186983
- const bound = bindingName(node.by);
186984
- const subject = bound ? parts.get(bound) : void 0;
186985
- const result = evaluateRequirement(req, subject);
188554
+ const result = evaluateSatisfy(node, (name) => requirements.get(name), (name) => parts.get(name));
188555
+ if (result.requirement) {
188556
+ const labels = node.isNegated ? NEGATED_EVAL_LABEL : EVAL_LABEL;
186986
188557
  lenses.push({
186987
188558
  range,
186988
188559
  command: {
186989
- title: EVAL_LABEL[result.status],
188560
+ title: labels[result.status],
186990
188561
  command: "editor.action.findReferences",
186991
188562
  arguments: [uri, range.start]
186992
188563
  }
@@ -189582,7 +191153,9 @@ function nodeSize(node, direction) {
189582
191153
  const portRunHeight = connectionUsage ? portRows ? portRows * 18 + 6 : 0 : portRows ? compactContainer ? portRows * 24 + 8 : 40 + portRows * 24 + 8 : 0;
189583
191154
  const bodyH = Math.max(
189584
191155
  connectionUsage ? 42 : BOX_H,
189585
- node.value !== void 0 ? 88 : 0,
191156
+ // REQ-209/375 - The value field sits at the bottom of the card, under
191157
+ // whatever compartments it carries, so both have to fit.
191158
+ node.value !== void 0 ? Math.max(88, NODE_COMPARTMENT_TOP + compartmentHeight(node) + 36) : 0,
189586
191159
  featureH === 0 ? NODE_COMPARTMENT_TOP + compartmentHeight(node) : 0,
189587
191160
  portRunHeight,
189588
191161
  portedSideLength(ph, "left"),
@@ -190253,7 +191826,7 @@ function collapseIvModel(model, hiddenInternals) {
190253
191826
  const frames = model.frames ?? [];
190254
191827
  if (!frames.length) return model;
190255
191828
  const frameById = new Map(frames.map((f) => [f.id, f]));
190256
- const requested = new Set(frames.filter((frame2) => framePresentationEnabled(hiddenInternals, frame2, true) && isCollapsibleFrame("iv", frame2)).map((frame2) => frame2.id));
191829
+ const requested = new Set(frames.filter((frame2) => (frame2.meta?.internalsExpandable === false || framePresentationEnabled(hiddenInternals, frame2, true)) && isCollapsibleFrame("iv", frame2)).map((frame2) => frame2.id));
190257
191830
  if (requested.size === 0) return model;
190258
191831
  const hasRequestedAncestor = (id2) => {
190259
191832
  let p = frameById.get(id2)?.parent;
@@ -190316,12 +191889,11 @@ function collapseIvModel(model, hiddenInternals) {
190316
191889
  const toRoot = containerRootOf(e.to);
190317
191890
  if (fromRoot !== void 0 && fromRoot === toRoot) return false;
190318
191891
  return !(hidden.has(e.from) && fromRoot === void 0) && !(hidden.has(e.to) && toRoot === void 0);
190319
- }).map((e) => {
191892
+ }).filter((e) => e.from === e.to || (bodyDock.get(e.from) ?? e.from) !== (bodyDock.get(e.to) ?? e.to)).map((e) => {
190320
191893
  const from = bodyDock.get(e.from) ?? e.from;
190321
191894
  const to = bodyDock.get(e.to) ?? e.to;
190322
191895
  return from === e.from && to === e.to ? e : { ...e, from, to };
190323
191896
  }).filter((e) => {
190324
- if (e.from === e.to) return false;
190325
191897
  const key2 = `${e.from}\0${e.to}\0${e.kind}\0${e.label ?? ""}`;
190326
191898
  if (seenEdge.has(`${key2}:${e.id}`)) return false;
190327
191899
  seenEdge.add(`${key2}:${e.id}`);
@@ -190399,17 +191971,30 @@ function isFeatureCompartmentNode(kind, node) {
190399
191971
  if (kind === "stv") return node.shape === "state";
190400
191972
  return false;
190401
191973
  }
191974
+ function graphicalChildOwners(model) {
191975
+ const owners = /* @__PURE__ */ new Set();
191976
+ for (const node of model.nodes) {
191977
+ const owner = node.frame ?? node.parent;
191978
+ if (owner && owner !== node.id) owners.add(owner);
191979
+ }
191980
+ for (const frame2 of model.frames ?? []) {
191981
+ if (frame2.parent && frame2.parent !== frame2.id) owners.add(frame2.parent);
191982
+ }
191983
+ return owners;
191984
+ }
190402
191985
  function applyFeatureCompartmentVisibility(model, visibleFeatureCompartments, hiddenInternals = {}) {
190403
191986
  if (!CONTAINER_PRESENTATION_KINDS.has(model.kind)) return model;
190404
191987
  const legacy = model.kind === "iv";
191988
+ const owners = graphicalChildOwners(model);
190405
191989
  let changed = false;
190406
191990
  const project = (host, leaf) => {
191991
+ const internalsExpandable = owners.has(host.id);
190407
191992
  const alwaysVisible = host.meta?.alwaysVisibleCompartments === true;
190408
191993
  const defaultVisible = leaf || model.kind === "afv" && !leaf;
190409
191994
  const visible = alwaysVisible || framePresentationEnabled(visibleFeatureCompartments, host, legacy, defaultVisible);
190410
191995
  const compartments = visible ? host.compartments : void 0;
190411
191996
  const internalsHidden = leaf ? framePresentationEnabled(hiddenInternals, host, legacy) : host.meta?.internalsHidden === true;
190412
- if (compartments === host.compartments && host.meta?.containerControls === true && host.meta?.featureCompartmentsVisible === visible && (!leaf || host.meta?.internalsHidden === internalsHidden)) return host;
191997
+ if (compartments === host.compartments && host.meta?.containerControls === true && host.meta?.internalsExpandable === internalsExpandable && host.meta?.featureCompartmentsVisible === visible && (!leaf || host.meta?.internalsHidden === internalsHidden)) return host;
190413
191998
  changed = true;
190414
191999
  return {
190415
192000
  ...host,
@@ -190417,6 +192002,7 @@ function applyFeatureCompartmentVisibility(model, visibleFeatureCompartments, hi
190417
192002
  meta: {
190418
192003
  ...host.meta,
190419
192004
  containerControls: true,
192005
+ internalsExpandable,
190420
192006
  featureCompartmentsVisible: visible,
190421
192007
  ...leaf ? { internalsHidden } : {}
190422
192008
  }
@@ -190432,10 +192018,10 @@ function collapseActionFrames(model, hiddenInternals, isHost = isCollapsibleActi
190432
192018
  if (!frames.length) return model;
190433
192019
  const frameById = new Map(frames.map((f) => [f.id, f]));
190434
192020
  const requested = new Set(
190435
- frames.filter((f) => framePresentationEnabled(hiddenInternals, f) && isHost(f)).map((f) => f.id)
192021
+ frames.filter((f) => (f.meta?.internalsExpandable === false || framePresentationEnabled(hiddenInternals, f)) && isHost(f)).map((f) => f.id)
190436
192022
  );
190437
192023
  if (requested.size === 0) return model;
190438
- const rootOf = (id2) => {
192024
+ const rootOf3 = (id2) => {
190439
192025
  let root4;
190440
192026
  const seen = /* @__PURE__ */ new Set();
190441
192027
  for (let cur = id2; cur !== void 0 && !seen.has(cur); cur = frameById.get(cur)?.parent) {
@@ -190444,13 +192030,13 @@ function collapseActionFrames(model, hiddenInternals, isHost = isCollapsibleActi
190444
192030
  }
190445
192031
  return root4;
190446
192032
  };
190447
- const roots = new Set([...requested].filter((id2) => rootOf(frameById.get(id2)?.parent) === void 0));
192033
+ const roots = new Set([...requested].filter((id2) => rootOf3(frameById.get(id2)?.parent) === void 0));
190448
192034
  const dockOf = /* @__PURE__ */ new Map();
190449
192035
  const proxyHost = /* @__PURE__ */ new Map();
190450
192036
  const ownerOfHiddenPort = /* @__PURE__ */ new Map();
190451
192037
  const hiddenFrameIds = /* @__PURE__ */ new Set();
190452
192038
  for (const f of frames) {
190453
- const root4 = roots.has(f.id) ? rootOf(f.parent) : rootOf(f.id);
192039
+ const root4 = roots.has(f.id) ? rootOf3(f.parent) : rootOf3(f.id);
190454
192040
  if (root4 === void 0) continue;
190455
192041
  hiddenFrameIds.add(f.id);
190456
192042
  dockOf.set(f.id, root4);
@@ -190461,7 +192047,7 @@ function collapseActionFrames(model, hiddenInternals, isHost = isCollapsibleActi
190461
192047
  }
190462
192048
  const hiddenNodeIds = /* @__PURE__ */ new Set();
190463
192049
  for (const n2 of model.nodes) {
190464
- const root4 = rootOf(n2.frame);
192050
+ const root4 = rootOf3(n2.frame);
190465
192051
  if (root4 === void 0) continue;
190466
192052
  hiddenNodeIds.add(n2.id);
190467
192053
  dockOf.set(n2.id, root4);
@@ -190490,12 +192076,11 @@ function collapseActionFrames(model, hiddenInternals, isHost = isCollapsibleActi
190490
192076
  const edges = model.edges.filter((e) => {
190491
192077
  const fromRoot = containerRootOf(e.from);
190492
192078
  return fromRoot === void 0 || fromRoot !== containerRootOf(e.to);
190493
- }).map((e) => {
192079
+ }).filter((e) => e.from === e.to || (dockOf.get(e.from) ?? e.from) !== (dockOf.get(e.to) ?? e.to)).map((e) => {
190494
192080
  const from = dockOf.get(e.from) ?? e.from;
190495
192081
  const to = dockOf.get(e.to) ?? e.to;
190496
192082
  return from === e.from && to === e.to ? e : { ...e, from, to };
190497
192083
  }).filter((e) => {
190498
- if (e.from === e.to) return false;
190499
192084
  const key2 = `${e.from}\0${e.to}\0${e.kind}\0${e.label ?? ""}`;
190500
192085
  if (seenEdge.has(`${key2}:${e.id}`)) return false;
190501
192086
  seenEdge.add(`${key2}:${e.id}`);
@@ -204908,6 +206493,10 @@ function markersFor(kind) {
204908
206493
  // REQ-199
204909
206494
  case "derive":
204910
206495
  // REQ-188
206496
+ case "assert":
206497
+ // REQ-131/REQ-415 — the constraint claims
206498
+ case "assume":
206499
+ case "require":
204911
206500
  case "causation":
204912
206501
  // REQ-189
204913
206502
  case "import":
@@ -205284,7 +206873,7 @@ var KIN_MARKER_DEFS_SVG = [
205284
206873
 
205285
206874
  // ../extension/src/webview/diagram/element-colors.ts
205286
206875
  var ELEMENT_CLOSED_OPACITY = 1;
205287
- var ELEMENT_OPEN_OPACITY = 0.2;
206876
+ var ELEMENT_OPEN_OPACITY = 0.3;
205288
206877
  var DIAGRAM_ELEMENT_COLORS = {
205289
206878
  default: {
205290
206879
  outline: { light: "#3a3a3a", dark: "#a1a1a1" },
@@ -205417,7 +207006,22 @@ var DIAGRAM_LINE_COLORS = {
205417
207006
  },
205418
207007
  dependency: {
205419
207008
  color: { light: "#6b46c1", dark: "#b08cf0" },
205420
- kinds: ["satisfy", "verify", "include", "dependency", "allocate", "frame", "derive", "causation", "import", "expose"],
207009
+ kinds: [
207010
+ "satisfy",
207011
+ "verify",
207012
+ "include",
207013
+ "dependency",
207014
+ "allocate",
207015
+ "frame",
207016
+ "derive",
207017
+ "causation",
207018
+ "import",
207019
+ "expose",
207020
+ // REQ-131/REQ-415 — the constraint claims read as the same family.
207021
+ "assert",
207022
+ "assume",
207023
+ "require"
207024
+ ],
205421
207025
  colorLabels: true
205422
207026
  },
205423
207027
  binding: {
@@ -205844,6 +207448,8 @@ body {
205844
207448
  .dlink.satisfy, .dlink.verify, .dlink.include, .dlink.dependency { stroke-dasharray: 4 3; }
205845
207449
  /* REQ-186/188/189/199/206/210 \u2014 the dashed labelled families */
205846
207450
  .dlink.allocate, .dlink.frame, .dlink.derive, .dlink.causation, .dlink.import, .dlink.expose { stroke-dasharray: 4 3; }
207451
+ /* REQ-131/REQ-415 \u2014 the three constraint claims */
207452
+ .dlink.assert, .dlink.assume, .dlink.require { stroke-dasharray: 4 3; }
205847
207453
  .dlink.annotation { stroke-dasharray: 2 3; }
205848
207454
  .dlink.elaboration { stroke-dasharray: 2 3; pointer-events: none; }
205849
207455
  .dlink.reply { stroke-dasharray: 4 3; } /* REQ-202 \u2014 sequence reply arrows */
@@ -207335,7 +208941,15 @@ var TOOLBOX = {
207335
208941
  rel("verify", "verify", "\u2713", "click the verification case, then the requirement"),
207336
208942
  rel("frame", "frame", "\u274F", "click the requirement/view, then the framed concern"),
207337
208943
  rel("exhibit", "exhibit", "\u25C9", "click the part, then the exhibited state"),
207338
- rel("perform", "perform", "\u25B7", "click the part, then the performed action")
208944
+ rel("perform", "perform", "\u25B7", "click the part, then the performed action"),
208945
+ // REQ-131/REQ-415 (user direction 2026-09-08 — "how do we add assert
208946
+ // constraint from the diagram") — the three constraint CLAIMS. The
208947
+ // diagram drew them in its compartments but could not create one, so
208948
+ // `assert constraint …` could only be typed. Each writes into the
208949
+ // claiming element, exactly as satisfy/verify/frame do.
208950
+ rel("assert", "assert", "\u22A8", "click the element that asserts, then the constraint"),
208951
+ rel("assume", "assume", "\u2283", "click the requirement/concern, then the assumed constraint"),
208952
+ rel("require", "require", "\u22A2", "click the requirement/concern, then the required constraint")
207339
208953
  ]
207340
208954
  },
207341
208955
  // The Interconnection View depicts parts, ports, and the compartment rows of
@@ -207366,7 +208980,12 @@ var TOOLBOX = {
207366
208980
  rel("flow", "flow", "\u2192", "click the source port/feature, then the target"),
207367
208981
  // issue #115 — an item flow that also sequences its ends.
207368
208982
  rel("successionFlow", "succession flow", "\u21C9", "click the source port/feature, then the target"),
207369
- rel("allocate", "allocate", "\u290F", "click the source part/feature, then the target")
208983
+ rel("allocate", "allocate", "\u290F", "click the source part/feature, then the target"),
208984
+ // REQ-131 — the view draws a part's constraints, and OMG's own
208985
+ // parametric picture is a part asserting one and binding its
208986
+ // parameters (ConstraintTest.sysml). `bind` was already here; the
208987
+ // claim that gives it something to bind was not.
208988
+ rel("assert", "assert", "\u22A8", "click the part, then the constraint it asserts")
207370
208989
  ]
207371
208990
  },
207372
208991
  // Action Flow depicts actions (a new `action def` becomes its own tile in a
@@ -207548,7 +209167,10 @@ var CHILD_KINDS = {
207548
209167
  "event occurrence": [],
207549
209168
  requirement: ["requirement", "constraint", "attribute", "part", "actor"],
207550
209169
  concern: ["requirement", "constraint", "attribute", "actor"],
207551
- constraint: ["attribute", "constraint"],
209170
+ // REQ-376 — a constraint and a calculation take INPUTS, and there was no way
209171
+ // to add one from the diagram. Only `in`: an `out` or `inout` parameter on
209172
+ // either is STYL014, so offering one would contradict the check.
209173
+ constraint: ["in parameter", "attribute", "constraint"],
207552
209174
  "use case": CASE_CHILDREN,
207553
209175
  "analysis case": CASE_CHILDREN,
207554
209176
  "verification case": CASE_CHILDREN,
@@ -207560,7 +209182,7 @@ var CHILD_KINDS = {
207560
209182
  // issue (GRV on enum def): an enum def owns enumeration VALUES — nested enum
207561
209183
  // usages — never requirements/parts; the old fallback offered the view list.
207562
209184
  enum: ["enum"],
207563
- calc: ["attribute", "calc"],
209185
+ calc: ["in parameter", "attribute", "calc"],
207564
209186
  connection: ["attribute", "item", "part"],
207565
209187
  connector: ["attribute", "item", "part"],
207566
209188
  interface: ["port", "attribute", "item"],
@@ -207575,6 +209197,10 @@ var CHILD_KINDS = {
207575
209197
  control: [],
207576
209198
  terminate: [],
207577
209199
  pin: [],
209200
+ // REQ-376 — the banner of a constraint/calc parameter card.
209201
+ "in parameter": [],
209202
+ "out parameter": [],
209203
+ "inout parameter": [],
207578
209204
  // REQ-196 — a «performer» swimlane (OMG SysML v2 Part 1 §8.2.3.17, p.90). Its
207579
209205
  // members are the actions that part performs; the edit writes the action into
207580
209206
  // the OWNING action's body and a `perform` for it into the part.
@@ -207687,12 +209313,33 @@ function relationToolsForNode(keyword, viewKind, shape) {
207687
209313
  case "exhibit":
207688
209314
  case "perform":
207689
209315
  return base === "part";
209316
+ // REQ-131 — the OMG corpus asserts inside a part or a package
209317
+ // (ConstraintTest.sysml, MassConstraintExample.sysml); a case and
209318
+ // a requirement own constraints of their own.
209319
+ case "assert":
209320
+ return [
209321
+ "part",
209322
+ "item",
209323
+ "package",
209324
+ "requirement",
209325
+ "concern",
209326
+ "use case",
209327
+ "analysis case",
209328
+ "verification case",
209329
+ "case"
209330
+ ].includes(base);
209331
+ // REQ-131 — OMG SysML 8.2.2.21.1: a RequirementConstraintMembership
209332
+ // belongs to a requirement or a concern.
209333
+ case "assume":
209334
+ case "require":
209335
+ return ["requirement", "concern"].includes(base);
207690
209336
  default:
207691
209337
  return true;
207692
209338
  }
207693
209339
  }
207694
209340
  if (viewKind === "iv") {
207695
209341
  if (!["part", "port", "attribute", "item", "connection"].includes(base)) return false;
209342
+ if (tool.kind === "assert") return base === "part" || base === "item";
207696
209343
  return tool.kind === "interface" ? base === "port" : true;
207697
209344
  }
207698
209345
  if (viewKind === "afv") {
@@ -208127,7 +209774,7 @@ function GvDisclosure({ element, svgWidth }) {
208127
209774
  }
208128
209775
  );
208129
209776
  }
208130
- function AttributeValueEditor({ id: id2, name, value, top }) {
209777
+ function AttributeValueEditor({ id: id2, name, value, top, label = "Value", placeholder = "Add value" }) {
208131
209778
  const { onSetElementValue } = useDiagram();
208132
209779
  const [draft, setDraft] = (0, import_react9.useState)(value);
208133
209780
  if (!onSetElementValue) return null;
@@ -208137,8 +209784,8 @@ function AttributeValueEditor({ id: id2, name, value, top }) {
208137
209784
  type: "text",
208138
209785
  className: "dattribute-value nodrag nopan nowheel",
208139
209786
  style: { top },
208140
- "aria-label": "Value of " + name,
208141
- placeholder: "Add value",
209787
+ "aria-label": label + " of " + name,
209788
+ placeholder,
208142
209789
  value: draft,
208143
209790
  onPointerDown: (event) => event.stopPropagation(),
208144
209791
  onClick: (event) => event.stopPropagation(),
@@ -208549,12 +210196,17 @@ function titleNameLine(name, type, mult, alias, availPx) {
208549
210196
  const shown = fitText(full, availPx, 11);
208550
210197
  return { full, shown, clipped: shown !== full };
208551
210198
  }
208552
- function AttributeValueShape({ value, w, top }) {
208553
- const shown = fitText(value || "Add value", Math.max(16, w - 32), 11);
210199
+ function valueFieldRole(keyword) {
210200
+ if (keyword.startsWith("constraint")) return { label: "Constraint", placeholder: "Add constraint" };
210201
+ if (keyword.startsWith("calc")) return { label: "Expression", placeholder: "Add expression" };
210202
+ return { label: "Value", placeholder: "Add value" };
210203
+ }
210204
+ function AttributeValueShape({ value, w, top, placeholder = "Add value" }) {
210205
+ const shown = fitText(value || placeholder, Math.max(16, w - 32), 11);
208554
210206
  return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("g", { className: "dattribute-value-shape", children: [
208555
210207
  /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("rect", { x: 8, y: top, width: Math.max(1, w - 16), height: 28, rx: 3 }),
208556
210208
  /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("text", { x: 15, y: top + 18, className: "dnode-label", children: [
208557
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("title", { children: value || "Add value" }),
210209
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("title", { children: value || placeholder }),
208558
210210
  shown
208559
210211
  ] })
208560
210212
  ] });
@@ -208601,7 +210253,15 @@ function BoxBody({ node, w, h, showMult }) {
208601
210253
  ] })
208602
210254
  ] }),
208603
210255
  /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Compartments, { node, w, ruleClass }),
208604
- node.value !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(AttributeValueShape, { value: node.value, w, top: h - 36 }) : null
210256
+ node.value !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
210257
+ AttributeValueShape,
210258
+ {
210259
+ value: node.value,
210260
+ w,
210261
+ top: h - 36,
210262
+ placeholder: valueFieldRole(node.keyword).placeholder
210263
+ }
210264
+ ) : null
208605
210265
  ] });
208606
210266
  }
208607
210267
  function RoundedBody({ node, w, h, cls, showMult }) {
@@ -208785,7 +210445,7 @@ function SendAcceptBody({ node, w, h, accept }) {
208785
210445
  }
208786
210446
  function PackageBody({ node, w, h }) {
208787
210447
  if (node.meta?.gvMode !== void 0) {
208788
- const title = fitText(node.name, Math.max(24, w - 42), 11);
210448
+ const title = fitText(node.name, Math.max(24, w - (node.meta?.gvCanExpand === true ? 42 : 20)), 11);
208789
210449
  return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("g", { children: [
208790
210450
  /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { className: "dnode-rect package", d: packageFramePath(w, h) }),
208791
210451
  /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("text", { className: "dnode-kind", x: 10, y: 12, children: "\xABpackage\xBB" }),
@@ -209555,7 +211215,7 @@ function SysmlNode({ id: id2, data, draggable, selected: selected2, width, heigh
209555
211215
  internalsVisible: !hiddenContainer,
209556
211216
  featureCompartmentsVisible,
209557
211217
  cornerRadius: nodeCornerRadius(node.shape, node.isDef, h, (node.compartments?.length ?? 0) > 0),
209558
- onToggleInternals: ctx.onToggleInternals,
211218
+ onToggleInternals: node.meta?.internalsExpandable === true ? ctx.onToggleInternals : void 0,
209559
211219
  onToggleFeatureCompartments: ctx.onToggleFeatureCompartments
209560
211220
  }
209561
211221
  ) : null,
@@ -209565,7 +211225,8 @@ function SysmlNode({ id: id2, data, draggable, selected: selected2, width, heigh
209565
211225
  id: id2,
209566
211226
  name: node.name,
209567
211227
  value: node.value,
209568
- top: h - 36
211228
+ top: h - 36,
211229
+ ...valueFieldRole(node.keyword)
209569
211230
  },
209570
211231
  id2 + ":" + node.value
209571
211232
  ) : null,
@@ -209812,7 +211473,15 @@ function FrameNode({ id: id2, data, selected: selected2, width, height }) {
209812
211473
  strokeWidth: 0.8
209813
211474
  }
209814
211475
  ) : null,
209815
- frame2.value !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(AttributeValueShape, { value: frame2.value, w, top: frameHeaderHeight - 34 }) : null,
211476
+ frame2.value !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
211477
+ AttributeValueShape,
211478
+ {
211479
+ value: frame2.value,
211480
+ w,
211481
+ top: frameHeaderHeight - 34,
211482
+ placeholder: valueFieldRole(frame2.keyword).placeholder
211483
+ }
211484
+ ) : null,
209816
211485
  isStructuredControl ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("g", { className: "dstructured-condition-compartment", children: [
209817
211486
  isNamedStructuredAction ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
209818
211487
  "line",
@@ -210078,7 +211747,7 @@ function FrameNode({ id: id2, data, selected: selected2, width, height }) {
210078
211747
  internalsVisible: true,
210079
211748
  featureCompartmentsVisible,
210080
211749
  cornerRadius: frame2.isDef === true ? 0 : FRAME_USAGE_CORNER_RADIUS,
210081
- onToggleInternals: ctx.onToggleInternals,
211750
+ onToggleInternals: frame2.meta?.internalsExpandable === true ? ctx.onToggleInternals : void 0,
210082
211751
  onToggleFeatureCompartments: ctx.onToggleFeatureCompartments
210083
211752
  }
210084
211753
  ) : null,
@@ -210088,7 +211757,8 @@ function FrameNode({ id: id2, data, selected: selected2, width, height }) {
210088
211757
  id: id2,
210089
211758
  name: frame2.label,
210090
211759
  value: frame2.value,
210091
- top: frameHeaderHeight - 34
211760
+ top: frameHeaderHeight - 34,
211761
+ ...valueFieldRole(frame2.keyword)
210092
211762
  },
210093
211763
  id2 + ":" + frame2.value
210094
211764
  ) : null,
@@ -210783,7 +212453,7 @@ async function runExport(command) {
210783
212453
  }
210784
212454
 
210785
212455
  // src/main.ts
210786
- var VERSION2 = true ? "0.35.0" : "dev";
212456
+ var VERSION2 = true ? "0.38.0" : "dev";
210787
212457
  function display(file) {
210788
212458
  const rel2 = path9.relative(process.cwd(), file);
210789
212459
  return rel2 && !rel2.startsWith("..") ? rel2.split(path9.sep).join("/") : file;