-
Notifications
You must be signed in to change notification settings - Fork 6
Implement initialisers for JaMoPP #12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
AlpTorac
wants to merge
55
commits into
CIPM-tools:build-pipeline
Choose a base branch
from
AlpTorac:inits-pull-req
base: build-pipeline
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Contributor
Author
|
A pull request filled with tests utilising the initialisers implemented here will follow soon. |
db40e49 to
c2ad5a0
Compare
Contributor
Author
|
The attempt to create a stacked pull request failed and the pull-request branch was reset to its previous state, hence the force-push. |
The abstract class encapsulates the logic behind storing adaptation strategies for initialisers
Initialiser packages (IInitialiserPackage implementors) can be used to grant centralised access to related groups of initialisers. They mimic org.emftext.language.java.JavaPackage and allow package-based access to initialisers. The content of initialiser packages is to be defined by overriding certain methods (refer to the documentation within the IInitialiserPackage interface).
for Java-related classes (all of them extend EObject) used by JaMoPP. The main purpose of this interface is to make it easier to declare methods for the said classes. This interface can also be used to filter JaMoPP-related initialisers from EObject initialisers, if initialisers for other EObject utilising techologies are implemented in the future.
org.emftext.language.java.classifiers
org.emftext.language.java.containers
org.emftext.language.java.expressions
org.emftext.language.java.generics
org.emftext.language.java.instantiations
org.emftext.language.java.literals
org.emftext.language.java.members
org.emftext.language.java.modules
org.emftext.language.java.parameters
org.emftext.language.java.references
org.emftext.language.java.statements
These strategies can be used to adapt the initialisers, so that they can successfully initialise the objects they create within tests (to be implemented in another plug-in in the future).
Implemented to extract some mutual method implementations. Provides default methods that can be used by tests, which check whether necessary initialisers are present and can be accessed.
Contains information about the naming convention used while naming initialisers
Contains some information about the naming convention used in JaMoPP Provides methods to access EObject implementations of Java-related elements in JaMoPP. Includes methods that can be used to retrieve initialisers corresponding to those JaMoPP-elements by using the name of the objects they are supposed to create.
These tests can be run to ensure that there are initialisers for each Java-related element in JaMoPP. Note: Relative paths are used within tests to access initialiser files. Therefore, if the position of cipm.consistency.initialisers.jamopp.utiltests changes relatively to the initialiser files, the said path will have to be changed for tests to work.
Those tests will aim to ensure that initialiser discovery by using initialiser packages works as intended. They will furthermore check, whether initialiser adaptation works as expected.
Their purpose is to be used to verify that initialisers can modify the objects they create as intended. They can also be used to test some static methods of IInitialiser (the top-level initialiser interface). The said dummy constructs also include a re-usable abstract class for further dummy constructs (to be implemented in the following commits).
Add a package that contains 4 dummy objects, as well as their dummy initialisers. Neither the said objects nor their initialisers form a type hierarchy (i.e. they do not extend one another). They are meant to be used in tests, which verify some static methods of IInitialiser (the top-level initialiser interface).
Add a package that contains some dummy objects and their dummy initialisers, which extend one another. They are to be used in tests that verify some static methods of IInitialiser (the top-level initialiser interface).
Use the same JUnit related dependencies as vsum tests Add JUnit Argument dependencies as well
c2ad5a0 to
445879c
Compare
Use the utility method in isInitialiserFor to retrieve the type of object they instantiate. Added to spare code duplication in tests
in order to make sure that the tests are working as intended. Computing and determining this dynamically can lead to misleading results. It is better to synchronise initialiser counts upon adding new initialisers, since adding new initialisers is not expected to be common.
to retrieve types, which should have a (concrete) initialiser. Although using the suffix each implementation has ("Impl") is possible, having a dynamic way of separating such types is more desirable.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Introduction
Implemented a new plug-in called "initialisers" (its full name is cipm.consistency.initialisers), which contains a series of classes/interfaces called initialisers. Initialisers' purpose is to ease the construction of Java-related objects (such as CompilationUnit, NamespaceClassifierReference, various expressions, etc.) used by JaMoPP from outside (JaMoPP objects), by addressing their complex and partially unintuitive construction.
The "initialisers" plug-in also contains tests for some top-level initialiser interfaces and further utility tests.
Note: Some commits, where initialisers for JaMoPP objects are implemented, are not functional because of unavoidable cyclic dependencies between certain initialiser packages. Such commits are indicated via the "(WIP)" in their message. Although it could be possible to have multiple commits for such initialiser packages, doing so would overcomplicate the pull request.
Description of Initialisers
Each initialiser has a corresponding type SomeType (which is its designated type) within the type hierarchy of the JaMoPP objects. For each initialiser with the designated type SomeType, there is an initialiser interface ISomeTypeInitialiser and its concrete implementation SomeTypeInitialiser (as a class). If SomeType is not instantiable, there will be no concrete implementation of its initialiser, only an initialiser interface. Here, a type is also considered to be instantiable, if it is an abstract class or interface that has a direct implementor. For example, CompilationUnit is directly instantiable, since CompilationUnitImpl directly implements it.
Each initialiser provides a method called instantiate(), which creates an instance of the designated type of the initialiser. Keep in mind that the instance created this way might be missing some of its required attributes and require further initialisation (see "Adaptation of Initialisers" below). The signature of the instantiate() method is overridden in each initialiser interface, in order to circumvent type inconsistencies.
Each initialiser is meant to provide modification methods, which summarise certain modifications on the initialiser's designated type that one would normally have to perform by directly calling methods of its designated objects. Because of the complex structure of JaMoPP objects, modification methods' return values are used to indicate, whether the modification was successful (similar to add(...) and remove(...) methods for some collections).
Type hierarchy of Initialisers
The one of the core ideas behind the implementation of JaMoPP objects is to encapsulate certain aspects with interfaces and to have those JaMoPP objects extend the interfaces, which encapsulate their various aspects. For example: The NamedElement interface in JaMoPP encapsulates the "name" attribute and is implemented/extended by JaMoPP objects that should have the "name" attribute. Because there are lots of different JaMoPP objects that share certain attributes (or groups of attributes), it is possible to spare large amounts of code by following that idea.
This idea is used in the initialisers as well: The modification methods provided by the initialisers are mostly implemented directly in their initialiser interface (as default methods). Since Java allows extending multiple interfaces, new initialisers can simply extend existing initialisers. Because of this, the type hierarchy of initialisers mirrors the type hierarchy of JaMoPP objects. Some implications are:
Changes to JaMoPP objects can be applied to initialisers in a similar way, in order to keep them synchronised with JaMoPP.
Adding initialisers for new JaMoPP objects is simple, as it is possible to implement/extend existing initialiser interfaces.
One can use the most general initialiser type in method signatures to abstract away (to a certain degree) from the concrete initialiser and also from its designated type.
Adaptation of Initialisers
Although all instances created by concrete initialisers (JaMoPP objects) are functional EObject instances, they may not be "valid" in terms of JaMoPP. This is caused by the fact that EObject (a meta-metamodel) being used to represent Java constructs (Java language is a metamodel). It is therefore possible to have JaMoPP objects that do not represent "valid" Java constructs.
Since some concrete initialisers can create "invalid" instances (obj) of their designated type, they have the means to be adapted by Initialiser Adapter Strategies. Initialiser adapter strategies can be added to certain initialisers, in order to add additional steps to their initialise(obj) method and perform other necessary modifications, which ultimately make obj "valid". Even though it would be possible to perform those necessary modifications manually, it may not always be feasible to do so, if the type of the concrete initialiser instance is not known (in parameterised tests explained previously, for instance).
Initialiser adapter strategies can also be used to extract construction steps, such as adding a "default" container to a JaMoPP object.
Future notes
The top-level initialiser interfaces defined in this plug-in can be re-used in other technologies. The initialisers defined here for JaMoPP objects can also be used in other projects that make use them. Therefore, it could be a good idea to eventually move this plug-in to its own repository.