sysml-diagram 0.36.0 → 0.39.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 +1496 -107
- package/out/main.js.map +4 -4
- package/package.json +1 -1
- package/resources/sysml.dimension-table.json +1 -1
package/out/main.js
CHANGED
|
@@ -161054,6 +161054,128 @@ 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 isInlineConstraintClaim(node) {
|
|
161064
|
+
return REFERENCE_KEYWORDS[node.$type] !== void 0 && node.constraintKw === true;
|
|
161065
|
+
}
|
|
161066
|
+
function constraintReferenceOf(node) {
|
|
161067
|
+
const kind = REFERENCE_KEYWORDS[node.$type];
|
|
161068
|
+
if (!kind)
|
|
161069
|
+
return void 0;
|
|
161070
|
+
const shape = node;
|
|
161071
|
+
if (shape.constraintKw)
|
|
161072
|
+
return void 0;
|
|
161073
|
+
const negated = shape.isNegated === true;
|
|
161074
|
+
if (kind === "assert") {
|
|
161075
|
+
if (!shape.name)
|
|
161076
|
+
return void 0;
|
|
161077
|
+
const links = [shape.name, ...shape.chainSegs ?? []];
|
|
161078
|
+
return { kind, negated, path: links.join("::"), simpleName: links[links.length - 1] };
|
|
161079
|
+
}
|
|
161080
|
+
const target = shape.target;
|
|
161081
|
+
if (typeof target !== "string" || target.length === 0)
|
|
161082
|
+
return void 0;
|
|
161083
|
+
return {
|
|
161084
|
+
kind,
|
|
161085
|
+
negated,
|
|
161086
|
+
property: "target",
|
|
161087
|
+
path: target,
|
|
161088
|
+
simpleName: lastLink(target)
|
|
161089
|
+
};
|
|
161090
|
+
}
|
|
161091
|
+
function lastLink(path10) {
|
|
161092
|
+
return path10.split(/::|\./u).filter(Boolean).pop() ?? path10;
|
|
161093
|
+
}
|
|
161094
|
+
var NON_CONSTRAINT_DECL_TYPES = /* @__PURE__ */ new Set([
|
|
161095
|
+
"Package",
|
|
161096
|
+
"NamespaceDecl",
|
|
161097
|
+
"Document",
|
|
161098
|
+
"Import",
|
|
161099
|
+
"PartDecl",
|
|
161100
|
+
"ItemDecl",
|
|
161101
|
+
"AttributeDecl",
|
|
161102
|
+
"PortDecl",
|
|
161103
|
+
"OccurrenceDecl",
|
|
161104
|
+
"InterfaceDecl",
|
|
161105
|
+
"ConnectionDecl",
|
|
161106
|
+
"AllocationDecl",
|
|
161107
|
+
"ConnectorDecl",
|
|
161108
|
+
"EnumDecl",
|
|
161109
|
+
"EnumValueDecl",
|
|
161110
|
+
"MetadataDecl",
|
|
161111
|
+
"MultiplicityDecl",
|
|
161112
|
+
"ActionDecl",
|
|
161113
|
+
"StateDecl",
|
|
161114
|
+
"CalcDecl",
|
|
161115
|
+
"CaseDecl",
|
|
161116
|
+
"UseCaseDecl",
|
|
161117
|
+
"AnalysisCaseDecl",
|
|
161118
|
+
"VerificationCaseDecl",
|
|
161119
|
+
"ViewDecl",
|
|
161120
|
+
"ViewpointDecl",
|
|
161121
|
+
"RenderingDecl",
|
|
161122
|
+
"ActorDecl",
|
|
161123
|
+
"StakeholderDecl",
|
|
161124
|
+
"StructDecl",
|
|
161125
|
+
"ClassDecl",
|
|
161126
|
+
"DatatypeDecl",
|
|
161127
|
+
"AssociationDecl",
|
|
161128
|
+
"MetaclassDecl",
|
|
161129
|
+
"BehaviorDecl",
|
|
161130
|
+
"FunctionDecl",
|
|
161131
|
+
"InteractionDecl"
|
|
161132
|
+
]);
|
|
161133
|
+
var NON_CONSTRAINT_LABELS = {
|
|
161134
|
+
Package: "a package",
|
|
161135
|
+
NamespaceDecl: "a namespace",
|
|
161136
|
+
Document: "a file root namespace",
|
|
161137
|
+
Import: "an import",
|
|
161138
|
+
PartDecl: "a part",
|
|
161139
|
+
ItemDecl: "an item",
|
|
161140
|
+
AttributeDecl: "an attribute",
|
|
161141
|
+
PortDecl: "a port",
|
|
161142
|
+
OccurrenceDecl: "an occurrence",
|
|
161143
|
+
InterfaceDecl: "an interface",
|
|
161144
|
+
ConnectionDecl: "a connection",
|
|
161145
|
+
AllocationDecl: "an allocation",
|
|
161146
|
+
ConnectorDecl: "a connector",
|
|
161147
|
+
EnumDecl: "an enumeration",
|
|
161148
|
+
EnumValueDecl: "an enumeration value",
|
|
161149
|
+
MetadataDecl: "a metadata usage",
|
|
161150
|
+
MultiplicityDecl: "a multiplicity",
|
|
161151
|
+
ActionDecl: "an action",
|
|
161152
|
+
StateDecl: "a state",
|
|
161153
|
+
CalcDecl: "a calculation",
|
|
161154
|
+
CaseDecl: "a case",
|
|
161155
|
+
UseCaseDecl: "a use case",
|
|
161156
|
+
AnalysisCaseDecl: "an analysis case",
|
|
161157
|
+
VerificationCaseDecl: "a verification case",
|
|
161158
|
+
ViewDecl: "a view",
|
|
161159
|
+
ViewpointDecl: "a viewpoint",
|
|
161160
|
+
RenderingDecl: "a rendering",
|
|
161161
|
+
ActorDecl: "an actor",
|
|
161162
|
+
StakeholderDecl: "a stakeholder",
|
|
161163
|
+
StructDecl: "a structure",
|
|
161164
|
+
ClassDecl: "a class",
|
|
161165
|
+
DatatypeDecl: "a datatype",
|
|
161166
|
+
AssociationDecl: "an association",
|
|
161167
|
+
MetaclassDecl: "a metaclass",
|
|
161168
|
+
BehaviorDecl: "a behavior",
|
|
161169
|
+
FunctionDecl: "a function",
|
|
161170
|
+
InteractionDecl: "an interaction"
|
|
161171
|
+
};
|
|
161172
|
+
function isWrongKindConstraintTarget(node) {
|
|
161173
|
+
return NON_CONSTRAINT_DECL_TYPES.has(node.$type);
|
|
161174
|
+
}
|
|
161175
|
+
function wrongKindLabel(node) {
|
|
161176
|
+
return NON_CONSTRAINT_LABELS[node.$type] ?? "not a constraint";
|
|
161177
|
+
}
|
|
161178
|
+
|
|
161057
161179
|
// ../language-server/out/src/services/requirement-semantics.js
|
|
161058
161180
|
var DEFAULT_SUBJECT_TYPE = "Anything";
|
|
161059
161181
|
var MAX_INHERITANCE_DEPTH = 16;
|
|
@@ -161071,6 +161193,16 @@ var REQUIREMENT_SHAPED = /* @__PURE__ */ new Set([
|
|
|
161071
161193
|
"ObjectiveDecl",
|
|
161072
161194
|
"ViewpointDecl"
|
|
161073
161195
|
]);
|
|
161196
|
+
var CASE_SHAPED = /* @__PURE__ */ new Set([
|
|
161197
|
+
"CaseDecl",
|
|
161198
|
+
"AnalysisCaseDecl",
|
|
161199
|
+
"VerificationCaseDecl",
|
|
161200
|
+
"UseCaseDecl"
|
|
161201
|
+
]);
|
|
161202
|
+
var SUBJECT_SHAPED = /* @__PURE__ */ new Set([
|
|
161203
|
+
...REQUIREMENT_SHAPED,
|
|
161204
|
+
...CASE_SHAPED
|
|
161205
|
+
]);
|
|
161074
161206
|
var CONSTRAINT_SHAPED = /* @__PURE__ */ new Set([
|
|
161075
161207
|
"ConstraintDecl",
|
|
161076
161208
|
"InvShorthand",
|
|
@@ -161178,9 +161310,10 @@ function referencePathOf(member) {
|
|
|
161178
161310
|
return target.trim() || void 0;
|
|
161179
161311
|
if (target && typeof target === "object") {
|
|
161180
161312
|
const text = target.$refText?.trim();
|
|
161181
|
-
|
|
161313
|
+
if (text)
|
|
161314
|
+
return text;
|
|
161182
161315
|
}
|
|
161183
|
-
return
|
|
161316
|
+
return constraintReferenceOf(member)?.path;
|
|
161184
161317
|
}
|
|
161185
161318
|
function referenceTargetOf(member, resolve8) {
|
|
161186
161319
|
const target = member.target;
|
|
@@ -161361,7 +161494,7 @@ function inheritedSubject(node, resolve8, depth, seen) {
|
|
|
161361
161494
|
return void 0;
|
|
161362
161495
|
seen.add(node);
|
|
161363
161496
|
for (const supertype of supertypesOf(node, resolve8)) {
|
|
161364
|
-
if (!
|
|
161497
|
+
if (!SUBJECT_SHAPED.has(supertype.$type))
|
|
161365
161498
|
continue;
|
|
161366
161499
|
const own = ownSubject(supertype);
|
|
161367
161500
|
if (own)
|
|
@@ -161685,7 +161818,7 @@ function memberNamed(node, name, seen = /* @__PURE__ */ new Set()) {
|
|
|
161685
161818
|
const typeRef = node.typing?.type?.ref;
|
|
161686
161819
|
return typeRef ? memberNamed(typeRef, name, seen) : void 0;
|
|
161687
161820
|
}
|
|
161688
|
-
function resolveFeatureValue(root4, segments) {
|
|
161821
|
+
function resolveFeatureValue(root4, segments, ext) {
|
|
161689
161822
|
let cur = root4;
|
|
161690
161823
|
for (const seg of segments) {
|
|
161691
161824
|
cur = memberNamed(cur, seg);
|
|
@@ -161693,7 +161826,7 @@ function resolveFeatureValue(root4, segments) {
|
|
|
161693
161826
|
return UNRESOLVED;
|
|
161694
161827
|
}
|
|
161695
161828
|
if (cur.value)
|
|
161696
|
-
return evaluateExpr(cur.value, () => INCONCLUSIVE);
|
|
161829
|
+
return evaluateExpr(cur.value, () => INCONCLUSIVE, ext);
|
|
161697
161830
|
return INCONCLUSIVE;
|
|
161698
161831
|
}
|
|
161699
161832
|
function subjectScope(subjectName, subjectBinding) {
|
|
@@ -161788,6 +161921,83 @@ function evaluateSatisfy(stmt, resolveRequirement, resolvePart, resolve8) {
|
|
|
161788
161921
|
const status = result.status === "pass" ? "fail" : result.status === "fail" ? "pass" : result.status;
|
|
161789
161922
|
return { status, requirement, satisfier };
|
|
161790
161923
|
}
|
|
161924
|
+
var CONSTRAINT_SHAPED_TYPES = /* @__PURE__ */ new Set([
|
|
161925
|
+
"ConstraintDecl",
|
|
161926
|
+
"InvShorthand",
|
|
161927
|
+
"RequirementDecl",
|
|
161928
|
+
"ConcernDecl",
|
|
161929
|
+
"PredicateDecl",
|
|
161930
|
+
"AssertConstraintStmt",
|
|
161931
|
+
"RequireConstraintStmt",
|
|
161932
|
+
"AssumeConstraintStmt"
|
|
161933
|
+
]);
|
|
161934
|
+
function exprText2(node) {
|
|
161935
|
+
return node?.$cstNode?.text?.trim() ?? "";
|
|
161936
|
+
}
|
|
161937
|
+
function rootOf2(node) {
|
|
161938
|
+
let current2 = node;
|
|
161939
|
+
while (current2.$container)
|
|
161940
|
+
current2 = current2.$container;
|
|
161941
|
+
return current2;
|
|
161942
|
+
}
|
|
161943
|
+
function* walkMembers(node) {
|
|
161944
|
+
for (const member of [...node.elements ?? [], ...node.members ?? []]) {
|
|
161945
|
+
yield member;
|
|
161946
|
+
yield* walkMembers(member);
|
|
161947
|
+
}
|
|
161948
|
+
}
|
|
161949
|
+
function documentConstraintResolver() {
|
|
161950
|
+
return (reference, member) => {
|
|
161951
|
+
for (const candidate of walkMembers(rootOf2(member))) {
|
|
161952
|
+
if (candidate.name === reference.simpleName && CONSTRAINT_SHAPED_TYPES.has(candidate.$type)) {
|
|
161953
|
+
return candidate;
|
|
161954
|
+
}
|
|
161955
|
+
}
|
|
161956
|
+
return void 0;
|
|
161957
|
+
};
|
|
161958
|
+
}
|
|
161959
|
+
var assertionExpression = (node) => {
|
|
161960
|
+
const expr = node;
|
|
161961
|
+
return (expr.$type === "NumericPrimary" || expr.$type === "PostfixOp") && expr.unit ? INCONCLUSIVE : void 0;
|
|
161962
|
+
};
|
|
161963
|
+
function evaluateAssertion(node, resolveConstraint = documentConstraintResolver()) {
|
|
161964
|
+
const member = node;
|
|
161965
|
+
if (member.$type !== "AssertConstraintStmt")
|
|
161966
|
+
return void 0;
|
|
161967
|
+
const reference = constraintReferenceOf(member);
|
|
161968
|
+
const negated = reference?.negated ?? member.isNegated === true;
|
|
161969
|
+
let body;
|
|
161970
|
+
let text;
|
|
161971
|
+
let target;
|
|
161972
|
+
if (reference) {
|
|
161973
|
+
text = `${reference.kind}${reference.negated ? " not" : ""} ${reference.path}`;
|
|
161974
|
+
target = resolveConstraint(reference, member);
|
|
161975
|
+
if (!target)
|
|
161976
|
+
return { status: "unresolved", text };
|
|
161977
|
+
body = member.body ?? constraintBodyOf(target, documentResolver(member));
|
|
161978
|
+
} else {
|
|
161979
|
+
body = member.body;
|
|
161980
|
+
text = exprText2(member.body);
|
|
161981
|
+
}
|
|
161982
|
+
if (!body)
|
|
161983
|
+
return { status: "inconclusive", text };
|
|
161984
|
+
const scope = (segments) => {
|
|
161985
|
+
for (const owner of [member, target]) {
|
|
161986
|
+
if (!owner)
|
|
161987
|
+
continue;
|
|
161988
|
+
if (memberNamed(owner, segments[0])) {
|
|
161989
|
+
return resolveFeatureValue(owner, segments, assertionExpression);
|
|
161990
|
+
}
|
|
161991
|
+
}
|
|
161992
|
+
return INCONCLUSIVE;
|
|
161993
|
+
};
|
|
161994
|
+
const value = negate2(evaluateExpr(body, scope, assertionExpression), negated);
|
|
161995
|
+
if (value.kind === "unresolved")
|
|
161996
|
+
return { status: "unresolved", text };
|
|
161997
|
+
if (value.kind !== "boolean")
|
|
161998
|
+
return { status: "inconclusive", text };
|
|
161999
|
+
return { status: value.value ? "pass" : "fail", text };
|
|
162000
|
+
}
|
|
161791
162001
|
function bindingName(by) {
|
|
161792
162002
|
const n2 = by;
|
|
161793
162003
|
if (n2?.$type !== "PathExpr")
|
|
@@ -163036,6 +163246,21 @@ function unwrap(node) {
|
|
|
163036
163246
|
}
|
|
163037
163247
|
var namedChildrenByNode = /* @__PURE__ */ new WeakMap();
|
|
163038
163248
|
var childrenByName = /* @__PURE__ */ new WeakMap();
|
|
163249
|
+
var REFERENCE_FORM_DECLARATIONS = {
|
|
163250
|
+
PerformStmt: "actionKw",
|
|
163251
|
+
EntryAction: "actionKw",
|
|
163252
|
+
DoAction: "actionKw",
|
|
163253
|
+
ExitAction: "actionKw",
|
|
163254
|
+
ExhibitStateDecl: "stateKw",
|
|
163255
|
+
AssertConstraintStmt: "constraintKw",
|
|
163256
|
+
EventDecl: "isOccurrence"
|
|
163257
|
+
};
|
|
163258
|
+
function isReferenceFormDeclaration(node) {
|
|
163259
|
+
const keyword = REFERENCE_FORM_DECLARATIONS[node.$type];
|
|
163260
|
+
if (!keyword)
|
|
163261
|
+
return false;
|
|
163262
|
+
return node[keyword] !== true;
|
|
163263
|
+
}
|
|
163039
163264
|
function directNamedChildren(node) {
|
|
163040
163265
|
const cached = namedChildrenByNode.get(node);
|
|
163041
163266
|
if (cached)
|
|
@@ -163044,6 +163269,8 @@ function directNamedChildren(node) {
|
|
|
163044
163269
|
const seen = /* @__PURE__ */ new Set();
|
|
163045
163270
|
for (const raw of ast_utils_exports.streamContents(node)) {
|
|
163046
163271
|
const child = unwrap(raw);
|
|
163272
|
+
if (isReferenceFormDeclaration(child))
|
|
163273
|
+
continue;
|
|
163047
163274
|
if (!nameOf(child) || seen.has(child))
|
|
163048
163275
|
continue;
|
|
163049
163276
|
seen.add(child);
|
|
@@ -163525,7 +163752,7 @@ var FeaturePathResolver = class {
|
|
|
163525
163752
|
}
|
|
163526
163753
|
for (let owner = node.$container; owner; owner = owner.$container) {
|
|
163527
163754
|
const declaredName3 = owner.name;
|
|
163528
|
-
if (typeof declaredName3 === "string" && canonicalEscapedName(declaredName3) === name && !isSelfReference(owner, node)) {
|
|
163755
|
+
if (typeof declaredName3 === "string" && canonicalEscapedName(declaredName3) === name && !isReferenceFormDeclaration(owner) && !isSelfReference(owner, node)) {
|
|
163529
163756
|
return this.targetForNode(owner, this.memberInventoryKnown(owner, snapshot));
|
|
163530
163757
|
}
|
|
163531
163758
|
if (boundVariableName(owner) === name) {
|
|
@@ -163877,6 +164104,28 @@ var FeaturePathResolver = class {
|
|
|
163877
164104
|
}
|
|
163878
164105
|
};
|
|
163879
164106
|
|
|
164107
|
+
// ../language-server/out/src/services/calculation-semantics.js
|
|
164108
|
+
function effectiveCalculationResult(node, resolve8) {
|
|
164109
|
+
const seen = /* @__PURE__ */ new Set();
|
|
164110
|
+
const walk = (current2, depth) => {
|
|
164111
|
+
if (depth > 32 || seen.has(current2))
|
|
164112
|
+
return void 0;
|
|
164113
|
+
seen.add(current2);
|
|
164114
|
+
const parameter = current2.members?.find((member) => member.$type === "ReturnDecl");
|
|
164115
|
+
if (parameter || current2.body)
|
|
164116
|
+
return {
|
|
164117
|
+
parameter,
|
|
164118
|
+
expression: parameter?.value ?? current2.body,
|
|
164119
|
+
inherited: current2 !== node
|
|
164120
|
+
};
|
|
164121
|
+
const parents = supertypesOf(current2, resolve8).filter((parent) => parent.$type === "CalcDecl");
|
|
164122
|
+
if (parents.length !== 1)
|
|
164123
|
+
return void 0;
|
|
164124
|
+
return walk(parents[0], depth + 1);
|
|
164125
|
+
};
|
|
164126
|
+
return walk(node, 0);
|
|
164127
|
+
}
|
|
164128
|
+
|
|
163880
164129
|
// ../language-server/out/src/platform/platform.js
|
|
163881
164130
|
var current;
|
|
163882
164131
|
function setPlatform(platform) {
|
|
@@ -166341,6 +166590,16 @@ var directionOf = (node) => {
|
|
|
166341
166590
|
return void 0;
|
|
166342
166591
|
return mods.find((m) => m === "in" || m === "out" || m === "inout");
|
|
166343
166592
|
};
|
|
166593
|
+
function parameterKeyword(node) {
|
|
166594
|
+
const direction = directionOf(node);
|
|
166595
|
+
if (!direction)
|
|
166596
|
+
return void 0;
|
|
166597
|
+
let owner = node.$container;
|
|
166598
|
+
while (owner?.$type === "PrefixMetadataMember" || owner?.$type === "MemberPrefixDecl") {
|
|
166599
|
+
owner = owner.$container;
|
|
166600
|
+
}
|
|
166601
|
+
return owner && (isConstraintDecl(owner) || isCalcDecl(owner)) ? `${direction} parameter` : void 0;
|
|
166602
|
+
}
|
|
166344
166603
|
function keywordFor(node) {
|
|
166345
166604
|
const n2 = node;
|
|
166346
166605
|
if (node.$type === "VariantReference")
|
|
@@ -166402,6 +166661,9 @@ function keywordFor(node) {
|
|
|
166402
166661
|
DoAction: "do action",
|
|
166403
166662
|
ExitAction: "exit action"
|
|
166404
166663
|
};
|
|
166664
|
+
const parameter = parameterKeyword(node);
|
|
166665
|
+
if (parameter)
|
|
166666
|
+
return parameter;
|
|
166405
166667
|
if (t === "ActionDecl" && n2.inlineBody?.$type === "AcceptNode") {
|
|
166406
166668
|
return "accept action";
|
|
166407
166669
|
}
|
|
@@ -166434,6 +166696,7 @@ var isBareDefDecl = (node) => node.$type === "BareDefDecl";
|
|
|
166434
166696
|
var isDefinitionNode = (node) => isDefinitionKind(node) && node.isDef === true || isBareDefDecl(node);
|
|
166435
166697
|
var ACTION_FLOW_STEP_TYPES = /* @__PURE__ */ new Set([
|
|
166436
166698
|
"ActionDecl",
|
|
166699
|
+
"CalcDecl",
|
|
166437
166700
|
"PerformStmt",
|
|
166438
166701
|
"AssignNode",
|
|
166439
166702
|
"SendNode",
|
|
@@ -167348,8 +167611,8 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
167348
167611
|
case "iv":
|
|
167349
167612
|
return firstContent(isPartDecl) ?? firstContent(isPackage) ?? firstThat(isPartDecl) ?? firstThat(isPackage) ?? root4;
|
|
167350
167613
|
case "afv":
|
|
167351
|
-
return firstContent((n2) => isActionDecl(n2) || this.isCaseLike(n2)) ?? firstContent(isPartDecl) ?? // REQ-196 — action flow over a part's performers
|
|
167352
|
-
firstThat((n2) => isActionDecl(n2) || this.isCaseLike(n2)) ?? root4;
|
|
167614
|
+
return firstContent((n2) => isActionDecl(n2) || isCalcDecl(n2) || this.isCaseLike(n2)) ?? firstContent(isPartDecl) ?? // REQ-196 — action flow over a part's performers
|
|
167615
|
+
firstThat((n2) => isActionDecl(n2) || isCalcDecl(n2) || this.isCaseLike(n2)) ?? root4;
|
|
167353
167616
|
case "stv":
|
|
167354
167617
|
return firstContent((n2) => isExhibitStateDecl(n2) || isStateDecl(n2)) ?? firstThat((n2) => isExhibitStateDecl(n2) || isStateDecl(n2)) ?? root4;
|
|
167355
167618
|
case "sv":
|
|
@@ -167399,7 +167662,7 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
167399
167662
|
case "iv":
|
|
167400
167663
|
return isPartDecl(node);
|
|
167401
167664
|
case "afv":
|
|
167402
|
-
return isActionDecl(node) || isPartDecl(node) || this.isCaseLike(node);
|
|
167665
|
+
return isActionDecl(node) || isCalcDecl(node) || isPartDecl(node) || this.isCaseLike(node);
|
|
167403
167666
|
case "stv":
|
|
167404
167667
|
return isStateDecl(node) || isExhibitStateDecl(node) || isPartDecl(node);
|
|
167405
167668
|
case "sv":
|
|
@@ -167422,7 +167685,7 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
167422
167685
|
// and `findAnchor` drills to them, so a view opened on the OWNER of an empty
|
|
167423
167686
|
// action definition shows the same thing the package overview does.
|
|
167424
167687
|
isAfvScaffoldAnchor(node) {
|
|
167425
|
-
return isActionDecl(node) && !!nameOf2(node) && (node.isDef === true || this.isDirectPackageMember(node));
|
|
167688
|
+
return (isActionDecl(node) || isCalcDecl(node)) && !!nameOf2(node) && (node.isDef === true || this.isDirectPackageMember(node));
|
|
167426
167689
|
}
|
|
167427
167690
|
// REQ-196 — a member that is a STEP of the flow its holder runs: an action
|
|
167428
167691
|
// usage, a send/accept/assign node, or a `perform`. An action DEFINITION is
|
|
@@ -167432,7 +167695,7 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
167432
167695
|
// `hasAnchorContent` and `hasAfvOverviewDescendant` both read, so what makes a
|
|
167433
167696
|
// part an anchor and what makes it a scope cannot drift apart.
|
|
167434
167697
|
isAfvFlowNode(member, index2) {
|
|
167435
|
-
return !this.isSwimlaneClaim(member, index2) && (isActionDecl(member) && member.isDef !== true || ["SendNode", "AcceptNode", "AssignNode", "PerformStmt"].includes(member.$type));
|
|
167698
|
+
return !this.isSwimlaneClaim(member, index2) && ((isActionDecl(member) || isCalcDecl(member)) && member.isDef !== true || ["SendNode", "AcceptNode", "AssignNode", "PerformStmt"].includes(member.$type));
|
|
167436
167699
|
}
|
|
167437
167700
|
// REQ-196 — does this part's own subtree hold action flow anywhere? Counted
|
|
167438
167701
|
// over the nested part usages of a flow-less part, this is what tells a shared
|
|
@@ -167558,20 +167821,29 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
167558
167821
|
* `accept` payload in on top) and the Interconnection View, where an action
|
|
167559
167822
|
* drawn inside a part must expose the same pins a flow can dock on. */
|
|
167560
167823
|
actionPinPorts(action, ownerId, index2, uri) {
|
|
167561
|
-
const inheritedFrom = action.isDef === true ? void 0 : this.resolveType(action, index2);
|
|
167562
167824
|
const directed = /* @__PURE__ */ new Map();
|
|
167563
|
-
|
|
167564
|
-
|
|
167565
|
-
|
|
167825
|
+
const inheritedTypes = /* @__PURE__ */ new Map();
|
|
167826
|
+
for (const owner of [...this.inheritedFeatureOwnersOf(action, index2)].reverse()) {
|
|
167827
|
+
for (const member of membersOf(owner)) {
|
|
167828
|
+
const targets = redefinitionTargetsOf(member).map(lastSeg);
|
|
167829
|
+
for (const target of targets)
|
|
167830
|
+
directed.delete(target);
|
|
167831
|
+
if (effectiveNameOf(member) && directionOf(member)) {
|
|
167832
|
+
directed.set(effectiveNameOf(member), member);
|
|
167833
|
+
inheritedTypes.set(effectiveNameOf(member), typeText(member) ?? inheritedTypes.get(targets[0] ?? effectiveNameOf(member)));
|
|
167834
|
+
}
|
|
167835
|
+
}
|
|
167566
167836
|
}
|
|
167567
167837
|
for (const member of membersOf(action)) {
|
|
167568
|
-
|
|
167569
|
-
directed.
|
|
167838
|
+
for (const target of redefinitionTargetsOf(member))
|
|
167839
|
+
directed.delete(lastSeg(target));
|
|
167840
|
+
if (effectiveNameOf(member) && directionOf(member))
|
|
167841
|
+
directed.set(effectiveNameOf(member), member);
|
|
167570
167842
|
}
|
|
167571
167843
|
const pinOf = (member, id2, parentPort) => ({
|
|
167572
167844
|
id: id2,
|
|
167573
|
-
name:
|
|
167574
|
-
type: typeText(member),
|
|
167845
|
+
name: effectiveNameOf(member),
|
|
167846
|
+
type: typeText(member) ?? inheritedTypes.get(lastSeg(redefinitionTargetsOf(member)[0] ?? effectiveNameOf(member))),
|
|
167575
167847
|
direction: directionOf(member),
|
|
167576
167848
|
conjugated: isConjugated(member) || void 0,
|
|
167577
167849
|
// REQ-194/REQ-408 - see the port rule above: only a written `ref` dashes.
|
|
@@ -167584,7 +167856,8 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
167584
167856
|
// part does, so Properties inspects it the same way in the AFV as it
|
|
167585
167857
|
// inspects a port in the IV.
|
|
167586
167858
|
compartments: this.compartmentsFor(member, uri, index2, true),
|
|
167587
|
-
source: sourceOf2(member, uri)
|
|
167859
|
+
source: sourceOf2(member, uri),
|
|
167860
|
+
meta: valueTextOf(member) !== void 0 ? { boundArgument: valueTextOf(member) } : void 0
|
|
167588
167861
|
});
|
|
167589
167862
|
const pins = [];
|
|
167590
167863
|
const addNestedPins = (param, paramId, depth, seenTypes) => {
|
|
@@ -167610,12 +167883,38 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
167610
167883
|
}
|
|
167611
167884
|
};
|
|
167612
167885
|
for (const member of directed.values()) {
|
|
167613
|
-
const id2 = `${ownerId}.${
|
|
167886
|
+
const id2 = `${ownerId}.${effectiveNameOf(member)}`;
|
|
167614
167887
|
pins.push(pinOf(member, id2));
|
|
167615
167888
|
addNestedPins(member, id2, 1, /* @__PURE__ */ new Set());
|
|
167616
167889
|
}
|
|
167890
|
+
if (isCalcDecl(action)) {
|
|
167891
|
+
const result = effectiveCalculationResult(action, (name) => index2.get(name));
|
|
167892
|
+
if (result) {
|
|
167893
|
+
const parameter = result.parameter;
|
|
167894
|
+
const name = parameter ? nameOf2(parameter) ?? "result" : "result";
|
|
167895
|
+
pins.push({
|
|
167896
|
+
id: `${ownerId}.${name}`,
|
|
167897
|
+
name,
|
|
167898
|
+
direction: "out",
|
|
167899
|
+
pin: true,
|
|
167900
|
+
isDef: false,
|
|
167901
|
+
type: parameter ? typeText(parameter) : void 0,
|
|
167902
|
+
source: sourceOf2(parameter ?? action, uri),
|
|
167903
|
+
meta: { calculationResult: true, inherited: result.inherited }
|
|
167904
|
+
});
|
|
167905
|
+
}
|
|
167906
|
+
}
|
|
167617
167907
|
return pins;
|
|
167618
167908
|
}
|
|
167909
|
+
// REQ-208 - Only a locally declared result expression is editable on a usage.
|
|
167910
|
+
calculationValue(node, index2) {
|
|
167911
|
+
if (!isCalcDecl(node))
|
|
167912
|
+
return {};
|
|
167913
|
+
const result = effectiveCalculationResult(node, (name) => index2.get(name));
|
|
167914
|
+
if (node.isDef !== true && (!result?.expression || result.inherited))
|
|
167915
|
+
return {};
|
|
167916
|
+
return { value: result?.expression?.$cstNode?.text.replace(/\s+/g, " ").trim() ?? "" };
|
|
167917
|
+
}
|
|
167619
167918
|
/** REQ-196/198: one definition node per type used by a drawn usage.
|
|
167620
167919
|
* The Defs filter controls these nodes. An existing definition tile is
|
|
167621
167920
|
* reused. Typing links are omitted by user direction (2026-09-06).
|
|
@@ -167732,8 +168031,10 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
167732
168031
|
}
|
|
167733
168032
|
return (isPackage(node) || isDocument(node)) && this.nestedUsages(node, isPartDecl).some((n2) => nameOf2(n2) !== void 0);
|
|
167734
168033
|
case "afv": {
|
|
168034
|
+
if (isCalcDecl(node))
|
|
168035
|
+
return true;
|
|
167735
168036
|
if (isActionDecl(node) || this.isCaseLike(node)) {
|
|
167736
|
-
const actions = membersOf(node).map((member) => this.thenActionMemberNode(member) ?? member).filter(isActionDecl);
|
|
168037
|
+
const actions = membersOf(node).map((member) => this.thenActionMemberNode(member) ?? member).filter((n2) => isActionDecl(n2) || isCalcDecl(n2));
|
|
167737
168038
|
if (actions.some((n2) => nameOf2(n2) !== void 0))
|
|
167738
168039
|
return true;
|
|
167739
168040
|
return node.inlineBody !== void 0;
|
|
@@ -167879,6 +168180,19 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
167879
168180
|
const all = [...ast_utils_exports.streamAllContents(scope)];
|
|
167880
168181
|
const annotationNodes = all.filter(isGvAnnotationNode);
|
|
167881
168182
|
const annotationNodeSet = new Set(annotationNodes);
|
|
168183
|
+
const declaredOwnerOf = (node) => {
|
|
168184
|
+
let owner = node.$container;
|
|
168185
|
+
while (owner?.$type === "PrefixMetadataMember" || owner?.$type === "MemberPrefixDecl") {
|
|
168186
|
+
owner = owner.$container;
|
|
168187
|
+
}
|
|
168188
|
+
return owner;
|
|
168189
|
+
};
|
|
168190
|
+
const isDefinitionParameter = (node) => {
|
|
168191
|
+
if (directionOf(node) === void 0)
|
|
168192
|
+
return false;
|
|
168193
|
+
const owner = declaredOwnerOf(node);
|
|
168194
|
+
return !!owner && owner.isDef === true && (isConstraintDecl(owner) || isCalcDecl(owner));
|
|
168195
|
+
};
|
|
167882
168196
|
const usageNodes = all.filter(isGvExplicitUsage);
|
|
167883
168197
|
const usageNodeSet = new Set(usageNodes);
|
|
167884
168198
|
const usageDefinitions = new Map(usageNodes.map((node) => [
|
|
@@ -167917,7 +168231,20 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
167917
168231
|
semanticOwners.set(member, found);
|
|
167918
168232
|
return found;
|
|
167919
168233
|
};
|
|
168234
|
+
const readsAsAttribute = (node) => isAttributeDecl(node) || isAttributeDecl(this.resolveType(node, index2));
|
|
168235
|
+
const implicitlyRedefined = (node) => {
|
|
168236
|
+
const name = nameOf2(node);
|
|
168237
|
+
const owner = semanticOwner(node);
|
|
168238
|
+
if (!name || !owner || owner.isDef === true)
|
|
168239
|
+
return void 0;
|
|
168240
|
+
const definition = usageDefinitions.get(owner);
|
|
168241
|
+
if (!definition)
|
|
168242
|
+
return void 0;
|
|
168243
|
+
return membersOf(definition).find((member) => nameOf2(member) === name);
|
|
168244
|
+
};
|
|
167920
168245
|
const attributeUsages = new Set(usageNodes.filter((node) => {
|
|
168246
|
+
if (isDefinitionParameter(node))
|
|
168247
|
+
return false;
|
|
167921
168248
|
if (isAttributeDecl(node))
|
|
167922
168249
|
return true;
|
|
167923
168250
|
const owner = semanticOwner(node);
|
|
@@ -167928,12 +168255,23 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
167928
168255
|
const definition = usageDefinitions.get(node);
|
|
167929
168256
|
if (definition && isAttributeDecl(definition))
|
|
167930
168257
|
return true;
|
|
167931
|
-
|
|
168258
|
+
if (redefinitionTargetsOf(node).some((target) => {
|
|
167932
168259
|
const inherited = this.resolveFeatureInheritanceTarget(node, target, index2, /* @__PURE__ */ new Set());
|
|
167933
168260
|
return inherited && isAttributeDecl(inherited);
|
|
167934
|
-
})
|
|
168261
|
+
}))
|
|
168262
|
+
return true;
|
|
168263
|
+
const implicit = implicitlyRedefined(node);
|
|
168264
|
+
return !!implicit && readsAsAttribute(implicit);
|
|
167935
168265
|
}));
|
|
167936
168266
|
const attributeValue = (node) => valueTextOf(node) ?? node.default?.value?.$cstNode?.text ?? "";
|
|
168267
|
+
const returnMemberOf = (node) => membersOf(node).find((m) => m.$type === "ReturnDecl");
|
|
168268
|
+
const expressionBody = (node) => {
|
|
168269
|
+
const result = isCalcDecl(node) ? effectiveCalculationResult(node, (name) => index2.get(name)) : void 0;
|
|
168270
|
+
const text = isCalcDecl(node) ? result && !result.inherited ? result.expression?.$cstNode?.text ?? "" : "" : node.body?.$cstNode?.text ?? "";
|
|
168271
|
+
return text.replace(/\s+/g, " ").trim();
|
|
168272
|
+
};
|
|
168273
|
+
const declaresExpression = (node) => node.body !== void 0 || isCalcDecl(node) && valueTextOf(returnMemberOf(node)) !== void 0;
|
|
168274
|
+
const showsExpressionField = (node) => (isConstraintDecl(node) || isCalcDecl(node)) && (node.isDef === true || declaresExpression(node));
|
|
167937
168275
|
const ids = /* @__PURE__ */ new Map();
|
|
167938
168276
|
const unnamedOrdinals = /* @__PURE__ */ new Map();
|
|
167939
168277
|
const semanticId = (node) => {
|
|
@@ -167989,6 +168327,8 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
167989
168327
|
multiplicity: this.multText(n2),
|
|
167990
168328
|
type: typeText(n2) ?? (usageDefinitions.get(n2) ? nameOf2(usageDefinitions.get(n2)) : void 0),
|
|
167991
168329
|
...attributeUsages.has(n2) ? { value: attributeValue(n2) } : {},
|
|
168330
|
+
// REQ-208/209 — the constraint or calculation expression field.
|
|
168331
|
+
...showsExpressionField(n2) ? { value: expressionBody(n2) } : {},
|
|
167992
168332
|
compartments: extra?.compartments ?? this.compartmentsFor(n2, uri, index2, shape === "box"),
|
|
167993
168333
|
...packageOf2(n2),
|
|
167994
168334
|
source: sourceOf2(n2, uri),
|
|
@@ -168003,9 +168343,60 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
168003
168343
|
for (const usage of usageNodes) {
|
|
168004
168344
|
pushNode(usage, "box", false, {
|
|
168005
168345
|
compartments: this.compartmentsFor(usage, uri, index2, true, false),
|
|
168006
|
-
|
|
168346
|
+
// REQ-376 — a parameter keeps its own banner; only an ordinary
|
|
168347
|
+
// attribute usage is relabelled by its value-carrying role.
|
|
168348
|
+
...attributeUsages.has(usage) && !parameterKeyword(usage) ? { keyword: "attribute" } : {}
|
|
168007
168349
|
});
|
|
168008
168350
|
}
|
|
168351
|
+
for (const usage of usageNodes) {
|
|
168352
|
+
if (!isConstraintDecl(usage) || usage.isDef === true)
|
|
168353
|
+
continue;
|
|
168354
|
+
const definition = usageDefinitions.get(usage);
|
|
168355
|
+
if (!definition || !isConstraintDecl(definition))
|
|
168356
|
+
continue;
|
|
168357
|
+
const usageId = semanticId(usage);
|
|
168358
|
+
const local = new Set(membersOf(usage).flatMap((member) => [nameOf2(member), ...redefinitionTargetsOf(member)]).filter((name) => !!name));
|
|
168359
|
+
for (const member of membersOf(definition)) {
|
|
168360
|
+
const name = nameOf2(member);
|
|
168361
|
+
if (!name || local.has(name))
|
|
168362
|
+
continue;
|
|
168363
|
+
if (directionOf(member) === void 0 && !isAttributeDecl(member))
|
|
168364
|
+
continue;
|
|
168365
|
+
const id2 = `${usageId}::${name}`;
|
|
168366
|
+
if (nodes.some((existing) => existing.id === id2))
|
|
168367
|
+
continue;
|
|
168368
|
+
nodes.push({
|
|
168369
|
+
id: id2,
|
|
168370
|
+
name: effectiveNameOf(member) ?? name,
|
|
168371
|
+
keyword: "attribute",
|
|
168372
|
+
isDef: false,
|
|
168373
|
+
shape: "box",
|
|
168374
|
+
multiplicity: this.multText(member),
|
|
168375
|
+
type: typeText(member),
|
|
168376
|
+
value: attributeValue(member),
|
|
168377
|
+
compartments: [],
|
|
168378
|
+
parent: usageId,
|
|
168379
|
+
// Navigation lands on the declaration the member comes from.
|
|
168380
|
+
source: sourceOf2(member, uri),
|
|
168381
|
+
meta: {
|
|
168382
|
+
gvUsage: true,
|
|
168383
|
+
gvOwnerId: usageId,
|
|
168384
|
+
gvExplicit: true,
|
|
168385
|
+
gvDeclaredName: name,
|
|
168386
|
+
gvDeclaredType: typeText(member) ?? "",
|
|
168387
|
+
// REQ-364 — the concrete usage that owns a local edit, plus
|
|
168388
|
+
// the relative redefinition path to write inside it.
|
|
168389
|
+
localUsageId: usageId,
|
|
168390
|
+
localUsageName: nameOf2(usage),
|
|
168391
|
+
localUsageSource: sourceOf2(usage, uri),
|
|
168392
|
+
localUsagePath: [name],
|
|
168393
|
+
expandedFromDefinition: true,
|
|
168394
|
+
declarationId: qnameOf(member),
|
|
168395
|
+
declarationSource: sourceOf2(member, uri)
|
|
168396
|
+
}
|
|
168397
|
+
});
|
|
168398
|
+
}
|
|
168399
|
+
}
|
|
168009
168400
|
for (const p of packageNodes) {
|
|
168010
168401
|
const pn = p;
|
|
168011
168402
|
pushNode(p, "package", false, {
|
|
@@ -168322,6 +168713,9 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
168322
168713
|
}
|
|
168323
168714
|
}
|
|
168324
168715
|
}
|
|
168716
|
+
for (const owner of [...defNodes, ...usageNodes]) {
|
|
168717
|
+
this.emitConstraintGraphics(owner, semanticId(owner), membersOf(owner), nodes, edges, index2, uri, false);
|
|
168718
|
+
}
|
|
168325
168719
|
const allocPairs = [
|
|
168326
168720
|
...all.filter((m) => m.$type === "AllocateStmt").map((a2) => ({
|
|
168327
168721
|
from: String(a2.source ?? ""),
|
|
@@ -168957,6 +169351,89 @@ ${node.id}`;
|
|
|
168957
169351
|
out.push({ title: "flows", items: rows });
|
|
168958
169352
|
return out;
|
|
168959
169353
|
}
|
|
169354
|
+
// REQ-209 - Claims preserve usage identity; references reuse their target.
|
|
169355
|
+
emitConstraintGraphics(owner, ownerId, members, nodes, edges, index2, uri, interconnection) {
|
|
169356
|
+
const kinds = {
|
|
169357
|
+
AssertConstraintStmt: "assert",
|
|
169358
|
+
AssumeConstraintStmt: "assume",
|
|
169359
|
+
RequireConstraintStmt: "require"
|
|
169360
|
+
};
|
|
169361
|
+
const ensureNode = (target, id2, keyword) => {
|
|
169362
|
+
let node = nodes.find((candidate) => candidate.id === id2);
|
|
169363
|
+
if (!node) {
|
|
169364
|
+
const body = target.body?.$cstNode?.text;
|
|
169365
|
+
node = {
|
|
169366
|
+
id: id2,
|
|
169367
|
+
name: effectiveNameOf(target) ?? keyword,
|
|
169368
|
+
keyword,
|
|
169369
|
+
shape: "box",
|
|
169370
|
+
isDef: target.isDef === true,
|
|
169371
|
+
type: typeText(target),
|
|
169372
|
+
multiplicity: this.multText(target),
|
|
169373
|
+
compartments: this.compartmentsFor(target, uri, index2),
|
|
169374
|
+
...(isConstraintDecl(target) || isInlineConstraintClaim(target)) && (body !== void 0 || target.isDef) ? { value: (body ?? "").replace(/\s+/g, " ").trim() } : {},
|
|
169375
|
+
...interconnection ? { ports: this.actionPinPorts(target, id2, index2, uri) } : {},
|
|
169376
|
+
source: sourceOf2(target, uri),
|
|
169377
|
+
...interconnection ? {} : { parent: ownerId },
|
|
169378
|
+
meta: { constraintUsage: true, ...!interconnection ? { gvUsage: true } : {} }
|
|
169379
|
+
};
|
|
169380
|
+
nodes.push(node);
|
|
169381
|
+
}
|
|
169382
|
+
node.meta = { ...node.meta, constraintUsage: true };
|
|
169383
|
+
return node;
|
|
169384
|
+
};
|
|
169385
|
+
for (const member of members) {
|
|
169386
|
+
const kind = kinds[member.$type];
|
|
169387
|
+
if (!kind) {
|
|
169388
|
+
if (interconnection && isConstraintDecl(member) && !member.isDef) {
|
|
169389
|
+
ensureNode(member, `${ownerId}::${effectiveNameOf(member) ?? member.$cstNode?.offset}`, "constraint");
|
|
169390
|
+
}
|
|
169391
|
+
continue;
|
|
169392
|
+
}
|
|
169393
|
+
const reference = constraintReferenceOf(member);
|
|
169394
|
+
let target = member;
|
|
169395
|
+
let targetId = `${ownerId}::${effectiveNameOf(member) ?? `#${member.$type}:${members.filter((m) => m.$type === member.$type).indexOf(member) + 1}`}`;
|
|
169396
|
+
if (reference) {
|
|
169397
|
+
const resolved = this.featurePaths.resolveDeclarationPath(member);
|
|
169398
|
+
const localPath = reference.path === reference.simpleName || reference.path.replaceAll("::", ".") === `self.${reference.simpleName}`;
|
|
169399
|
+
const effective = interconnection && localPath ? members.find((candidate) => (isConstraintDecl(candidate) || isInlineConstraintClaim(candidate)) && [effectiveNameOf(candidate), ...redefinitionTargetsOf(candidate).map(lastSeg)].includes(reference.simpleName)) : void 0;
|
|
169400
|
+
const found = effective ?? resolved.segments.at(-1)?.target ?? membersOf(owner).find((candidate) => candidate !== member && nameOf2(candidate) === reference.path) ?? index2.get(reference.path) ?? index2.get(reference.simpleName);
|
|
169401
|
+
if (!found || found === member)
|
|
169402
|
+
continue;
|
|
169403
|
+
target = found;
|
|
169404
|
+
targetId = interconnection && members.includes(target) && effectiveNameOf(target) ? `${ownerId}::${effectiveNameOf(target)}` : qnameOf(target) || reference.path;
|
|
169405
|
+
}
|
|
169406
|
+
const negated = member.isNegated === true;
|
|
169407
|
+
ensureNode(target, targetId, reference ? keywordFor(target) : `${kind}${negated ? " not" : ""} constraint`);
|
|
169408
|
+
const id2 = `${ownerId}::__${kind}_${member.$cstNode?.offset ?? edges.length}`;
|
|
169409
|
+
if (!edges.some((edge) => edge.id === id2))
|
|
169410
|
+
edges.push({
|
|
169411
|
+
id: id2,
|
|
169412
|
+
from: ownerId,
|
|
169413
|
+
to: targetId,
|
|
169414
|
+
kind,
|
|
169415
|
+
label: `\xAB${kind}${negated ? " not" : ""}\xBB`,
|
|
169416
|
+
source: sourceOf2(member, uri),
|
|
169417
|
+
meta: { constraintReference: !!reference, negated }
|
|
169418
|
+
});
|
|
169419
|
+
if (!reference && !interconnection) {
|
|
169420
|
+
const definition = this.resolveType(member, index2);
|
|
169421
|
+
const definitionId = definition ? qnameOf(definition) : void 0;
|
|
169422
|
+
if (definitionId && nodes.some((node) => node.id === definitionId) && !edges.some((edge) => edge.kind === "definedBy" && edge.from === targetId)) {
|
|
169423
|
+
edges.push({
|
|
169424
|
+
id: `${id2}_type`,
|
|
169425
|
+
from: targetId,
|
|
169426
|
+
to: definitionId,
|
|
169427
|
+
kind: "definedBy",
|
|
169428
|
+
source: sourceOf2(member, uri)
|
|
169429
|
+
});
|
|
169430
|
+
}
|
|
169431
|
+
}
|
|
169432
|
+
}
|
|
169433
|
+
const drawnOwner = nodes.find((node) => node.id === ownerId);
|
|
169434
|
+
if (drawnOwner && interconnection)
|
|
169435
|
+
drawnOwner.compartments = withoutCompartments(drawnOwner.compartments, "assert constraints", "assume constraints", "require constraints");
|
|
169436
|
+
}
|
|
168960
169437
|
// REQ-192/360/363 — the ONE recursive Interconnection View renderer. Given the
|
|
168961
169438
|
// top-level `roots` to draw, it renders each part instance and nests its
|
|
168962
169439
|
// internals recursively, drilling into a usage's type DEFINITION (+
|
|
@@ -169009,8 +169486,13 @@ ${node.id}`;
|
|
|
169009
169486
|
const emptyPrefixFlow = isEmptyPrefixFlow(member);
|
|
169010
169487
|
const emptyPrefixInterface = isInterfaceDecl(member) && relationship.target !== void 0 && relationship.connect === void 0;
|
|
169011
169488
|
const namedRelationship = isConnectorDecl(member) || isConnectionDecl(member) || isInterfaceDecl(member) && !emptyPrefixInterface || member.$type === "BindingDecl" || member.$type === "FlowStmt" && !emptyPrefixFlow;
|
|
169012
|
-
|
|
169013
|
-
|
|
169489
|
+
const constraint = isConstraintDecl(member) || isInlineConstraintClaim(member);
|
|
169490
|
+
if (namedRelationship || constraint) {
|
|
169491
|
+
const names = [
|
|
169492
|
+
nameOf2(member),
|
|
169493
|
+
redefinedNameOf(member),
|
|
169494
|
+
...constraint ? redefinitionTargetsOf(member).map(lastSeg) : []
|
|
169495
|
+
].filter((name) => name !== void 0);
|
|
169014
169496
|
if (names.some((name) => claimedNames.has(name)))
|
|
169015
169497
|
continue;
|
|
169016
169498
|
for (const name of names)
|
|
@@ -169259,6 +169741,10 @@ ${node.id}`;
|
|
|
169259
169741
|
const resolver = childResolver([], { usage: part, id: instanceId });
|
|
169260
169742
|
this.emitInterconnectEdges(effectiveMembersOf(part), resolver.resolve, [], index2, uri, target.nodes, target.edges, eRef, instanceId, resolver.actionPinIds, resolver.structuralPortIds, part, occurrenceInherited, endpointProvenance);
|
|
169261
169743
|
}
|
|
169744
|
+
this.emitConstraintGraphics(part, instanceId, effectiveMembersOf(part), target.nodes, target.edges, index2, uri, true);
|
|
169745
|
+
const claimFrame = target.frames.find((frame2) => frame2.id === instanceId);
|
|
169746
|
+
if (claimFrame)
|
|
169747
|
+
claimFrame.compartments = withoutCompartments(claimFrame.compartments, "assert constraints", "assume constraints", "require constraints");
|
|
169262
169748
|
};
|
|
169263
169749
|
const packageOfRoot = (root4) => enclosingPackage(root4) ?? scope;
|
|
169264
169750
|
const rootBaseId = (root4) => qnameOf(root4) || nameOf2(root4) || `__root_${root4.$cstNode?.offset ?? 0}__`;
|
|
@@ -169350,8 +169836,35 @@ ${node.id}`;
|
|
|
169350
169836
|
// single Interconnection View (called once over the anchor's whole subtree)
|
|
169351
169837
|
// and the package overview (called once per container part, tagging any
|
|
169352
169838
|
// synthetic n-ary dot with that container's frame id).
|
|
169353
|
-
emitInterconnectEdges(members,
|
|
169839
|
+
emitInterconnectEdges(members, resolveStructuralEnd, parts, index2, uri, nodes, edges, eRef, frameId, actionPinIds = /* @__PURE__ */ new Set(), structuralPortIds = /* @__PURE__ */ new Set(), memberOwner, memberOwnerInherited = false, endpointProvenance = /* @__PURE__ */ new Map()) {
|
|
169354
169840
|
const memberList2 = [...members];
|
|
169841
|
+
if (memberOwner && frameId)
|
|
169842
|
+
this.emitConstraintGraphics(memberOwner, frameId, memberList2, nodes, edges, index2, uri, true);
|
|
169843
|
+
const resolveEnd = (pathText) => {
|
|
169844
|
+
const structural = resolveStructuralEnd(pathText);
|
|
169845
|
+
if (structural)
|
|
169846
|
+
return structural;
|
|
169847
|
+
const path10 = pathText.replaceAll("::", ".");
|
|
169848
|
+
const candidates = nodes.filter((node) => node.meta?.constraintUsage === true && (!frameId || node.id.startsWith(`${frameId}::`) || edges.some((edge) => edge.from === frameId && edge.to === node.id))).flatMap((node) => (node.ports ?? []).filter((pin) => `${node.name}.${pin.name}` === path10 || pin.id.replaceAll("::", ".") === path10));
|
|
169849
|
+
if (candidates.length === 1)
|
|
169850
|
+
return candidates[0].id;
|
|
169851
|
+
const attribute = memberList2.find((member) => isAttributeDecl(member) && nameOf2(member) === path10);
|
|
169852
|
+
if (!attribute || !frameId)
|
|
169853
|
+
return void 0;
|
|
169854
|
+
const id2 = `${frameId}::${nameOf2(attribute)}`;
|
|
169855
|
+
if (!nodes.some((node) => node.id === id2))
|
|
169856
|
+
nodes.push({
|
|
169857
|
+
id: id2,
|
|
169858
|
+
name: nameOf2(attribute),
|
|
169859
|
+
keyword: "attribute",
|
|
169860
|
+
isDef: false,
|
|
169861
|
+
shape: "box",
|
|
169862
|
+
type: typeText(attribute),
|
|
169863
|
+
value: valueTextOf(attribute),
|
|
169864
|
+
source: sourceOf2(attribute, uri)
|
|
169865
|
+
});
|
|
169866
|
+
return id2;
|
|
169867
|
+
};
|
|
169355
169868
|
const pendingFlows = [];
|
|
169356
169869
|
const firstEdge = edges.length;
|
|
169357
169870
|
const relationshipFields = (source) => {
|
|
@@ -169898,7 +170411,7 @@ ${node.id}`;
|
|
|
169898
170411
|
while (cur && cur !== scope) {
|
|
169899
170412
|
if (set3.has(cur)) {
|
|
169900
170413
|
if (kind !== "stv" || !isPartDecl(n2)) {
|
|
169901
|
-
if (kind === "afv" && isPartDecl(cur) && n2.isDef === true && isActionDecl(n2))
|
|
170414
|
+
if (kind === "afv" && isPartDecl(cur) && n2.isDef === true && (isActionDecl(n2) || isCalcDecl(n2)))
|
|
169902
170415
|
break;
|
|
169903
170416
|
return false;
|
|
169904
170417
|
}
|
|
@@ -169952,12 +170465,12 @@ ${node.id}`;
|
|
|
169952
170465
|
anchor: sub,
|
|
169953
170466
|
diagramRoot: ctx.diagramRoot ?? ctx.anchor
|
|
169954
170467
|
});
|
|
169955
|
-
if (this.diagramElementCount(subModel) === 0 && !(kind === "afv" && isActionDecl(sub)) && !(kind === "stv" && (isStateDecl(sub) || isExhibitStateDecl(sub))))
|
|
170468
|
+
if (this.diagramElementCount(subModel) === 0 && !(kind === "afv" && (isActionDecl(sub) || isCalcDecl(sub))) && !(kind === "stv" && (isStateDecl(sub) || isExhibitStateDecl(sub))))
|
|
169956
170469
|
continue;
|
|
169957
170470
|
const frameId = `t${tile}`;
|
|
169958
170471
|
const q = qnameOf(sub) || nameOf2(sub) || "";
|
|
169959
170472
|
const rel2 = scopeQ && q.startsWith(`${scopeQ}::`) ? q.slice(scopeQ.length + 2) : nameOf2(sub) ?? q;
|
|
169960
|
-
const tileMetaTag = kind === "afv" ? isPartDecl(sub) ? { afvPart: true } : isActionDecl(sub) && sub.isDef === true ? { behaviorDef: true } : void 0 : kind === "stv" && sub.isDef === true ? { behaviorDef: true } : void 0;
|
|
170473
|
+
const tileMetaTag = kind === "afv" ? isPartDecl(sub) ? { afvPart: true } : (isActionDecl(sub) || isCalcDecl(sub)) && sub.isDef === true ? { behaviorDef: true } : void 0 : kind === "stv" && sub.isDef === true ? { behaviorDef: true } : void 0;
|
|
169961
170474
|
const tileIdentity = {
|
|
169962
170475
|
declarationId: qnameOf(sub) || nameOf2(sub),
|
|
169963
170476
|
declarationName: nameOf2(sub),
|
|
@@ -170178,7 +170691,7 @@ ${node.id}`;
|
|
|
170178
170691
|
addStepAlias(alias, id2);
|
|
170179
170692
|
};
|
|
170180
170693
|
let anon = 0;
|
|
170181
|
-
const anchorHostsFlow = isActionDecl(anchor) || this.isCaseLike(anchor);
|
|
170694
|
+
const anchorHostsFlow = isActionDecl(anchor) || isCalcDecl(anchor) || this.isCaseLike(anchor);
|
|
170182
170695
|
const exprTextOf = (v) => (v?.$cstNode?.text ?? (typeof v === "string" ? v : "")).replace(/\s+/g, " ").trim();
|
|
170183
170696
|
const performPathOf = (m) => [nameOf2(m), ...m.chainSegs ?? []].filter((segment) => !!segment);
|
|
170184
170697
|
const performLabel = (m) => performPathOf(m).at(-1) ?? typeText(m) ?? "perform";
|
|
@@ -170187,6 +170700,9 @@ ${node.id}`;
|
|
|
170187
170700
|
const flowNodeInfo = (m) => {
|
|
170188
170701
|
const mm = m;
|
|
170189
170702
|
switch (m.$type) {
|
|
170703
|
+
// REQ-208 - Calculations share action occurrence docking.
|
|
170704
|
+
case "CalcDecl":
|
|
170705
|
+
return { shape: "action", label: nameOf2(m) ?? "calc" };
|
|
170190
170706
|
case "ActionDecl": {
|
|
170191
170707
|
if (!nameOf2(m))
|
|
170192
170708
|
return void 0;
|
|
@@ -170421,7 +170937,7 @@ ${node.id}`;
|
|
|
170421
170937
|
pinByPath.set(alias, null);
|
|
170422
170938
|
};
|
|
170423
170939
|
const actionPinsOf = (action, ownerId) => {
|
|
170424
|
-
if (!isActionDecl(action) && action.$type !== "PerformStmt")
|
|
170940
|
+
if (!isActionDecl(action) && !isCalcDecl(action) && action.$type !== "PerformStmt")
|
|
170425
170941
|
return [];
|
|
170426
170942
|
const pins = this.actionPinPorts(action, ownerId, index2, uri);
|
|
170427
170943
|
const inline = action.inlineBody;
|
|
@@ -170606,7 +171122,7 @@ ${node.id}`;
|
|
|
170606
171122
|
frameOfNode.set(holder, frameId);
|
|
170607
171123
|
const framePorts = isPartDecl(holder) ? [...framePins, ...this.portsOf(holder, index2, uri, frameId).ports.filter((port) => !framePins.some((pin) => pin.name === port.name)).map((port) => ({ ...port, meta: { ...port.meta, afvPartPort: true } }))] : framePins;
|
|
170608
171124
|
registerPins(holder, frameId, framePins, isAnchor);
|
|
170609
|
-
const frameCompartments = isActionDecl(holder) ? actionFeatureCompartments(holder) : withoutCompartments(this.compartmentsFor(holder, uri, index2), ...graphicalAfvTitles);
|
|
171125
|
+
const frameCompartments = isActionDecl(holder) || isCalcDecl(holder) ? actionFeatureCompartments(holder) : withoutCompartments(this.compartmentsFor(holder, uri, index2), ...graphicalAfvTitles);
|
|
170610
171126
|
frames.push({
|
|
170611
171127
|
id: frameId,
|
|
170612
171128
|
label: nameOf2(holder) ?? lastSeg(frameId),
|
|
@@ -170615,6 +171131,7 @@ ${node.id}`;
|
|
|
170615
171131
|
isDef: holder.isDef === true,
|
|
170616
171132
|
type: typeText(holder),
|
|
170617
171133
|
multiplicity: this.multText(holder),
|
|
171134
|
+
...this.calculationValue(holder, index2),
|
|
170618
171135
|
compartments: frameCompartments?.length ? frameCompartments : void 0,
|
|
170619
171136
|
ports: framePorts,
|
|
170620
171137
|
source: sourceOf2(holder, uri),
|
|
@@ -170651,7 +171168,7 @@ ${node.id}`;
|
|
|
170651
171168
|
this.featurePath(namedSendNode.via) ? `via ${this.featurePath(namedSendNode.via)}` : void 0,
|
|
170652
171169
|
this.featurePath(namedSendNode.sendTarget) ? `to ${this.featurePath(namedSendNode.sendTarget)}` : void 0
|
|
170653
171170
|
].filter((value) => !!value).join(" ") : void 0;
|
|
170654
|
-
const featureCompartments = m.$type === "ActionDecl" || m.$type === "PerformStmt" ? actionFeatureCompartments(m) : [];
|
|
171171
|
+
const featureCompartments = isCalcDecl(m) || m.$type === "ActionDecl" || m.$type === "PerformStmt" ? actionFeatureCompartments(m) : [];
|
|
170655
171172
|
const detailCompartment = acceptTrigger || sendDetail ? [{
|
|
170656
171173
|
title: acceptTrigger ? "accepts" : "sends",
|
|
170657
171174
|
items: [{ text: acceptTrigger ?? sendDetail, source: sourceOf2(inlineAccept ?? m, uri) }]
|
|
@@ -170664,6 +171181,8 @@ ${node.id}`;
|
|
|
170664
171181
|
keyword: info.keyword ?? keywordFor(m),
|
|
170665
171182
|
isDef: m.isDef === true,
|
|
170666
171183
|
shape: info.shape,
|
|
171184
|
+
...isCalcDecl(m) ? { type: typeText(m), multiplicity: this.multText(m) } : {},
|
|
171185
|
+
...this.calculationValue(m, index2),
|
|
170667
171186
|
ports: pins,
|
|
170668
171187
|
compartments: compartments.length ? compartments : void 0,
|
|
170669
171188
|
frame: frameId,
|
|
@@ -170765,14 +171284,14 @@ ${node.id}`;
|
|
|
170765
171284
|
}) || inline?.$type === "AssignNode" || definitionFlowMembersOf(node).length > 0;
|
|
170766
171285
|
};
|
|
170767
171286
|
const contentSourceOf = (node) => {
|
|
170768
|
-
if (node
|
|
171287
|
+
if (isActionDecl(node) || isCalcDecl(node))
|
|
170769
171288
|
return ownsFlow(node) ? node : void 0;
|
|
170770
171289
|
if (node.$type !== "PerformStmt")
|
|
170771
171290
|
return void 0;
|
|
170772
171291
|
if (ownsFlow(node))
|
|
170773
171292
|
return node;
|
|
170774
171293
|
const target = performTarget(node);
|
|
170775
|
-
return target && isActionDecl(target) && ownsFlow(target) ? target : void 0;
|
|
171294
|
+
return target && (isActionDecl(target) || isCalcDecl(target)) && ownsFlow(target) ? target : void 0;
|
|
170776
171295
|
};
|
|
170777
171296
|
const isCompositeAction = (node) => contentSourceOf(node) !== void 0;
|
|
170778
171297
|
const openFrames = /* @__PURE__ */ new Set();
|
|
@@ -170807,6 +171326,7 @@ ${node.id}`;
|
|
|
170807
171326
|
isDef: action.isDef === true,
|
|
170808
171327
|
type: typeText(action),
|
|
170809
171328
|
multiplicity: this.multText(action),
|
|
171329
|
+
...this.calculationValue(action, index2),
|
|
170810
171330
|
compartments: actionCompartments.length ? actionCompartments : void 0,
|
|
170811
171331
|
ports: pins,
|
|
170812
171332
|
source: sourceOf2(action, uri),
|
|
@@ -172388,7 +172908,12 @@ ${node.id}`;
|
|
|
172388
172908
|
idOf.set(n2, id2);
|
|
172389
172909
|
nodes.push({
|
|
172390
172910
|
id: id2,
|
|
172391
|
-
|
|
172911
|
+
// REQ-404 — a redeclaration (`actor :>> driver = …`) writes no name
|
|
172912
|
+
// of its own; the name it is KNOWN BY is the one it redefines, which
|
|
172913
|
+
// is the same derivation the rest of the model is labelled by. The
|
|
172914
|
+
// last-resort fallback is the SHAPE, never the literal 'subject':
|
|
172915
|
+
// that string labelled every unnamed actor "subject" on the card.
|
|
172916
|
+
name: effectiveNameOf(n2) ?? lastSeg(typeText(n2) ?? shape),
|
|
172392
172917
|
keyword: keywordFor(n2),
|
|
172393
172918
|
isDef: n2.isDef === true,
|
|
172394
172919
|
shape,
|
|
@@ -172432,14 +172957,15 @@ ${node.id}`;
|
|
|
172432
172957
|
const declarationKey = (subject) => {
|
|
172433
172958
|
const type = this.resolveType(subject, index2);
|
|
172434
172959
|
const typeKey = (type ? qnameOf(type) : void 0) || typeText(subject) || "";
|
|
172435
|
-
const name =
|
|
172960
|
+
const name = effectiveNameOf(subject) ?? "";
|
|
172436
172961
|
return name || typeKey ? `subject:${name}|${typeKey}` : "";
|
|
172437
172962
|
};
|
|
172438
172963
|
const declarationText = (subject) => {
|
|
172439
172964
|
const value = subjectValuePath(subject);
|
|
172440
172965
|
const type = typeText(subject);
|
|
172441
|
-
return [
|
|
172966
|
+
return [effectiveNameOf(subject), type ? `: ${type}` : void 0, value ? `= ${value}` : void 0].filter((part) => !!part).join(" ");
|
|
172442
172967
|
};
|
|
172968
|
+
const boundKeysOfDeclaration = /* @__PURE__ */ new Map();
|
|
172443
172969
|
const subjectKey = (subject, seen = /* @__PURE__ */ new Set()) => {
|
|
172444
172970
|
const canonical = canonicalSubjectTarget(subject);
|
|
172445
172971
|
if (canonical && isSubjectDecl(canonical) && canonical !== subject && !seen.has(canonical)) {
|
|
@@ -172448,7 +172974,14 @@ ${node.id}`;
|
|
|
172448
172974
|
}
|
|
172449
172975
|
const canonicalQName = canonical && !isSubjectDecl(canonical) ? qnameOf(canonical) : "";
|
|
172450
172976
|
const value = subjectValuePath(subject);
|
|
172451
|
-
|
|
172977
|
+
if (canonicalQName)
|
|
172978
|
+
return `target:${canonicalQName}`;
|
|
172979
|
+
if (value)
|
|
172980
|
+
return `value:${value}`;
|
|
172981
|
+
const adopted = boundKeysOfDeclaration.get(subject);
|
|
172982
|
+
if (adopted?.size === 1)
|
|
172983
|
+
return [...adopted][0];
|
|
172984
|
+
return declarationKey(subject) || `decl:${qnameOf(subject) || `${subject.$cstNode?.offset ?? 0}:subject`}`;
|
|
172452
172985
|
};
|
|
172453
172986
|
const subjectIdByKey = /* @__PURE__ */ new Map();
|
|
172454
172987
|
const subjectOfCase = /* @__PURE__ */ new Map();
|
|
@@ -172459,7 +172992,7 @@ ${node.id}`;
|
|
|
172459
172992
|
const key2 = subjectKey(subject);
|
|
172460
172993
|
let sid = subjectIdByKey.get(key2);
|
|
172461
172994
|
if (!sid) {
|
|
172462
|
-
const label =
|
|
172995
|
+
const label = effectiveNameOf(identity6) ?? lastSeg(value || typeText(identity6) || "subject");
|
|
172463
172996
|
add(identity6, "subject", {
|
|
172464
172997
|
id: `${scopeId}::__cv_subject__::${key2}`,
|
|
172465
172998
|
name: label,
|
|
@@ -172471,6 +173004,26 @@ ${node.id}`;
|
|
|
172471
173004
|
idOf.set(subject, sid);
|
|
172472
173005
|
return sid;
|
|
172473
173006
|
};
|
|
173007
|
+
for (const c of displayedCases) {
|
|
173008
|
+
const declared = declaredMembers(c).filter(isSubjectDecl);
|
|
173009
|
+
for (const bound of declared) {
|
|
173010
|
+
if (!subjectValuePath(bound))
|
|
173011
|
+
continue;
|
|
173012
|
+
const name = effectiveNameOf(bound);
|
|
173013
|
+
if (!name)
|
|
173014
|
+
continue;
|
|
173015
|
+
for (const target of declared) {
|
|
173016
|
+
if (target === bound || subjectValuePath(target))
|
|
173017
|
+
continue;
|
|
173018
|
+
if (effectiveNameOf(target) !== name)
|
|
173019
|
+
continue;
|
|
173020
|
+
let keys3 = boundKeysOfDeclaration.get(target);
|
|
173021
|
+
if (!keys3)
|
|
173022
|
+
boundKeysOfDeclaration.set(target, keys3 = /* @__PURE__ */ new Set());
|
|
173023
|
+
keys3.add(subjectKey(bound));
|
|
173024
|
+
}
|
|
173025
|
+
}
|
|
173026
|
+
}
|
|
172474
173027
|
const denotesSubject = (s) => !!(nameOf2(s) || typeText(s) || subjectValuePath(s));
|
|
172475
173028
|
for (const c of displayedCases) {
|
|
172476
173029
|
const declared = declaredMembers(c).filter(isSubjectDecl);
|
|
@@ -172513,16 +173066,47 @@ ${node.id}`;
|
|
|
172513
173066
|
};
|
|
172514
173067
|
const actorOfCase = [];
|
|
172515
173068
|
const actorCasePairs = /* @__PURE__ */ new Set();
|
|
172516
|
-
const
|
|
173069
|
+
const actorTypeKey = (actor) => {
|
|
173070
|
+
const type = this.resolveType(actor, index2);
|
|
173071
|
+
return (type ? qnameOf(type) : void 0) || typeText(actor) || "";
|
|
173072
|
+
};
|
|
173073
|
+
const actorTypeSource = (actor, siblings) => {
|
|
173074
|
+
if (actorTypeKey(actor))
|
|
173075
|
+
return actor;
|
|
173076
|
+
const name = effectiveNameOf(actor);
|
|
173077
|
+
if (!name)
|
|
173078
|
+
return void 0;
|
|
173079
|
+
return siblings.find((sibling) => sibling !== actor && effectiveNameOf(sibling) === name && !!actorTypeKey(sibling));
|
|
173080
|
+
};
|
|
173081
|
+
const actorDeclarationKey = (actor, siblings) => {
|
|
173082
|
+
const name = effectiveNameOf(actor) ?? "";
|
|
173083
|
+
const typeKey = actorTypeKey(actorTypeSource(actor, siblings) ?? actor);
|
|
173084
|
+
return name || typeKey ? `actor:${name}|${typeKey}` : "";
|
|
173085
|
+
};
|
|
173086
|
+
const actorKey = (actor, siblings) => actorDeclarationKey(actor, siblings) || `decl:${qnameOf(actor) || ""}:${actor.$cstNode?.offset ?? 0}`;
|
|
173087
|
+
const actorIdByKey = /* @__PURE__ */ new Map();
|
|
173088
|
+
const addActor = (actor, siblings) => {
|
|
173089
|
+
const canonical = actorCanonical(actor);
|
|
173090
|
+
const key2 = actorKey(canonical, siblings);
|
|
173091
|
+
let aid = actorIdByKey.get(key2);
|
|
173092
|
+
if (aid === void 0) {
|
|
173093
|
+
const typeSource = actorTypeSource(canonical, siblings);
|
|
173094
|
+
add(canonical, "actor", {
|
|
173095
|
+
id: `${scopeId}::__cv_actor__::${key2}`,
|
|
173096
|
+
...typeSource && typeSource !== canonical ? { type: typeText(typeSource) } : {},
|
|
173097
|
+
meta: { cvAuxiliary: true }
|
|
173098
|
+
});
|
|
173099
|
+
aid = idOf.get(canonical);
|
|
173100
|
+
actorIdByKey.set(key2, aid);
|
|
173101
|
+
}
|
|
173102
|
+
idOf.set(actor, aid);
|
|
173103
|
+
return aid;
|
|
173104
|
+
};
|
|
172517
173105
|
for (const c of displayedCases) {
|
|
172518
|
-
|
|
172519
|
-
|
|
172520
|
-
|
|
172521
|
-
const
|
|
172522
|
-
if (!idOf.has(canonical))
|
|
172523
|
-
add(canonical, "actor", { id: anonymousActorId(canonical), meta: { cvAuxiliary: true } });
|
|
172524
|
-
const actorId = idOf.get(canonical);
|
|
172525
|
-
idOf.set(a2, actorId);
|
|
173106
|
+
const siblings = declaredMembers(c).filter(isActorDecl);
|
|
173107
|
+
const typeSources = siblings.some((a2) => !actorTypeKey(a2)) ? [...siblings, ...this.inheritedTypesOf(c, index2).flatMap((t) => membersOf(t).filter(isActorDecl))] : siblings;
|
|
173108
|
+
for (const a2 of siblings) {
|
|
173109
|
+
const actorId = addActor(a2, typeSources);
|
|
172526
173110
|
const pair = `${actorId}\0${qnameOf(c) ?? nameOf2(c) ?? ""}`;
|
|
172527
173111
|
if (!actorCasePairs.has(pair)) {
|
|
172528
173112
|
actorCasePairs.add(pair);
|
|
@@ -174271,7 +174855,7 @@ ${node.id}`;
|
|
|
174271
174855
|
const inherited = includeInherited ? this.inheritedItems(node, index2, uri) : [];
|
|
174272
174856
|
const inheritedRows = (predicate, text = (member) => this.featureText(member)) => inherited.filter(({ member }) => predicate(member)).map(({ member, source }) => ({ text: `^${text(member)}`, source }));
|
|
174273
174857
|
const usages = (guard) => members.filter((m) => guard(m) && m.isDef !== true && nameOf2(m) && isOrdinaryMember(m));
|
|
174274
|
-
const
|
|
174858
|
+
const exprText4 = (m) => (m.body?.$cstNode?.text ?? "").replace(/\s+/g, " ").trim();
|
|
174275
174859
|
const statementText = (m) => (m.$cstNode?.text ?? this.featureText(m)).replace(/\s+/g, " ").replace(/;$/, "").trim();
|
|
174276
174860
|
const canonicalFeatureText = (m) => m.$type === "FeatureShorthand" || m.$type === "FeatureRedefinitionShorthand" ? statementText(m) : this.featureText(m);
|
|
174277
174861
|
const out = [];
|
|
@@ -174323,8 +174907,8 @@ ${node.id}`;
|
|
|
174323
174907
|
add("occurrences", members.map((m) => this.thenActionMemberNode(m) ?? m).filter(isNonVariantMember).filter((m) => isEventDecl(m) && m.isOccurrence === true && nameOf2(m)).map((m) => item(m)));
|
|
174324
174908
|
add("calcs", undirected(isCalcDecl).map((m) => item(m)));
|
|
174325
174909
|
add("constraints", undirected(isConstraintDecl).map((m) => item(m)));
|
|
174326
|
-
add("assume constraints", members.filter((m) => m.$type === "AssumeConstraintStmt").map((m) => item(m,
|
|
174327
|
-
add("require constraints", members.filter((m) => m.$type === "RequireConstraintStmt").map((m) => item(m,
|
|
174910
|
+
add("assume constraints", members.filter((m) => m.$type === "AssumeConstraintStmt").map((m) => item(m, exprText4(m) || "assume constraint")));
|
|
174911
|
+
add("require constraints", members.filter((m) => m.$type === "RequireConstraintStmt").map((m) => item(m, exprText4(m) || `require ${this.featurePath(m.target) ?? ""}`.trim())));
|
|
174328
174912
|
add("actors", members.filter(isActorDecl).filter(isNonVariantMember).map((m) => item(m)));
|
|
174329
174913
|
add("stakeholders", members.filter(isStakeholderDecl).filter(isNonVariantMember).map((m) => item(m)));
|
|
174330
174914
|
add("frames", members.filter((m) => m.$type === "FrameMember").map((m) => item(m, this.refText(m.target) ?? "concern")));
|
|
@@ -174332,7 +174916,7 @@ ${node.id}`;
|
|
|
174332
174916
|
add("objective", members.filter(isObjectiveDecl).filter(isNonVariantMember).map((m) => item(m, nameOf2(m) ?? "objective")));
|
|
174333
174917
|
add("verifies", members.filter((m) => m.$type === "VerifyStmt").map((m) => item(m, String(m.target ?? ""))));
|
|
174334
174918
|
add("verification methods", members.filter((m) => isMetadataDecl(m) && (typeText(m) ?? "").includes("VerificationMethod")).map((m) => item(m, typeText(m) ?? "method")));
|
|
174335
|
-
const behavioralParameterOwner = isActionDecl(node) || isCalcDecl(node) || isConstraintDecl(node) || isCaseDecl(node) || isAnalysisCaseDecl(node) || isVerificationCaseDecl(node) || isUseCaseDecl(node);
|
|
174919
|
+
const behavioralParameterOwner = ["AssertConstraintStmt", "AssumeConstraintStmt", "RequireConstraintStmt"].includes(node.$type) || isActionDecl(node) || isCalcDecl(node) || isConstraintDecl(node) || isCaseDecl(node) || isAnalysisCaseDecl(node) || isVerificationCaseDecl(node) || isUseCaseDecl(node);
|
|
174336
174920
|
const enclosingBehavioralParameterOwner = (() => {
|
|
174337
174921
|
if (isPartDecl(node) || isPortDecl(node) || directionOf(node) === void 0)
|
|
174338
174922
|
return false;
|
|
@@ -174351,9 +174935,17 @@ ${node.id}`;
|
|
|
174351
174935
|
...members.filter((m) => directionOf(m) !== void 0 && nameOf2(m)).filter((m) => !isVariantMember(m) && !isVariantConfigMember(m)).map((m) => item(m, canonicalFeatureText(m))),
|
|
174352
174936
|
...inheritedRows((member) => directionOf(member) !== void 0 && isNonVariantMember(member))
|
|
174353
174937
|
]);
|
|
174354
|
-
|
|
174355
|
-
|
|
174356
|
-
|
|
174938
|
+
const calculationResult = isCalcDecl(node) ? effectiveCalculationResult(node, (name) => index2?.get(name)) : void 0;
|
|
174939
|
+
const results = calculationResult?.parameter ? [calculationResult.parameter] : members.filter((m) => m.$type === "ReturnDecl");
|
|
174940
|
+
add("result", results.map((m) => item(m, `${calculationResult?.inherited ? "^" : ""}return${nameOf2(m) ? ` ${nameOf2(m)}` : ""}${typeText(m) ? ` : ${typeText(m)}` : ""}${valueTextOf(m) ? ` = ${valueTextOf(m)}` : ""}`)));
|
|
174941
|
+
if (calculationResult?.expression)
|
|
174942
|
+
add("expression", [{
|
|
174943
|
+
text: calculationResult.expression.$cstNode?.text ?? "",
|
|
174944
|
+
source: sourceOf2(calculationResult.expression, uri)
|
|
174945
|
+
}]);
|
|
174946
|
+
if (isConstraintDecl(node) || ["AssertConstraintStmt", "AssumeConstraintStmt", "RequireConstraintStmt"].includes(node.$type)) {
|
|
174947
|
+
add("expression", exprText4(node) ? [{ text: exprText4(node), source: sourceOf2(node, uri) }] : []);
|
|
174948
|
+
}
|
|
174357
174949
|
const enumValueMembers = isEnumDecl(node) ? members.filter(isOwnedEnumerationValue) : members.filter((m) => isNonVariantMember(m) && m.$type === "EnumValueDecl" && !m.typing);
|
|
174358
174950
|
add("enums", enumValueMembers.map((m) => {
|
|
174359
174951
|
const nm = nameOf2(m);
|
|
@@ -174382,11 +174974,11 @@ ${node.id}`;
|
|
|
174382
174974
|
add("state transition", members.filter((m) => m.$type === "TransitionDecl").map((m) => item(m, `${m.from ?? ""} \u2192 ${m.to ?? ""}`)));
|
|
174383
174975
|
const successionText = (m) => (m.$cstNode?.text ?? "").replace(/\s+/g, " ").replace(/;$/, "").trim();
|
|
174384
174976
|
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));
|
|
174385
|
-
add("assert constraints", members.filter((m) => m.$type === "AssertConstraintStmt").map((m) => item(m,
|
|
174977
|
+
add("assert constraints", members.filter((m) => m.$type === "AssertConstraintStmt").map((m) => item(m, exprText4(m) || nameOf2(m) || "assert constraint")));
|
|
174386
174978
|
add("invariants", members.filter((m) => m.$type === "InvShorthand").map((m) => {
|
|
174387
174979
|
const inv = m;
|
|
174388
174980
|
const head2 = `inv${inv.isNegated ? " false" : ""}${nameOf2(m) ? ` ${nameOf2(m)}` : ""}`;
|
|
174389
|
-
const expr =
|
|
174981
|
+
const expr = exprText4(m);
|
|
174390
174982
|
return item(m, `${head2} { ${expr} }`.replace(/\s+/g, " ").trim());
|
|
174391
174983
|
}));
|
|
174392
174984
|
add("actions", usages(isActionDecl).map((m) => item(m)));
|
|
@@ -174643,8 +175235,12 @@ function projectGvCompartments(input) {
|
|
|
174643
175235
|
continue;
|
|
174644
175236
|
visible.add(node.id);
|
|
174645
175237
|
const key2 = gvElementKey(node);
|
|
174646
|
-
const
|
|
174647
|
-
|
|
175238
|
+
const children2 = (index2.children.get(node.id) ?? []).filter(
|
|
175239
|
+
(child) => child.meta?.gvDerived !== true && child.meta?.connectionDefinitionHub !== true
|
|
175240
|
+
);
|
|
175241
|
+
const canExpand = children2.length > 0;
|
|
175242
|
+
const open = canExpand && gvElementIsExpanded(node, expanded2);
|
|
175243
|
+
if (canExpand) expandable.add(key2);
|
|
174648
175244
|
nodes.push({
|
|
174649
175245
|
...node,
|
|
174650
175246
|
parent,
|
|
@@ -174663,7 +175259,7 @@ function projectGvCompartments(input) {
|
|
|
174663
175259
|
...node.meta,
|
|
174664
175260
|
gvMode: "group",
|
|
174665
175261
|
gvExpansionKey: key2,
|
|
174666
|
-
gvCanExpand:
|
|
175262
|
+
gvCanExpand: canExpand,
|
|
174667
175263
|
gvExpanded: open,
|
|
174668
175264
|
gvOpenContainer: open,
|
|
174669
175265
|
internalsHidden: !open,
|
|
@@ -174671,7 +175267,7 @@ function projectGvCompartments(input) {
|
|
|
174671
175267
|
}
|
|
174672
175268
|
});
|
|
174673
175269
|
if (open) {
|
|
174674
|
-
for (const child of
|
|
175270
|
+
for (const child of children2) {
|
|
174675
175271
|
queue.push({ node: child, parent: node.id });
|
|
174676
175272
|
}
|
|
174677
175273
|
}
|
|
@@ -174707,17 +175303,17 @@ function projectGvTree(input) {
|
|
|
174707
175303
|
visible.add(node.id);
|
|
174708
175304
|
const isPackage2 = node.shape === "package";
|
|
174709
175305
|
const children2 = (index2.children.get(node.id) ?? []).filter(
|
|
174710
|
-
(child) => isPackage2 || isGvPartUsage(child)
|
|
175306
|
+
(child) => child.meta?.gvTreeExcluded !== true && !isDerivedHub(child) && (isPackage2 || isGvPartUsage(child) || child.meta?.constraintUsage === true)
|
|
174711
175307
|
);
|
|
174712
175308
|
const key2 = gvElementKey(node);
|
|
174713
|
-
const canExpand =
|
|
175309
|
+
const canExpand = children2.length > 0;
|
|
174714
175310
|
const open = canExpand && gvElementIsExpanded(node, expanded2, true);
|
|
174715
175311
|
if (canExpand) expandable.add(key2);
|
|
174716
175312
|
nodes.push({
|
|
174717
175313
|
...node,
|
|
174718
175314
|
// Tree states membership with a line. It does not borrow canvas containment.
|
|
174719
175315
|
parent: void 0,
|
|
174720
|
-
compartments: (isPackage2 && open ? void 0 : gvPackageMemberCompartments(node, index2))?.filter((compartment) => !open || !isPackage2 &&
|
|
175316
|
+
compartments: (isPackage2 && open ? void 0 : gvPackageMemberCompartments(node, index2))?.filter((compartment) => !open || !isPackage2 && !["parts", "assert constraints", "assume constraints", "require constraints"].includes(compartment.title)).map((compartment) => ({ ...compartment, expandable: false, expanded: false })),
|
|
174721
175317
|
meta: {
|
|
174722
175318
|
...node.meta,
|
|
174723
175319
|
gvMode: "tree",
|
|
@@ -175761,6 +176357,283 @@ function resolveEffectiveSubject(node) {
|
|
|
175761
176357
|
return void 0;
|
|
175762
176358
|
}
|
|
175763
176359
|
|
|
176360
|
+
// ../language-server/out/src/services/case-semantics.js
|
|
176361
|
+
var CASE_KIND_BY_TYPE = /* @__PURE__ */ new Map([
|
|
176362
|
+
["CaseDecl", "case"],
|
|
176363
|
+
["AnalysisCaseDecl", "analysis"],
|
|
176364
|
+
["VerificationCaseDecl", "verification"],
|
|
176365
|
+
["UseCaseDecl", "use-case"]
|
|
176366
|
+
]);
|
|
176367
|
+
var MAX_INHERITANCE_DEPTH2 = 16;
|
|
176368
|
+
function caseKindOf(node) {
|
|
176369
|
+
return node ? CASE_KIND_BY_TYPE.get(node.$type) : void 0;
|
|
176370
|
+
}
|
|
176371
|
+
function enclosingCase(node) {
|
|
176372
|
+
let current2 = node;
|
|
176373
|
+
while (current2) {
|
|
176374
|
+
if (CASE_SHAPED.has(current2.$type))
|
|
176375
|
+
return current2;
|
|
176376
|
+
current2 = current2.$container;
|
|
176377
|
+
}
|
|
176378
|
+
return void 0;
|
|
176379
|
+
}
|
|
176380
|
+
function writtenTypes(node, resolve8) {
|
|
176381
|
+
const out = [];
|
|
176382
|
+
for (const typing of [node.typing, ...node.moreTypings ?? []]) {
|
|
176383
|
+
if (!typing)
|
|
176384
|
+
continue;
|
|
176385
|
+
for (const ref of [typing.type, ...typing.moreTypes ?? []]) {
|
|
176386
|
+
if (!ref)
|
|
176387
|
+
continue;
|
|
176388
|
+
const name = ref.$refText?.trim() ?? ref.ref?.name;
|
|
176389
|
+
if (!name)
|
|
176390
|
+
continue;
|
|
176391
|
+
out.push({ name, node: ref.ref ?? resolve8(name) });
|
|
176392
|
+
}
|
|
176393
|
+
}
|
|
176394
|
+
return out;
|
|
176395
|
+
}
|
|
176396
|
+
function effectiveCaseDefinition(node, resolve8) {
|
|
176397
|
+
const kind = caseKindOf(node);
|
|
176398
|
+
if (!kind)
|
|
176399
|
+
return void 0;
|
|
176400
|
+
const decl = node;
|
|
176401
|
+
const resolver = resolve8 ?? documentResolver(node);
|
|
176402
|
+
const definitions = writtenTypes(decl, resolver).filter((type) => type.node === void 0 || CASE_SHAPED.has(type.node.$type));
|
|
176403
|
+
return {
|
|
176404
|
+
kind,
|
|
176405
|
+
isDefinition: decl.isDef === true,
|
|
176406
|
+
definitions,
|
|
176407
|
+
sole: definitions.length === 1 ? definitions[0] : void 0
|
|
176408
|
+
};
|
|
176409
|
+
}
|
|
176410
|
+
function hasAmbiguousDefinition(node, resolve8) {
|
|
176411
|
+
const effective = effectiveCaseDefinition(node, resolve8);
|
|
176412
|
+
if (!effective || effective.isDefinition)
|
|
176413
|
+
return false;
|
|
176414
|
+
return effective.definitions.filter((type) => type.node !== void 0).length > 1;
|
|
176415
|
+
}
|
|
176416
|
+
function isDecidedSubject(subject) {
|
|
176417
|
+
if (!subject)
|
|
176418
|
+
return false;
|
|
176419
|
+
return subject.origin !== "default" && subject.origin !== "ambiguous" && subject.typeName !== DEFAULT_SUBJECT_TYPE;
|
|
176420
|
+
}
|
|
176421
|
+
function effectiveCaseSubject(node, resolve8) {
|
|
176422
|
+
const resolver = resolve8 ?? documentResolver(node);
|
|
176423
|
+
if (hasAmbiguousDefinition(node, resolver)) {
|
|
176424
|
+
const own = ownSubject(node);
|
|
176425
|
+
return own ? subjectInfo(own, node, "own") : { typeName: DEFAULT_SUBJECT_TYPE, origin: "ambiguous" };
|
|
176426
|
+
}
|
|
176427
|
+
return effectiveSubject(node, resolver);
|
|
176428
|
+
}
|
|
176429
|
+
function ownActors(node) {
|
|
176430
|
+
return (node.members ?? []).filter((member) => member.$type === "ActorDecl");
|
|
176431
|
+
}
|
|
176432
|
+
function effectiveActors(node, resolve8) {
|
|
176433
|
+
const resolver = resolve8 ?? documentResolver(node);
|
|
176434
|
+
const ambiguous = hasAmbiguousDefinition(node, resolver);
|
|
176435
|
+
const out = [];
|
|
176436
|
+
const seenNodes = /* @__PURE__ */ new Set();
|
|
176437
|
+
const seenNames = /* @__PURE__ */ new Set();
|
|
176438
|
+
const walk = (current2, origin, depth) => {
|
|
176439
|
+
if (depth > MAX_INHERITANCE_DEPTH2 || seenNodes.has(current2))
|
|
176440
|
+
return;
|
|
176441
|
+
seenNodes.add(current2);
|
|
176442
|
+
for (const actor of ownActors(current2)) {
|
|
176443
|
+
if (actor.name && seenNames.has(actor.name))
|
|
176444
|
+
continue;
|
|
176445
|
+
if (actor.name)
|
|
176446
|
+
seenNames.add(actor.name);
|
|
176447
|
+
out.push({
|
|
176448
|
+
declaration: actor,
|
|
176449
|
+
name: actor.name,
|
|
176450
|
+
typeName: subjectTypeName(actor),
|
|
176451
|
+
origin,
|
|
176452
|
+
owner: current2
|
|
176453
|
+
});
|
|
176454
|
+
}
|
|
176455
|
+
if (ambiguous)
|
|
176456
|
+
return;
|
|
176457
|
+
for (const supertype of supertypesOf(current2, resolver)) {
|
|
176458
|
+
if (!CASE_SHAPED.has(supertype.$type))
|
|
176459
|
+
continue;
|
|
176460
|
+
walk(supertype, "inherited", depth + 1);
|
|
176461
|
+
}
|
|
176462
|
+
};
|
|
176463
|
+
walk(node, "own", 0);
|
|
176464
|
+
return out;
|
|
176465
|
+
}
|
|
176466
|
+
function caseResult(node, resolve8) {
|
|
176467
|
+
const resolver = resolve8 ?? documentResolver(node);
|
|
176468
|
+
const ambiguous = hasAmbiguousDefinition(node, resolver);
|
|
176469
|
+
const seen = /* @__PURE__ */ new Set();
|
|
176470
|
+
const walk = (current2, origin, depth) => {
|
|
176471
|
+
if (depth > MAX_INHERITANCE_DEPTH2 || seen.has(current2))
|
|
176472
|
+
return void 0;
|
|
176473
|
+
seen.add(current2);
|
|
176474
|
+
const own = (current2.members ?? []).find((member) => member.$type === "ReturnDecl");
|
|
176475
|
+
if (own) {
|
|
176476
|
+
return {
|
|
176477
|
+
declaration: own,
|
|
176478
|
+
name: own.name,
|
|
176479
|
+
typeName: subjectTypeName(own),
|
|
176480
|
+
origin,
|
|
176481
|
+
owner: current2
|
|
176482
|
+
};
|
|
176483
|
+
}
|
|
176484
|
+
if (ambiguous)
|
|
176485
|
+
return void 0;
|
|
176486
|
+
for (const supertype of supertypesOf(current2, resolver)) {
|
|
176487
|
+
if (!CASE_SHAPED.has(supertype.$type))
|
|
176488
|
+
continue;
|
|
176489
|
+
const inherited = walk(supertype, "inherited", depth + 1);
|
|
176490
|
+
if (inherited)
|
|
176491
|
+
return inherited;
|
|
176492
|
+
}
|
|
176493
|
+
return void 0;
|
|
176494
|
+
};
|
|
176495
|
+
return walk(node, "own", 0);
|
|
176496
|
+
}
|
|
176497
|
+
function objectiveBindingOf(objective, resolve8) {
|
|
176498
|
+
if (objective.$type !== "ObjectiveDecl")
|
|
176499
|
+
return void 0;
|
|
176500
|
+
const caseNode = enclosingCase(objective.$container);
|
|
176501
|
+
const caseKind = caseKindOf(caseNode);
|
|
176502
|
+
if (!caseNode || !caseKind)
|
|
176503
|
+
return void 0;
|
|
176504
|
+
const resolver = resolve8 ?? documentResolver(objective);
|
|
176505
|
+
const own = ownSubject(objective);
|
|
176506
|
+
const bindsSubject = caseKind === "verification" || caseKind === "use-case";
|
|
176507
|
+
if (bindsSubject) {
|
|
176508
|
+
const subject = effectiveCaseSubject(caseNode, resolver);
|
|
176509
|
+
return {
|
|
176510
|
+
objective,
|
|
176511
|
+
caseNode,
|
|
176512
|
+
caseKind,
|
|
176513
|
+
target: "case-subject",
|
|
176514
|
+
strength: "bind",
|
|
176515
|
+
boundTo: subject.declaration,
|
|
176516
|
+
// An undecided subject names no type: the case still binds its
|
|
176517
|
+
// objective to whatever its subject is, but neither hover nor
|
|
176518
|
+
// `SSM046` may say what that is.
|
|
176519
|
+
typeName: isDecidedSubject(subject) ? subject.typeName : void 0,
|
|
176520
|
+
own
|
|
176521
|
+
};
|
|
176522
|
+
}
|
|
176523
|
+
const result = caseResult(caseNode, resolver);
|
|
176524
|
+
return {
|
|
176525
|
+
objective,
|
|
176526
|
+
caseNode,
|
|
176527
|
+
caseKind,
|
|
176528
|
+
target: "case-result",
|
|
176529
|
+
strength: "default",
|
|
176530
|
+
boundTo: result?.declaration,
|
|
176531
|
+
typeName: result?.typeName,
|
|
176532
|
+
own
|
|
176533
|
+
};
|
|
176534
|
+
}
|
|
176535
|
+
function effectiveObjectiveSubject(objective, resolve8) {
|
|
176536
|
+
const resolver = resolve8 ?? documentResolver(objective);
|
|
176537
|
+
const binding = objectiveBindingOf(objective, resolver);
|
|
176538
|
+
const own = ownSubject(objective);
|
|
176539
|
+
if (!binding) {
|
|
176540
|
+
return own ? { declaration: own, name: own.name, typeName: subjectTypeName(own) ?? DEFAULT_SUBJECT_TYPE, origin: "own", owner: objective } : { typeName: DEFAULT_SUBJECT_TYPE, origin: "default" };
|
|
176541
|
+
}
|
|
176542
|
+
if (own && binding.strength === "default") {
|
|
176543
|
+
return {
|
|
176544
|
+
declaration: own,
|
|
176545
|
+
name: own.name,
|
|
176546
|
+
typeName: subjectTypeName(own) ?? DEFAULT_SUBJECT_TYPE,
|
|
176547
|
+
origin: "own",
|
|
176548
|
+
owner: objective
|
|
176549
|
+
};
|
|
176550
|
+
}
|
|
176551
|
+
return {
|
|
176552
|
+
declaration: binding.boundTo,
|
|
176553
|
+
typeName: binding.typeName ?? DEFAULT_SUBJECT_TYPE,
|
|
176554
|
+
origin: "enclosing",
|
|
176555
|
+
owner: binding.caseNode
|
|
176556
|
+
};
|
|
176557
|
+
}
|
|
176558
|
+
function objectiveSubrequirements(objective, resolve8) {
|
|
176559
|
+
if (objective.$type !== "ObjectiveDecl")
|
|
176560
|
+
return [];
|
|
176561
|
+
const resolver = resolve8 ?? documentResolver(objective);
|
|
176562
|
+
const subjectTypeName2 = effectiveObjectiveSubject(objective, resolver).typeName;
|
|
176563
|
+
const out = [];
|
|
176564
|
+
for (const member of objective.members ?? []) {
|
|
176565
|
+
if (member.$type === "VerifyStmt") {
|
|
176566
|
+
const path10 = referencePathOf(member);
|
|
176567
|
+
out.push({
|
|
176568
|
+
declaration: member,
|
|
176569
|
+
kind: "verify",
|
|
176570
|
+
path: path10,
|
|
176571
|
+
target: referenceTargetOf(member, resolver),
|
|
176572
|
+
subjectTypeName: subjectTypeName2
|
|
176573
|
+
});
|
|
176574
|
+
} else if (member.$type === "RequirementDecl") {
|
|
176575
|
+
out.push({ declaration: member, kind: "requirement", subjectTypeName: subjectTypeName2 });
|
|
176576
|
+
}
|
|
176577
|
+
}
|
|
176578
|
+
return out;
|
|
176579
|
+
}
|
|
176580
|
+
function valueSimpleName(value) {
|
|
176581
|
+
const node = value;
|
|
176582
|
+
if (!node)
|
|
176583
|
+
return void 0;
|
|
176584
|
+
if (node.$type === "ParenExpr") {
|
|
176585
|
+
const items = node.items ?? [];
|
|
176586
|
+
return items.length === 1 ? valueSimpleName(items[0]) : void 0;
|
|
176587
|
+
}
|
|
176588
|
+
if (node.$type !== "PathExpr")
|
|
176589
|
+
return void 0;
|
|
176590
|
+
return node.path ? simpleName(node.path) : void 0;
|
|
176591
|
+
}
|
|
176592
|
+
function includeBindingOf(stmt, resolve8) {
|
|
176593
|
+
if (stmt.$type !== "IncludeStmt")
|
|
176594
|
+
return void 0;
|
|
176595
|
+
const node = stmt;
|
|
176596
|
+
const resolver = resolve8 ?? documentResolver(stmt);
|
|
176597
|
+
const isUseCase = (candidate) => candidate !== void 0 && candidate.$type === "UseCaseDecl";
|
|
176598
|
+
const typed = writtenTypes(node, resolver).find((type) => type.node === void 0 || isUseCase(type.node));
|
|
176599
|
+
const path10 = referencePathOf(node);
|
|
176600
|
+
const named2 = typed?.node ?? (typed ? void 0 : referenceTargetOf(node, resolver));
|
|
176601
|
+
const target = isUseCase(named2) ? named2 : void 0;
|
|
176602
|
+
const form = node.useCaseKw === true || typed !== void 0 ? "declaration" : "reference";
|
|
176603
|
+
const containing = enclosingCase(node.$container);
|
|
176604
|
+
const parameters = target ? effectiveActors(target, resolver) : [];
|
|
176605
|
+
const actors = [];
|
|
176606
|
+
for (const member of node.members ?? []) {
|
|
176607
|
+
if (member.$type !== "ActorDecl")
|
|
176608
|
+
continue;
|
|
176609
|
+
const name = member.name;
|
|
176610
|
+
actors.push({
|
|
176611
|
+
declaration: member,
|
|
176612
|
+
name,
|
|
176613
|
+
valueName: valueSimpleName(member.value),
|
|
176614
|
+
typeName: subjectTypeName(member),
|
|
176615
|
+
parameter: name ? parameters.find((parameter) => parameter.name === name) : void 0
|
|
176616
|
+
});
|
|
176617
|
+
}
|
|
176618
|
+
const containingSubject = containing ? effectiveCaseSubject(containing, resolver) : void 0;
|
|
176619
|
+
const includedSubject = target ? effectiveCaseSubject(target, resolver) : void 0;
|
|
176620
|
+
const subjectOrigin = isDecidedSubject(includedSubject) ? "included" : isDecidedSubject(containingSubject) ? "containing" : "default";
|
|
176621
|
+
const subjectTypeName2 = subjectOrigin === "included" ? includedSubject.typeName : subjectOrigin === "containing" ? containingSubject.typeName : DEFAULT_SUBJECT_TYPE;
|
|
176622
|
+
return {
|
|
176623
|
+
statement: stmt,
|
|
176624
|
+
form,
|
|
176625
|
+
path: typed ? typed.name : path10,
|
|
176626
|
+
target,
|
|
176627
|
+
containing,
|
|
176628
|
+
containingSubject,
|
|
176629
|
+
includedSubject,
|
|
176630
|
+
subjectOrigin,
|
|
176631
|
+
subjectTypeName: subjectTypeName2,
|
|
176632
|
+
parameters,
|
|
176633
|
+
actors
|
|
176634
|
+
};
|
|
176635
|
+
}
|
|
176636
|
+
|
|
175764
176637
|
// ../language-server/out/src/services/implicit-specialization.js
|
|
175765
176638
|
var EXPLICIT_SPECIALIZATION_KINDS = /* @__PURE__ */ new Set([
|
|
175766
176639
|
":>",
|
|
@@ -176530,11 +177403,64 @@ var DIAGNOSTIC_MESSAGES = {
|
|
|
176530
177403
|
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.`,
|
|
176531
177404
|
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'.`,
|
|
176532
177405
|
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.`,
|
|
177406
|
+
// REQ-415 — issue #164. `assert c`, `require c` and `assume c` all reach their
|
|
177407
|
+
// constraint through the same OwnedReferenceSubsetting, so one message covers
|
|
177408
|
+
// the three. The kind is named because the fix depends on it: a part or an
|
|
177409
|
+
// action is not something that can be true or false.
|
|
177410
|
+
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.`,
|
|
177411
|
+
// REQ-415 — the reference resolves and its constraint evaluates to a definite
|
|
177412
|
+
// false, so the model states something against itself. A warning, never an
|
|
177413
|
+
// error: the text is well formed, and only a closed constant expression is
|
|
177414
|
+
// decided at all - anything that depends on a binding stays silent.
|
|
177415
|
+
SEM014_ASSERTION_VIOLATED: (text) => `Asserted constraint '${text}' evaluates to false, so this model is inconsistent as written.`,
|
|
177416
|
+
// REQ-131 — a constraint is a predicate: `BooleanEvaluation` returns
|
|
177417
|
+
// `Boolean[1]` (Kernel Semantic Library, `Performances.kerml`). A body that is
|
|
177418
|
+
// demonstrably some other type can never be true or false. Only a body the
|
|
177419
|
+
// checker can PROVE is not Boolean is reported, so an expression whose type it
|
|
177420
|
+
// cannot settle stays silent.
|
|
177421
|
+
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.`,
|
|
177422
|
+
// REQ-209 — a usage inherits its definition's expression. Replacing it hides
|
|
177423
|
+
// what the definition says while every other usage still reads the original.
|
|
177424
|
+
// Advisory: the language permits the redefinition, the modelling idiom does not
|
|
177425
|
+
// use it, and no model in the OMG corpus does.
|
|
177426
|
+
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.`,
|
|
177427
|
+
/* REQ-376 — a parameter of a constraint or a calculation is an INPUT.
|
|
177428
|
+
*
|
|
177429
|
+
* A constraint is a predicate: its one output is its Boolean result, which
|
|
177430
|
+
* comes from the body, never from a parameter. A calculation produces its
|
|
177431
|
+
* value through `return`. Neither has anything to send back out through a
|
|
177432
|
+
* parameter, and the OMG corpus bears that out: 40 `in` parameters on
|
|
177433
|
+
* constraints and 44 on calculations, and not one `out` or `inout` on either.
|
|
177434
|
+
*
|
|
177435
|
+
* A constraint is also ACAUSAL — `StraightLineDynamicsEquations` declares even
|
|
177436
|
+
* the quantities it would be solved for (`x_f`, `v_f`, `a`) as `in`, because
|
|
177437
|
+
* which parameter is the unknown is the binding's business, not the
|
|
177438
|
+
* constraint's. Fixing a direction would bake in one solving order. */
|
|
177439
|
+
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.`,
|
|
177440
|
+
// REQ-376 — a directed parameter is an input to be bound by a usage, not a
|
|
177441
|
+
// value slot. OMG declares parameters bare on a definition and puts values on
|
|
177442
|
+
// `attribute` members (`StraightLineDynamicsEquations`).
|
|
177443
|
+
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.`,
|
|
176533
177444
|
// issue #165 — a satisfaction binds a thing to the subject a requirement
|
|
176534
177445
|
// constrains, so the thing has to BE one of those (OMG SysML v2 Part 1
|
|
176535
177446
|
// §7.21.2). The message names both types because the fix is either to bind a
|
|
176536
177447
|
// different satisfier or to widen the requirement's subject.
|
|
176537
177448
|
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.`,
|
|
177449
|
+
// issue #166 — a case usage performs ONE case (OMG SysML v2 Part 1 §7.22.2),
|
|
177450
|
+
// and every effective binding this extension derives reads through that one:
|
|
177451
|
+
// the subject, the actor parameters and the objective. Two definitions leave
|
|
177452
|
+
// all three undecided, so the message names them and asks for one.
|
|
177453
|
+
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.`,
|
|
177454
|
+
// issue #166 — an `objective` written inside a verification case or a use
|
|
177455
|
+
// case has its subject BOUND to the case's subject, so a `subject` of an
|
|
177456
|
+
// unrelated type on the objective states something the case has already
|
|
177457
|
+
// decided otherwise.
|
|
177458
|
+
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.`,
|
|
177459
|
+
// issue #166 — an `include` investigates the included use case on the
|
|
177460
|
+
// including case's subject (§7.25), and an `actor` written inside the
|
|
177461
|
+
// include binds one of the included use case's actor parameters.
|
|
177462
|
+
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.`,
|
|
177463
|
+
SSM048_INCLUDE_ACTOR_BINDING: (actor, included, known2) => `'${actor}' is not an actor parameter of the included use case '${included}'. It declares ${known2}.`,
|
|
176538
177464
|
// REQ-392 — a `sysml-format` comment the formatter cannot act on. Advisory:
|
|
176539
177465
|
// the directive is inert, and saying so beats leaving the author to wonder
|
|
176540
177466
|
// why their layout was reformatted anyway.
|
|
@@ -176997,7 +177923,7 @@ function nearestAncestor(node, types) {
|
|
|
176997
177923
|
}
|
|
176998
177924
|
return void 0;
|
|
176999
177925
|
}
|
|
177000
|
-
function
|
|
177926
|
+
function exprText3(node) {
|
|
177001
177927
|
return node?.$cstNode?.text?.trim().replace(/\s+/gu, " ") ?? "";
|
|
177002
177928
|
}
|
|
177003
177929
|
function conditionTypeLabel(node) {
|
|
@@ -177008,7 +177934,7 @@ function conditionTypeLabel(node) {
|
|
|
177008
177934
|
if (["AndExpr", "OrExpr", "XorExpr", "NotExpr", "CompareExpr", "ClassifyOp"].includes(node.$type)) {
|
|
177009
177935
|
return "Boolean";
|
|
177010
177936
|
}
|
|
177011
|
-
const text =
|
|
177937
|
+
const text = exprText3(node);
|
|
177012
177938
|
return /\b(true|false)\b|[=!<>]=?|(?:\band\b|\bor\b|\bnot\b|\bxor\b)/u.test(text) ? "Boolean" : "Boolean (expected)";
|
|
177013
177939
|
}
|
|
177014
177940
|
function buildConditionalHover(node) {
|
|
@@ -177022,7 +177948,7 @@ function buildConditionalHover(node) {
|
|
|
177022
177948
|
"",
|
|
177023
177949
|
"Canonical form: `if condition ? thenExpression else elseExpression`",
|
|
177024
177950
|
`Then marker: ${usesQuestion ? "canonical `?`" : "non-canonical `then`; use `?`"}`,
|
|
177025
|
-
`Condition: \`${
|
|
177951
|
+
`Condition: \`${exprText3(n2.cond)}\``,
|
|
177026
177952
|
`Condition type: ${conditionTypeLabel(n2.cond)}`,
|
|
177027
177953
|
"",
|
|
177028
177954
|
sourceFooter(nodeSource(node))
|
|
@@ -177194,6 +178120,8 @@ ${headerLines.join("\n")}
|
|
|
177194
178120
|
const subject = subjectInheritanceSection(node);
|
|
177195
178121
|
if (subject)
|
|
177196
178122
|
parts.push(subject);
|
|
178123
|
+
for (const section of caseBindingSections(node))
|
|
178124
|
+
parts.push(section);
|
|
177197
178125
|
if (relationshipDetails)
|
|
177198
178126
|
parts.push(relationshipDetails);
|
|
177199
178127
|
const flip = conjugationFlipSection(node);
|
|
@@ -177230,6 +178158,62 @@ function subjectInheritanceSection(node) {
|
|
|
177230
178158
|
const ownerName = effective.owner.name ?? "(anonymous requirement)";
|
|
177231
178159
|
return `*Subject inherited from \`${ownerName}\`:* \`${subjectText}\``;
|
|
177232
178160
|
}
|
|
178161
|
+
var CASE_KIND_LABELS = {
|
|
178162
|
+
"case": "Case",
|
|
178163
|
+
"analysis": "Analysis case",
|
|
178164
|
+
"verification": "Verification case",
|
|
178165
|
+
"use-case": "Use case"
|
|
178166
|
+
};
|
|
178167
|
+
function caseBindingSections(node) {
|
|
178168
|
+
const out = [];
|
|
178169
|
+
const kind = caseKindOf(node);
|
|
178170
|
+
if (kind) {
|
|
178171
|
+
const effective = effectiveCaseDefinition(node);
|
|
178172
|
+
if (effective && !effective.isDefinition && effective.sole) {
|
|
178173
|
+
out.push(`*${CASE_KIND_LABELS[kind]} performs:* \`${effective.sole.name}\``);
|
|
178174
|
+
}
|
|
178175
|
+
const subject = effectiveCaseSubject(node);
|
|
178176
|
+
if (subject.origin === "inherited") {
|
|
178177
|
+
const owner = subject.owner?.name;
|
|
178178
|
+
out.push(`*Subject inherited${owner ? ` from \`${owner}\`` : ""}:* \`${subject.name ?? "subject"} : ${subject.typeName}\``);
|
|
178179
|
+
} else if (subject.origin === "default") {
|
|
178180
|
+
out.push("*Subject:* none declared, so this case investigates `Anything`.");
|
|
178181
|
+
}
|
|
178182
|
+
const inherited = effectiveActors(node).filter((actor) => actor.origin === "inherited");
|
|
178183
|
+
if (inherited.length > 0) {
|
|
178184
|
+
const list = inherited.map((actor) => `\`${actor.name ?? "actor"}${actor.typeName ? ` : ${actor.typeName}` : ""}\``).join(", ");
|
|
178185
|
+
out.push(`*Actors inherited:* ${list}`);
|
|
178186
|
+
}
|
|
178187
|
+
}
|
|
178188
|
+
if (node.$type === "ObjectiveDecl") {
|
|
178189
|
+
const binding = objectiveBindingOf(node);
|
|
178190
|
+
if (binding) {
|
|
178191
|
+
const what = binding.target === "case-subject" ? "subject" : "result";
|
|
178192
|
+
const verb = binding.strength === "bind" ? "is bound to" : "defaults to";
|
|
178193
|
+
const type = binding.typeName ? ` (\`${binding.typeName}\`)` : "";
|
|
178194
|
+
const caseName = binding.caseNode.name;
|
|
178195
|
+
out.push(`*Objective subject ${verb}* the ${what} of ${caseName ? `\`${caseName}\`` : "the enclosing case"}${type}.`);
|
|
178196
|
+
}
|
|
178197
|
+
const subrequirements = objectiveSubrequirements(node);
|
|
178198
|
+
if (subrequirements.length > 0) {
|
|
178199
|
+
const list = subrequirements.map((sub) => `\`${sub.path ?? sub.declaration.name ?? "requirement"}\``).join(", ");
|
|
178200
|
+
out.push(`*Required subrequirements:* ${list} \u2014 each is checked on this objective's subject.`);
|
|
178201
|
+
}
|
|
178202
|
+
}
|
|
178203
|
+
if (node.$type === "IncludeStmt") {
|
|
178204
|
+
const binding = includeBindingOf(node);
|
|
178205
|
+
if (binding?.target) {
|
|
178206
|
+
const name = binding.path ? `\`${binding.path}\`` : "the included use case";
|
|
178207
|
+
out.push(`*Includes:* ${name}, a reference to a use case performed elsewhere. It keeps its own identity and is not copied here.`);
|
|
178208
|
+
if (binding.subjectOrigin === "containing") {
|
|
178209
|
+
out.push(`*Investigated on:* the including case's subject (\`${binding.subjectTypeName}\`).`);
|
|
178210
|
+
} else if (binding.subjectOrigin === "included") {
|
|
178211
|
+
out.push(`*Investigated on:* its own subject (\`${binding.subjectTypeName}\`).`);
|
|
178212
|
+
}
|
|
178213
|
+
}
|
|
178214
|
+
}
|
|
178215
|
+
return out;
|
|
178216
|
+
}
|
|
177233
178217
|
function flipDirection(direction) {
|
|
177234
178218
|
return direction === "in" ? "out" : direction === "out" ? "in" : direction;
|
|
177235
178219
|
}
|
|
@@ -178204,6 +179188,13 @@ var TYPE_CONTEXTS = {
|
|
|
178204
179188
|
calc: ["CalcDecl", "FunctionDecl"],
|
|
178205
179189
|
constraint: ["ConstraintDecl", "PredicateDecl"]
|
|
178206
179190
|
};
|
|
179191
|
+
var CONSTRAINT_REFERENCE_TYPES = [
|
|
179192
|
+
"ConstraintDecl",
|
|
179193
|
+
"InvShorthand",
|
|
179194
|
+
"PredicateDecl",
|
|
179195
|
+
"RequirementDecl",
|
|
179196
|
+
"ConcernDecl"
|
|
179197
|
+
];
|
|
178207
179198
|
var ALL_DEFINITION_TYPES = [
|
|
178208
179199
|
"PartDecl",
|
|
178209
179200
|
"PortDecl",
|
|
@@ -178389,6 +179380,10 @@ var SysmlCompletionProvider = class extends DefaultCompletionProvider {
|
|
|
178389
179380
|
allowedLabels.add("requirement");
|
|
178390
179381
|
allowedLabels.add("by");
|
|
178391
179382
|
}
|
|
179383
|
+
if (context.kind === "constraint-reference") {
|
|
179384
|
+
allowedLabels.add("constraint");
|
|
179385
|
+
allowedLabels.add("not");
|
|
179386
|
+
}
|
|
178392
179387
|
if (context.kind === "specialization") {
|
|
178393
179388
|
allowedLabels.add("specializes");
|
|
178394
179389
|
allowedLabels.add("subsets");
|
|
@@ -178463,6 +179458,14 @@ var SysmlCompletionProvider = class extends DefaultCompletionProvider {
|
|
|
178463
179458
|
addUnique(items, this.visibleSymbolItems(["RequirementDecl"], { document: document2, offset: offset2 }));
|
|
178464
179459
|
return;
|
|
178465
179460
|
}
|
|
179461
|
+
// REQ-415 — a reference shorthand names a CONSTRAINT, so the slot
|
|
179462
|
+
// offers constraint usages and definitions rather than every symbol.
|
|
179463
|
+
// A requirement and a concern are constraints too (OMG SysML v2
|
|
179464
|
+
// Part 1 §7.20.2, §7.21.2), so both belong in the list.
|
|
179465
|
+
case "constraint-reference": {
|
|
179466
|
+
addUnique(items, this.visibleSymbolItems(CONSTRAINT_REFERENCE_TYPES, { document: document2, offset: offset2 }));
|
|
179467
|
+
return;
|
|
179468
|
+
}
|
|
178466
179469
|
case "connect": {
|
|
178467
179470
|
addUnique(items, this.connectPortItems(document2, offset2));
|
|
178468
179471
|
return;
|
|
@@ -178484,6 +179487,8 @@ var SysmlCompletionProvider = class extends DefaultCompletionProvider {
|
|
|
178484
179487
|
symbolTypesForContext(context) {
|
|
178485
179488
|
if (context.kind === "verify" || context.kind === "satisfy")
|
|
178486
179489
|
return ["RequirementDecl"];
|
|
179490
|
+
if (context.kind === "constraint-reference")
|
|
179491
|
+
return CONSTRAINT_REFERENCE_TYPES;
|
|
178487
179492
|
const keyword = context.typingKeyword;
|
|
178488
179493
|
if (!keyword)
|
|
178489
179494
|
return ALL_DEFINITION_TYPES;
|
|
@@ -178687,6 +179692,9 @@ function detectCompletionContext(text, offset2) {
|
|
|
178687
179692
|
if (/\bconnect\s+(?:[\p{L}_:'.]+(?:\.[\p{L}_:']+)*\s+to\s*)?[\p{L}_:'.]*$/u.test(statement)) {
|
|
178688
179693
|
return { kind: "connect", statement };
|
|
178689
179694
|
}
|
|
179695
|
+
if (/\b(?:assert|require|assume)\s+(?:not\s+)?[\p{L}_:'.]*$/u.test(statement)) {
|
|
179696
|
+
return { kind: "constraint-reference", statement };
|
|
179697
|
+
}
|
|
178690
179698
|
if (/(?:^|[^\w:])(?::>|:>>|specializes|subsets|redefines)\s*~?[\p{L}_:'.]*$/u.test(statement)) {
|
|
178691
179699
|
return { kind: "specialization", statement, typingKeyword: keyword };
|
|
178692
179700
|
}
|
|
@@ -180197,6 +181205,60 @@ var CONSTRAINT_SIDE_EFFECT_TYPES = /* @__PURE__ */ new Set([
|
|
|
180197
181205
|
"DoAction",
|
|
180198
181206
|
"ExitAction"
|
|
180199
181207
|
]);
|
|
181208
|
+
var BOOLEAN_OPERATORS = /* @__PURE__ */ new Set([
|
|
181209
|
+
"or",
|
|
181210
|
+
"|",
|
|
181211
|
+
"implies",
|
|
181212
|
+
"xor",
|
|
181213
|
+
"and",
|
|
181214
|
+
"&",
|
|
181215
|
+
">=",
|
|
181216
|
+
"<=",
|
|
181217
|
+
"===",
|
|
181218
|
+
"!==",
|
|
181219
|
+
"==",
|
|
181220
|
+
"!=",
|
|
181221
|
+
">",
|
|
181222
|
+
"<",
|
|
181223
|
+
"hastype",
|
|
181224
|
+
"istype",
|
|
181225
|
+
"@",
|
|
181226
|
+
"@@"
|
|
181227
|
+
]);
|
|
181228
|
+
var ARITHMETIC_OPERATORS = /* @__PURE__ */ new Set(["+", "-", "*", "/", "%", "**", "^", ".."]);
|
|
181229
|
+
function nonBooleanExpressionKind(expr) {
|
|
181230
|
+
const node = expr;
|
|
181231
|
+
switch (expr.$type) {
|
|
181232
|
+
case "NumericPrimary":
|
|
181233
|
+
return node.unit ? "a quantity" : "a number";
|
|
181234
|
+
case "LiteralStr":
|
|
181235
|
+
return "a string";
|
|
181236
|
+
case "UnaryMinusExpr":
|
|
181237
|
+
case "UnaryPlusExpr":
|
|
181238
|
+
return "a number";
|
|
181239
|
+
case "ParenExpr": {
|
|
181240
|
+
const items = Array.isArray(node.items) ? node.items : [];
|
|
181241
|
+
return items.length === 1 ? nonBooleanExpressionKind(items[0]) : void 0;
|
|
181242
|
+
}
|
|
181243
|
+
case "BinExpr": {
|
|
181244
|
+
const op = typeof node.op === "string" ? node.op : void 0;
|
|
181245
|
+
if (op && BOOLEAN_OPERATORS.has(op))
|
|
181246
|
+
return void 0;
|
|
181247
|
+
if (op && ARITHMETIC_OPERATORS.has(op)) {
|
|
181248
|
+
return op === ".." ? "a range" : "an arithmetic expression";
|
|
181249
|
+
}
|
|
181250
|
+
return void 0;
|
|
181251
|
+
}
|
|
181252
|
+
default:
|
|
181253
|
+
return void 0;
|
|
181254
|
+
}
|
|
181255
|
+
}
|
|
181256
|
+
function directionOfModifiers(node) {
|
|
181257
|
+
const modifiers2 = node.modifiers;
|
|
181258
|
+
if (!Array.isArray(modifiers2))
|
|
181259
|
+
return void 0;
|
|
181260
|
+
return modifiers2.find((modifier) => modifier === "in" || modifier === "out" || modifier === "inout");
|
|
181261
|
+
}
|
|
180200
181262
|
var ACTION_BODY_TYPES = /* @__PURE__ */ new Set([
|
|
180201
181263
|
"ActionDecl",
|
|
180202
181264
|
"PerformStmt",
|
|
@@ -180497,7 +181559,122 @@ var SysmlValidator = class _SysmlValidator {
|
|
|
180497
181559
|
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" });
|
|
180498
181560
|
}
|
|
180499
181561
|
}
|
|
181562
|
+
const notBoolean = node.body ? nonBooleanExpressionKind(node.body) : void 0;
|
|
181563
|
+
if (node.body?.$cstNode && notBoolean) {
|
|
181564
|
+
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" });
|
|
181565
|
+
}
|
|
181566
|
+
if (!node.isDef && node.body) {
|
|
181567
|
+
const definition = this.constraintTypeOf(node);
|
|
181568
|
+
if (definition?.body && definition.name) {
|
|
181569
|
+
accept(severity("STYL012", "hint"), DIAGNOSTIC_MESSAGES.STYL012_CONSTRAINT_BODY_OVERRIDES_DEFINITION(node.name ?? "(anonymous)", definition.name), { node, property: "body", code: "STYL012" });
|
|
181570
|
+
}
|
|
181571
|
+
}
|
|
181572
|
+
}
|
|
181573
|
+
/** REQ-209 — the constraint definition a usage is typed by, when the link
|
|
181574
|
+
* resolved. Only a direct typing is followed: a deeper specialization chain
|
|
181575
|
+
* is not what "replaces its definition's expression" is about. */
|
|
181576
|
+
constraintTypeOf(node) {
|
|
181577
|
+
const target = node.typing?.type?.ref;
|
|
181578
|
+
return target?.$type === "ConstraintDecl" ? target : void 0;
|
|
180500
181579
|
}
|
|
181580
|
+
/* REQ-376 (user direction 2026-09-07) — STYL014: a parameter of a constraint
|
|
181581
|
+
* or a calculation is an INPUT. A constraint's one output is its Boolean
|
|
181582
|
+
* result and a calculation's is its `return`; neither sends anything back
|
|
181583
|
+
* through a parameter, and no model in the OMG corpus declares one `out` or
|
|
181584
|
+
* `inout`.
|
|
181585
|
+
*
|
|
181586
|
+
* Reported where the parameter is DECLARED: on a definition, and on a usage
|
|
181587
|
+
* that declares its own (an untyped `constraint c { out x : T; … }`). A TYPED
|
|
181588
|
+
* usage inherits its parameters, so a direction written there is a
|
|
181589
|
+
* redefinition of one, and `SSM025` already reports that as an error - saying
|
|
181590
|
+
* it twice, once as an error and once as an advisory, helps nobody. */
|
|
181591
|
+
checkParameterDirection(node, accept) {
|
|
181592
|
+
const decl = node;
|
|
181593
|
+
const typed = node.typing?.type?.ref;
|
|
181594
|
+
if (decl.isDef !== true && typed)
|
|
181595
|
+
return;
|
|
181596
|
+
const kind = node.$type === "ConstraintDecl" ? "constraint" : "calculation";
|
|
181597
|
+
const owner = typeof decl.name === "string" && decl.name ? decl.name : "(anonymous)";
|
|
181598
|
+
for (const member of decl.members ?? []) {
|
|
181599
|
+
const direction = directionOfModifiers(member);
|
|
181600
|
+
if (direction !== "out" && direction !== "inout")
|
|
181601
|
+
continue;
|
|
181602
|
+
const name = member.name;
|
|
181603
|
+
if (typeof name !== "string" || !name)
|
|
181604
|
+
continue;
|
|
181605
|
+
accept(severity("STYL014", "hint"), DIAGNOSTIC_MESSAGES.STYL014_PARAMETER_DIRECTION(name, direction, kind, owner), { node: member, code: "STYL014" });
|
|
181606
|
+
}
|
|
181607
|
+
}
|
|
181608
|
+
// REQ-376 — STYL013: a directed parameter is an input a usage binds, not a
|
|
181609
|
+
// value slot. OMG declares them bare on a definition and puts values on
|
|
181610
|
+
// `attribute` members. Only a DEFINITION is flagged: `in x = expr;` on a usage
|
|
181611
|
+
// is the canonical binding form.
|
|
181612
|
+
checkParameterDefaultOnDefinition(node, accept) {
|
|
181613
|
+
const decl = node;
|
|
181614
|
+
if (decl.isDef !== true || typeof decl.name !== "string" || !decl.name)
|
|
181615
|
+
return;
|
|
181616
|
+
for (const member of decl.members ?? []) {
|
|
181617
|
+
const name = member.name;
|
|
181618
|
+
const value = member.value;
|
|
181619
|
+
if (!value || typeof name !== "string" || !name)
|
|
181620
|
+
continue;
|
|
181621
|
+
if (directionOfModifiers(member) === void 0)
|
|
181622
|
+
continue;
|
|
181623
|
+
accept(severity("STYL013", "hint"), DIAGNOSTIC_MESSAGES.STYL013_PARAMETER_DEFAULT_ON_DEFINITION(name, decl.name), { node: member, code: "STYL013" });
|
|
181624
|
+
}
|
|
181625
|
+
}
|
|
181626
|
+
// REQ-415 — issue #164. `assert c;`, `assert not c;`, `require c;` and
|
|
181627
|
+
// `assume c;` name a constraint declared elsewhere (OMG SysML v2 Part 1
|
|
181628
|
+
// §7.20.3, §7.21.2). Three things can go wrong with that name, and all three
|
|
181629
|
+
// were silent: it may resolve to nothing, it may resolve to something that is
|
|
181630
|
+
// not a constraint, and the constraint it resolves to may be decidably false.
|
|
181631
|
+
//
|
|
181632
|
+
// The ROOT link is judged here rather than in `checkWrittenPaths`, which
|
|
181633
|
+
// deliberately leaves a root alone: a root is reported absent only when the
|
|
181634
|
+
// resolver could enumerate the whole surrounding inventory, and that is
|
|
181635
|
+
// exactly the guarantee `unresolvedIndex === 0` carries. It is the same rule
|
|
181636
|
+
// `checkRelationshipTargets` applies to a redefinition target.
|
|
181637
|
+
checkConstraintReference(node, accept) {
|
|
181638
|
+
const reference = constraintReferenceOf(node);
|
|
181639
|
+
if (!reference)
|
|
181640
|
+
return;
|
|
181641
|
+
const resolution = reference.property ? this.featurePaths.resolvePropertyPath(node, reference.property) : this.featurePaths.resolveDeclarationPath(node);
|
|
181642
|
+
if (resolution.segments.length === 0)
|
|
181643
|
+
return;
|
|
181644
|
+
if (resolution.unresolvedIndex === 0) {
|
|
181645
|
+
const invalid = resolution.segments[0];
|
|
181646
|
+
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 } });
|
|
181647
|
+
return;
|
|
181648
|
+
}
|
|
181649
|
+
if (resolution.unresolvedIndex !== void 0 || resolution.indeterminateIndex !== void 0)
|
|
181650
|
+
return;
|
|
181651
|
+
const last2 = resolution.segments[resolution.segments.length - 1];
|
|
181652
|
+
const target = last2.target;
|
|
181653
|
+
if (target && isWrongKindConstraintTarget(target)) {
|
|
181654
|
+
accept(severity("SSM043", "error"), DIAGNOSTIC_MESSAGES.SSM043_CONSTRAINT_REFERENCE_KIND(reference.kind, reference.path, wrongKindLabel(target)), { node, range: last2.cst.range, code: "SSM043" });
|
|
181655
|
+
}
|
|
181656
|
+
}
|
|
181657
|
+
// REQ-415 — SEM014. An assertion the model can DECIDE and that comes out
|
|
181658
|
+
// false is an inconsistency the author wrote against themselves. Only a
|
|
181659
|
+
// closed constant expression is decided: every feature reference is
|
|
181660
|
+
// inconclusive here, so an assertion that depends on a binding, on time, or
|
|
181661
|
+
// on anything this evaluator does not model stays silent rather than passing
|
|
181662
|
+
// quietly or being reported on a guess.
|
|
181663
|
+
checkAssertionConsistency(node, accept) {
|
|
181664
|
+
if (node.$type !== "AssertConstraintStmt")
|
|
181665
|
+
return;
|
|
181666
|
+
const result = evaluateAssertion(node, this.constraintResolver);
|
|
181667
|
+
if (result?.status !== "fail")
|
|
181668
|
+
return;
|
|
181669
|
+
accept(severity("SEM014", "warning"), DIAGNOSTIC_MESSAGES.SEM014_ASSERTION_VIOLATED(result.text), { node, code: "SEM014" });
|
|
181670
|
+
}
|
|
181671
|
+
// REQ-415 — Resolve a reference shorthand through the shared path resolver,
|
|
181672
|
+
// so a target in another file or in the standard library is evaluated exactly
|
|
181673
|
+
// as a same-file one is.
|
|
181674
|
+
constraintResolver = (reference, member) => {
|
|
181675
|
+
const resolution = reference.property ? this.featurePaths.resolvePropertyPath(member, reference.property) : this.featurePaths.resolveDeclarationPath(member);
|
|
181676
|
+
return resolution.segments[resolution.segments.length - 1]?.target;
|
|
181677
|
+
};
|
|
180501
181678
|
// REQ-410 — SEM013. A `ref` feature is NON-composite: it names a feature that
|
|
180502
181679
|
// is owned somewhere else. An unbound one therefore names nothing at all, and
|
|
180503
181680
|
// the General View cannot draw it as anything: a box would claim the owner
|
|
@@ -181996,6 +183173,7 @@ ${baseIndent}}`;
|
|
|
181996
183173
|
const decls = [];
|
|
181997
183174
|
const verifyStmts = [];
|
|
181998
183175
|
const satisfyStmts = [];
|
|
183176
|
+
const includeStmts = [];
|
|
181999
183177
|
const aliasMap = /* @__PURE__ */ new Map();
|
|
182000
183178
|
for (const child of ast_utils_exports.streamAllContents(node)) {
|
|
182001
183179
|
if (isImport(child)) {
|
|
@@ -182019,6 +183197,8 @@ ${baseIndent}}`;
|
|
|
182019
183197
|
if (a2.name && a2.target)
|
|
182020
183198
|
aliasMap.set(a2.name, a2.target);
|
|
182021
183199
|
}
|
|
183200
|
+
if (child.$type === "IncludeStmt")
|
|
183201
|
+
includeStmts.push(child);
|
|
182022
183202
|
}
|
|
182023
183203
|
this.checkAmbiguousReferences(node, imports, index2, accept);
|
|
182024
183204
|
this.checkPrivateImports(imports, index2, accept);
|
|
@@ -182054,7 +183234,7 @@ ${baseIndent}}`;
|
|
|
182054
183234
|
this.checkInverseOfTargets(decl, index2, accept);
|
|
182055
183235
|
this.checkTypeComposition(decl, index2, accept);
|
|
182056
183236
|
}
|
|
182057
|
-
this.checkTypeConformance(decls, satisfyStmts, index2, accept);
|
|
183237
|
+
this.checkTypeConformance(decls, satisfyStmts, includeStmts, index2, accept);
|
|
182058
183238
|
}
|
|
182059
183239
|
// ══════════════════════════════════════════════════════════════════════
|
|
182060
183240
|
// REQ-390 — SSM017-SSM021: whole-model type conformance (issue #104)
|
|
@@ -182064,7 +183244,7 @@ ${baseIndent}}`;
|
|
|
182064
183244
|
// the walk, so a type rooted in the unparsed standard library yields
|
|
182065
183245
|
// `unknown` and no diagnostic. That is what keeps the OMG corpus clean while
|
|
182066
183246
|
// still catching the workspace-local mistakes these codes exist for.
|
|
182067
|
-
checkTypeConformance(decls, satisfyStmts, index2, accept) {
|
|
183247
|
+
checkTypeConformance(decls, satisfyStmts, includeStmts, index2, accept) {
|
|
182068
183248
|
const model = new ConformanceModel((name) => this.resolveUnique(name, index2), (node) => this.implicit?.closureOf(node) ?? { names: /* @__PURE__ */ new Set(), complete: true });
|
|
182069
183249
|
for (const decl of decls) {
|
|
182070
183250
|
this.checkRedefinitionTypeConformance(decl, model, index2, accept);
|
|
@@ -182079,9 +183259,78 @@ ${baseIndent}}`;
|
|
|
182079
183259
|
this.checkRedefinitionDirection(decl, index2, accept);
|
|
182080
183260
|
this.checkInterfaceEndTypes(decl, model, index2, accept);
|
|
182081
183261
|
this.checkIndividualDefinitions(decl, model, accept);
|
|
183262
|
+
this.checkCaseDefinitionCount(decl, index2, accept);
|
|
183263
|
+
this.checkObjectiveSubject(decl, model, index2, accept);
|
|
182082
183264
|
}
|
|
182083
183265
|
for (const stmt of satisfyStmts)
|
|
182084
183266
|
this.checkSatisfierSubjectType(stmt, model, index2, accept);
|
|
183267
|
+
for (const stmt of includeStmts)
|
|
183268
|
+
this.checkIncludeBindings(stmt, model, index2, accept);
|
|
183269
|
+
}
|
|
183270
|
+
// ══════════════════════════════════════════════════════════════════════
|
|
183271
|
+
// REQ-417 — SSM045-SSM048: the bindings a case makes (issue #166)
|
|
183272
|
+
// ══════════════════════════════════════════════════════════════════════
|
|
183273
|
+
// SSM045 — OMG SysML v2 Part 1 §7.22.2: a CaseUsage has exactly one
|
|
183274
|
+
// CaseDefinition. Everything this extension derives about a case usage reads
|
|
183275
|
+
// through that one — its subject, its actor parameters, its objective — so
|
|
183276
|
+
// two leave all three undecided rather than merged. A type this validator
|
|
183277
|
+
// could not read is NOT counted: an unread type is not a wrong one, the same
|
|
183278
|
+
// three-valued rule the rest of this family follows.
|
|
183279
|
+
checkCaseDefinitionCount(decl, index2, accept) {
|
|
183280
|
+
const effective = effectiveCaseDefinition(decl, (name) => this.resolveUnique(name, index2));
|
|
183281
|
+
if (!effective || effective.isDefinition)
|
|
183282
|
+
return;
|
|
183283
|
+
const read = effective.definitions.filter((type) => type.node !== void 0);
|
|
183284
|
+
if (read.length < 2)
|
|
183285
|
+
return;
|
|
183286
|
+
accept(severity("SSM045", "error"), DIAGNOSTIC_MESSAGES.SSM045_CASE_MULTIPLE_DEFINITIONS(decl.name ?? "this case", read[0].name, read[1].name), { node: decl, code: "SSM045" });
|
|
183287
|
+
}
|
|
183288
|
+
// SSM046 — a `verification case` and a `use case` BIND their objective's
|
|
183289
|
+
// subject to their own (`objective obj { subject subj = VerificationCase::subj; }`
|
|
183290
|
+
// in `VerificationCases.sysml`), so a `subject` written on the objective with
|
|
183291
|
+
// an unrelated type states something the case has already decided otherwise.
|
|
183292
|
+
// A generic `case` and an `analysis case` only DEFAULT the objective's subject
|
|
183293
|
+
// to their result, which the model may override, so neither is judged here.
|
|
183294
|
+
checkObjectiveSubject(decl, model, index2, accept) {
|
|
183295
|
+
if (decl.$type !== "ObjectiveDecl")
|
|
183296
|
+
return;
|
|
183297
|
+
const binding = objectiveBindingOf(decl, (name) => this.resolveUnique(name, index2));
|
|
183298
|
+
if (!binding || binding.strength !== "bind" || !binding.own)
|
|
183299
|
+
return;
|
|
183300
|
+
const written = binding.own.typing?.type?.$refText?.trim();
|
|
183301
|
+
if (!written)
|
|
183302
|
+
return;
|
|
183303
|
+
const bound = binding.typeName;
|
|
183304
|
+
if (!bound || bound === DEFAULT_SUBJECT_TYPE)
|
|
183305
|
+
return;
|
|
183306
|
+
if (model.compatible(written, bound) !== "unrelated")
|
|
183307
|
+
return;
|
|
183308
|
+
const caseName = binding.caseNode.name ?? "this case";
|
|
183309
|
+
accept(severity("SSM046", "warning"), DIAGNOSTIC_MESSAGES.SSM046_OBJECTIVE_SUBJECT_TYPE(caseName, written, bound), { node: binding.own, code: "SSM046" });
|
|
183310
|
+
}
|
|
183311
|
+
// SSM047 / SSM048 — OMG SysML v2 Part 1 §7.25 / §8.2.2.25 IncludeUseCaseUsage.
|
|
183312
|
+
// An include is a REFERENCE to a use case performed elsewhere: it keeps that
|
|
183313
|
+
// use case's identity, is investigated on the including case's subject, and
|
|
183314
|
+
// binds that use case's own actor parameters. Both checks stay silent unless
|
|
183315
|
+
// the included use case was actually read.
|
|
183316
|
+
checkIncludeBindings(stmt, model, index2, accept) {
|
|
183317
|
+
const binding = includeBindingOf(stmt, (name) => this.resolveUnique(name, index2));
|
|
183318
|
+
if (!binding?.target)
|
|
183319
|
+
return;
|
|
183320
|
+
const included = binding.path ?? "the included use case";
|
|
183321
|
+
const includedSubject = binding.includedSubject;
|
|
183322
|
+
const containingSubject = binding.containingSubject;
|
|
183323
|
+
if (isDecidedSubject(includedSubject) && isDecidedSubject(containingSubject) && model.compatible(includedSubject.typeName, containingSubject.typeName) === "unrelated") {
|
|
183324
|
+
accept(severity("SSM047", "warning"), DIAGNOSTIC_MESSAGES.SSM047_INCLUDE_SUBJECT_TYPE(included, includedSubject.typeName, containingSubject.typeName), { node: stmt, code: "SSM047" });
|
|
183325
|
+
}
|
|
183326
|
+
if (binding.parameters.length === 0)
|
|
183327
|
+
return;
|
|
183328
|
+
const known2 = binding.parameters.map((parameter) => `'${parameter.name ?? "(anonymous)"}'`).join(", ");
|
|
183329
|
+
for (const actor of binding.actors) {
|
|
183330
|
+
if (!actor.name || actor.parameter)
|
|
183331
|
+
continue;
|
|
183332
|
+
accept(severity("SSM048", "warning"), DIAGNOSTIC_MESSAGES.SSM048_INCLUDE_ACTOR_BINDING(actor.name, included, known2), { node: actor.declaration, code: "SSM048" });
|
|
183333
|
+
}
|
|
182085
183334
|
}
|
|
182086
183335
|
// REQ-416 — SSM044: `satisfy MassReq by engine;` claims that `engine` is one
|
|
182087
183336
|
// of the things `MassReq` constrains, so `engine`'s type has to conform to
|
|
@@ -183346,7 +184595,16 @@ ${baseIndent}}`;
|
|
|
183346
184595
|
// issue #215 — the rest of the reference-form declarations. They share
|
|
183347
184596
|
// `ReferenceFormPath` with `perform`/`exhibit`, so they can spell the
|
|
183348
184597
|
// same defect and are judged by the same rule.
|
|
183349
|
-
|
|
184598
|
+
// REQ-415 — issue #164: the constraint reference shorthands. `assert`
|
|
184599
|
+
// shares its `ReferenceFormPath` with the other reference forms, so it
|
|
184600
|
+
// also carries the RES019 separator rule above.
|
|
184601
|
+
AssertConstraintStmt: [
|
|
184602
|
+
this.checkChainSeparators.bind(this),
|
|
184603
|
+
this.checkConstraintReference.bind(this),
|
|
184604
|
+
this.checkAssertionConsistency.bind(this)
|
|
184605
|
+
],
|
|
184606
|
+
RequireConstraintStmt: this.checkConstraintReference.bind(this),
|
|
184607
|
+
AssumeConstraintStmt: this.checkConstraintReference.bind(this),
|
|
183350
184608
|
EntryAction: this.checkChainSeparators.bind(this),
|
|
183351
184609
|
DoAction: this.checkChainSeparators.bind(this),
|
|
183352
184610
|
ExitAction: this.checkChainSeparators.bind(this),
|
|
@@ -183354,7 +184612,17 @@ ${baseIndent}}`;
|
|
|
183354
184612
|
ConnectorEnd: this.checkConnectorEndSeparators.bind(this),
|
|
183355
184613
|
RequirementDecl: this.checkRequirementDecl.bind(this),
|
|
183356
184614
|
AttributeDecl: this.checkAttributeDecl.bind(this),
|
|
183357
|
-
|
|
184615
|
+
// REQ-376 — STYL013 applies to both behavioral definitions that take
|
|
184616
|
+
// parameters, so the constraint check runs beside it here.
|
|
184617
|
+
ConstraintDecl: [
|
|
184618
|
+
this.checkConstraintDecl.bind(this),
|
|
184619
|
+
this.checkParameterDefaultOnDefinition.bind(this),
|
|
184620
|
+
this.checkParameterDirection.bind(this)
|
|
184621
|
+
],
|
|
184622
|
+
CalcDecl: [
|
|
184623
|
+
this.checkParameterDefaultOnDefinition.bind(this),
|
|
184624
|
+
this.checkParameterDirection.bind(this)
|
|
184625
|
+
],
|
|
183358
184626
|
VerificationCaseDecl: this.checkVerificationCaseDecl.bind(this),
|
|
183359
184627
|
AnalysisCaseDecl: this.checkAnalysisCaseDecl.bind(this),
|
|
183360
184628
|
ViewDecl: this.checkViewDecl.bind(this),
|
|
@@ -184077,6 +185345,9 @@ var STYLE_ADVISORY_CODES = /* @__PURE__ */ new Set([
|
|
|
184077
185345
|
"STYL009",
|
|
184078
185346
|
"STYL010",
|
|
184079
185347
|
"STYL011",
|
|
185348
|
+
"STYL012",
|
|
185349
|
+
"STYL013",
|
|
185350
|
+
"STYL014",
|
|
184080
185351
|
"LEX009",
|
|
184081
185352
|
// trailing whitespace
|
|
184082
185353
|
"SYN024",
|
|
@@ -184399,6 +185670,8 @@ var SysmlScopeComputation = class extends DefaultScopeComputation {
|
|
|
184399
185670
|
break;
|
|
184400
185671
|
if (node.$type === "ShortName" || node.$type === "ImportSeg")
|
|
184401
185672
|
continue;
|
|
185673
|
+
if (isReferenceFormDeclaration(node))
|
|
185674
|
+
continue;
|
|
184402
185675
|
const aliases = this.nameAliasesOf(node);
|
|
184403
185676
|
if (aliases.length === 0)
|
|
184404
185677
|
continue;
|
|
@@ -189965,7 +191238,7 @@ function nodeBlockForCanvas(node) {
|
|
|
189965
191238
|
compartments: compartments2?.length ? compartments2 : void 0
|
|
189966
191239
|
};
|
|
189967
191240
|
}
|
|
189968
|
-
if (!/\
|
|
191241
|
+
if (!/\b(?:constraint|calc)(?:\s+def)?$/u.test(node.keyword.trim().toLowerCase())) return node;
|
|
189969
191242
|
const compartments = node.compartments?.filter((compartment) => compartment.title !== "expression");
|
|
189970
191243
|
return {
|
|
189971
191244
|
...node,
|
|
@@ -190059,7 +191332,9 @@ function nodeSize(node, direction) {
|
|
|
190059
191332
|
const portRunHeight = connectionUsage ? portRows ? portRows * 18 + 6 : 0 : portRows ? compactContainer ? portRows * 24 + 8 : 40 + portRows * 24 + 8 : 0;
|
|
190060
191333
|
const bodyH = Math.max(
|
|
190061
191334
|
connectionUsage ? 42 : BOX_H,
|
|
190062
|
-
|
|
191335
|
+
// REQ-209/375 - The value field sits at the bottom of the card, under
|
|
191336
|
+
// whatever compartments it carries, so both have to fit.
|
|
191337
|
+
node.value !== void 0 ? Math.max(88, NODE_COMPARTMENT_TOP + compartmentHeight(node) + 36) : 0,
|
|
190063
191338
|
featureH === 0 ? NODE_COMPARTMENT_TOP + compartmentHeight(node) : 0,
|
|
190064
191339
|
portRunHeight,
|
|
190065
191340
|
portedSideLength(ph, "left"),
|
|
@@ -190730,7 +192005,7 @@ function collapseIvModel(model, hiddenInternals) {
|
|
|
190730
192005
|
const frames = model.frames ?? [];
|
|
190731
192006
|
if (!frames.length) return model;
|
|
190732
192007
|
const frameById = new Map(frames.map((f) => [f.id, f]));
|
|
190733
|
-
const requested = new Set(frames.filter((frame2) => framePresentationEnabled(hiddenInternals, frame2, true) && isCollapsibleFrame("iv", frame2)).map((frame2) => frame2.id));
|
|
192008
|
+
const requested = new Set(frames.filter((frame2) => (frame2.meta?.internalsExpandable === false || framePresentationEnabled(hiddenInternals, frame2, true)) && isCollapsibleFrame("iv", frame2)).map((frame2) => frame2.id));
|
|
190734
192009
|
if (requested.size === 0) return model;
|
|
190735
192010
|
const hasRequestedAncestor = (id2) => {
|
|
190736
192011
|
let p = frameById.get(id2)?.parent;
|
|
@@ -190793,12 +192068,11 @@ function collapseIvModel(model, hiddenInternals) {
|
|
|
190793
192068
|
const toRoot = containerRootOf(e.to);
|
|
190794
192069
|
if (fromRoot !== void 0 && fromRoot === toRoot) return false;
|
|
190795
192070
|
return !(hidden.has(e.from) && fromRoot === void 0) && !(hidden.has(e.to) && toRoot === void 0);
|
|
190796
|
-
}).map((e) => {
|
|
192071
|
+
}).filter((e) => e.from === e.to || (bodyDock.get(e.from) ?? e.from) !== (bodyDock.get(e.to) ?? e.to)).map((e) => {
|
|
190797
192072
|
const from = bodyDock.get(e.from) ?? e.from;
|
|
190798
192073
|
const to = bodyDock.get(e.to) ?? e.to;
|
|
190799
192074
|
return from === e.from && to === e.to ? e : { ...e, from, to };
|
|
190800
192075
|
}).filter((e) => {
|
|
190801
|
-
if (e.from === e.to) return false;
|
|
190802
192076
|
const key2 = `${e.from}\0${e.to}\0${e.kind}\0${e.label ?? ""}`;
|
|
190803
192077
|
if (seenEdge.has(`${key2}:${e.id}`)) return false;
|
|
190804
192078
|
seenEdge.add(`${key2}:${e.id}`);
|
|
@@ -190876,17 +192150,30 @@ function isFeatureCompartmentNode(kind, node) {
|
|
|
190876
192150
|
if (kind === "stv") return node.shape === "state";
|
|
190877
192151
|
return false;
|
|
190878
192152
|
}
|
|
192153
|
+
function graphicalChildOwners(model) {
|
|
192154
|
+
const owners = /* @__PURE__ */ new Set();
|
|
192155
|
+
for (const node of model.nodes) {
|
|
192156
|
+
const owner = node.frame ?? node.parent;
|
|
192157
|
+
if (owner && owner !== node.id) owners.add(owner);
|
|
192158
|
+
}
|
|
192159
|
+
for (const frame2 of model.frames ?? []) {
|
|
192160
|
+
if (frame2.parent && frame2.parent !== frame2.id) owners.add(frame2.parent);
|
|
192161
|
+
}
|
|
192162
|
+
return owners;
|
|
192163
|
+
}
|
|
190879
192164
|
function applyFeatureCompartmentVisibility(model, visibleFeatureCompartments, hiddenInternals = {}) {
|
|
190880
192165
|
if (!CONTAINER_PRESENTATION_KINDS.has(model.kind)) return model;
|
|
190881
192166
|
const legacy = model.kind === "iv";
|
|
192167
|
+
const owners = graphicalChildOwners(model);
|
|
190882
192168
|
let changed = false;
|
|
190883
192169
|
const project = (host, leaf) => {
|
|
192170
|
+
const internalsExpandable = owners.has(host.id);
|
|
190884
192171
|
const alwaysVisible = host.meta?.alwaysVisibleCompartments === true;
|
|
190885
192172
|
const defaultVisible = leaf || model.kind === "afv" && !leaf;
|
|
190886
192173
|
const visible = alwaysVisible || framePresentationEnabled(visibleFeatureCompartments, host, legacy, defaultVisible);
|
|
190887
192174
|
const compartments = visible ? host.compartments : void 0;
|
|
190888
192175
|
const internalsHidden = leaf ? framePresentationEnabled(hiddenInternals, host, legacy) : host.meta?.internalsHidden === true;
|
|
190889
|
-
if (compartments === host.compartments && host.meta?.containerControls === true && host.meta?.featureCompartmentsVisible === visible && (!leaf || host.meta?.internalsHidden === internalsHidden)) return host;
|
|
192176
|
+
if (compartments === host.compartments && host.meta?.containerControls === true && host.meta?.internalsExpandable === internalsExpandable && host.meta?.featureCompartmentsVisible === visible && (!leaf || host.meta?.internalsHidden === internalsHidden)) return host;
|
|
190890
192177
|
changed = true;
|
|
190891
192178
|
return {
|
|
190892
192179
|
...host,
|
|
@@ -190894,6 +192181,7 @@ function applyFeatureCompartmentVisibility(model, visibleFeatureCompartments, hi
|
|
|
190894
192181
|
meta: {
|
|
190895
192182
|
...host.meta,
|
|
190896
192183
|
containerControls: true,
|
|
192184
|
+
internalsExpandable,
|
|
190897
192185
|
featureCompartmentsVisible: visible,
|
|
190898
192186
|
...leaf ? { internalsHidden } : {}
|
|
190899
192187
|
}
|
|
@@ -190909,10 +192197,10 @@ function collapseActionFrames(model, hiddenInternals, isHost = isCollapsibleActi
|
|
|
190909
192197
|
if (!frames.length) return model;
|
|
190910
192198
|
const frameById = new Map(frames.map((f) => [f.id, f]));
|
|
190911
192199
|
const requested = new Set(
|
|
190912
|
-
frames.filter((f) => framePresentationEnabled(hiddenInternals, f) && isHost(f)).map((f) => f.id)
|
|
192200
|
+
frames.filter((f) => (f.meta?.internalsExpandable === false || framePresentationEnabled(hiddenInternals, f)) && isHost(f)).map((f) => f.id)
|
|
190913
192201
|
);
|
|
190914
192202
|
if (requested.size === 0) return model;
|
|
190915
|
-
const
|
|
192203
|
+
const rootOf3 = (id2) => {
|
|
190916
192204
|
let root4;
|
|
190917
192205
|
const seen = /* @__PURE__ */ new Set();
|
|
190918
192206
|
for (let cur = id2; cur !== void 0 && !seen.has(cur); cur = frameById.get(cur)?.parent) {
|
|
@@ -190921,13 +192209,13 @@ function collapseActionFrames(model, hiddenInternals, isHost = isCollapsibleActi
|
|
|
190921
192209
|
}
|
|
190922
192210
|
return root4;
|
|
190923
192211
|
};
|
|
190924
|
-
const roots = new Set([...requested].filter((id2) =>
|
|
192212
|
+
const roots = new Set([...requested].filter((id2) => rootOf3(frameById.get(id2)?.parent) === void 0));
|
|
190925
192213
|
const dockOf = /* @__PURE__ */ new Map();
|
|
190926
192214
|
const proxyHost = /* @__PURE__ */ new Map();
|
|
190927
192215
|
const ownerOfHiddenPort = /* @__PURE__ */ new Map();
|
|
190928
192216
|
const hiddenFrameIds = /* @__PURE__ */ new Set();
|
|
190929
192217
|
for (const f of frames) {
|
|
190930
|
-
const root4 = roots.has(f.id) ?
|
|
192218
|
+
const root4 = roots.has(f.id) ? rootOf3(f.parent) : rootOf3(f.id);
|
|
190931
192219
|
if (root4 === void 0) continue;
|
|
190932
192220
|
hiddenFrameIds.add(f.id);
|
|
190933
192221
|
dockOf.set(f.id, root4);
|
|
@@ -190938,7 +192226,7 @@ function collapseActionFrames(model, hiddenInternals, isHost = isCollapsibleActi
|
|
|
190938
192226
|
}
|
|
190939
192227
|
const hiddenNodeIds = /* @__PURE__ */ new Set();
|
|
190940
192228
|
for (const n2 of model.nodes) {
|
|
190941
|
-
const root4 =
|
|
192229
|
+
const root4 = rootOf3(n2.frame);
|
|
190942
192230
|
if (root4 === void 0) continue;
|
|
190943
192231
|
hiddenNodeIds.add(n2.id);
|
|
190944
192232
|
dockOf.set(n2.id, root4);
|
|
@@ -190967,12 +192255,11 @@ function collapseActionFrames(model, hiddenInternals, isHost = isCollapsibleActi
|
|
|
190967
192255
|
const edges = model.edges.filter((e) => {
|
|
190968
192256
|
const fromRoot = containerRootOf(e.from);
|
|
190969
192257
|
return fromRoot === void 0 || fromRoot !== containerRootOf(e.to);
|
|
190970
|
-
}).map((e) => {
|
|
192258
|
+
}).filter((e) => e.from === e.to || (dockOf.get(e.from) ?? e.from) !== (dockOf.get(e.to) ?? e.to)).map((e) => {
|
|
190971
192259
|
const from = dockOf.get(e.from) ?? e.from;
|
|
190972
192260
|
const to = dockOf.get(e.to) ?? e.to;
|
|
190973
192261
|
return from === e.from && to === e.to ? e : { ...e, from, to };
|
|
190974
192262
|
}).filter((e) => {
|
|
190975
|
-
if (e.from === e.to) return false;
|
|
190976
192263
|
const key2 = `${e.from}\0${e.to}\0${e.kind}\0${e.label ?? ""}`;
|
|
190977
192264
|
if (seenEdge.has(`${key2}:${e.id}`)) return false;
|
|
190978
192265
|
seenEdge.add(`${key2}:${e.id}`);
|
|
@@ -191114,6 +192401,8 @@ function modelToFlow(model, opts) {
|
|
|
191114
192401
|
nodes.push({
|
|
191115
192402
|
id: f.id,
|
|
191116
192403
|
type: "frame",
|
|
192404
|
+
// REQ-361 - Portless GV bounds include the complete painted frame.
|
|
192405
|
+
className: model.kind === "gv" && !f.ports?.length ? "rf-bounded-paint" : void 0,
|
|
191117
192406
|
position: { x: 0, y: 0 },
|
|
191118
192407
|
data: {
|
|
191119
192408
|
kind: model.kind,
|
|
@@ -191229,6 +192518,8 @@ function modelToFlow(model, opts) {
|
|
|
191229
192518
|
nodes.push({
|
|
191230
192519
|
id: n2.id,
|
|
191231
192520
|
type: isGeo ? "geo" : "sysml",
|
|
192521
|
+
// REQ-361 - Outside port labels must never enter paint containment.
|
|
192522
|
+
className: model.kind === "gv" && !n2.ports?.length ? "rf-bounded-paint" : void 0,
|
|
191232
192523
|
position: { x: 0, y: 0 },
|
|
191233
192524
|
data: {
|
|
191234
192525
|
kind: model.kind,
|
|
@@ -205385,6 +206676,10 @@ function markersFor(kind) {
|
|
|
205385
206676
|
// REQ-199
|
|
205386
206677
|
case "derive":
|
|
205387
206678
|
// REQ-188
|
|
206679
|
+
case "assert":
|
|
206680
|
+
// REQ-131/REQ-415 — the constraint claims
|
|
206681
|
+
case "assume":
|
|
206682
|
+
case "require":
|
|
205388
206683
|
case "causation":
|
|
205389
206684
|
// REQ-189
|
|
205390
206685
|
case "import":
|
|
@@ -205761,7 +207056,7 @@ var KIN_MARKER_DEFS_SVG = [
|
|
|
205761
207056
|
|
|
205762
207057
|
// ../extension/src/webview/diagram/element-colors.ts
|
|
205763
207058
|
var ELEMENT_CLOSED_OPACITY = 1;
|
|
205764
|
-
var ELEMENT_OPEN_OPACITY = 0.
|
|
207059
|
+
var ELEMENT_OPEN_OPACITY = 0.3;
|
|
205765
207060
|
var DIAGRAM_ELEMENT_COLORS = {
|
|
205766
207061
|
default: {
|
|
205767
207062
|
outline: { light: "#3a3a3a", dark: "#a1a1a1" },
|
|
@@ -205894,7 +207189,22 @@ var DIAGRAM_LINE_COLORS = {
|
|
|
205894
207189
|
},
|
|
205895
207190
|
dependency: {
|
|
205896
207191
|
color: { light: "#6b46c1", dark: "#b08cf0" },
|
|
205897
|
-
kinds: [
|
|
207192
|
+
kinds: [
|
|
207193
|
+
"satisfy",
|
|
207194
|
+
"verify",
|
|
207195
|
+
"include",
|
|
207196
|
+
"dependency",
|
|
207197
|
+
"allocate",
|
|
207198
|
+
"frame",
|
|
207199
|
+
"derive",
|
|
207200
|
+
"causation",
|
|
207201
|
+
"import",
|
|
207202
|
+
"expose",
|
|
207203
|
+
// REQ-131/REQ-415 — the constraint claims read as the same family.
|
|
207204
|
+
"assert",
|
|
207205
|
+
"assume",
|
|
207206
|
+
"require"
|
|
207207
|
+
],
|
|
205898
207208
|
colorLabels: true
|
|
205899
207209
|
},
|
|
205900
207210
|
binding: {
|
|
@@ -206321,6 +207631,8 @@ body {
|
|
|
206321
207631
|
.dlink.satisfy, .dlink.verify, .dlink.include, .dlink.dependency { stroke-dasharray: 4 3; }
|
|
206322
207632
|
/* REQ-186/188/189/199/206/210 \u2014 the dashed labelled families */
|
|
206323
207633
|
.dlink.allocate, .dlink.frame, .dlink.derive, .dlink.causation, .dlink.import, .dlink.expose { stroke-dasharray: 4 3; }
|
|
207634
|
+
/* REQ-131/REQ-415 \u2014 the three constraint claims */
|
|
207635
|
+
.dlink.assert, .dlink.assume, .dlink.require { stroke-dasharray: 4 3; }
|
|
206324
207636
|
.dlink.annotation { stroke-dasharray: 2 3; }
|
|
206325
207637
|
.dlink.elaboration { stroke-dasharray: 2 3; pointer-events: none; }
|
|
206326
207638
|
.dlink.reply { stroke-dasharray: 4 3; } /* REQ-202 \u2014 sequence reply arrows */
|
|
@@ -207035,6 +208347,15 @@ svg.react-flow__connectionline { z-index: 1; }
|
|
|
207035
208347
|
.rf-ctl-zoom { width: auto; min-width: 42px; padding: 0 4px; text-align: center; font: 600 11px var(--font-mono); color: var(--fg-2); }
|
|
207036
208348
|
.rf-ctl-sep { width: 1px; height: 16px; background: var(--line); margin: 0 3px; }
|
|
207037
208349
|
.react-flow__node { font-family: var(--font-mono); font-size: 11px; color: var(--fg-0); }
|
|
208350
|
+
/* REQ-361 - Bound hit testing on portless GV cards. The margin retains border
|
|
208351
|
+
* strokes, package tabs and side handles. Port glyphs and their outside labels
|
|
208352
|
+
* remain unbounded. Editing and hover controls also retain their full overflow. */
|
|
208353
|
+
/* Keep every card mounted. Only ordinary Group cards defer off-screen contents.
|
|
208354
|
+
* Their explicit dimensions preserve geometry. Large frames and Tree retain
|
|
208355
|
+
* their regular rendering path; deferring their contents adds layout work. */
|
|
208356
|
+
.react-flow__node.rf-bounded-paint { contain: paint; overflow-clip-margin: 16px; }
|
|
208357
|
+
.rf-gv-group .react-flow__node-sysml.rf-bounded-paint { content-visibility: auto; }
|
|
208358
|
+
.react-flow__node.rf-bounded-paint:is(:hover, :focus-within, .selected) { contain: none; content-visibility: visible; }
|
|
207038
208359
|
.react-flow__node-sysml, .react-flow__node-frame { background: transparent; border: none; padding: 0; border-radius: 0; box-shadow: none; }
|
|
207039
208360
|
.rf-node, .rf-frame { position: relative; user-select: none; }
|
|
207040
208361
|
/* Container frames: the interior is click-through so connectors drawn underneath
|
|
@@ -207812,7 +209133,15 @@ var TOOLBOX = {
|
|
|
207812
209133
|
rel("verify", "verify", "\u2713", "click the verification case, then the requirement"),
|
|
207813
209134
|
rel("frame", "frame", "\u274F", "click the requirement/view, then the framed concern"),
|
|
207814
209135
|
rel("exhibit", "exhibit", "\u25C9", "click the part, then the exhibited state"),
|
|
207815
|
-
rel("perform", "perform", "\u25B7", "click the part, then the performed action")
|
|
209136
|
+
rel("perform", "perform", "\u25B7", "click the part, then the performed action"),
|
|
209137
|
+
// REQ-131/REQ-415 (user direction 2026-09-08 — "how do we add assert
|
|
209138
|
+
// constraint from the diagram") — the three constraint CLAIMS. The
|
|
209139
|
+
// diagram drew them in its compartments but could not create one, so
|
|
209140
|
+
// `assert constraint …` could only be typed. Each writes into the
|
|
209141
|
+
// claiming element, exactly as satisfy/verify/frame do.
|
|
209142
|
+
rel("assert", "assert", "\u22A8", "click the element that asserts, then the constraint"),
|
|
209143
|
+
rel("assume", "assume", "\u2283", "click the requirement/concern, then the assumed constraint"),
|
|
209144
|
+
rel("require", "require", "\u22A2", "click the requirement/concern, then the required constraint")
|
|
207816
209145
|
]
|
|
207817
209146
|
},
|
|
207818
209147
|
// The Interconnection View depicts parts, ports, and the compartment rows of
|
|
@@ -207843,7 +209172,12 @@ var TOOLBOX = {
|
|
|
207843
209172
|
rel("flow", "flow", "\u2192", "click the source port/feature, then the target"),
|
|
207844
209173
|
// issue #115 — an item flow that also sequences its ends.
|
|
207845
209174
|
rel("successionFlow", "succession flow", "\u21C9", "click the source port/feature, then the target"),
|
|
207846
|
-
rel("allocate", "allocate", "\u290F", "click the source part/feature, then the target")
|
|
209175
|
+
rel("allocate", "allocate", "\u290F", "click the source part/feature, then the target"),
|
|
209176
|
+
// REQ-131 — the view draws a part's constraints, and OMG's own
|
|
209177
|
+
// parametric picture is a part asserting one and binding its
|
|
209178
|
+
// parameters (ConstraintTest.sysml). `bind` was already here; the
|
|
209179
|
+
// claim that gives it something to bind was not.
|
|
209180
|
+
rel("assert", "assert", "\u22A8", "click the part, then the constraint it asserts")
|
|
207847
209181
|
]
|
|
207848
209182
|
},
|
|
207849
209183
|
// Action Flow depicts actions (a new `action def` becomes its own tile in a
|
|
@@ -207857,6 +209191,8 @@ var TOOLBOX = {
|
|
|
207857
209191
|
// they are the action's parameter pins.
|
|
207858
209192
|
afv: {
|
|
207859
209193
|
elements: [
|
|
209194
|
+
el("calc def", "calc def", "\u2211"),
|
|
209195
|
+
el("calc", "calc", "\u2211"),
|
|
207860
209196
|
el("action def", "action def", "\u25B7"),
|
|
207861
209197
|
el("action", "action", "\u25B7"),
|
|
207862
209198
|
// issue #217 — a behaviour-root canvas writes into the action
|
|
@@ -208025,7 +209361,10 @@ var CHILD_KINDS = {
|
|
|
208025
209361
|
"event occurrence": [],
|
|
208026
209362
|
requirement: ["requirement", "constraint", "attribute", "part", "actor"],
|
|
208027
209363
|
concern: ["requirement", "constraint", "attribute", "actor"],
|
|
208028
|
-
constraint
|
|
209364
|
+
// REQ-376 — a constraint and a calculation take INPUTS, and there was no way
|
|
209365
|
+
// to add one from the diagram. Only `in`: an `out` or `inout` parameter on
|
|
209366
|
+
// either is STYL014, so offering one would contradict the check.
|
|
209367
|
+
constraint: ["in parameter", "attribute", "constraint"],
|
|
208029
209368
|
"use case": CASE_CHILDREN,
|
|
208030
209369
|
"analysis case": CASE_CHILDREN,
|
|
208031
209370
|
"verification case": CASE_CHILDREN,
|
|
@@ -208037,7 +209376,7 @@ var CHILD_KINDS = {
|
|
|
208037
209376
|
// issue (GRV on enum def): an enum def owns enumeration VALUES — nested enum
|
|
208038
209377
|
// usages — never requirements/parts; the old fallback offered the view list.
|
|
208039
209378
|
enum: ["enum"],
|
|
208040
|
-
calc: ["attribute", "calc"],
|
|
209379
|
+
calc: ["in parameter", "attribute", "calc"],
|
|
208041
209380
|
connection: ["attribute", "item", "part"],
|
|
208042
209381
|
connector: ["attribute", "item", "part"],
|
|
208043
209382
|
interface: ["port", "attribute", "item"],
|
|
@@ -208052,6 +209391,10 @@ var CHILD_KINDS = {
|
|
|
208052
209391
|
control: [],
|
|
208053
209392
|
terminate: [],
|
|
208054
209393
|
pin: [],
|
|
209394
|
+
// REQ-376 — the banner of a constraint/calc parameter card.
|
|
209395
|
+
"in parameter": [],
|
|
209396
|
+
"out parameter": [],
|
|
209397
|
+
"inout parameter": [],
|
|
208055
209398
|
// REQ-196 — a «performer» swimlane (OMG SysML v2 Part 1 §8.2.3.17, p.90). Its
|
|
208056
209399
|
// members are the actions that part performs; the edit writes the action into
|
|
208057
209400
|
// the OWNING action's body and a `perform` for it into the part.
|
|
@@ -208063,6 +209406,7 @@ var CHILD_KINDS = {
|
|
|
208063
209406
|
function normalizedElementKeyword(keyword) {
|
|
208064
209407
|
const normalized = keyword.trim().toLowerCase();
|
|
208065
209408
|
let base = normalized.replace(/\s*def$/u, "").replace(/^(?:(?:abstract|variation|variant|ref|derived|readonly|individual|timeslice|snapshot|parallel)\s+)+/u, "").trim();
|
|
209409
|
+
if (/^(assert(?: not)?|assume|require) constraint$/u.test(base)) base = "constraint";
|
|
208066
209410
|
const isDecision = base === "decide" || base === "decision";
|
|
208067
209411
|
if ([
|
|
208068
209412
|
"send action",
|
|
@@ -208164,15 +209508,37 @@ function relationToolsForNode(keyword, viewKind, shape) {
|
|
|
208164
209508
|
case "exhibit":
|
|
208165
209509
|
case "perform":
|
|
208166
209510
|
return base === "part";
|
|
209511
|
+
// REQ-131 — the OMG corpus asserts inside a part or a package
|
|
209512
|
+
// (ConstraintTest.sysml, MassConstraintExample.sysml); a case and
|
|
209513
|
+
// a requirement own constraints of their own.
|
|
209514
|
+
case "assert":
|
|
209515
|
+
return [
|
|
209516
|
+
"part",
|
|
209517
|
+
"item",
|
|
209518
|
+
"package",
|
|
209519
|
+
"requirement",
|
|
209520
|
+
"concern",
|
|
209521
|
+
"use case",
|
|
209522
|
+
"analysis case",
|
|
209523
|
+
"verification case",
|
|
209524
|
+
"case"
|
|
209525
|
+
].includes(base);
|
|
209526
|
+
// REQ-131 — OMG SysML 8.2.2.21.1: a RequirementConstraintMembership
|
|
209527
|
+
// belongs to a requirement or a concern.
|
|
209528
|
+
case "assume":
|
|
209529
|
+
case "require":
|
|
209530
|
+
return ["requirement", "concern"].includes(base);
|
|
208167
209531
|
default:
|
|
208168
209532
|
return true;
|
|
208169
209533
|
}
|
|
208170
209534
|
}
|
|
208171
209535
|
if (viewKind === "iv") {
|
|
208172
209536
|
if (!["part", "port", "attribute", "item", "connection"].includes(base)) return false;
|
|
209537
|
+
if (tool.kind === "assert") return base === "part" || base === "item";
|
|
208173
209538
|
return tool.kind === "interface" ? base === "port" : true;
|
|
208174
209539
|
}
|
|
208175
209540
|
if (viewKind === "afv") {
|
|
209541
|
+
if (base === "calc") return tool.kind === "succession" || tool.kind === "begin";
|
|
208176
209542
|
if (base === "action") return tool.kind === "succession" || tool.kind === "begin" || tool.kind === "guard" || tool.kind === "terminate" || tool.kind === TERMINAL_RELATION;
|
|
208177
209543
|
if (base === "control") return tool.kind === "succession" || tool.kind === "begin" || tool.kind === "guard" || isDecision && tool.kind === "else" || tool.kind === "terminate" || tool.kind === TERMINAL_RELATION;
|
|
208178
209544
|
if (base === "port") return false;
|
|
@@ -208604,7 +209970,7 @@ function GvDisclosure({ element, svgWidth }) {
|
|
|
208604
209970
|
}
|
|
208605
209971
|
);
|
|
208606
209972
|
}
|
|
208607
|
-
function AttributeValueEditor({ id: id2, name, value, top }) {
|
|
209973
|
+
function AttributeValueEditor({ id: id2, name, value, top, label = "Value", placeholder = "Add value" }) {
|
|
208608
209974
|
const { onSetElementValue } = useDiagram();
|
|
208609
209975
|
const [draft, setDraft] = (0, import_react9.useState)(value);
|
|
208610
209976
|
if (!onSetElementValue) return null;
|
|
@@ -208614,8 +209980,8 @@ function AttributeValueEditor({ id: id2, name, value, top }) {
|
|
|
208614
209980
|
type: "text",
|
|
208615
209981
|
className: "dattribute-value nodrag nopan nowheel",
|
|
208616
209982
|
style: { top },
|
|
208617
|
-
"aria-label": "
|
|
208618
|
-
placeholder
|
|
209983
|
+
"aria-label": label + " of " + name,
|
|
209984
|
+
placeholder,
|
|
208619
209985
|
value: draft,
|
|
208620
209986
|
onPointerDown: (event) => event.stopPropagation(),
|
|
208621
209987
|
onClick: (event) => event.stopPropagation(),
|
|
@@ -209026,12 +210392,17 @@ function titleNameLine(name, type, mult, alias, availPx) {
|
|
|
209026
210392
|
const shown = fitText(full, availPx, 11);
|
|
209027
210393
|
return { full, shown, clipped: shown !== full };
|
|
209028
210394
|
}
|
|
209029
|
-
function
|
|
209030
|
-
|
|
210395
|
+
function valueFieldRole(keyword) {
|
|
210396
|
+
if (/\bconstraint(?:\s+def)?$/u.test(keyword)) return { label: "Constraint", placeholder: "Add constraint" };
|
|
210397
|
+
if (keyword.startsWith("calc")) return { label: "Expression", placeholder: "Add expression" };
|
|
210398
|
+
return { label: "Value", placeholder: "Add value" };
|
|
210399
|
+
}
|
|
210400
|
+
function AttributeValueShape({ value, w, top, placeholder = "Add value" }) {
|
|
210401
|
+
const shown = fitText(value || placeholder, Math.max(16, w - 32), 11);
|
|
209031
210402
|
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("g", { className: "dattribute-value-shape", children: [
|
|
209032
210403
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("rect", { x: 8, y: top, width: Math.max(1, w - 16), height: 28, rx: 3 }),
|
|
209033
210404
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("text", { x: 15, y: top + 18, className: "dnode-label", children: [
|
|
209034
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("title", { children: value ||
|
|
210405
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("title", { children: value || placeholder }),
|
|
209035
210406
|
shown
|
|
209036
210407
|
] })
|
|
209037
210408
|
] });
|
|
@@ -209078,7 +210449,15 @@ function BoxBody({ node, w, h, showMult }) {
|
|
|
209078
210449
|
] })
|
|
209079
210450
|
] }),
|
|
209080
210451
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Compartments, { node, w, ruleClass }),
|
|
209081
|
-
node.value !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
210452
|
+
node.value !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
210453
|
+
AttributeValueShape,
|
|
210454
|
+
{
|
|
210455
|
+
value: node.value,
|
|
210456
|
+
w,
|
|
210457
|
+
top: h - 36,
|
|
210458
|
+
placeholder: valueFieldRole(node.keyword).placeholder
|
|
210459
|
+
}
|
|
210460
|
+
) : null
|
|
209082
210461
|
] });
|
|
209083
210462
|
}
|
|
209084
210463
|
function RoundedBody({ node, w, h, cls, showMult }) {
|
|
@@ -209262,7 +210641,7 @@ function SendAcceptBody({ node, w, h, accept }) {
|
|
|
209262
210641
|
}
|
|
209263
210642
|
function PackageBody({ node, w, h }) {
|
|
209264
210643
|
if (node.meta?.gvMode !== void 0) {
|
|
209265
|
-
const title = fitText(node.name, Math.max(24, w - 42), 11);
|
|
210644
|
+
const title = fitText(node.name, Math.max(24, w - (node.meta?.gvCanExpand === true ? 42 : 20)), 11);
|
|
209266
210645
|
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("g", { children: [
|
|
209267
210646
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { className: "dnode-rect package", d: packageFramePath(w, h) }),
|
|
209268
210647
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("text", { className: "dnode-kind", x: 10, y: 12, children: "\xABpackage\xBB" }),
|
|
@@ -210032,7 +211411,7 @@ function SysmlNode({ id: id2, data, draggable, selected: selected2, width, heigh
|
|
|
210032
211411
|
internalsVisible: !hiddenContainer,
|
|
210033
211412
|
featureCompartmentsVisible,
|
|
210034
211413
|
cornerRadius: nodeCornerRadius(node.shape, node.isDef, h, (node.compartments?.length ?? 0) > 0),
|
|
210035
|
-
onToggleInternals: ctx.onToggleInternals,
|
|
211414
|
+
onToggleInternals: node.meta?.internalsExpandable === true ? ctx.onToggleInternals : void 0,
|
|
210036
211415
|
onToggleFeatureCompartments: ctx.onToggleFeatureCompartments
|
|
210037
211416
|
}
|
|
210038
211417
|
) : null,
|
|
@@ -210042,7 +211421,8 @@ function SysmlNode({ id: id2, data, draggable, selected: selected2, width, heigh
|
|
|
210042
211421
|
id: id2,
|
|
210043
211422
|
name: node.name,
|
|
210044
211423
|
value: node.value,
|
|
210045
|
-
top: h - 36
|
|
211424
|
+
top: h - 36,
|
|
211425
|
+
...valueFieldRole(node.keyword)
|
|
210046
211426
|
},
|
|
210047
211427
|
id2 + ":" + node.value
|
|
210048
211428
|
) : null,
|
|
@@ -210289,7 +211669,15 @@ function FrameNode({ id: id2, data, selected: selected2, width, height }) {
|
|
|
210289
211669
|
strokeWidth: 0.8
|
|
210290
211670
|
}
|
|
210291
211671
|
) : null,
|
|
210292
|
-
frame2.value !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
211672
|
+
frame2.value !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
211673
|
+
AttributeValueShape,
|
|
211674
|
+
{
|
|
211675
|
+
value: frame2.value,
|
|
211676
|
+
w,
|
|
211677
|
+
top: frameHeaderHeight - 34,
|
|
211678
|
+
placeholder: valueFieldRole(frame2.keyword).placeholder
|
|
211679
|
+
}
|
|
211680
|
+
) : null,
|
|
210293
211681
|
isStructuredControl ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("g", { className: "dstructured-condition-compartment", children: [
|
|
210294
211682
|
isNamedStructuredAction ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
210295
211683
|
"line",
|
|
@@ -210555,7 +211943,7 @@ function FrameNode({ id: id2, data, selected: selected2, width, height }) {
|
|
|
210555
211943
|
internalsVisible: true,
|
|
210556
211944
|
featureCompartmentsVisible,
|
|
210557
211945
|
cornerRadius: frame2.isDef === true ? 0 : FRAME_USAGE_CORNER_RADIUS,
|
|
210558
|
-
onToggleInternals: ctx.onToggleInternals,
|
|
211946
|
+
onToggleInternals: frame2.meta?.internalsExpandable === true ? ctx.onToggleInternals : void 0,
|
|
210559
211947
|
onToggleFeatureCompartments: ctx.onToggleFeatureCompartments
|
|
210560
211948
|
}
|
|
210561
211949
|
) : null,
|
|
@@ -210565,7 +211953,8 @@ function FrameNode({ id: id2, data, selected: selected2, width, height }) {
|
|
|
210565
211953
|
id: id2,
|
|
210566
211954
|
name: frame2.label,
|
|
210567
211955
|
value: frame2.value,
|
|
210568
|
-
top: frameHeaderHeight - 34
|
|
211956
|
+
top: frameHeaderHeight - 34,
|
|
211957
|
+
...valueFieldRole(frame2.keyword)
|
|
210569
211958
|
},
|
|
210570
211959
|
id2 + ":" + frame2.value
|
|
210571
211960
|
) : null,
|
|
@@ -211260,7 +212649,7 @@ async function runExport(command) {
|
|
|
211260
212649
|
}
|
|
211261
212650
|
|
|
211262
212651
|
// src/main.ts
|
|
211263
|
-
var VERSION2 = true ? "0.
|
|
212652
|
+
var VERSION2 = true ? "0.39.0" : "dev";
|
|
211264
212653
|
function display(file) {
|
|
211265
212654
|
const rel2 = path9.relative(process.cwd(), file);
|
|
211266
212655
|
return rel2 && !rel2.startsWith("..") ? rel2.split(path9.sep).join("/") : file;
|