Skip to content

Commit a8cc426

Browse files
authored
Merge pull request #730 from Systems-Modeling/ST6RI-907
ST6RI-907 Cannot correctly render nested inherited connections with SHOWINHERITED style (PlantUML)
2 parents 5a95437 + 4c54180 commit a8cc426

1 file changed

Lines changed: 74 additions & 29 deletions

File tree

  • org.omg.sysml.plantuml/src/org/omg/sysml/plantuml

org.omg.sysml.plantuml/src/org/omg/sysml/plantuml/VPath.java

Lines changed: 74 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*****************************************************************************
22
* SysML 2 Pilot Implementation, PlantUML Visualization
3-
* Copyright (c) 2020-2024 Mgnite Inc.
3+
* Copyright (c) 2020-2026 Mgnite Inc.
44
* Copyright (c) 2022 Model Driven Solutions, Inc.
55
*
66
* This program is free software: you can redistribute it and/or modify
@@ -327,29 +327,38 @@ public PCTerminal(PC prev) {
327327

328328
// Make an InheritKey for ref, which is either a connector end or FeatureReferenceExpression or FeatureChainExpression.
329329
// These are (indirectly) owned by the innermost feature, which effectively determines the target scope.
330-
private InheritKey makeInheritKeyForReferer(PC pc) {
330+
private RefPC makeRefPCForReferer(PC pc) {
331331
if (pc == null) return null;
332332
Element e = pc.getTarget();
333333
if (!(e instanceof Feature)) return null;
334334
Feature ref = (Feature) e;
335335

336-
Namespace ns = getCurrentNamespace();
336+
Namespace ns = getCurrentNamespace(); // the namespace owning a connector
337337
if (!(ns instanceof Type)) return null;
338338

339339
if (ns instanceof Feature) {
340-
Feature tgt = (Feature) ns;
341-
InheritKey ik = makeInheritKey(tgt);
340+
//Feature tgt = (Feature) ns;
341+
InheritKey ik = makeInheritKey(ref);
342342
if (ik != null) {
343343
// Make the inherit key indirect in order to refer to redefined targets as well as inherited ones.
344344
ik = InheritKey.makeIndirect(ik);
345-
ik = InheritKey.findTop(ik, ref);
346-
if (ik != null) return ik;
345+
InheritKey ik2 = InheritKey.findTop(ik, ref);
346+
if (ik2 != null) {
347+
// This is overspecifying case.
348+
return createRefPC(ik2, pc);
349+
}
350+
// This is underspecifying case and we need to add a PCNamespace to capture ns/tgt
351+
PCNamespace pcn = new PCNamespace(ns, pc);
352+
return createRefPC(ik, pcn);
347353
}
348354
}
349355

350356
// In case that tgt inherits ref, we need to make an InheritKey for tgt.
351-
Type tgt = (Type) ns;
352-
return InheritKey.makeTargetKey(tgt, ref);
357+
{
358+
Type tgt = (Type) ns;
359+
InheritKey ik = InheritKey.makeTargetKey(tgt, ref);
360+
return createRefPC(ik, pc);
361+
}
353362
}
354363

355364

@@ -359,27 +368,36 @@ private InheritKey makeInheritKeyForReferer(PC pc) {
359368
iff : Feature :>> ioTarget: ReferenceUsage;
360369
}
361370
*/
371+
372+
private static Feature getRootRedefinedFeature(Feature f) {
373+
for (Redefinition rd: f.getOwnedRedefinition()) {
374+
Feature rf = rd.getRedefinedFeature();
375+
Feature rrf = getRootRedefinedFeature(rf);
376+
if (rrf == null) return rf;
377+
return rrf;
378+
}
379+
return null;
380+
}
381+
362382
private static Feature getIOTarget(FlowEnd ife) {
363383
for (FeatureMembership fm: toOwnedFeatureMembershipArray(ife)) {
364384
Feature f = fm.getOwnedMemberFeature();
365-
for (Redefinition rd: f.getOwnedRedefinition()) {
366-
return rd.getRedefinedFeature();
367-
}
385+
return getRootRedefinedFeature(f);
368386
}
369387
return null;
370388
}
371389

372-
private class PCItemFlowEnd extends PC {
390+
private class PCFlowEnd extends PC {
373391
private final Feature ioTarget;
374392
private final PC basePC;
375393

376-
public PCItemFlowEnd(FlowEnd ife, PC basePC, Feature ioTarget) {
394+
public PCFlowEnd(FlowEnd ife, PC basePC, Feature ioTarget) {
377395
super(ife, false);
378396
this.basePC = basePC;
379397
this.ioTarget = ioTarget;
380398
}
381399

382-
private PCItemFlowEnd(PCItemFlowEnd prev, PC basePC) {
400+
private PCFlowEnd(PCFlowEnd prev, PC basePC) {
383401
super(prev);
384402
this.basePC = basePC;
385403
this.ioTarget = prev.ioTarget;
@@ -406,12 +424,12 @@ protected PC getNext() {
406424
if (basePC == null) return new PCTerminal(this);
407425
PC ret = basePC.getNext();
408426
if (!ret.isTerminal()) {
409-
return new PCItemFlowEnd(this, ret);
427+
return new PCFlowEnd(this, ret);
410428
}
411429
if (ioTarget == null) {
412430
return new PCTerminal(this);
413431
} else {
414-
return new PCItemFlowEnd(this, null);
432+
return new PCFlowEnd(this, null);
415433
}
416434
}
417435
}
@@ -447,6 +465,37 @@ protected Element getTarget() {
447465
}
448466
}
449467

468+
private class PCNamespace extends PC {
469+
public final Namespace ns;
470+
private final PC pc;
471+
472+
@Override
473+
protected PC getNext() {
474+
return pc;
475+
}
476+
477+
@Override
478+
public PC enter(Namespace ns) {
479+
if (ns.equals(this.ns)) {
480+
return pc;
481+
} else {
482+
return this;
483+
}
484+
}
485+
486+
public PCNamespace(Namespace ns, PC pc) {
487+
super((Element) null, true);
488+
this.ns = ns;
489+
this.pc = pc;
490+
pc.setPrev(this);
491+
}
492+
493+
@Override
494+
protected Element getTarget() {
495+
return null;
496+
}
497+
}
498+
450499
private class RefPC {
451500
private PC pc;
452501
private final InheritKey ik;
@@ -542,37 +591,33 @@ private String addContextForFeature(Feature f, boolean isRedefinition) {
542591

543592
private String addContextForEnd(Feature f) {
544593
if (f instanceof FlowEnd) {
545-
return addContextForItemFlowEnd((FlowEnd) f);
594+
return addContextForFlowEnd((FlowEnd) f);
546595
}
547596
PC pc = makeEndFeaturePC(f);
548-
InheritKey ik = makeInheritKeyForReferer(pc);
549-
if (createRefPC(ik, pc) == null) return null;
597+
if (makeRefPCForReferer(pc) == null) return null;
550598
return "";
551599
}
552600

553-
private String addContextForItemFlowEnd(FlowEnd ife) {
601+
private String addContextForFlowEnd(FlowEnd ife) {
554602
PC pc = makeEndFeaturePC(ife);
555603
if (pc == null) return null;
556604
Feature ioTarget = getIOTarget(ife);
557-
pc = new PCItemFlowEnd(ife, pc, ioTarget);
558-
InheritKey ik = makeInheritKeyForReferer(pc);
559-
if (createRefPC(ik, pc) == null) return null;
605+
pc = new PCFlowEnd(ife, pc, ioTarget);
606+
if (makeRefPCForReferer(pc) == null) return null;
560607
return "";
561608
}
562609

563610
private String addContextForFeatureChainExpression(FeatureChainExpression fce) {
564611
PC pc = new PCFeatureChainExpression(fce);
565-
InheritKey ik = makeInheritKeyForReferer(pc);
566-
createRefPC(ik, pc);
612+
makeRefPCForReferer(pc);
567613
return "";
568614
}
569615

570616
private String addContextForFeatureReferenceExpression(FeatureReferenceExpression fre) {
571617
Feature f = fre.getReferent();
572618
if (f == null) return "";
573619
PC pc = new PCFeature(fre, f, false);
574-
InheritKey ik = makeInheritKeyForReferer(pc);
575-
createRefPC(ik, pc);
620+
makeRefPCForReferer(pc);
576621
return "";
577622
}
578623

@@ -666,7 +711,7 @@ public String caseFeatureReferenceExpression(FeatureReferenceExpression fre) {
666711

667712
@Override
668713
public String caseFlowEnd(FlowEnd ife) {
669-
return addContextForItemFlowEnd(ife);
714+
return addContextForFlowEnd(ife);
670715
}
671716

672717
@Override

0 commit comments

Comments
 (0)