Bug 468073: [codegen] generator ignores exclusions (part 2)

* Added support for attribute exclusion

Change-Id: I0321e6f7f67eac17fc17ec7e8749ddab4db74a6c
Signed-off-by: Ernesto Posse <eposse@gmail.com>
diff --git a/models/samples/ComputerSystem/expected_src/CMakeLists.txt b/models/samples/ComputerSystem/expected_src/CMakeLists.txt
index e5fcb27..20cbe76 100644
--- a/models/samples/ComputerSystem/expected_src/CMakeLists.txt
+++ b/models/samples/ComputerSystem/expected_src/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Generated 2017-02-16 14:58:15
+# Generated 2017-02-22 17:53:55
 
 cmake_minimum_required(VERSION 2.8.7)
 set(TARGET TopMain)
diff --git a/models/samples/ComputerSystem/expected_src/USBPrinterDriver.cc b/models/samples/ComputerSystem/expected_src/USBPrinterDriver.cc
index 7b9e284..d9e80b9 100644
--- a/models/samples/ComputerSystem/expected_src/USBPrinterDriver.cc
+++ b/models/samples/ComputerSystem/expected_src/USBPrinterDriver.cc
@@ -14,6 +14,7 @@
 : Capsule_USBDeviceDriver( cd, st, border, internal, isStat )
 , usbExtPort( borderPorts[borderport_usbExtPort] )
 , usbInPort( borderPorts[borderport_usbInPort] )
+, busID( 0 )
 {
 }
 
@@ -31,6 +32,7 @@
 }
 
 
+
 void Capsule_USBPrinterDriver::initialize( const UMLRTMessage & msg )
 {
 }
diff --git a/models/samples/ComputerSystem/expected_src/USBPrinterDriver.hh b/models/samples/ComputerSystem/expected_src/USBPrinterDriver.hh
index 95a23e4..5594aeb 100644
--- a/models/samples/ComputerSystem/expected_src/USBPrinterDriver.hh
+++ b/models/samples/ComputerSystem/expected_src/USBPrinterDriver.hh
@@ -42,6 +42,7 @@
     virtual void unbindPort( bool isBorder, int portId, int index );
 protected:
     static const USBDeviceClasses usbDevice = Printer;
+    int busID;
 public:
     virtual void initialize( const UMLRTMessage & msg );
     virtual void inject( const UMLRTMessage & msg );
diff --git a/models/samples/ComputerSystem/expected_src/USBStorageDriver.cc b/models/samples/ComputerSystem/expected_src/USBStorageDriver.cc
index 8578664..d5fb508 100644
--- a/models/samples/ComputerSystem/expected_src/USBStorageDriver.cc
+++ b/models/samples/ComputerSystem/expected_src/USBStorageDriver.cc
@@ -14,6 +14,7 @@
 : Capsule_USBDeviceDriver( cd, st, border, internal, isStat )
 , usbExtPort( borderPorts[borderport_usbExtPort] )
 , usbInPort( borderPorts[borderport_usbInPort] )
+, busID( 0 )
 {
 }
 
@@ -31,6 +32,7 @@
 }
 
 
+
 void Capsule_USBStorageDriver::initialize( const UMLRTMessage & msg )
 {
 }
diff --git a/models/samples/ComputerSystem/expected_src/USBStorageDriver.hh b/models/samples/ComputerSystem/expected_src/USBStorageDriver.hh
index eaffc11..cc27aa7 100644
--- a/models/samples/ComputerSystem/expected_src/USBStorageDriver.hh
+++ b/models/samples/ComputerSystem/expected_src/USBStorageDriver.hh
@@ -42,6 +42,7 @@
     virtual void unbindPort( bool isBorder, int portId, int index );
 protected:
     static const USBDeviceClasses deviceClass = MassStorage;
+    int busID;
 public:
     virtual void initialize( const UMLRTMessage & msg );
     virtual void inject( const UMLRTMessage & msg );
diff --git a/models/tests/executable/PingPong/expected_src/CMakeLists.txt b/models/tests/executable/PingPong/expected_src/CMakeLists.txt
index 9d67a2b..ea4f546 100644
--- a/models/tests/executable/PingPong/expected_src/CMakeLists.txt
+++ b/models/tests/executable/PingPong/expected_src/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Generated 2017-02-16 14:58:01
+# Generated 2017-02-22 17:57:02
 
 cmake_minimum_required(VERSION 2.8.7)
 set(TARGET TopMain)
diff --git a/plugins/umlrt/codegen/org.eclipse.papyrusrt.codegen.cpp/src/org/eclipse/papyrusrt/codegen/cpp/internal/BasicClassGenerator.java b/plugins/umlrt/codegen/org.eclipse.papyrusrt.codegen.cpp/src/org/eclipse/papyrusrt/codegen/cpp/internal/BasicClassGenerator.java
index 81731a9..02c772d 100644
--- a/plugins/umlrt/codegen/org.eclipse.papyrusrt.codegen.cpp/src/org/eclipse/papyrusrt/codegen/cpp/internal/BasicClassGenerator.java
+++ b/plugins/umlrt/codegen/org.eclipse.papyrusrt.codegen.cpp/src/org/eclipse/papyrusrt/codegen/cpp/internal/BasicClassGenerator.java
@@ -520,7 +520,7 @@
 	 * @return {@code true} if successful.
 	 */
 	protected boolean generateAttributes(CppClass cls) {
-		for (Attribute attr : element.getAttributes()) {
+		for (Attribute attr : XTUMLRTUtil.getAllAttributes(element)) {
 			generate(cls, attr);
 		}
 		return true;
diff --git a/plugins/xtumlrt/common/org.eclipse.papyrusrt.xtumlrt.util/src/org/eclipse/papyrusrt/xtumlrt/util/XTUMLRTSMVirtualInheritanceExtensions.xtend b/plugins/xtumlrt/common/org.eclipse.papyrusrt.xtumlrt.util/src/org/eclipse/papyrusrt/xtumlrt/util/XTUMLRTSMVirtualInheritanceExtensions.xtend
index b5f76b2..1a93f05 100644
--- a/plugins/xtumlrt/common/org.eclipse.papyrusrt.xtumlrt.util/src/org/eclipse/papyrusrt/xtumlrt/util/XTUMLRTSMVirtualInheritanceExtensions.xtend
+++ b/plugins/xtumlrt/common/org.eclipse.papyrusrt.xtumlrt.util/src/org/eclipse/papyrusrt/xtumlrt/util/XTUMLRTSMVirtualInheritanceExtensions.xtend
@@ -659,6 +659,21 @@
      * </code>
      * </pre>
      * 
+     * <p>Another way of understanding this is this: suppose that transition t
+     * is owned by state r which extends state r', and suppose that the real
+     * source of t is some vertex s' owned by r', but s' is redefined by a vertex
+     * s owned by r:
+     * 
+     * <pre>
+     * <code>
+     * parent state      r':    s' -+
+     *                   ^      ^   |
+     *                   |      |   |
+     * extended state    r:     s   +-t-> d
+     * </code>
+     * </pre>
+     * 
+     * <p> In such a case, this method reports s as the source of t in r.
      */
     static def Vertex getTransitionSourceInState( Transition t, CompositeState r )
     {
@@ -714,13 +729,13 @@
      * state which may be an extended state of the state containing the "real"
      * target of the transition. This is, if transition t is inside (composite)
      * state r because it was inherited, this is, t is defined in and actually
-     * belongs to a (composite) state r' redefined by r, then the real target s'
-     * of t is in r', but there may be a vertex s in r which redefines s', and
+     * belongs to a (composite) state r' redefined by r, then the real target d'
+     * of t is in r', but there may be a vertex d in r which redefines d', and
      * therefore it should be considered the target of t in r.
      *
      * <p> The following diagram describes the situation: t in r is inherited
-     * from r', and its real target is s' and target is d'. This method returns
-     * s, the target of t in r.
+     * from r', and its real source is s' and target is d'. This method returns
+     * d, the target of t in r.
      * <p>
      * <pre>
      * <code>
@@ -731,6 +746,22 @@
      * </code>
      * </pre>
      * 
+     * <p>Another way of understanding this is this: suppose that transition t
+     * is owned by state r which extends state r', and suppose that the real
+     * target of t is some vertex d' owned by r', but d' is redefined by a vertex
+     * d owned by r:
+     * 
+     * <pre>
+     * <code>
+     * parent state      r':           +-> d'
+     *                   ^             |   ^
+     *                   |             |   |
+     * extended state    r:     s  --t-+   d
+     * </code>
+     * </pre>
+     * 
+     * <p> In such a case, this method reports d as the target of t in r.
+     * 
      */
     static def Vertex getTransitionTargetInState( Transition t, CompositeState r )
     {
diff --git a/plugins/xtumlrt/common/org.eclipse.papyrusrt.xtumlrt.util/src/org/eclipse/papyrusrt/xtumlrt/util/XTUMLRTUtil.xtend b/plugins/xtumlrt/common/org.eclipse.papyrusrt.xtumlrt.util/src/org/eclipse/papyrusrt/xtumlrt/util/XTUMLRTUtil.xtend
index 76bbc03..7a4410f 100644
--- a/plugins/xtumlrt/common/org.eclipse.papyrusrt.xtumlrt.util/src/org/eclipse/papyrusrt/xtumlrt/util/XTUMLRTUtil.xtend
+++ b/plugins/xtumlrt/common/org.eclipse.papyrusrt.xtumlrt.util/src/org/eclipse/papyrusrt/xtumlrt/util/XTUMLRTUtil.xtend
@@ -11,6 +11,7 @@
 import java.util.LinkedHashSet
 import java.util.List
 import org.eclipse.emf.ecore.EObject
+import org.eclipse.papyrusrt.xtumlrt.common.Attribute
 import org.eclipse.papyrusrt.xtumlrt.common.BaseContainer
 import org.eclipse.papyrusrt.xtumlrt.common.Behaviour
 import org.eclipse.papyrusrt.xtumlrt.common.Capsule
@@ -43,7 +44,6 @@
 import static extension org.eclipse.papyrusrt.xtumlrt.util.GeneralUtil.*
 import static extension org.eclipse.papyrusrt.xtumlrt.util.XTUMLRTAnnotations.*
 
-
 class XTUMLRTUtil
 {
     static class NameComparator implements Comparator<NamedElement>
@@ -97,6 +97,26 @@
     }
 
     /**
+     * Returns the set of all attributed in the structured type element, including those which have been inherited
+     * and those which are redefinitions of inherited attributes.
+     */
+    static def Iterable<Attribute> getAllAttributes( StructuredType struct )
+    {
+        val allAttributes = new LinkedHashSet<Attribute>()
+        if (struct !== null)
+        {
+            allAttributes.addAll( struct.classAttributes )
+            val parentElement = struct.redefines
+            if (parentElement !== null && parentElement instanceof StructuredType)
+            {
+                val parent = parentElement as StructuredType
+                allAttributes.addAll( parent.allAttributes.filter [ !redefines( struct, it ) ] )
+            }
+        }
+        allAttributes
+    }
+
+    /**
      * Returns the set of all capsules in a model or package.
      */
     static def Iterable<Capsule> getAllCapsules( BaseContainer model )
@@ -153,7 +173,7 @@
             if (parentElement !== null && parentElement instanceof Capsule)
             {
                 val parent = parentElement as Capsule
-                allParts.addAll( parent.allCapsuleParts.filter [ !redefines( capsule, it) ] )
+                allParts.addAll( parent.allCapsuleParts.filter [ !redefines( capsule, it ) ] )
             }
         }
         allParts
@@ -173,7 +193,7 @@
             if (parentElement !== null && parentElement instanceof Capsule)
             {
                 val parent = parentElement as Capsule
-                allConnectors.addAll( parent.allConnectors.filter [ !redefines( capsule, it) ]  )
+                allConnectors.addAll( parent.allConnectors.filter [ !redefines( capsule, it ) ]  )
             }
         }
         allConnectors
@@ -209,7 +229,7 @@
             if (parentElement !== null && parentElement instanceof Capsule)
             {
                 val parent = parentElement as Capsule
-                allPorts.addAll( parent.allRTPorts.filter [ !redefines( capsule, it) ] )
+                allPorts.addAll( parent.allRTPorts.filter [ !redefines( capsule, it ) ] )
             }
         }
         allPorts
@@ -229,7 +249,7 @@
             if (parentElement !== null && parentElement instanceof Capsule)
             {
                 val parent = parentElement as Protocol
-                allSignals.addAll( parent.allSignals.filter [ !redefines( protocol, it) ] )
+                allSignals.addAll( parent.allSignals.filter [ !redefines( protocol, it ) ] )
             }
         }
         allSignals
@@ -238,6 +258,18 @@
     /**
      * Return the given capsule's parts that have a type.
      */
+    static def Iterable<Attribute> getClassAttributes( StructuredType struct ) {
+        // Ports are put into a sorted list to make sure that the order is
+        // stable between
+        // different parts of the generator (as well as between invocations).
+        val attrs = new LinkedHashSet<Attribute>()
+        attrs.addAll( struct.attributes.filter [ type !== null && !isExcluded ] )
+        attrs
+    }
+
+    /**
+     * Return the given capsule's parts that have a type.
+     */
     static def Iterable<CapsulePart> getCapsuleParts( Capsule capsule ) {
         // Ports are put into a sorted list to make sure that the order is
         // stable between
@@ -248,6 +280,19 @@
     }
 
     /**
+     * A filter that produces only Ports that are properly stereotyped as RTPort
+     * and have a UML-RT protocol.
+     */
+    static def Iterable<Port> getRTPorts( Capsule capsule ) {
+        // Ports are put into a sorted list to make sure that the order is
+        // stable between
+        // different parts of the generator (as well as between invocations).
+        val ports = new LinkedHashSet<Port>()
+        ports.addAll( capsule.ports.filter [ type !== null && !isExcluded ] )
+        ports
+    }
+
+    /**
      * Return the given capsule's connectors.
      */
     static def Iterable<Connector> getCapsuleConnectors( Capsule capsule ) {
@@ -360,6 +405,14 @@
     }
 
     /**
+     * Returns an iterable over the attributes of the given class which redefine some inherited attribute.
+     */
+    static def Iterable<Attribute> getAttributeRedefinitions( StructuredType struct )
+    {
+        struct.attributes.filter[ it.redefines !== null && it.redefines instanceof Attribute ]
+    }
+
+    /**
      * Returns an iterable over the ports of the given class which redefine some inherited port.
      */
     static def Iterable<CapsulePart> getPartRedefinitions( Capsule capsule )
@@ -392,6 +445,14 @@
     }
 
     /**
+     * Returns an iterable over the attributed redefined by the given class.
+     */
+    static def Iterable<Attribute> getRedefinedAttributes( StructuredType struct )
+    {
+        struct.attributeRedefinitions.map [ it.redefines as Attribute ]
+    }
+
+    /**
      * Returns an iterable over the ports redefined by the given class.
      */
     static def Iterable<CapsulePart> getRedefinedParts( Capsule capsule )
@@ -423,19 +484,6 @@
         protocol.signalRedefinitions.map [ it.redefines as Signal ]
     }
 
-    /**
-     * A filter that produces only Ports that are properly stereotyped as RTPort
-     * and have a UML-RT protocol.
-     */
-    static def Iterable<Port> getRTPorts( Capsule capsule ) {
-        // Ports are put into a sorted list to make sure that the order is
-        // stable between
-        // different parts of the generator (as well as between invocations).
-        val ports = new LinkedHashSet<Port>()
-        ports.addAll( capsule.ports.filter [ type !== null && !isExcluded ] )
-        ports
-    }
-
     static def Iterable<StructuredType> getSupertypes( StructuredType type )
     {
         type.generalizations?.map [ it.getSuper ]
@@ -589,6 +637,14 @@
     }
 
     /**
+     * Returns true iff the given attribute is inherited and redefined by the given class.
+     */
+    private static dispatch def redefines( StructuredType struct, Attribute attr )
+    {
+        struct.redefinedAttributes.exists[ it == attr ]
+    }
+
+    /**
      * Returns true iff the given port is inherited and redefined by the given class.
      */
     private static dispatch def redefines( Capsule capsule, Port port )