Forráskód Böngészése

OCB interfaces should be checked for null in enter() method (#1757)

* added error code and tests

* added cpp test

* added implementation for errorCode

* added optional feature for error code and unimplemted ocbs

* Added docu for feature
rherrmannr 8 éve
szülő
commit
3f2df58746
18 módosított fájl, 444 hozzáadás és 9 törlés
  1. 20 0
      plugins/org.yakindu.sct.doc.user/src/user-guide/generating_code.textile
  2. 8 0
      plugins/org.yakindu.sct.generator.cpp/library/FeatureTypeLibrary.xmi
  3. 24 0
      plugins/org.yakindu.sct.generator.cpp/src/org/yakindu/sct/generator/cpp/ErrorCode.java
  4. 1 1
      plugins/org.yakindu.sct.generator.cpp/src/org/yakindu/sct/generator/cpp/StatemachineHeader.xtend
  5. 38 2
      plugins/org.yakindu.sct.generator.cpp/src/org/yakindu/sct/generator/cpp/StatemachineImplementation.xtend
  6. 3 2
      plugins/org.yakindu.sct.generator.cpp/src/org/yakindu/sct/generator/cpp/StatemachineInterface.xtend
  7. 21 2
      plugins/org.yakindu.sct.generator.cpp/src/org/yakindu/sct/generator/cpp/Types.xtend
  8. 7 1
      plugins/org.yakindu.sct.generator.cpp/src/org/yakindu/sct/generator/cpp/features/CPPDefaultFeatureValueProvider.java
  9. 4 0
      plugins/org.yakindu.sct.generator.cpp/src/org/yakindu/sct/generator/cpp/features/CPPFeatureConstants.java
  10. 14 0
      plugins/org.yakindu.sct.generator.cpp/src/org/yakindu/sct/generator/cpp/features/GenmodelEntriesExtension.xtend
  11. 38 0
      test-plugins/org.yakindu.sct.generator.cpp.test/gtests/UnimplementedOCBTest/OCBDefaultInterfaceImpl.h
  12. 36 0
      test-plugins/org.yakindu.sct.generator.cpp.test/gtests/UnimplementedOCBTest/OCBInternalImpl.h
  13. 35 0
      test-plugins/org.yakindu.sct.generator.cpp.test/gtests/UnimplementedOCBTest/OCBNamedInterfaceImpl.h
  14. 24 0
      test-plugins/org.yakindu.sct.generator.cpp.test/gtests/UnimplementedOCBTest/UnimplementedOCB.sgen
  15. 34 0
      test-plugins/org.yakindu.sct.generator.cpp.test/gtests/UnimplementedOCBTest/UnimplementedOCBTest.cc
  16. 1 1
      test-plugins/org.yakindu.sct.generator.cpp.test/src/org/yakindu/sct/generator/cpp/test/AllTestsTestCustom.java
  17. 47 0
      test-plugins/org.yakindu.sct.generator.cpp.test/src/org/yakindu/sct/generator/cpp/test/UnimplementedOCBTest.java
  18. 89 0
      test-plugins/org.yakindu.sct.test.models/testmodels/SCTUnit/UnimplementedOCB.sct

+ 20 - 0
plugins/org.yakindu.sct.doc.user/src/user-guide/generating_code.textile

@@ -989,6 +989,26 @@ bc. feature Includes {
 ==<!-- End sgen_feature_includes -->==
 
 
+==<!-- Start sgen_feature_api -->==
+
+h4(#codegen_cpp_api_feature). API feature
+
+The *API* feature allows to change the way include statements are generated:
+
+* _checkUnimplementedOCBs_ (Boolean, optional): If set to _true_ init function returns an error code, otherwise the init function return type is void.
+
+==<div class="example">==
+
+Example:
+
+bc. feature API {
+    checkUnimplementedOCBs = true
+}
+
+==</div>==
+
+==<!-- End sgen_feature_api -->==
+
 
 
 h3(#codegen_cpp_specification_of_cpp_code). Specification of C++ code

+ 8 - 0
plugins/org.yakindu.sct.generator.cpp/library/FeatureTypeLibrary.xmi

@@ -40,4 +40,12 @@
         optional="true"
         parameterType="BOOLEAN"/>
   </types>
+  <types name="API"
+      comment=""
+      optional="true">
+    <parameters
+        name="checkUnimplementedOCBs"
+        comment="If set to 'true' init function returns an error code, otherwise the init function return type is void."
+        parameterType="BOOLEAN"/>
+  </types>
 </sgen:FeatureTypeLibrary>

+ 24 - 0
plugins/org.yakindu.sct.generator.cpp/src/org/yakindu/sct/generator/cpp/ErrorCode.java

@@ -0,0 +1,24 @@
+package org.yakindu.sct.generator.cpp;
+
+public enum ErrorCode {
+	OCB_INIT_MASK("0b1000000100000000", "OCB_INIT_ERROR_MASK"),
+	OCB_DEFAULT_INIT("0b00000001", "OCB_DEFAULT_INIT_ERROR"),
+	OCB_NAMED_INIT("0b00000010", "OCB_NAMED_INIT_ERROR"),
+	OCB_INTERNAL_INIT("0b00000100", "OCB_INTERNAL_INIT_ERROR")
+	;
+	
+	protected String value;
+	protected String name;
+	ErrorCode(String value, String name) {
+		this.value = value;
+		this.name = name;
+	}
+	
+	public String getValue() {
+		return value;
+	}
+	
+	public String getName() {
+		return name;
+	}
+}

+ 1 - 1
plugins/org.yakindu.sct.generator.cpp/src/org/yakindu/sct/generator/cpp/StatemachineHeader.xtend

@@ -296,7 +296,7 @@ class StatemachineHeader extends org.yakindu.sct.generator.c.StatemachineHeader
 		/*
 		 * Functions inherited from StatemachineInterface
 		 */
-		virtual void init();
+		virtual «IF entry.checkUnimplementedOCBs»sc_errorCode«ELSE»void«ENDIF» init();
 		
 		virtual void enter();
 		

+ 38 - 2
plugins/org.yakindu.sct.generator.cpp/src/org/yakindu/sct/generator/cpp/StatemachineImplementation.xtend

@@ -14,6 +14,7 @@ import com.google.inject.Inject
 import java.util.List
 import org.yakindu.sct.generator.c.IContentTemplate
 import org.yakindu.sct.generator.c.IGenArtifactConfigurations
+import org.yakindu.sct.generator.c.extensions.ExpressionsChecker
 import org.yakindu.sct.generator.core.types.ICodegenTypeSystemAccess
 import org.yakindu.sct.generator.cpp.features.GenmodelEntriesExtension
 import org.yakindu.sct.model.sexec.Check
@@ -23,11 +24,11 @@ import org.yakindu.sct.model.sexec.extensions.StateVectorExtensions
 import org.yakindu.sct.model.sexec.naming.INamingService
 import org.yakindu.sct.model.sgen.GeneratorEntry
 import org.yakindu.sct.model.stext.stext.InterfaceScope
+import org.yakindu.sct.model.stext.stext.InternalScope
 import org.yakindu.sct.model.stext.stext.StatechartScope
 import org.yakindu.sct.model.stext.stext.VariableDefinition
 
 import static org.eclipse.xtext.util.Strings.*
-import org.yakindu.sct.generator.c.extensions.ExpressionsChecker
 
 class StatemachineImplementation implements IContentTemplate {
 	
@@ -150,8 +151,12 @@ class StatemachineImplementation implements IContentTemplate {
 	'''
 	
 	def initFunction(ExecutionFlow it) '''
-		void «module»::init()
+		«IF entry.checkUnimplementedOCBs»sc_errorCode«ELSE»void«ENDIF» «module»::init()
 		{
+			«IF entry.checkUnimplementedOCBs»
+			sc_errorCode errorCode = 0;
+			
+			«unimplementedOCBErrors»«ENDIF»
 			for (int i = 0; i < «orthogonalStatesConst»; ++i)
 				stateConfVector[i] = «null_state»;
 			
@@ -166,6 +171,9 @@ class StatemachineImplementation implements IContentTemplate {
 			clearOutEvents();
 			
 			«initSequence.code»
+			«IF entry.checkUnimplementedOCBs»
+			return errorCode;
+			«ENDIF»
 		}
 	'''
 	
@@ -328,6 +336,34 @@ class StatemachineImplementation implements IContentTemplate {
 		«ENDFOR»
 	'''
 	
+	def unimplementedOCBErrors(ExecutionFlow it)'''
+		«FOR iface : getInterfaces.filter[hasOperations && !entry.useStaticOPC]»
+			«IF iface instanceof InternalScope»
+				«checkInternalOCB(iface)»			
+			«ELSEIF iface instanceof InterfaceScope»
+				«checkInterfaceOCB(iface)»
+			«ENDIF»
+		«ENDFOR»
+	'''
+	
+	def checkInternalOCB(StatechartScope it) '''
+		if (this->«OCB_Instance» == null) { 
+			errorCode |= «ErrorCode.OCB_INTERNAL_INIT.name»;
+		}
+	'''
+	
+	def checkInterfaceOCB(StatechartScope it) '''
+		«IF defaultInterface»
+			if (this->«OCB_Instance» == null) { 
+				errorCode |=  «ErrorCode.OCB_DEFAULT_INIT.name»;
+			}
+		«ELSE»
+			if (this->«OCB_Instance» == null) { 
+				errorCode |= «ErrorCode.OCB_NAMED_INIT.name»;
+			}
+		«ENDIF»
+	'''
+	
 	/* ===================================================================================
 	 * Implementation of interface element access functions
 	 */

+ 3 - 2
plugins/org.yakindu.sct.generator.cpp/src/org/yakindu/sct/generator/cpp/StatemachineInterface.xtend

@@ -15,6 +15,7 @@ import org.yakindu.sct.generator.c.IGenArtifactConfigurations
 import org.yakindu.sct.generator.c.extensions.GenmodelEntries
 import org.yakindu.sct.model.sexec.ExecutionFlow
 import org.yakindu.sct.model.sgen.GeneratorEntry
+import org.yakindu.sct.generator.cpp.features.GenmodelEntriesExtension
 
 class StatemachineInterface implements IContentTemplate {
 	
@@ -22,7 +23,7 @@ class StatemachineInterface implements IContentTemplate {
 	extension CppNaming
 	
 	@Inject
-	extension GenmodelEntries
+	extension GenmodelEntriesExtension
 	
 	override content(ExecutionFlow it, GeneratorEntry entry, IGenArtifactConfigurations locations) {
 		'''
@@ -41,7 +42,7 @@ class StatemachineInterface implements IContentTemplate {
 				
 				/*! Initializes the state machine. Used to initialize internal variables etc.
 				*/
-				virtual void init() = 0;
+				virtual «IF entry.checkUnimplementedOCBs»sc_errorCode«ELSE»void«ENDIF» init() = 0;
 			
 				/*! Enters the state machine. Sets the state machine into a defined state.
 				*/

+ 21 - 2
plugins/org.yakindu.sct.generator.cpp/src/org/yakindu/sct/generator/cpp/Types.xtend

@@ -32,21 +32,40 @@ class Types implements IContentTemplate {
 		// #include <cstdint>
 		#include <stdint.h>
 		
-
+		#ifndef sc_string
 		#define sc_string      char*
+		#endif
 		
 		typedef int_fast16_t   sc_short;
 		typedef uint_fast16_t  sc_ushort;
 		typedef int32_t        sc_integer;
+		typedef int16_t		   sc_errorCode;
 		typedef double         sc_real;
 		typedef bool           sc_boolean;
 		
 		typedef intptr_t       sc_eventid;
 		
 		#ifndef «CppNaming::NULL_STRING»
-			#define «CppNaming::NULL_STRING» 0
+		#define «CppNaming::NULL_STRING» 0
 		#endif
 		
+		/* Error codes and mask can be used to check unimplemented operation callbacks. They can be activated in the API feature within the .sgen file.*/
+		#ifndef «ErrorCode.OCB_INIT_MASK.name»
+		#define «ErrorCode.OCB_INIT_MASK.name» «ErrorCode.OCB_INIT_MASK.value»
+		#endif
+
+		#ifndef «ErrorCode.OCB_DEFAULT_INIT.name»
+		#define «ErrorCode.OCB_DEFAULT_INIT.name» («ErrorCode.OCB_INIT_MASK.name» | «ErrorCode.OCB_DEFAULT_INIT.value»)
+		#endif
+
+		#ifndef «ErrorCode.OCB_NAMED_INIT.name»
+		#define «ErrorCode.OCB_NAMED_INIT.name» («ErrorCode.OCB_INIT_MASK.name» | «ErrorCode.OCB_NAMED_INIT.value»)
+		#endif
+
+		#ifndef «ErrorCode.OCB_INTERNAL_INIT.name»
+		#define «ErrorCode.OCB_INTERNAL_INIT.name» («ErrorCode.OCB_INIT_MASK.name» | «ErrorCode.OCB_INTERNAL_INIT.value»)
+		#endif			
+		
 		#endif /* «typesModule.define»_H_ */
 	'''
 	

+ 7 - 1
plugins/org.yakindu.sct.generator.cpp/src/org/yakindu/sct/generator/cpp/features/CPPDefaultFeatureValueProvider.java

@@ -62,7 +62,9 @@ public class CPPDefaultFeatureValueProvider extends AbstractDefaultFeatureValueP
 			parameterValue.setValue(false);
 		} else if (parameterValue.getParameter().getName().equals(CPPFeatureConstants.PARAMETER_INCLUDES_USE_RELATIVE_PATHS)) {
 			parameterValue.setValue(true);
-		}
+		} else if (parameterValue.getParameter().getName().equals(CPPFeatureConstants.PARAMETER_API_CHECK_UNIMPLEMENTED_OCBS)) {
+			parameterValue.setValue(true);
+		} 
 	}
 
 	public IStatus validateParameterValue(FeatureParameterValue parameter) {
@@ -90,6 +92,10 @@ public class CPPDefaultFeatureValueProvider extends AbstractDefaultFeatureValueP
 			if (!found) {
 				return error("Visibility could only be private or protected");
 			}
+		} else if (CPPFeatureConstants.PARAMETER_API_CHECK_UNIMPLEMENTED_OCBS.equals(parameterName)) {
+			if (!parameter.getStringValue().matches(VALID_IDENTIFIER_REGEX)) {
+				return error ("Invalid check for unimplemented OCBs");
+			}
 		}
 		return Status.OK_STATUS;
 	}

+ 4 - 0
plugins/org.yakindu.sct.generator.cpp/src/org/yakindu/sct/generator/cpp/features/CPPFeatureConstants.java

@@ -33,4 +33,8 @@ public interface CPPFeatureConstants {
 	public static final String FEATURE_INCLUDES = "Includes";
 	
 	public static final String PARAMETER_INCLUDES_USE_RELATIVE_PATHS = "useRelativePaths";
+
+	public static final String FEATURE_API = "API";
+	
+	public static final String PARAMETER_API_CHECK_UNIMPLEMENTED_OCBS = "checkUnimplementedOCBs";
 }

+ 14 - 0
plugins/org.yakindu.sct.generator.cpp/src/org/yakindu/sct/generator/cpp/features/GenmodelEntriesExtension.xtend

@@ -19,10 +19,18 @@ class GenmodelEntriesExtension extends GenmodelEntries {
 	def private getGeneratorOptionsFeature(GeneratorEntry it) {
 		getFeatureConfiguration(CPPFeatureConstants::FEATURE_GENERATOR_OPTIONS)
 	}
+	
+	def private getAPIFeature(GeneratorEntry it){
+		getFeatureConfiguration(CPPFeatureConstants::FEATURE_API)
+	}
 
 	def private getVisibilityParameter(GeneratorEntry it) {
 		generatorOptionsFeature?.getParameterValue(CPPFeatureConstants.PARAMETER_INNER_FUNCTION_VISIBILITY)
 	}
+	
+	def private getCheckUnimplementedParamter(GeneratorEntry it) {
+		APIFeature?.getParameterValue(CPPFeatureConstants.PARAMETER_API_CHECK_UNIMPLEMENTED_OCBS)
+	}
 
 	def getInnerClassVisibility(GeneratorEntry it) {
 		if (visibilityParameter != null) {
@@ -41,4 +49,10 @@ class GenmodelEntriesExtension extends GenmodelEntries {
 		}
 		return false
 	}
+	
+	def getCheckUnimplementedOCBs(GeneratorEntry it) {
+		if (checkUnimplementedParamter != null){
+			return checkUnimplementedParamter.booleanValue
+		}
+	}
 }

+ 38 - 0
test-plugins/org.yakindu.sct.generator.cpp.test/gtests/UnimplementedOCBTest/OCBDefaultInterfaceImpl.h

@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2017 committers of YAKINDU and others.
+ * 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:
+ *     committers of YAKINDU - initial API and implementation
+ */
+
+#ifndef OCBDEFAULTINTERFACEIMPL_H_
+#define OCBDEFAULTINTERFACEIMPL_H_
+
+#include "UnimplementedOCB.h"
+
+class OCBDefaultInterfaceImpl: public UnimplementedOCB::DefaultSCI_OCB {
+public:
+	OCBDefaultInterfaceImpl();
+	virtual ~OCBDefaultInterfaceImpl();
+
+	void defaultInterfaceOperation();
+};
+
+OCBDefaultInterfaceImpl::OCBDefaultInterfaceImpl() {
+
+}
+
+OCBDefaultInterfaceImpl::~OCBDefaultInterfaceImpl() {
+
+}
+
+void OCBDefaultInterfaceImpl::defaultInterfaceOperation(){
+
+}
+
+
+#endif /* OCBDEFAULTINTERFACEIMPL_H_ */

+ 36 - 0
test-plugins/org.yakindu.sct.generator.cpp.test/gtests/UnimplementedOCBTest/OCBInternalImpl.h

@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2017 committers of YAKINDU and others.
+ * 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:
+ *     committers of YAKINDU - initial API and implementation
+ */
+
+#ifndef SRC_GEN_OCBINTERNALIMPL_H_
+#define SRC_GEN_OCBINTERNALIMPL_H_
+
+#include "UnimplementedOCB.h"
+
+class OCBInternalImpl : public UnimplementedOCB::InternalSCI_OCB {
+	public:
+		OCBInternalImpl();
+		virtual ~OCBInternalImpl();
+		void internalInterfaceOperation();
+};
+
+OCBInternalImpl::OCBInternalImpl() {
+
+}
+
+OCBInternalImpl::~OCBInternalImpl() {
+
+}
+
+void OCBInternalImpl::internalInterfaceOperation() {
+
+}
+
+#endif /* SRC_GEN_OCBINTERNALIMPL_H_ */

+ 35 - 0
test-plugins/org.yakindu.sct.generator.cpp.test/gtests/UnimplementedOCBTest/OCBNamedInterfaceImpl.h

@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2017 committers of YAKINDU and others.
+ * 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:
+ *     committers of YAKINDU - initial API and implementation
+ */
+
+#ifndef SRC_GEN_OCBNAMEDINTERFACEIMPL_H_
+#define SRC_GEN_OCBNAMEDINTERFACEIMPL_H_
+
+#include "UnimplementedOCB.h"
+
+class OCBNamedInterfaceImpl : public UnimplementedOCB::SCI_Named_OCB {
+	public:
+		OCBNamedInterfaceImpl();
+		virtual ~OCBNamedInterfaceImpl();
+		void namedInterfaceOperation();
+};
+
+OCBNamedInterfaceImpl::OCBNamedInterfaceImpl() {
+
+}
+
+OCBNamedInterfaceImpl::~OCBNamedInterfaceImpl() {
+
+}
+
+void OCBNamedInterfaceImpl::namedInterfaceOperation(){}
+
+
+#endif /* SRC_GEN_OCBNAMEDINTERFACEIMPL_H_ */

+ 24 - 0
test-plugins/org.yakindu.sct.generator.cpp.test/gtests/UnimplementedOCBTest/UnimplementedOCB.sgen

@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2017 committers of YAKINDU and others.
+ * 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:
+ *     committers of YAKINDU - initial API and implementation
+ */
+GeneratorModel for yakindu::cpp {
+
+	statechart UnimplementedOCB {
+
+		feature Outlet {
+			targetProject = "gtests"
+			targetFolder = "UnimplementedOCBTest"
+		}
+		
+		feature API {
+			checkUnimplementedOCBs = true
+		}
+	}
+}

+ 34 - 0
test-plugins/org.yakindu.sct.generator.cpp.test/gtests/UnimplementedOCBTest/UnimplementedOCBTest.cc

@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2017 committers of YAKINDU and others.
+ * 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:
+ *     committers of YAKINDU - initial API and implementation
+ */
+#include <string>
+#include "gtest/gtest.h"
+#include "UnimplementedOCB.h"
+#include "OCBDefaultInterfaceImpl.h"
+#include "OCBInternalImpl.h"
+#include "OCBNamedInterfaceImpl.h"
+
+
+TEST(UnimplementedOCBTest, UnimplementedOCBTest) {
+	UnimplementedOCB* statechart = new UnimplementedOCB();
+	OCBDefaultInterfaceImpl* di = new OCBDefaultInterfaceImpl();
+	OCBNamedInterfaceImpl* ni = new OCBNamedInterfaceImpl();
+	OCBInternalImpl* ii = new OCBInternalImpl();
+	
+	
+	EXPECT_TRUE(statechart->init() < 0);
+	statechart->setDefaultSCI_OCB(di);
+	EXPECT_TRUE(statechart->init() < 0);
+	statechart->setSCI_Named_OCB(ni);
+	EXPECT_TRUE(statechart->init() < 0);
+	statechart->setInternalSCI_OCB(ii);
+	EXPECT_TRUE(statechart->init() == 0);
+	delete statechart;
+}

+ 1 - 1
test-plugins/org.yakindu.sct.generator.cpp.test/src/org/yakindu/sct/generator/cpp/test/AllTestsTestCustom.java

@@ -15,6 +15,6 @@ import org.junit.runners.Suite;
 import org.junit.runners.Suite.SuiteClasses;
 
 @RunWith(Suite.class)
-@SuiteClasses({ OperationsWithoutBracesTestCustom.class})
+@SuiteClasses({ OperationsWithoutBracesTestCustom.class, UnimplementedOCBTest.class})
 public class AllTestsTestCustom {
 }

+ 47 - 0
test-plugins/org.yakindu.sct.generator.cpp.test/src/org/yakindu/sct/generator/cpp/test/UnimplementedOCBTest.java

@@ -0,0 +1,47 @@
+/**
+ * Copyright (c) 2017 committers of YAKINDU and others.
+ * 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:
+ *     committers of YAKINDU - initial API and implementation
+ */
+package org.yakindu.sct.generator.cpp.test;
+
+import java.util.Collection;
+
+import org.junit.Before;
+import org.junit.runner.RunWith;
+import org.yakindu.sct.generator.c.gtest.GTest;
+import org.yakindu.sct.generator.c.gtest.GTestHelper;
+import org.yakindu.sct.generator.c.gtest.GTestRunner;
+
+@GTest(sourceFile = "gtests/UnimplementedOCBTest/UnimplementedOCBTest.cc", program = "gtests/UnimplementedOCBTest/UnimplementedOCB", model = "testmodels/SCTUnit/UnimplementedOCB.sct", statechartBundle = "org.yakindu.sct.test.models")
+@RunWith(GTestRunner.class)
+public class UnimplementedOCBTest {
+	protected final GTestHelper helper = new GTestHelper(this) {
+
+		@Override
+		protected void getTestDataFiles(Collection<String> files) {
+			super.getTestDataFiles(files);
+			files.add("gtests/UnimplementedOCBTest/OCBDefaultInterfaceImpl.h");
+			files.add("gtests/UnimplementedOCBTest/OCBInternalImpl.h");
+			files.add("gtests/UnimplementedOCBTest/OCBNamedInterfaceImpl.h");
+		}
+
+		@Override
+		protected void getSourceFiles(Collection<String> files) {
+			super.getSourceFiles(files);
+			files.add(getFileName(getTestProgram()) + ".cpp");
+		}
+
+	};
+
+	@Before
+	public void setUp() {
+		helper.generate();
+		helper.compile();
+	}
+}

+ 89 - 0
test-plugins/org.yakindu.sct.test.models/testmodels/SCTUnit/UnimplementedOCB.sct

@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.2/notation" xmlns:sgraph="http://www.yakindu.org/sct/sgraph/2.0.0">
+  <sgraph:Statechart xmi:id="_TvpisM9oEeejKJ6u2IsdcA" specification="interface:&#xA;operation defaultInterfaceOperation()&#xA;&#xA;interface named:&#xA;operation namedInterfaceOperation()&#xA;&#xA;internal:&#xA;operation internalInterfaceOperation()" name="UnimplementedOCB">
+    <regions xmi:id="_Tvqw0s9oEeejKJ6u2IsdcA" name="main region">
+      <vertices xsi:type="sgraph:Entry" xmi:id="_TvvpU89oEeejKJ6u2IsdcA">
+        <outgoingTransitions xmi:id="_TvysoM9oEeejKJ6u2IsdcA" target="_Tvw3dM9oEeejKJ6u2IsdcA"/>
+      </vertices>
+      <vertices xsi:type="sgraph:State" xmi:id="_Tvw3dM9oEeejKJ6u2IsdcA" name="StateA" incomingTransitions="_TvysoM9oEeejKJ6u2IsdcA">
+        <outgoingTransitions xmi:id="_WkgP8M9oEeejKJ6u2IsdcA" specification="always" target="_Vx9YsM9oEeejKJ6u2IsdcA"/>
+      </vertices>
+      <vertices xsi:type="sgraph:FinalState" xmi:id="_Vx9YsM9oEeejKJ6u2IsdcA" incomingTransitions="_WkgP8M9oEeejKJ6u2IsdcA"/>
+    </regions>
+  </sgraph:Statechart>
+  <notation:Diagram xmi:id="_Tvqw0M9oEeejKJ6u2IsdcA" type="org.yakindu.sct.ui.editor.editor.StatechartDiagramEditor" element="_TvpisM9oEeejKJ6u2IsdcA" measurementUnit="Pixel">
+    <children xmi:id="_TvtNEM9oEeejKJ6u2IsdcA" type="Region" element="_Tvqw0s9oEeejKJ6u2IsdcA">
+      <children xsi:type="notation:DecorationNode" xmi:id="_TvvCQM9oEeejKJ6u2IsdcA" type="RegionName">
+        <styles xsi:type="notation:ShapeStyle" xmi:id="_TvvCQc9oEeejKJ6u2IsdcA"/>
+        <layoutConstraint xsi:type="notation:Location" xmi:id="_TvvCQs9oEeejKJ6u2IsdcA"/>
+      </children>
+      <children xsi:type="notation:Shape" xmi:id="_TvvpUM9oEeejKJ6u2IsdcA" type="RegionCompartment" fontName="Verdana" lineColor="4210752">
+        <children xmi:id="_TvwQYM9oEeejKJ6u2IsdcA" type="Entry" element="_TvvpU89oEeejKJ6u2IsdcA">
+          <children xmi:id="_TvwQZM9oEeejKJ6u2IsdcA" type="BorderItemLabelContainer">
+            <children xsi:type="notation:DecorationNode" xmi:id="_Tvw3cM9oEeejKJ6u2IsdcA" type="BorderItemLabel">
+              <styles xsi:type="notation:ShapeStyle" xmi:id="_Tvw3cc9oEeejKJ6u2IsdcA"/>
+              <layoutConstraint xsi:type="notation:Location" xmi:id="_Tvw3cs9oEeejKJ6u2IsdcA"/>
+            </children>
+            <styles xsi:type="notation:ShapeStyle" xmi:id="_TvwQZc9oEeejKJ6u2IsdcA" fontName="Verdana" lineColor="4210752"/>
+            <layoutConstraint xsi:type="notation:Bounds" xmi:id="_TvwQZs9oEeejKJ6u2IsdcA"/>
+          </children>
+          <styles xsi:type="notation:ShapeStyle" xmi:id="_TvwQYc9oEeejKJ6u2IsdcA" fontName="Verdana" fillColor="0" lineColor="16777215"/>
+          <styles xsi:type="notation:NamedStyle" xmi:id="_TvwQYs9oEeejKJ6u2IsdcA" name="allowColors"/>
+          <layoutConstraint xsi:type="notation:Bounds" xmi:id="_Tvw3c89oEeejKJ6u2IsdcA" x="70" y="20"/>
+        </children>
+        <children xmi:id="_TvxegM9oEeejKJ6u2IsdcA" type="State" element="_Tvw3dM9oEeejKJ6u2IsdcA">
+          <children xsi:type="notation:DecorationNode" xmi:id="_TvxehM9oEeejKJ6u2IsdcA" type="StateName">
+            <styles xsi:type="notation:ShapeStyle" xmi:id="_Tvxehc9oEeejKJ6u2IsdcA"/>
+            <layoutConstraint xsi:type="notation:Location" xmi:id="_Tvxehs9oEeejKJ6u2IsdcA"/>
+          </children>
+          <children xsi:type="notation:Compartment" xmi:id="_TvyFkM9oEeejKJ6u2IsdcA" type="StateTextCompartment">
+            <children xsi:type="notation:Shape" xmi:id="_TvyFkc9oEeejKJ6u2IsdcA" type="StateTextCompartmentExpression" fontName="Verdana" lineColor="4210752">
+              <layoutConstraint xsi:type="notation:Bounds" xmi:id="_TvyFks9oEeejKJ6u2IsdcA"/>
+            </children>
+          </children>
+          <children xsi:type="notation:Compartment" xmi:id="_TvyFk89oEeejKJ6u2IsdcA" type="StateFigureCompartment"/>
+          <styles xsi:type="notation:ShapeStyle" xmi:id="_Tvxegc9oEeejKJ6u2IsdcA" fontName="Verdana" fillColor="15981773" lineColor="12632256"/>
+          <styles xsi:type="notation:FontStyle" xmi:id="_Tvxegs9oEeejKJ6u2IsdcA"/>
+          <styles xsi:type="notation:BooleanValueStyle" xmi:id="_TvyFlM9oEeejKJ6u2IsdcA" name="isHorizontal" booleanValue="true"/>
+          <layoutConstraint xsi:type="notation:Bounds" xmi:id="_TvyFlc9oEeejKJ6u2IsdcA" x="40" y="80"/>
+        </children>
+        <children xsi:type="notation:Shape" xmi:id="_VyEtcM9oEeejKJ6u2IsdcA" type="FinalState" element="_Vx9YsM9oEeejKJ6u2IsdcA" fontName="Verdana" lineColor="4210752">
+          <layoutConstraint xsi:type="notation:Bounds" xmi:id="_VyEtcc9oEeejKJ6u2IsdcA" x="90" y="174"/>
+        </children>
+        <layoutConstraint xsi:type="notation:Bounds" xmi:id="_TvvpUc9oEeejKJ6u2IsdcA"/>
+      </children>
+      <styles xsi:type="notation:ShapeStyle" xmi:id="_TvtNEc9oEeejKJ6u2IsdcA" fontName="Verdana" fillColor="15790320" lineColor="12632256"/>
+      <layoutConstraint xsi:type="notation:Bounds" xmi:id="_TvvpUs9oEeejKJ6u2IsdcA" x="220" y="10" width="400" height="400"/>
+    </children>
+    <children xsi:type="notation:Shape" xmi:id="_Tvz6xM9oEeejKJ6u2IsdcA" type="StatechartText" fontName="Verdana" lineColor="4210752">
+      <children xsi:type="notation:DecorationNode" xmi:id="_Tv0h0M9oEeejKJ6u2IsdcA" type="StatechartName">
+        <styles xsi:type="notation:ShapeStyle" xmi:id="_Tv0h0c9oEeejKJ6u2IsdcA"/>
+        <layoutConstraint xsi:type="notation:Location" xmi:id="_Tv0h0s9oEeejKJ6u2IsdcA"/>
+      </children>
+      <children xsi:type="notation:Shape" xmi:id="_Tv0h089oEeejKJ6u2IsdcA" type="StatechartTextExpression" fontName="Verdana" lineColor="4210752">
+        <layoutConstraint xsi:type="notation:Bounds" xmi:id="_Tv0h1M9oEeejKJ6u2IsdcA"/>
+      </children>
+      <layoutConstraint xsi:type="notation:Bounds" xmi:id="_Tv0h1c9oEeejKJ6u2IsdcA" x="10" y="10" width="200" height="400"/>
+    </children>
+    <styles xsi:type="notation:DiagramStyle" xmi:id="_Tvqw0c9oEeejKJ6u2IsdcA"/>
+    <edges xmi:id="_TvzTsM9oEeejKJ6u2IsdcA" type="Transition" element="_TvysoM9oEeejKJ6u2IsdcA" source="_TvwQYM9oEeejKJ6u2IsdcA" target="_TvxegM9oEeejKJ6u2IsdcA">
+      <children xsi:type="notation:DecorationNode" xmi:id="_Tvz6wc9oEeejKJ6u2IsdcA" type="TransitionExpression">
+        <styles xsi:type="notation:ShapeStyle" xmi:id="_Tvz6ws9oEeejKJ6u2IsdcA"/>
+        <layoutConstraint xsi:type="notation:Location" xmi:id="_Tvz6w89oEeejKJ6u2IsdcA" y="10"/>
+      </children>
+      <styles xsi:type="notation:ConnectorStyle" xmi:id="_TvzTsc9oEeejKJ6u2IsdcA" routing="Rectilinear" lineColor="4210752"/>
+      <styles xsi:type="notation:FontStyle" xmi:id="_Tvz6wM9oEeejKJ6u2IsdcA" fontName="Verdana"/>
+      <bendpoints xsi:type="notation:RelativeBendpoints" xmi:id="_TvzTss9oEeejKJ6u2IsdcA" points="[0, 0, 0, 0]$[0, 0, 0, 0]"/>
+    </edges>
+    <edges xmi:id="_WkjTQM9oEeejKJ6u2IsdcA" type="Transition" element="_WkgP8M9oEeejKJ6u2IsdcA" source="_TvxegM9oEeejKJ6u2IsdcA" target="_VyEtcM9oEeejKJ6u2IsdcA">
+      <children xsi:type="notation:DecorationNode" xmi:id="_WknksM9oEeejKJ6u2IsdcA" type="TransitionExpression">
+        <styles xsi:type="notation:ShapeStyle" xmi:id="_Wknksc9oEeejKJ6u2IsdcA"/>
+        <layoutConstraint xsi:type="notation:Location" xmi:id="_Wknkss9oEeejKJ6u2IsdcA" y="10"/>
+      </children>
+      <styles xsi:type="notation:ConnectorStyle" xmi:id="_WkjTQc9oEeejKJ6u2IsdcA" routing="Rectilinear" lineColor="4210752"/>
+      <styles xsi:type="notation:FontStyle" xmi:id="_Wkm9oM9oEeejKJ6u2IsdcA" fontName="Verdana"/>
+      <bendpoints xsi:type="notation:RelativeBendpoints" xmi:id="_WkjTQs9oEeejKJ6u2IsdcA" points="[-18, 18, -20, -53]$[9, 69, 7, -2]"/>
+      <sourceAnchor xsi:type="notation:IdentityAnchor" xmi:id="_WkqA8M9oEeejKJ6u2IsdcA" id="(1.0,0.6415094339622641)"/>
+    </edges>
+  </notation:Diagram>
+</xmi:XMI>