Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Difference between revisions of "Papyrus Software Designer/Model Code Synchronization"

(Mapping definition)
m (UML and Java)
 
Line 8: Line 8:
 
* Addition
 
* Addition
 
* Deletion
 
* Deletion
* Rename
+
* Change (e.g. change signature of method, rename)
 
* Move
 
* Move
 
** = Addition + Deletion?
 
** = Addition + Deletion?

Latest revision as of 10:11, 4 January 2017

Model Code Synchronization

This page gathers ideas on the model-code synchronization component of Papyrus Software Designer, developed by IncQuery Labs and CEA. It will later become a finalized wiki page for users and developers. The synchronization component is based on change-based incremental transformation (code generation and reverse).

UML and Java

Events to handle (both UML side and Java side):

  • Addition
  • Deletion
  • Change (e.g. change signature of method, rename)
  • Move
    • = Addition + Deletion?
  • Refactor [UML-side] such as “impact of changing any element E on other elements that reference ”, e.g.
    • Impact of a renaming performed on a class which types properties
    • Impact of moving some class, typing properties, to another package
  • Refactor [Java-side]
    • By using the JDT refactor command, referenced JDT elements will be updated, firing change events so no problem.
    • Without using JDT refactor command, we will have broken code to be ignored (e.g. attribute with nonexistent type). I don’t think JDT will fire a change event on the broken code.

It doesn’t matter if such events are not explicit, as long as we can express them (e.g. combination of other events) and update elements without ambiguity.

Mapping definition

Mapping root

The root of the mapping is selected by the user:

  • Java: packages are handled with source folders considered as roots that are not mapped themselves
  • UML: by default, the root object of the UML model (a Model EObject, e.g. RootElement) is already a Package that can be mapped to a root Java package, or an added prefix (e.g. com.mycompany) can be used to map the contents of the model to a sub package (e.g. com.mycompany.RootElement)

Note that the root of the mapping is best described as a Java package and a corresponding UML Package (potentially Model) element, where the namespace (container package qualified name) of the Java package is the prefix for the code generated from the UML Package.

  • Java root object <-sync-> UML root object

Packages

  • A Java package is mapped to a Package object in the UML model.
    • Java package (JP) <-> UML Package (UP)
  • The name attribute of the Package is the same as the name of the Java package.
    • JP.name <-> UP.name
  • The container of the Package object is the same as the Package object synchronised with the Java package that contains the mapped Java package
    • JP.package <-> UP.owner

Compilation units

  • Compilation units (CU) are classes, interfaces and enums, each defined in source files (*.java).
    • Java class <-> UML Class
    • Java interface <-> UML Interface
    • Java enum <-> UML Enumeration
  • The name attribute of the UML NamedElement is the same as the name of the Java Package.
    • CU.name <-> NamedElement.name
  • The container of the CU is the same as the Package object synchronised with the Java package that contains the mapped CU
    • CU.package <-> Element.owner
  • The visibility of the compilation unit (public, private, package, protected) is the same as the VisibilityKind set for the UML element.
    • Only public and package-private visibility is allowed in units contained by packages
    • Inner types can use all visibility kinds
    • CU.visibility <-> NamedElement.visibility
  • Strictfp modifier is available on classes, interfaces and non-abstract methods to restrict floating point calculations for portability.
    • CU.strictfp <-> PapyrusJava.Strictfp stereotype applied on element
  • Extending classes and interfaces in Java is represented by UML Generalization elements
    • CU.extends <-> Classifier.generalizations->Generalization.general
    • Note that Generalizations are DirectedRelationships
  • Implementing interfaces for classifiers in Java is represented by UML InterfaceRealization elements
    • CU.implements <-> BehavioredClassifier.interfaceRealizations->InterfaceRealization.contract
    • Note that InterfaceRealizations are DirectedRelationships
  • Template parameters (generics) of CU in Java are represented by TemplateParameters of a UML TemplateSignature of the classifier
    • CU.generics <-> Classifier.ownedTemplateSignature -> TemplateSignature.ownedParameters
    • TO BE DEFINED: template parameter support is not implemented in the existing codegen and reverse, so the mapping cannot be reverse engineered from that!
    • The Java Profile contains Template, TemplateParameter and TemplateBinding stereotypes that probably provide the additional details needed to represent the aspects of generics not covered by base UML.
  • Imports are required in Java for all types used in a given compilation unit (and its inner types) that are not in the same package as the CU
    • The list of imports during code generation is prepared by:
      1. processing all required classifiers based on attributes, operations, dependencies etc.
      2. Imports property of PapyrusJava.ExternalLibrary stereotype applied on the element or any of its parents
      3. Name property of PapyrusJava.External stereotype applied on the element or any of its parents
      4. ManualImports property of PapyrusJava.Import stereotype applied to the UML element

Class

  • Java classes (JC) have fields and methods that are mapped to properties and operations in UML Classes
    • See details in later sections
  • Class modifiers are abstract and final
    • JC.abstract <-> Classifier.abstract
    • JC.final <-> RedefinableElement.leaf

Interface

  • Interfaces only have public methods without body (before Java 8)
  • From Java 8, interface methods can define default implementations and static methods as well
  • See details in later sections

Enumeration

  • Java enum literals are mapped to UML EnumerationLiterals
    • Java enum literal <-> UML EnumerationLiteral
  • Initial value of literals can be represented by the specification of EnumerationLiterals in UML
    • In case of enums with constructors and fields, the literals have initial values using assignment
    • literal.inital <-> EnumerationLiteral.specification
  • Java enums may have methods and fields similarly to a class
    • See details in later sections

Fields

  • Java fields are mapped to UML Properties
    • Java field <-> UML Property
  • The container of the Property is the UML Element that is mapped to the container of the Java field.
    • Field.container <-> Property.owner (Owner.ownedAttribute)
  • The type of the the UML Property is mapped to the type of the Java field
    • Field.type <-> TypedElement.type
  • Initial value is provided by assignment in Java, while UML represents this as default value
    • Field.initial <-> Property.defaultValue
  • Visibility of members are represented by the VisibilityKind of the NamedElement
    • CU.visibility <-> NamedElement.visibility
    • In case of "package" visibility in UML, no visibility is added to Java
  • Static modifier is represented using the static attribute of UML Features and the Java Profile
    • Member.static <-> Feature.static and PapyrusJava.StaticClassifier stereotype applied on owner Classifier if it is inner type
  • Final modifier is added for leaf UML elements
    • Member.final <-> RedefinableElement.leaf
  • Transient modifier is represented using Java Profile
    • Member.transient <-> PapyrusJava.Transient stereotype applied on Element
  • Volatile modifier is represented using Java Profile
    • Member.volatile <-> PapyrusJava.Volatile stereotype applied on Element, unless RedefinableElement.leaf is true

Note that while fields could be represented by full Associations owned by the container, it is not done that way.

  • TO BE DEFINED: there is a "Create Association From Property" command, that transforms simple properties to association, it is not clear how this should be handled in synchronization

Interface fields

    • Always public, static, final (but not necessary to explicitly add it to code).

Methods

  • Constructor is represented by Standard Profile
    • Method.isConstructor <-> standard.Create stereotype applied on Operation
  • Visibility of members are represented by the VisibilityKind of the NamedElement
    • Method.visibility <-> NamedElement.visibility
    • In case of "package" visibility in UML, no visibility is added to Java
    • Constructors of Enumerations are always private
  • Static modifier is represented using the static attribute of UML Features and the Java Profile
    • Member.static <-> Feature.static and PapyrusJava.StaticClassifier stereotype applied on owner Classifier if it is inner type
  • Override annotation is used in Java on methods that implement an interface method or extend a superclass method.
    • TO BE DEFINED Existing code generator does not add @Override annotations to methods (see Annotations section)
  • Final modifier is added for leaf UML elements, unless the method is abstract or interface static method
    • Member.final <-> RedefinableElement.leaf
  • Synchronized modifier is represented using the Java Profile
    • Method.synchronized <-> PapyrusJava.Synchronized stereotype applied on Operation
  • Native modifier is represented using the Java Profile
    • Method.native <-> PapyrusJava.Native stereotype applied on Operation
  • Strictfp modifier is represented using the Java Profile
    • Method.strictfp <-> PapyrusJava.Strictfp stereotype applied on Operation
  • Generics on operation
    • TO BE DEFINED: template parameter support is not implemented in the existing codegen and reverse, so the mapping cannot be reverse engineered from that!

Return type and parameters

  • Java allows a single return type for methods (can be void), while UML Operations have a type and a list of Parameters that have ParameterDirectionKind which may be return (in addition to in/out/inout).
    • Constructors have no return type (see above for identifying constructors in UML)
    • Method.return <-> Operation.type
      • Multiplicity is decided based on first Parameter with return direction kind that has the same type as the Operation
      • void <-> no type and not constructor
  • Java method parameters are represented by UML Parameters of Operation
    • Method.parameters <-> Operation.ownedParameters (except those that have return direction kind)
    • Parameter.final <-> PapyrusJava.Final stereotype applied on Parameter
    • Parameter.array ( param[] ) <-> MultiplicityElement.upper is -1 or higher than 1
    • Parameter.varargs ( param... ) <-> PapyrusJava.Variadic stereotype applied on Parameter
    • Generics on operation parameters
      • TO BE DEFINED: template parameter support is not implemented in the existing codegen and reverse, so the mapping cannot be reverse engineered from that!
  • Throws declarations in Java are represented by raised exceptions of the UML Operation
    • Method.throws <-> BehavioralFeature.raisedExceptions
  • Java method body is represented by Operation OpaqueBahavior body with Java language
    • Method.body <-> Operation.behaviors[language = "Java"].body
    • Abstract operations do not have body

Interface methods

    • Implicitly public
    • Implicitly abstract, unless default or static
    • Default modifier is represented using the Java Profile
      • Java.default <-> PapyrusJava.Default stereotype applied on Operation
    • No body, unless default or static


Annotations

  • TO BE DEFINED: handling Annotations are not yet defined in mapping and not supported by code generator or reverse engineering transformation.

Comments

  • Comments in Java files that are added to elements and not inside blocks are stored in UML Comment elements

Inner types

  • Inner types are owned by a Compilation Unit instead of a Package
  • Static modifier can be used on inner types in Java
    • Type.static <-> PapyrusJava.StaticClassifier stereotype applied on Classifier

UML and C

To prepare for a future prototype and feature development for synchronizing UML models with C source code, the change notification API of Eclipse CDT (https://eclipse.org/cdt/) is evaluated. Based on this evaluation, it seems possible to develop a synchronization that uses the same architecture as the UML-Java synchronization and even reuse some code if the mapping definitions are not too different.

  • Element change istener:
    • Only called on elements that had their content changed
    • POST_CHANGE events on save
    • POST_RECONCILE events during editing, without save
  • Other translation units are not reconciled after changes automatically
    • If they are open in an editor then reconciliation occurs when the editor is in focus (already in focus or focus changes to it)
  • Build errors are different from code analysis errors
    • C/C++ problem (compiler) vs. Semantic error (analysis)
    • Analysis executed on editor in focus

The following sections provide some examples of change notifications provided by the CDT API with Xtend codes at the beginning to show how they were recorded and how the API can be used for registering these listeners.

CDT element changed notifications:

CoreModel.^default.addElementChangedListener[ event | 
	event.processEvent
]
 
def processEvent(ElementChangedEvent event) {
	val typeString = switch(event.type) {
		case 1 : "POST_CHANGE"
		case 4 : "POST_RECONCILE"
		case 5 : "POST_SHIFT"
	}
 
	val eventString = '''
		>> Element changed event received: 
		```
		«typeString»
		«event»
		```
	'''
 
	print(eventString)
}

Open C project tree to first level after startup

POST_CHANGE
org.eclipse.cdt.core.model.ElementChangedEvent[source= CMODEL [*]: {CHILDREN | FINE GRAINED}
	test CPROJECT [*]: {CONTENT}]

Create folder *abc* inside source folder

POST_CHANGE
org.eclipse.cdt.core.model.ElementChangedEvent[source= CMODEL [*]: {CHILDREN | FINE GRAINED}
	test CPROJECT [*]: {CHILDREN | CONTENT | FINE GRAINED}
		src SOURCE_ROOT [*]: {CHILDREN | CONTENT | FINE GRAINED}
			abc CCONTAINER [+]: {}
			ResourceDelta(/test/src/abc)[+]
		ResourceDelta(/test/src)[*]]

File level modifications

  • Open existing file *test.cpp*
POST_CHANGE
org.eclipse.cdt.core.model.ElementChangedEvent[source= CMODEL [*]: {CHILDREN | FINE GRAINED}
	test CPROJECT [*]: {CHILDREN | FINE GRAINED}
		src SOURCE_ROOT [*]: {CHILDREN | FINE GRAINED}
			test.cpp WORKING_UNIT [+]: {}]

When AST is ready:

POST_RECONCILE
org.eclipse.cdt.core.model.ElementChangedEvent[source=test.cpp WORKING_UNIT [+]: {}]
  • Close unmodified file *test.cpp*
POST_CHANGE
org.eclipse.cdt.core.model.ElementChangedEvent[source= CMODEL [*]: {CHILDREN | FINE GRAINED}
	test CPROJECT [*]: {CHILDREN | FINE GRAINED}
		src SOURCE_ROOT [*]: {CHILDREN | FINE GRAINED}
			test.cpp WORKING_UNIT [-]: {}]
  • Copy-paste file *test.cpp* with name *test2.cpp*
POST_CHANGE
org.eclipse.cdt.core.model.ElementChangedEvent[source= CMODEL [*]: {CHILDREN | FINE GRAINED}
	test CPROJECT [*]: {CHILDREN | CONTENT | FINE GRAINED}
		src SOURCE_ROOT [*]: {CHILDREN | FINE GRAINED}
			test2.cpp TRANSLATION_UNIT [+]: {}
		ResourceDelta(/test/src)[*]]
  • Save modified file *test2.cpp*
POST_CHANGE
org.eclipse.cdt.core.model.ElementChangedEvent[source= CMODEL [*]: {CHILDREN | FINE GRAINED}
	test CPROJECT [*]: {CHILDREN | CONTENT | FINE GRAINED}
		src SOURCE_ROOT [*]: {CHILDREN | FINE GRAINED}
			test2.cpp TRANSLATION_UNIT [*]: {CONTENT}
		ResourceDelta(/test/src)[*]]
POST_RECONCILE
org.eclipse.cdt.core.model.ElementChangedEvent[source=test2.cpp WORKING_UNIT [?]: {FINE GRAINED}]
  • Delete closed file *test2.cpp*
POST_CHANGE
org.eclipse.cdt.core.model.ElementChangedEvent[source= CMODEL [*]: {CHILDREN | FINE GRAINED}
	test CPROJECT [*]: {CHILDREN | CONTENT | FINE GRAINED}
		src SOURCE_ROOT [*]: {CHILDREN | FINE GRAINED}
			test2.cpp TRANSLATION_UNIT [-]: {}
		ResourceDelta(/test/src)[*]]
  • Restore deleted file *test2.cpp*
POST_CHANGE
org.eclipse.cdt.core.model.ElementChangedEvent[source= CMODEL [*]: {CHILDREN | FINE GRAINED}
	test CPROJECT [*]: {CHILDREN | CONTENT | FINE GRAINED}
		src SOURCE_ROOT [*]: {CHILDREN | FINE GRAINED}
			test2.cpp TRANSLATION_UNIT [+]: {}
		ResourceDelta(/test/src)[*]]
  • Create class *Test2* with namespace *a::b* in folder *abc*

Both header and source file is created, content added and working units closed in single transaction:

POST_CHANGE
org.eclipse.cdt.core.model.ElementChangedEvent[source= CMODEL [*]: {CHILDREN | FINE GRAINED}
	test CPROJECT [*]: {CHILDREN | FINE GRAINED}
		src SOURCE_ROOT [*]: {CHILDREN | FINE GRAINED}
			abc CCONTAINER [*]: {CHILDREN | FINE GRAINED}
				Test2.h TRANSLATION_UNIT [*]: {CHILDREN | FINE GRAINED}
					ABC_TEST2_H_ C_MACRO [+]: {}
					a C_NAMESPACE [+]: {}
				Test2.cpp TRANSLATION_UNIT [*]: {CHILDREN | FINE GRAINED}
					Test2.h C_INCLUDE [+]: {}
					a C_NAMESPACE [+]: {}
				Test2.h WORKING_UNIT [-]: {}
				Test2.cpp WORKING_UNIT [-]: {}]

Translation units added (although already modified above, maybe from different thread?):

POST_CHANGE
org.eclipse.cdt.core.model.ElementChangedEvent[source= CMODEL [*]: {CHILDREN | FINE GRAINED}
	test CPROJECT [*]: {CHILDREN | CONTENT | FINE GRAINED}
		src SOURCE_ROOT [*]: {CHILDREN | CONTENT | FINE GRAINED}
			abc CCONTAINER [*]: {CHILDREN | FINE GRAINED}
				Test2.cpp TRANSLATION_UNIT [+]: {}
				Test2.h TRANSLATION_UNIT [+]: {}
			ResourceDelta(/test/src/abc)[*]
		ResourceDelta(/test/src)[*]]

Folder content changed?

POST_CHANGE
org.eclipse.cdt.core.model.ElementChangedEvent[source= CMODEL [*]: {CHILDREN | FINE GRAINED}
	test CPROJECT [*]: {CHILDREN | CONTENT | FINE GRAINED}
		src SOURCE_ROOT [*]: {CONTENT}
			ResourceDelta(/test/src/abc)[*]
		ResourceDelta(/test/src)[*]]

Test2.cpp and Test2.h files are opened in editor

POST_CHANGE
org.eclipse.cdt.core.model.ElementChangedEvent[source= CMODEL [*]: {CHILDREN | FINE GRAINED}
	test CPROJECT [*]: {CHILDREN | FINE GRAINED}
		src SOURCE_ROOT [*]: {CHILDREN | FINE GRAINED}
			abc CCONTAINER [*]: {CHILDREN | FINE GRAINED}
				Test2.cpp WORKING_UNIT [+]: {}]
POST_CHANGE
org.eclipse.cdt.core.model.ElementChangedEvent[source= CMODEL [*]: {CHILDREN | FINE GRAINED}
	test CPROJECT [*]: {CHILDREN | FINE GRAINED}
		src SOURCE_ROOT [*]: {CHILDREN | FINE GRAINED}
			abc CCONTAINER [*]: {CHILDREN | FINE GRAINED}
				Test2.h WORKING_UNIT [+]: {}]

After AST is built:

POST_RECONCILE
org.eclipse.cdt.core.model.ElementChangedEvent[source=Test2.cpp WORKING_UNIT [+]: {}]
POST_RECONCILE
org.eclipse.cdt.core.model.ElementChangedEvent[source=Test2.h WORKING_UNIT [+]: {}]
  • Open editor *Test2.cpp* gets focus
POST_RECONCILE
org.eclipse.cdt.core.model.ElementChangedEvent[source=Test2.cpp WORKING_UNIT [?]: {FINE GRAINED}]
  • Rename file *test2.cpp* to *test3.cpp*
POST_CHANGE
org.eclipse.cdt.core.model.ElementChangedEvent[source= CMODEL [*]: {CHILDREN | FINE GRAINED}
	test CPROJECT [*]: {CHILDREN | CONTENT | FINE GRAINED}
		src SOURCE_ROOT [*]: {CHILDREN | FINE GRAINED}
			test2.cpp TRANSLATION_UNIT [-]: {}
			test3.cpp TRANSLATION_UNIT [+]: {}
		ResourceDelta(/test/src)[*]]
  • Move file between directories
POST_CHANGE
org.eclipse.cdt.core.model.ElementChangedEvent[source= CMODEL [*]: {CHILDREN | FINE GRAINED}
	test CPROJECT [*]: {CHILDREN | CONTENT | FINE GRAINED}
		src SOURCE_ROOT [*]: {CHILDREN | CONTENT | FINE GRAINED}
			abc CCONTAINER [*]: {CHILDREN | FINE GRAINED}
				test3.cpp TRANSLATION_UNIT [+]: {}
			test3.cpp TRANSLATION_UNIT [-]: {}
			ResourceDelta(/test/src/abc)[*]
		ResourceDelta(/test/src)[*]]

File content modifications

  • Move function to namespace
POST_RECONCILE
org.eclipse.cdt.core.model.ElementChangedEvent[source=test.cpp WORKING_UNIT [*]: {CHILDREN | FINE GRAINED}
	x C_NAMESPACE [*]: {CHILDREN}
		f C_FUNCTION [+]: {}
	f C_FUNCTION [-]: {}]
  • Add argument to function
POST_RECONCILE
org.eclipse.cdt.core.model.ElementChangedEvent[source=test.cpp WORKING_UNIT [*]: {CHILDREN | FINE GRAINED}
	x C_NAMESPACE [*]: {CHILDREN}
		f C_FUNCTION [+]: {}
		f C_FUNCTION [-]: {}]
    • Same change for:
      • Change argument type in function
      • Delete argument of function
  • Change type of variable
POST_RECONCILE
org.eclipse.cdt.core.model.ElementChangedEvent[source=test.cpp WORKING_UNIT [*]: {CHILDREN | FINE GRAINED}
	x C_VARIABLE [*]: {CONTENT}]
  • Add field to class
POST_RECONCILE
org.eclipse.cdt.core.model.ElementChangedEvent[source=Test2.h WORKING_UNIT [*]: {CHILDREN | FINE GRAINED}
	a C_NAMESPACE [*]: {CHILDREN}
		b C_NAMESPACE [*]: {CHILDREN}
			Test2 C_CLASS [*]: {CHILDREN}
				x C_FIELD [+]: {}]
  • Change type or visibility of field
POST_RECONCILE
org.eclipse.cdt.core.model.ElementChangedEvent[source=Test2.h WORKING_UNIT [*]: {CHILDREN | FINE GRAINED}
	a C_NAMESPACE [*]: {CHILDREN}
		b C_NAMESPACE [*]: {CHILDREN}
			Test2 C_CLASS [*]: {CHILDREN}
				x C_FIELD [*]: {CONTENT}]
  • Change initial value of field
POST_RECONCILE
org.eclipse.cdt.core.model.ElementChangedEvent[source=Test2.h WORKING_UNIT [?]: {FINE GRAINED}]

CDT Indexer notifications

Indexer state

Indexer state listener is called when indexer is set to busy or idle:

CCorePlugin.indexManager.addIndexerStateListener[ event |
	event.processIndexerStateEvent
]
 
def processIndexerStateEvent(IIndexerStateEvent event) {
	println('''
		>> Index state event:
		```
		Indexer is now «IF event.indexerIsIdle»IDLE«ELSE»BUSY«ENDIF»
		```
	''')
}

This information can be used for scheduling, e.g. fire activations once the indexer returns to idle state. Ensures that reading from index returns stable results.

Index change

Index change listener is called when the index changes:

CCorePlugin.indexManager.addIndexChangeListener[ event |
	event.processIndexChangeEvent
]
 
def processIndexChangeEvent(IIndexChangeEvent event) {
	println('''
		>> Index change event:
		```
		Affected project: «event.affectedProject»
		Files cleared «event.filesCleared»
		Files written «event.filesWritten»
		«IF event.cleared»Index cleared«ENDIF»
		«IF event.hasNewFile»Index has new file«ENDIF»
		«IF event.reloaded»Index reloaded«ENDIF»
		```
	''')
}

Indexer is only updated on save or other file level changes. Althought change events include the affected project and both the cleared and written files are arrays, the event arrives multiple times for the same project in a single processing (busy) period.

Deleting multiple files results in a single update.

Developer resources

UML-Java synchronization

  • Gerrit change: https://git.eclipse.org/r/#/c/85611/
  • Java plugins path: languages/java/sync
  • User interface plugin:
    • org.eclipse.papyrus.designer.languages.java.sync.ui
      • Contains the entry point to setting up the synchronization from the user interface
      • To start exploring, a good place would be org.eclipse.papyrus.designer.languages.java.sync.ui.SynchronisationModelHandler.startTransformation(IProject, Model)
      • Synchronizations handled be the UI are managed by org.eclipse.papyrus.designer.languages.java.sync.ui.manager.RunningSynchronizationManager
  • Java-to-UML incremental transformation:
    • org.eclipse.papyrus.designer.languages.java.sync.reverse
      • Contains the code that uses VIATRA Transformation EVM-JDT integration to update the UML model
      • Transformation entry point org.eclipse.papyrus.designer.languages.java.sync.reverse.JDTUMLTransformation
      • High level rules are in the org.eclipse.papyrus.designer.languages.java.sync.reverse.rules package
        • At this point only TransactionalCompilationUnitRule and PackageRule are used
      • AST visitor for processing Java source code: org.eclipse.papyrus.designer.languages.java.sync.reverse.rules.visitors.TypeVisitor
    • org.eclipse.papyrus.designer.languages.java.sync.umlmanipulator
      • Contains the interface and implementation for manipulating the UML model
      • See org.eclipse.papyrus.designer.languages.java.sync.umlmanipulator.UMLModelAccess
  • UML-to-Java incremental transformation:
    • org.eclipse.papyrus.designer.languages.java.sync.codegen
      • Contains the code that uses VIATRA Transformation to update the Java source code
      • Transformation entry point org.eclipse.papyrus.designer.languages.java.sync.codegen.UMLToJavaTransformation
      • Transformation rules are in the org.eclipse.papyrus.designer.languages.java.sync.codegen.rules package
    • org.eclipse.papyrus.designer.languages.java.sync.jdtmanipulator
      • Contains the interface and implementation for manipulating the Java source code through the JDT API
      • See org.eclipse.papyrus.designer.languages.java.sync.jdtmanipulator.IJDTManipulator

Copyright © Eclipse Foundation, Inc. All Rights Reserved.