- edited description
Multiple contributions in single contributes declaration
Current version: JastAdd2 2.1.11-7-g910ba89
#Motivation
The contributes
declaration is currently used to either contribute a single item to one collection attribute, or a single item to multiple attributes.
For example, we could create a collection attribute to find supertypes of class declarations and write a contribution statement for the superclass like this:
ClassDecl contributes getSuperclass() when hasSuperclass() to CompilationUnit.supertypes() for compilationUnit();
If we want to contribute multiple things for a single node it gets trickier, for example if we want to contribute all interfaces implemented by a class declaration it would be useful if an Iterable
contribution could be specified, something like this:
ClassDecl contributes each getImplementsList() to CompilationUnit.supertypes() for compilationUnit();
The addition of the each
keyword here indicates that the contribution is an Iterable
containing individual contributions. Using this keyword should work well since it is already a JastAdd reserved word.
One may argue that the given example is slightly unrealistic because one would probably not want to mix Access
(from the implements list) and TypeDecl
(as returned by superclass()
) in a single collection, however it seems like similar cases where multiple contributions for a single node are needed could easily occur in practice.
#Workarounds
One workaround for this use case is to add contributions for Access
or TypeAccess
, however this is problematic because such nodes occur in many other places than only the implements list of a ClassDecl, so such contributions would have to have a when
clause to figure out if the Access
is in an Implements
list.
Another workaround is to let each contribution be a Collection
, and use addAll
as the mutation method. This then requires creating singleton wrapper collections for each non-collection contribution, also this does not work with non-collection iterable value-expressions such as AST lists.
#Proposed Changes
##Additions to Parser
Allow an each
keyword after contributes
. This should flag the contribution as an iterable contribution.
##Changes to Code Generation
Code generation must be modified to support the new iterable contribution declaration. This should be simple since we do not need to modify the computation of contributors, only the way a contribution is added to the collection value, by generating a loop to iterate over the contribution values.
##Additions to Documentation
Contribution declaration
N1 contributes each value-exp
when cond-exp
to N2.a()
for N2-ref-exp;
The each keyword indicates that value-exp is an iterable collection of single contributions which should all be added to the target collection attribute by iterating over the result of value-exp and adding each to the collection.
##References:
Comments (3)
-
reporter -
reporter - edited description
Added alternative workaround.
-
reporter - changed status to resolved
This is implemented already. See issue
#249 - Log in to comment
Fixed error in example:
each
was used in the wrong contribution.