From 516b2ad9484bc24d7b7dd7dbc83aa6efed5dee30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20M=C3=A4ckelmann?= Date: Mon, 11 May 2026 13:21:30 +0200 Subject: [PATCH 01/10] Initial sctx to json transformation --- .../META-INF/MANIFEST.MF | 6 +- .../sccharts/processors/json/Action.java | 172 +++++++++++++++ .../sccharts/processors/json/Region.java | 90 ++++++++ .../sccharts/processors/json/SCTXToJSON.xtend | 185 +++++++++++++++++ .../sccharts/processors/json/State.java | 195 ++++++++++++++++++ .../sccharts/processors/json/Transition.java | 140 +++++++++++++ .../sccharts/processors/json/Variable.java | 113 ++++++++++ .../providers/SCChartsProcessorProvider.xtend | 3 +- .../providers/SCChartsSystemProvider.xtend | 3 +- .../de.cau.cs.kieler.sccharts.SCTXToJSON.kico | 4 + 10 files changed, 907 insertions(+), 4 deletions(-) create mode 100644 plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/Action.java create mode 100644 plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/Region.java create mode 100644 plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/SCTXToJSON.xtend create mode 100644 plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/State.java create mode 100644 plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/Transition.java create mode 100644 plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/Variable.java create mode 100644 plugins/de.cau.cs.kieler.sccharts/system/de.cau.cs.kieler.sccharts.SCTXToJSON.kico diff --git a/plugins/de.cau.cs.kieler.sccharts/META-INF/MANIFEST.MF b/plugins/de.cau.cs.kieler.sccharts/META-INF/MANIFEST.MF index 10b0563472..4b985745b9 100644 --- a/plugins/de.cau.cs.kieler.sccharts/META-INF/MANIFEST.MF +++ b/plugins/de.cau.cs.kieler.sccharts/META-INF/MANIFEST.MF @@ -54,6 +54,8 @@ Require-Bundle: org.eclipse.emf.ecore;visibility:=reexport, org.eclipse.core.resources, org.eclipse.core.runtime, org.eclipse.elk.graph;bundle-version="0.4.0", - org.eclipse.elk.core;bundle-version="0.4.0" + org.eclipse.elk.core;bundle-version="0.4.0", + com.google.gson;bundle-version="[2.11.0,3.0.0)" Bundle-ActivationPolicy: lazy -Import-Package: org.apache.log4j +Import-Package: com.google.gson;version="[2.11.0,3.0.0)", + org.apache.log4j diff --git a/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/Action.java b/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/Action.java new file mode 100644 index 0000000000..e53d30e65a --- /dev/null +++ b/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/Action.java @@ -0,0 +1,172 @@ + +package de.cau.cs.kieler.sccharts.processors.json; + +import java.util.HashMap; +import java.util.Map; +import javax.annotation.processing.Generated; +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +@Generated("jsonschema2pojo") +public class Action { + + @SerializedName("label") + @Expose + private String label; + /** + * + * (Required) + * + */ + @SerializedName("type") + @Expose + private Action.Type type; + /** + * + * (Required) + * + */ + @SerializedName("isImmediate") + @Expose + private boolean isImmediate; + @SerializedName("guard") + @Expose + private String guard; + /** + * + * (Required) + * + */ + @SerializedName("action") + @Expose + private String action; + + /** + * No args constructor for use in serialization + * + */ + public Action() { + } + + public Action(String label, Action.Type type, boolean isImmediate, String guard, String action) { + super(); + this.label = label; + this.type = type; + this.isImmediate = isImmediate; + this.guard = guard; + this.action = action; + } + + public String getLabel() { + return label; + } + + public void setLabel(String label) { + this.label = label; + } + + /** + * + * (Required) + * + */ + public Action.Type getType() { + return type; + } + + /** + * + * (Required) + * + */ + public void setType(Action.Type type) { + this.type = type; + } + + /** + * + * (Required) + * + */ + public boolean isIsImmediate() { + return isImmediate; + } + + /** + * + * (Required) + * + */ + public void setIsImmediate(boolean isImmediate) { + this.isImmediate = isImmediate; + } + + public String getGuard() { + return guard; + } + + public void setGuard(String guard) { + this.guard = guard; + } + + /** + * + * (Required) + * + */ + public String getAction() { + return action; + } + + /** + * + * (Required) + * + */ + public void setAction(String action) { + this.action = action; + } + + @Generated("jsonschema2pojo") + public enum Type { + + @SerializedName("during") + DURING("during"), + @SerializedName("entry") + ENTRY("entry"), + @SerializedName("exit") + EXIT("exit"); + private final String value; + private final static Map CONSTANTS = new HashMap(); + + static { + for (Action.Type c: values()) { + CONSTANTS.put(c.value, c); + } + } + + Type(String value) { + this.value = value; + } + + @Override + public String toString() { + return this.value; + } + + public String value() { + return this.value; + } + + public static Action.Type fromValue(String value) { + Action.Type constant = CONSTANTS.get(value); + if (constant == null) { + throw new IllegalArgumentException(value); + } else { + return constant; + } + } + + } + +} diff --git a/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/Region.java b/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/Region.java new file mode 100644 index 0000000000..b9494bf651 --- /dev/null +++ b/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/Region.java @@ -0,0 +1,90 @@ + +package de.cau.cs.kieler.sccharts.processors.json; + +import java.util.List; +import javax.annotation.processing.Generated; +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +@Generated("jsonschema2pojo") +public class Region { + + /** + * + * (Required) + * + */ + @SerializedName("id") + @Expose + private String id; + @SerializedName("label") + @Expose + private String label; + /** + * + * (Required) + * + */ + @SerializedName("states") + @Expose + private List states; + + /** + * No args constructor for use in serialization + * + */ + public Region() { + } + + public Region(String id, String label, List states) { + super(); + this.id = id; + this.label = label; + this.states = states; + } + + /** + * + * (Required) + * + */ + public String getId() { + return id; + } + + /** + * + * (Required) + * + */ + public void setId(String id) { + this.id = id; + } + + public String getLabel() { + return label; + } + + public void setLabel(String label) { + this.label = label; + } + + /** + * + * (Required) + * + */ + public List getStates() { + return states; + } + + /** + * + * (Required) + * + */ + public void setStates(List states) { + this.states = states; + } + +} diff --git a/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/SCTXToJSON.xtend b/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/SCTXToJSON.xtend new file mode 100644 index 0000000000..d7561b6900 --- /dev/null +++ b/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/SCTXToJSON.xtend @@ -0,0 +1,185 @@ +/* + * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient + * + * http://rtsys.informatik.uni-kiel.de/kieler + * + * Copyright ${year} by + * + Kiel University + * + Department of Computer Science + * + Real-Time and Embedded Systems Group + * + * This code is provided under the terms of the Eclipse Public License (EPL). + */ +package de.cau.cs.kieler.sccharts.processors.json; + +import java.util.Map; + +import de.cau.cs.kieler.kicool.compilation.CodeContainer; +import de.cau.cs.kieler.kicool.compilation.Processor; +import de.cau.cs.kieler.kicool.compilation.ProcessorType; +import de.cau.cs.kieler.sccharts.SCCharts; +import de.cau.cs.kieler.sccharts.State; +import com.google.gson.GsonBuilder +import de.cau.cs.kieler.kexpressions.keffects.extensions.KEffectsSerializeExtensions +import de.cau.cs.kieler.kexpressions.extensions.KExpressionsSerializeExtensions +import com.google.inject.Inject +import de.cau.cs.kieler.kexpressions.Declaration +import de.cau.cs.kieler.sccharts.ControlflowRegion +import de.cau.cs.kieler.sccharts.DelayType +import de.cau.cs.kieler.sccharts.PreemptionType +import java.util.Optional +import java.util.List +import java.util.LinkedList +import de.cau.cs.kieler.kexpressions.VariableDeclaration +import de.cau.cs.kieler.kexpressions.ValuedObject +import de.cau.cs.kieler.kexpressions.ValueType + +/** + * + */ +public class SCTXToJSON extends Processor { + + @Inject + private KEffectsSerializeExtensions effect_serializer; + @Inject + private KExpressionsSerializeExtensions expr_serializer; + + + /** + * {@inheritDoc} + */ + + override String getId() { + return "de.cau.cs.kieler.sccharts.processors.SCTXToJSON"; + } + + /** + * {@inheritDoc} + */ + override String getName() { + return "SCTX to JSON"; + } + + + /** + * {@inheritDoc} + */ + override ProcessorType getType() { + return ProcessorType.EXOGENOUS_TRANSFORMATOR; + } + + /** + * {@inheritDoc} + */ + override void process() { + val cc = new CodeContainer(); + + val gson = new GsonBuilder().setPrettyPrinting().create(); + val transformedRoots = this.sourceModel.rootStates.map[transformState]; + val fileName = this.sourceModel.name?.hostcodeSafeName ?: "scchart" + + cc.add(fileName + ".json", gson.toJson(transformedRoots)); + this.setModel(cc); + + } + + def de.cau.cs.kieler.sccharts.processors.json.Region transformRegion(de.cau.cs.kieler.sccharts.Region region) { + + switch (region) { + ControlflowRegion: { + val transformed = new de.cau.cs.kieler.sccharts.processors.json.Region() + transformed.id = region.name; + transformed.label = region.label; + transformed.states = region.states.map[transformState] + + transformed + } + default: { + environment.errors.add("Cannot handle region %s of type %s.".format(region.name, region.class.name)) + null + } + } + } + + + def de.cau.cs.kieler.sccharts.processors.json.State transformState(de.cau.cs.kieler.sccharts.State state) { + + val transformed = new de.cau.cs.kieler.sccharts.processors.json.State(); + + transformed.id = state.name + transformed.label = state.label + transformed.actions = state.actions.map[transformAction] + transformed.transitions = state.outgoingTransitions.map[transformTransition] + transformed.variables = state.declarations.flatMap[transformDeclaration].toList + transformed.isInitial = state.isInitial() + transformed.isFinal = state.isFinal() + transformed.regions = state.regions.map[transformRegion] + + return transformed + } + + def de.cau.cs.kieler.sccharts.processors.json.Action transformAction(de.cau.cs.kieler.sccharts.LocalAction action) { + val transformed = new de.cau.cs.kieler.sccharts.processors.json.Action() + + transformed.label = action.label + transformed.type = switch (action) { + de.cau.cs.kieler.sccharts.DuringAction: Action.Type.DURING + de.cau.cs.kieler.sccharts.EntryAction: Action.Type.ENTRY + de.cau.cs.kieler.sccharts.ExitAction: Action.Type.EXIT + default: { + environment.errors.add("Cannot handle action %s of type %s.".format(action.label, action.class.name)) + + null + } + } + + transformed.isImmediate = action.delay.equals(DelayType.IMMEDIATE) + transformed.guard = Optional.ofNullable(action.trigger).map[expr_serializer.serialize(it)].map[toString].orElse(null) + transformed.action = String.valueOf(effect_serializer.serialize(action.effects)) + + return transformed + } + + def de.cau.cs.kieler.sccharts.processors.json.Transition transformTransition(de.cau.cs.kieler.sccharts.Transition transition) { + val transformed = new de.cau.cs.kieler.sccharts.processors.json.Transition() + + transformed.label = transition.label + transformed.targetID = transition.targetState.name + transformed.isImmediate = transition.delay.equals(DelayType.IMMEDIATE) + transformed.isTermination = transition.preemption.equals(PreemptionType.TERMINATION) + transformed.guard = Optional.ofNullable(transition.trigger).map[expr_serializer.serialize(it)].map[toString].orElse(null) + transformed.action = String.valueOf(effect_serializer.serialize(transition.effects)) + + return transformed + } + + def List transformDeclaration(Declaration declaration) { + switch (declaration) { + VariableDeclaration: declaration.valuedObjects.map[ + transformVariable(it, declaration.type, declaration.input, declaration.output) + ] + default: { + environment.errors.add("Cannot handle declaration %s of type %s.".format(declaration.toString(), declaration.class.name)) + new LinkedList() + } + } + + } + + def de.cau.cs.kieler.sccharts.processors.json.Variable transformVariable(ValuedObject v, ValueType t, boolean isInput, boolean isOutput) { + val transformed = new de.cau.cs.kieler.sccharts.processors.json.Variable() + + transformed.id = v.name + transformed.type = t.literal + transformed.initialValue = Optional.ofNullable(v.initialValue).map[expr_serializer.serialize(it)].map[toString].orElse(null) + transformed.isInput = isInput + transformed.isOutput = isOutput + + return transformed + } + + protected def hostcodeSafeName(String string) { + if (string === null) return "" + string.replaceAll("[\\s-]","_") + } +} diff --git a/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/State.java b/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/State.java new file mode 100644 index 0000000000..6c04b4bc4d --- /dev/null +++ b/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/State.java @@ -0,0 +1,195 @@ + +package de.cau.cs.kieler.sccharts.processors.json; + +import java.util.List; +import javax.annotation.processing.Generated; +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +@Generated("jsonschema2pojo") +public class State { + + /** + * + * (Required) + * + */ + @SerializedName("id") + @Expose + private String id; + @SerializedName("label") + @Expose + private String label; + @SerializedName("actions") + @Expose + private List actions; + /** + * + * (Required) + * + */ + @SerializedName("transitions") + @Expose + private List transitions; + @SerializedName("variables") + @Expose + private List variables; + /** + * + * (Required) + * + */ + @SerializedName("isInitial") + @Expose + private boolean isInitial; + /** + * + * (Required) + * + */ + @SerializedName("isFinal") + @Expose + private boolean isFinal; + /** + * + * (Required) + * + */ + @SerializedName("regions") + @Expose + private List regions; + + /** + * No args constructor for use in serialization + * + */ + public State() { + } + + public State(String id, String label, List actions, List transitions, List variables, boolean isInitial, boolean isFinal, List regions) { + super(); + this.id = id; + this.label = label; + this.actions = actions; + this.transitions = transitions; + this.variables = variables; + this.isInitial = isInitial; + this.isFinal = isFinal; + this.regions = regions; + } + + /** + * + * (Required) + * + */ + public String getId() { + return id; + } + + /** + * + * (Required) + * + */ + public void setId(String id) { + this.id = id; + } + + public String getLabel() { + return label; + } + + public void setLabel(String label) { + this.label = label; + } + + public List getActions() { + return actions; + } + + public void setActions(List actions) { + this.actions = actions; + } + + /** + * + * (Required) + * + */ + public List getTransitions() { + return transitions; + } + + /** + * + * (Required) + * + */ + public void setTransitions(List transitions) { + this.transitions = transitions; + } + + public List getVariables() { + return variables; + } + + public void setVariables(List variables) { + this.variables = variables; + } + + /** + * + * (Required) + * + */ + public boolean isIsInitial() { + return isInitial; + } + + /** + * + * (Required) + * + */ + public void setIsInitial(boolean isInitial) { + this.isInitial = isInitial; + } + + /** + * + * (Required) + * + */ + public boolean isIsFinal() { + return isFinal; + } + + /** + * + * (Required) + * + */ + public void setIsFinal(boolean isFinal) { + this.isFinal = isFinal; + } + + /** + * + * (Required) + * + */ + public List getRegions() { + return regions; + } + + /** + * + * (Required) + * + */ + public void setRegions(List regions) { + this.regions = regions; + } + +} diff --git a/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/Transition.java b/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/Transition.java new file mode 100644 index 0000000000..5317854f32 --- /dev/null +++ b/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/Transition.java @@ -0,0 +1,140 @@ + +package de.cau.cs.kieler.sccharts.processors.json; + +import javax.annotation.processing.Generated; +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +@Generated("jsonschema2pojo") +public class Transition { + + @SerializedName("label") + @Expose + private String label; + /** + * + * (Required) + * + */ + @SerializedName("targetID") + @Expose + private String targetID; + /** + * + * (Required) + * + */ + @SerializedName("isImmediate") + @Expose + private boolean isImmediate; + /** + * + * (Required) + * + */ + @SerializedName("isTermination") + @Expose + private boolean isTermination; + @SerializedName("guard") + @Expose + private String guard; + @SerializedName("action") + @Expose + private String action; + + /** + * No args constructor for use in serialization + * + */ + public Transition() { + } + + public Transition(String label, String targetID, boolean isImmediate, boolean isTermination, String guard, String action) { + super(); + this.label = label; + this.targetID = targetID; + this.isImmediate = isImmediate; + this.isTermination = isTermination; + this.guard = guard; + this.action = action; + } + + public String getLabel() { + return label; + } + + public void setLabel(String label) { + this.label = label; + } + + /** + * + * (Required) + * + */ + public String getTargetID() { + return targetID; + } + + /** + * + * (Required) + * + */ + public void setTargetID(String targetID) { + this.targetID = targetID; + } + + /** + * + * (Required) + * + */ + public boolean isIsImmediate() { + return isImmediate; + } + + /** + * + * (Required) + * + */ + public void setIsImmediate(boolean isImmediate) { + this.isImmediate = isImmediate; + } + + /** + * + * (Required) + * + */ + public boolean isIsTermination() { + return isTermination; + } + + /** + * + * (Required) + * + */ + public void setIsTermination(boolean isTermination) { + this.isTermination = isTermination; + } + + public String getGuard() { + return guard; + } + + public void setGuard(String guard) { + this.guard = guard; + } + + public String getAction() { + return action; + } + + public void setAction(String action) { + this.action = action; + } + +} diff --git a/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/Variable.java b/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/Variable.java new file mode 100644 index 0000000000..4c9ca7f0e8 --- /dev/null +++ b/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/Variable.java @@ -0,0 +1,113 @@ + +package de.cau.cs.kieler.sccharts.processors.json; + +import javax.annotation.processing.Generated; +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +@Generated("jsonschema2pojo") +public class Variable { + + /** + * + * (Required) + * + */ + @SerializedName("id") + @Expose + private String id; + /** + * + * (Required) + * + */ + @SerializedName("type") + @Expose + private String type; + @SerializedName("initialValue") + @Expose + private Object initialValue; + @SerializedName("isInput") + @Expose + private boolean isInput; + @SerializedName("isOutput") + @Expose + private boolean isOutput; + + /** + * No args constructor for use in serialization + * + */ + public Variable() { + } + + public Variable(String id, String type, Object initialValue, boolean isInput, boolean isOutput) { + super(); + this.id = id; + this.type = type; + this.initialValue = initialValue; + this.isInput = isInput; + this.isOutput = isOutput; + } + + /** + * + * (Required) + * + */ + public String getId() { + return id; + } + + /** + * + * (Required) + * + */ + public void setId(String id) { + this.id = id; + } + + /** + * + * (Required) + * + */ + public String getType() { + return type; + } + + /** + * + * (Required) + * + */ + public void setType(String type) { + this.type = type; + } + + public Object getInitialValue() { + return initialValue; + } + + public void setInitialValue(Object initialValue) { + this.initialValue = initialValue; + } + + public boolean isIsInput() { + return isInput; + } + + public void setIsInput(boolean isInput) { + this.isInput = isInput; + } + + public boolean isIsOutput() { + return isOutput; + } + + public void setIsOutput(boolean isOutput) { + this.isOutput = isOutput; + } + +} diff --git a/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/providers/SCChartsProcessorProvider.xtend b/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/providers/SCChartsProcessorProvider.xtend index e834a5e5e1..b824057314 100644 --- a/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/providers/SCChartsProcessorProvider.xtend +++ b/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/providers/SCChartsProcessorProvider.xtend @@ -91,7 +91,8 @@ class SCChartsProcessorProvider implements IProcessorProvider { de.cau.cs.kieler.sccharts.processors.AbortRegion, de.cau.cs.kieler.sccharts.processors.scg.SCGAbortRegionProcessor, de.cau.cs.kieler.sccharts.processors.MethodSignaling, - de.cau.cs.kieler.sccharts.processors.analyzers.SCChartsModelData + de.cau.cs.kieler.sccharts.processors.analyzers.SCChartsModelData, + de.cau.cs.kieler.sccharts.processors.json.SCTXToJSON ] } diff --git a/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/providers/SCChartsSystemProvider.xtend b/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/providers/SCChartsSystemProvider.xtend index 8b66c8cf07..4da2d5a25a 100644 --- a/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/providers/SCChartsSystemProvider.xtend +++ b/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/providers/SCChartsSystemProvider.xtend @@ -68,7 +68,8 @@ class SCChartsSystemProvider implements ISystemProvider { "system/de.cau.cs.kieler.c.sccharts.dataflow.kico", "system/de.cau.cs.kieler.sccharts.simulation.priority.java.legacy.kico", "system/de.cau.cs.kieler.sccharts.simulation.tts.priority.java.legacy.kico", - "system/de.cau.cs.kieler.sccharts.netlist.simulink.kico" + "system/de.cau.cs.kieler.sccharts.netlist.simulink.kico", + "system/de.cau.cs.kieler.sccharts.SCTXToJSON.kico" ] } diff --git a/plugins/de.cau.cs.kieler.sccharts/system/de.cau.cs.kieler.sccharts.SCTXToJSON.kico b/plugins/de.cau.cs.kieler.sccharts/system/de.cau.cs.kieler.sccharts.SCTXToJSON.kico new file mode 100644 index 0000000000..7915b5d6d4 --- /dev/null +++ b/plugins/de.cau.cs.kieler.sccharts/system/de.cau.cs.kieler.sccharts.SCTXToJSON.kico @@ -0,0 +1,4 @@ +public system de.cau.cs.kieler.sccharts.SCTXToJSON + label "JSON Generation" + +de.cau.cs.kieler.sccharts.processors.SCTXToJSON From 1ca0a31796f4480c7bf0d9f7a8c83ef8c40dc2f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20M=C3=A4ckelmann?= Date: Thu, 21 May 2026 10:39:35 +0200 Subject: [PATCH 02/10] Updated JSON generation to updated schema --- .../sccharts/processors/json/Action.java | 16 ---- .../sccharts/processors/json/Region.java | 14 ---- .../sccharts/processors/json/SCTXToJSON.xtend | 7 +- .../sccharts/processors/json/State.java | 49 ++++++++----- .../sccharts/processors/json/Transition.java | 73 +++++++++++++------ .../sccharts/processors/json/Variable.java | 46 ++++++++---- 6 files changed, 116 insertions(+), 89 deletions(-) diff --git a/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/Action.java b/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/Action.java index e53d30e65a..a710a9fbab 100644 --- a/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/Action.java +++ b/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/Action.java @@ -41,22 +41,6 @@ public class Action { @Expose private String action; - /** - * No args constructor for use in serialization - * - */ - public Action() { - } - - public Action(String label, Action.Type type, boolean isImmediate, String guard, String action) { - super(); - this.label = label; - this.type = type; - this.isImmediate = isImmediate; - this.guard = guard; - this.action = action; - } - public String getLabel() { return label; } diff --git a/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/Region.java b/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/Region.java index b9494bf651..82f49b3617 100644 --- a/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/Region.java +++ b/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/Region.java @@ -29,20 +29,6 @@ public class Region { @Expose private List states; - /** - * No args constructor for use in serialization - * - */ - public Region() { - } - - public Region(String id, String label, List states) { - super(); - this.id = id; - this.label = label; - this.states = states; - } - /** * * (Required) diff --git a/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/SCTXToJSON.xtend b/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/SCTXToJSON.xtend index d7561b6900..197fd17037 100644 --- a/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/SCTXToJSON.xtend +++ b/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/SCTXToJSON.xtend @@ -146,7 +146,12 @@ public class SCTXToJSON extends Processor { transformed.label = transition.label transformed.targetID = transition.targetState.name transformed.isImmediate = transition.delay.equals(DelayType.IMMEDIATE) - transformed.isTermination = transition.preemption.equals(PreemptionType.TERMINATION) + transformed.preemption = switch(transition.preemption) { + case PreemptionType.TERMINATION: de.cau.cs.kieler.sccharts.processors.json.Transition.Preemption.TERMINATION + case PreemptionType.STRONG: de.cau.cs.kieler.sccharts.processors.json.Transition.Preemption.STRONG + case PreemptionType.WEAK: de.cau.cs.kieler.sccharts.processors.json.Transition.Preemption.WEAK + case PreemptionType.UNDEFINED: de.cau.cs.kieler.sccharts.processors.json.Transition.Preemption.WEAK + } transformed.guard = Optional.ofNullable(transition.trigger).map[expr_serializer.serialize(it)].map[toString].orElse(null) transformed.action = String.valueOf(effect_serializer.serialize(transition.effects)) diff --git a/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/State.java b/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/State.java index 6c04b4bc4d..a741669486 100644 --- a/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/State.java +++ b/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/State.java @@ -20,6 +20,11 @@ public class State { @SerializedName("label") @Expose private String label; + /** + * + * (Required) + * + */ @SerializedName("actions") @Expose private List actions; @@ -31,6 +36,11 @@ public class State { @SerializedName("transitions") @Expose private List transitions; + /** + * + * (Required) + * + */ @SerializedName("variables") @Expose private List variables; @@ -59,25 +69,6 @@ public class State { @Expose private List regions; - /** - * No args constructor for use in serialization - * - */ - public State() { - } - - public State(String id, String label, List actions, List transitions, List variables, boolean isInitial, boolean isFinal, List regions) { - super(); - this.id = id; - this.label = label; - this.actions = actions; - this.transitions = transitions; - this.variables = variables; - this.isInitial = isInitial; - this.isFinal = isFinal; - this.regions = regions; - } - /** * * (Required) @@ -104,10 +95,20 @@ public void setLabel(String label) { this.label = label; } + /** + * + * (Required) + * + */ public List getActions() { return actions; } + /** + * + * (Required) + * + */ public void setActions(List actions) { this.actions = actions; } @@ -130,10 +131,20 @@ public void setTransitions(List transitions) { this.transitions = transitions; } + /** + * + * (Required) + * + */ public List getVariables() { return variables; } + /** + * + * (Required) + * + */ public void setVariables(List variables) { this.variables = variables; } diff --git a/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/Transition.java b/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/Transition.java index 5317854f32..eba7baa65e 100644 --- a/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/Transition.java +++ b/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/Transition.java @@ -1,6 +1,8 @@ package de.cau.cs.kieler.sccharts.processors.json; +import java.util.HashMap; +import java.util.Map; import javax.annotation.processing.Generated; import com.google.gson.annotations.Expose; import com.google.gson.annotations.SerializedName; @@ -32,9 +34,9 @@ public class Transition { * (Required) * */ - @SerializedName("isTermination") + @SerializedName("preemption") @Expose - private boolean isTermination; + private Transition.Preemption preemption; @SerializedName("guard") @Expose private String guard; @@ -42,23 +44,6 @@ public class Transition { @Expose private String action; - /** - * No args constructor for use in serialization - * - */ - public Transition() { - } - - public Transition(String label, String targetID, boolean isImmediate, boolean isTermination, String guard, String action) { - super(); - this.label = label; - this.targetID = targetID; - this.isImmediate = isImmediate; - this.isTermination = isTermination; - this.guard = guard; - this.action = action; - } - public String getLabel() { return label; } @@ -108,8 +93,8 @@ public void setIsImmediate(boolean isImmediate) { * (Required) * */ - public boolean isIsTermination() { - return isTermination; + public Transition.Preemption getPreemption() { + return preemption; } /** @@ -117,8 +102,8 @@ public boolean isIsTermination() { * (Required) * */ - public void setIsTermination(boolean isTermination) { - this.isTermination = isTermination; + public void setPreemption(Transition.Preemption preemption) { + this.preemption = preemption; } public String getGuard() { @@ -137,4 +122,46 @@ public void setAction(String action) { this.action = action; } + @Generated("jsonschema2pojo") + public enum Preemption { + + @SerializedName("strong") + STRONG("strong"), + @SerializedName("weak") + WEAK("weak"), + @SerializedName("termination") + TERMINATION("termination"); + private final String value; + private final static Map CONSTANTS = new HashMap(); + + static { + for (Transition.Preemption c: values()) { + CONSTANTS.put(c.value, c); + } + } + + Preemption(String value) { + this.value = value; + } + + @Override + public String toString() { + return this.value; + } + + public String value() { + return this.value; + } + + public static Transition.Preemption fromValue(String value) { + Transition.Preemption constant = CONSTANTS.get(value); + if (constant == null) { + throw new IllegalArgumentException(value); + } else { + return constant; + } + } + + } + } diff --git a/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/Variable.java b/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/Variable.java index 4c9ca7f0e8..8f0baac932 100644 --- a/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/Variable.java +++ b/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/Variable.java @@ -27,28 +27,22 @@ public class Variable { @SerializedName("initialValue") @Expose private Object initialValue; + /** + * + * (Required) + * + */ @SerializedName("isInput") @Expose private boolean isInput; - @SerializedName("isOutput") - @Expose - private boolean isOutput; - /** - * No args constructor for use in serialization + * + * (Required) * */ - public Variable() { - } - - public Variable(String id, String type, Object initialValue, boolean isInput, boolean isOutput) { - super(); - this.id = id; - this.type = type; - this.initialValue = initialValue; - this.isInput = isInput; - this.isOutput = isOutput; - } + @SerializedName("isOutput") + @Expose + private boolean isOutput; /** * @@ -94,18 +88,38 @@ public void setInitialValue(Object initialValue) { this.initialValue = initialValue; } + /** + * + * (Required) + * + */ public boolean isIsInput() { return isInput; } + /** + * + * (Required) + * + */ public void setIsInput(boolean isInput) { this.isInput = isInput; } + /** + * + * (Required) + * + */ public boolean isIsOutput() { return isOutput; } + /** + * + * (Required) + * + */ public void setIsOutput(boolean isOutput) { this.isOutput = isOutput; } From 9ba9f4b75cb4a61b50ff3e4c17bbd62139a9ad09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20M=C3=A4ckelmann?= Date: Tue, 16 Jun 2026 13:09:16 +0200 Subject: [PATCH 03/10] Ensure that all regions and states have names in the produced json --- .../sccharts/processors/json/SCTXToJSON.xtend | 161 ++++++++++++------ 1 file changed, 111 insertions(+), 50 deletions(-) diff --git a/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/SCTXToJSON.xtend b/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/SCTXToJSON.xtend index 197fd17037..b1d4727474 100644 --- a/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/SCTXToJSON.xtend +++ b/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/SCTXToJSON.xtend @@ -12,7 +12,7 @@ */ package de.cau.cs.kieler.sccharts.processors.json; -import java.util.Map; +import java.util.Set; import de.cau.cs.kieler.kicool.compilation.CodeContainer; import de.cau.cs.kieler.kicool.compilation.Processor; @@ -33,22 +33,28 @@ import java.util.LinkedList import de.cau.cs.kieler.kexpressions.VariableDeclaration import de.cau.cs.kieler.kexpressions.ValuedObject import de.cau.cs.kieler.kexpressions.ValueType +import java.util.HashSet /** * */ public class SCTXToJSON extends Processor { - + @Inject private KEffectsSerializeExtensions effect_serializer; @Inject private KExpressionsSerializeExtensions expr_serializer; + int regionCounter = 0; + int stateCounter = 0; + + val String namePrefix = "" + + Set scopeNames = new HashSet(); /** * {@inheritDoc} */ - override String getId() { return "de.cau.cs.kieler.sccharts.processors.SCTXToJSON"; } @@ -60,7 +66,6 @@ public class SCTXToJSON extends Processor { return "SCTX to JSON"; } - /** * {@inheritDoc} */ @@ -73,25 +78,72 @@ public class SCTXToJSON extends Processor { */ override void process() { val cc = new CodeContainer(); - + val gson = new GsonBuilder().setPrettyPrinting().create(); + this.sourceModel.rootStates.forEach[renameState] val transformedRoots = this.sourceModel.rootStates.map[transformState]; val fileName = this.sourceModel.name?.hostcodeSafeName ?: "scchart" - + cc.add(fileName + ".json", gson.toJson(transformedRoots)); this.setModel(cc); - + + } + + def void renameState(de.cau.cs.kieler.sccharts.State state) { + val name = if (state.name.nullOrEmpty) { + // Generate a name with a running number if no state name is set + namePrefix + '_stateS' + (stateCounter++) + } else { + var new_name = namePrefix + state.name.hostcodeSafeName + + // Ensure the name is really unique + while (scopeNames.contains(new_name)) { + new_name = namePrefix + state.name.hostcodeSafeName + (stateCounter++) + } + new_name + } + scopeNames.add(name); + + state.name = name + + state.regions.forEach[renameRegion] } - + + def void renameRegion(de.cau.cs.kieler.sccharts.Region region) { + val name = if (region.name.nullOrEmpty) { + // Generate a name with a running number if no region name is set + namePrefix + '_regionR' + (regionCounter++) + } else { + var new_name = namePrefix + region.name.hostcodeSafeName + + // Ensure the name is really unique + while (scopeNames.contains(new_name)) { + new_name = namePrefix + region.name.hostcodeSafeName + (regionCounter++) + } + new_name + } + scopeNames.add(name) + + region.name = name + + switch (region) { + ControlflowRegion: { + region.states.forEach[renameState] + } + default: { + } + } + } + def de.cau.cs.kieler.sccharts.processors.json.Region transformRegion(de.cau.cs.kieler.sccharts.Region region) { - + switch (region) { ControlflowRegion: { val transformed = new de.cau.cs.kieler.sccharts.processors.json.Region() transformed.id = region.name; transformed.label = region.label; transformed.states = region.states.map[transformState] - + transformed } default: { @@ -99,13 +151,12 @@ public class SCTXToJSON extends Processor { null } } - } - - + } + def de.cau.cs.kieler.sccharts.processors.json.State transformState(de.cau.cs.kieler.sccharts.State state) { - + val transformed = new de.cau.cs.kieler.sccharts.processors.json.State(); - + transformed.id = state.name transformed.label = state.label transformed.actions = state.actions.map[transformAction] @@ -114,77 +165,87 @@ public class SCTXToJSON extends Processor { transformed.isInitial = state.isInitial() transformed.isFinal = state.isFinal() transformed.regions = state.regions.map[transformRegion] - + return transformed } - + def de.cau.cs.kieler.sccharts.processors.json.Action transformAction(de.cau.cs.kieler.sccharts.LocalAction action) { val transformed = new de.cau.cs.kieler.sccharts.processors.json.Action() - + transformed.label = action.label transformed.type = switch (action) { - de.cau.cs.kieler.sccharts.DuringAction: Action.Type.DURING - de.cau.cs.kieler.sccharts.EntryAction: Action.Type.ENTRY - de.cau.cs.kieler.sccharts.ExitAction: Action.Type.EXIT + de.cau.cs.kieler.sccharts.DuringAction: + Action.Type.DURING + de.cau.cs.kieler.sccharts.EntryAction: + Action.Type.ENTRY + de.cau.cs.kieler.sccharts.ExitAction: + Action.Type.EXIT default: { environment.errors.add("Cannot handle action %s of type %s.".format(action.label, action.class.name)) - + null } } - + transformed.isImmediate = action.delay.equals(DelayType.IMMEDIATE) - transformed.guard = Optional.ofNullable(action.trigger).map[expr_serializer.serialize(it)].map[toString].orElse(null) + transformed.guard = Optional.ofNullable(action.trigger).map[expr_serializer.serialize(it)].map[toString]. + orElse(null) transformed.action = String.valueOf(effect_serializer.serialize(action.effects)) - + return transformed } - - def de.cau.cs.kieler.sccharts.processors.json.Transition transformTransition(de.cau.cs.kieler.sccharts.Transition transition) { + + def de.cau.cs.kieler.sccharts.processors.json.Transition transformTransition( + de.cau.cs.kieler.sccharts.Transition transition) { val transformed = new de.cau.cs.kieler.sccharts.processors.json.Transition() - + transformed.label = transition.label transformed.targetID = transition.targetState.name transformed.isImmediate = transition.delay.equals(DelayType.IMMEDIATE) - transformed.preemption = switch(transition.preemption) { - case PreemptionType.TERMINATION: de.cau.cs.kieler.sccharts.processors.json.Transition.Preemption.TERMINATION - case PreemptionType.STRONG: de.cau.cs.kieler.sccharts.processors.json.Transition.Preemption.STRONG - case PreemptionType.WEAK: de.cau.cs.kieler.sccharts.processors.json.Transition.Preemption.WEAK - case PreemptionType.UNDEFINED: de.cau.cs.kieler.sccharts.processors.json.Transition.Preemption.WEAK + transformed.preemption = switch (transition.preemption) { + case PreemptionType.TERMINATION: de.cau.cs.kieler.sccharts.processors.json.Transition.Preemption.TERMINATION + case PreemptionType.STRONG: de.cau.cs.kieler.sccharts.processors.json.Transition.Preemption.STRONG + case PreemptionType.WEAK: de.cau.cs.kieler.sccharts.processors.json.Transition.Preemption.WEAK + case PreemptionType.UNDEFINED: de.cau.cs.kieler.sccharts.processors.json.Transition.Preemption.WEAK } - transformed.guard = Optional.ofNullable(transition.trigger).map[expr_serializer.serialize(it)].map[toString].orElse(null) - transformed.action = String.valueOf(effect_serializer.serialize(transition.effects)) - + transformed.guard = Optional.ofNullable(transition.trigger).map[expr_serializer.serialize(it)].map[toString]. + orElse(null) + transformed.action = String.valueOf(effect_serializer.serialize(transition.effects)) + return transformed } - + def List transformDeclaration(Declaration declaration) { switch (declaration) { - VariableDeclaration: declaration.valuedObjects.map[ - transformVariable(it, declaration.type, declaration.input, declaration.output) - ] + VariableDeclaration: + declaration.valuedObjects.map [ + transformVariable(it, declaration.type, declaration.input, declaration.output) + ] default: { - environment.errors.add("Cannot handle declaration %s of type %s.".format(declaration.toString(), declaration.class.name)) + environment.errors.add( + "Cannot handle declaration %s of type %s.".format(declaration.toString(), declaration.class.name)) new LinkedList() } } - + } - - def de.cau.cs.kieler.sccharts.processors.json.Variable transformVariable(ValuedObject v, ValueType t, boolean isInput, boolean isOutput) { + + def de.cau.cs.kieler.sccharts.processors.json.Variable transformVariable(ValuedObject v, ValueType t, + boolean isInput, boolean isOutput) { val transformed = new de.cau.cs.kieler.sccharts.processors.json.Variable() - + transformed.id = v.name transformed.type = t.literal - transformed.initialValue = Optional.ofNullable(v.initialValue).map[expr_serializer.serialize(it)].map[toString].orElse(null) + transformed.initialValue = Optional.ofNullable(v.initialValue).map[expr_serializer.serialize(it)].map[toString]. + orElse(null) transformed.isInput = isInput transformed.isOutput = isOutput - + return transformed } - + protected def hostcodeSafeName(String string) { - if (string === null) return "" - string.replaceAll("[\\s-]","_") + if(string === null) return "" + string.replaceAll("[\\s-]", "_") } } From a442733e4cb116a669b9a11c9ee213913eefed32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20M=C3=A4ckelmann?= Date: Tue, 30 Jun 2026 18:22:21 +0200 Subject: [PATCH 04/10] Added support for encoding connector and referenced states Also some code cleanup --- .../sccharts/processors/json/Reference.java | 76 +++++++++++++++++++ .../sccharts/processors/json/SCTXToJSON.xtend | 39 ++++++---- .../sccharts/processors/json/State.java | 37 +++++++++ 3 files changed, 139 insertions(+), 13 deletions(-) create mode 100644 plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/Reference.java diff --git a/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/Reference.java b/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/Reference.java new file mode 100644 index 0000000000..c33d950c5b --- /dev/null +++ b/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/Reference.java @@ -0,0 +1,76 @@ + +package de.cau.cs.kieler.sccharts.processors.json; + +import java.util.List; +import javax.annotation.processing.Generated; +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +@Generated("jsonschema2pojo") +public class Reference { + + /** + * + * (Required) + * + */ + @SerializedName("targetID") + @Expose + private String targetID; + @SerializedName("targetFile") + @Expose + private String targetFile; + /** + * + * (Required) + * + */ + @SerializedName("parameters") + @Expose + private List parameters; + + /** + * + * (Required) + * + */ + public String getTargetID() { + return targetID; + } + + /** + * + * (Required) + * + */ + public void setTargetID(String targetID) { + this.targetID = targetID; + } + + public String getTargetFile() { + return targetFile; + } + + public void setTargetFile(String targetFile) { + this.targetFile = targetFile; + } + + /** + * + * (Required) + * + */ + public List getParameters() { + return parameters; + } + + /** + * + * (Required) + * + */ + public void setParameters(List parameters) { + this.parameters = parameters; + } + +} diff --git a/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/SCTXToJSON.xtend b/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/SCTXToJSON.xtend index b1d4727474..b6ba9e46bd 100644 --- a/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/SCTXToJSON.xtend +++ b/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/SCTXToJSON.xtend @@ -1,6 +1,6 @@ /* * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient - * + * * http://rtsys.informatik.uni-kiel.de/kieler * * Copyright ${year} by @@ -34,6 +34,9 @@ import de.cau.cs.kieler.kexpressions.VariableDeclaration import de.cau.cs.kieler.kexpressions.ValuedObject import de.cau.cs.kieler.kexpressions.ValueType import java.util.HashSet +import de.cau.cs.kieler.sccharts.extensions.SCChartsCoreExtensions +import de.cau.cs.kieler.sccharts.extensions.SCChartsTransitionExtensions +import com.google.gson.Strictness /** * @@ -41,10 +44,13 @@ import java.util.HashSet public class SCTXToJSON extends Processor { @Inject - private KEffectsSerializeExtensions effect_serializer; + extension SCChartsCoreExtensions; @Inject - private KExpressionsSerializeExtensions expr_serializer; - + extension SCChartsTransitionExtensions; + @Inject + extension KEffectsSerializeExtensions; +// @Inject +// extension KExpressionsSerializeExtensions; int regionCounter = 0; int stateCounter = 0; @@ -79,7 +85,7 @@ public class SCTXToJSON extends Processor { override void process() { val cc = new CodeContainer(); - val gson = new GsonBuilder().setPrettyPrinting().create(); + val gson = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create(); this.sourceModel.rootStates.forEach[renameState] val transformedRoots = this.sourceModel.rootStates.map[transformState]; val fileName = this.sourceModel.name?.hostcodeSafeName ?: "scchart" @@ -164,8 +170,18 @@ public class SCTXToJSON extends Processor { transformed.variables = state.declarations.flatMap[transformDeclaration].toList transformed.isInitial = state.isInitial() transformed.isFinal = state.isFinal() + transformed.isConnector = state.connector transformed.regions = state.regions.map[transformRegion] + if (state.reference !== null) { + transformed.reference = new Reference(); + transformed.reference.targetID = state.reference.target?.name + // TODO: maybe add structure to the binding. + transformed.reference.parameters = state.reference.parameters.map [ + it.explicitBinding.serialize + " to " + it.expression.serialize + ] + } + return transformed } @@ -188,9 +204,8 @@ public class SCTXToJSON extends Processor { } transformed.isImmediate = action.delay.equals(DelayType.IMMEDIATE) - transformed.guard = Optional.ofNullable(action.trigger).map[expr_serializer.serialize(it)].map[toString]. - orElse(null) - transformed.action = String.valueOf(effect_serializer.serialize(action.effects)) + transformed.guard = Optional.ofNullable(action.trigger).map[serialize].map[toString].orElse(null) + transformed.action = String.valueOf(action.effects.serialize()) return transformed } @@ -208,9 +223,8 @@ public class SCTXToJSON extends Processor { case PreemptionType.WEAK: de.cau.cs.kieler.sccharts.processors.json.Transition.Preemption.WEAK case PreemptionType.UNDEFINED: de.cau.cs.kieler.sccharts.processors.json.Transition.Preemption.WEAK } - transformed.guard = Optional.ofNullable(transition.trigger).map[expr_serializer.serialize(it)].map[toString]. - orElse(null) - transformed.action = String.valueOf(effect_serializer.serialize(transition.effects)) + transformed.guard = Optional.ofNullable(transition.trigger).map[serialize].map[toString].orElse(null) + transformed.action = String.valueOf(transition.effects.serialize) return transformed } @@ -236,8 +250,7 @@ public class SCTXToJSON extends Processor { transformed.id = v.name transformed.type = t.literal - transformed.initialValue = Optional.ofNullable(v.initialValue).map[expr_serializer.serialize(it)].map[toString]. - orElse(null) + transformed.initialValue = Optional.ofNullable(v.initialValue).map[serialize].map[toString].orElse(null) transformed.isInput = isInput transformed.isOutput = isOutput diff --git a/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/State.java b/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/State.java index a741669486..569db889f8 100644 --- a/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/State.java +++ b/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/State.java @@ -60,6 +60,14 @@ public class State { @SerializedName("isFinal") @Expose private boolean isFinal; + /** + * + * (Required) + * + */ + @SerializedName("isConnector") + @Expose + private boolean isConnector; /** * * (Required) @@ -68,6 +76,9 @@ public class State { @SerializedName("regions") @Expose private List regions; + @SerializedName("reference") + @Expose + private Reference reference; /** * @@ -185,6 +196,24 @@ public void setIsFinal(boolean isFinal) { this.isFinal = isFinal; } + /** + * + * (Required) + * + */ + public boolean isIsConnector() { + return isConnector; + } + + /** + * + * (Required) + * + */ + public void setIsConnector(boolean isConnector) { + this.isConnector = isConnector; + } + /** * * (Required) @@ -203,4 +232,12 @@ public void setRegions(List regions) { this.regions = regions; } + public Reference getReference() { + return reference; + } + + public void setReference(Reference reference) { + this.reference = reference; + } + } From 8d9d7b82a2e07cc1397128152fcf94a380441c75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20M=C3=A4ckelmann?= Date: Mon, 20 Jul 2026 12:15:41 +0200 Subject: [PATCH 05/10] Add history field to Transition and update SCTXToJSON for history handling --- .../sccharts/processors/json/SCTXToJSON.xtend | 13 ++++++++-- .../sccharts/processors/json/Transition.java | 26 +++++++++++++++++++ 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/SCTXToJSON.xtend b/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/SCTXToJSON.xtend index b6ba9e46bd..ae97f02b47 100644 --- a/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/SCTXToJSON.xtend +++ b/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/SCTXToJSON.xtend @@ -21,7 +21,6 @@ import de.cau.cs.kieler.sccharts.SCCharts; import de.cau.cs.kieler.sccharts.State; import com.google.gson.GsonBuilder import de.cau.cs.kieler.kexpressions.keffects.extensions.KEffectsSerializeExtensions -import de.cau.cs.kieler.kexpressions.extensions.KExpressionsSerializeExtensions import com.google.inject.Inject import de.cau.cs.kieler.kexpressions.Declaration import de.cau.cs.kieler.sccharts.ControlflowRegion @@ -36,7 +35,8 @@ import de.cau.cs.kieler.kexpressions.ValueType import java.util.HashSet import de.cau.cs.kieler.sccharts.extensions.SCChartsCoreExtensions import de.cau.cs.kieler.sccharts.extensions.SCChartsTransitionExtensions -import com.google.gson.Strictness + +import static extension java.lang.String.format /** * @@ -176,6 +176,7 @@ public class SCTXToJSON extends Processor { if (state.reference !== null) { transformed.reference = new Reference(); transformed.reference.targetID = state.reference.target?.name + transformed.reference.targetFile = state.reference.target?.eResource()?.URI?.toString // TODO: maybe add structure to the binding. transformed.reference.parameters = state.reference.parameters.map [ it.explicitBinding.serialize + " to " + it.expression.serialize @@ -223,6 +224,14 @@ public class SCTXToJSON extends Processor { case PreemptionType.WEAK: de.cau.cs.kieler.sccharts.processors.json.Transition.Preemption.WEAK case PreemptionType.UNDEFINED: de.cau.cs.kieler.sccharts.processors.json.Transition.Preemption.WEAK } + transformed.history = switch (transition.history) { + case RESET: false + case DEEP: true + case SHALLOW: { + environment.errors.add("Shallow history for transition %s is not supported. Changing to deep history.".format(transition.toString())); + true + } + } transformed.guard = Optional.ofNullable(transition.trigger).map[serialize].map[toString].orElse(null) transformed.action = String.valueOf(transition.effects.serialize) diff --git a/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/Transition.java b/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/Transition.java index eba7baa65e..0978dedf4c 100644 --- a/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/Transition.java +++ b/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/Transition.java @@ -37,6 +37,14 @@ public class Transition { @SerializedName("preemption") @Expose private Transition.Preemption preemption; + /** + * + * (Required) + * + */ + @SerializedName("history") + @Expose + private boolean history; @SerializedName("guard") @Expose private String guard; @@ -106,6 +114,24 @@ public void setPreemption(Transition.Preemption preemption) { this.preemption = preemption; } + /** + * + * (Required) + * + */ + public boolean isHistory() { + return history; + } + + /** + * + * (Required) + * + */ + public void setHistory(boolean history) { + this.history = history; + } + public String getGuard() { return guard; } From fc14ca4dc28473b55c01a947853d5584f728879a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20M=C3=A4ckelmann?= Date: Thu, 23 Jul 2026 18:02:11 +0200 Subject: [PATCH 06/10] Added conversion from traces to json --- .../sccharts/processors/json/SCTXToJSON.xtend | 2 + .../sccharts/processors/json/Variable.java | 25 +++ .../SimulationProcessorProvider.xtend | 3 +- .../providers/SimulationSystemProvider.xtend | 3 +- .../trace/ktrace/json/Assignment.java | 64 +++++++ .../simulation/trace/ktrace/json/Tick.java | 87 +++++++++ .../simulation/trace/ktrace/json/Trace.java | 39 ++++ .../trace/ktrace/json/TraceToJSON.xtend | 173 ++++++++++++++++++ .../de.cau.cs.kieler.ktrace.toJson.kico | 4 + 9 files changed, 398 insertions(+), 2 deletions(-) create mode 100644 plugins/de.cau.cs.kieler.simulation/src/de/cau/cs/kieler/simulation/trace/ktrace/json/Assignment.java create mode 100644 plugins/de.cau.cs.kieler.simulation/src/de/cau/cs/kieler/simulation/trace/ktrace/json/Tick.java create mode 100644 plugins/de.cau.cs.kieler.simulation/src/de/cau/cs/kieler/simulation/trace/ktrace/json/Trace.java create mode 100644 plugins/de.cau.cs.kieler.simulation/src/de/cau/cs/kieler/simulation/trace/ktrace/json/TraceToJSON.xtend create mode 100644 plugins/de.cau.cs.kieler.simulation/system/de.cau.cs.kieler.ktrace.toJson.kico diff --git a/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/SCTXToJSON.xtend b/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/SCTXToJSON.xtend index ae97f02b47..31feb07fae 100644 --- a/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/SCTXToJSON.xtend +++ b/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/SCTXToJSON.xtend @@ -83,6 +83,7 @@ public class SCTXToJSON extends Processor { * {@inheritDoc} */ override void process() { + val cc = new CodeContainer(); val gson = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create(); @@ -262,6 +263,7 @@ public class SCTXToJSON extends Processor { transformed.initialValue = Optional.ofNullable(v.initialValue).map[serialize].map[toString].orElse(null) transformed.isInput = isInput transformed.isOutput = isOutput + transformed.cardinalities = v.cardinalities?.map[serialize]?.map[Integer.parseInt(it.toString, 10)] ?: List.of() return transformed } diff --git a/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/Variable.java b/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/Variable.java index 8f0baac932..b8211e1e22 100644 --- a/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/Variable.java +++ b/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/Variable.java @@ -1,6 +1,8 @@ package de.cau.cs.kieler.sccharts.processors.json; +import java.util.List; + import javax.annotation.processing.Generated; import com.google.gson.annotations.Expose; import com.google.gson.annotations.SerializedName; @@ -43,6 +45,29 @@ public class Variable { @SerializedName("isOutput") @Expose private boolean isOutput; + + /** + * + * (Required) + * + */ + @SerializedName("cardinalities") + @Expose + private List cardinalities; + + /** + * @return the cardinalities + */ + public List getCardinalities() { + return cardinalities; + } + + /** + * @param cardinalities the cardinalities to set + */ + public void setCardinalities(List cardinalities) { + this.cardinalities = cardinalities; + } /** * diff --git a/plugins/de.cau.cs.kieler.simulation/src/de/cau/cs/kieler/simulation/providers/SimulationProcessorProvider.xtend b/plugins/de.cau.cs.kieler.simulation/src/de/cau/cs/kieler/simulation/providers/SimulationProcessorProvider.xtend index 306751a1c1..0be26c8928 100644 --- a/plugins/de.cau.cs.kieler.simulation/src/de/cau/cs/kieler/simulation/providers/SimulationProcessorProvider.xtend +++ b/plugins/de.cau.cs.kieler.simulation/src/de/cau/cs/kieler/simulation/providers/SimulationProcessorProvider.xtend @@ -37,7 +37,8 @@ class SimulationProcessorProvider implements IProcessorProvider { de.cau.cs.kieler.simulation.testing.processor.TraceSimulator, de.cau.cs.kieler.simulation.testing.processor.TestSuiteGenerator, de.cau.cs.kieler.simulation.testing.processor.SimpleSimulationBenchmarkRunner, - de.cau.cs.kieler.simulation.testing.processor.JsonBenchmarkRunner + de.cau.cs.kieler.simulation.testing.processor.JsonBenchmarkRunner, + de.cau.cs.kieler.simulation.trace.ktrace.json.TraceToJSON ] } diff --git a/plugins/de.cau.cs.kieler.simulation/src/de/cau/cs/kieler/simulation/providers/SimulationSystemProvider.xtend b/plugins/de.cau.cs.kieler.simulation/src/de/cau/cs/kieler/simulation/providers/SimulationSystemProvider.xtend index 251850f78a..4fbcb5ed80 100644 --- a/plugins/de.cau.cs.kieler.simulation/src/de/cau/cs/kieler/simulation/providers/SimulationSystemProvider.xtend +++ b/plugins/de.cau.cs.kieler.simulation/src/de/cau/cs/kieler/simulation/providers/SimulationSystemProvider.xtend @@ -31,7 +31,8 @@ class SimulationSystemProvider implements ISystemProvider { "system/de.cau.cs.kieler.simulation.c.kico", "system/de.cau.cs.kieler.simulation.java.kico", "system/de.cau.cs.kieler.simulation.benchmarks.csv.simple.kico", - "system/de.cau.cs.kieler.simulation.benchmarks.json.kico" + "system/de.cau.cs.kieler.simulation.benchmarks.json.kico", + "system/de.cau.cs.kieler.ktrace.toJson.kico" ] } diff --git a/plugins/de.cau.cs.kieler.simulation/src/de/cau/cs/kieler/simulation/trace/ktrace/json/Assignment.java b/plugins/de.cau.cs.kieler.simulation/src/de/cau/cs/kieler/simulation/trace/ktrace/json/Assignment.java new file mode 100644 index 0000000000..9e08b35484 --- /dev/null +++ b/plugins/de.cau.cs.kieler.simulation/src/de/cau/cs/kieler/simulation/trace/ktrace/json/Assignment.java @@ -0,0 +1,64 @@ + +package de.cau.cs.kieler.simulation.trace.ktrace.json; + +import javax.annotation.processing.Generated; +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +@Generated("jsonschema2pojo") +public class Assignment { + + /** + * + * (Required) + * + */ + @SerializedName("variableID") + @Expose + private String variableID; + /** + * + * (Required) + * + */ + @SerializedName("value") + @Expose + private Object value; + + /** + * + * (Required) + * + */ + public String getVariableID() { + return variableID; + } + + /** + * + * (Required) + * + */ + public void setVariableID(String variableID) { + this.variableID = variableID; + } + + /** + * + * (Required) + * + */ + public Object getValue() { + return value; + } + + /** + * + * (Required) + * + */ + public void setValue(Object value) { + this.value = value; + } + +} diff --git a/plugins/de.cau.cs.kieler.simulation/src/de/cau/cs/kieler/simulation/trace/ktrace/json/Tick.java b/plugins/de.cau.cs.kieler.simulation/src/de/cau/cs/kieler/simulation/trace/ktrace/json/Tick.java new file mode 100644 index 0000000000..42d33af0b3 --- /dev/null +++ b/plugins/de.cau.cs.kieler.simulation/src/de/cau/cs/kieler/simulation/trace/ktrace/json/Tick.java @@ -0,0 +1,87 @@ + +package de.cau.cs.kieler.simulation.trace.ktrace.json; + +import java.util.List; +import javax.annotation.processing.Generated; +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +@Generated("jsonschema2pojo") +public class Tick { + + /** + * + * (Required) + * + */ + @SerializedName("inputs") + @Expose + private List inputs; + /** + * + * (Required) + * + */ + @SerializedName("outputs") + @Expose + private List outputs; + @SerializedName("id") + @Expose + private String id; + @SerializedName("gotoID") + @Expose + private String gotoID; + + /** + * + * (Required) + * + */ + public List getInputs() { + return inputs; + } + + /** + * + * (Required) + * + */ + public void setInputs(List inputs) { + this.inputs = inputs; + } + + /** + * + * (Required) + * + */ + public List getOutputs() { + return outputs; + } + + /** + * + * (Required) + * + */ + public void setOutputs(List outputs) { + this.outputs = outputs; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getGotoID() { + return gotoID; + } + + public void setGotoID(String gotoID) { + this.gotoID = gotoID; + } + +} diff --git a/plugins/de.cau.cs.kieler.simulation/src/de/cau/cs/kieler/simulation/trace/ktrace/json/Trace.java b/plugins/de.cau.cs.kieler.simulation/src/de/cau/cs/kieler/simulation/trace/ktrace/json/Trace.java new file mode 100644 index 0000000000..5387b0aef4 --- /dev/null +++ b/plugins/de.cau.cs.kieler.simulation/src/de/cau/cs/kieler/simulation/trace/ktrace/json/Trace.java @@ -0,0 +1,39 @@ + +package de.cau.cs.kieler.simulation.trace.ktrace.json; + +import java.util.List; +import javax.annotation.processing.Generated; +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +@Generated("jsonschema2pojo") +public class Trace { + + /** + * + * (Required) + * + */ + @SerializedName("ticks") + @Expose + private List ticks; + + /** + * + * (Required) + * + */ + public List getTicks() { + return ticks; + } + + /** + * + * (Required) + * + */ + public void setTicks(List ticks) { + this.ticks = ticks; + } + +} diff --git a/plugins/de.cau.cs.kieler.simulation/src/de/cau/cs/kieler/simulation/trace/ktrace/json/TraceToJSON.xtend b/plugins/de.cau.cs.kieler.simulation/src/de/cau/cs/kieler/simulation/trace/ktrace/json/TraceToJSON.xtend new file mode 100644 index 0000000000..2e3afe1254 --- /dev/null +++ b/plugins/de.cau.cs.kieler.simulation/src/de/cau/cs/kieler/simulation/trace/ktrace/json/TraceToJSON.xtend @@ -0,0 +1,173 @@ +/* + * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient + * + * http://rtsys.informatik.uni-kiel.de/kieler + * + * Copyright ${year} by + * + Kiel University + * + Department of Computer Science + * + Real-Time and Embedded Systems Group + * + * This code is provided under the terms of the Eclipse Public License (EPL). + */ +package de.cau.cs.kieler.simulation.trace.ktrace.json; + +import com.google.gson.GsonBuilder +import com.google.gson.JsonNull +import com.google.inject.Inject +import de.cau.cs.kieler.kexpressions.BoolValue +import de.cau.cs.kieler.kexpressions.Expression +import de.cau.cs.kieler.kexpressions.FloatValue +import de.cau.cs.kieler.kexpressions.IntValue +import de.cau.cs.kieler.kexpressions.JsonArrayValue +import de.cau.cs.kieler.kexpressions.JsonObjectValue +import de.cau.cs.kieler.kexpressions.NullValue +import de.cau.cs.kieler.kexpressions.extensions.KExpressionsSerializeExtensions +import de.cau.cs.kieler.kexpressions.keffects.Effect +import de.cau.cs.kieler.kexpressions.keffects.extensions.KEffectsSerializeExtensions +import de.cau.cs.kieler.kicool.compilation.CodeContainer +import de.cau.cs.kieler.kicool.compilation.Processor +import de.cau.cs.kieler.kicool.compilation.ProcessorType +import de.cau.cs.kieler.simulation.trace.ktrace.TraceFile +import java.io.File + +import static extension java.lang.String.format +import de.cau.cs.kieler.kexpressions.VectorValue +import de.cau.cs.kieler.kexpressions.StringValue +import com.google.gson.JsonDeserializer +import com.google.gson.JsonElement +import java.lang.reflect.Type +import com.google.gson.JsonDeserializationContext +import com.google.gson.JsonParseException +import com.google.gson.JsonSerializer +import com.google.gson.JsonSerializationContext + +/** + * + */ +class TraceToJSON extends Processor { + + @Inject + extension KEffectsSerializeExtensions; + + /** + * {@inheritDoc} + */ + override String getId() { + return "de.cau.cs.kieler.ktrace.TraceToJSON"; + } + + /** + * {@inheritDoc} + */ + override String getName() { + return "Trace file to JSON"; + } + + /** + * {@inheritDoc} + */ + override ProcessorType getType() { + return ProcessorType.EXOGENOUS_TRANSFORMATOR; + } + + /** + * {@inheritDoc} + */ + override process() { + val cc = new CodeContainer(); + + // TODO: figure out how to make Explicit Null work. + val gson = new GsonBuilder().registerTypeAdapter(ExplicitNull, new JsonNullSerializer).setPrettyPrinting(). + disableHtmlEscaping().create(); + val transformedRoots = this.sourceModel.traces.map[transformTrace]; + val fileName = "trace" + + println("Processing Resource " + this.sourceModel.eResource) + + cc.add(fileName + ".json", gson.toJson(transformedRoots)); + this.setModel(cc); + } + + def de.cau.cs.kieler.simulation.trace.ktrace.json.Trace transformTrace( + de.cau.cs.kieler.simulation.trace.ktrace.Trace trace) { + val transformed = new de.cau.cs.kieler.simulation.trace.ktrace.json.Trace(); + + transformed.ticks = trace.ticks.map[transformTick] + + transformed + } + + def de.cau.cs.kieler.simulation.trace.ktrace.json.Tick transformTick( + de.cau.cs.kieler.simulation.trace.ktrace.Tick tick) { + val transformed = new de.cau.cs.kieler.simulation.trace.ktrace.json.Tick(); + + transformed.inputs = tick.inputs.map[transformEffect] + transformed.outputs = tick.outputs.map[transformEffect] + + transformed.id = tick.name + transformed.gotoID = tick.goto?.name + + transformed + } + + def de.cau.cs.kieler.simulation.trace.ktrace.json.Assignment transformEffect(Effect effect) { + switch (effect) { + de.cau.cs.kieler.kexpressions.keffects.Assignment: { + val transformed = new de.cau.cs.kieler.simulation.trace.ktrace.json.Assignment() + + transformed.variableID = effect.reference?.valuedObject?.name + if (transformed.variableID === null) { + environment.errors.add( + "Assignment %s has no target variable.".format(effect.serialize, effect.class.name)) + } + + transformed.value = effect.expression.tryExpressionToValue + + transformed + } + default: { + environment.errors.add( + "Cannot handle effect %s of type %s.".format(effect.serialize, effect.class.name)) + null + } + } + } + + protected def Object tryExpressionToValue(Expression assignee) { + switch (assignee) { + BoolValue: + assignee.value + IntValue: + assignee.value + FloatValue: + assignee.value + StringValue: + assignee.value + JsonArrayValue: + assignee.elements + JsonObjectValue: + assignee.membersMap + VectorValue: + assignee.values.map[tryExpressionToValue] + NullValue: + new ExplicitNull() + default: { + println("unexpected expression in trace of type " + assignee) + assignee.serialize.toString + } + } + } + +} + +class ExplicitNull { +} + +class JsonNullSerializer implements JsonSerializer { + + override serialize(ExplicitNull src, Type typeOfSrc, JsonSerializationContext context) { + JsonNull.INSTANCE + } + +} diff --git a/plugins/de.cau.cs.kieler.simulation/system/de.cau.cs.kieler.ktrace.toJson.kico b/plugins/de.cau.cs.kieler.simulation/system/de.cau.cs.kieler.ktrace.toJson.kico new file mode 100644 index 0000000000..7b6732d8a1 --- /dev/null +++ b/plugins/de.cau.cs.kieler.simulation/system/de.cau.cs.kieler.ktrace.toJson.kico @@ -0,0 +1,4 @@ +public system de.cau.cs.kieler.ktrace.toJSON + label "JSON Generation" + +de.cau.cs.kieler.ktrace.TraceToJSON From 62cea9dc7739358caf903b7f6761b231ecb10281 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20M=C3=A4ckelmann?= Date: Fri, 24 Jul 2026 16:26:16 +0200 Subject: [PATCH 07/10] added new compilation system with some pre-processing and extended trace json generation --- .../providers/SCChartsSystemProvider.xtend | 3 +- ...au.cs.kieler.sccharts.extended.toJSON.kico | 13 +++++ .../trace/ktrace/json/TraceToJSON.xtend | 53 ++++++++++++++++--- 3 files changed, 62 insertions(+), 7 deletions(-) create mode 100644 plugins/de.cau.cs.kieler.sccharts/system/de.cau.cs.kieler.sccharts.extended.toJSON.kico diff --git a/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/providers/SCChartsSystemProvider.xtend b/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/providers/SCChartsSystemProvider.xtend index 4da2d5a25a..630cb77022 100644 --- a/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/providers/SCChartsSystemProvider.xtend +++ b/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/providers/SCChartsSystemProvider.xtend @@ -69,7 +69,8 @@ class SCChartsSystemProvider implements ISystemProvider { "system/de.cau.cs.kieler.sccharts.simulation.priority.java.legacy.kico", "system/de.cau.cs.kieler.sccharts.simulation.tts.priority.java.legacy.kico", "system/de.cau.cs.kieler.sccharts.netlist.simulink.kico", - "system/de.cau.cs.kieler.sccharts.SCTXToJSON.kico" + "system/de.cau.cs.kieler.sccharts.SCTXToJSON.kico", + "system/de.cau.cs.kieler.sccharts.extended.toJSON.kico" ] } diff --git a/plugins/de.cau.cs.kieler.sccharts/system/de.cau.cs.kieler.sccharts.extended.toJSON.kico b/plugins/de.cau.cs.kieler.sccharts/system/de.cau.cs.kieler.sccharts.extended.toJSON.kico new file mode 100644 index 0000000000..86a52badb8 --- /dev/null +++ b/plugins/de.cau.cs.kieler.sccharts/system/de.cau.cs.kieler.sccharts.extended.toJSON.kico @@ -0,0 +1,13 @@ +public system de.cau.cs.kieler.sccharts.extended.toJSON + label "JSON generation with preprocessing" + +de.cau.cs.kieler.sccharts.processors.timedautomata + +[ label "SyncCharts" + de.cau.cs.kieler.sccharts.processors.^signal + de.cau.cs.kieler.sccharts.processors.suspend + de.cau.cs.kieler.sccharts.processors.countDelay + de.cau.cs.kieler.sccharts.processors.^pre +] + +de.cau.cs.kieler.sccharts.processors.SCTXToJSON diff --git a/plugins/de.cau.cs.kieler.simulation/src/de/cau/cs/kieler/simulation/trace/ktrace/json/TraceToJSON.xtend b/plugins/de.cau.cs.kieler.simulation/src/de/cau/cs/kieler/simulation/trace/ktrace/json/TraceToJSON.xtend index 2e3afe1254..c387f05932 100644 --- a/plugins/de.cau.cs.kieler.simulation/src/de/cau/cs/kieler/simulation/trace/ktrace/json/TraceToJSON.xtend +++ b/plugins/de.cau.cs.kieler.simulation/src/de/cau/cs/kieler/simulation/trace/ktrace/json/TraceToJSON.xtend @@ -41,6 +41,11 @@ import com.google.gson.JsonDeserializationContext import com.google.gson.JsonParseException import com.google.gson.JsonSerializer import com.google.gson.JsonSerializationContext +import de.cau.cs.kieler.kexpressions.keffects.Emission +import java.util.Map +import com.google.gson.JsonObject +import com.google.gson.Gson +import com.google.gson.JsonPrimitive /** * @@ -78,8 +83,8 @@ class TraceToJSON extends Processor { val cc = new CodeContainer(); // TODO: figure out how to make Explicit Null work. - val gson = new GsonBuilder().registerTypeAdapter(ExplicitNull, new JsonNullSerializer).setPrettyPrinting(). - disableHtmlEscaping().create(); + val gson = new GsonBuilder().registerTypeAdapter(Tick, new TickSerializer()).setPrettyPrinting(). + disableHtmlEscaping().serializeNulls().create(); val transformedRoots = this.sourceModel.traces.map[transformTrace]; val fileName = "trace" @@ -126,6 +131,27 @@ class TraceToJSON extends Processor { transformed } + Emission: { + val transformed = new de.cau.cs.kieler.simulation.trace.ktrace.json.Assignment() + transformed.variableID = effect.reference?.valuedObject?.name + if (transformed.variableID === null) { + environment.errors.add( + "Assignment %s has no target variable.".format(effect.serialize, effect.class.name)) + } + transformed.value = switch (effect.newValue) { + case null: + Map.of("present", true) + default: + Map.of( + "present", + true, + "value", + effect.newValue.serialize.toString + ) + } + + transformed + } default: { environment.errors.add( "Cannot handle effect %s of type %s.".format(effect.serialize, effect.class.name)) @@ -151,7 +177,7 @@ class TraceToJSON extends Processor { VectorValue: assignee.values.map[tryExpressionToValue] NullValue: - new ExplicitNull() + ExplicitNull.INSTANCE default: { println("unexpected expression in trace of type " + assignee) assignee.serialize.toString @@ -162,12 +188,27 @@ class TraceToJSON extends Processor { } class ExplicitNull { + public static final ExplicitNull INSTANCE = new ExplicitNull(); + + private new() {} } -class JsonNullSerializer implements JsonSerializer { +class TickSerializer implements JsonSerializer { + + override serialize(Tick src, Type typeOfSrc, JsonSerializationContext context) { + val obj = new JsonObject() + + obj.add("inputs", context.serialize(src.inputs)) + obj.add("outputs", context.serialize(src.outputs)) + + if (src.id !== null) { + obj.addProperty("id", src.id) + } + if (src.gotoID !== null) { + obj.addProperty("gotoID", src.gotoID) + } - override serialize(ExplicitNull src, Type typeOfSrc, JsonSerializationContext context) { - JsonNull.INSTANCE + return obj } } From 73bd41e83da194ba84f78537df7c660bcfb8b32f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20M=C3=A4ckelmann?= Date: Wed, 5 Aug 2026 13:55:32 +0200 Subject: [PATCH 08/10] Some small cleanup --- .../cs/kieler/sccharts/processors/json/SCTXToJSON.xtend | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/SCTXToJSON.xtend b/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/SCTXToJSON.xtend index 31feb07fae..2617f1ba68 100644 --- a/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/SCTXToJSON.xtend +++ b/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/SCTXToJSON.xtend @@ -206,7 +206,7 @@ public class SCTXToJSON extends Processor { } transformed.isImmediate = action.delay.equals(DelayType.IMMEDIATE) - transformed.guard = Optional.ofNullable(action.trigger).map[serialize].map[toString].orElse(null) + transformed.guard = action.trigger?.serialize?.toString transformed.action = String.valueOf(action.effects.serialize()) return transformed @@ -233,8 +233,8 @@ public class SCTXToJSON extends Processor { true } } - transformed.guard = Optional.ofNullable(transition.trigger).map[serialize].map[toString].orElse(null) - transformed.action = String.valueOf(transition.effects.serialize) + transformed.guard = transition.trigger?.serialize?.toString + transformed.action = if (!transition.effects.isEmpty()) transition.effects.serialize?.toString return transformed } @@ -260,7 +260,7 @@ public class SCTXToJSON extends Processor { transformed.id = v.name transformed.type = t.literal - transformed.initialValue = Optional.ofNullable(v.initialValue).map[serialize].map[toString].orElse(null) + transformed.initialValue = v.initialValue?.serialize?.toString transformed.isInput = isInput transformed.isOutput = isOutput transformed.cardinalities = v.cardinalities?.map[serialize]?.map[Integer.parseInt(it.toString, 10)] ?: List.of() From 5728fc3fb54bfcd0bef62ab838ccd13dbba3e47f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20M=C3=A4ckelmann?= Date: Fri, 7 Aug 2026 18:32:15 +0200 Subject: [PATCH 09/10] Small improvements to ktrace conversion --- .../trace/ktrace/json/TraceToJSON.xtend | 84 ++++++++++++++++--- 1 file changed, 71 insertions(+), 13 deletions(-) diff --git a/plugins/de.cau.cs.kieler.simulation/src/de/cau/cs/kieler/simulation/trace/ktrace/json/TraceToJSON.xtend b/plugins/de.cau.cs.kieler.simulation/src/de/cau/cs/kieler/simulation/trace/ktrace/json/TraceToJSON.xtend index c387f05932..f2aba40932 100644 --- a/plugins/de.cau.cs.kieler.simulation/src/de/cau/cs/kieler/simulation/trace/ktrace/json/TraceToJSON.xtend +++ b/plugins/de.cau.cs.kieler.simulation/src/de/cau/cs/kieler/simulation/trace/ktrace/json/TraceToJSON.xtend @@ -46,6 +46,8 @@ import java.util.Map import com.google.gson.JsonObject import com.google.gson.Gson import com.google.gson.JsonPrimitive +import de.cau.cs.kieler.kexpressions.OperatorExpression +import java.util.concurrent.StructuredTaskScope.Subtask.State /** * @@ -82,7 +84,6 @@ class TraceToJSON extends Processor { override process() { val cc = new CodeContainer(); - // TODO: figure out how to make Explicit Null work. val gson = new GsonBuilder().registerTypeAdapter(Tick, new TickSerializer()).setPrettyPrinting(). disableHtmlEscaping().serializeNulls().create(); val transformedRoots = this.sourceModel.traces.map[transformTrace]; @@ -121,7 +122,9 @@ class TraceToJSON extends Processor { de.cau.cs.kieler.kexpressions.keffects.Assignment: { val transformed = new de.cau.cs.kieler.simulation.trace.ktrace.json.Assignment() - transformed.variableID = effect.reference?.valuedObject?.name + transformed.variableID = effect.reference?.valuedObject?.name + effect.reference?.indices?.map [ + "[" + it.serialize + "]" + ].join() if (transformed.variableID === null) { environment.errors.add( "Assignment %s has no target variable.".format(effect.serialize, effect.class.name)) @@ -146,7 +149,7 @@ class TraceToJSON extends Processor { "present", true, "value", - effect.newValue.serialize.toString + effect.newValue.tryExpressionToValue ) } @@ -177,9 +180,70 @@ class TraceToJSON extends Processor { VectorValue: assignee.values.map[tryExpressionToValue] NullValue: - ExplicitNull.INSTANCE + null + OperatorExpression: + if (assignee.subExpressions.size != 1) { + environment.warnings.add("unexpected number of expressions in " + assignee) + assignee.serialize.toString + } else { + val subexpression = assignee.subExpressions.get(0).tryExpressionToValue + if (subexpression instanceof String) { + assignee.operator.literal + subexpression + } else if (subexpression instanceof Integer) { + switch (assignee.operator) { + case ADD: { + subexpression + } + case BITWISE_NOT: { + subexpression.bitwiseNot + } + case NOT: { + subexpression == 0 + } + case SUB: { + - subexpression + } + default: { + environment.warnings.add("unexpected unary expression with operator " + + assignee.operator.literal) + assignee.operator.literal + subexpression + } + } + } else if (subexpression instanceof Double) { + switch (assignee.operator) { + case ADD: { + subexpression + } + case NOT: { + subexpression == 0.0 + } + case SUB: { + - subexpression + } + default: { + environment.warnings.add("unexpected unary expression with operator " + + assignee.operator.literal) + assignee.operator.literal + subexpression + } + } + } else if (subexpression instanceof Boolean) { + switch (assignee.operator) { + case BITWISE_NOT: { + ! subexpression + } + case NOT: { + ! subexpression + } + default: { + environment.warnings.add("unexpected unary expression with operator " + + assignee.operator.literal) + assignee.operator.literal + subexpression + } + } + } + } default: { - println("unexpected expression in trace of type " + assignee) + environment.warnings.add("unexpected expression in trace of type " + assignee) assignee.serialize.toString } } @@ -187,20 +251,14 @@ class TraceToJSON extends Processor { } -class ExplicitNull { - public static final ExplicitNull INSTANCE = new ExplicitNull(); - - private new() {} -} - class TickSerializer implements JsonSerializer { override serialize(Tick src, Type typeOfSrc, JsonSerializationContext context) { val obj = new JsonObject() - + obj.add("inputs", context.serialize(src.inputs)) obj.add("outputs", context.serialize(src.outputs)) - + if (src.id !== null) { obj.addProperty("id", src.id) } From 87571767f5eb8bff994d4b79142d21d857a13d67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20M=C3=A4ckelmann?= Date: Mon, 10 Aug 2026 16:24:08 +0200 Subject: [PATCH 10/10] Fixed some bugs with the processing of referenced states --- .../sccharts/processors/json/SCTXToJSON.xtend | 138 ++++++++++++------ 1 file changed, 94 insertions(+), 44 deletions(-) diff --git a/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/SCTXToJSON.xtend b/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/SCTXToJSON.xtend index 2617f1ba68..230d01c4f0 100644 --- a/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/SCTXToJSON.xtend +++ b/plugins/de.cau.cs.kieler.sccharts/src/de/cau/cs/kieler/sccharts/processors/json/SCTXToJSON.xtend @@ -12,29 +12,33 @@ */ package de.cau.cs.kieler.sccharts.processors.json; -import java.util.Set; - -import de.cau.cs.kieler.kicool.compilation.CodeContainer; -import de.cau.cs.kieler.kicool.compilation.Processor; -import de.cau.cs.kieler.kicool.compilation.ProcessorType; -import de.cau.cs.kieler.sccharts.SCCharts; -import de.cau.cs.kieler.sccharts.State; import com.google.gson.GsonBuilder -import de.cau.cs.kieler.kexpressions.keffects.extensions.KEffectsSerializeExtensions import com.google.inject.Inject import de.cau.cs.kieler.kexpressions.Declaration +import de.cau.cs.kieler.kexpressions.ValueType +import de.cau.cs.kieler.kexpressions.ValuedObject +import de.cau.cs.kieler.kexpressions.VariableDeclaration +import de.cau.cs.kieler.kexpressions.keffects.extensions.KEffectsSerializeExtensions +import de.cau.cs.kieler.kicool.compilation.CodeContainer +import de.cau.cs.kieler.kicool.compilation.Processor +import de.cau.cs.kieler.kicool.compilation.ProcessorType import de.cau.cs.kieler.sccharts.ControlflowRegion import de.cau.cs.kieler.sccharts.DelayType +import de.cau.cs.kieler.sccharts.DuringAction +import de.cau.cs.kieler.sccharts.EntryAction +import de.cau.cs.kieler.sccharts.ExitAction +import de.cau.cs.kieler.sccharts.LocalAction import de.cau.cs.kieler.sccharts.PreemptionType -import java.util.Optional -import java.util.List -import java.util.LinkedList -import de.cau.cs.kieler.kexpressions.VariableDeclaration -import de.cau.cs.kieler.kexpressions.ValuedObject -import de.cau.cs.kieler.kexpressions.ValueType -import java.util.HashSet +import de.cau.cs.kieler.sccharts.Region +import de.cau.cs.kieler.sccharts.SCCharts +import de.cau.cs.kieler.sccharts.State import de.cau.cs.kieler.sccharts.extensions.SCChartsCoreExtensions +import de.cau.cs.kieler.sccharts.extensions.SCChartsReferenceExtensions import de.cau.cs.kieler.sccharts.extensions.SCChartsTransitionExtensions +import java.util.HashSet +import java.util.LinkedList +import java.util.List +import java.util.Set import static extension java.lang.String.format @@ -49,6 +53,9 @@ public class SCTXToJSON extends Processor { extension SCChartsTransitionExtensions; @Inject extension KEffectsSerializeExtensions; + @Inject + extension SCChartsReferenceExtensions; + // @Inject // extension KExpressionsSerializeExtensions; int regionCounter = 0; @@ -83,10 +90,11 @@ public class SCTXToJSON extends Processor { * {@inheritDoc} */ override void process() { - + val cc = new CodeContainer(); val gson = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create(); + this.sourceModel.rootStates.forEach[collectNames] this.sourceModel.rootStates.forEach[renameState] val transformedRoots = this.sourceModel.rootStates.map[transformState]; val fileName = this.sourceModel.name?.hostcodeSafeName ?: "scchart" @@ -96,7 +104,38 @@ public class SCTXToJSON extends Processor { } - def void renameState(de.cau.cs.kieler.sccharts.State state) { + /** + * Pre-populate the scopeNames set with names that should not be shadowed + * (i.e. everything that is part of the interface, like the referenced state or variable names. + */ + def void collectNames(State state) { + if (state.reference !== null) { + // TODO: if the target is in the same file as the referencing statement, this causes the target to be renamed + // in the renaming step. Not an issue, but weird. + scopeNames.add(state.reference.target.name.hostcodeSafeName) + } + + for (declaration : state.declarations) { + switch (declaration) { + VariableDeclaration: + declaration.valuedObjects.forEach [ + scopeNames.add(name) + ] + default: { + // Do nothing here + } + } + } + + // iterate down the tree + for (region : state.regions) { + if (region instanceof ControlflowRegion) { + region.states.forEach[collectNames] + } + } + } + + def void renameState(State state) { val name = if (state.name.nullOrEmpty) { // Generate a name with a running number if no state name is set namePrefix + '_stateS' + (stateCounter++) @@ -111,12 +150,15 @@ public class SCTXToJSON extends Processor { } scopeNames.add(name); - state.name = name + if (name != state.name) { + state.label = state.name + state.name = name + } state.regions.forEach[renameRegion] } - def void renameRegion(de.cau.cs.kieler.sccharts.Region region) { + def void renameRegion(Region region) { val name = if (region.name.nullOrEmpty) { // Generate a name with a running number if no region name is set namePrefix + '_regionR' + (regionCounter++) @@ -131,7 +173,10 @@ public class SCTXToJSON extends Processor { } scopeNames.add(name) - region.name = name + if (name != region.name) { + region.label = region.name + region.name = name + } switch (region) { ControlflowRegion: { @@ -142,7 +187,7 @@ public class SCTXToJSON extends Processor { } } - def de.cau.cs.kieler.sccharts.processors.json.Region transformRegion(de.cau.cs.kieler.sccharts.Region region) { + def de.cau.cs.kieler.sccharts.processors.json.Region transformRegion(Region region) { switch (region) { ControlflowRegion: { @@ -160,7 +205,7 @@ public class SCTXToJSON extends Processor { } } - def de.cau.cs.kieler.sccharts.processors.json.State transformState(de.cau.cs.kieler.sccharts.State state) { + def de.cau.cs.kieler.sccharts.processors.json.State transformState(State state) { val transformed = new de.cau.cs.kieler.sccharts.processors.json.State(); @@ -176,27 +221,30 @@ public class SCTXToJSON extends Processor { if (state.reference !== null) { transformed.reference = new Reference(); + val bindings = state.createBindings transformed.reference.targetID = state.reference.target?.name transformed.reference.targetFile = state.reference.target?.eResource()?.URI?.toString // TODO: maybe add structure to the binding. - transformed.reference.parameters = state.reference.parameters.map [ - it.explicitBinding.serialize + " to " + it.expression.serialize + transformed.reference.parameters = bindings.map [ + sourceExpression.serialize + " to " + targetValuedObject.serialize + targetIndices?.map [ + "[" + it.serialize + "]" + ].join() ] } return transformed } - def de.cau.cs.kieler.sccharts.processors.json.Action transformAction(de.cau.cs.kieler.sccharts.LocalAction action) { - val transformed = new de.cau.cs.kieler.sccharts.processors.json.Action() + def Action transformAction(LocalAction action) { + val transformed = new Action() transformed.label = action.label transformed.type = switch (action) { - de.cau.cs.kieler.sccharts.DuringAction: + DuringAction: Action.Type.DURING - de.cau.cs.kieler.sccharts.EntryAction: + EntryAction: Action.Type.ENTRY - de.cau.cs.kieler.sccharts.ExitAction: + ExitAction: Action.Type.EXIT default: { environment.errors.add("Cannot handle action %s of type %s.".format(action.label, action.class.name)) @@ -212,34 +260,37 @@ public class SCTXToJSON extends Processor { return transformed } - def de.cau.cs.kieler.sccharts.processors.json.Transition transformTransition( - de.cau.cs.kieler.sccharts.Transition transition) { - val transformed = new de.cau.cs.kieler.sccharts.processors.json.Transition() + def Transition transformTransition(de.cau.cs.kieler.sccharts.Transition transition) { + val transformed = new Transition() transformed.label = transition.label transformed.targetID = transition.targetState.name transformed.isImmediate = transition.delay.equals(DelayType.IMMEDIATE) transformed.preemption = switch (transition.preemption) { - case PreemptionType.TERMINATION: de.cau.cs.kieler.sccharts.processors.json.Transition.Preemption.TERMINATION - case PreemptionType.STRONG: de.cau.cs.kieler.sccharts.processors.json.Transition.Preemption.STRONG - case PreemptionType.WEAK: de.cau.cs.kieler.sccharts.processors.json.Transition.Preemption.WEAK - case PreemptionType.UNDEFINED: de.cau.cs.kieler.sccharts.processors.json.Transition.Preemption.WEAK + case PreemptionType.TERMINATION: Transition.Preemption.TERMINATION + case PreemptionType.STRONG: Transition.Preemption.STRONG + case PreemptionType.WEAK: Transition.Preemption.WEAK + case PreemptionType.UNDEFINED: Transition.Preemption.WEAK } transformed.history = switch (transition.history) { - case RESET: false - case DEEP: true + case RESET: + false + case DEEP: + true case SHALLOW: { - environment.errors.add("Shallow history for transition %s is not supported. Changing to deep history.".format(transition.toString())); + environment.errors.add( + "Shallow history for transition %s is not supported. Changing to deep history.".format( + transition.toString())); true } } transformed.guard = transition.trigger?.serialize?.toString - transformed.action = if (!transition.effects.isEmpty()) transition.effects.serialize?.toString + transformed.action = if(!transition.effects.isEmpty()) transition.effects.serialize?.toString return transformed } - def List transformDeclaration(Declaration declaration) { + def List transformDeclaration(Declaration declaration) { switch (declaration) { VariableDeclaration: declaration.valuedObjects.map [ @@ -254,9 +305,8 @@ public class SCTXToJSON extends Processor { } - def de.cau.cs.kieler.sccharts.processors.json.Variable transformVariable(ValuedObject v, ValueType t, - boolean isInput, boolean isOutput) { - val transformed = new de.cau.cs.kieler.sccharts.processors.json.Variable() + def Variable transformVariable(ValuedObject v, ValueType t, boolean isInput, boolean isOutput) { + val transformed = new Variable() transformed.id = v.name transformed.type = t.literal