Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ST6RI-767: Some redefinitions are not correctly rendered (PlantUML) #561

Merged
merged 4 commits into from
Apr 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 6 additions & 17 deletions org.omg.sysml.plantuml/src/org/omg/sysml/plantuml/InheritKey.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
package org.omg.sysml.plantuml;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

Expand All @@ -35,9 +34,9 @@
import org.omg.sysml.lang.sysml.FeatureValue;
import org.omg.sysml.lang.sysml.Membership;
import org.omg.sysml.lang.sysml.Namespace;
import org.omg.sysml.lang.sysml.Redefinition;
import org.omg.sysml.lang.sysml.Relationship;
import org.omg.sysml.lang.sysml.Type;
import org.omg.sysml.util.FeatureUtil;


/* InheritKey identifies a feature or a membership with the context of inheriting.
Expand Down Expand Up @@ -238,22 +237,12 @@ public static InheritKey construct(List<Namespace> ctx, List<Integer> inheritIdi
return constructInternal(ctx, inheritIdices, idx);
}

private static boolean matchRedefined(Feature f, Feature ft, Set<Feature> visited) {
if (visited.contains(f)) return false;
visited.add(f);
for (Redefinition rd: f.getOwnedRedefinition()) {
Feature rf = rd.getRedefinedFeature();
if (ft.equals(rf)) return true;
return matchRedefined(rf, ft, visited);
}
return false;
}

private static boolean matchRedefined(Feature f, Feature ft) {
return matchRedefined(f, ft, new HashSet<Feature>());
Set<Feature> redefs = FeatureUtil.getAllRedefinedFeaturesOf(f);
return redefs.contains(ft);
}

public static boolean matchElement(Element e, Element et) {
public static boolean matchElementWithRedefined(Element e, Element et) {
if (e.equals(et)) return true;
if ((e instanceof Feature) && (et instanceof Feature)) {
return matchRedefined((Feature) e, (Feature) et);
Expand All @@ -277,14 +266,14 @@ public static boolean match(InheritKey ik, List<Namespace> ctx, List<Integer> in
for (int i = 0; i < iSize; i++) {
int idx = inheritIdices.get(i);
Namespace ns = ctx.get(idx);
if (!matchElement(ns, ik.keys[i])) return false;
if (!matchElementWithRedefined(ns, ik.keys[i])) return false;
}
if (diff == 0) return true;

// diff must be 1
if (ik.isDirect) return false;
// case ^ow)
return matchElement(ctx.get(ctxSize - 1), ik.keys[kLen - 1]);
return matchElementWithRedefined(ctx.get(ctxSize - 1), ik.keys[kLen - 1]);
}
}

Expand Down
21 changes: 6 additions & 15 deletions org.omg.sysml.plantuml/src/org/omg/sysml/plantuml/VDefault.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@
import org.omg.sysml.lang.sysml.MetadataFeature;
import org.omg.sysml.lang.sysml.Namespace;
import org.omg.sysml.lang.sysml.OwningMembership;
import org.omg.sysml.lang.sysml.Redefinition;
import org.omg.sysml.lang.sysml.Relationship;
import org.omg.sysml.lang.sysml.Specialization;
import org.omg.sysml.lang.sysml.Subsetting;
Expand Down Expand Up @@ -118,23 +117,15 @@ public String caseNamespace(Namespace ns) {

protected void addSpecializations(int typId, Type typ) {
if (typId < 0) return;
InheritKey ik = null;
InheritKey ik;
if (typ instanceof Feature) {
ik = makeInheritKey((Feature) typ);
} else {
ik = null;
}
for (Specialization s: typ.getOwnedSpecialization()) {
Type gt = s.getGeneral();
if (gt == null) continue;
if (ik == null && gt instanceof Feature) {
if (s instanceof Redefinition) {
// If we just create an inherit key for redefinition target, always create a cyclic reference
// because redefining feature can be a target in this sense. So we must create an inherit key
// for the membership owning the target since the redefined target always exists.
Membership ms = gt.getOwningMembership();
if (ms != null) {
ik = makeInheritKey(ms);
}
} else {
ik = makeInheritKey((Feature) gt);
}
}
PRelation pr = new PRelation(ik, typId, gt, s, null);
addPRelation(pr);
}
Expand Down
52 changes: 32 additions & 20 deletions org.omg.sysml.plantuml/src/org/omg/sysml/plantuml/VPath.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,14 @@ public static Expression getRefTarget(Expression e) {

private boolean initialized;

// PC (PathContext) management.
// PC (PathContext) management.
private abstract class PC {
private final Element idTarget;

// If it's true, PC does consider Redefinition when it match with idTarget.
// This is used for Redefinition.
protected final boolean noRedefine;

private PC next;
private PC prev;
public void setPrev(PC prev) {
Expand All @@ -88,11 +93,13 @@ private PC getNextI() {
protected PC(PC prev) {
this.prev = prev;
this.idTarget = prev.idTarget;
this.noRedefine = prev.noRedefine;
}

protected PC(Element idTarget) {
protected PC(Element idTarget, boolean noRedefine) {
this.prev = null;
this.idTarget = idTarget;
this.noRedefine = noRedefine;
}

private boolean isSet;
Expand Down Expand Up @@ -120,7 +127,11 @@ public void setId(InheritKey ik, Element e, Integer id) {
private boolean match(Element e) {
if (isTerminal()) return false;
Element et = getTarget();
return InheritKey.matchElement(e, et);
if (noRedefine) {
return e.equals(et);
} else {
return InheritKey.matchElementWithRedefined(e, et);
}
}

public Element requiredElement() {
Expand Down Expand Up @@ -196,7 +207,7 @@ protected PC getNext() {
}

public PCFeatureChainExpression(FeatureChainExpression fce) {
super(fce);
super(fce, false);
this.fce = fce;
}
}
Expand All @@ -219,9 +230,9 @@ public PCFeature(PC prev, Feature f) {
this.f = f;
}

public PCFeature(Element tgt, Feature f) {
super(tgt);
this.f = f;
public PCFeature(Element tgt, Feature f, boolean noRedefine) {
super(tgt, noRedefine);
this.f = f;
}

protected PCFeature(PCFeature pc) {
Expand Down Expand Up @@ -283,8 +294,8 @@ private PCFeatureChain(PCFeatureChain prev) {
this.index = prev.index + 1;
}

public PCFeatureChain(Element tgt, Feature f) {
super(tgt);
public PCFeatureChain(Element tgt, Feature f, boolean noRedefine) {
super(tgt, noRedefine);
this.fcs = f.getOwnedFeatureChaining();
this.index = 0;
}
Expand Down Expand Up @@ -362,7 +373,7 @@ private class PCItemFlowEnd extends PC {
private final PC basePC;

public PCItemFlowEnd(ItemFlowEnd ife, PC basePC, Feature ioTarget) {
super(ife);
super(ife, false);
this.basePC = basePC;
this.ioTarget = ioTarget;
}
Expand Down Expand Up @@ -423,7 +434,7 @@ public PC enter(Namespace ns) {
}

public PCInheritKey(InheritKey ik, PC pc) {
super((Element) null);
super((Element) null, pc.noRedefine);
this.ik = ik;
this.pc = pc;
pc.setPrev(this);
Expand Down Expand Up @@ -496,19 +507,19 @@ private void putPathIdMap(Integer id, InheritKey ik, Element pt) {

private List<RefPC> current = new ArrayList<RefPC>();

private PC makeFeaturePC(Element tgt, Feature f) {
private PC makeFeaturePC(Element tgt, Feature f, boolean noRedefine) {
List<FeatureChaining> fcs = f.getOwnedFeatureChaining();
if (fcs.isEmpty()) {
return new PCFeature(tgt, f);
return new PCFeature(tgt, f, noRedefine);
} else {
return new PCFeatureChain(tgt, f);
return new PCFeatureChain(tgt, f, noRedefine);
}
}

private PC makeEndFeaturePC(Feature end) {
Feature sf = ConnectorUtil.getRelatedFeatureOfEnd(end);
if (sf == null) return null;
return makeFeaturePC(end, sf);
return makeFeaturePC(end, sf, false);
}

private RefPC createRefPC(InheritKey ik, PC pc) {
Expand All @@ -518,9 +529,10 @@ private RefPC createRefPC(InheritKey ik, PC pc) {
return rpc;
}

private String addContextForFeature(Feature f) {
PC pc = makeFeaturePC(f, f);
InheritKey ik = makeInheritKey(f);
private String addContextForFeature(Feature f, boolean isRedefinition) {
PC pc = makeFeaturePC(f, f, isRedefinition);
InheritKey ik = makeInheritKeyForReferer(pc);
// InheritKey ik = makeInheritKey(f);
if (createRefPC(ik, pc) == null) return null;
return "";
}
Expand Down Expand Up @@ -562,7 +574,7 @@ private String addContextForFeatureChainExpression(FeatureChainExpression fce) {
private String addContextForFeatureReferenceExpression(FeatureReferenceExpression fre) {
Feature f = fre.getReferent();
if (f == null) return "";
PC pc = new PCFeature(fre, f);
PC pc = new PCFeature(fre, f, false);
InheritKey ik = makeInheritKeyForReferer(pc);
createRefPC(ik, pc);
return "";
Expand Down Expand Up @@ -635,7 +647,7 @@ public String caseType(Type typ) {
// Type s = sp.getSpecific();
if (g == null) continue;
if (g instanceof Feature) {
addContextForFeature((Feature) g);
addContextForFeature((Feature) g, sp instanceof Redefinition);
}
if (checkVisited(g)) continue;
visit(g);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,10 @@
import org.omg.sysml.lang.sysml.Import;
import org.omg.sysml.lang.sysml.Membership;
import org.omg.sysml.lang.sysml.Namespace;
import org.omg.sysml.lang.sysml.Redefinition;
import org.omg.sysml.lang.sysml.Relationship;
import org.omg.sysml.lang.sysml.Type;
import org.omg.sysml.util.ElementUtil;
import org.omg.sysml.util.FeatureUtil;

public abstract class VTraverser extends Visitor {
private Set<Namespace> visited;
Expand Down Expand Up @@ -72,10 +72,7 @@ private boolean markRedefining(Element e, Set<Element> covered) {
if (covered.contains(e)) return true;
if (!(e instanceof Feature)) return false;
Feature f = (Feature) e;
for (Redefinition r: f.getOwnedRedefinition()) {
Feature rf = r.getRedefinedFeature();
covered.add(rf);
}
covered.addAll(FeatureUtil.getAllRedefinedFeaturesOf(f));
return false;
}

Expand Down Expand Up @@ -115,9 +112,10 @@ private void traverseInherited(Type typ, Set<Element> covered) {
}
}

private void traverseRest(VPath vpath) {
private void traverseRest(VPath vpath, Set<Element> covered) {
for (Element e: vpath.rest()) {
if (!showLib() && isModelLibrary(e)) continue;
if (markRedefining(e, covered)) continue;
currentMembership = null;
setInherited(true);
visit(e);
Expand All @@ -137,7 +135,7 @@ public String traverse(Namespace ns, boolean noInherit, boolean noPopNamespace)
traverseInherited((Type) ns, covered);
}
} else {
traverseRest(vpath);
traverseRest(vpath, covered);
}
}
vpath.leave(ns);
Expand Down