Search code examples
rascal

Adding annotations for Java M3 nodes


I am trying to add multiple annotations to a Java M3 node. As a working example this is what I'm trying to do:

n = \number("5");
n = setAnnotations(n, ("modifiers" : [\static()]));
n = setAnnotations(n, ("modifiers" : getAnnotations(n ["modifiers"]+\public()));

Which causes the following error:

|rascal://Driver|(1556,7,<59,57>,<59,64>): insert into collection not supported on value and Modifier
?[Advice](http://tutor.rascal-mpl.org/Errors/Static/UnsupportedOperation/UnsupportedOperation.html)

In addition I have tried:

n = \number("5");
n = setAnnotations(n, ("modifiers" : [\static()]));
n = setAnnotations(n, ("modifiers" : getAnnotations(n)["modifiers"]+[\public()]));

Which doesn't crash but produces an annotation as follows:

number("5")[
  @modifiers=[
    [static()],
    public()
  ]
]

Which is not what I'm looking for. I have also tried:

n = \number("5");
n = setAnnotations(n, ("modifiers" : [\static()]));
a = [\static(), [ m | m <- getAnnotations(n)["modifiers"] ] ];
n = setAnnotations(n, (modifiers : a));

With the following error:

|rascal://Driver|(1548,11,<59,49>,<59,60>): value is not enumerable
?[Advice](http://tutor.rascal-mpl.org/Errors/Static/NotEnumerable/NotEnumerable.html)

Really I just want some way to append Modifiers to the modifiers annotation. What am I doing wrong here? Thanks.


Solution

  • If you just want to add an annotation to a value, valid alternatives are the following:

    // as assignment statements which modify the variable `n`:
    n@modifiers = [\static(), \public()]; // setting a new value for the modifiers annotation
    n@modifiers += [\public()]; // short-hand to concatenate to the existing value of modifiers 
    n@modifiers?[] += [\public()]; // in case sometimes there is no initial value to begin with we initialize with empty list.
    // as expression to create a new value assigned to m with a different annotation than n had:
    m = n[@modifiers=[\static(), \public()];
    m = n[@modifiers=n@modifiers + [\public()]]; // using the previous value too
    

    Some clarification about the errors you've seen:

    • getAnnotations returns a value of type map[str,value], since value is the top type Rascal does not know many operations to apply to it. This explains why you can't concatenate or enumerate. It requires pattern matching to downcast to a more useful type, as in for (list[Modifier] modifiers := getAnnotations(n)["modifiers"], Modifier m <- modifiers) { ... }
    • to retrieve an annotation in a typed manner simply use n@modifiers which is of type list[Modifier] due to the declaration anno list[Modifier] Declaration@modifiers; somewhere in the M3 library.