Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHenrik Rentz-Reichert2018-04-30 12:37:58 -0400
committerHenrik Rentz-Reichert2018-06-08 07:53:10 -0400
commit29873f1151bb915cf3044f21deca9c756d3f95e0 (patch)
treedfb65025ce0f630a188baf879d0fd27c5e412cc9
parentd1dab866b5986c7e9ec36cdc1d9c9a6fde6d73c4 (diff)
downloadorg.eclipse.etrice-29873f1151bb915cf3044f21deca9c756d3f95e0.tar.gz
org.eclipse.etrice-29873f1151bb915cf3044f21deca9c756d3f95e0.tar.xz
org.eclipse.etrice-29873f1151bb915cf3044f21deca9c756d3f95e0.zip
Bug 534211 - unify Detail Code parsing
new scanner, parser and linker for detail code including tests * the scanner is tokenizing the text * the parser creates an AST * the linker associates Room objects to the AST nodes in a context dependent way * unit tests for scanner, parser and linker * a detail code translator is provided with a slightly changed interface to the translation provider Change-Id: I84075b6618dc0cedcec6e8da73520bf0a7bcaf90
-rw-r--r--features/org.eclipse.etrice.feature/feature.xml14
-rw-r--r--features/org.eclipse.etrice.fsm.feature/feature.xml7
-rw-r--r--features/org.eclipse.etrice.tests.feature/feature.xml6
-rw-r--r--plugins/org.eclipse.etrice.abstractexec.behavior/src/org/eclipse/etrice/abstractexec/behavior/ActionCodeAnalyzer.java6
-rw-r--r--plugins/org.eclipse.etrice.dctools.fsm/.classpath8
-rw-r--r--plugins/org.eclipse.etrice.dctools.fsm/.gitignore4
-rw-r--r--plugins/org.eclipse.etrice.dctools.fsm/.project34
-rw-r--r--plugins/org.eclipse.etrice.dctools.fsm/.settings/org.eclipse.jdt.core.prefs7
-rw-r--r--plugins/org.eclipse.etrice.dctools.fsm/META-INF/MANIFEST.MF20
-rw-r--r--plugins/org.eclipse.etrice.dctools.fsm/build.properties5
-rw-r--r--plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/CandidateMap.xtend20
-rw-r--r--plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/DCLanguage.xtend20
-rw-r--r--plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/DCParser.xtend365
-rw-r--r--plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/DCScanner.xtend100
-rw-r--r--plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/IFSMTranslationProvider.xtend83
-rw-r--r--plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/internal/DCBracketRule.xtend32
-rw-r--r--plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/internal/DCBracketToken.xtend53
-rw-r--r--plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/internal/DCIdentifierRule.xtend53
-rw-r--r--plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/internal/DCKeywordRule.xtend40
-rw-r--r--plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/internal/DCKeywords.xtend131
-rw-r--r--plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/internal/DCSpecialCharRule.xtend44
-rw-r--r--plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/internal/DCTextToken.xtend22
-rw-r--r--plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/internal/DCToken.xtend57
-rw-r--r--plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/internal/DCWhitespaceDetector.xtend23
-rw-r--r--plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/internal/DCWordDetector.xtend35
-rw-r--r--plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstArrayAccessNode.xtend27
-rw-r--r--plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstBracketNode.xtend72
-rw-r--r--plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstFeatureCallNode.xtend32
-rw-r--r--plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstIdentifierBracketNode.xtend55
-rw-r--r--plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstIdentifierNode.xtend35
-rw-r--r--plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstMatchNode.xtend24
-rw-r--r--plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstNode.xtend96
-rw-r--r--plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstOperationCallNode.xtend27
-rw-r--r--plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstOtherNode.xtend33
-rw-r--r--plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstPeriodNode.xtend26
-rw-r--r--plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstWhitespaceNode.xtend31
-rw-r--r--plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/util/DCAstPrinter.xtend48
-rw-r--r--plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/util/IDCAstNodeVisitor.xtend21
-rw-r--r--plugins/org.eclipse.etrice.dctools/.classpath8
-rw-r--r--plugins/org.eclipse.etrice.dctools/.gitignore4
-rw-r--r--plugins/org.eclipse.etrice.dctools/.project34
-rw-r--r--plugins/org.eclipse.etrice.dctools/.settings/org.eclipse.jdt.core.prefs7
-rw-r--r--plugins/org.eclipse.etrice.dctools/META-INF/MANIFEST.MF19
-rw-r--r--plugins/org.eclipse.etrice.dctools/build.properties5
-rw-r--r--plugins/org.eclipse.etrice.dctools/src/org/eclipse/etrice/dctools/ast/DCLinker.xtend277
-rw-r--r--plugins/org.eclipse.etrice.dctools/src/org/eclipse/etrice/dctools/ast/DCTranslator.xtend84
-rw-r--r--plugins/org.eclipse.etrice.dctools/src/org/eclipse/etrice/dctools/ast/ITranslationProvider.xtend112
-rw-r--r--plugins/org.eclipse.etrice.dctools/src/org/eclipse/etrice/dctools/ast/internal/DCTranslatorVisitor.xtend246
-rw-r--r--plugins/org.eclipse.etrice.expressions.ui/META-INF/MANIFEST.MF1
-rw-r--r--plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/CTranslationProvider.java12
-rw-r--r--plugins/org.eclipse.etrice.generator.cpp/src/org/eclipse/etrice/generator/cpp/gen/CppTranslationProvider.java4
-rw-r--r--plugins/org.eclipse.etrice.generator.fsm/src/org/eclipse/etrice/generator/fsm/base/DefaultFSMTranslationProvider.java6
-rw-r--r--plugins/org.eclipse.etrice.generator.fsm/src/org/eclipse/etrice/generator/fsm/base/IFSMTranslationProvider.java6
-rw-r--r--plugins/org.eclipse.etrice.generator.java/src/org/eclipse/etrice/generator/java/gen/JavaTranslationProvider.java6
-rw-r--r--plugins/org.eclipse.etrice.generator/src/org/eclipse/etrice/generator/base/DefaultTranslationProvider.java6
-rw-r--r--plugins/org.eclipse.etrice.generator/src/org/eclipse/etrice/generator/base/ITranslationProvider.java6
-rw-r--r--pom.xml3
-rw-r--r--releng/org.eclipse.etrice.parent/pom.xml8
-rw-r--r--tests/org.eclipse.etrice.core.genmodel.tests/org.eclipse.etrice.core.genmodel.tests.launch2
-rw-r--r--tests/org.eclipse.etrice.core.room.tests/META-INF/MANIFEST.MF3
-rw-r--r--tests/org.eclipse.etrice.core.room.tests/src-gen/org/eclipse/etrice/core/room/tests/RoomInjectorProvider.java8
-rw-r--r--tests/org.eclipse.etrice.core.room.tests/src/org/eclipse/etrice/core/FormatterTest.xtend8
-rw-r--r--tests/org.eclipse.etrice.core.room.tests/src/org/eclipse/etrice/core/TestNames.xtend2
-rw-r--r--tests/org.eclipse.etrice.dctools.tests/.classpath8
-rw-r--r--tests/org.eclipse.etrice.dctools.tests/.gitignore4
-rw-r--r--tests/org.eclipse.etrice.dctools.tests/.project34
-rw-r--r--tests/org.eclipse.etrice.dctools.tests/.settings/org.eclipse.jdt.core.prefs7
-rw-r--r--tests/org.eclipse.etrice.dctools.tests/META-INF/MANIFEST.MF24
-rw-r--r--tests/org.eclipse.etrice.dctools.tests/build.properties5
-rw-r--r--tests/org.eclipse.etrice.dctools.tests/models/DetailCodes.room103
-rw-r--r--tests/org.eclipse.etrice.dctools.tests/models/Types.room13
-rw-r--r--tests/org.eclipse.etrice.dctools.tests/models/diagrams/DCParserTests.AC.behavior184
-rw-r--r--tests/org.eclipse.etrice.dctools.tests/models/diagrams/DCParserTests.AC.structure70
-rw-r--r--tests/org.eclipse.etrice.dctools.tests/org.eclipse.etrice.dctools.tests - plugin-test.launch47
-rw-r--r--tests/org.eclipse.etrice.dctools.tests/src/org/eclipse/etrice/dctools/tests/DCToolsTestsActivator.java21
-rw-r--r--tests/org.eclipse.etrice.dctools.tests/src/org/eclipse/etrice/dctools/tests/TestConstants.xtend62
-rw-r--r--tests/org.eclipse.etrice.dctools.tests/src/org/eclipse/etrice/dctools/tests/TestDCLinker.xtend642
-rw-r--r--tests/org.eclipse.etrice.dctools.tests/src/org/eclipse/etrice/dctools/tests/TestDCParser.xtend408
-rw-r--r--tests/org.eclipse.etrice.dctools.tests/src/org/eclipse/etrice/dctools/tests/TestDCScanner.xtend304
-rw-r--r--tests/org.eclipse.etrice.dctools.tests/src/org/eclipse/etrice/dctools/tests/TestDCTranslator.xtend163
-rw-r--r--tests/org.eclipse.etrice.dctools.tests/src/org/eclipse/etrice/dctools/tests/TranslationProviderForTests.xtend125
-rw-r--r--tests/org.eclipse.etrice.etunit.converter.tests/org.eclipse.etrice.etunit.converter.tests.launch2
-rw-r--r--tests/org.eclipse.etrice.generator.tests/org.eclipse.etrice.generator.tests.launch2
-rw-r--r--tests/org.eclipse.etrice.generator.tests/src/org/eclipse/etrice/generator/base/TestDetailCodeTranslator.java12
-rw-r--r--tests/org.eclipse.etrice.ui.behavior.tests/org.eclipse.etrice.ui.behavior.tests.launch2
-rw-r--r--tests/org.eclipse.etrice.ui.structure.tests/org.eclipse.etrice.ui.structure.tests.launch2
86 files changed, 4789 insertions, 48 deletions
diff --git a/features/org.eclipse.etrice.feature/feature.xml b/features/org.eclipse.etrice.feature/feature.xml
index be56fabf3..38f929ce9 100644
--- a/features/org.eclipse.etrice.feature/feature.xml
+++ b/features/org.eclipse.etrice.feature/feature.xml
@@ -331,4 +331,18 @@ http://www.eclipse.org/legal/epl-v10.html
version="0.0.0"
unpack="false"/>
+ <plugin
+ id="org.eclipse.etrice.dctools.fsm"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.etrice.dctools"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
</feature>
diff --git a/features/org.eclipse.etrice.fsm.feature/feature.xml b/features/org.eclipse.etrice.fsm.feature/feature.xml
index dba7836a4..5c2da09f0 100644
--- a/features/org.eclipse.etrice.fsm.feature/feature.xml
+++ b/features/org.eclipse.etrice.fsm.feature/feature.xml
@@ -95,4 +95,11 @@ http://www.eclipse.org/legal/epl-v10.html
version="0.0.0"
unpack="false"/>
+ <plugin
+ id="org.eclipse.etrice.dctools.fsm"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
</feature>
diff --git a/features/org.eclipse.etrice.tests.feature/feature.xml b/features/org.eclipse.etrice.tests.feature/feature.xml
index 6adcc594a..70946640b 100644
--- a/features/org.eclipse.etrice.tests.feature/feature.xml
+++ b/features/org.eclipse.etrice.tests.feature/feature.xml
@@ -171,5 +171,11 @@ http://www.eclipse.org/legal/epl-v10.html
version="0.0.0"
unpack="false"/>
+ <plugin
+ id="org.eclipse.etrice.dctools.tests"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
</feature>
diff --git a/plugins/org.eclipse.etrice.abstractexec.behavior/src/org/eclipse/etrice/abstractexec/behavior/ActionCodeAnalyzer.java b/plugins/org.eclipse.etrice.abstractexec.behavior/src/org/eclipse/etrice/abstractexec/behavior/ActionCodeAnalyzer.java
index 538aa3374..ca742c5c0 100644
--- a/plugins/org.eclipse.etrice.abstractexec.behavior/src/org/eclipse/etrice/abstractexec/behavior/ActionCodeAnalyzer.java
+++ b/plugins/org.eclipse.etrice.abstractexec.behavior/src/org/eclipse/etrice/abstractexec/behavior/ActionCodeAnalyzer.java
@@ -32,16 +32,16 @@ public class ActionCodeAnalyzer {
private ArrayList<HandledMessage> mifs = new ArrayList<HandledMessage>();
- public ArrayList<HandledMessage> getMifs() {
+ public List<HandledMessage> getMifs() {
return mifs;
}
/* (non-Javadoc)
- * @see org.eclipse.etrice.generator.base.DefaultTranslationProvider#getInterfaceItemMessageText(org.eclipse.etrice.core.room.InterfaceItem, org.eclipse.etrice.core.room.Message, java.util.ArrayList, java.lang.String, java.lang.String)
+ * @see org.eclipse.etrice.generator.base.DefaultTranslationProvider#getInterfaceItemMessageText(org.eclipse.etrice.core.room.InterfaceItem, org.eclipse.etrice.core.room.Message, java.util.List, java.lang.String, java.lang.String)
*/
@Override
public String getInterfaceItemMessageText(AbstractInterfaceItem item,
- EObject msg, ArrayList<String> args, String index, String orig) {
+ EObject msg, List<String> args, String index, String orig) {
HandledMessage sm = new HandledMessage(item, msg, origin);
mifs.add(sm);
diff --git a/plugins/org.eclipse.etrice.dctools.fsm/.classpath b/plugins/org.eclipse.etrice.dctools.fsm/.classpath
new file mode 100644
index 000000000..428337e56
--- /dev/null
+++ b/plugins/org.eclipse.etrice.dctools.fsm/.classpath
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="src" path="xtend-gen"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/plugins/org.eclipse.etrice.dctools.fsm/.gitignore b/plugins/org.eclipse.etrice.dctools.fsm/.gitignore
new file mode 100644
index 000000000..1a7726dc2
--- /dev/null
+++ b/plugins/org.eclipse.etrice.dctools.fsm/.gitignore
@@ -0,0 +1,4 @@
+bin
+*._trace
+*.smap
+*.xtendbin
diff --git a/plugins/org.eclipse.etrice.dctools.fsm/.project b/plugins/org.eclipse.etrice.dctools.fsm/.project
new file mode 100644
index 000000000..8fe3f91ab
--- /dev/null
+++ b/plugins/org.eclipse.etrice.dctools.fsm/.project
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.etrice.dctools.fsm</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.xtext.ui.shared.xtextBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.eclipse.xtext.ui.shared.xtextNature</nature>
+ </natures>
+</projectDescription>
diff --git a/plugins/org.eclipse.etrice.dctools.fsm/.settings/org.eclipse.jdt.core.prefs b/plugins/org.eclipse.etrice.dctools.fsm/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 000000000..0c68a61dc
--- /dev/null
+++ b/plugins/org.eclipse.etrice.dctools.fsm/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.8
diff --git a/plugins/org.eclipse.etrice.dctools.fsm/META-INF/MANIFEST.MF b/plugins/org.eclipse.etrice.dctools.fsm/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..88e3030b2
--- /dev/null
+++ b/plugins/org.eclipse.etrice.dctools.fsm/META-INF/MANIFEST.MF
@@ -0,0 +1,20 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Detail Code Tools for FSM
+Bundle-SymbolicName: org.eclipse.etrice.dctools.fsm
+Bundle-Version: 1.1.1.qualifier
+Automatic-Module-Name: org.eclipse.etrice.dctools.fsm
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
+Bundle-Vendor: Eclipse eTrice
+Require-Bundle: org.eclipse.jface.text,
+ org.eclipse.xtext.xbase.lib;bundle-version="2.6.0",
+ org.eclipse.xtend.lib;bundle-version="2.6.0",
+ org.eclipse.xtend.lib.macro;bundle-version="2.6.0",
+ org.eclipse.xtext.ui,
+ org.eclipse.etrice.core.fsm,
+ org.eclipse.etrice.generator
+Export-Package: org.eclipse.etrice.dctools.fsm.ast,
+ org.eclipse.etrice.dctools.fsm.ast.internal;x-friends:="org.eclipse.etrice.dctools.tests",
+ org.eclipse.etrice.dctools.fsm.ast.nodes,
+ org.eclipse.etrice.dctools.fsm.ast.util
+
diff --git a/plugins/org.eclipse.etrice.dctools.fsm/build.properties b/plugins/org.eclipse.etrice.dctools.fsm/build.properties
new file mode 100644
index 000000000..d8e2f0e92
--- /dev/null
+++ b/plugins/org.eclipse.etrice.dctools.fsm/build.properties
@@ -0,0 +1,5 @@
+source.. = src/,\
+ xtend-gen/
+output.. = bin/
+bin.includes = META-INF/,\
+ .
diff --git a/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/CandidateMap.xtend b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/CandidateMap.xtend
new file mode 100644
index 000000000..178ad0200
--- /dev/null
+++ b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/CandidateMap.xtend
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ * Copyright (c) 2011 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * CONTRIBUTORS:
+ * Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.dctools.fsm.ast
+
+import java.util.HashMap
+import org.eclipse.emf.ecore.EObject
+
+class CandidateMap extends HashMap<String, EObject> {
+
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/DCLanguage.xtend b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/DCLanguage.xtend
new file mode 100644
index 000000000..c02887dbf
--- /dev/null
+++ b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/DCLanguage.xtend
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ * Copyright (c) 2018 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * CONTRIBUTORS:
+ * Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.dctools.fsm.ast
+
+enum DCLanguage {
+ C_LANGUAGE,
+ CPP_LANGUAGE,
+ JAVA_LANGUAGE,
+ OTHER_LANGUAGE
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/DCParser.xtend b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/DCParser.xtend
new file mode 100644
index 000000000..d2c554a4d
--- /dev/null
+++ b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/DCParser.xtend
@@ -0,0 +1,365 @@
+/*******************************************************************************
+ * Copyright (c) 2018 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * CONTRIBUTORS:
+ * Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.dctools.fsm.ast
+
+import java.util.ArrayList
+import org.eclipse.etrice.dctools.fsm.ast.internal.DCBracketToken
+import org.eclipse.etrice.dctools.fsm.ast.internal.DCBracketToken.BracketKind
+import org.eclipse.etrice.dctools.fsm.ast.internal.DCTextToken
+import org.eclipse.etrice.dctools.fsm.ast.internal.DCToken.Kind
+import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstArrayAccessNode
+import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstBracketNode
+import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstBracketNode.BracketType
+import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstFeatureCallNode
+import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstIdentifierBracketNode
+import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstIdentifierNode
+import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstMatchNode
+import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstNode
+import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstOperationCallNode
+import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstOtherNode
+import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstPeriodNode
+import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstWhitespaceNode
+
+/**
+ *
+ * Grammar:
+ *
+ * PartialMatch: BracketExpression | FeatureCall
+ *
+ * BracketExpression: RoundBracketExpression | CurlyBracketExpression | SquareBracketExpression
+ * RoundBracketExpression: LEFT_ROUNDBRACKET Match RIGHT_ROUNDBRACKET
+ * CurlyBracketExpression: LEFT_CURLYBRACKET Match RIGHT_CORLYBRACKET
+ * SquareBracketExpression: LEFT_SQUAREBRACKET Match RIGHT_SQUAREBRACKET
+ *
+ * FeatureCall: Call Whitespace (PERIOD Whitespace Call Whitespace)*
+ * Call: ArrayAccess | OperationCall | IDENTIFIER
+ * ArrayAccess: IDENTIFIER Whitespace SquareBracketExpression
+ * OperationCall: IDENTIFIER Whitespace RoundBracketExpression
+ *
+ * Whitespace: WHITESPACE*
+ *
+ * Match: (PartialMatch* Other)*
+ *
+ * Other: *
+ */
+class DCParser {
+
+ val DCScanner scanner
+ String text
+ ArrayList<DCTextToken> tokens
+ int currentPosition = 0
+
+ new(DCLanguage language) {
+ scanner = new DCScanner(language)
+ }
+
+ def parse(String text) {
+ this.text = text
+ this.tokens = scanner.scan(text)
+
+ Match(null)
+ }
+
+ /*
+ * rules
+ */
+ private def DCAstMatchNode Match(DCAstNode parent) {
+ val mNode = new DCAstMatchNode(parent)
+
+ var continue = true
+ while (continue) {
+ while (PartialMatch(mNode)!==null) {}
+ if (Other(mNode)===null) {
+ continue = false
+ }
+ }
+
+ return mNode
+ }
+
+ private def DCAstOtherNode Other(DCAstNode parent) {
+ var DCAstOtherNode lastNode = null
+ var token = read
+
+ if (token!==null) {
+ while (token!==null) {
+ if (stopOther(token)) {
+ unread
+ token = null
+ }
+ else {
+ // we consumed a token
+ lastNode = new DCAstOtherNode(parent, text.substring(token.begin, token.begin + token.length), token)
+
+ // do we have a partial match after that token?
+ val pNode = PartialMatch(null)
+ if (pNode!==null) {
+ unread(pNode)
+ token = null
+ }
+ else {
+ token = read
+ }
+ }
+ }
+ }
+
+ return lastNode
+ }
+
+ private def boolean stopOther(DCTextToken token) {
+ if (token.token instanceof DCBracketToken) {
+ return true
+ }
+ if (token.token.kind==Kind.IDENTIFIER) {
+ return true
+ }
+ return false
+ }
+
+ private def DCAstNode PartialMatch(DCAstNode parent) {
+ var node = ConcreteBracketExpression(parent) as DCAstNode
+ if (node===null) {
+ node = FeatureCall(parent)
+ }
+ return node
+ }
+
+ private def DCAstBracketNode ConcreteBracketExpression(DCAstNode parent) {
+ var node = RoundBracketExpression(parent)
+ if (node===null) {
+ node = CurlyBracketExpression(parent)
+ }
+ if (node===null) {
+ node = SquareBracketExpression(parent)
+ }
+ return node
+ }
+
+ private def DCAstBracketNode RoundBracketExpression(DCAstNode parent) {
+ return ConcreteBracketExpression(parent, BracketKind.LEFT_ROUND, BracketKind.RIGHT_ROUND, BracketType.ROUND)
+ }
+
+ private def DCAstBracketNode CurlyBracketExpression(DCAstNode parent) {
+ return ConcreteBracketExpression(parent, BracketKind.LEFT_CURLY, BracketKind.RIGHT_CURLY, BracketType.CURLY)
+ }
+
+ private def DCAstBracketNode SquareBracketExpression(DCAstNode parent) {
+ return ConcreteBracketExpression(parent, BracketKind.LEFT_SQUARE, BracketKind.RIGHT_SQUARE, BracketType.SQUARE)
+ }
+
+ private def DCAstBracketNode ConcreteBracketExpression(DCAstNode parent, BracketKind left, BracketKind right, BracketType type) {
+ var token = read
+
+ if (token!==null) {
+ if (token.token instanceof DCBracketToken) {
+ var b = token.token as DCBracketToken
+ if (b.bracketKind==left) {
+ val contents = Match(parent)
+ token = read
+ if (token!==null) {
+ if (token.token instanceof DCBracketToken) {
+ b = token.token as DCBracketToken
+ if (b.bracketKind==right) {
+ return new DCAstBracketNode(parent, type, contents)
+ }
+ }
+ unread // second token
+ }
+ else {
+ // we reached the end without a matching right bracket
+ return new DCAstBracketNode(parent, type, contents, false)
+ }
+ unread(contents)
+ }
+ }
+ unread // first token
+ }
+
+ return null
+ }
+
+ private def DCAstFeatureCallNode FeatureCall(DCAstNode parent) {
+ val callNode = Call(parent)
+
+ if (callNode!==null) {
+ val fcNode = new DCAstFeatureCallNode(parent)
+ callNode.parent = fcNode
+
+ // optional whitespace
+ Whitespace(fcNode)
+
+ // (PERIOD Whitespace Call)*
+ var token = read
+ while (token!==null) {
+ if (token.token.kind==Kind.PERIOD) {
+ val pNode = new DCAstPeriodNode(null)
+ val wsNode = Whitespace(null)
+ val cNode = Call(null)
+ val wsNode2 = Whitespace(null)
+ if (pNode!==null) {
+ pNode.parent = fcNode
+ if (wsNode!==null) {
+ wsNode.parent = fcNode
+ }
+ if (cNode!==null) {
+ cNode.parent = fcNode
+ }
+ if (wsNode2!==null) {
+ wsNode2.parent = fcNode
+ }
+
+ if (cNode!==null) {
+ // next token
+ token = read
+ }
+ else {
+ token = null
+ }
+ }
+ else {
+ unread(pNode)
+ unread(wsNode)
+ unread(pNode)
+ unread(wsNode2)
+ unread // the token itself
+ token = null
+ }
+ }
+ else {
+ unread // the token itself
+ token = null
+ }
+ }
+
+ return fcNode
+ }
+
+ unread(callNode)
+
+ return null
+ }
+
+ private def DCAstNode Call(DCAstNode parent) {
+ // try ArrayAccess
+ var node = BracketExpressionCall(parent, [SquareBracketExpression], [p, i, w, b| new DCAstArrayAccessNode(p, i, w, b)])
+ if (node===null) {
+ // try OperationCall
+ node = BracketExpressionCall(parent, [RoundBracketExpression], [p, i, w, b| new DCAstOperationCallNode(p, i, w, b)])
+ }
+ if (node!==null) {
+ return node
+ }
+ else {
+ // try IDENTIFIER
+ val token = read
+ if (token!==null) {
+ if (token.token.kind==Kind.IDENTIFIER) {
+ val id = text.substring(token.begin, token.begin + token.length)
+ return new DCAstIdentifierNode(parent, id, token)
+ }
+ unread
+ }
+ }
+ return null
+ }
+
+ private def DCAstIdentifierBracketNode BracketExpressionCall(
+ DCAstNode parent,
+ (DCAstNode)=>DCAstBracketNode bracketExpression,
+ (DCAstNode, DCAstIdentifierNode, DCAstWhitespaceNode, DCAstBracketNode)=>DCAstIdentifierBracketNode factory
+ ) {
+ val token = read
+ if (token!==null) {
+ if (token.token.kind==Kind.IDENTIFIER) {
+ // first child is ID
+ val id = text.substring(token.begin, token.begin + token.length)
+ val idNode = new DCAstIdentifierNode(parent, id, token)
+
+ // optional whitespace
+ val wsNode = Whitespace(parent)
+
+ // second child is BracketExpression
+ val node = bracketExpression.apply(parent)
+ if (node!==null) {
+ // the node of the bracket expression call
+ val callNode = factory.apply(parent, idNode, wsNode, node)
+ return callNode
+ }
+
+ unread(idNode)
+ unread(wsNode)
+ }
+ else {
+ unread
+ }
+ }
+
+ return null
+ }
+
+ private def DCAstWhitespaceNode Whitespace(DCAstNode parent) {
+ var token = read
+ val begin = if (token!==null) token.begin else 0
+ var int end = 0
+ var count = 0
+ while (token!==null) {
+ if (token.token.kind==Kind.WHITESPACE) {
+ end = token.begin + token.length
+ count++
+ token = read
+ }
+ else {
+ token = null
+ unread
+ }
+ }
+
+ if (count>0) {
+ val ws = text.substring(begin, end)
+ return new DCAstWhitespaceNode(parent, count, ws)
+ }
+
+ return null
+ }
+
+ /*
+ * helpers
+ */
+ private def DCTextToken read() {
+ if (currentPosition<tokens.size) {
+ tokens.get(currentPosition++)
+ }
+ else {
+ null
+ }
+ }
+
+ private def void unread() {
+ unread(1)
+ }
+
+ private def void unread(int i) {
+ currentPosition = currentPosition - i
+ if (currentPosition<0) {
+ println("oops")
+ }
+ }
+
+ private def void unread(DCAstNode node) {
+ if (node!==null) {
+ node.parent = null
+ unread(node.totallyReadTokens)
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/DCScanner.xtend b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/DCScanner.xtend
new file mode 100644
index 000000000..d228afe9a
--- /dev/null
+++ b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/DCScanner.xtend
@@ -0,0 +1,100 @@
+/*******************************************************************************
+ * Copyright (c) 2018 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * CONTRIBUTORS:
+ * Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.dctools.fsm.ast
+
+import com.google.common.collect.Iterables
+import org.eclipse.etrice.dctools.fsm.ast.internal.DCKeywordRule
+import org.eclipse.etrice.dctools.fsm.ast.internal.DCToken
+import org.eclipse.etrice.dctools.fsm.ast.internal.DCToken.Kind
+import org.eclipse.etrice.dctools.fsm.ast.internal.DCWhitespaceDetector
+import org.eclipse.jface.text.rules.EndOfLineRule
+import org.eclipse.jface.text.rules.IRule
+import org.eclipse.jface.text.rules.MultiLineRule
+import org.eclipse.jface.text.rules.NumberRule
+import org.eclipse.jface.text.rules.RuleBasedScanner
+import org.eclipse.jface.text.rules.SingleLineRule
+import org.eclipse.jface.text.rules.WhitespaceRule
+import org.eclipse.etrice.dctools.fsm.ast.internal.DCIdentifierRule
+import org.eclipse.etrice.dctools.fsm.ast.internal.DCBracketRule
+import org.eclipse.etrice.dctools.fsm.ast.internal.DCSpecialCharRule
+import org.eclipse.jface.text.rules.IToken
+import org.eclipse.jface.text.rules.Token
+import org.eclipse.etrice.dctools.fsm.ast.internal.DCTextToken
+import org.eclipse.jface.text.Document
+
+class DCScanner {
+
+ val RuleBasedScanner scanner = new RuleBasedScanner
+ DCLanguage language
+
+ new(DCLanguage language) {
+ this.language = language
+
+ // initialize scanner with rules
+ scanner.rules = rules
+ }
+
+ def scan(String text) {
+ val result = newArrayList
+
+ scanner.setRange(new Document(text), 0, text.length())
+
+ var IToken lastToken = null
+ while (lastToken !== Token.EOF) {
+ lastToken = scanner.nextToken()
+ if (lastToken !== null) {
+ val begin = scanner.tokenOffset
+ val end = begin + scanner.tokenLength
+ if (begin >= 0 && begin < end) {
+ if (lastToken instanceof DCToken) {
+ result.add(new DCTextToken(begin, scanner.tokenLength, lastToken))
+ }
+ else {
+ result.add(new DCTextToken(begin, scanner.tokenLength, new DCToken(Kind.OTHER)))
+ }
+ }
+ }
+ }
+
+ return result
+ }
+
+ private def getRules() {
+ val rules = newArrayList
+
+ // rules for comments (also unclosed C-comments)
+ rules.add(new EndOfLineRule("//", new DCToken(Kind.COMMENT)))
+ rules.add(new MultiLineRule("/*", "*/", new DCToken(Kind.COMMENT), 0 as char, true))
+
+ // rules for strings
+ rules.add(new SingleLineRule("\"", "\"", new DCToken(Kind.STRING), '\\'))
+ rules.add(new SingleLineRule("'", "'", new DCToken(Kind.STRING), '\\'))
+ // multiline or unclosed strings (which may occur during editing)
+ rules.add(new MultiLineRule("\"", "\"", new DCToken(Kind.STRING), '\\', true))
+ rules.add(new MultiLineRule("'", "'", new DCToken(Kind.STRING), '\\', true))
+
+ // keywords, numbers and IDs
+ rules.add(new NumberRule(new DCToken(Kind.NUMBER)))
+ if (language!==DCLanguage.OTHER_LANGUAGE) {
+ rules.add(new DCKeywordRule(language))
+ }
+ rules.add(new DCIdentifierRule)
+
+ // whitespace, brackets and special characters
+ rules.add(new WhitespaceRule(new DCWhitespaceDetector, new DCToken(Kind.WHITESPACE)))
+ rules.add(new DCBracketRule)
+ rules.add(new DCSpecialCharRule)
+
+ Iterables.toArray(rules, IRule)
+ }
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/IFSMTranslationProvider.xtend b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/IFSMTranslationProvider.xtend
new file mode 100644
index 000000000..89de4130d
--- /dev/null
+++ b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/IFSMTranslationProvider.xtend
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright (c) 2011 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * CONTRIBUTORS:
+ * Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.dctools.fsm.ast
+
+import org.eclipse.emf.ecore.EObject
+import org.eclipse.etrice.core.fsm.fSM.AbstractInterfaceItem
+import org.eclipse.etrice.core.fsm.fSM.DetailCode
+import org.eclipse.etrice.core.fsm.fSM.ModelComponent
+
+/**
+ * @author Henrik Rentz-Reichert
+ *
+ */
+interface IFSMTranslationProvider {
+
+ /**
+ * start sequence for tags to be translated
+ */
+ public static final String TAG_START="<|"
+
+ /**
+ * end sequence for tags to be translated
+ */
+ public static final String TAG_END="|>"
+
+ /**
+ * the container class for which translations have to be provided.
+ * This can be either of
+ * <ul>
+ * <li>{@link ModelComponent}</li>
+ * <li>DataClass</li>
+ * <li>ProtocolClass</li>
+ * <li>PortClass</li>
+ * </ul>
+ * @param container
+ */
+ def void setContainerClass(EObject container)
+
+ /**
+ * @return true if translation should be applied to members (attributes, operations and port.msg)
+ */
+ def boolean translateMembers()
+
+ /**
+ * yield a sequence that sends a message through an interface item (port or SAP).
+ * Is called whenever <i>port</i>.<i>msg</i>(<i>args</i>)
+ * or <i>port</i>[<i>index</i>].<i>msg</i>(<i>args</i>) is found in the detail code
+ * @param item the interface item
+ * @param msg the message to send
+ * @param ifitem the pointer of the interface item
+ * @param args the message parameters
+ * @param index array index for replicated ports, should be null for simple ports
+ * and may be null for broadcast through replicated port
+ * @param orig the original text
+ * @return the translation
+ */
+ def String getInterfaceItemMessageText(AbstractInterfaceItem item, EObject msg, String ifitem, String args, String index, String orig)
+
+ /**
+ * @return true if translations are provided for tags
+ */
+ def boolean translateTags()
+
+ /**
+ * yield a replacement for a tag. Is called whenever &lt;|<i>tag</i>|>
+ * is found in the detail code
+ * @param tag the tag name
+ * @param code the detail code containing the tag
+ * @return the translated tag
+ */
+ def String translateTag(String tag, DetailCode code)
+
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/internal/DCBracketRule.xtend b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/internal/DCBracketRule.xtend
new file mode 100644
index 000000000..8faf2654f
--- /dev/null
+++ b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/internal/DCBracketRule.xtend
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2018 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * CONTRIBUTORS:
+ * Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.dctools.fsm.ast.internal
+
+import org.eclipse.jface.text.rules.IRule
+import org.eclipse.jface.text.rules.ICharacterScanner
+import org.eclipse.jface.text.rules.Token
+
+class DCBracketRule implements IRule {
+
+ override evaluate(ICharacterScanner scanner) {
+ val c = scanner.read
+ val token = DCBracketToken.getToken(c as char)
+ if (token!==null) {
+ return token
+ }
+
+ scanner.unread
+ return Token.UNDEFINED
+ }
+
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/internal/DCBracketToken.xtend b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/internal/DCBracketToken.xtend
new file mode 100644
index 000000000..03341f329
--- /dev/null
+++ b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/internal/DCBracketToken.xtend
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2018 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * CONTRIBUTORS:
+ * Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.dctools.fsm.ast.internal
+
+import org.eclipse.etrice.dctools.fsm.ast.internal.DCBracketToken.BracketKind
+import org.eclipse.xtend.lib.annotations.Data
+
+@Data
+class DCBracketToken extends DCToken {
+
+ enum BracketKind {
+ LEFT_ROUND, RIGHT_ROUND,
+ LEFT_CURLY, RIGHT_CURLY,
+ LEFT_SQUARE, RIGHT_SQUARE
+ }
+
+ static val leftRoundBracket = new DCBracketToken(BracketKind.LEFT_ROUND)
+ static val rightRoundBracket = new DCBracketToken(BracketKind.RIGHT_ROUND)
+ static val leftCurlyBracket = new DCBracketToken(BracketKind.LEFT_CURLY)
+ static val rightCurlyBracket = new DCBracketToken(BracketKind.RIGHT_CURLY)
+ static val leftSquareBracket = new DCBracketToken(BracketKind.LEFT_SQUARE)
+ static val rightSquareBracket = new DCBracketToken(BracketKind.RIGHT_SQUARE)
+
+ static val char2token = #{
+ Character.valueOf('(') -> leftRoundBracket,
+ Character.valueOf(')') -> rightRoundBracket,
+ Character.valueOf('{') -> leftCurlyBracket,
+ Character.valueOf('}') -> rightCurlyBracket,
+ Character.valueOf('[') -> leftSquareBracket,
+ Character.valueOf(']') -> rightSquareBracket
+ }
+
+ BracketKind bracketKind
+
+ private new(BracketKind bk) {
+ super(Kind.BRACKET)
+ this.bracketKind = bk
+ }
+
+ static def getToken(char c) {
+ char2token.get(c)
+ }
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/internal/DCIdentifierRule.xtend b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/internal/DCIdentifierRule.xtend
new file mode 100644
index 000000000..936af2ddb
--- /dev/null
+++ b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/internal/DCIdentifierRule.xtend
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2018 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * CONTRIBUTORS:
+ * Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.dctools.fsm.ast.internal
+
+import org.eclipse.etrice.dctools.fsm.ast.internal.DCToken.Kind
+import org.eclipse.jface.text.rules.ICharacterScanner
+import org.eclipse.jface.text.rules.IRule
+import org.eclipse.jface.text.rules.Token
+
+class DCIdentifierRule implements IRule {
+
+ val detector = new DCWordDetector
+ val token = new DCToken(Kind.IDENTIFIER)
+ val buffer= new StringBuffer
+
+ override evaluate(ICharacterScanner scanner) {
+ buffer.setLength(0)
+
+ var c = scanner.read
+ if (c != ICharacterScanner.EOF && detector.isWordStart(c as char)) {
+ do {
+ buffer.append(c as char)
+ c = scanner.read()
+ }
+ while (c != ICharacterScanner.EOF && detector.isWordPart(c as char))
+ scanner.unread
+
+ val id = buffer.toString
+ if (!id.empty) {
+ return token
+ }
+ }
+ else {
+ scanner.unread
+ }
+
+ for (var i= buffer.length() - 1; i >= 0; i--) {
+ scanner.unread
+ }
+ return Token.UNDEFINED
+ }
+
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/internal/DCKeywordRule.xtend b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/internal/DCKeywordRule.xtend
new file mode 100644
index 000000000..aba6941dc
--- /dev/null
+++ b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/internal/DCKeywordRule.xtend
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2018 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * CONTRIBUTORS:
+ * Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.dctools.fsm.ast.internal
+
+import org.eclipse.etrice.dctools.fsm.ast.internal.DCToken.Kind
+import org.eclipse.jface.text.rules.WordRule
+import org.eclipse.etrice.dctools.fsm.ast.internal.DCKeywords
+import org.eclipse.etrice.dctools.fsm.ast.DCLanguage
+
+class DCKeywordRule extends WordRule {
+
+ val keywordToken = new DCToken(Kind.KEYWORD)
+
+ new(org.eclipse.etrice.dctools.fsm.ast.DCLanguage language) {
+ super(new DCWordDetector(language.isCFamily))
+
+ switch language {
+ case C_LANGUAGE: DCKeywords.CKeywords.forEach[addWord(keywordToken)]
+ case CPP_LANGUAGE: DCKeywords.cppKeywords.forEach[addWord(keywordToken)]
+ case JAVA_LANGUAGE: DCKeywords.javaKeywords.forEach[addWord(keywordToken)]
+ default: {
+ // ignore
+ }
+ }
+ }
+
+ static def isCFamily(org.eclipse.etrice.dctools.fsm.ast.DCLanguage language) {
+ language==DCLanguage.C_LANGUAGE || language==DCLanguage.CPP_LANGUAGE
+ }
+}
diff --git a/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/internal/DCKeywords.xtend b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/internal/DCKeywords.xtend
new file mode 100644
index 000000000..259006b0b
--- /dev/null
+++ b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/internal/DCKeywords.xtend
@@ -0,0 +1,131 @@
+/*******************************************************************************
+ * Copyright (c) 2018 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * CONTRIBUTORS:
+ * Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.dctools.fsm.ast.internal
+
+class DCKeywords {
+
+ static String[] cKeywords=#[
+ "const",
+ "unsigned",
+ "sizeof",
+ "typedef",
+ "virtual",
+ "struct",
+ "union",
+ "sizeof",
+ "explicit",
+ "export",
+ "extern",
+ "goto",
+ "register",
+
+ // preprocessor
+ "#include",
+ "#define",
+ "#ifdef",
+ "#endif",
+ "#if",
+ "#else",
+ "#ifndef",
+ "#undef",
+ "#pragma"
+ ]
+ static String[] cppKeywords=#[
+ "mutable",
+ "friend",
+ "inline",
+ "typeid",
+ "typename",
+ "namespace",
+ "class",
+ "using",
+ "template",
+ "this",
+
+ // exceptions
+ "throw",
+ "try",
+ "catch",
+ "new",
+ "delete",
+
+ // visibility
+ "public",
+ "private",
+ "protected"
+ ]
+ static String[] javaKeywords=#[
+ "class",
+ "interface",
+ "extends",
+ "implements",
+ "abstract",
+ "this",
+ "new",
+
+ // visibility
+ "public",
+ "private",
+ "protected",
+
+ // exceptions
+ "throw",
+ "try",
+ "catch",
+ "final",
+ "finally"
+ ]
+ static String[] commonKeywords=#[
+ // flow control
+ "while",
+ "do",
+ "for",
+ "if",
+ "else",
+ "break",
+ "continue",
+ "switch",
+ "case",
+ "default",
+ "static",
+ "return",
+
+ "volatile",
+
+ // types
+ "void",
+ "int",
+ "float",
+ "double",
+ "short",
+ "char",
+ "long",
+ "signed",
+
+ // literals
+ "true",
+ "false"
+ ]
+
+ static def getCKeywords() {
+ (commonKeywords + cKeywords).toList
+ }
+
+ static def getCppKeywords() {
+ (commonKeywords + cKeywords + cppKeywords).toList
+ }
+
+ static def getJavaKeywords() {
+ (commonKeywords + javaKeywords).toList
+ }
+}
diff --git a/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/internal/DCSpecialCharRule.xtend b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/internal/DCSpecialCharRule.xtend
new file mode 100644
index 000000000..4a5dd1418
--- /dev/null
+++ b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/internal/DCSpecialCharRule.xtend
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2018 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * CONTRIBUTORS:
+ * Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.dctools.fsm.ast.internal
+
+import org.eclipse.jface.text.rules.IRule
+import org.eclipse.jface.text.rules.ICharacterScanner
+import org.eclipse.jface.text.rules.Token
+import org.eclipse.etrice.dctools.fsm.ast.internal.DCToken.Kind
+
+class DCSpecialCharRule implements IRule {
+
+ val period = new DCToken(Kind.PERIOD)
+ val sep = new DCToken(Kind.STATEMENT_SEP)
+
+ val char SEP = ';'
+ val char PERIOD = '.'
+
+ override evaluate(ICharacterScanner scanner) {
+ val c = scanner.read as char
+
+ // Note: switch/case didn't work
+ if (c==SEP) {
+ sep
+ }
+ else if (c==PERIOD) {
+ period
+ }
+ else {
+ scanner.unread
+ Token.UNDEFINED
+ }
+ }
+
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/internal/DCTextToken.xtend b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/internal/DCTextToken.xtend
new file mode 100644
index 000000000..02f71becc
--- /dev/null
+++ b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/internal/DCTextToken.xtend
@@ -0,0 +1,22 @@
+/*******************************************************************************
+ * Copyright (c) 2018 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * CONTRIBUTORS:
+ * Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.dctools.fsm.ast.internal
+
+import org.eclipse.xtend.lib.annotations.Data
+
+@Data
+class DCTextToken {
+ int begin
+ int length
+ DCToken token
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/internal/DCToken.xtend b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/internal/DCToken.xtend
new file mode 100644
index 000000000..d54abfd4b
--- /dev/null
+++ b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/internal/DCToken.xtend
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (c) 2018 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * CONTRIBUTORS:
+ * Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.dctools.fsm.ast.internal
+
+import org.eclipse.jface.text.rules.IToken
+import org.eclipse.xtend.lib.annotations.Data
+
+@Data
+class DCToken implements IToken {
+
+ enum Kind {
+ COMMENT,
+ STRING,
+ WHITESPACE,
+ PERIOD,
+ STATEMENT_SEP,
+ BRACKET,
+ NUMBER,
+ KEYWORD,
+ IDENTIFIER,
+ OTHER,
+ EOF
+ }
+
+ Kind kind
+
+ override getData() {
+ null
+ }
+
+ override isEOF() {
+ kind===Kind.EOF
+ }
+
+ override isOther() {
+ kind===Kind.OTHER
+ }
+
+ override isUndefined() {
+ false
+ }
+
+ override isWhitespace() {
+ kind===Kind.WHITESPACE
+ }
+
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/internal/DCWhitespaceDetector.xtend b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/internal/DCWhitespaceDetector.xtend
new file mode 100644
index 000000000..a3c3218d5
--- /dev/null
+++ b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/internal/DCWhitespaceDetector.xtend
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * Copyright (c) 2018 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * CONTRIBUTORS:
+ * Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.dctools.fsm.ast.internal
+
+import org.eclipse.jface.text.rules.IWhitespaceDetector
+
+class DCWhitespaceDetector implements IWhitespaceDetector {
+
+ override isWhitespace(char c) {
+ Character.isWhitespace(c)
+ }
+
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/internal/DCWordDetector.xtend b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/internal/DCWordDetector.xtend
new file mode 100644
index 000000000..96b7165bf
--- /dev/null
+++ b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/internal/DCWordDetector.xtend
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2018 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * CONTRIBUTORS:
+ * Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.dctools.fsm.ast.internal
+
+import org.eclipse.jface.text.rules.IWordDetector
+
+class DCWordDetector implements IWordDetector {
+
+ boolean includePreprocessDirectives
+
+ new() {
+ this(false)
+ }
+
+ new(boolean includePreprocessDirectives) {
+ this.includePreprocessDirectives = includePreprocessDirectives
+ }
+
+ override boolean isWordStart(char c) {
+ Character.isJavaIdentifierStart(c) || (includePreprocessDirectives && c === Character.valueOf('#').charValue)
+ }
+ override boolean isWordPart(char c) {
+ Character.isJavaIdentifierPart(c)
+ }
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstArrayAccessNode.xtend b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstArrayAccessNode.xtend
new file mode 100644
index 000000000..f27463309
--- /dev/null
+++ b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstArrayAccessNode.xtend
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2018 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * CONTRIBUTORS:
+ * Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.dctools.fsm.ast.nodes
+
+import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstIdentifierBracketNode
+
+class DCAstArrayAccessNode extends DCAstIdentifierBracketNode {
+
+ new(DCAstNode parent, DCAstIdentifierNode id, DCAstWhitespaceNode ws, DCAstBracketNode bracket) {
+ super(parent, id, ws, bracket)
+ }
+
+ override protected doPrint(String indent) {
+ println(indent + "DCAstArrayAccessNode '" + id + ws + bracket + "'" + linkedObjectText)
+ }
+
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstBracketNode.xtend b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstBracketNode.xtend
new file mode 100644
index 000000000..99a2bccfa
--- /dev/null
+++ b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstBracketNode.xtend
@@ -0,0 +1,72 @@
+/*******************************************************************************
+ * Copyright (c) 2018 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * CONTRIBUTORS:
+ * Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.dctools.fsm.ast.nodes
+
+import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstNode
+import org.eclipse.xtend.lib.annotations.Accessors
+
+@Accessors
+class DCAstBracketNode extends DCAstNode {
+
+ enum BracketType {
+ ROUND,
+ CURLY,
+ SQUARE
+ }
+
+ BracketType type
+ boolean closed
+
+ new(DCAstNode parent, BracketType type, DCAstNode contents) {
+ this(parent, type, contents, true)
+ }
+
+ new(DCAstNode parent, BracketType type, DCAstNode contents, boolean closed) {
+ super(parent, 2)
+ this.type = type
+ this.closed = closed
+
+ if (contents!==null) {
+ contents.parent = this
+ }
+ }
+
+ def left() {
+ switch type {
+ case CURLY: "{"
+ case ROUND: "("
+ case SQUARE: "["
+ }
+ }
+
+ def right() {
+ switch type {
+ case CURLY: "}"
+ case ROUND: ")"
+ case SQUARE: "]"
+ }
+ }
+
+ override toString() {
+ switch type {
+ case CURLY: "{}"
+ case ROUND: "()"
+ case SQUARE: "[]"
+ }
+ }
+
+ override protected doPrint(String indent) {
+ println(indent + "DCAstBracketNode " + this.toString)
+ }
+
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstFeatureCallNode.xtend b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstFeatureCallNode.xtend
new file mode 100644
index 000000000..4cabcbb30
--- /dev/null
+++ b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstFeatureCallNode.xtend
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2018 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * CONTRIBUTORS:
+ * Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.dctools.fsm.ast.nodes
+
+import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstNode
+
+class DCAstFeatureCallNode extends DCAstNode {
+
+ new(DCAstNode parent) {
+ super(parent, 0)
+ }
+
+ override protected doPrint(String indent) {
+ val extra = if (incomplete) " (incomplete)" else ""
+ println(indent + "DCAstFeatureCallNode" + extra)
+ }
+
+ def isIncomplete() {
+ !children.empty && children.last instanceof DCAstPeriodNode
+ }
+
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstIdentifierBracketNode.xtend b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstIdentifierBracketNode.xtend
new file mode 100644
index 000000000..94d5d31b0
--- /dev/null
+++ b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstIdentifierBracketNode.xtend
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2018 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * CONTRIBUTORS:
+ * Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.dctools.fsm.ast.nodes
+
+import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstNode
+
+abstract class DCAstIdentifierBracketNode extends DCAstNode {
+
+ new(DCAstNode parent, DCAstIdentifierNode id, DCAstWhitespaceNode ws, DCAstBracketNode bracket) {
+ super(parent, 0 /* consumed no tokens itself */)
+
+ id.parent = this
+
+ if (ws!==null) {
+ ws.parent = this
+ }
+
+ bracket.parent = this
+ }
+
+ def DCAstIdentifierNode idNode() {
+ children.head as DCAstIdentifierNode
+ }
+
+ def String id() {
+ idNode.identifier
+ }
+
+ def String ws() {
+ if (children.size==3) {
+ (children.get(1) as DCAstWhitespaceNode).text
+ }
+ else {
+ ""
+ }
+ }
+
+ def DCAstBracketNode bracketNode() {
+ children.last as DCAstBracketNode
+ }
+
+ def String bracket() {
+ bracketNode.toString
+ }
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstIdentifierNode.xtend b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstIdentifierNode.xtend
new file mode 100644
index 000000000..24bfe2177
--- /dev/null
+++ b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstIdentifierNode.xtend
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2018 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * CONTRIBUTORS:
+ * Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.dctools.fsm.ast.nodes
+
+import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstNode
+import org.eclipse.xtend.lib.annotations.Accessors
+import org.eclipse.etrice.dctools.fsm.ast.internal.DCTextToken
+
+@Accessors
+class DCAstIdentifierNode extends DCAstNode {
+
+ String identifier
+ DCTextToken token
+
+ new(DCAstNode parent, String identifier, DCTextToken token) {
+ super(parent, 1)
+ this.identifier = identifier
+ this.token = token
+ }
+
+ override protected doPrint(String indent) {
+ println(indent + "DCAstIdentifierNode '" + identifier + "'" + linkedObjectText)
+ }
+
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstMatchNode.xtend b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstMatchNode.xtend
new file mode 100644
index 000000000..43537a08a
--- /dev/null
+++ b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstMatchNode.xtend
@@ -0,0 +1,24 @@
+/*******************************************************************************
+ * Copyright (c) 2018 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * CONTRIBUTORS:
+ * Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.dctools.fsm.ast.nodes
+
+class DCAstMatchNode extends DCAstNode {
+
+ new(DCAstNode parent) {
+ super(parent, 0 /* no own tokens */)
+ }
+
+ override protected doPrint(String indent) {
+ println(indent + "DCAstMatchNode")
+ }
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstNode.xtend b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstNode.xtend
new file mode 100644
index 000000000..e27e67ded
--- /dev/null
+++ b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstNode.xtend
@@ -0,0 +1,96 @@
+/*******************************************************************************
+ * Copyright (c) 2018 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * CONTRIBUTORS:
+ * Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.dctools.fsm.ast.nodes
+
+import java.util.List
+import org.eclipse.emf.ecore.EObject
+import org.eclipse.xtend.lib.annotations.Accessors
+import org.eclipse.etrice.dctools.fsm.ast.util.IDCAstNodeVisitor
+
+@Accessors
+abstract class DCAstNode {
+
+ DCAstNode parent
+ int readTokens
+ List<DCAstNode> children = newArrayList
+ EObject linkedObject
+ Object linkedData
+
+ new() {
+ this(null, 0)
+ }
+
+ new(DCAstNode parent, int readTokens) {
+ this.parent = parent
+ this.readTokens = readTokens
+ if (parent!==null) {
+ parent.children.add(this)
+ }
+ }
+
+ def DCAstNode c(int i) {
+ children.get(i)
+ }
+
+ def void setParent(DCAstNode parent) {
+ if (this.parent!==null) {
+ this.parent.children.remove(this)
+ }
+ this.parent = parent
+ if (parent!==null) {
+ this.parent.children.add(this)
+ }
+ }
+
+ def int totallyReadTokens() {
+ var sum = readTokens
+ for (child : children) {
+ sum += child.totallyReadTokens
+ }
+ return sum
+ }
+
+ def void print() {
+ printRecursive("")
+ }
+
+ def void visit(IDCAstNodeVisitor visitor) {
+ val descend = visitor.visitBegin(this)
+
+ if (descend) {
+ for (child : children) {
+ child.visit(visitor)
+ }
+ }
+
+ visitor.visitEnd(this)
+ }
+
+ protected def void printRecursive(String indent) {
+ doPrint(indent)
+ for (child : children) {
+ child.printRecursive(indent + " ")
+ }
+ }
+
+ protected def String getLinkedObjectText() {
+ if (linkedObject!==null) {
+ return " --> " + linkedObject.eClass.name
+ }
+ else {
+ ""
+ }
+ }
+
+ protected abstract def void doPrint(String indent)
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstOperationCallNode.xtend b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstOperationCallNode.xtend
new file mode 100644
index 000000000..e6fc4fac4
--- /dev/null
+++ b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstOperationCallNode.xtend
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2018 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * CONTRIBUTORS:
+ * Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.dctools.fsm.ast.nodes
+
+import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstIdentifierBracketNode
+
+class DCAstOperationCallNode extends DCAstIdentifierBracketNode {
+
+ new(DCAstNode parent, DCAstIdentifierNode id, DCAstWhitespaceNode ws, DCAstBracketNode bracket) {
+ super(parent, id, ws, bracket)
+ }
+
+ override protected doPrint(String indent) {
+ println(indent + "DCAstOperationCallNode '" + id + ws + bracket + "'" + linkedObjectText)
+ }
+
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstOtherNode.xtend b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstOtherNode.xtend
new file mode 100644
index 000000000..5f6e330fb
--- /dev/null
+++ b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstOtherNode.xtend
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2018 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * CONTRIBUTORS:
+ * Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.dctools.fsm.ast.nodes
+
+import org.eclipse.etrice.dctools.fsm.ast.internal.DCTextToken
+import org.eclipse.xtend.lib.annotations.Accessors
+
+@Accessors
+class DCAstOtherNode extends DCAstNode {
+
+ String text
+ DCTextToken token
+
+ new(DCAstNode parent, String text, DCTextToken token) {
+ super(parent, 1)
+ this.text = text
+ this.token = token
+ }
+
+ override protected doPrint(String indent) {
+ println(indent + "DCAstOtherNode '" + text + "' " + token.token.kind)
+ }
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstPeriodNode.xtend b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstPeriodNode.xtend
new file mode 100644
index 000000000..535d401dc
--- /dev/null
+++ b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstPeriodNode.xtend
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2018 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * CONTRIBUTORS:
+ * Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.dctools.fsm.ast.nodes
+
+import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstNode
+
+class DCAstPeriodNode extends DCAstNode {
+
+ new(DCAstNode parent) {
+ super(parent, 1)
+ }
+
+ override protected doPrint(String indent) {
+ println(indent + "DCAstPeriodNode")
+ }
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstWhitespaceNode.xtend b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstWhitespaceNode.xtend
new file mode 100644
index 000000000..c0017774f
--- /dev/null
+++ b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/nodes/DCAstWhitespaceNode.xtend
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2018 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * CONTRIBUTORS:
+ * Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.dctools.fsm.ast.nodes
+
+import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstNode
+import org.eclipse.xtend.lib.annotations.Accessors
+
+@Accessors
+class DCAstWhitespaceNode extends DCAstNode {
+
+ String text
+
+ new(DCAstNode parent, int readTokens, String text) {
+ super(parent, readTokens)
+ this.text = text
+ }
+
+ override protected doPrint(String indent) {
+ println(indent + "DCAstWhitespaceNode '" + text + "'")
+ }
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/util/DCAstPrinter.xtend b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/util/DCAstPrinter.xtend
new file mode 100644
index 000000000..d5e7435cf
--- /dev/null
+++ b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/util/DCAstPrinter.xtend
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2018 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * CONTRIBUTORS:
+ * Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.dctools.fsm.ast.util
+
+import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstBracketNode
+import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstIdentifierNode
+import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstNode
+import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstPeriodNode
+import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstWhitespaceNode
+import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstOtherNode
+
+class DCAstPrinter implements IDCAstNodeVisitor {
+
+ val sb = new StringBuilder
+
+ def getText() {
+ sb.toString
+ }
+
+ override visitBegin(DCAstNode node) {
+
+ switch node {
+ DCAstBracketNode: sb.append(node.left)
+ DCAstIdentifierNode: sb.append(node.identifier)
+ DCAstPeriodNode: sb.append(".")
+ DCAstWhitespaceNode: sb.append(node.text)
+ DCAstOtherNode: sb.append(node.text)
+ }
+
+ return true
+ }
+
+ override visitEnd(DCAstNode node) {
+ switch node {
+ DCAstBracketNode: if (node.closed) sb.append(node.right)
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/util/IDCAstNodeVisitor.xtend b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/util/IDCAstNodeVisitor.xtend
new file mode 100644
index 000000000..d430bf589
--- /dev/null
+++ b/plugins/org.eclipse.etrice.dctools.fsm/src/org/eclipse/etrice/dctools/fsm/ast/util/IDCAstNodeVisitor.xtend
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ * Copyright (c) 2018 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * CONTRIBUTORS:
+ * Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.dctools.fsm.ast.util
+
+import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstNode
+
+interface IDCAstNodeVisitor {
+
+ def boolean visitBegin(DCAstNode node)
+ def void visitEnd(DCAstNode node)
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.etrice.dctools/.classpath b/plugins/org.eclipse.etrice.dctools/.classpath
new file mode 100644
index 000000000..428337e56
--- /dev/null
+++ b/plugins/org.eclipse.etrice.dctools/.classpath
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="src" path="xtend-gen"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/plugins/org.eclipse.etrice.dctools/.gitignore b/plugins/org.eclipse.etrice.dctools/.gitignore
new file mode 100644
index 000000000..1a7726dc2
--- /dev/null
+++ b/plugins/org.eclipse.etrice.dctools/.gitignore
@@ -0,0 +1,4 @@
+bin
+*._trace
+*.smap
+*.xtendbin
diff --git a/plugins/org.eclipse.etrice.dctools/.project b/plugins/org.eclipse.etrice.dctools/.project
new file mode 100644
index 000000000..af0ef944b
--- /dev/null
+++ b/plugins/org.eclipse.etrice.dctools/.project
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.etrice.dctools</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.xtext.ui.shared.xtextBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.eclipse.xtext.ui.shared.xtextNature</nature>
+ </natures>
+</projectDescription>
diff --git a/plugins/org.eclipse.etrice.dctools/.settings/org.eclipse.jdt.core.prefs b/plugins/org.eclipse.etrice.dctools/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 000000000..0c68a61dc
--- /dev/null
+++ b/plugins/org.eclipse.etrice.dctools/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.8
diff --git a/plugins/org.eclipse.etrice.dctools/META-INF/MANIFEST.MF b/plugins/org.eclipse.etrice.dctools/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..809caa340
--- /dev/null
+++ b/plugins/org.eclipse.etrice.dctools/META-INF/MANIFEST.MF
@@ -0,0 +1,19 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Detail Code Tools
+Bundle-SymbolicName: org.eclipse.etrice.dctools
+Bundle-Version: 1.1.1.qualifier
+Bundle-Vendor: Eclipse eTrice
+Automatic-Module-Name: org.eclipse.etrice.dctools
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
+Require-Bundle: com.google.guava,
+ org.eclipse.emf.ecore,
+ org.eclipse.xtext.xbase.lib,
+ org.eclipse.xtend.lib,
+ org.eclipse.xtend.lib.macro,
+ org.eclipse.etrice.core.fsm,
+ org.eclipse.etrice.core.room,
+ org.eclipse.etrice.dctools.fsm;visibility:=reexport,
+ org.eclipse.etrice.generator.fsm
+Export-Package: org.eclipse.etrice.dctools.ast
+
diff --git a/plugins/org.eclipse.etrice.dctools/build.properties b/plugins/org.eclipse.etrice.dctools/build.properties
new file mode 100644
index 000000000..d8e2f0e92
--- /dev/null
+++ b/plugins/org.eclipse.etrice.dctools/build.properties
@@ -0,0 +1,5 @@
+source.. = src/,\
+ xtend-gen/
+output.. = bin/
+bin.includes = META-INF/,\
+ .
diff --git a/plugins/org.eclipse.etrice.dctools/src/org/eclipse/etrice/dctools/ast/DCLinker.xtend b/plugins/org.eclipse.etrice.dctools/src/org/eclipse/etrice/dctools/ast/DCLinker.xtend
new file mode 100644
index 000000000..30ea98b41
--- /dev/null
+++ b/plugins/org.eclipse.etrice.dctools/src/org/eclipse/etrice/dctools/ast/DCLinker.xtend
@@ -0,0 +1,277 @@
+/*******************************************************************************
+ * Copyright (c) 2011 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * CONTRIBUTORS:
+ * Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.dctools.ast
+
+import java.util.Deque
+import java.util.LinkedList
+import org.eclipse.emf.ecore.EObject
+import org.eclipse.emf.ecore.EReference
+import org.eclipse.emf.ecore.util.EcoreUtil
+import org.eclipse.etrice.core.fsm.fSM.StateGraphItem
+import org.eclipse.etrice.core.room.ActorClass
+import org.eclipse.etrice.core.room.Attribute
+import org.eclipse.etrice.core.room.DataClass
+import org.eclipse.etrice.core.room.EnumerationType
+import org.eclipse.etrice.core.room.InterfaceItem
+import org.eclipse.etrice.core.room.MessageData
+import org.eclipse.etrice.core.room.Operation
+import org.eclipse.etrice.core.room.Port
+import org.eclipse.etrice.core.room.PortClass
+import org.eclipse.etrice.core.room.RoomClass
+import org.eclipse.etrice.core.room.SAP
+import org.eclipse.etrice.core.room.VarDecl
+import org.eclipse.etrice.core.room.util.RoomHelpers
+import org.eclipse.etrice.dctools.fsm.ast.CandidateMap
+import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstArrayAccessNode
+import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstFeatureCallNode
+import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstIdentifierNode
+import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstNode
+import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstOperationCallNode
+import org.eclipse.etrice.dctools.fsm.ast.util.IDCAstNodeVisitor
+
+import static org.eclipse.etrice.core.fsm.fSM.FSMPackage.Literals.*
+
+import static extension org.eclipse.xtext.EcoreUtil2.*
+import org.eclipse.etrice.core.fsm.fSM.DetailCode
+
+class DCLinker implements IDCAstNodeVisitor {
+
+ enum FeatureType {
+ SCALAR,
+ ARRAY,
+ OPERATION
+ }
+
+ EObject owner
+ EReference reference
+ MessageData transitionData
+
+ protected val extension RoomHelpers roomHelpers = new RoomHelpers
+
+ val Deque<EObject> contexts = new LinkedList
+
+ new(DetailCode dc) {
+ this(dc.eContainer, dc.eContainingFeature as EReference)
+ }
+
+ new(EObject owner, EReference reference) {
+ this(owner, reference, null)
+ }
+
+ new(DetailCode dc, MessageData transitionData) {
+ this(dc.eContainer, dc.eContainingFeature as EReference, transitionData)
+ }
+
+ new(EObject owner, EReference reference, MessageData transitionData) {
+ this.owner = owner
+ this.reference = reference
+ this.transitionData = transitionData
+ }
+
+ override visitBegin(DCAstNode node) {
+ switch node {
+ DCAstFeatureCallNode: {
+ // a feature call always starts in the global context
+ contexts.push(owner)
+ }
+ DCAstIdentifierNode case node.parent instanceof DCAstFeatureCallNode: link(node)
+ DCAstArrayAccessNode: link(node)
+ DCAstOperationCallNode: link(node)
+ }
+
+ return true
+ }
+
+ override visitEnd(DCAstNode node) {
+ switch node {
+ DCAstFeatureCallNode: contexts.pop
+ }
+ }
+
+ protected def dispatch void link(DCAstIdentifierNode node) {
+ val candidates = getCandidates(FeatureType.SCALAR)
+ node.linkedObject = candidates.get(node.identifier)
+ replaceContext(node.linkedObject)
+ }
+
+ protected def dispatch void link(DCAstArrayAccessNode node) {
+ val candidates = getCandidates(FeatureType.ARRAY)
+ node.linkedObject = candidates.get(node.id)
+ replaceContext(node.linkedObject)
+ }
+
+ protected def dispatch void link(DCAstOperationCallNode node) {
+ val candidates = getCandidates(FeatureType.OPERATION)
+ node.linkedObject = candidates.get(node.id)
+ replaceContext(node.linkedObject)
+ }
+
+ protected def replaceContext(EObject obj) {
+ contexts.pop
+ contexts.push(obj?.contextOf)
+ }
+
+ protected def dispatch getContextOf(EObject obj) {
+ null
+ }
+
+ protected def dispatch getContextOf(Port port) {
+ port
+ }
+
+ protected def dispatch getContextOf(Attribute att) {
+ att.type.type
+ }
+
+ protected def dispatch getContextOf(VarDecl vd) {
+ vd.refType.type
+ }
+
+ protected def dispatch getContextOf(MessageData md) {
+ md?.refType?.type
+ }
+
+ protected def dispatch getContextOf(Operation op) {
+ op?.returnType?.type
+ }
+
+ //http://git.eclipse.org/c/etrice/org.eclipse.etrice.git/tree/tests/org.eclipse.etrice.generator.common.tests/models/EnumTest.room?h=newfsmgen_finalize&id=79aa00b074c61bde5173d4859ce2b52e50b52dec#n117
+
+ protected def getCandidates(FeatureType type) {
+ val candidates = new CandidateMap
+
+ if (contexts.peek===owner) {
+ // this is the top level
+ topLevelCandidates(candidates, type)
+ }
+ else {
+ val current = contexts.peek
+ switch current {
+ DataClass: {
+ current.getCandidates(type, candidates)
+ }
+
+ InterfaceItem: {
+ current.getCandidates(candidates)
+ }
+
+ Attribute case current.type?.type instanceof DataClass: {
+ val dc = current.type.type as DataClass
+ dc.getCandidates(type, candidates)
+ }
+ MessageData case current.refType?.type instanceof DataClass: {
+ val dc = current.refType.type as DataClass
+ dc.getCandidates(type, candidates)
+ }
+ EnumerationType: {
+ // from descriptions, have to be resolved
+ var enumType = current
+ if (current.eIsProxy) {
+ val resolved = EcoreUtil.resolve(current, owner)
+ if (resolved instanceof EnumerationType)
+ enumType = resolved
+ }
+ enumType.literals.forEach[candidates.put(it.name, it)]
+ }
+ }
+ }
+
+ return candidates
+ }
+
+ protected def void topLevelCandidates(CandidateMap candidates, FeatureType type) {
+ // operation arguments
+ owner.getContainerOfType(Operation)?.arguments?.forEach[candidates.put(it.name, it)]
+
+ // TODO: compare with org.eclipse.etrice.expressions.detailcode.DetailExpressionProvider.initialFsmExpression(EObject, ActorClass, List<ExpressionFeature>)
+ if (!reference.name.contains('userCode')) {
+ val roomClass = owner.getContainerOfType(RoomClass)
+ switch roomClass {
+ ActorClass: {
+ if (transitionData!==null) {
+ candidates.put("transitionData", transitionData)
+ }
+ if (type==FeatureType.SCALAR) {
+ roomClass.allAttributes.forEach[candidates.put(it.name, it)]
+ }
+ if (type==FeatureType.ARRAY) {
+ roomClass.allAttributes.filter[size>1].forEach[candidates.put(it.name, it)]
+ }
+ if (type==FeatureType.OPERATION) {
+ roomClass.latestOperations.forEach[candidates.put(it.name, it)]
+ }
+ roomClass.allInterfaceItems.forEach[
+ switch it {
+ Port case type==FeatureType.SCALAR: candidates.put(it.name, it)
+ Port case type==FeatureType.ARRAY && it.replicated: candidates.put(it.name, it)
+ SAP case type==FeatureType.SCALAR: candidates.put(it.name, it)
+ }
+ ]
+ }
+
+ DataClass: {
+ roomClass.getCandidates(type, candidates)
+ }
+
+ case owner.getContainerOfType(PortClass)!==null: {
+ val portClass = owner.getContainerOfType(PortClass)
+ // TODO inheritance
+ portClass.operations.forEach[candidates.put(it.name, it)]
+ portClass.attributes.forEach[candidates.put(it.name, it)]
+ }
+ }
+ }
+ }
+
+ protected def void getCandidates(DataClass dataClass, FeatureType type, CandidateMap candidates) {
+ if (type==FeatureType.SCALAR) {
+ dataClass.allAttributes.forEach[candidates.put(it.name, it)]
+ }
+ if (type==FeatureType.ARRAY) {
+ dataClass.allAttributes.filter[size>1].forEach[candidates.put(it.name, it)]
+ }
+ if (type==FeatureType.OPERATION) {
+ dataClass.latestOperations.forEach[candidates.put(it.name, it)]
+ }
+ }
+
+ protected def void getCandidates(InterfaceItem ifItem, CandidateMap candidates) {
+ // operations
+ ifItem.protocol.getAllOperations(!ifItem.conjugated).forEach[candidates.put(it.name, it)]
+
+ // messages
+ switch reference {
+ case CP_BRANCH_TRANSITION__CONDITION,
+ case GUARDED_TRANSITION__GUARD,
+ case GUARD__GUARD: {
+ val pc = ifItem.protocol
+ switch pc?.commType {
+ case DATA_DRIVEN:
+ if (!ifItem.conjugated) pc.allIncomingMessages.forEach[candidates.put(it.name, it)]
+ case EVENT_DRIVEN: { /* no async message calls */}
+ case SYNCHRONOUS: {}
+ }
+ }
+ case owner.getContainerOfType(StateGraphItem)!==null: {
+ val pc = ifItem.protocol
+ switch pc?.commType {
+ case EVENT_DRIVEN:
+ pc.getAllMessages(ifItem.conjugated).forEach[candidates.put(it.name, it)]
+ case DATA_DRIVEN:
+ pc.allIncomingMessages.forEach[candidates.put(it.name, it)]
+ case SYNCHRONOUS: {}
+ }
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.etrice.dctools/src/org/eclipse/etrice/dctools/ast/DCTranslator.xtend b/plugins/org.eclipse.etrice.dctools/src/org/eclipse/etrice/dctools/ast/DCTranslator.xtend
new file mode 100644
index 000000000..7c72cd54b
--- /dev/null
+++ b/plugins/org.eclipse.etrice.dctools/src/org/eclipse/etrice/dctools/ast/DCTranslator.xtend
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * Copyright (c) 2018 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * CONTRIBUTORS:
+ * Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.dctools.ast
+
+import org.eclipse.etrice.generator.fsm.generic.IDetailCodeTranslator
+import org.eclipse.etrice.core.fsm.fSM.DetailCode
+import org.eclipse.etrice.dctools.ast.internal.DCTranslatorVisitor
+import org.eclipse.etrice.core.room.util.RoomHelpers
+import org.eclipse.etrice.generator.fsm.base.IFSMTranslationProvider
+import org.eclipse.etrice.dctools.fsm.ast.DCLanguage
+import org.eclipse.etrice.dctools.fsm.ast.DCParser
+import org.eclipse.etrice.core.room.MessageData
+
+class DCTranslator implements IDetailCodeTranslator {
+
+ DCLanguage language
+ ITranslationProvider translationProvider
+
+ val extension RoomHelpers roomHelpers = new RoomHelpers
+
+ new(DCLanguage language, ITranslationProvider translationProvider) {
+ this.language = language
+ this.translationProvider = translationProvider
+ }
+
+ override getTranslatedCode(DetailCode dc) {
+ return getTranslatedCode(dc, null)
+ }
+
+ def getTranslatedCode(DetailCode dc, MessageData transitionData) {
+ var code = dc.detailCode
+
+ // before the actual parsing is done we translate tags
+ if (translationProvider.translateTags) {
+ code = translateTags(code, dc)
+ }
+
+ // parse
+ val parser = new DCParser(language)
+ val ast = parser.parse(code)
+
+ // link
+ val linker = new DCLinker(dc, transitionData)
+ ast.visit(linker)
+
+ // translate
+ val visitor = new DCTranslatorVisitor(translationProvider)
+ ast.visit(visitor)
+
+ return visitor.translatedCode
+ }
+
+ def translateTags(String text, DetailCode dc) {
+ val result = new StringBuilder
+
+ var int last = 0
+ var int next = text.indexOf(IFSMTranslationProvider.TAG_START, last)
+ while (next >= 0) {
+ result.append(text.substring(last, next))
+ last = next + IFSMTranslationProvider.TAG_START.length()
+ next = text.indexOf(IFSMTranslationProvider.TAG_END, last)
+ if (next >= 0) {
+ val String tag = text.substring(last, next)
+ result.append(translationProvider.translateTag(tag, dc))
+ last = next + IFSMTranslationProvider.TAG_END.length()
+ next = text.indexOf(IFSMTranslationProvider.TAG_START, last)
+ }
+ }
+ result.append(text.substring(last))
+
+ return result.toString
+ }
+
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.etrice.dctools/src/org/eclipse/etrice/dctools/ast/ITranslationProvider.xtend b/plugins/org.eclipse.etrice.dctools/src/org/eclipse/etrice/dctools/ast/ITranslationProvider.xtend
new file mode 100644
index 000000000..2bb57091d
--- /dev/null
+++ b/plugins/org.eclipse.etrice.dctools/src/org/eclipse/etrice/dctools/ast/ITranslationProvider.xtend
@@ -0,0 +1,112 @@
+/*******************************************************************************
+ * Copyright (c) 2011 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * CONTRIBUTORS:
+ * Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.dctools.ast
+
+import org.eclipse.etrice.core.room.InterfaceItem
+import org.eclipse.etrice.core.fsm.fSM.AbstractInterfaceItem
+import org.eclipse.etrice.core.room.Attribute
+import org.eclipse.etrice.core.room.Message
+import org.eclipse.etrice.core.room.Operation
+import org.eclipse.etrice.core.room.PortOperation
+import org.eclipse.etrice.core.room.EnumLiteral
+import org.eclipse.etrice.dctools.fsm.ast.IFSMTranslationProvider
+
+/**
+ * This interface is used by the detail code translator to replace
+ * common constructs in detail level code with a target language specific
+ * piece of code.
+ * <p>
+ * The constructs that are replaced are
+ * <ul>
+ * <li>attributes</li>
+ * <li>operations</li>
+ * <li>port.message</li>
+ * <li>tags of the form <code><|tag|></code></li>
+ * </ul>
+ * </p>
+ * @see DCTranslator
+ * @author Henrik Rentz-Reichert
+ */
+interface ITranslationProvider extends IFSMTranslationProvider{
+
+ /**
+ * yield text to read an attribute (array index may be null). Is called whenever <i>attribute</i>
+ * or <i>attribute</i>[<i>index</i>] or is
+ * found in the detail code
+ * @param att the actor class attribute
+ * @param instance a pointer to the instance object
+ * @param index the index (should be null for scalars, !=null for arrays)
+ * @param orig the original text
+ * @return the translation
+ */
+ def String getAttributeGetter(Attribute att, String instance, String index, String orig)
+
+ /**
+ * yield text to write an attribute (array index may be null). Is called whenever <i>attribute</i>.set(<i>value</i>)
+ * or <i>attribute</i>[<i>index</i>].set(<i>value</i>) is
+ * found in the detail code
+ * @param att the actor class attribute
+ * @param instance a pointer to the instance object
+ * @param index the index (should be null for scalars, !=null for arrays)
+ * @param value to assign to the attribute
+ * @param orig the original text
+ * @return the translation
+ */
+ def String getAttributeSetter(Attribute att, String instance, String index, String value, String orig)
+
+ /**
+ * yield text for operation call. Is called whenever <i>operation</i>(<i>args</i>)
+ * is found in the detail code
+ * @param op operation to call
+ * @param instance a pointer to the defining class instance
+ * @param args the arguments to pass
+ * @param orig the original text
+ * @return the translation
+ */
+ def String getOperationText(Operation op, String instance, String args, String orig)
+
+ /**
+ * yields a sequence that reads data from a <b>data driven</b> port.
+ * Is called whenever <i>port</i>.<i>msg</i> or <i>port</i>[<i>index</i>].<i>msg</i>
+ * is found in the detail code
+ * @param item the interface item
+ * @param msg the message to read
+ * @param orig the original text
+ * @return the translation
+ */
+ def String getInterfaceItemMessageValue(InterfaceItem item, Message msg, String orig)
+
+ /**
+ * @return true if translations are provided for enumerations
+ */
+ def boolean translateEnums()
+
+ /**
+ * yields a replacement for &lt;enumtype>.&lt;literal>
+ * @param literal the enumeration literal to be translated
+ * @return the translated enumeration literal
+ */
+ def String getEnumText(EnumLiteral literal)
+
+ /**
+ * yields a call to an operation of an interface item
+ * @param item the interface item
+ * @param op the port class operation
+ * @param instance a pointer to the defining class instance
+ * @param args the argument list
+ * @param orig the original test
+ * @return the translation
+ */
+ def String getInterfaceItemOperationText(AbstractInterfaceItem item, PortOperation op, String instance, String args, String orig)
+
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.etrice.dctools/src/org/eclipse/etrice/dctools/ast/internal/DCTranslatorVisitor.xtend b/plugins/org.eclipse.etrice.dctools/src/org/eclipse/etrice/dctools/ast/internal/DCTranslatorVisitor.xtend
new file mode 100644
index 000000000..afd514a07
--- /dev/null
+++ b/plugins/org.eclipse.etrice.dctools/src/org/eclipse/etrice/dctools/ast/internal/DCTranslatorVisitor.xtend
@@ -0,0 +1,246 @@
+/*******************************************************************************
+ * Copyright (c) 2011 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * CONTRIBUTORS:
+ * Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.dctools.ast.internal
+
+import org.eclipse.etrice.core.room.Attribute
+import org.eclipse.etrice.core.room.InterfaceItem
+import org.eclipse.etrice.core.room.Message
+import org.eclipse.etrice.core.room.Operation
+import org.eclipse.etrice.dctools.ast.ITranslationProvider
+import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstArrayAccessNode
+import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstBracketNode
+import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstBracketNode.BracketType
+import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstIdentifierNode
+import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstNode
+import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstOperationCallNode
+import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstOtherNode
+import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstPeriodNode
+import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstWhitespaceNode
+import org.eclipse.etrice.dctools.fsm.ast.util.DCAstPrinter
+import org.eclipse.etrice.dctools.fsm.ast.util.IDCAstNodeVisitor
+import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstFeatureCallNode
+import org.eclipse.etrice.core.room.Port
+import org.eclipse.etrice.core.room.VarDecl
+
+class DCTranslatorVisitor implements IDCAstNodeVisitor {
+
+ ITranslationProvider translationProvider
+
+ val sb = new StringBuilder
+ var currentSB = sb
+
+ new(ITranslationProvider translationProvider) {
+ this.translationProvider = translationProvider
+ }
+
+ def String getTranslatedCode() {
+ sb.toString
+ }
+
+
+ override visitBegin(DCAstNode node) {
+
+ if (node instanceof DCAstBracketNode) {
+ if (node.shouldCollectArguments) {
+ currentSB = new StringBuilder
+ node.linkedData = currentSB
+ }
+ else {
+ currentSB.append(node.left)
+ }
+ }
+ else {
+ if (!node.skipOutput) {
+ switch node {
+ DCAstIdentifierNode: currentSB.append(node.identifier)
+ DCAstPeriodNode: currentSB.append(".")
+ DCAstWhitespaceNode: currentSB.append(node.text)
+ DCAstOtherNode: currentSB.append(node.text)
+ }
+ }
+ }
+
+ return true
+ }
+
+ override visitEnd(DCAstNode node) {
+ switch node {
+ DCAstBracketNode: {
+ if (node.linkedData!==null) {
+ // leave the nested StringBuilder and switch to the enclosing (or top) one
+ currentSB = node.enclosingSB
+ }
+ else if (node.closed) {
+ currentSB.append(node.right)
+ }
+ }
+
+ DCAstFeatureCallNode case node.canTranslate: node.translate
+ }
+ }
+
+ private def canTranslate(DCAstFeatureCallNode node) {
+ // if all even children are linked then we can translate the whole
+ for (var i=0; i<node.children.size; i=i+2) {
+ if (node.c(i).linkedObject===null) {
+ return false
+ }
+ }
+
+ // make sure the last child is not a period
+ val lastNode = node.children.last
+ if (lastNode instanceof DCAstPeriodNode) {
+ return false
+ }
+
+ return true
+ }
+
+ private def translate(DCAstFeatureCallNode node) {
+ val lastNode = node.children.last
+ var linkedObject = lastNode.linkedObject
+
+ // TODO: handle getter for data driven ports: port.message - i.e. no () after message
+
+ if (lastNode instanceof DCAstOperationCallNode) {
+ if (linkedObject instanceof Message) {
+ handleSendMessage(lastNode, linkedObject)
+ return
+ }
+ }
+
+ node.handleCallChain
+ }
+
+ def handleCallChain(DCAstFeatureCallNode node) {
+ var String instance = null
+ for (var i=0; i<node.children.size; i=i+2) {
+ val childNode = node.c(i)
+ val linkedObject = childNode.linkedObject
+ switch linkedObject {
+ Attribute: {
+ val index = if (childNode instanceof DCAstArrayAccessNode) {
+ (childNode.bracketNode.linkedData as StringBuilder).toString
+ }
+ instance = translationProvider.getAttributeGetter(linkedObject, instance, index, childNode.originalText)
+ }
+
+ VarDecl: {
+ instance = linkedObject.name
+ }
+
+ Operation: {
+ val args = if (childNode instanceof DCAstOperationCallNode) {
+ (childNode.bracketNode.linkedData as StringBuilder).toString
+ }
+ instance = translationProvider.getOperationText(linkedObject, instance, args, childNode.originalText)
+ }
+ }
+ }
+ currentSB.append(instance)
+ }
+
+ private def handleSendMessage(DCAstOperationCallNode msgNode, Message msg) {
+ val args = (msgNode.bracketNode.linkedData as StringBuilder).toString
+ // look back to interface item
+ val ifItemNode = msgNode.parent.c(0)
+ val ifItem = ifItemNode.linkedObject as InterfaceItem
+
+ val translated =
+ if (ifItemNode instanceof DCAstIdentifierNode) {
+ // accessed as scalar (means broadcast for replicated port)
+ val inst = ifItemNode.identifier
+ translationProvider.getInterfaceItemMessageText(ifItem, msg, inst, args, null, msgNode.originalText)
+ }
+ else if (ifItemNode instanceof DCAstArrayAccessNode) {
+ // accessed as array
+ val inst = ifItemNode.id
+ val index = (ifItemNode.bracketNode.linkedData as StringBuilder).toString
+ translationProvider.getInterfaceItemMessageText(ifItem, msg, inst, args, index, msgNode.originalText)
+ }
+ else {
+ // TODO: assert(false)
+ "internal translator error"
+ }
+ currentSB.append(translated)
+ }
+
+ private def skipOutput(DCAstNode node) {
+ val surroundingContext = node.getEnclosingBracketOrFeatureCall
+
+ // check whether we are inside a bracket without a feature call
+ if (surroundingContext instanceof DCAstBracketNode) {
+ return false
+ }
+
+ if (surroundingContext instanceof DCAstFeatureCallNode) {
+ return surroundingContext.canTranslate
+ }
+
+ return false
+ }
+
+ private def getEnclosingBracketOrFeatureCall(DCAstNode node) {
+ var parent = node.parent
+ while (parent!==null) {
+ if (parent instanceof DCAstFeatureCallNode || parent instanceof DCAstBracketNode) {
+ return parent
+ }
+ parent = parent.parent
+ }
+
+ return null
+ }
+
+ private def getOriginalText(DCAstNode node) {
+ val printer = new DCAstPrinter
+ node.visit(printer)
+ return printer.text
+ }
+
+ private def getEnclosingSB(DCAstBracketNode node) {
+ var parent = node.parent
+ while (parent!==null) {
+ if (parent instanceof DCAstBracketNode && parent.linkedData instanceof StringBuilder) {
+ return parent.linkedData as StringBuilder
+ }
+ parent = parent.parent
+ }
+
+ // return top level
+ return sb
+ }
+
+ private def shouldCollectArguments(DCAstBracketNode node) {
+ val linkedObject = node.parent.linkedObject
+
+ if (node.type==BracketType.CURLY) {
+ false
+ }
+ else if (linkedObject instanceof Operation) {
+ true
+ }
+ else if (linkedObject instanceof Message) {
+ true
+ }
+ else if (linkedObject instanceof Attribute) {
+ true
+ }
+ else if (linkedObject instanceof Port) {
+ true
+ }
+ else {
+ false
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.etrice.expressions.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.etrice.expressions.ui/META-INF/MANIFEST.MF
index 667e443c0..c37ee22c3 100644
--- a/plugins/org.eclipse.etrice.expressions.ui/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.etrice.expressions.ui/META-INF/MANIFEST.MF
@@ -15,4 +15,5 @@ Require-Bundle: org.eclipse.jface.text,
Export-Package: org.eclipse.etrice.expressions.detailcode,
org.eclipse.etrice.expressions.ui.contentassist,
org.eclipse.etrice.expressions.ui.highlight
+Bundle-Vendor: Eclipse eTrice
diff --git a/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/CTranslationProvider.java b/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/CTranslationProvider.java
index 33f6e1a6e..fc6ed1edb 100644
--- a/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/CTranslationProvider.java
+++ b/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/CTranslationProvider.java
@@ -12,13 +12,13 @@
package org.eclipse.etrice.generator.c.gen;
-import java.util.ArrayList;
+import java.util.List;
import org.eclipse.emf.ecore.EObject;
-import org.eclipse.etrice.core.room.Attribute;
-import org.eclipse.etrice.core.room.CommunicationType;
import org.eclipse.etrice.core.fsm.fSM.AbstractInterfaceItem;
import org.eclipse.etrice.core.fsm.fSM.DetailCode;
+import org.eclipse.etrice.core.room.Attribute;
+import org.eclipse.etrice.core.room.CommunicationType;
import org.eclipse.etrice.core.room.EnumLiteral;
import org.eclipse.etrice.core.room.EnumerationType;
import org.eclipse.etrice.core.room.InterfaceItem;
@@ -51,7 +51,7 @@ public class CTranslationProvider extends DefaultTranslationProvider {
}
@Override
- public String getInterfaceItemMessageText(AbstractInterfaceItem item, EObject abstractMsg, ArrayList<String> args, String index, String orig) {
+ public String getInterfaceItemMessageText(AbstractInterfaceItem item, EObject abstractMsg, List<String> args, String index, String orig) {
if (!(abstractMsg instanceof Message))
return orig;
@@ -110,11 +110,11 @@ public class CTranslationProvider extends DefaultTranslationProvider {
}
/* (non-Javadoc)
- * @see org.eclipse.etrice.generator.base.DefaultTranslationProvider#getInterfaceItemOperationText(org.eclipse.etrice.core.fsm.fSM.AbstractInterfaceItem, org.eclipse.etrice.core.room.PortOperation, java.util.ArrayList, java.lang.String)
+ * @see org.eclipse.etrice.generator.base.DefaultTranslationProvider#getInterfaceItemOperationText(org.eclipse.etrice.core.fsm.fSM.AbstractInterfaceItem, org.eclipse.etrice.core.room.PortOperation, java.util.List, java.lang.String)
*/
@Override
public String getInterfaceItemOperationText(AbstractInterfaceItem item,
- PortOperation op, ArrayList<String> args, String orig) {
+ PortOperation op, List<String> args, String orig) {
StringBuilder argtext = new StringBuilder();
for (String arg : args) {
diff --git a/plugins/org.eclipse.etrice.generator.cpp/src/org/eclipse/etrice/generator/cpp/gen/CppTranslationProvider.java b/plugins/org.eclipse.etrice.generator.cpp/src/org/eclipse/etrice/generator/cpp/gen/CppTranslationProvider.java
index 5b04cf94f..40c5d2c31 100644
--- a/plugins/org.eclipse.etrice.generator.cpp/src/org/eclipse/etrice/generator/cpp/gen/CppTranslationProvider.java
+++ b/plugins/org.eclipse.etrice.generator.cpp/src/org/eclipse/etrice/generator/cpp/gen/CppTranslationProvider.java
@@ -12,7 +12,7 @@
package org.eclipse.etrice.generator.cpp.gen;
-import java.util.ArrayList;
+import java.util.List;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.etrice.core.fsm.fSM.AbstractInterfaceItem;
@@ -39,7 +39,7 @@ public class CppTranslationProvider extends DefaultTranslationProvider {
}
@Override
- public String getInterfaceItemMessageText(AbstractInterfaceItem item, EObject abstractMsg, ArrayList<String> args, String index, String orig) {
+ public String getInterfaceItemMessageText(AbstractInterfaceItem item, EObject abstractMsg, List<String> args, String index, String orig) {
if (index==null)
return orig;
diff --git a/plugins/org.eclipse.etrice.generator.fsm/src/org/eclipse/etrice/generator/fsm/base/DefaultFSMTranslationProvider.java b/plugins/org.eclipse.etrice.generator.fsm/src/org/eclipse/etrice/generator/fsm/base/DefaultFSMTranslationProvider.java
index 48311b750..10fcc4dc5 100644
--- a/plugins/org.eclipse.etrice.generator.fsm/src/org/eclipse/etrice/generator/fsm/base/DefaultFSMTranslationProvider.java
+++ b/plugins/org.eclipse.etrice.generator.fsm/src/org/eclipse/etrice/generator/fsm/base/DefaultFSMTranslationProvider.java
@@ -12,7 +12,7 @@
package org.eclipse.etrice.generator.fsm.base;
-import java.util.ArrayList;
+import java.util.List;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.etrice.core.fsm.fSM.AbstractInterfaceItem;
@@ -58,11 +58,11 @@ public class DefaultFSMTranslationProvider implements IFSMTranslationProvider {
/**
* @return the original String
- * @see org.eclipse.etrice.generator.base.ITranslationProvider#getInterfaceItemMessageText(org.eclipse.etrice.core.room.InterfaceItem, org.eclipse.etrice.core.room.Message, java.util.ArrayList, java.lang.String, java.lang.String)
+ * @see org.eclipse.etrice.generator.base.ITranslationProvider#getInterfaceItemMessageText(org.eclipse.etrice.core.room.InterfaceItem, org.eclipse.etrice.core.room.Message, java.util.List, java.lang.String, java.lang.String)
*/
@Override
public String getInterfaceItemMessageText(AbstractInterfaceItem item, EObject msg,
- ArrayList<String> args, String index, String orig) {
+ List<String> args, String index, String orig) {
return orig;
}
diff --git a/plugins/org.eclipse.etrice.generator.fsm/src/org/eclipse/etrice/generator/fsm/base/IFSMTranslationProvider.java b/plugins/org.eclipse.etrice.generator.fsm/src/org/eclipse/etrice/generator/fsm/base/IFSMTranslationProvider.java
index 1f643defd..dc98d0bb0 100644
--- a/plugins/org.eclipse.etrice.generator.fsm/src/org/eclipse/etrice/generator/fsm/base/IFSMTranslationProvider.java
+++ b/plugins/org.eclipse.etrice.generator.fsm/src/org/eclipse/etrice/generator/fsm/base/IFSMTranslationProvider.java
@@ -12,7 +12,7 @@
package org.eclipse.etrice.generator.fsm.base;
-import java.util.ArrayList;
+import java.util.List;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.etrice.core.fsm.fSM.AbstractInterfaceItem;
@@ -49,7 +49,7 @@ public interface IFSMTranslationProvider {
void setContainerClass(EObject container);
/**
- * @return true if translation should be applied to members (attributes, operations and port.msg
+ * @return true if translation should be applied to members (attributes, operations and port.msg)
*/
boolean translateMembers();
@@ -66,7 +66,7 @@ public interface IFSMTranslationProvider {
* @param orig the original text
* @return the translation
*/
- String getInterfaceItemMessageText(AbstractInterfaceItem item, EObject msg, ArrayList<String> args, String index, String orig);
+ String getInterfaceItemMessageText(AbstractInterfaceItem item, EObject msg, List<String> args, String index, String orig);
/**
* @return true if translations are provided for tags
diff --git a/plugins/org.eclipse.etrice.generator.java/src/org/eclipse/etrice/generator/java/gen/JavaTranslationProvider.java b/plugins/org.eclipse.etrice.generator.java/src/org/eclipse/etrice/generator/java/gen/JavaTranslationProvider.java
index cdfdfc660..e7591cf59 100644
--- a/plugins/org.eclipse.etrice.generator.java/src/org/eclipse/etrice/generator/java/gen/JavaTranslationProvider.java
+++ b/plugins/org.eclipse.etrice.generator.java/src/org/eclipse/etrice/generator/java/gen/JavaTranslationProvider.java
@@ -12,12 +12,12 @@
package org.eclipse.etrice.generator.java.gen;
-import java.util.ArrayList;
+import java.util.List;
import org.eclipse.emf.ecore.EObject;
-import org.eclipse.etrice.core.room.Attribute;
import org.eclipse.etrice.core.fsm.fSM.AbstractInterfaceItem;
import org.eclipse.etrice.core.fsm.fSM.DetailCode;
+import org.eclipse.etrice.core.room.Attribute;
import org.eclipse.etrice.core.room.InterfaceItem;
import org.eclipse.etrice.core.room.Message;
import org.eclipse.etrice.generator.base.DefaultTranslationProvider;
@@ -47,7 +47,7 @@ public class JavaTranslationProvider extends DefaultTranslationProvider {
}
@Override
- public String getInterfaceItemMessageText(AbstractInterfaceItem item, EObject abstractMsg, ArrayList<String> args, String index, String orig) {
+ public String getInterfaceItemMessageText(AbstractInterfaceItem item, EObject abstractMsg, List<String> args, String index, String orig) {
if (index==null)
return orig;
diff --git a/plugins/org.eclipse.etrice.generator/src/org/eclipse/etrice/generator/base/DefaultTranslationProvider.java b/plugins/org.eclipse.etrice.generator/src/org/eclipse/etrice/generator/base/DefaultTranslationProvider.java
index c33255324..a9911c4e0 100644
--- a/plugins/org.eclipse.etrice.generator/src/org/eclipse/etrice/generator/base/DefaultTranslationProvider.java
+++ b/plugins/org.eclipse.etrice.generator/src/org/eclipse/etrice/generator/base/DefaultTranslationProvider.java
@@ -12,7 +12,7 @@
package org.eclipse.etrice.generator.base;
-import java.util.ArrayList;
+import java.util.List;
import org.eclipse.etrice.core.fsm.fSM.AbstractInterfaceItem;
import org.eclipse.etrice.core.fsm.fSM.DetailCode;
@@ -72,7 +72,7 @@ public class DefaultTranslationProvider extends DefaultFSMTranslationProvider im
* @see org.eclipse.etrice.generator.base.ITranslationProvider#getOperationText(org.eclipse.etrice.core.room.Operation, java.util.ArrayList, java.lang.String)
*/
@Override
- public String getOperationText(Operation op, ArrayList<String> args, String orig) {
+ public String getOperationText(Operation op, List<String> args, String orig) {
return orig;
}
@@ -122,7 +122,7 @@ public class DefaultTranslationProvider extends DefaultFSMTranslationProvider im
*/
@Override
public String getInterfaceItemOperationText(AbstractInterfaceItem item,
- PortOperation op, ArrayList<String> args, String orig) {
+ PortOperation op, List<String> args, String orig) {
return orig;
}
diff --git a/plugins/org.eclipse.etrice.generator/src/org/eclipse/etrice/generator/base/ITranslationProvider.java b/plugins/org.eclipse.etrice.generator/src/org/eclipse/etrice/generator/base/ITranslationProvider.java
index 6fcd9a79d..603bf709e 100644
--- a/plugins/org.eclipse.etrice.generator/src/org/eclipse/etrice/generator/base/ITranslationProvider.java
+++ b/plugins/org.eclipse.etrice.generator/src/org/eclipse/etrice/generator/base/ITranslationProvider.java
@@ -12,7 +12,7 @@
package org.eclipse.etrice.generator.base;
-import java.util.ArrayList;
+import java.util.List;
import org.eclipse.etrice.core.fsm.fSM.AbstractInterfaceItem;
import org.eclipse.etrice.core.room.Attribute;
@@ -78,7 +78,7 @@ public interface ITranslationProvider extends IFSMTranslationProvider {
* @param orig the original text
* @return the translation
*/
- String getOperationText(Operation op, ArrayList<String> args, String orig);
+ String getOperationText(Operation op, List<String> args, String orig);
/**
* yields a sequence that reads data from a <b>data driven</b> port.
@@ -115,5 +115,5 @@ public interface ITranslationProvider extends IFSMTranslationProvider {
* @return the translation
*/
String getInterfaceItemOperationText(AbstractInterfaceItem item,
- PortOperation op, ArrayList<String> args, String orig);
+ PortOperation op, List<String> args, String orig);
} \ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 1ed77f576..14bb9f669 100644
--- a/pom.xml
+++ b/pom.xml
@@ -27,6 +27,8 @@
<module>plugins/org.eclipse.etrice.core.genmodel.fsm</module>
<module>plugins/org.eclipse.etrice.core.room</module>
<module>plugins/org.eclipse.etrice.core.room.ui</module>
+ <module>plugins/org.eclipse.etrice.dctools.fsm</module>
+ <module>plugins/org.eclipse.etrice.dctools</module>
<module>plugins/org.eclipse.etrice.doc</module>
<module>plugins/org.eclipse.etrice.etunit.converter</module>
<module>plugins/org.eclipse.etrice.expressions.ui</module>
@@ -66,6 +68,7 @@
<module>tests/org.eclipse.etrice.core.genmodel.tests</module>
<module>tests/org.eclipse.etrice.core.genmodel.fsm.tests</module>
<module>tests/org.eclipse.etrice.core.room.tests</module>
+ <module>tests/org.eclipse.etrice.dctools.tests</module>
<module>tests/org.eclipse.etrice.etunit.converter.tests</module>
<module>tests/org.eclipse.etrice.generator.fsmtest.tests</module>
<module>tests/org.eclipse.etrice.generator.tests</module>
diff --git a/releng/org.eclipse.etrice.parent/pom.xml b/releng/org.eclipse.etrice.parent/pom.xml
index 0cf52161d..209632eb9 100644
--- a/releng/org.eclipse.etrice.parent/pom.xml
+++ b/releng/org.eclipse.etrice.parent/pom.xml
@@ -11,11 +11,12 @@
<properties>
<project.build.sourceEncoding>Cp1252</project.build.sourceEncoding>
- <xtext.version>2.12.0</xtext.version>
+ <xtext.version>2.13.0</xtext.version>
<tycho.version>1.0.0</tycho.version>
<cbi.version>1.1.4</cbi.version>
<eclipse.url>http://download.eclipse.org/releases/oxygen</eclipse.url>
+ <xtext.url>http://download.eclipse.org/modeling/tmf/xtext/updates/composite/releases/</xtext.url>
<license.url>http://download.eclipse.org/cbi/updates/license</license.url>
<orbit.url>http://download.eclipse.org/tools/orbit/R-builds/R20170516192513/repository</orbit.url>
<cbi.url>https://repo.eclipse.org/content/repositories/cbi-releases</cbi.url>
@@ -30,6 +31,11 @@
<layout>p2</layout>
</repository>
<repository>
+ <id>xtext</id>
+ <url>${xtext.url}</url>
+ <layout>p2</layout>
+ </repository>
+ <repository>
<id>license</id>
<url>${license.url}</url>
<layout>p2</layout>
diff --git a/tests/org.eclipse.etrice.core.genmodel.tests/org.eclipse.etrice.core.genmodel.tests.launch b/tests/org.eclipse.etrice.core.genmodel.tests/org.eclipse.etrice.core.genmodel.tests.launch
index 06c1560bc..abf91faa4 100644
--- a/tests/org.eclipse.etrice.core.genmodel.tests/org.eclipse.etrice.core.genmodel.tests.launch
+++ b/tests/org.eclipse.etrice.core.genmodel.tests/org.eclipse.etrice.core.genmodel.tests.launch
@@ -29,7 +29,7 @@
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-os ${target.os} -ws ${target.ws} -arch ${target.arch} -nl ${target.nl} -consoleLog"/>
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="org.eclipse.etrice.core.genmodel.tests"/>
<stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.pde.ui.workbenchClasspathProvider"/>
-<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-ea&#13;&#10;-Xmx512m&#13;&#10;-Xms128m&#13;&#10;-XX:PermSize=32m&#13;&#10;-XX:MaxPermSize=256m&#13;&#10;-Dfile.encoding=UTF-8&#13;&#10;-Dosgi.requiredJavaVersion=1.5"/>
+<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-ea&#13;&#10;-Xmx512m&#13;&#10;-Xms128m&#13;&#10;-Dfile.encoding=UTF-8&#13;&#10;-Dosgi.requiredJavaVersion=1.5"/>
<stringAttribute key="pde.version" value="3.3"/>
<stringAttribute key="product" value="org.eclipse.sdk.ide"/>
<booleanAttribute key="run_in_ui_thread" value="false"/>
diff --git a/tests/org.eclipse.etrice.core.room.tests/META-INF/MANIFEST.MF b/tests/org.eclipse.etrice.core.room.tests/META-INF/MANIFEST.MF
index 249e68142..936985085 100644
--- a/tests/org.eclipse.etrice.core.room.tests/META-INF/MANIFEST.MF
+++ b/tests/org.eclipse.etrice.core.room.tests/META-INF/MANIFEST.MF
@@ -14,7 +14,8 @@ Require-Bundle: org.eclipse.etrice.core.room;bundle-version="1.1.1",
org.eclipse.osgi;bundle-version="3.6.0",
org.eclipse.xtext;bundle-version="2.6.0",
org.eclipse.core.runtime;bundle-version="3.6.0",
- org.eclipse.emf.ecore
+ org.eclipse.emf.ecore,
+ org.eclipse.xtext.testing;bundle-version="2.13.0"
Bundle-Activator: org.eclipse.etrice.core.CoreTestsActivator
Bundle-ActivationPolicy: lazy
Export-Package: org.eclipse.etrice.core
diff --git a/tests/org.eclipse.etrice.core.room.tests/src-gen/org/eclipse/etrice/core/room/tests/RoomInjectorProvider.java b/tests/org.eclipse.etrice.core.room.tests/src-gen/org/eclipse/etrice/core/room/tests/RoomInjectorProvider.java
index cccecc6f5..4c7560546 100644
--- a/tests/org.eclipse.etrice.core.room.tests/src-gen/org/eclipse/etrice/core/room/tests/RoomInjectorProvider.java
+++ b/tests/org.eclipse.etrice.core.room.tests/src-gen/org/eclipse/etrice/core/room/tests/RoomInjectorProvider.java
@@ -6,10 +6,10 @@ package org.eclipse.etrice.core.room.tests;
import org.eclipse.etrice.core.RoomRuntimeModule;
import org.eclipse.etrice.core.RoomStandaloneSetup;
-import org.eclipse.xtext.junit4.GlobalRegistries;
-import org.eclipse.xtext.junit4.GlobalRegistries.GlobalStateMemento;
-import org.eclipse.xtext.junit4.IInjectorProvider;
-import org.eclipse.xtext.junit4.IRegistryConfigurator;
+import org.eclipse.xtext.testing.GlobalRegistries;
+import org.eclipse.xtext.testing.GlobalRegistries.GlobalStateMemento;
+import org.eclipse.xtext.testing.IInjectorProvider;
+import org.eclipse.xtext.testing.IRegistryConfigurator;
import com.google.inject.Guice;
import com.google.inject.Injector;
diff --git a/tests/org.eclipse.etrice.core.room.tests/src/org/eclipse/etrice/core/FormatterTest.xtend b/tests/org.eclipse.etrice.core.room.tests/src/org/eclipse/etrice/core/FormatterTest.xtend
index 2a710a92d..35044f72e 100644
--- a/tests/org.eclipse.etrice.core.room.tests/src/org/eclipse/etrice/core/FormatterTest.xtend
+++ b/tests/org.eclipse.etrice.core.room.tests/src/org/eclipse/etrice/core/FormatterTest.xtend
@@ -8,9 +8,9 @@ import java.util.regex.Pattern
import org.eclipse.core.runtime.FileLocator
import org.eclipse.emf.common.util.URI
import org.eclipse.etrice.core.room.tests.RoomInjectorProvider
-import org.eclipse.xtext.junit4.InjectWith
-import org.eclipse.xtext.junit4.XtextRunner
-import org.eclipse.xtext.junit4.formatter.FormatterTester
+import org.eclipse.xtext.testing.InjectWith
+import org.eclipse.xtext.testing.XtextRunner
+import org.eclipse.xtext.testing.formatter.FormatterTestHelper
import org.junit.Test
import org.junit.runner.RunWith
@@ -19,7 +19,7 @@ import static org.junit.Assert.assertNotEquals
@RunWith(XtextRunner)
@InjectWith(RoomInjectorProvider)
-class FormatterTest extends FormatterTester {
+class FormatterTest extends FormatterTestHelper {
// does not work with comments or ccstring
val patterns = #[
diff --git a/tests/org.eclipse.etrice.core.room.tests/src/org/eclipse/etrice/core/TestNames.xtend b/tests/org.eclipse.etrice.core.room.tests/src/org/eclipse/etrice/core/TestNames.xtend
index bc7f587b7..002cfd17d 100644
--- a/tests/org.eclipse.etrice.core.room.tests/src/org/eclipse/etrice/core/TestNames.xtend
+++ b/tests/org.eclipse.etrice.core.room.tests/src/org/eclipse/etrice/core/TestNames.xtend
@@ -38,7 +38,7 @@ class TestNames extends TestBase {
if(it instanceof AbstractValidationDiagnostic){
val obj = it.sourceEObject
var nameError = nameErrorMap.get(obj)
- if(nameError == null) nameError = false
+ if(nameError === null) nameError = false
nameErrorMap.put(obj, (nameError || it.isNameErrorMessage))
}
]
diff --git a/tests/org.eclipse.etrice.dctools.tests/.classpath b/tests/org.eclipse.etrice.dctools.tests/.classpath
new file mode 100644
index 000000000..428337e56
--- /dev/null
+++ b/tests/org.eclipse.etrice.dctools.tests/.classpath
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="src" path="xtend-gen"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/tests/org.eclipse.etrice.dctools.tests/.gitignore b/tests/org.eclipse.etrice.dctools.tests/.gitignore
new file mode 100644
index 000000000..1a7726dc2
--- /dev/null
+++ b/tests/org.eclipse.etrice.dctools.tests/.gitignore
@@ -0,0 +1,4 @@
+bin
+*._trace
+*.smap
+*.xtendbin
diff --git a/tests/org.eclipse.etrice.dctools.tests/.project b/tests/org.eclipse.etrice.dctools.tests/.project
new file mode 100644
index 000000000..fecccdd43
--- /dev/null
+++ b/tests/org.eclipse.etrice.dctools.tests/.project
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.etrice.dctools.tests</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.xtext.ui.shared.xtextBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.eclipse.xtext.ui.shared.xtextNature</nature>
+ </natures>
+</projectDescription>
diff --git a/tests/org.eclipse.etrice.dctools.tests/.settings/org.eclipse.jdt.core.prefs b/tests/org.eclipse.etrice.dctools.tests/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 000000000..0c68a61dc
--- /dev/null
+++ b/tests/org.eclipse.etrice.dctools.tests/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.8
diff --git a/tests/org.eclipse.etrice.dctools.tests/META-INF/MANIFEST.MF b/tests/org.eclipse.etrice.dctools.tests/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..b410cf21b
--- /dev/null
+++ b/tests/org.eclipse.etrice.dctools.tests/META-INF/MANIFEST.MF
@@ -0,0 +1,24 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Expressions UI Tests
+Bundle-SymbolicName: org.eclipse.etrice.dctools.tests;singleton:=true
+Bundle-Version: 1.1.1.qualifier
+Automatic-Module-Name: org.eclipse.etrice.expressions.ui.tests
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
+Bundle-Vendor: Eclipse eTrice
+Require-Bundle: org.junit;bundle-version="4.12.0",
+ org.eclipse.jface.text;bundle-version="3.12.2",
+ org.eclipse.core.runtime;bundle-version="3.13.0",
+ org.eclipse.emf.ecore;bundle-version="2.13.0",
+ com.google.guava,
+ org.eclipse.etrice.dctools,
+ org.eclipse.osgi,
+ org.eclipse.xtext.xbase.lib,
+ org.eclipse.xtend.lib,
+ org.eclipse.xtend.lib.macro,
+ org.eclipse.etrice.core.fsm,
+ org.eclipse.etrice.core.room,
+ org.eclipse.etrice.core.room.tests
+Bundle-ActivationPolicy: lazy
+Bundle-Activator: org.eclipse.etrice.dctools.tests.DCToolsTestsActivator
+
diff --git a/tests/org.eclipse.etrice.dctools.tests/build.properties b/tests/org.eclipse.etrice.dctools.tests/build.properties
new file mode 100644
index 000000000..d8e2f0e92
--- /dev/null
+++ b/tests/org.eclipse.etrice.dctools.tests/build.properties
@@ -0,0 +1,5 @@
+source.. = src/,\
+ xtend-gen/
+output.. = bin/
+bin.includes = META-INF/,\
+ .
diff --git a/tests/org.eclipse.etrice.dctools.tests/models/DetailCodes.room b/tests/org.eclipse.etrice.dctools.tests/models/DetailCodes.room
new file mode 100644
index 000000000..a153e50a9
--- /dev/null
+++ b/tests/org.eclipse.etrice.dctools.tests/models/DetailCodes.room
@@ -0,0 +1,103 @@
+RoomModel DCParserTests {
+
+ import room.basic.types.* from "Types.room"
+
+ async ActorClass AC {
+ Interface {
+ Port prt: PC
+ Port replPrt[2]: PC
+
+ Port dataPort: PCData
+ }
+ Structure {
+ external Port prt
+ external Port replPrt
+ external Port dataPort
+
+ Attribute p[2]: Point
+ Attribute pt: Point
+ Attribute c: Circle
+ }
+ Behavior {
+ Operation distance(p1: Point, p2: Point): float64 '''
+ return p1.distance(p2);
+ '''
+
+ StateMachine {
+ State first {
+ entry '''
+ prt.start();
+
+ Point lpt = new Point(1,2);
+ prt.result(lpt);'''
+ }
+ State second {
+ entry '''
+ double d = c.diameter();
+ d = p[0].distance(p[1]);
+ d = distance(p[0], p[1]);
+ d = c.c.x;
+ '''
+ exit '''
+ replPrt[0].start();
+ replPrt.start();
+ prt[0].start();
+ '''
+ }
+ Transition init0: initial -> first
+ Transition tr0: first -> second {
+ triggers {
+ <circle: prt>
+ }
+ action '''transitionData.west().distance(transitionData.c);'''
+ }
+ State third
+ Transition tr1: second -> third {
+ guard '''true'''
+ action '''pt.set(dataPort.point);'''
+ }
+ }
+ }
+ }
+
+ datadriven ProtocolClass PCData {
+ incoming {
+ Message point(Point)
+ }
+ }
+
+ ProtocolClass PC {
+ incoming {
+ Message point(Point)
+ Message circle(Circle)
+ }
+ outgoing {
+ Message start()
+ Message result(Point)
+ }
+ }
+
+ DataClass Circle {
+ Operation diameter(): float64 '''
+ return 2*r;
+ '''
+ Operation west(): Point '''
+ return new Point(c.x + r, c.y);
+ '''
+ Operation isInside(other: Point): boolean '''
+ return c.distance(other) < r;
+ '''
+ Attribute r: float64
+ Attribute c: Point
+ }
+
+ DataClass Point {
+ Operation distance(other: Point): float64 '''
+ double dx = x - other.x;
+ double dy = y - other.y;
+ return Math.sqrt(dx*dx + dy*dy);
+ '''
+ Attribute x: float64
+ Attribute y: float64
+ }
+}
diff --git a/tests/org.eclipse.etrice.dctools.tests/models/Types.room b/tests/org.eclipse.etrice.dctools.tests/models/Types.room
new file mode 100644
index 000000000..b27d100f4
--- /dev/null
+++ b/tests/org.eclipse.etrice.dctools.tests/models/Types.room
@@ -0,0 +1,13 @@
+RoomModel room.basic.types {
+
+ PrimitiveType boolean: ptBoolean -> 'boolean' (Boolean) default 'false'
+ PrimitiveType char: ptCharacter -> 'char' (Char) default ''
+ PrimitiveType int8: ptInteger -> 'byte' (Byte) default '0'
+ PrimitiveType int16: ptInteger -> 'short' (Short) default '0'
+ PrimitiveType int32: ptInteger -> 'int' (Integer) default '0'
+ PrimitiveType int64: ptInteger -> 'long' (Long) default '0'
+ PrimitiveType float32: ptReal -> 'float' (Float) default '0'
+ PrimitiveType float64: ptReal -> 'double' (Double) default '0'
+ PrimitiveType string: ptCharacter -> 'String' (String) default ''
+
+} \ No newline at end of file
diff --git a/tests/org.eclipse.etrice.dctools.tests/models/diagrams/DCParserTests.AC.behavior b/tests/org.eclipse.etrice.dctools.tests/models/diagrams/DCParserTests.AC.behavior
new file mode 100644
index 000000000..2164fa1e3
--- /dev/null
+++ b/tests/org.eclipse.etrice.dctools.tests/models/diagrams/DCParserTests.AC.behavior
@@ -0,0 +1,184 @@
+<?xml version="1.0" encoding="ASCII"?>
+<pi:Diagram xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:al="http://eclipse.org/graphiti/mm/algorithms" xmlns:pi="http://eclipse.org/graphiti/mm/pictograms" visible="true" gridUnit="10" diagramTypeId="room.behavior" name="Behavior of AC" pictogramLinks="//@link //@children.0/@link //@children.0/@children.1/@link //@children.0/@children.2/@link //@children.0/@children.3/@link //@connections.0/@link //@connections.1/@link //@children.0/@children.4/@link //@connections.2/@link" verticalGridUnit="10" version="0.14.0">
+ <graphicsAlgorithm xsi:type="al:Rectangle" background="//@colors.1" foreground="//@colors.0" lineWidth="1" transparency="0.0" width="1000" height="1000"/>
+ <link>
+ <businessObjects href="../DetailCodes.room#ActorClass:AC"/>
+ </link>
+ <children xsi:type="pi:ContainerShape" visible="true" active="true">
+ <properties key="obj-type" value="sg"/>
+ <graphicsAlgorithm xsi:type="al:Rectangle" lineWidth="1" filled="false" lineVisible="false" transparency="0.0" width="880" height="580" x="40" y="40">
+ <graphicsAlgorithmChildren xsi:type="al:RoundedRectangle" background="//@colors.1" foreground="//@colors.2" lineWidth="4" transparency="0.5" width="800" height="500" x="40" y="40" cornerHeight="20" cornerWidth="20"/>
+ <graphicsAlgorithmChildren xsi:type="al:RoundedRectangle" foreground="//@colors.2" lineWidth="4" filled="false" transparency="0.0" width="800" height="500" x="40" y="40" cornerHeight="20" cornerWidth="20"/>
+ </graphicsAlgorithm>
+ <link>
+ <businessObjects href="../DetailCodes.room#StateGraph:AC$sg"/>
+ </link>
+ <children visible="true">
+ <graphicsAlgorithm xsi:type="al:Text" background="//@colors.2" foreground="//@colors.2" lineWidth="1" filled="false" transparency="0.0" width="800" height="80" y="40" font="//@fonts.1" horizontalAlignment="ALIGNMENT_RIGHT" verticalAlignment="ALIGNMENT_TOP" value="/"/>
+ </children>
+ <children xsi:type="pi:ContainerShape" visible="true" active="true">
+ <properties key="obj-type" value="state"/>
+ <graphicsAlgorithm xsi:type="al:Rectangle" lineWidth="1" filled="false" lineVisible="false" transparency="0.0" width="120" height="90" x="187" y="150">
+ <graphicsAlgorithmChildren xsi:type="al:RoundedRectangle" background="//@colors.3" foreground="//@colors.2" lineWidth="1" transparency="0.0" width="60" height="30" x="30" y="30" cornerHeight="20" cornerWidth="20">
+ <graphicsAlgorithmChildren xsi:type="al:RoundedRectangle" foreground="//@colors.2" lineWidth="1" filled="false" lineVisible="false" transparency="0.0" width="15" height="8" x="35" y="3" cornerHeight="5" cornerWidth="5"/>
+ <graphicsAlgorithmChildren xsi:type="al:Polygon" foreground="//@colors.2" lineWidth="1" filled="false" lineVisible="true" transparency="0.0" x="30" y="24">
+ <points x="-3" y="-3"/>
+ <points x="-3" y="3"/>
+ <points x="-11" y="3"/>
+ </graphicsAlgorithmChildren>
+ <graphicsAlgorithmChildren xsi:type="al:Polygon" foreground="//@colors.2" lineWidth="1" filled="false" lineVisible="false" transparency="0.0" x="30" y="24">
+ <points x="3" y="-3"/>
+ <points x="3" y="3"/>
+ <points x="11" y="3"/>
+ </graphicsAlgorithmChildren>
+ <graphicsAlgorithmChildren xsi:type="al:Polygon" foreground="//@colors.2" lineWidth="1" filled="false" lineVisible="false" transparency="0.0" x="30" y="24">
+ <points x="-2" y="-3"/>
+ <points x="-2" y="3"/>
+ <points x="2" y="3"/>
+ <points x="2" y="-3"/>
+ </graphicsAlgorithmChildren>
+ </graphicsAlgorithmChildren>
+ </graphicsAlgorithm>
+ <link>
+ <businessObjects href="../DetailCodes.room#SimpleState:AC$first"/>
+ </link>
+ <anchors xsi:type="pi:ChopboxAnchor" outgoingConnections="//@connections.1" incomingConnections="//@connections.0"/>
+ <children visible="true">
+ <graphicsAlgorithm xsi:type="al:Text" background="//@colors.2" foreground="//@colors.2" lineWidth="1" filled="false" transparency="0.0" width="60" height="30" x="30" y="30" font="//@fonts.0" horizontalAlignment="ALIGNMENT_CENTER" value="first"/>
+ </children>
+ </children>
+ <children xsi:type="pi:ContainerShape" visible="true" active="true">
+ <properties key="obj-type" value="state"/>
+ <graphicsAlgorithm xsi:type="al:Rectangle" lineWidth="1" filled="false" lineVisible="false" transparency="0.0" width="120" height="90" x="457" y="281">
+ <graphicsAlgorithmChildren xsi:type="al:RoundedRectangle" background="//@colors.3" foreground="//@colors.2" lineWidth="1" transparency="0.0" width="60" height="30" x="30" y="30" cornerHeight="20" cornerWidth="20">
+ <graphicsAlgorithmChildren xsi:type="al:RoundedRectangle" foreground="//@colors.2" lineWidth="1" filled="false" lineVisible="false" transparency="0.0" width="15" height="8" x="35" y="3" cornerHeight="5" cornerWidth="5"/>
+ <graphicsAlgorithmChildren xsi:type="al:Polygon" foreground="//@colors.2" lineWidth="1" filled="false" lineVisible="true" transparency="0.0" x="30" y="24">
+ <points x="-3" y="-3"/>
+ <points x="-3" y="3"/>
+ <points x="-11" y="3"/>
+ </graphicsAlgorithmChildren>
+ <graphicsAlgorithmChildren xsi:type="al:Polygon" foreground="//@colors.2" lineWidth="1" filled="false" lineVisible="true" transparency="0.0" x="30" y="24">
+ <points x="3" y="-3"/>
+ <points x="3" y="3"/>
+ <points x="11" y="3"/>
+ </graphicsAlgorithmChildren>
+ <graphicsAlgorithmChildren xsi:type="al:Polygon" foreground="//@colors.2" lineWidth="1" filled="false" lineVisible="false" transparency="0.0" x="30" y="24">
+ <points x="-2" y="-3"/>
+ <points x="-2" y="3"/>
+ <points x="2" y="3"/>
+ <points x="2" y="-3"/>
+ </graphicsAlgorithmChildren>
+ </graphicsAlgorithmChildren>
+ </graphicsAlgorithm>
+ <link>
+ <businessObjects href="../DetailCodes.room#SimpleState:AC$second"/>
+ </link>
+ <anchors xsi:type="pi:ChopboxAnchor" outgoingConnections="//@connections.2" incomingConnections="//@connections.1"/>
+ <children visible="true">
+ <graphicsAlgorithm xsi:type="al:Text" background="//@colors.2" foreground="//@colors.2" lineWidth="1" filled="false" transparency="0.0" width="60" height="30" x="30" y="30" font="//@fonts.0" horizontalAlignment="ALIGNMENT_CENTER" value="second"/>
+ </children>
+ </children>
+ <children xsi:type="pi:ContainerShape" visible="true" active="true">
+ <properties key="obj-type" value="ini"/>
+ <graphicsAlgorithm xsi:type="al:Rectangle" lineWidth="1" filled="false" lineVisible="false" transparency="0.0" width="40" height="40" x="90" y="77">
+ <graphicsAlgorithmChildren xsi:type="al:Ellipse" background="//@colors.1" foreground="//@colors.2" lineWidth="2" transparency="0.0" width="20" height="20" x="10" y="10"/>
+ </graphicsAlgorithm>
+ <link>
+ <businessObjects href="../DetailCodes.room#StateGraph:AC$sg"/>
+ </link>
+ <anchors xsi:type="pi:ChopboxAnchor" outgoingConnections="//@connections.0"/>
+ <children visible="true">
+ <graphicsAlgorithm xsi:type="al:Text" background="//@colors.4" foreground="//@colors.4" lineWidth="1" filled="false" transparency="0.0" width="40" height="20" y="10" font="//@fonts.0" horizontalAlignment="ALIGNMENT_CENTER" value="I"/>
+ </children>
+ </children>
+ <children xsi:type="pi:ContainerShape" visible="true" active="true">
+ <properties key="obj-type" value="state"/>
+ <graphicsAlgorithm xsi:type="al:Rectangle" lineWidth="1" filled="false" lineVisible="false" transparency="0.0" width="120" height="90" x="560" y="91">
+ <graphicsAlgorithmChildren xsi:type="al:RoundedRectangle" background="//@colors.3" foreground="//@colors.2" lineWidth="1" transparency="0.0" width="60" height="30" x="30" y="30" cornerHeight="20" cornerWidth="20">
+ <graphicsAlgorithmChildren xsi:type="al:RoundedRectangle" foreground="//@colors.2" lineWidth="1" filled="false" lineVisible="false" transparency="0.0" width="15" height="8" x="35" y="3" cornerHeight="5" cornerWidth="5"/>
+ <graphicsAlgorithmChildren xsi:type="al:Polygon" foreground="//@colors.2" lineWidth="1" filled="false" lineVisible="false" transparency="0.0" x="30" y="24">
+ <points x="-3" y="-3"/>
+ <points x="-3" y="3"/>
+ <points x="-11" y="3"/>
+ </graphicsAlgorithmChildren>
+ <graphicsAlgorithmChildren xsi:type="al:Polygon" foreground="//@colors.2" lineWidth="1" filled="false" lineVisible="false" transparency="0.0" x="30" y="24">
+ <points x="3" y="-3"/>
+ <points x="3" y="3"/>
+ <points x="11" y="3"/>
+ </graphicsAlgorithmChildren>
+ <graphicsAlgorithmChildren xsi:type="al:Polygon" foreground="//@colors.2" lineWidth="1" filled="false" lineVisible="false" transparency="0.0" x="30" y="24">
+ <points x="-2" y="-3"/>
+ <points x="-2" y="3"/>
+ <points x="2" y="3"/>
+ <points x="2" y="-3"/>
+ </graphicsAlgorithmChildren>
+ </graphicsAlgorithmChildren>
+ </graphicsAlgorithm>
+ <link>
+ <businessObjects href="../DetailCodes.room#SimpleState:AC$third"/>
+ </link>
+ <anchors xsi:type="pi:ChopboxAnchor" incomingConnections="//@connections.2" referencedGraphicsAlgorithm="//@children.0/@children.4/@graphicsAlgorithm/@graphicsAlgorithmChildren.0"/>
+ <children visible="true">
+ <graphicsAlgorithm xsi:type="al:Text" background="//@colors.2" foreground="//@colors.2" lineWidth="1" filled="false" transparency="0.0" width="60" height="30" x="30" y="30" font="//@fonts.0" horizontalAlignment="ALIGNMENT_CENTER" value="third"/>
+ </children>
+ </children>
+ </children>
+ <connections xsi:type="pi:FreeFormConnection" visible="true" active="true" start="//@children.0/@children.3/@anchors.0" end="//@children.0/@children.1/@anchors.0">
+ <properties key="obj-type" value="trans"/>
+ <graphicsAlgorithm xsi:type="al:Polyline" foreground="//@colors.2" lineWidth="1" filled="false" transparency="0.0"/>
+ <link>
+ <businessObjects href="../DetailCodes.room#InitialTransition:AC$initial"/>
+ </link>
+ <connectionDecorators visible="true" locationRelative="true" location="1.0">
+ <graphicsAlgorithm xsi:type="al:Polygon" background="//@colors.1" foreground="//@colors.2" lineWidth="1" filled="true" transparency="0.0">
+ <points x="-15" y="5"/>
+ <points/>
+ <points x="-15" y="-5"/>
+ </graphicsAlgorithm>
+ </connectionDecorators>
+ <connectionDecorators visible="true" active="true" locationRelative="true" location="0.5">
+ <graphicsAlgorithm xsi:type="al:Text" foreground="//@colors.2" lineWidth="1" filled="false" transparency="0.0" x="10" font="//@fonts.0" value="init"/>
+ </connectionDecorators>
+ </connections>
+ <connections xsi:type="pi:FreeFormConnection" visible="true" active="true" start="//@children.0/@children.1/@anchors.0" end="//@children.0/@children.2/@anchors.0">
+ <properties key="obj-type" value="trans"/>
+ <graphicsAlgorithm xsi:type="al:Polyline" foreground="//@colors.2" lineWidth="1" filled="false" transparency="0.0"/>
+ <link>
+ <businessObjects href="../DetailCodes.room#TriggeredTransition:AC$tr0"/>
+ </link>
+ <connectionDecorators visible="true" locationRelative="true" location="1.0">
+ <graphicsAlgorithm xsi:type="al:Polygon" background="//@colors.2" foreground="//@colors.2" lineWidth="1" filled="true" transparency="0.0">
+ <points x="-15" y="5"/>
+ <points/>
+ <points x="-15" y="-5"/>
+ </graphicsAlgorithm>
+ </connectionDecorators>
+ <connectionDecorators visible="true" active="true" locationRelative="true" location="0.5">
+ <graphicsAlgorithm xsi:type="al:Text" foreground="//@colors.2" lineWidth="1" filled="false" transparency="0.0" x="10" font="//@fonts.0" value="tr0: &lt;circle:prt>"/>
+ </connectionDecorators>
+ </connections>
+ <connections xsi:type="pi:FreeFormConnection" visible="true" active="true" start="//@children.0/@children.2/@anchors.0" end="//@children.0/@children.4/@anchors.0">
+ <properties key="obj-type" value="trans"/>
+ <graphicsAlgorithm xsi:type="al:Polyline" foreground="//@colors.2" lineWidth="1" filled="false" transparency="0.0"/>
+ <link>
+ <businessObjects href="../DetailCodes.room#GuardedTransition:AC$tr1"/>
+ </link>
+ <connectionDecorators visible="true" locationRelative="true" location="1.0">
+ <graphicsAlgorithm xsi:type="al:Polygon" background="//@colors.2" foreground="//@colors.2" lineWidth="1" filled="true" transparency="0.0">
+ <points x="-15" y="5"/>
+ <points/>
+ <points x="-15" y="-5"/>
+ </graphicsAlgorithm>
+ </connectionDecorators>
+ <connectionDecorators visible="true" active="true" locationRelative="true" location="0.5">
+ <graphicsAlgorithm xsi:type="al:Text" foreground="//@colors.2" lineWidth="1" filled="false" transparency="0.0" x="10" font="//@fonts.0" value="tr1: guard {true}"/>
+ </connectionDecorators>
+ </connections>
+ <colors red="227" green="238" blue="249"/>
+ <colors red="255" green="255" blue="255"/>
+ <colors/>
+ <colors red="200" green="200" blue="200"/>
+ <colors red="100" green="100" blue="100"/>
+ <fonts name="Arial" size="8"/>
+ <fonts name="Arial" size="9" bold="true"/>
+</pi:Diagram>
diff --git a/tests/org.eclipse.etrice.dctools.tests/models/diagrams/DCParserTests.AC.structure b/tests/org.eclipse.etrice.dctools.tests/models/diagrams/DCParserTests.AC.structure
new file mode 100644
index 000000000..54817afc0
--- /dev/null
+++ b/tests/org.eclipse.etrice.dctools.tests/models/diagrams/DCParserTests.AC.structure
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="ASCII"?>
+<pi:Diagram xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:al="http://eclipse.org/graphiti/mm/algorithms" xmlns:pi="http://eclipse.org/graphiti/mm/pictograms" visible="true" gridUnit="10" diagramTypeId="room.structure" name="Structure of AC" pictogramLinks="//@link //@children.0/@link //@children.0/@children.0/@link //@children.0/@children.1/@link //@children.0/@children.2/@link" verticalGridUnit="10" version="0.14.0">
+ <graphicsAlgorithm xsi:type="al:Rectangle" background="//@colors.1" foreground="//@colors.0" lineWidth="1" transparency="0.0" width="1000" height="1000"/>
+ <link>
+ <businessObjects href="../DetailCodes.room#ActorClass:AC"/>
+ </link>
+ <children xsi:type="pi:ContainerShape" visible="true" active="true">
+ <properties key="obj-type" value="cls"/>
+ <graphicsAlgorithm xsi:type="al:Rectangle" lineWidth="1" filled="false" lineVisible="false" transparency="0.0" width="880" height="580" x="40" y="40">
+ <graphicsAlgorithmChildren xsi:type="al:Rectangle" background="//@colors.1" foreground="//@colors.2" lineWidth="1" lineVisible="false" transparency="0.5" width="800" height="500" x="40" y="40"/>
+ <graphicsAlgorithmChildren xsi:type="al:Rectangle" foreground="//@colors.2" lineWidth="4" filled="false" transparency="0.0" width="800" height="500" x="40" y="40"/>
+ </graphicsAlgorithm>
+ <link>
+ <businessObjects href="../DetailCodes.room#ActorClass:AC"/>
+ </link>
+ <children xsi:type="pi:ContainerShape" visible="true" active="true">
+ <properties key="obj-type" value="port"/>
+ <properties key="inherited" value="false"/>
+ <properties key="item-kind" value=""/>
+ <graphicsAlgorithm xsi:type="al:Rectangle" lineWidth="1" filled="false" lineVisible="false" transparency="0.0" width="80" height="80" x="379" y="500">
+ <graphicsAlgorithmChildren xsi:type="al:Rectangle" background="//@colors.2" foreground="//@colors.2" lineWidth="2" transparency="0.0" width="40" height="40" x="20" y="20"/>
+ <graphicsAlgorithmChildren xsi:type="al:Ellipse" background="//@colors.1" foreground="//@colors.1" lineWidth="2" transparency="0.0" width="20" height="20" x="30" y="30"/>
+ </graphicsAlgorithm>
+ <link>
+ <businessObjects href="../DetailCodes.room#Port:AC$prt"/>
+ </link>
+ <anchors xsi:type="pi:ChopboxAnchor" referencedGraphicsAlgorithm="//@children.0/@children.0/@graphicsAlgorithm/@graphicsAlgorithmChildren.0"/>
+ <children visible="true">
+ <graphicsAlgorithm xsi:type="al:Text" foreground="//@colors.2" lineWidth="1" filled="false" transparency="0.0" width="80" height="20" y="60" font="//@fonts.0" horizontalAlignment="ALIGNMENT_CENTER" value="prt"/>
+ </children>
+ </children>
+ <children xsi:type="pi:ContainerShape" visible="true" active="true">
+ <properties key="obj-type" value="port"/>
+ <properties key="inherited" value="false"/>
+ <properties key="item-kind" value="M"/>
+ <graphicsAlgorithm xsi:type="al:Rectangle" lineWidth="1" filled="false" lineVisible="false" transparency="0.0" width="80" height="80" x="374">
+ <graphicsAlgorithmChildren xsi:type="al:Rectangle" background="//@colors.1" foreground="//@colors.2" lineWidth="2" transparency="0.0" width="40" height="40" x="25" y="15"/>
+ <graphicsAlgorithmChildren xsi:type="al:Rectangle" background="//@colors.2" foreground="//@colors.2" lineWidth="2" transparency="0.0" width="40" height="40" x="20" y="20"/>
+ <graphicsAlgorithmChildren xsi:type="al:Ellipse" background="//@colors.1" foreground="//@colors.1" lineWidth="2" transparency="0.0" width="20" height="20" x="30" y="30"/>
+ </graphicsAlgorithm>
+ <link>
+ <businessObjects href="../DetailCodes.room#Port:AC$replPrt"/>
+ </link>
+ <anchors xsi:type="pi:ChopboxAnchor" referencedGraphicsAlgorithm="//@children.0/@children.1/@graphicsAlgorithm/@graphicsAlgorithmChildren.1"/>
+ <children visible="true">
+ <graphicsAlgorithm xsi:type="al:Text" foreground="//@colors.2" lineWidth="1" filled="false" transparency="0.0" width="80" height="20" font="//@fonts.0" horizontalAlignment="ALIGNMENT_CENTER" value="replPrt"/>
+ </children>
+ </children>
+ <children xsi:type="pi:ContainerShape" visible="true" active="true">
+ <properties key="obj-type" value="port"/>
+ <properties key="inherited" value="false"/>
+ <properties key="item-kind" value=""/>
+ <graphicsAlgorithm xsi:type="al:Rectangle" lineWidth="1" filled="false" lineVisible="false" transparency="0.0" width="80" height="80" x="800" y="214">
+ <graphicsAlgorithmChildren xsi:type="al:Rectangle" background="//@colors.2" foreground="//@colors.2" lineWidth="2" transparency="0.0" width="40" height="40" x="20" y="20"/>
+ <graphicsAlgorithmChildren xsi:type="al:Ellipse" background="//@colors.1" foreground="//@colors.1" lineWidth="2" transparency="0.0" width="20" height="20" x="30" y="30"/>
+ </graphicsAlgorithm>
+ <link>
+ <businessObjects href="../DetailCodes.room#Port:AC$dataPort"/>
+ </link>
+ <anchors xsi:type="pi:ChopboxAnchor" referencedGraphicsAlgorithm="//@children.0/@children.2/@graphicsAlgorithm/@graphicsAlgorithmChildren.0"/>
+ <children visible="true">
+ <graphicsAlgorithm xsi:type="al:Text" foreground="//@colors.2" lineWidth="1" filled="false" transparency="0.0" width="80" height="20" y="60" font="//@fonts.0" horizontalAlignment="ALIGNMENT_RIGHT" value="dataPort"/>
+ </children>
+ </children>
+ </children>
+ <colors red="227" green="238" blue="249"/>
+ <colors red="255" green="255" blue="255"/>
+ <colors/>
+ <fonts name="Arial" size="8"/>
+</pi:Diagram>
diff --git a/tests/org.eclipse.etrice.dctools.tests/org.eclipse.etrice.dctools.tests - plugin-test.launch b/tests/org.eclipse.etrice.dctools.tests/org.eclipse.etrice.dctools.tests - plugin-test.launch
new file mode 100644
index 000000000..0d1aa7c91
--- /dev/null
+++ b/tests/org.eclipse.etrice.dctools.tests/org.eclipse.etrice.dctools.tests - plugin-test.launch
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<launchConfiguration type="org.eclipse.pde.ui.JunitLaunchConfig">
+<booleanAttribute key="append.args" value="true"/>
+<stringAttribute key="application" value="org.eclipse.pde.junit.runtime.coretestapplication"/>
+<booleanAttribute key="askclear" value="false"/>
+<booleanAttribute key="automaticAdd" value="true"/>
+<booleanAttribute key="automaticValidate" value="false"/>
+<stringAttribute key="bootstrap" value=""/>
+<stringAttribute key="checked" value="[NONE]"/>
+<booleanAttribute key="clearConfig" value="true"/>
+<booleanAttribute key="clearws" value="true"/>
+<booleanAttribute key="clearwslog" value="false"/>
+<stringAttribute key="configLocation" value="${workspace_loc}/.metadata/.plugins/org.eclipse.pde.core/pde-junit"/>
+<booleanAttribute key="default" value="true"/>
+<stringAttribute key="deselected_workspace_plugins" value="my.etrice.generator,my.etrice.generator.launch,org.eclipse.etrice.abstractexec.behavior,org.eclipse.etrice.abstractexec.behavior.tests,org.eclipse.etrice.core.common.tests,org.eclipse.etrice.core.common.ui,org.eclipse.etrice.core.config,org.eclipse.etrice.core.config.tests,org.eclipse.etrice.core.config.ui,org.eclipse.etrice.core.etmap.tests,org.eclipse.etrice.core.etmap.ui,org.eclipse.etrice.core.etphys.tests,org.eclipse.etrice.core.etphys.ui,org.eclipse.etrice.core.fsm.tests,org.eclipse.etrice.core.fsm.ui,org.eclipse.etrice.core.genmodel.fsm.tests,org.eclipse.etrice.core.genmodel.tests,org.eclipse.etrice.core.room.ui,org.eclipse.etrice.doc,org.eclipse.etrice.etunit.converter,org.eclipse.etrice.etunit.converter.tests,org.eclipse.etrice.generator.c,org.eclipse.etrice.generator.config,org.eclipse.etrice.generator.cpp,org.eclipse.etrice.generator.doc,org.eclipse.etrice.generator.fsmtest,org.eclipse.etrice.generator.fsmtest.tests,org.eclipse.etrice.generator.fsmtest.ui,org.eclipse.etrice.generator.gnuplot,org.eclipse.etrice.generator.java,org.eclipse.etrice.generator.launch,org.eclipse.etrice.generator.launch.c,org.eclipse.etrice.generator.launch.cpp,org.eclipse.etrice.generator.launch.java,org.eclipse.etrice.generator.tests,org.eclipse.etrice.generator.ui,org.eclipse.etrice.generator.ui.cdt,org.eclipse.etrice.modellib.java,org.eclipse.etrice.runtime.java,org.eclipse.etrice.runtime.java.aspects,org.eclipse.etrice.ui.base.tests,org.eclipse.etrice.ui.behavior,org.eclipse.etrice.ui.behavior.actioneditor,org.eclipse.etrice.ui.behavior.fsm,org.eclipse.etrice.ui.behavior.tests,org.eclipse.etrice.ui.commands,org.eclipse.etrice.ui.common,org.eclipse.etrice.ui.common.base,org.eclipse.etrice.ui.runtime,org.eclipse.etrice.ui.structure,org.eclipse.etrice.ui.structure.tests"/>
+<booleanAttribute key="includeOptional" value="true"/>
+<stringAttribute key="location" value="${workspace_loc}/../junit-workspace"/>
+<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
+<listEntry value="/org.eclipse.etrice.dctools.tests"/>
+</listAttribute>
+<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
+<listEntry value="4"/>
+</listAttribute>
+<stringAttribute key="org.eclipse.jdt.junit.CONTAINER" value="=org.eclipse.etrice.dctools.tests"/>
+<booleanAttribute key="org.eclipse.jdt.junit.KEEPRUNNING_ATTR" value="false"/>
+<stringAttribute key="org.eclipse.jdt.junit.TESTNAME" value=""/>
+<stringAttribute key="org.eclipse.jdt.junit.TEST_KIND" value="org.eclipse.jdt.junit.loader.junit4"/>
+<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="true"/>
+<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value=""/>
+<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-os ${target.os} -ws ${target.ws} -arch ${target.arch} -nl ${target.nl} -consoleLog"/>
+<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="org.eclipse.etrice.dctools.tests"/>
+<stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.pde.ui.workbenchClasspathProvider"/>
+<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-ea&#13;&#10;-Xmx512m&#13;&#10;-Xms128m&#13;&#10;-Dfile.encoding=UTF-8&#13;&#10;-Dosgi.requiredJavaVersion=1.8"/>
+<stringAttribute key="pde.version" value="3.3"/>
+<stringAttribute key="product" value="org.eclipse.platform.ide"/>
+<booleanAttribute key="run_in_ui_thread" value="true"/>
+<stringAttribute key="selected_target_plugins" value="com.google.guava*21.0.0.v20170206-1425@default:default,com.google.inject.multibindings@default:false,com.google.inject@default:default,com.ibm.icu@default:default,com.jcraft.jsch@default:default,com.jcraft.jzlib@default:default,de.itemis.xtext.antlr@default:default,javax.annotation@default:default,javax.inject@default:default,javax.servlet*3.1.0.v201410161800@default:default,javax.xml@default:default,org.antlr.generator@default:default,org.antlr.runtime*4.3.0.v201502022030@default:default,org.apache.ant@default:default,org.apache.batik.css*1.8.0.v20170214-1941@default:default,org.apache.batik.util*1.8.0.v20170214-1941@default:default,org.apache.commons.cli@default:default,org.apache.commons.io@default:default,org.apache.commons.jxpath@default:default,org.apache.commons.lang@default:default,org.apache.commons.logging@default:default,org.apache.felix.gogo.command@default:default,org.apache.felix.gogo.runtime@default:default,org.apache.log4j@default:default,org.apache.lucene.analyzers-common@default:default,org.apache.lucene.analyzers-smartcn@default:default,org.apache.lucene.core*6.1.0.v20170814-1820@default:default,org.apache.lucene.misc@default:default,org.apache.xml.resolver@default:default,org.eclipse.ant.core@default:default,org.eclipse.ant.launching@default:default,org.eclipse.ant.ui@default:default,org.eclipse.compare.core@default:default,org.eclipse.compare@default:default,org.eclipse.core.commands@default:default,org.eclipse.core.contenttype@default:default,org.eclipse.core.databinding.observable@default:default,org.eclipse.core.databinding.property@default:default,org.eclipse.core.databinding@default:default,org.eclipse.core.expressions@default:default,org.eclipse.core.externaltools@default:default,org.eclipse.core.filebuffers@default:default,org.eclipse.core.filesystem.win32.x86_64@default:false,org.eclipse.core.filesystem@default:default,org.eclipse.core.jobs@default:default,org.eclipse.core.net.win32.x86_64@default:false,org.eclipse.core.net@default:default,org.eclipse.core.resources.win32.x86_64@default:false,org.eclipse.core.resources@default:default,org.eclipse.core.runtime@default:true,org.eclipse.core.variables@default:default,org.eclipse.debug.core@default:default,org.eclipse.debug.ui@default:default,org.eclipse.e4.core.commands@default:default,org.eclipse.e4.core.contexts@default:default,org.eclipse.e4.core.di.annotations@default:default,org.eclipse.e4.core.di.extensions.supplier@default:default,org.eclipse.e4.core.di.extensions@default:default,org.eclipse.e4.core.di@default:default,org.eclipse.e4.core.services@default:default,org.eclipse.e4.emf.xpath@default:default,org.eclipse.e4.ui.bindings@default:default,org.eclipse.e4.ui.css.core@default:default,org.eclipse.e4.ui.css.swt.theme@default:default,org.eclipse.e4.ui.css.swt@default:default,org.eclipse.e4.ui.di@default:default,org.eclipse.e4.ui.model.workbench@default:default,org.eclipse.e4.ui.services@default:default,org.eclipse.e4.ui.widgets@default:default,org.eclipse.e4.ui.workbench.addons.swt@default:default,org.eclipse.e4.ui.workbench.renderers.swt@default:default,org.eclipse.e4.ui.workbench.swt@default:default,org.eclipse.e4.ui.workbench3@default:default,org.eclipse.e4.ui.workbench@default:default,org.eclipse.emf.codegen.ecore@default:default,org.eclipse.emf.codegen@default:default,org.eclipse.emf.common.ui@default:default,org.eclipse.emf.common@default:default,org.eclipse.emf.ecore.change@default:default,org.eclipse.emf.ecore.edit@default:default,org.eclipse.emf.ecore.editor@default:default,org.eclipse.emf.ecore.xmi@default:default,org.eclipse.emf.ecore@default:default,org.eclipse.emf.edit.ui@default:default,org.eclipse.emf.edit@default:default,org.eclipse.emf.mwe.core@default:default,org.eclipse.emf.mwe.utils@default:default,org.eclipse.emf.mwe2.language@default:default,org.eclipse.emf.mwe2.launch@default:default,org.eclipse.emf.mwe2.lib@default:default,org.eclipse.emf.mwe2.runtime@default:default,org.eclipse.emf@default:default,org.eclipse.equinox.app@default:default,org.eclipse.equinox.bidi@default:default,org.eclipse.equinox.common@2:true,org.eclipse.equinox.frameworkadmin.equinox@default:default,org.eclipse.equinox.frameworkadmin@default:default,org.eclipse.equinox.http.jetty@default:default,org.eclipse.equinox.http.servlet@default:default,org.eclipse.equinox.p2.artifact.repository@default:default,org.eclipse.equinox.p2.core@default:default,org.eclipse.equinox.p2.director.app@default:default,org.eclipse.equinox.p2.director@default:default,org.eclipse.equinox.p2.engine@default:default,org.eclipse.equinox.p2.garbagecollector@default:default,org.eclipse.equinox.p2.jarprocessor@default:default,org.eclipse.equinox.p2.metadata.repository@default:default,org.eclipse.equinox.p2.metadata@default:default,org.eclipse.equinox.p2.operations@default:default,org.eclipse.equinox.p2.publisher.eclipse@default:default,org.eclipse.equinox.p2.publisher@default:default,org.eclipse.equinox.p2.repository.tools@default:default,org.eclipse.equinox.p2.repository@default:default,org.eclipse.equinox.p2.touchpoint.eclipse@default:default,org.eclipse.equinox.p2.ui@default:default,org.eclipse.equinox.p2.updatesite@default:default,org.eclipse.equinox.preferences@default:default,org.eclipse.equinox.registry@default:default,org.eclipse.equinox.security.ui@default:default,org.eclipse.equinox.security.win32.x86_64@default:false,org.eclipse.equinox.security@default:default,org.eclipse.equinox.simpleconfigurator.manipulator@default:default,org.eclipse.equinox.simpleconfigurator@1:true,org.eclipse.help.base@default:default,org.eclipse.help.ui@default:default,org.eclipse.help@default:default,org.eclipse.jdt.compiler.apt@default:false,org.eclipse.jdt.compiler.tool@default:false,org.eclipse.jdt.core.manipulation@default:default,org.eclipse.jdt.core@default:default,org.eclipse.jdt.debug.ui@default:default,org.eclipse.jdt.debug@default:default,org.eclipse.jdt.junit.core@default:default,org.eclipse.jdt.junit.runtime@default:default,org.eclipse.jdt.junit@default:default,org.eclipse.jdt.launching@default:default,org.eclipse.jdt.ui@default:default,org.eclipse.jetty.http@default:default,org.eclipse.jetty.io@default:default,org.eclipse.jetty.security@default:default,org.eclipse.jetty.server@default:default,org.eclipse.jetty.servlet@default:default,org.eclipse.jetty.util@default:default,org.eclipse.jface.databinding@default:default,org.eclipse.jface.text@default:default,org.eclipse.jface@default:default,org.eclipse.ltk.core.refactoring@default:default,org.eclipse.ltk.ui.refactoring@default:default,org.eclipse.osgi.compatibility.state@default:false,org.eclipse.osgi.services@default:default,org.eclipse.osgi.util@default:default,org.eclipse.osgi@-1:true,org.eclipse.pde.build@default:default,org.eclipse.pde.core@default:default,org.eclipse.pde.launching@default:default,org.eclipse.pde.ui@default:default,org.eclipse.search@default:default,org.eclipse.swt.win32.win32.x86_64@default:false,org.eclipse.swt@default:default,org.eclipse.team.core@default:default,org.eclipse.team.ui@default:default,org.eclipse.text@default:default,org.eclipse.ui.cheatsheets@default:default,org.eclipse.ui.console@default:default,org.eclipse.ui.editors@default:default,org.eclipse.ui.externaltools@default:default,org.eclipse.ui.forms@default:default,org.eclipse.ui.ide@default:default,org.eclipse.ui.intro@default:default,org.eclipse.ui.navigator.resources@default:default,org.eclipse.ui.navigator@default:default,org.eclipse.ui.trace@default:default,org.eclipse.ui.views.log@default:default,org.eclipse.ui.views.properties.tabbed@default:default,org.eclipse.ui.views@default:default,org.eclipse.ui.win32@default:false,org.eclipse.ui.workbench.texteditor@default:default,org.eclipse.ui.workbench@default:default,org.eclipse.ui@default:default,org.eclipse.update.configurator@3:true,org.eclipse.xpand@default:default,org.eclipse.xtend.lib.macro@default:default,org.eclipse.xtend.lib@default:default,org.eclipse.xtend.typesystem.emf@default:default,org.eclipse.xtend@default:default,org.eclipse.xtext.builder.standalone@default:default,org.eclipse.xtext.builder@default:default,org.eclipse.xtext.common.types.edit@default:default,org.eclipse.xtext.common.types.ui@default:default,org.eclipse.xtext.common.types@default:default,org.eclipse.xtext.ecore@default:default,org.eclipse.xtext.generator@default:default,org.eclipse.xtext.ide@default:default,org.eclipse.xtext.junit4@default:default,org.eclipse.xtext.logging@default:false,org.eclipse.xtext.smap@default:default,org.eclipse.xtext.testing@default:default,org.eclipse.xtext.ui.codetemplates.ide@default:default,org.eclipse.xtext.ui.codetemplates.ui@default:default,org.eclipse.xtext.ui.codetemplates@default:default,org.eclipse.xtext.ui.shared@default:default,org.eclipse.xtext.ui.testing@default:default,org.eclipse.xtext.ui@default:default,org.eclipse.xtext.util@default:default,org.eclipse.xtext.xbase.ide@default:default,org.eclipse.xtext.xbase.junit@default:default,org.eclipse.xtext.xbase.lib@default:default,org.eclipse.xtext.xbase.ui@default:default,org.eclipse.xtext.xbase@default:default,org.eclipse.xtext.xtext.generator@default:default,org.eclipse.xtext@default:default,org.hamcrest.core@default:default,org.junit@default:default,org.objectweb.asm*6.0.0.v20180116-1719@default:default,org.sat4j.core@default:default,org.sat4j.pb@default:default,org.slf4j.api@default:default,org.slf4j.impl.log4j12@default:false,org.tukaani.xz@default:default,org.w3c.css.sac@default:default,org.w3c.dom.events@default:default,org.w3c.dom.smil@default:default,org.w3c.dom.svg@default:default"/>
+<stringAttribute key="selected_workspace_plugins" value="org.eclipse.etrice.core.common@default:default,org.eclipse.etrice.core.etmap@default:default,org.eclipse.etrice.core.etphys@default:default,org.eclipse.etrice.core.fsm@default:default,org.eclipse.etrice.core.genmodel.fsm@default:default,org.eclipse.etrice.core.genmodel@default:default,org.eclipse.etrice.core.room.tests@default:default,org.eclipse.etrice.core.room@default:default,org.eclipse.etrice.expressions.ui.tests@default:default,org.eclipse.etrice.expressions.ui@default:default,org.eclipse.etrice.generator.fsm@default:default,org.eclipse.etrice.generator@default:default,org.eclipse.etrice.logging@default:false"/>
+<booleanAttribute key="show_selected_only" value="false"/>
+<stringAttribute key="templateConfig" value="${target_home}\configuration\config.ini"/>
+<booleanAttribute key="tracing" value="false"/>
+<booleanAttribute key="useCustomFeatures" value="false"/>
+<booleanAttribute key="useDefaultConfig" value="true"/>
+<booleanAttribute key="useDefaultConfigArea" value="false"/>
+<booleanAttribute key="useProduct" value="false"/>
+</launchConfiguration>
diff --git a/tests/org.eclipse.etrice.dctools.tests/src/org/eclipse/etrice/dctools/tests/DCToolsTestsActivator.java b/tests/org.eclipse.etrice.dctools.tests/src/org/eclipse/etrice/dctools/tests/DCToolsTestsActivator.java
new file mode 100644
index 000000000..a9c153105
--- /dev/null
+++ b/tests/org.eclipse.etrice.dctools.tests/src/org/eclipse/etrice/dctools/tests/DCToolsTestsActivator.java
@@ -0,0 +1,21 @@
+package org.eclipse.etrice.dctools.tests;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.eclipse.core.runtime.Plugin;
+
+public class DCToolsTestsActivator extends Plugin implements BundleActivator {
+
+ private static DCToolsTestsActivator instance = null;
+
+ public static DCToolsTestsActivator getInstance() {
+ return instance;
+ }
+
+ @Override
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+
+ instance = this;
+ }
+}
diff --git a/tests/org.eclipse.etrice.dctools.tests/src/org/eclipse/etrice/dctools/tests/TestConstants.xtend b/tests/org.eclipse.etrice.dctools.tests/src/org/eclipse/etrice/dctools/tests/TestConstants.xtend
new file mode 100644
index 000000000..8a38916a8
--- /dev/null
+++ b/tests/org.eclipse.etrice.dctools.tests/src/org/eclipse/etrice/dctools/tests/TestConstants.xtend
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (c) 2018 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * CONTRIBUTORS:
+ * Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.dctools.tests
+
+interface TestConstants {
+
+ static val TEST_STRING = "\"some test string\""
+ static val TEST_C_COMMENT = "/* comment */"
+ static val TEST_C_COMMENT2 = "/* comment\n\tnext line */"
+ static val TEST_CPP_COMMENT = "// cpp comment"
+ static val TEST_EMPTY_ROUND_BRACKET = "()"
+ static val TEST_EMPTY_CURLY_BRACKET = "{}"
+ static val TEST_EMPTY_SQUARE_BRACKET = "[]"
+ static val CONTENTS1 = "/* comment */"
+ static val CONTENTS2 = "/* another comment */"
+ static val CONTENTS3 = "/* third comment */"
+ static val TEST_EMPTY_ROUND_BRACKET_W_CONTENTS1 = "(" + CONTENTS1 + ")"
+ static val TEST_NESTED_BRACKETS = "(" + CONTENTS1 + "(" + CONTENTS2 + ")" + CONTENTS3 + ")"
+ static val TEST_IDENTIFIER = "someIdentifier_123_name"
+ static val TEST_ARRAY_ACCESS = "array[]"
+ static val TEST_OPERATION_CALL = "foo()"
+ static val TEST_MEMBER_ACCESS = "field.member"
+ static val TEST_ARRAY_MEMBER_ACCESS = "field[1+2].member"
+ static val TEST_ARRAY_MEMBER_ACCESS_AND_CALL = TEST_ARRAY_MEMBER_ACCESS + ".op()"
+ static val TEST_SPACY_ARRAY_MEMBER_ACCESS_AND_CALL = "field [ 1 + 2 ]\n\t. member . op ( )"
+ static val TEST_CODE = "DC var = new DC(); port.message(var);"
+ static val TEST_CODE1 = "field.member1.member2[3].operation(x+4)"
+ static val TEST_CODE2 = '''
+ sendPort.ping(x /* comment */);
+ ping.ping(1);
+ // comment
+ int local = 0;
+ foo(foo(123+456+x)*2+foo(local));
+ /* foo(i) */
+ String t = "foo(i)";
+ '''
+ static val TEST_CODE3 = '''
+ int result = 1;
+ for (int i=0; i<10; ++i) {
+ if (i>=5) {
+ result = result * 3;
+ }
+ result = foo(result*2);
+ }
+ '''
+
+ // incomplete sequences
+ static val TEST_UNCLOSED_STRING = "\"the closing quotes are missing"
+ static val TEST_UNCLOSED_BRACKETS = "(/* the closing round bracket is missing*/"
+ static val TEST_UNCLOSED_NESTED_BRACKETS = "((/* nested */)/* the outer closing round bracket is missing*/"
+ static val TEST_INCOMPLETE_FEATURE_CALL = "field.member."
+} \ No newline at end of file
diff --git a/tests/org.eclipse.etrice.dctools.tests/src/org/eclipse/etrice/dctools/tests/TestDCLinker.xtend b/tests/org.eclipse.etrice.dctools.tests/src/org/eclipse/etrice/dctools/tests/TestDCLinker.xtend
new file mode 100644
index 000000000..b5fab53d0
--- /dev/null
+++ b/tests/org.eclipse.etrice.dctools.tests/src/org/eclipse/etrice/dctools/tests/TestDCLinker.xtend
@@ -0,0 +1,642 @@
+/*******************************************************************************
+ * Copyright (c) 2011 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * CONTRIBUTORS:
+ * Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.dctools.tests
+
+import org.eclipse.emf.ecore.resource.Resource
+import org.eclipse.etrice.core.TestBase
+import org.eclipse.etrice.core.room.Attribute
+import org.eclipse.etrice.core.room.MessageData
+import org.eclipse.etrice.core.room.ProtocolClass
+import org.eclipse.etrice.core.room.RoomModel
+import org.eclipse.etrice.core.room.RoomPackage
+import org.eclipse.etrice.core.room.StandardOperation
+import org.eclipse.etrice.core.room.VarDecl
+import org.eclipse.etrice.core.room.util.RoomHelpers
+import org.eclipse.etrice.dctools.fsm.ast.DCLanguage
+import org.eclipse.etrice.dctools.ast.DCLinker
+import org.eclipse.etrice.dctools.fsm.ast.DCParser
+import org.junit.Before
+import org.junit.Test
+
+import static org.hamcrest.CoreMatchers.*
+import static org.junit.Assert.*
+import org.eclipse.etrice.core.fsm.fSM.FSMPackage
+import org.eclipse.etrice.core.room.Port
+import org.eclipse.etrice.core.room.Message
+import org.eclipse.etrice.core.room.ActorClass
+import org.eclipse.etrice.core.room.DataClass
+
+class TestDCLinker extends TestBase {
+
+ Resource res = null;
+ RoomModel model
+ val extension RoomHelpers roomHelpers = new RoomHelpers
+
+ @Before
+ def void SetUp() {
+ prepare(DCToolsTestsActivator.getInstance.bundle)
+ res = getResource("DetailCodes.room")
+ assertNotNull(res)
+ assertFalse(res.contents.empty)
+ assertTrue(res.contents.head instanceof RoomModel)
+ model = res.contents.head as RoomModel
+ }
+
+// detail code:
+// double dx = x - other.x;
+// double dy = y - other.y;
+// return Math.sqrt(dx*dx + dy*dy);
+
+// AST:
+//DCAstMatchNode
+// DCAstOtherNode 'double' KEYWORD
+// DCAstOtherNode ' ' WHITESPACE
+// DCAstFeatureCallNode
+// DCAstIdentifierNode 'dx'
+// DCAstWhitespaceNode ' '
+// DCAstOtherNode '=' OTHER
+// DCAstOtherNode ' ' WHITESPACE
+// DCAstFeatureCallNode
+// DCAstIdentifierNode 'x' --> Attribute
+// DCAstWhitespaceNode ' '
+// DCAstOtherNode '-' OTHER
+// DCAstOtherNode ' ' WHITESPACE
+// DCAstFeatureCallNode
+// DCAstIdentifierNode 'other' --> VarDecl
+// DCAstPeriodNode
+// DCAstIdentifierNode 'x' --> Attribute
+// DCAstOtherNode ';' STATEMENT_SEP
+// DCAstOtherNode '
+//' WHITESPACE
+// DCAstOtherNode 'double' KEYWORD
+// DCAstOtherNode ' ' WHITESPACE
+// DCAstFeatureCallNode
+// DCAstIdentifierNode 'dy'
+// DCAstWhitespaceNode ' '
+// DCAstOtherNode '=' OTHER
+// DCAstOtherNode ' ' WHITESPACE
+// DCAstFeatureCallNode
+// DCAstIdentifierNode 'y' --> Attribute
+// DCAstWhitespaceNode ' '
+// DCAstOtherNode '-' OTHER
+// DCAstOtherNode ' ' WHITESPACE
+// DCAstFeatureCallNode
+// DCAstIdentifierNode 'other' --> VarDecl
+// DCAstPeriodNode
+// DCAstIdentifierNode 'y' --> Attribute
+// DCAstOtherNode ';' STATEMENT_SEP
+// DCAstOtherNode '
+//' WHITESPACE
+// DCAstOtherNode 'return' KEYWORD
+// DCAstOtherNode ' ' WHITESPACE
+// DCAstFeatureCallNode
+// DCAstIdentifierNode 'Math'
+// DCAstPeriodNode
+// DCAstOperationCallNode 'sqrt()'
+// DCAstIdentifierNode 'sqrt'
+// DCAstBracketNode ()
+// DCAstMatchNode
+// DCAstFeatureCallNode
+// DCAstIdentifierNode 'dx'
+// DCAstOtherNode '*' OTHER
+// DCAstFeatureCallNode
+// DCAstIdentifierNode 'dx'
+// DCAstWhitespaceNode ' '
+// DCAstOtherNode '+' OTHER
+// DCAstOtherNode ' ' WHITESPACE
+// DCAstFeatureCallNode
+// DCAstIdentifierNode 'dy'
+// DCAstOtherNode '*' OTHER
+// DCAstFeatureCallNode
+// DCAstIdentifierNode 'dy'
+// DCAstOtherNode ';' STATEMENT_SEP
+// DCAstOtherNode '
+//
+//' WHITESPACE
+ @Test
+ def void testDataClassOperationWithAttributesAndVarDecl() {
+ // we want to test the distance operation of data class Point
+ val dc = model.dataClasses.filter[name=="Point"].head
+ val op = dc.operations.filter[name=="distance"].head
+ val code = op.detailCode.detailCode
+
+ // parse
+ val parser = new DCParser(DCLanguage.JAVA_LANGUAGE)
+ val ast = parser.parse(code)
+
+ // link
+ val linker = new DCLinker(op.detailCode)
+ ast.visit(linker)
+
+ ast.print
+
+ assertTrue(ast.c(5).c(0).linkedObject instanceof Attribute)
+ var att = ast.c(5).c(0).linkedObject as Attribute
+ assertThat(att.name, is("x"))
+
+ assertTrue(ast.c(8).c(0).linkedObject instanceof VarDecl)
+ val vd = ast.c(8).c(0).linkedObject as VarDecl
+ assertThat(vd.name, is("other"))
+
+ assertTrue(ast.c(8).c(2).linkedObject instanceof Attribute)
+ att = ast.c(8).c(2).linkedObject as Attribute
+ assertThat(att.name, is("x"))
+ }
+
+// detail code:
+// return c.distance(other) < r;
+
+// AST:
+//DCAstMatchNode
+// DCAstOtherNode 'return' KEYWORD
+// DCAstOtherNode ' ' WHITESPACE
+// DCAstFeatureCallNode
+// DCAstIdentifierNode 'c' --> Attribute
+// DCAstPeriodNode
+// DCAstOperationCallNode 'distance()' --> StandardOperation
+// DCAstIdentifierNode 'distance'
+// DCAstBracketNode ()
+// DCAstMatchNode
+// DCAstFeatureCallNode
+// DCAstIdentifierNode 'other' --> VarDecl
+// DCAstWhitespaceNode ' '
+// DCAstOtherNode '<' OTHER
+// DCAstOtherNode ' ' WHITESPACE
+// DCAstFeatureCallNode
+// DCAstIdentifierNode 'r' --> Attribute
+// DCAstOtherNode ';' STATEMENT_SEP
+// DCAstOtherNode '
+//
+//' WHITESPACE
+ @Test
+ def void testDataClassOperationWithOperationCall() {
+ // we want to test the isInside operation of data class Circle
+ val dc = model.dataClasses.filter[name=="Circle"].head
+ val op = dc.operations.filter[name=="isInside"].head
+ val code = op.detailCode.detailCode
+
+ // parse
+ val parser = new DCParser(DCLanguage.JAVA_LANGUAGE)
+ val ast = parser.parse(code)
+
+ // link
+ val linker = new DCLinker(op, RoomPackage.Literals.OPERATION__DETAIL_CODE)
+ ast.visit(linker)
+
+ ast.print
+
+ var lo = ast.c(2).c(0).linkedObject
+ assertTrue(lo instanceof Attribute)
+ var att = lo as Attribute
+ assertThat(att.name, is("c"))
+
+ lo = ast.c(2).c(2).linkedObject
+ assertTrue(lo instanceof StandardOperation)
+ var sop = lo as StandardOperation
+ assertThat(sop.name, is("distance"))
+
+ lo = ast.c(2).c(2).c(1).c(0).c(0).c(0).linkedObject
+ assertTrue(lo instanceof VarDecl)
+ var vd = lo as VarDecl
+ assertThat(vd.name, is("other"))
+ }
+
+// detail code:
+// transitionData.west().distance(transitionData.c);
+
+// AST:
+//DCAstMatchNode
+// DCAstFeatureCallNode
+// DCAstIdentifierNode 'transitionData' --> MessageData
+// DCAstPeriodNode
+// DCAstOperationCallNode 'west()' --> StandardOperation
+// DCAstIdentifierNode 'west'
+// DCAstBracketNode ()
+// DCAstMatchNode
+// DCAstPeriodNode
+// DCAstOperationCallNode 'distance()' --> StandardOperation
+// DCAstIdentifierNode 'distance'
+// DCAstBracketNode ()
+// DCAstMatchNode
+// DCAstFeatureCallNode
+// DCAstIdentifierNode 'transitionData' --> MessageData
+// DCAstPeriodNode
+// DCAstIdentifierNode 'c' --> Attribute
+// DCAstOtherNode ';' STATEMENT_SEP
+// DCAstOtherNode '
+//' WHITESPACE
+ @Test
+ def void testTransitionData() {
+ // we want to test the action code of tr0
+ val ac = model.actorClasses.filter[name=="AC"].head
+ val tr = ac.stateMachine.transitions.filter[name=="tr0"].head
+ val code = tr.action.detailCode
+
+ // parse
+ val parser = new DCParser(DCLanguage.JAVA_LANGUAGE)
+ val ast = parser.parse(code)
+
+ // link
+ val pc = model.protocolClasses.filter(ProtocolClass).filter[name=="PC"].head
+ val msg = pc.incomingMessages.filter[name=="circle"].head
+ val md = msg.data
+ val linker = new DCLinker(tr.action, md)
+ ast.visit(linker)
+
+ ast.print
+
+ var lo = ast.c(0).c(0).linkedObject
+ assertTrue(lo instanceof MessageData)
+
+ lo = ast.c(0).c(2).linkedObject
+ assertTrue(lo instanceof StandardOperation)
+ var sop = lo as StandardOperation
+ assertThat(sop.name, is("west"))
+
+ lo = ast.c(0).c(4).linkedObject
+ assertTrue(lo instanceof StandardOperation)
+ sop = lo as StandardOperation
+ assertThat(sop.name, is("distance"))
+
+ lo = ast.c(0).c(4).c(1).c(0).c(0).c(0).linkedObject
+ assertTrue(lo instanceof MessageData)
+
+ lo = ast.c(0).c(4).c(1).c(0).c(0).c(2).linkedObject
+ assertTrue(lo instanceof Attribute)
+ var att = lo as Attribute
+ assertThat(att.name, is("c"))
+ }
+
+// detail code:
+// prt.start();
+//
+// Point pt = new Point(1,2);
+// prt.result(pt);'''
+
+// AST:
+//DCAstMatchNode
+// DCAstFeatureCallNode
+// DCAstIdentifierNode 'prt' --> Port
+// DCAstPeriodNode
+// DCAstOperationCallNode 'start()' --> Message
+// DCAstIdentifierNode 'start'
+// DCAstBracketNode ()
+// DCAstMatchNode
+// DCAstOtherNode ';' STATEMENT_SEP
+// DCAstOtherNode '
+//
+//' WHITESPACE
+// DCAstFeatureCallNode
+// DCAstIdentifierNode 'Point'
+// DCAstWhitespaceNode ' '
+// DCAstFeatureCallNode
+// DCAstIdentifierNode 'pt'
+// DCAstWhitespaceNode ' '
+// DCAstOtherNode '=' OTHER
+// DCAstOtherNode ' ' WHITESPACE
+// DCAstOtherNode 'new' KEYWORD
+// DCAstOtherNode ' ' WHITESPACE
+// DCAstFeatureCallNode
+// DCAstOperationCallNode 'Point()'
+// DCAstIdentifierNode 'Point'
+// DCAstBracketNode ()
+// DCAstMatchNode
+// DCAstOtherNode '1' NUMBER
+// DCAstOtherNode ',' OTHER
+// DCAstOtherNode '2' NUMBER
+// DCAstOtherNode ';' STATEMENT_SEP
+// DCAstOtherNode '
+//' WHITESPACE
+// DCAstFeatureCallNode
+// DCAstIdentifierNode 'prt' --> Port
+// DCAstPeriodNode
+// DCAstOperationCallNode 'result()' --> Message
+// DCAstIdentifierNode 'result'
+// DCAstBracketNode ()
+// DCAstMatchNode
+// DCAstFeatureCallNode
+// DCAstIdentifierNode 'pt'
+// DCAstOtherNode ';' STATEMENT_SEP
+// DCAstOtherNode '
+//' WHITESPACE
+ @Test
+ def void testPortMessage() {
+ // we want to test the entry code of state 'first'
+ val ac = model.actorClasses.filter[name=="AC"].head
+ val st = ac.stateMachine.states.filter[name=="first"].head
+ val code = st.entryCode.detailCode
+
+ // parse
+ val parser = new DCParser(DCLanguage.JAVA_LANGUAGE)
+ val ast = parser.parse(code)
+
+ // link
+ val linker = new DCLinker(st.entryCode)
+ ast.visit(linker)
+
+ ast.print
+
+ var lo = ast.c(0).c(0).linkedObject
+ assertTrue(lo instanceof Port)
+ var p = lo as Port
+ assertThat(p.name, is("prt"))
+
+ lo = ast.c(0).c(2).linkedObject
+ assertTrue(lo instanceof Message)
+ var m = lo as Message
+ assertThat(m.name, is("start"))
+
+ lo = ast.c(12).c(0).linkedObject
+ assertTrue(lo instanceof Port)
+ p = lo as Port
+ assertThat(p.name, is("prt"))
+
+ lo = ast.c(12).c(2).linkedObject
+ assertTrue(lo instanceof Message)
+ m = lo as Message
+ assertThat(m.name, is("result"))
+ }
+
+// detail code:
+// double d = c.diameter();
+// d = p[0].distance(p[1]);
+// d = distance(p[0], p[1]);
+// d = c.c.x;
+
+// AST:
+//DCAstMatchNode
+// DCAstOtherNode 'double' KEYWORD
+// DCAstOtherNode ' ' WHITESPACE
+// DCAstFeatureCallNode
+// DCAstIdentifierNode 'd'
+// DCAstWhitespaceNode ' '
+// DCAstOtherNode '=' OTHER
+// DCAstOtherNode ' ' WHITESPACE
+// DCAstFeatureCallNode
+// DCAstIdentifierNode 'c' --> Attribute
+// DCAstPeriodNode
+// DCAstOperationCallNode 'diameter()' --> StandardOperation
+// DCAstIdentifierNode 'diameter'
+// DCAstBracketNode ()
+// DCAstMatchNode
+// DCAstOtherNode ';' STATEMENT_SEP
+// DCAstOtherNode '
+//' WHITESPACE
+// DCAstFeatureCallNode
+// DCAstIdentifierNode 'd'
+// DCAstWhitespaceNode ' '
+// DCAstOtherNode '=' OTHER
+// DCAstOtherNode ' ' WHITESPACE
+// DCAstFeatureCallNode
+// DCAstArrayAccessNode 'p[]' --> Attribute
+// DCAstIdentifierNode 'p'
+// DCAstBracketNode []
+// DCAstMatchNode
+// DCAstOtherNode '0' NUMBER
+// DCAstPeriodNode
+// DCAstOperationCallNode 'distance()' --> StandardOperation
+// DCAstIdentifierNode 'distance'
+// DCAstBracketNode ()
+// DCAstMatchNode
+// DCAstFeatureCallNode
+// DCAstArrayAccessNode 'p[]' --> Attribute
+// DCAstIdentifierNode 'p'
+// DCAstBracketNode []
+// DCAstMatchNode
+// DCAstOtherNode '1' NUMBER
+// DCAstOtherNode ';' STATEMENT_SEP
+// DCAstOtherNode '
+//' WHITESPACE
+// DCAstFeatureCallNode
+// DCAstIdentifierNode 'd'
+// DCAstWhitespaceNode ' '
+// DCAstOtherNode '=' OTHER
+// DCAstOtherNode ' ' WHITESPACE
+// DCAstFeatureCallNode
+// DCAstOperationCallNode 'distance()' --> StandardOperation
+// DCAstIdentifierNode 'distance'
+// DCAstBracketNode ()
+// DCAstMatchNode
+// DCAstFeatureCallNode
+// DCAstArrayAccessNode 'p[]' --> Attribute
+// DCAstIdentifierNode 'p'
+// DCAstBracketNode []
+// DCAstMatchNode
+// DCAstOtherNode '0' NUMBER
+// DCAstOtherNode ',' OTHER
+// DCAstOtherNode ' ' WHITESPACE
+// DCAstFeatureCallNode
+// DCAstArrayAccessNode 'p[]' --> Attribute
+// DCAstIdentifierNode 'p'
+// DCAstBracketNode []
+// DCAstMatchNode
+// DCAstOtherNode '1' NUMBER
+// DCAstOtherNode ';' STATEMENT_SEP
+// DCAstOtherNode '
+//' WHITESPACE
+// DCAstFeatureCallNode
+// DCAstIdentifierNode 'd'
+// DCAstWhitespaceNode ' '
+// DCAstOtherNode '=' OTHER
+// DCAstOtherNode ' ' WHITESPACE
+// DCAstFeatureCallNode
+// DCAstIdentifierNode 'c' --> Attribute
+// DCAstPeriodNode
+// DCAstIdentifierNode 'c' --> Attribute
+// DCAstPeriodNode
+// DCAstIdentifierNode 'x' --> Attribute
+// DCAstWhitespaceNode '
+//
+//'
+ @Test
+ def void testActorClassAttributes() {
+ // we want to test the entry code of state 'first'
+ val ac = model.actorClasses.filter[name=="AC"].head
+ val st = ac.stateMachine.states.filter[name=="second"].head
+ val code = st.entryCode.detailCode
+
+ // parse
+ val parser = new DCParser(DCLanguage.JAVA_LANGUAGE)
+ val ast = parser.parse(code)
+
+ // link
+ val linker = new DCLinker(st, FSMPackage.Literals.STATE__ENTRY_CODE)
+ ast.visit(linker)
+
+ ast.print
+
+ var lo = ast.c(5).c(0).linkedObject
+ assertTrue(lo instanceof Attribute)
+ var a = lo as Attribute
+ assertThat(a.name, is("c"))
+
+ lo = ast.c(5).c(2).linkedObject
+ assertTrue(lo instanceof StandardOperation)
+ var op = lo as StandardOperation
+ assertThat(op.name, is("diameter"))
+ var dc = model.dataClasses.filter[name=="Circle"].head
+ val circleOp = dc.operations.filter[name=="diameter"].head
+ assertThat(op, is(circleOp))
+
+ lo = ast.c(11).c(0).linkedObject
+ assertTrue(lo instanceof Attribute)
+ a = lo as Attribute
+ assertThat(a.name, is("p"))
+
+ lo = ast.c(11).c(2).linkedObject
+ assertTrue(lo instanceof StandardOperation)
+ op = lo as StandardOperation
+ assertThat(op.name, is("distance"))
+ dc = model.dataClasses.filter[name=="Point"].head
+ val pointOp = dc.operations.filter[name=="distance"].head
+ assertThat(op, is(pointOp))
+
+ lo = ast.c(17).c(0).linkedObject
+ assertTrue(lo instanceof StandardOperation)
+ op = lo as StandardOperation
+ assertThat(op.name, is("distance"))
+ val actorOp = ac.operations.filter[name=="distance"].head
+ assertThat(op, is(actorOp))
+
+ lo = ast.c(23).c(0).linkedObject
+ assertTrue(lo instanceof Attribute)
+ a = lo as Attribute
+ assertThat(a.name, is("c"))
+ assertTrue(a.eContainer instanceof ActorClass)
+
+ lo = ast.c(23).c(2).linkedObject
+ assertTrue(lo instanceof Attribute)
+ a = lo as Attribute
+ assertThat(a.name, is("c"))
+ assertTrue(a.eContainer instanceof DataClass)
+ assertThat((a.eContainer as DataClass).name, is("Circle"))
+
+ lo = ast.c(23).c(4).linkedObject
+ assertTrue(lo instanceof Attribute)
+ a = lo as Attribute
+ assertThat(a.name, is("x"))
+ assertTrue(a.eContainer instanceof DataClass)
+ assertThat((a.eContainer as DataClass).name, is("Point"))
+ }
+
+// detail code:
+// replPrt[0].start();
+// replPrt.start();
+// prt[0].start();
+
+// AST:
+//DCAstMatchNode
+// DCAstFeatureCallNode
+// DCAstArrayAccessNode 'replPrt[]' --> Port
+// DCAstIdentifierNode 'replPrt'
+// DCAstBracketNode []
+// DCAstMatchNode
+// DCAstOtherNode '0' NUMBER
+// DCAstPeriodNode
+// DCAstOperationCallNode 'start()' --> Message
+// DCAstIdentifierNode 'start'
+// DCAstBracketNode ()
+// DCAstMatchNode
+// DCAstOtherNode ';' STATEMENT_SEP
+// DCAstOtherNode '
+//' WHITESPACE
+// DCAstFeatureCallNode
+// DCAstIdentifierNode 'replPrt' --> Port
+// DCAstPeriodNode
+// DCAstOperationCallNode 'start()' --> Message
+// DCAstIdentifierNode 'start'
+// DCAstBracketNode ()
+// DCAstMatchNode
+// DCAstOtherNode ';' STATEMENT_SEP
+// DCAstOtherNode '
+//' WHITESPACE
+// DCAstFeatureCallNode
+// DCAstArrayAccessNode 'prt[]'
+// DCAstIdentifierNode 'prt'
+// DCAstBracketNode []
+// DCAstMatchNode
+// DCAstOtherNode '0' NUMBER
+// DCAstPeriodNode
+// DCAstOperationCallNode 'start()'
+// DCAstIdentifierNode 'start'
+// DCAstBracketNode ()
+// DCAstMatchNode
+// DCAstOtherNode ';' STATEMENT_SEP
+// DCAstOtherNode '
+//
+//' WHITESPACE
+ @Test
+ def void testReplPortMessage() {
+ // we want to test the exit code of state 'second'
+ val ac = model.actorClasses.filter[name=="AC"].head
+ val st = ac.stateMachine.states.filter[name=="second"].head
+ val code = st.exitCode.detailCode
+
+ // parse
+ val parser = new DCParser(DCLanguage.JAVA_LANGUAGE)
+ val ast = parser.parse(code)
+
+ // link
+ val linker = new DCLinker(st, FSMPackage.Literals.STATE__ENTRY_CODE)
+ ast.visit(linker)
+
+ ast.print
+
+ // array access to replicated port
+ var lo = ast.c(0).c(0).linkedObject
+ assertTrue(lo instanceof Port)
+ var p = lo as Port
+ assertThat(p.name, is("replPrt"))
+
+ lo = ast.c(0).c(2).linkedObject
+ assertTrue(lo instanceof Message)
+ var m = lo as Message
+ assertThat(m.name, is("start"))
+
+ // broadcast through replicated port (scalar access)
+ lo = ast.c(3).c(0).linkedObject
+ assertTrue(lo instanceof Port)
+ p = lo as Port
+ assertThat(p.name, is("replPrt"))
+
+ lo = ast.c(3).c(2).linkedObject
+ assertTrue(lo instanceof Message)
+ m = lo as Message
+ assertThat(m.name, is("start"))
+
+ // a non replicated port with array access shouldn't be linked
+ lo = ast.c(6).c(0).linkedObject
+ assertThat(lo, is(nullValue))
+ }
+
+ @Test
+ def void testDataPortGetterAndAttributeSetter() {
+ // we want to test the action code of tr1
+ val ac = model.actorClasses.filter[name=="AC"].head
+ val tr = ac.stateMachine.transitions.filter[name=="tr1"].head
+ val code = tr.action.detailCode
+
+ // parse
+ val parser = new DCParser(DCLanguage.JAVA_LANGUAGE)
+ val ast = parser.parse(code)
+
+ // link
+ val pc = model.protocolClasses.filter(ProtocolClass).filter[name=="PCData"].head
+ val msg = pc.incomingMessages.filter[name=="point"].head
+ val md = msg.data
+ val linker = new DCLinker(tr.action, md)
+ ast.visit(linker)
+
+ ast.print
+ }
+} \ No newline at end of file
diff --git a/tests/org.eclipse.etrice.dctools.tests/src/org/eclipse/etrice/dctools/tests/TestDCParser.xtend b/tests/org.eclipse.etrice.dctools.tests/src/org/eclipse/etrice/dctools/tests/TestDCParser.xtend
new file mode 100644
index 000000000..df0e392ab
--- /dev/null
+++ b/tests/org.eclipse.etrice.dctools.tests/src/org/eclipse/etrice/dctools/tests/TestDCParser.xtend
@@ -0,0 +1,408 @@
+/*******************************************************************************
+ * Copyright (c) 2018 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * CONTRIBUTORS:
+ * Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.dctools.tests
+
+import org.eclipse.etrice.dctools.fsm.ast.DCLanguage
+import org.eclipse.etrice.dctools.fsm.ast.DCParser
+import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstArrayAccessNode
+import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstBracketNode
+import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstFeatureCallNode
+import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstIdentifierNode
+import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstMatchNode
+import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstNode
+import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstOperationCallNode
+import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstOtherNode
+import org.eclipse.etrice.dctools.fsm.ast.nodes.DCAstPeriodNode
+import org.eclipse.etrice.dctools.fsm.ast.util.DCAstPrinter
+import org.junit.Before
+import org.junit.Test
+
+import static org.eclipse.etrice.dctools.tests.TestConstants.*
+import static org.hamcrest.CoreMatchers.*
+import static org.junit.Assert.*
+
+class TestDCParser {
+
+ DCParser parser
+
+ @Before
+ def void createParser() {
+ parser = new DCParser(DCLanguage.C_LANGUAGE)
+ }
+
+ @Test
+ def void testString() {
+ testSingleOther("testString", TEST_STRING)
+ }
+
+ @Test
+ def void testCComment() {
+ testSingleOther("testCComment", TEST_C_COMMENT)
+ }
+
+ @Test
+ def void testCComment2() {
+ testSingleOther("testCComment2", TEST_C_COMMENT2)
+ }
+
+ @Test
+ def void testCppComment() {
+ testSingleOther("testCppComment", TEST_CPP_COMMENT)
+ }
+
+ @Test
+ def void testEmptyRoundBracket() {
+ testBracketExpression(TEST_EMPTY_ROUND_BRACKET, DCAstBracketNode.BracketType.ROUND)
+ }
+
+ @Test
+ def void testEmptyCurlyBracket() {
+ testBracketExpression(TEST_EMPTY_CURLY_BRACKET, DCAstBracketNode.BracketType.CURLY)
+ }
+
+ @Test
+ def void testEmptySquareBracket() {
+ testBracketExpression(TEST_EMPTY_SQUARE_BRACKET, DCAstBracketNode.BracketType.SQUARE)
+ }
+
+ @Test
+ def void testRoundBracketWithContents() {
+ testBracketExpression(TEST_EMPTY_ROUND_BRACKET_W_CONTENTS1, DCAstBracketNode.BracketType.ROUND, CONTENTS1)
+ }
+
+ @Test
+ def void testNestedBrackets() {
+ val result = parser.parse(TEST_NESTED_BRACKETS)
+ assertNotNull(result)
+
+ // we have a single bracket expression
+ assertThat(result.children.size, is(1))
+ var node = result.children.get(0)
+
+ // it is a bracket node
+ assertTrue(node instanceof DCAstBracketNode)
+ assertTrue((node as DCAstBracketNode).type==DCAstBracketNode.BracketType.ROUND)
+
+ // which has one child
+ assertThat(node.children.size, is(1))
+ node = node.children.get(0)
+
+ // which is a match node
+ assertTrue(node instanceof DCAstMatchNode)
+
+ // which has three children
+ assertThat(node.children.size, is(3))
+
+ // first child is a comment
+ node = node.children.get(0)
+ assertTrue(node instanceof DCAstOtherNode)
+ assertEquals((node as DCAstOtherNode).text, CONTENTS1)
+
+ // third child is a comment
+ node = node.parent.children.get(2)
+ assertTrue(node instanceof DCAstOtherNode)
+ assertEquals((node as DCAstOtherNode).text, CONTENTS3)
+
+ // middle child is a bracket
+ node = node.parent.children.get(1)
+ assertTrue(node instanceof DCAstBracketNode)
+ assertTrue((node as DCAstBracketNode).type==DCAstBracketNode.BracketType.ROUND)
+
+ // which has one child
+ assertThat(node.children.size, is(1))
+ node = node.children.get(0)
+
+ // which is a match node
+ assertTrue(node instanceof DCAstMatchNode)
+
+ // which has one child
+ assertThat(node.children.size, is(1))
+ node = node.children.get(0)
+
+ // which is a comment
+ assertTrue(node instanceof DCAstOtherNode)
+ assertEquals((node as DCAstOtherNode).text, CONTENTS2)
+
+ prettyPrint("testNestedBrackets", TEST_NESTED_BRACKETS, result, 7, 8)
+ }
+
+ @Test
+ def void testIdentifier() {
+ val result = parser.parse(TEST_IDENTIFIER)
+ assertNotNull(result)
+
+ // we have a feature
+ assertThat(result.children.size, is(1))
+ var node = result.children.get(0)
+ assertTrue(node instanceof DCAstFeatureCallNode)
+
+ // it is an identifier node
+ node = node.children.get(0)
+ assertTrue(node instanceof DCAstIdentifierNode)
+ assertThat((node as DCAstIdentifierNode).identifier, is(TEST_IDENTIFIER))
+
+ prettyPrint("testIdentifier", TEST_IDENTIFIER, result, 1, 3)
+ }
+
+ @Test
+ def void testArrayAccess() {
+ val result = parser.parse(TEST_ARRAY_ACCESS)
+ assertNotNull(result)
+
+ // we have a feature
+ assertThat(result.children.size, is(1))
+ var node = result.children.get(0)
+ assertTrue(node instanceof DCAstFeatureCallNode)
+
+ // with an array access
+ assertThat(node.children.size, is(1))
+ node = node.children.get(0)
+ assertTrue(node instanceof DCAstArrayAccessNode)
+
+ // with two children
+ assertThat(node.children.size, is(2))
+
+ // an identifier
+ node = node.children.get(0)
+ assertTrue(node instanceof DCAstIdentifierNode)
+
+ // and a bracket
+ node = node.parent.children.get(1)
+ assertTrue(node instanceof DCAstBracketNode)
+
+ prettyPrint("testArrayAccess", TEST_ARRAY_ACCESS, result, 3, 6)
+ }
+
+ @Test
+ def void testOperationCall() {
+ val result = parser.parse(TEST_OPERATION_CALL)
+ assertNotNull(result)
+
+ // we have a feature
+ assertThat(result.children.size, is(1))
+ var node = result.children.get(0)
+ assertTrue(node instanceof DCAstFeatureCallNode)
+
+ // with an operation call
+ assertThat(node.children.size, is(1))
+ node = node.children.get(0)
+ assertTrue(node instanceof DCAstOperationCallNode)
+
+ // with two children
+ assertThat(node.children.size, is(2))
+
+ // an identifier
+ node = node.children.get(0)
+ assertTrue(node instanceof DCAstIdentifierNode)
+
+ // and a bracket
+ node = node.parent.children.get(1)
+ assertTrue(node instanceof DCAstBracketNode)
+
+ prettyPrint("testOperationCall", TEST_OPERATION_CALL, result, 3, 6)
+ }
+
+ @Test
+ def void testMemberAccess() {
+ val result = parser.parse(TEST_MEMBER_ACCESS)
+ assertNotNull(result)
+
+ // we have a feature
+ assertThat(result.children.size, is(1))
+ var node = result.children.get(0)
+ assertTrue(node instanceof DCAstFeatureCallNode)
+
+ // with identifier period identifier
+ assertThat(node.children.size, is(3))
+
+ // identifier node
+ node = node.children.get(0)
+ assertTrue(node instanceof DCAstIdentifierNode)
+
+ // period node
+ node = node.parent.children.get(1)
+ assertTrue(node instanceof DCAstPeriodNode)
+
+ // identifier node
+ node = node.parent.children.get(2)
+ assertTrue(node instanceof DCAstIdentifierNode)
+
+ prettyPrint("testMemberAccess", TEST_MEMBER_ACCESS, result, 3, 5)
+ }
+
+ @Test
+ def void testArrayMemberAccess() {
+ val result = parser.parse(TEST_ARRAY_MEMBER_ACCESS)
+ assertNotNull(result)
+
+ prettyPrint("testArrayMemberAccess", TEST_ARRAY_MEMBER_ACCESS, result, 8, 11)
+ }
+
+ @Test
+ def void testArrayMemberAccessAndCall() {
+ val result = parser.parse(TEST_ARRAY_MEMBER_ACCESS_AND_CALL)
+ assertNotNull(result)
+
+ prettyPrint("testArrayMemberAccessAndCall", TEST_ARRAY_MEMBER_ACCESS_AND_CALL, result, 12, 16)
+ }
+
+ @Test
+ def void testSpacyArrayMemberAccessAndCall() {
+ val result = parser.parse(TEST_SPACY_ARRAY_MEMBER_ACCESS_AND_CALL)
+ assertNotNull(result)
+
+ prettyPrint("testSpacyArrayMemberAccessAndCall", TEST_SPACY_ARRAY_MEMBER_ACCESS_AND_CALL, result, 23, 27)
+ }
+
+ @Test
+ def void testCode() {
+ val result = parser.parse(TEST_CODE)
+ assertNotNull(result)
+
+ prettyPrint("testCode", TEST_CODE, result, 20, 29)
+ }
+
+ @Test
+ def void testCode1() {
+ val result = parser.parse(TEST_CODE1)
+ assertNotNull(result)
+
+ prettyPrint("testCode", TEST_CODE1, result, 15, 20)
+ }
+
+ @Test
+ def void testCode2() {
+ val result = parser.parse(TEST_CODE2)
+ assertNotNull(result)
+
+ prettyPrint("testCode2", TEST_CODE2, result, 59, 76)
+ }
+
+ @Test
+ def void testCode3() {
+ val result = parser.parse(TEST_CODE3)
+ assertNotNull(result)
+
+ prettyPrint("testCode3", TEST_CODE3, result, 69, 81)
+ }
+
+ @Test
+ def void testUnclosedString() {
+ val result = parser.parse(TEST_UNCLOSED_STRING)
+ assertNotNull(result)
+
+ prettyPrint("testUnclosedString", TEST_UNCLOSED_STRING, result, 1, 2)
+ }
+
+ @Test
+ def void testUnclosedNestedBrackets() {
+ val result = parser.parse(TEST_UNCLOSED_NESTED_BRACKETS)
+ assertNotNull(result)
+
+ prettyPrint("testUnclosedNestedBrackets", TEST_UNCLOSED_NESTED_BRACKETS, result, 6, 7)
+ }
+
+ @Test
+ def void testIncompleteFeatureCall() {
+ val result = parser.parse(TEST_INCOMPLETE_FEATURE_CALL)
+ assertNotNull(result)
+
+ prettyPrint("testIncompleteFeatureCall", TEST_INCOMPLETE_FEATURE_CALL, result, 4, 6)
+ }
+
+ /*
+ * helper methods
+ */
+ private def prettyPrint(String method, String orig, DCAstMatchNode node, int nTokes, int nNodes) {
+ val printer = new DCAstPrinter
+ node.visit(printer)
+
+ println("<<<" + method)
+ println("tree: ")
+ node.print
+ println(nNodes + " nodes, " + nTokes + " tokens")
+ println("orig: '" + orig + "'")
+ println("ast: '" + printer.text + "'")
+ println(method + ">>>")
+
+ assertEquals(orig, printer.text)
+ assertThat(node.totallyReadTokens, is(nTokes))
+ assertThat(node.countNodes, is(nNodes))
+ }
+
+ private def void testBracketExpression(String test, DCAstBracketNode.BracketType bt) {
+ testBracketExpression(test, bt, null)
+ }
+
+ private def void testBracketExpression(String test, DCAstBracketNode.BracketType bt, String contents) {
+ val result = parser.parse(test)
+ assertNotNull(result)
+
+ // we have only a bracket expression
+ assertThat(result.children.size, is(1))
+ var node = result.children.get(0)
+
+ // it is a bracket node
+ assertTrue(node instanceof DCAstBracketNode)
+ assertTrue((node as DCAstBracketNode).type==bt)
+
+ // which has one child
+ assertThat(node.children.size, is(1))
+ node = node.children.get(0)
+
+ // which is a match node
+ assertTrue(node instanceof DCAstMatchNode)
+
+ if (contents===null) {
+ // which is empty
+ assertThat(node.children.size, is(0))
+ }
+ else {
+ // which has a single sub node
+ assertThat(node.children.size, is(1))
+
+ // which is Other with contents
+ testOther(node.children.get(0), contents)
+ }
+ }
+
+ private def testSingleOther(String method, String test) {
+ val result = parser.parse(test)
+ assertNotNull(result)
+
+ prettyPrint(method, test, result, 1, 2)
+
+ // only one Other expression
+ assertThat(result.children.size, is(1))
+
+ testOther(result.children.get(0), test)
+ }
+
+ private def testOther(DCAstNode node, String contents) {
+ // which is an Other node
+ assertTrue(node instanceof DCAstOtherNode)
+
+ // with the test text as contents
+ assertEquals((node as DCAstOtherNode).text, contents)
+ }
+
+ private def int countNodes(DCAstNode node) {
+ var sum = 1
+
+ for (child : node.children) {
+ sum += child.countNodes
+ }
+
+ return sum
+ }
+} \ No newline at end of file
diff --git a/tests/org.eclipse.etrice.dctools.tests/src/org/eclipse/etrice/dctools/tests/TestDCScanner.xtend b/tests/org.eclipse.etrice.dctools.tests/src/org/eclipse/etrice/dctools/tests/TestDCScanner.xtend
new file mode 100644
index 000000000..96b4913b4
--- /dev/null
+++ b/tests/org.eclipse.etrice.dctools.tests/src/org/eclipse/etrice/dctools/tests/TestDCScanner.xtend
@@ -0,0 +1,304 @@
+/*******************************************************************************
+ * Copyright (c) 2018 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * CONTRIBUTORS:
+ * Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.dctools.tests
+
+import org.eclipse.etrice.dctools.fsm.ast.DCLanguage
+import org.eclipse.etrice.dctools.fsm.ast.DCScanner
+import org.junit.Before
+import org.junit.Test
+import org.eclipse.etrice.dctools.fsm.ast.internal.DCBracketToken.BracketKind
+import org.eclipse.etrice.dctools.fsm.ast.internal.DCToken.Kind
+
+import static org.eclipse.etrice.dctools.tests.TestConstants.*
+import static org.hamcrest.CoreMatchers.*
+import static org.junit.Assert.*
+import org.eclipse.etrice.dctools.fsm.ast.internal.DCBracketToken
+import org.eclipse.etrice.dctools.fsm.ast.internal.DCToken
+
+class TestDCScanner {
+
+ DCScanner scanner
+
+ @Before
+ def void createScanner() {
+ scanner = new DCScanner(DCLanguage.C_LANGUAGE)
+ }
+
+ @Test
+ def void testString() {
+ val tokens = scanner.scan(TEST_STRING)
+ assertThat(tokens.size, is(1))
+ assertThat(tokens.get(0).token.kind, is(Kind.STRING))
+ }
+
+ @Test
+ def void testCComment() {
+ val tokens = scanner.scan(TEST_C_COMMENT)
+ assertThat(tokens.size, is(1))
+ assertThat(tokens.get(0).token.kind, is(Kind.COMMENT))
+ }
+
+ @Test
+ def void testCComment2() {
+ val tokens = scanner.scan(TEST_C_COMMENT2)
+ assertThat(tokens.size, is(1))
+ assertThat(tokens.get(0).token.kind, is(Kind.COMMENT))
+ }
+
+ @Test
+ def void testCppComment() {
+ val tokens = scanner.scan(TEST_CPP_COMMENT)
+ assertThat(tokens.size, is(1))
+ assertThat(tokens.get(0).token.kind, is(Kind.COMMENT))
+ }
+
+ @Test
+ def void testEmptyRoundBracket() {
+ testBracketExpression(TEST_EMPTY_ROUND_BRACKET, BracketKind.LEFT_ROUND, BracketKind.RIGHT_ROUND)
+ }
+
+ @Test
+ def void testEmptyCurlyBracket() {
+ testBracketExpression(TEST_EMPTY_CURLY_BRACKET, BracketKind.LEFT_CURLY, BracketKind.RIGHT_CURLY)
+ }
+
+ @Test
+ def void testEmptySquareBracket() {
+ testBracketExpression(TEST_EMPTY_SQUARE_BRACKET, BracketKind.LEFT_SQUARE, BracketKind.RIGHT_SQUARE)
+ }
+
+ @Test
+ def void testRoundBracketWithContents() {
+ val tokens = testBracketExpression(TEST_EMPTY_ROUND_BRACKET_W_CONTENTS1, BracketKind.LEFT_ROUND, BracketKind.RIGHT_ROUND, 1)
+ assertThat(tokens.get(1).token.kind, is(Kind.COMMENT))
+ }
+
+ @Test
+ def void testNestedBrackets() {
+ val tokens = scanner.scan(TEST_NESTED_BRACKETS)
+ assertThat(tokens.size, is(7))
+ testBracketToken(tokens.get(0).token, BracketKind.LEFT_ROUND)
+ assertThat(tokens.get(1).token.kind, is(Kind.COMMENT))
+ testBracketToken(tokens.get(2).token, BracketKind.LEFT_ROUND)
+ assertThat(tokens.get(3).token.kind, is(Kind.COMMENT))
+ testBracketToken(tokens.get(4).token, BracketKind.RIGHT_ROUND)
+ assertThat(tokens.get(5).token.kind, is(Kind.COMMENT))
+ testBracketToken(tokens.get(6).token, BracketKind.RIGHT_ROUND)
+ }
+
+ @Test
+ def void testIdentifier() {
+ val tokens = scanner.scan(TEST_IDENTIFIER)
+ assertThat(tokens.size, is(1))
+ assertThat(tokens.get(0).token.kind, is(Kind.IDENTIFIER))
+ }
+
+ @Test
+ def void testArrayAccess() {
+ val tokens = scanner.scan(TEST_ARRAY_ACCESS)
+ assertThat(tokens.size, is(3))
+ assertThat(tokens.get(0).token.kind, is(Kind.IDENTIFIER))
+ testBracketToken(tokens.get(1).token, BracketKind.LEFT_SQUARE)
+ testBracketToken(tokens.get(2).token, BracketKind.RIGHT_SQUARE)
+ }
+
+ @Test
+ def void testOperationCall() {
+ val tokens = scanner.scan(TEST_OPERATION_CALL)
+ assertThat(tokens.size, is(3))
+ assertThat(tokens.get(0).token.kind, is(Kind.IDENTIFIER))
+ testBracketToken(tokens.get(1).token, BracketKind.LEFT_ROUND)
+ testBracketToken(tokens.get(2).token, BracketKind.RIGHT_ROUND)
+ }
+
+ @Test
+ def void testMemberAccess() {
+ val tokens = scanner.scan(TEST_MEMBER_ACCESS)
+ assertThat(tokens.size, is(3))
+ assertThat(tokens.get(0).token.kind, is(Kind.IDENTIFIER))
+ assertThat(tokens.get(1).token.kind, is(Kind.PERIOD))
+ assertThat(tokens.get(2).token.kind, is(Kind.IDENTIFIER))
+ }
+
+ @Test
+ def void testArrayMemberAccess() {
+ val tokens = scanner.scan(TEST_ARRAY_MEMBER_ACCESS)
+ assertThat(tokens.size, is(8))
+ assertThat(tokens.get(0).token.kind, is(Kind.IDENTIFIER))
+ testBracketToken(tokens.get(1).token, BracketKind.LEFT_SQUARE)
+ assertThat(tokens.get(2).token.kind, is(Kind.NUMBER))
+ assertThat(tokens.get(3).token.kind, is(Kind.OTHER))
+ assertThat(tokens.get(4).token.kind, is(Kind.NUMBER))
+ testBracketToken(tokens.get(5).token, BracketKind.RIGHT_SQUARE)
+ assertThat(tokens.get(6).token.kind, is(Kind.PERIOD))
+ assertThat(tokens.get(7).token.kind, is(Kind.IDENTIFIER))
+ }
+
+ @Test
+ def void testArrayMemberAccessAndCall() {
+ val tokens = scanner.scan(TEST_ARRAY_MEMBER_ACCESS_AND_CALL)
+ assertThat(tokens.size, is(12))
+
+ var pos = 0
+ assertThat(tokens.get(pos++).token.kind, is(Kind.IDENTIFIER))
+ testBracketToken(tokens.get(pos++).token, BracketKind.LEFT_SQUARE)
+ assertThat(tokens.get(pos++).token.kind, is(Kind.NUMBER))
+ assertThat(tokens.get(pos++).token.kind, is(Kind.OTHER))
+ assertThat(tokens.get(pos++).token.kind, is(Kind.NUMBER))
+ testBracketToken(tokens.get(pos++).token, BracketKind.RIGHT_SQUARE)
+ assertThat(tokens.get(pos++).token.kind, is(Kind.PERIOD))
+ assertThat(tokens.get(pos++).token.kind, is(Kind.IDENTIFIER))
+
+ assertThat(tokens.get(pos++).token.kind, is(Kind.PERIOD))
+ assertThat(tokens.get(pos++).token.kind, is(Kind.IDENTIFIER))
+ testBracketToken(tokens.get(pos++).token, BracketKind.LEFT_ROUND)
+ testBracketToken(tokens.get(pos++).token, BracketKind.RIGHT_ROUND)
+ }
+
+ @Test
+ def void testSpacyArrayMemberAccessAndCall() {
+ val tokens = scanner.scan(TEST_SPACY_ARRAY_MEMBER_ACCESS_AND_CALL)
+ assertThat(tokens.size, is(23))
+
+ var pos = 0
+ assertThat(tokens.get(pos++).token.kind, is(Kind.IDENTIFIER))
+ assertThat(tokens.get(pos++).token.kind, is(Kind.WHITESPACE))
+ testBracketToken(tokens.get(pos++).token, BracketKind.LEFT_SQUARE)
+ assertThat(tokens.get(pos++).token.kind, is(Kind.WHITESPACE))
+ assertThat(tokens.get(pos++).token.kind, is(Kind.NUMBER))
+ assertThat(tokens.get(pos++).token.kind, is(Kind.WHITESPACE))
+ assertThat(tokens.get(pos++).token.kind, is(Kind.OTHER))
+ assertThat(tokens.get(pos++).token.kind, is(Kind.WHITESPACE))
+ assertThat(tokens.get(pos++).token.kind, is(Kind.NUMBER))
+ assertThat(tokens.get(pos++).token.kind, is(Kind.WHITESPACE))
+ testBracketToken(tokens.get(pos++).token, BracketKind.RIGHT_SQUARE)
+ assertThat(tokens.get(pos++).token.kind, is(Kind.WHITESPACE))
+ assertThat(tokens.get(pos++).token.kind, is(Kind.PERIOD))
+ assertThat(tokens.get(pos++).token.kind, is(Kind.WHITESPACE))
+ assertThat(tokens.get(pos++).token.kind, is(Kind.IDENTIFIER))
+
+ assertThat(tokens.get(pos++).token.kind, is(Kind.WHITESPACE))
+ assertThat(tokens.get(pos++).token.kind, is(Kind.PERIOD))
+ assertThat(tokens.get(pos++).token.kind, is(Kind.WHITESPACE))
+ assertThat(tokens.get(pos++).token.kind, is(Kind.IDENTIFIER))
+ assertThat(tokens.get(pos++).token.kind, is(Kind.WHITESPACE))
+ testBracketToken(tokens.get(pos++).token, BracketKind.LEFT_ROUND)
+ assertThat(tokens.get(pos++).token.kind, is(Kind.WHITESPACE))
+ testBracketToken(tokens.get(pos++).token, BracketKind.RIGHT_ROUND)
+ }
+
+ @Test
+ def void testCode() {
+ val tokens = scanner.scan(TEST_CODE)
+ assertThat(tokens.size, is(20))
+
+ var pos = 0
+ assertThat(tokens.get(pos++).token.kind, is(Kind.IDENTIFIER))
+ }
+
+ @Test
+ def void testCode1() {
+ val tokens = scanner.scan(TEST_CODE1)
+ assertThat(tokens.size, is(15))
+
+ var pos = 0
+ assertThat(tokens.get(pos++).token.kind, is(Kind.IDENTIFIER))
+ }
+
+ @Test
+ def void testCode2() {
+ val tokens = scanner.scan(TEST_CODE2)
+ assertThat(tokens.size, is(59))
+
+ assertThat(tokens.get(19).token.kind, is(Kind.KEYWORD))
+ assertThat(tokens.get(34).token.kind, is(Kind.NUMBER))
+ }
+
+ @Test
+ def void testCode3() {
+ val tokens = scanner.scan(TEST_CODE3)
+ assertThat(tokens.size, is(69))
+
+ assertThat(tokens.get(6).token.kind, is(Kind.NUMBER))
+ assertThat(tokens.get(7).token.kind, is(Kind.STATEMENT_SEP))
+ assertThat(tokens.get(19).token.kind, is(Kind.IDENTIFIER))
+ assertThat(tokens.get(29).token.kind, is(Kind.BRACKET))
+ assertThat(tokens.get(34).token.kind, is(Kind.IDENTIFIER))
+ }
+
+ @Test
+ def void testUnclosedString() {
+ val tokens = scanner.scan(TEST_UNCLOSED_STRING)
+ assertThat(tokens.size, is(1))
+ assertThat(tokens.get(0).token.kind, is(Kind.STRING))
+ }
+
+ @Test
+ def void testUnclosedBrackets() {
+ val tokens = scanner.scan(TEST_UNCLOSED_BRACKETS)
+ assertThat(tokens.size, is(2))
+
+ var pos = 0
+ testBracketToken(tokens.get(pos++).token, BracketKind.LEFT_ROUND)
+ assertThat(tokens.get(pos++).token.kind, is(Kind.COMMENT))
+ }
+
+ @Test
+ def void testUnclosedNestedBrackets() {
+ val tokens = scanner.scan(TEST_UNCLOSED_NESTED_BRACKETS)
+ assertThat(tokens.size, is(5))
+
+ var pos = 0
+ testBracketToken(tokens.get(pos++).token, BracketKind.LEFT_ROUND)
+ testBracketToken(tokens.get(pos++).token, BracketKind.LEFT_ROUND)
+ assertThat(tokens.get(pos++).token.kind, is(Kind.COMMENT))
+ testBracketToken(tokens.get(pos++).token, BracketKind.RIGHT_ROUND)
+ assertThat(tokens.get(pos++).token.kind, is(Kind.COMMENT))
+ }
+
+ @Test
+ def void testIncompleteFeatureCall() {
+ val tokens = scanner.scan(TEST_INCOMPLETE_FEATURE_CALL)
+ assertThat(tokens.size, is(4))
+
+ var pos = 0
+ assertThat(tokens.get(pos++).token.kind, is(Kind.IDENTIFIER))
+ assertThat(tokens.get(pos++).token.kind, is(Kind.PERIOD))
+ assertThat(tokens.get(pos++).token.kind, is(Kind.IDENTIFIER))
+ assertThat(tokens.get(pos++).token.kind, is(Kind.PERIOD))
+ }
+
+ /*
+ * helper methods
+ */
+ private def testBracketExpression(String test, BracketKind left, BracketKind right) {
+ testBracketExpression(test, left, right, 0)
+ }
+
+ private def testBracketExpression(String test, BracketKind left, BracketKind right, int nInnerTokens) {
+ val tokens = scanner.scan(test)
+
+ assertThat(tokens.size, is(2+nInnerTokens))
+ testBracketToken(tokens.get(0).token, left)
+ testBracketToken(tokens.get(1+nInnerTokens).token, right)
+
+ return tokens
+ }
+
+ private def testBracketToken(DCToken t, BracketKind k) {
+ assertThat(t.kind, is(Kind.BRACKET))
+ assertTrue(t instanceof DCBracketToken)
+ var bt = t as DCBracketToken
+ assertThat(bt.bracketKind, is(k))
+ }
+} \ No newline at end of file
diff --git a/tests/org.eclipse.etrice.dctools.tests/src/org/eclipse/etrice/dctools/tests/TestDCTranslator.xtend b/tests/org.eclipse.etrice.dctools.tests/src/org/eclipse/etrice/dctools/tests/TestDCTranslator.xtend
new file mode 100644
index 000000000..e9a2863d3
--- /dev/null
+++ b/tests/org.eclipse.etrice.dctools.tests/src/org/eclipse/etrice/dctools/tests/TestDCTranslator.xtend
@@ -0,0 +1,163 @@
+/*******************************************************************************
+ * Copyright (c) 2011 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * CONTRIBUTORS:
+ * Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.dctools.tests
+
+import org.eclipse.emf.ecore.resource.Resource
+import org.eclipse.etrice.core.TestBase
+import org.eclipse.etrice.core.room.RoomModel
+import org.eclipse.etrice.core.room.util.RoomHelpers
+import org.junit.Before
+import static org.junit.Assert.*
+import static org.hamcrest.CoreMatchers.*
+import org.junit.Test
+import org.eclipse.etrice.dctools.fsm.ast.DCLanguage
+import org.eclipse.etrice.dctools.ast.DCTranslator
+import org.eclipse.etrice.core.fsm.fSM.DetailCode
+
+class TestDCTranslator extends TestBase {
+
+ Resource res = null;
+ RoomModel model
+ TranslationProviderForTests provider
+ DCTranslator translator
+ val extension RoomHelpers roomHelpers = new RoomHelpers
+
+ @Before
+ def void SetUp() {
+ prepare(DCToolsTestsActivator.getInstance.bundle)
+ res = getResource("DetailCodes.room")
+ assertNotNull(res)
+ assertFalse(res.contents.empty)
+ assertTrue(res.contents.head instanceof RoomModel)
+ model = res.contents.head as RoomModel
+ provider = new TranslationProviderForTests
+ translator = new DCTranslator(DCLanguage.C_LANGUAGE, provider)
+ }
+
+ @Test
+ def void testPortMessage() {
+ // we want to test the entry code of state 'first'
+ val ac = model.actorClasses.filter[name=="AC"].head
+ val st = ac.stateMachine.states.filter[name=="first"].head
+
+ val translated = translator.getTranslatedCode(st.entryCode)
+ printResult("testPortMessage", st.entryCode, translated)
+
+ // check the translation count
+ assertThat(provider.attributeCount, is(0))
+ assertThat(provider.operationCount, is(0))
+ assertThat(provider.messageTextCount, is(2))
+
+ // check the two translated parts
+ assertThat(translated, startsWith("PC_start(prt);"))
+ assertThat(translated, containsString("\nPC_result(prt, lpt);"))
+
+ // and the result should not contain a null string
+ assertThat(translated, not(containsString("null")))
+ }
+
+ @Test
+ def void testReplPortMessage() {
+ // we want to test the exit code of state 'second'
+ val ac = model.actorClasses.filter[name=="AC"].head
+ val st = ac.stateMachine.states.filter[name=="second"].head
+
+ val translated = translator.getTranslatedCode(st.exitCode)
+ printResult("testReplPortMessage", st.exitCode, translated)
+
+ // check the translation count
+ assertThat(provider.attributeCount, is(0))
+ assertThat(provider.operationCount, is(0))
+ assertThat(provider.messageTextCount, is(2))
+
+ // check the two translated parts
+ assertThat(translated, startsWith("PC_start(replPrt, 0);"))
+ assertThat(translated, containsString("\nPC_start_broadcast(replPrt);"))
+
+ // and the result should not contain a null string
+ assertThat(translated, not(containsString("null")))
+ }
+
+ @Test
+ def void testActorClassAttributes() {
+ // we want to test the entry code of state 'first'
+ val ac = model.actorClasses.filter[name=="AC"].head
+ val st = ac.stateMachine.states.filter[name=="second"].head
+
+ val translated = translator.getTranslatedCode(st.entryCode)
+ printResult("testActorClassAttributes", st.entryCode, translated)
+
+ // check the translation count
+ assertThat(provider.attributeCount, is(8))
+ assertThat(provider.operationCount, is(3))
+ assertThat(provider.messageTextCount, is(0))
+
+ // check the translated parts
+ assertThat(translated, startsWith("double d = diameter(c(globalScopeSelf));"))
+ assertThat(translated, containsString("\nd = distance(p(globalScopeSelf, 0), p(globalScopeSelf, 1));"))
+ assertThat(translated, containsString("\nd = distance(globalScopeSelf, p(globalScopeSelf, 0), p(globalScopeSelf, 1));"))
+ assertThat(translated, containsString("\nd = x(c(c(globalScopeSelf)));"))
+ }
+
+ @Test
+ def void testDataClassOperationWithAttributesAndVarDecl() {
+ // we want to test the distance operation of data class Point
+ val dc = model.dataClasses.filter[name=="Point"].head
+ val op = dc.operations.filter[name=="distance"].head
+
+ val translated = translator.getTranslatedCode(op.detailCode)
+ printResult("testDataClassOperationWithAttributesAndVarDecl", op.detailCode, translated)
+
+ // check the translation count
+ assertThat(provider.attributeCount, is(4))
+ assertThat(provider.operationCount, is(0))
+ assertThat(provider.messageTextCount, is(0))
+
+ // check the two translated parts
+ assertThat(translated, startsWith("double dx = x(globalScopeSelf)- x(other);"))
+ assertThat(translated, containsString("\ndouble dy = y(globalScopeSelf)- y(other);"))
+
+ // and the result should not contain a null string
+ assertThat(translated, not(containsString("null")))
+ }
+
+ @Test
+ def void testDataClassOperationWithOperationCall() {
+ // we want to test the isInside operation of data class Circle
+ val dc = model.dataClasses.filter[name=="Circle"].head
+ val op = dc.operations.filter[name=="isInside"].head
+
+ val translated = translator.getTranslatedCode(op.detailCode)
+ printResult("testDataClassOperationWithOperationCall", op.detailCode, translated)
+
+ // check the translation count
+ assertThat(provider.attributeCount, is(2))
+ assertThat(provider.operationCount, is(1))
+ assertThat(provider.messageTextCount, is(0))
+
+ // check the translated part
+ assertThat(translated, startsWith("return distance(c(globalScopeSelf), other)< r(globalScopeSelf);"))
+
+ // and the result should not contain a null string
+ assertThat(translated, not(containsString("null")))
+ }
+
+ private def printResult(String test, DetailCode dc, String translated) {
+ println("<<<" + test)
+ println("orig:")
+ println(dc.detailCode)
+ println("translated:")
+ println(translated)
+ println(test + ">>>")
+ }
+} \ No newline at end of file
diff --git a/tests/org.eclipse.etrice.dctools.tests/src/org/eclipse/etrice/dctools/tests/TranslationProviderForTests.xtend b/tests/org.eclipse.etrice.dctools.tests/src/org/eclipse/etrice/dctools/tests/TranslationProviderForTests.xtend
new file mode 100644
index 000000000..807942ef7
--- /dev/null
+++ b/tests/org.eclipse.etrice.dctools.tests/src/org/eclipse/etrice/dctools/tests/TranslationProviderForTests.xtend
@@ -0,0 +1,125 @@
+/*******************************************************************************
+ * Copyright (c) 2011 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * CONTRIBUTORS:
+ * Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.dctools.tests
+
+import org.eclipse.etrice.dctools.ast.ITranslationProvider
+import org.eclipse.etrice.core.room.Attribute
+import org.eclipse.etrice.core.room.Operation
+import org.eclipse.etrice.core.room.InterfaceItem
+import org.eclipse.etrice.core.room.Message
+import org.eclipse.etrice.core.room.EnumLiteral
+import org.eclipse.etrice.core.fsm.fSM.AbstractInterfaceItem
+import org.eclipse.etrice.core.room.PortOperation
+import org.eclipse.emf.ecore.EObject
+import org.eclipse.etrice.core.fsm.fSM.DetailCode
+import org.eclipse.etrice.core.room.Port
+import org.eclipse.xtend.lib.annotations.Accessors
+import org.eclipse.xtend.lib.annotations.AccessorType
+
+class TranslationProviderForTests implements ITranslationProvider {
+
+ @Accessors(AccessorType.PUBLIC_GETTER)
+ var messageTextCount = 0
+
+ @Accessors(AccessorType.PUBLIC_GETTER)
+ var attributeCount = 0
+
+ @Accessors(AccessorType.PUBLIC_GETTER)
+ var operationCount = 0
+
+ override setContainerClass(EObject container) {
+ // unused
+ }
+
+ //-- members
+
+ override translateMembers() {
+ true
+ }
+
+ override getAttributeGetter(Attribute att, String instance, String index, String orig) {
+ attributeCount++
+ val slf = if (instance===null) "globalScopeSelf" else instance
+ val allArgs = slf + index.append
+ att.name + "(" + allArgs + ")"
+ }
+
+ override getAttributeSetter(Attribute att, String instance, String index, String value, String orig) {
+ throw new UnsupportedOperationException("TODO: auto-generated method stub")
+ }
+
+ override getOperationText(Operation op, String instance, String args, String orig) {
+ operationCount++
+ val slf = if (instance===null) "globalScopeSelf" else instance
+ val allArgs = slf + args.append
+ op.name + "(" + allArgs + ")"
+ }
+
+ override getInterfaceItemMessageText(AbstractInterfaceItem item, EObject msg, String ifitem, String args, String index, String orig) {
+ if (msg instanceof Message) {
+ if (item instanceof Port) {
+ messageTextCount++
+ val protocol = item.protocol
+ val allArgs = item.name + index.append + args.append
+ if (index===null && item.multiplicity!=1) {
+ protocol.name + "_" + msg.name + "_broadcast(" + allArgs + ")"
+ }
+ else {
+ protocol.name + "_" + msg.name + "(" + allArgs + ")"
+ }
+ }
+ else {
+ orig
+ }
+ }
+ else {
+ orig
+ }
+ }
+
+ override getInterfaceItemMessageValue(InterfaceItem item, Message msg, String orig) {
+ throw new UnsupportedOperationException("TODO: auto-generated method stub")
+ }
+
+ override getInterfaceItemOperationText(AbstractInterfaceItem item, PortOperation op, String instance, String args, String orig) {
+ throw new UnsupportedOperationException("TODO: auto-generated method stub")
+ }
+
+ //-- enums
+
+ override translateEnums() {
+ true
+ }
+
+ override getEnumText(EnumLiteral literal) {
+ throw new UnsupportedOperationException("TODO: auto-generated method stub")
+ }
+
+ //-- tags
+
+ override translateTags() {
+ true
+ }
+
+ override translateTag(String tag, DetailCode code) {
+ return TAG_START+"?"+tag+"?"+TAG_END;
+ }
+
+ private def append(String args) {
+ if (args!==null && !args.trim.empty)
+ ", " + args
+ else
+ ""
+ }
+
+} \ No newline at end of file
diff --git a/tests/org.eclipse.etrice.etunit.converter.tests/org.eclipse.etrice.etunit.converter.tests.launch b/tests/org.eclipse.etrice.etunit.converter.tests/org.eclipse.etrice.etunit.converter.tests.launch
index cd546f2fd..41bb14a77 100644
--- a/tests/org.eclipse.etrice.etunit.converter.tests/org.eclipse.etrice.etunit.converter.tests.launch
+++ b/tests/org.eclipse.etrice.etunit.converter.tests/org.eclipse.etrice.etunit.converter.tests.launch
@@ -29,7 +29,7 @@
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-os ${target.os} -ws ${target.ws} -arch ${target.arch} -nl ${target.nl} -consoleLog"/>
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="org.eclipse.etrice.etunit.converter.tests"/>
<stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.pde.ui.workbenchClasspathProvider"/>
-<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-ea&#13;&#10;-Xmx512m&#13;&#10;-Xms128m&#13;&#10;-XX:PermSize=32m&#13;&#10;-XX:MaxPermSize=256m&#13;&#10;-Dfile.encoding=UTF-8&#13;&#10;-Dosgi.requiredJavaVersion=1.8"/>
+<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-ea&#13;&#10;-Xmx512m&#13;&#10;-Xms128m&#13;&#10;-Dfile.encoding=UTF-8&#13;&#10;-Dosgi.requiredJavaVersion=1.8"/>
<stringAttribute key="pde.version" value="3.3"/>
<stringAttribute key="product" value="org.eclipse.platform.ide"/>
<booleanAttribute key="run_in_ui_thread" value="false"/>
diff --git a/tests/org.eclipse.etrice.generator.tests/org.eclipse.etrice.generator.tests.launch b/tests/org.eclipse.etrice.generator.tests/org.eclipse.etrice.generator.tests.launch
index 45e384c45..f1ea3ff66 100644
--- a/tests/org.eclipse.etrice.generator.tests/org.eclipse.etrice.generator.tests.launch
+++ b/tests/org.eclipse.etrice.generator.tests/org.eclipse.etrice.generator.tests.launch
@@ -33,7 +33,7 @@
<stringAttribute key="pde.version" value="3.3"/>
<stringAttribute key="product" value="org.eclipse.sdk.ide"/>
<booleanAttribute key="run_in_ui_thread" value="false"/>
-<stringAttribute key="selected_target_plugins" value="com.google.guava@default:default,com.google.inject@default:default,com.ibm.icu@default:default,javax.inject@default:default,javax.xml@default:default,org.antlr.runtime@default:default,org.apache.commons.cli@default:default,org.apache.commons.io@default:default,org.apache.commons.lang@default:default,org.apache.commons.logging@default:default,org.apache.log4j@default:default,org.eclipse.core.commands@default:default,org.eclipse.core.contenttype@default:default,org.eclipse.core.expressions@default:default,org.eclipse.core.filesystem.win32.x86_64@default:false,org.eclipse.core.filesystem@default:default,org.eclipse.core.jobs@default:default,org.eclipse.core.resources.win32.x86_64@default:false,org.eclipse.core.resources@default:default,org.eclipse.core.runtime@default:true,org.eclipse.core.variables@default:default,org.eclipse.debug.core@default:default,org.eclipse.emf.codegen.ecore@default:default,org.eclipse.emf.codegen@default:default,org.eclipse.emf.common@default:default,org.eclipse.emf.ecore.xmi@default:default,org.eclipse.emf.ecore@default:default,org.eclipse.emf.mwe.core@default:default,org.eclipse.emf.mwe.utils@default:default,org.eclipse.emf.mwe2.runtime@default:default,org.eclipse.emf@default:default,org.eclipse.equinox.app@default:default,org.eclipse.equinox.common@2:true,org.eclipse.equinox.preferences@default:default,org.eclipse.equinox.registry@default:default,org.eclipse.jdt.annotation*2.1.0.v20160418-1457@default:default,org.eclipse.jdt.compiler.apt@default:false,org.eclipse.jdt.compiler.tool@default:false,org.eclipse.jdt.core@default:default,org.eclipse.jdt.debug@default:default,org.eclipse.jdt.launching@default:default,org.eclipse.osgi.compatibility.state@default:false,org.eclipse.osgi@-1:true,org.eclipse.text@default:default,org.eclipse.xpand@default:default,org.eclipse.xtend.lib.macro@default:default,org.eclipse.xtend.lib@default:default,org.eclipse.xtend.typesystem.emf@default:default,org.eclipse.xtend@default:default,org.eclipse.xtext.common.types@default:default,org.eclipse.xtext.ecore@default:default,org.eclipse.xtext.generator@default:default,org.eclipse.xtext.logging@default:false,org.eclipse.xtext.smap@default:default,org.eclipse.xtext.util@default:default,org.eclipse.xtext.xbase.lib@default:default,org.eclipse.xtext.xtext.generator@default:default,org.eclipse.xtext@default:default,org.hamcrest.core@default:default,org.junit@default:default,org.objectweb.asm@default:default"/>
+<stringAttribute key="selected_target_plugins" value="com.google.guava*15.0.0.v201403281430@default:default,com.google.guava*21.0.0.v20170206-1425@default:default,com.google.inject@default:default,com.ibm.icu@default:default,javax.inject@default:default,javax.xml@default:default,org.antlr.runtime*3.2.0.v201101311130@default:default,org.antlr.runtime*4.3.0.v201502022030@default:default,org.apache.commons.cli@default:default,org.apache.commons.io@default:default,org.apache.commons.lang@default:default,org.apache.commons.logging@default:default,org.apache.log4j@default:default,org.eclipse.core.commands@default:default,org.eclipse.core.contenttype@default:default,org.eclipse.core.expressions@default:default,org.eclipse.core.filesystem.win32.x86_64@default:false,org.eclipse.core.filesystem@default:default,org.eclipse.core.jobs@default:default,org.eclipse.core.resources.win32.x86_64@default:false,org.eclipse.core.resources@default:default,org.eclipse.core.runtime@default:true,org.eclipse.core.variables@default:default,org.eclipse.debug.core@default:default,org.eclipse.emf.codegen.ecore@default:default,org.eclipse.emf.codegen@default:default,org.eclipse.emf.common@default:default,org.eclipse.emf.ecore.xmi@default:default,org.eclipse.emf.ecore@default:default,org.eclipse.emf.mwe.core@default:default,org.eclipse.emf.mwe.utils@default:default,org.eclipse.emf.mwe2.runtime@default:default,org.eclipse.emf@default:default,org.eclipse.equinox.app@default:default,org.eclipse.equinox.common@2:true,org.eclipse.equinox.preferences@default:default,org.eclipse.equinox.registry@default:default,org.eclipse.jdt.compiler.apt@default:false,org.eclipse.jdt.compiler.tool@default:false,org.eclipse.jdt.core@default:default,org.eclipse.jdt.debug@default:default,org.eclipse.jdt.launching@default:default,org.eclipse.osgi.compatibility.state@default:false,org.eclipse.osgi@-1:true,org.eclipse.text@default:default,org.eclipse.xpand@default:default,org.eclipse.xtend.lib.macro@default:default,org.eclipse.xtend.lib@default:default,org.eclipse.xtend.typesystem.emf@default:default,org.eclipse.xtend@default:default,org.eclipse.xtext.common.types@default:default,org.eclipse.xtext.ecore@default:default,org.eclipse.xtext.generator@default:default,org.eclipse.xtext.logging@default:false,org.eclipse.xtext.smap@default:default,org.eclipse.xtext.util@default:default,org.eclipse.xtext.xbase.lib@default:default,org.eclipse.xtext.xtext.generator@default:default,org.eclipse.xtext@default:default,org.hamcrest.core@default:default,org.junit@default:default,org.objectweb.asm*5.2.0.v20170126-0011@default:default,org.objectweb.asm*6.0.0.v20180116-1719@default:default"/>
<stringAttribute key="selected_workspace_plugins" value="org.eclipse.etrice.core.common@default:default,org.eclipse.etrice.core.etmap@default:default,org.eclipse.etrice.core.etphys@default:default,org.eclipse.etrice.core.fsm@default:default,org.eclipse.etrice.core.genmodel.fsm@default:default,org.eclipse.etrice.core.genmodel@default:default,org.eclipse.etrice.core.room@default:default,org.eclipse.etrice.generator.fsm@default:default,org.eclipse.etrice.generator.tests@default:default,org.eclipse.etrice.generator@default:default,org.eclipse.etrice.logging@default:false"/>
<booleanAttribute key="show_selected_only" value="true"/>
<booleanAttribute key="tracing" value="false"/>
diff --git a/tests/org.eclipse.etrice.generator.tests/src/org/eclipse/etrice/generator/base/TestDetailCodeTranslator.java b/tests/org.eclipse.etrice.generator.tests/src/org/eclipse/etrice/generator/base/TestDetailCodeTranslator.java
index ccfc8fa17..4161aca07 100644
--- a/tests/org.eclipse.etrice.generator.tests/src/org/eclipse/etrice/generator/base/TestDetailCodeTranslator.java
+++ b/tests/org.eclipse.etrice.generator.tests/src/org/eclipse/etrice/generator/base/TestDetailCodeTranslator.java
@@ -19,7 +19,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
-import java.util.ArrayList;
+import java.util.List;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.emf.ecore.EObject;
@@ -88,12 +88,12 @@ public class TestDetailCodeTranslator {
}
@Override
- public String getOperationText(Operation op, ArrayList<String> args, String orig) {
+ public String getOperationText(Operation op, List<String> args, String orig) {
return ">"+op.getName()+"("+getArgList(args)+")<";
}
@Override
- public String getInterfaceItemMessageText(AbstractInterfaceItem item, EObject abstractMsg, ArrayList<String> args, String index, String orig) {
+ public String getInterfaceItemMessageText(AbstractInterfaceItem item, EObject abstractMsg, List<String> args, String index, String orig) {
if (!(abstractMsg instanceof Message))
return orig;
@@ -110,7 +110,7 @@ public class TestDetailCodeTranslator {
return ">"+item.getName()+"."+msg.getName()+"<";
}
- private String getArgList(ArrayList<String> args) {
+ private String getArgList(List<String> args) {
StringBuilder result = new StringBuilder();
for (String string : args) {
result.append(string+", ");
@@ -145,11 +145,11 @@ public class TestDetailCodeTranslator {
}
/* (non-Javadoc)
- * @see org.eclipse.etrice.generator.base.ITranslationProvider#getInterfaceItemOperationText(org.eclipse.etrice.core.fsm.fSM.AbstractInterfaceItem, org.eclipse.etrice.core.room.PortOperation, java.util.ArrayList, java.lang.String)
+ * @see org.eclipse.etrice.generator.base.ITranslationProvider#getInterfaceItemOperationText(org.eclipse.etrice.core.fsm.fSM.AbstractInterfaceItem, org.eclipse.etrice.core.room.PortOperation, java.util.List, java.lang.String)
*/
@Override
public String getInterfaceItemOperationText(AbstractInterfaceItem item,
- PortOperation op, ArrayList<String> args, String orig) {
+ PortOperation op, List<String> args, String orig) {
return null;
}
}
diff --git a/tests/org.eclipse.etrice.ui.behavior.tests/org.eclipse.etrice.ui.behavior.tests.launch b/tests/org.eclipse.etrice.ui.behavior.tests/org.eclipse.etrice.ui.behavior.tests.launch
index 637fadb1f..1d7afa5bd 100644
--- a/tests/org.eclipse.etrice.ui.behavior.tests/org.eclipse.etrice.ui.behavior.tests.launch
+++ b/tests/org.eclipse.etrice.ui.behavior.tests/org.eclipse.etrice.ui.behavior.tests.launch
@@ -33,7 +33,7 @@
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-os ${target.os} -ws ${target.ws} -arch ${target.arch} -nl ${target.nl} -consoleLog"/>
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="org.eclipse.etrice.ui.behavior.tests"/>
<stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.pde.ui.workbenchClasspathProvider"/>
-<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-ea&#13;&#10;-Xmx512m&#13;&#10;-Xms128m&#13;&#10;-XX:PermSize=32m&#13;&#10;-XX:MaxPermSize=256m&#13;&#10;-Dfile.encoding=UTF-8&#13;&#10;-Dosgi.requiredJavaVersion=1.5"/>
+<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-ea&#13;&#10;-Xmx512m&#13;&#10;-Xms128m&#13;&#10;-Dfile.encoding=UTF-8&#13;&#10;-Dosgi.requiredJavaVersion=1.5"/>
<stringAttribute key="pde.version" value="3.3"/>
<stringAttribute key="product" value="org.eclipse.platform.ide"/>
<booleanAttribute key="run_in_ui_thread" value="true"/>
diff --git a/tests/org.eclipse.etrice.ui.structure.tests/org.eclipse.etrice.ui.structure.tests.launch b/tests/org.eclipse.etrice.ui.structure.tests/org.eclipse.etrice.ui.structure.tests.launch
index 0550a9654..7a69f51e9 100644
--- a/tests/org.eclipse.etrice.ui.structure.tests/org.eclipse.etrice.ui.structure.tests.launch
+++ b/tests/org.eclipse.etrice.ui.structure.tests/org.eclipse.etrice.ui.structure.tests.launch
@@ -32,7 +32,7 @@
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-os ${target.os} -ws ${target.ws} -arch ${target.arch} -nl ${target.nl} -consoleLog"/>
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="org.eclipse.etrice.ui.structure.tests"/>
<stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.pde.ui.workbenchClasspathProvider"/>
-<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-ea&#13;&#10;-Xmx512m&#13;&#10;-Xms128m&#13;&#10;-XX:PermSize=32m&#13;&#10;-XX:MaxPermSize=256m&#13;&#10;-Dfile.encoding=UTF-8&#13;&#10;-Dosgi.requiredJavaVersion=1.5"/>
+<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-ea&#13;&#10;-Xmx512m&#13;&#10;-Xms128m&#13;&#10;-Dfile.encoding=UTF-8&#13;&#10;-Dosgi.requiredJavaVersion=1.5"/>
<stringAttribute key="pde.version" value="3.3"/>
<stringAttribute key="product" value="org.eclipse.platform.ide"/>
<booleanAttribute key="run_in_ui_thread" value="true"/>

Back to the top