INRIA / INRIA/spoon

Annotations source position handling on parameters and parameter type annotation.

Open
#3,358 3 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
Java
Stars
2k
Forks
392
Avg merge
11h 24m
Merged PRs (30d)
36

Description

It seems that currently annotation on type usages lead to spoon cloning annotations to put them on both the typed element and the type reference when the annotation's target is ambiguous. (Which is probably legitimate.)

This leads indirectly to position problem and sniper printer problems as documented in #3321 . Even if this can be worked around ( #3352 ), or may be fixed by changing the start position of the type reference.

Consider the following case:

```java
//A type use annotation
@Target({ElementType.TYPE_USE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnno {
}

//A parameter annotation
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface OtherAnno {
}

//An annotation the can target both parameter and type usage
@Target({ElementType.PARAMETER, ElementType.TYPE_USE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Ambiguous {
}

public class AnnoUser {
public void m1(@MyAnno String p) {} // Annotation is on the type reference to String
public void m2(@OtherAnno String p) {} // Annotation is on parameter p
public void m3(@Ambiguous String p) {} // Annotation is on both
}
```

Corresponding bytecode
```
public void m1(java.lang.String);
descriptor: (Ljava/lang/String;)V
flags: ACC_PUBLIC
Code:
stack=0, locals=2, args_size=2
0: return
LineNumberTable:
line 4: 0
LocalVariableTable:
Start Length Slot Name Signature
0 1 0 this Lse/kth/access/testannoagain/AnnoUser;
0 1 1 p Ljava/lang/String;
RuntimeVisibleTypeAnnotations:
0: #16(): METHOD_FORMAL_PARAMETER, param_index=0

public void m2(java.lang.String);
descriptor: (Ljava/lang/String;)V
flags: ACC_PUBLIC
Code:
stack=0, locals=2, args_size=2
0: return
LineNumberTable:
line 5: 0
LocalVariableTable:
Start Length Slot Name Signature
0 1 0 this Lse/kth/access/testannoagain/AnnoUser;
0 1 1 p Ljava/lang/String;
RuntimeVisibleParameterAnnotations:
parameter 0:
0: #19()

public void m3(java.lang.String);
descriptor: (Ljava/lang/String;)V
flags: ACC_PUBLIC
Code:
stack=0, locals=2, args_size=2
0: return
LineNumberTable:
line 6: 0
LocalVariableTable:
Start Length Slot Name Signature
0 1 0 this Lse/kth/access/testannoagain/AnnoUser;
0 1 1 p Ljava/lang/String;
RuntimeVisibleTypeAnnotations:
0: #21(): METHOD_FORMAL_PARAMETER, param_index=0
RuntimeVisibleParameterAnnotations:
parameter 0:
0: #21()
```

To my understanding:

* in the case of `m1`, the position of the parameter and its type reference should include the position of the annotation.
* in the case of `m2`, the position of the parameter should include the position of the annotation, but the position of the type reference should not include it.
* in the case of `m3`, the position of the parameter and its type reference should include the position of the annotation.

As far as I can see, non of this happen, in all three situation the position of the annotation is exterior to the parameter position.

Side note, in case 3, as the annotation is cloned, if a transformation is applied to on of the annotation it would not affect the other, hence I am not sure how it would be then pretty printed.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.