Improved type annotation support

PsiTypeElementImpl#addAnnotation implemented
AddAnnotationPsiFix, NullableNotNullManager adjusted
Fixes IDEA-232258 "Annotate overridden method parameters @NotNull" erroneously adds notNull to the param, not its type
Fixes IDEA-232565 Intention "Annotate overriding methods as NotNull" doesn't respect "type use"
Also, AddAnnotationPsiFix can be applied in batch now when annotations are not external.

GitOrigin-RevId: 0b652d3b032ed0d1c701beeda102c5e3c841762c
This commit is contained in:
Tagir Valeev
2020-02-12 06:13:13 +00:00
committed by intellij-monorepo-bot
parent ba85ab49e2
commit 2c486b2d0a
13 changed files with 456 additions and 79 deletions
@@ -0,0 +1,36 @@
// "Fix all '@NotNull/@Nullable problems' problems in file" "true"
package typeUse;
import java.lang.annotation.*;
@Target({ElementType.TYPE_USE, ElementType.PARAMETER}) public @interface NotNull { }
@Target({ElementType.TYPE_USE, ElementType.PARAMETER}) public @interface Nullable { }
interface Foo {
void processString(@NotNull String s);
void processArray(String @NotNull [] arr);
void processArray2(String @NotNull [] arr);
void processString2(java.lang.@NotNull String qualified);
void processList(@NotNull List<@NotNull String> list);
void processList2(@NotNull List<String> finalList);
}
static class Bar implements Foo {
@Override
public void processString(@NotNull String s) { }
@Override
public void processArray(String @NotNull [] arr) { }
@Override
public void processArray2(@NotNull String @NotNull [] arr) { }
@Override
public void processString2(java.lang.@NotNull String qualified) { }
@Override
public void processList(@NotNull List<@NotNull String> list) { }
@Override
public void processList2(final @NotNull List<String> finalList) { }
}
@@ -0,0 +1,42 @@
// "Fix all '@NotNull/@Nullable problems' problems in file" "true"
package typeUse;
import java.lang.annotation.*;
@Target(ElementType.TYPE_USE) public @interface NotNull { }
@Target(ElementType.TYPE_USE) public @interface Nullable { }
interface Foo {
@NotNull String getString();
String @NotNull [] getArray();
java.lang.@NotNull String getString2();
@NotNull List<@NotNull String> getList();
<T> @NotNull List<String> getList2();
}
class Bar implements Foo {
@Override
public @NotNull String getString() {
return "";
}
@Override
public String @NotNull [] getArray() {
return new String[0];
}
@Override
public java.lang.@NotNull String getString2() {
return "";
}
@Override
public @NotNull List<String> getList() {
return Collections.emptyList();
}
@Override
public <T> @NotNull List<String> getList2() {
return Collections.emptyList();
}
}
@@ -0,0 +1,40 @@
// "Fix all '@NotNull/@Nullable problems' problems in file" "true"
package typeUse;
import java.lang.annotation.*;
@Target(ElementType.TYPE_USE) public @interface NotNull { }
@Target(ElementType.TYPE_USE) public @interface Nullable { }
interface Foo {
void processString(@NotNull String s);
void processArray(String @NotNull [] arr);
void processArray2(String @NotNull [] arr);
void processArray3(String @NotNull ... arr);
void processString2(java.lang.@NotNull String qualified);
void processList(@NotNull List<@NotNull String> list);
void processList2(@NotNull List<String> finalList);
}
static class Bar implements Foo {
@Override
public void processString(@NotNull String s) { }
@Override
public void processArray(String @NotNull [] arr) { }
@Override
public void processArray2(@NotNull String @NotNull [] arr) { }
@Override
public void processArray3(String @NotNull ... arr) { }
@Override
public void processString2(java.lang.@NotNull String qualified) { }
@Override
public void processList(@NotNull List<@NotNull String> list) { }
@Override
public void processList2(final @NotNull List<String> finalList) { }
}
@@ -0,0 +1,36 @@
// "Fix all '@NotNull/@Nullable problems' problems in file" "true"
package typeUse;
import java.lang.annotation.*;
@Target({ElementType.TYPE_USE, ElementType.PARAMETER}) public @interface NotNull { }
@Target({ElementType.TYPE_USE, ElementType.PARAMETER}) public @interface Nullable { }
interface Foo {
void processString(@NotNull String s);
void processArray(String @NotNull [] arr);
void processArray2(String @NotNull [] arr);
void processString2(java.lang.@NotNull String qualified);
void processList(@NotNull List<@NotNull String> list);
void processList2(@NotNull List<String> finalList);
}
static class Bar implements Foo {
@Override
public void processString(String <caret>s) { }
@Override
public void processArray(String[] arr) { }
@Override
public void processArray2(@NotNull String[] arr) { }
@Override
public void processString2(java.lang.String qualified) { }
@Override
public void processList(List<@NotNull String> list) { }
@Override
public void processList2(final List<String> finalList) { }
}
@@ -0,0 +1,42 @@
// "Fix all '@NotNull/@Nullable problems' problems in file" "true"
package typeUse;
import java.lang.annotation.*;
@Target(ElementType.TYPE_USE) public @interface NotNull { }
@Target(ElementType.TYPE_USE) public @interface Nullable { }
interface Foo {
@NotNull String getString();
String @NotNull [] getArray();
java.lang.@NotNull String getString2();
@NotNull List<@NotNull String> getList();
<T> @NotNull List<String> getList2();
}
class Bar implements Foo {
@Override
public String g<caret>etString() {
return "";
}
@Override
public String[] getArray() {
return new String[0];
}
@Override
public java.lang.String getString2() {
return "";
}
@Override
public List<String> getList() {
return Collections.emptyList();
}
@Override
public <T> List<String> getList2() {
return Collections.emptyList();
}
}
@@ -0,0 +1,40 @@
// "Fix all '@NotNull/@Nullable problems' problems in file" "true"
package typeUse;
import java.lang.annotation.*;
@Target(ElementType.TYPE_USE) public @interface NotNull { }
@Target(ElementType.TYPE_USE) public @interface Nullable { }
interface Foo {
void processString(@NotNull String s);
void processArray(String @NotNull [] arr);
void processArray2(String @NotNull [] arr);
void processArray3(String @NotNull ... arr);
void processString2(java.lang.@NotNull String qualified);
void processList(@NotNull List<@NotNull String> list);
void processList2(@NotNull List<String> finalList);
}
static class Bar implements Foo {
@Override
public void processString(String <caret>s) { }
@Override
public void processArray(String[] arr) { }
@Override
public void processArray2(@NotNull String[] arr) { }
@Override
public void processArray3(String... arr) { }
@Override
public void processString2(java.lang.String qualified) { }
@Override
public void processList(List<@NotNull String> list) { }
@Override
public void processList2(final List<String> finalList) { }
}