Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJuergen Haug2019-01-17 15:48:03 +0000
committerJuergen Haug2019-01-17 15:48:03 +0000
commit08f2edfebbeb032aed2e3a972edeaa616d9cdf03 (patch)
tree37266af668fea9de9082d7440e244ee15356d749
parentda48ed6bbfdee34b1a42c76b5b2325aaeb296208 (diff)
downloadorg.eclipse.etrice-08f2edfebbeb032aed2e3a972edeaa616d9cdf03.tar.gz
org.eclipse.etrice-08f2edfebbeb032aed2e3a972edeaa616d9cdf03.tar.xz
org.eclipse.etrice-08f2edfebbeb032aed2e3a972edeaa616d9cdf03.zip
[Bug 540562] Support var args for operations
-rw-r--r--plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/ActorClassGen.xtend28
-rw-r--r--plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/DataClassGen.xtend23
-rw-r--r--plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/ProtocolClassGen.xtend23
-rw-r--r--plugins/org.eclipse.etrice.generator.fsm/src/org/eclipse/etrice/generator/fsm/base/Diagnostician.java22
-rw-r--r--plugins/org.eclipse.etrice.generator/src/org/eclipse/etrice/generator/base/DetailCodeTranslator.java3
-rw-r--r--tests/org.eclipse.etrice.generator.common.tests/build.gradle6
-rw-r--r--tests/org.eclipse.etrice.generator.common.tests/models/CompileTests.room2
-rw-r--r--tests/org.eclipse.etrice.generator.common.tests/models/VarargsTest.room65
8 files changed, 145 insertions, 27 deletions
diff --git a/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/ActorClassGen.xtend b/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/ActorClassGen.xtend
index dee7b704e..9b702edd6 100644
--- a/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/ActorClassGen.xtend
+++ b/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/ActorClassGen.xtend
@@ -283,8 +283,9 @@ class ActorClassGen extends GenericActorClassGenerator {
/* operations */
«FOR op : ac.latestOperations»
- «val args = op.argList»
- #define «op.name»(«args») «ac.name»_«op.name»(self«IF !op.arguments.empty», «args»«ENDIF»)
+ «val params = op.operationParams»
+ «val args = op.operationArgs»
+ #define «op.name»(«params») «ac.name»_«op.name»(self«IF !op.arguments.empty», «args»«ENDIF»)
«ENDFOR»
/* attributes */
@@ -295,8 +296,9 @@ class ActorClassGen extends GenericActorClassGenerator {
/* port operations */
«FOR p : portsWithOperations»
«FOR op : p.portClass.operations»
- «val args = op.argList»
- #define «p.name»_«op.name»(«args») «p.portClassName»_«op.name»((«p.portClassName»*)&self->constData->«p.name»«IF !op.arguments.empty», «args»«ENDIF»)
+ «val params = op.operationParams»
+ «val args = op.operationArgs»
+ #define «p.name»_«op.name»(«params») «p.portClassName»_«op.name»((«p.portClassName»*)&self->constData->«p.name»«IF !op.arguments.empty», «args»«ENDIF»)
«ENDFOR»
«ENDFOR»
@@ -305,8 +307,22 @@ class ActorClassGen extends GenericActorClassGenerator {
'''
}
- private def argList(Operation op) {
- '''«FOR a : op.arguments SEPARATOR ", "»«a.name»«ENDFOR»'''
+ private def operationParams(Operation op) {
+ op.arguments.map[
+ switch it {
+ case isVarargs: '...'
+ default: name
+ }
+ ].join(', ')
+ }
+
+ private def operationArgs(Operation op) {
+ op.arguments.map[
+ switch it {
+ case isVarargs: '__VA_ARGS__'
+ default: name
+ }
+ ].join(', ')
}
def protected generateSourceFile(Root root, ExpandedActorClass xpac) {
diff --git a/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/DataClassGen.xtend b/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/DataClassGen.xtend
index 46ceea2f9..774ace9e6 100644
--- a/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/DataClassGen.xtend
+++ b/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/DataClassGen.xtend
@@ -120,8 +120,9 @@ class DataClassGen {
/* operations */
«FOR op : dc.allOperations»
- «val args = op.argList»
- #define «op.name»(«args») «dc.name»_«op.name»(self«IF !op.arguments.empty», «args»«ENDIF»)
+ «val params = op.operationParams»
+ «val args = op.operationArgs»
+ #define «op.name»(«params») «dc.name»_«op.name»(self«IF !op.arguments.empty», «args»«ENDIF»)
«ENDFOR»
/* attributes */
@@ -134,8 +135,22 @@ class DataClassGen {
'''
}
- private def argList(Operation op) {
- '''«FOR a : op.arguments SEPARATOR ", "»«a.name»«ENDFOR»'''
+ private def operationParams(Operation op) {
+ op.arguments.map[
+ switch it {
+ case isVarargs: '...'
+ default: name
+ }
+ ].join(', ')
+ }
+
+ private def operationArgs(Operation op) {
+ op.arguments.map[
+ switch it {
+ case isVarargs: '__VA_ARGS__'
+ default: name
+ }
+ ].join(', ')
}
def generateSourceFile(Root root, DataClass dc) {'''
diff --git a/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/ProtocolClassGen.xtend b/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/ProtocolClassGen.xtend
index 22b3c60c1..f6fd647c4 100644
--- a/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/ProtocolClassGen.xtend
+++ b/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/ProtocolClassGen.xtend
@@ -152,8 +152,9 @@ class ProtocolClassGen extends GenericProtocolClassGenerator {
/* operations */
«FOR op : portClass.operations»
- «val args = op.argList»
- #define «op.name»(«args») «portClassName»_«op.name»(self«IF !op.arguments.empty», «args»«ENDIF»)
+ «val params = op.operationParams»
+ «val args = op.operationArgs»
+ #define «op.name»(«params») «portClassName»_«op.name»(self«IF !op.arguments.empty», «args»«ENDIF»)
«ENDFOR»
/* attributes */
@@ -164,8 +165,22 @@ class ProtocolClassGen extends GenericProtocolClassGenerator {
'''
}
- private def argList(Operation op) {
- '''«FOR a : op.arguments SEPARATOR ", "»«a.name»«ENDFOR»'''
+ private def operationParams(Operation op) {
+ op.arguments.map[
+ switch it {
+ case isVarargs: '...'
+ default: name
+ }
+ ].join(', ')
+ }
+
+ private def operationArgs(Operation op) {
+ op.arguments.map[
+ switch it {
+ case isVarargs: '__VA_ARGS__'
+ default: name
+ }
+ ].join(', ')
}
def private generateSourceFile(Root root, ProtocolClass pc) {'''
diff --git a/plugins/org.eclipse.etrice.generator.fsm/src/org/eclipse/etrice/generator/fsm/base/Diagnostician.java b/plugins/org.eclipse.etrice.generator.fsm/src/org/eclipse/etrice/generator/fsm/base/Diagnostician.java
index 258f84abe..7761e0642 100644
--- a/plugins/org.eclipse.etrice.generator.fsm/src/org/eclipse/etrice/generator/fsm/base/Diagnostician.java
+++ b/plugins/org.eclipse.etrice.generator.fsm/src/org/eclipse/etrice/generator/fsm/base/Diagnostician.java
@@ -87,17 +87,21 @@ public class Diagnostician implements IDiagnostician {
}
EObject errorObject = null;
- Object obj = source.eGet(feature);
- if (feature.isMany() && obj instanceof List<?>) {
- if (idx>=0) {
- List<?> list = (List<?>) obj;
- if (list.size()>idx) {
- errorObject = (EObject) list.get(idx);
+ if(feature != null) {
+ Object obj = source.eGet(feature);
+ if (feature.isMany() && obj instanceof List<?>) {
+ if (idx>=0) {
+ List<?> list = (List<?>) obj;
+ if (list.size()>idx) {
+ errorObject = (EObject) list.get(idx);
+ }
}
}
- }
- else {
- errorObject = (EObject) obj;
+ else {
+ errorObject = (EObject) obj;
+ }
+ } else {
+ errorObject = source;
}
if (errorObject!=null) {
// prefer location to toString()
diff --git a/plugins/org.eclipse.etrice.generator/src/org/eclipse/etrice/generator/base/DetailCodeTranslator.java b/plugins/org.eclipse.etrice.generator/src/org/eclipse/etrice/generator/base/DetailCodeTranslator.java
index b15a3ecf0..f3320d9f2 100644
--- a/plugins/org.eclipse.etrice.generator/src/org/eclipse/etrice/generator/base/DetailCodeTranslator.java
+++ b/plugins/org.eclipse.etrice.generator/src/org/eclipse/etrice/generator/base/DetailCodeTranslator.java
@@ -157,7 +157,8 @@ public class DetailCodeTranslator extends FSMDetailCodeTranslator {
Operation operation = name2op.get(token);
if (operation!=null && (operation.eContainer() instanceof ActorClass || operation.eContainer() instanceof DataClass)) {
ArrayList<String> args = getArgs(text, curr);
- if (args!=null && operation.getArguments().size()==args.size()) {
+ boolean isVarargs = operation.getArguments().stream().anyMatch(arg -> arg.isVarargs());
+ if (args!=null && (operation.getArguments().size()==args.size() || isVarargs)) {
// recursively apply this algorithm to each argument
for (int i=0; i<args.size(); ++i) {
String transArg = translateText(args.remove(i));
diff --git a/tests/org.eclipse.etrice.generator.common.tests/build.gradle b/tests/org.eclipse.etrice.generator.common.tests/build.gradle
index db760ff3d..42d4d908d 100644
--- a/tests/org.eclipse.etrice.generator.common.tests/build.gradle
+++ b/tests/org.eclipse.etrice.generator.common.tests/build.gradle
@@ -12,7 +12,7 @@ def tests = [
choicePointTestExtended: ['models/ChoicePointTestExtended.room', genericPhysical],
dataDrivenTest: ['models/DataDrivenTest.room', genericPhysical],
/* enumTest: ['models/EnumTest.room', genericPhysical], not supported in c++ */
- compileTests: ['models/CompileTests.room', genericPhysical, 'models/StatemachineInterfaceTest.room', 'models/StatemachineInterfaceInheritedTest.room', 'models/StatemachineInterfaceTest.room', 'models/ContinuationTransitionTest.room', 'models/VarargsTest.room'],
+ compileTests: ['models/CompileTests.room', genericPhysical, 'models/StatemachineInterfaceTest.room', 'models/StatemachineInterfaceInheritedTest.room', 'models/StatemachineInterfaceTest.room', 'models/ContinuationTransitionTest.room'],
handlerTest: ['models/HandlerTest.room', genericPhysical],
operationInheritanceTest: ['models/OperationInheritanceTest.room', genericPhysical],
@@ -33,3 +33,7 @@ createTest('java', 'enumTest', ['models/EnumTest.room', genericPhysical])
// DetailExpressionCompile Test
createTest('c', 'detailExpressionCompileTest', [genericPhysical, 'models/DetailExpressionTest.room', 'models/DetailExpressionEnum.room', 'models/DetailExpressionTypes.room'])
createTest('java', 'detailExpressionCompileTest', [genericPhysical, 'models/DetailExpressionTest.room', 'models/DetailExpressionEnum.room', 'models/DetailExpressionTypes.room'])
+
+// VarargsTTest
+createTest('c', 'varargsTest', [genericPhysical, 'models/VarargsTest.room'])
+createTest('java', 'varargsTest', [genericPhysical, 'models/VarargsTest.room'])
diff --git a/tests/org.eclipse.etrice.generator.common.tests/models/CompileTests.room b/tests/org.eclipse.etrice.generator.common.tests/models/CompileTests.room
index e2790656b..f846c4db5 100644
--- a/tests/org.eclipse.etrice.generator.common.tests/models/CompileTests.room
+++ b/tests/org.eclipse.etrice.generator.common.tests/models/CompileTests.room
@@ -6,7 +6,6 @@ RoomModel CompileTests {
import StatemachineInterfaceTestModel.StatemachineInterfaceTest from "StatemachineInterfaceTest.room"
import StatemachineInterfaceTestInheritedModel.StatemachineInterfaceInheritedTest from "StatemachineInterfaceInheritedTest.room"
import ContinuationTransitionTest.ContinuationTransitionTest from "ContinuationTransitionTest.room"
- import VarargsTest.* from "VarargsTest.room"
ActorClass CompileTests {
@TestInstance
@@ -17,7 +16,6 @@ RoomModel CompileTests {
ActorRef statemachineInterfaceTest : StatemachineInterfaceTest
ActorRef statemachineInterfaceInheritedTest : StatemachineInterfaceInheritedTest
ActorRef continuationTransitionTest : ContinuationTransitionTest
- ActorRef varargsTest : AVarargs
}
Behavior {
ctor {
diff --git a/tests/org.eclipse.etrice.generator.common.tests/models/VarargsTest.room b/tests/org.eclipse.etrice.generator.common.tests/models/VarargsTest.room
index dde861c7c..19e28a487 100644
--- a/tests/org.eclipse.etrice.generator.common.tests/models/VarargsTest.room
+++ b/tests/org.eclipse.etrice.generator.common.tests/models/VarargsTest.room
@@ -1,17 +1,66 @@
RoomModel VarargsTest {
import room.basic.types.* from "../../../runtime/${etModellib}/model/Types.room"
+ import room.basic.test.* from "../../../runtime/${etModellib}/model/Tests.room"
ActorClass AVarargs {
+ @TestInstance
Structure {
+ Attribute caseId : int32
+
Port port: PVarargs
Attribute attr: DVarargs
+ Attribute text : string = "text"
}
Behavior {
// varargs keyword is hidden in proposals -> internal use
Operation log(format: string, args: string varargs) ''''''
Operation single(args: string varargs) ''''''
+ Operation callTest() '''
+ //log("text");
+ log("text %d", "5");
+ log("text %d, %s", "5", text);
+ //single();
+ single("5");
+ single("5", "txt");
+
+ // not supported by translation
+ /*
+ port.callTest();
+ attr.callTest();
+
+ //port.log("text");
+ port.log("text %d", "5");
+ port.log("text %d, %s", "5", "txt");
+ //port.single();
+ port.single("5");
+ port.single("5", "txt");
+
+ //attr.log("text");
+ attr.log("text %d", "5");
+ attr.log("text %d, %s", "5", "txt");
+ //attr.single();
+ attr.single("5");
+ attr.single("5", "txt");
+ */
+ '''
+
+ ctor '''
+ caseId = etUnit_openAll("log", "VarargsTest", "org.eclipse.etrice.generator.common.tests.VarargsTest", "VarargsTest_case");
+ '''
+ dtor '''
+ etUnit_closeAll(caseId);
+ '''
+ StateMachine {
+ Transition init: initial -> finish
+ State finish {
+ entry '''
+ callTest();
+ etUnit_testFinished(caseId);
+ '''
+ }
+ }
}
}
@@ -23,6 +72,14 @@ RoomModel VarargsTest {
{
Operation log(format: string, args: string varargs) ''''''
Operation single(args: string varargs) ''''''
+ Operation callTest() '''
+ //log("text");
+ log("text %d", "5");
+ log("text %d, %s", "5", "txt");
+ //single();
+ single("5");
+ single("5", "txt");
+ '''
}
}
@@ -32,5 +89,13 @@ RoomModel VarargsTest {
// varargs keyword is hidden in proposals -> internal use
Operation log(format: string, args: string varargs) ''''''
Operation single(args: string varargs) ''''''
+ Operation callTest() '''
+ //log("text");
+ log("text %d", "5");
+ log("text %d, %s", "5", "txt");
+ //single();
+ single("5");
+ single("5", "txt");
+ '''
}
} \ No newline at end of file

Back to the top