mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[java-inspections] part of IDEA-380832
- external annotations for type parameters GitOrigin-RevId: 43e826ca12b06ad607e325e81736fe56c514b69f
This commit is contained in:
committed by
intellij-monorepo-bot
parent
0ecc455ce9
commit
89af2dec36
@@ -22,7 +22,9 @@ import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.pom.java.JavaFeature
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.impl.source.PsiClassReferenceType
|
||||
import com.intellij.psi.tree.TokenSet
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import com.intellij.psi.util.PsiUtil
|
||||
import com.intellij.psi.util.createSmartPointer
|
||||
import org.jetbrains.annotations.PropertyKey
|
||||
@@ -55,18 +57,52 @@ public class AnnotationInlayProvider : InlayHintsProvider {
|
||||
if (project.isDefault) return null
|
||||
return object : SharedBypassCollector {
|
||||
override fun collectFromElement(element: PsiElement, sink: InlayTreeSink) {
|
||||
if (element is PsiTypeParameterListOwner) {
|
||||
sink.whenOptionEnabled(SHOW_EXTERNAL) {
|
||||
val originalOwner = element.originalElement
|
||||
if (originalOwner !is PsiCompiledElement || originalOwner !is PsiTypeParameterListOwner) {
|
||||
return@whenOptionEnabled
|
||||
}
|
||||
val typeParameterList = originalOwner.typeParameterList ?: return@whenOptionEnabled
|
||||
for ((index, originalParameter) in typeParameterList.typeParameters.withIndex()) {
|
||||
val parameter = element.typeParameters.getOrNull(index) ?: return@whenOptionEnabled
|
||||
val manager = ExternalAnnotationsManager.getInstance(project)
|
||||
processTypeParameterRecursively(parameter, originalParameter, sink)
|
||||
parameter.extendsList.referenceElements.zip(originalParameter.extendsList.referencedTypes)
|
||||
.forEach { pair: Pair<PsiJavaCodeReferenceElement?, PsiClassType?> ->
|
||||
val referenceElement = pair.first
|
||||
val classType = pair.second
|
||||
if (referenceElement == null || classType == null) {
|
||||
return@forEach
|
||||
}
|
||||
classType.annotations
|
||||
.filter(manager::isExternalAnnotation)
|
||||
.forEach {
|
||||
sink.addAnnotationPresentation(it, project, InlineInlayPosition(referenceElement.textRange.startOffset, false), HINT_FORMAT, TYPE_ANNOTATION_PAYLOADS)
|
||||
}
|
||||
}
|
||||
if (originalParameter.superTypes.size == 1 && parameter.extendsList.referenceElements.isEmpty()) {
|
||||
if (originalParameter.superTypes[0].equalsToText(CommonClassNames.JAVA_LANG_OBJECT)) {
|
||||
originalParameter.superTypes[0].annotations
|
||||
.filter(manager::isExternalAnnotation)
|
||||
.forEach {
|
||||
// it is not really correct, because
|
||||
// annotations should be applied to object, like: `T extends @NotNull Object`
|
||||
// but it is too long, so let's apply it to type parameters
|
||||
sink.addAnnotationPresentation(it, project, InlineInlayPosition(parameter.textRange.startOffset, false), HINT_FORMAT, TYPE_ANNOTATION_PAYLOADS)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (element is PsiTypeElement) {
|
||||
sink.whenOptionEnabled(SHOW_EXTERNAL) {
|
||||
val originalElement = element.originalElement
|
||||
val typeParameter = PsiTreeUtil.getParentOfType(element, PsiTypeParameter::class.java)
|
||||
if (typeParameter != null) return@whenOptionEnabled
|
||||
if (originalElement is PsiTypeElement && originalElement is PsiCompiledElement) {
|
||||
val type = originalElement.type
|
||||
val offset = element.textRange.startOffset
|
||||
val manager = ExternalAnnotationsManager.getInstance(project)
|
||||
type.annotations
|
||||
.filter(manager::isExternalAnnotation)
|
||||
.forEach {
|
||||
sink.addAnnotationPresentation(it, project, InlineInlayPosition(offset, false), HINT_FORMAT, TYPE_ANNOTATION_PAYLOADS)
|
||||
}
|
||||
showPsiTypeElement(originalElement, element, sink)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -101,6 +137,78 @@ public class AnnotationInlayProvider : InlayHintsProvider {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun showPsiTypeElement(
|
||||
originalElement: PsiTypeElement,
|
||||
element: PsiTypeElement,
|
||||
sink: InlayTreeSink,
|
||||
) {
|
||||
val type = originalElement.type
|
||||
val offset = element.textRange.startOffset
|
||||
val manager = ExternalAnnotationsManager.getInstance(project)
|
||||
type.annotations
|
||||
.filter(manager::isExternalAnnotation)
|
||||
.forEach {
|
||||
sink.addAnnotationPresentation(it, project, InlineInlayPosition(offset, false), HINT_FORMAT, TYPE_ANNOTATION_PAYLOADS)
|
||||
}
|
||||
}
|
||||
|
||||
private fun processTypeParameterRecursively(parameter: PsiTypeParameter, originalParameter: PsiTypeParameter, sink: InlayTreeSink) {
|
||||
fun recursiveProcessTypeElement(element: PsiElement, originalElement: PsiElement) {
|
||||
if (element is PsiTypeElement && originalElement is PsiTypeElement) {
|
||||
showPsiTypeElement(originalElement, element, sink)
|
||||
}
|
||||
element.children
|
||||
.filter {
|
||||
it is PsiTypeElement ||
|
||||
it is PsiJavaCodeReferenceElement ||
|
||||
it is PsiReferenceParameterList
|
||||
}.zip(
|
||||
originalElement.children
|
||||
.filter {
|
||||
it is PsiTypeElement ||
|
||||
it is PsiJavaCodeReferenceElement
|
||||
})
|
||||
.forEach {
|
||||
val nestedElement = it.first
|
||||
val nestedOriginalElement = it.second
|
||||
if (nestedElement is PsiTypeElement && nestedOriginalElement is PsiTypeElement) {
|
||||
recursiveProcessTypeElement(nestedElement, nestedOriginalElement)
|
||||
}
|
||||
if (nestedElement is PsiReferenceParameterList && nestedOriginalElement is PsiReferenceParameterList) {
|
||||
nestedElement.typeParameterElements.zip(nestedOriginalElement.typeParameterElements).forEach { nested ->
|
||||
recursiveProcessTypeElement(nested.first, nested.second)
|
||||
}
|
||||
}
|
||||
if (nestedElement is PsiJavaCodeReferenceElement && nestedOriginalElement is PsiJavaCodeReferenceElement) {
|
||||
val originalTypeParameterElements = nestedOriginalElement.parameterList?.typeParameterElements
|
||||
val typeParameterElements = nestedElement.parameterList?.typeParameterElements
|
||||
if (typeParameterElements != null && originalTypeParameterElements != null) {
|
||||
typeParameterElements.zip(originalTypeParameterElements).forEach { nested ->
|
||||
recursiveProcessTypeElement(nested.first, nested.second)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
parameter.extendsList.referenceElements.zip(originalParameter.superTypes)
|
||||
.forEach {
|
||||
val referenceElement = it.first
|
||||
val originalType = it.second
|
||||
if (referenceElement == null || originalType !is PsiClassReferenceType) return@forEach
|
||||
val parameterList = referenceElement.parameterList
|
||||
val originalParameterList = originalType.reference.parameterList
|
||||
if (parameterList == null || originalParameterList == null) return@forEach
|
||||
parameterList.typeParameterElements.zip(originalParameterList.typeParameterElements)
|
||||
.forEach { pair ->
|
||||
val parameter = pair.first
|
||||
val originalParameter = pair.second
|
||||
if (parameter == null || originalParameter == null) return@forEach
|
||||
recursiveProcessTypeElement(parameter, originalParameter)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,7 +129,7 @@ public final class TypeNullability {
|
||||
if (manager != null) {
|
||||
NullabilityAnnotationInfo typeUseNullability = manager.findDefaultTypeUseNullability(parameter);
|
||||
if (typeUseNullability != null) {
|
||||
return typeUseNullability.toTypeNullability();
|
||||
return typeUseNullability.toTypeNullability().inherited();
|
||||
}
|
||||
}
|
||||
return UNKNOWN;
|
||||
|
||||
@@ -53,6 +53,13 @@ public final class JavaTypeNullabilityUtil {
|
||||
PsiTypeParameter typeParameter = (PsiTypeParameter)target;
|
||||
PsiReferenceList extendsList = typeParameter.getExtendsList();
|
||||
PsiClassType[] extendTypes = extendsList.getReferencedTypes();
|
||||
Set<PsiClassType> nextVisited = visited == null ? new HashSet<>() : visited;
|
||||
nextVisited.add(type);
|
||||
//superTypes returns Object for `empty` parameter list, which can contain external annotations
|
||||
List<TypeNullability> nullabilities = ContainerUtil.map(typeParameter.getSuperTypes(), t -> getTypeNullability(t, nextVisited, checkContainer));
|
||||
TypeNullability fromSuper = TypeNullability.intersect(nullabilities).inherited();
|
||||
if (fromSuper != TypeNullability.UNKNOWN) return fromSuper;
|
||||
//but this Object cannot hold nullability container, because doesn't have a reference
|
||||
if (extendTypes.length == 0 && checkContainer) {
|
||||
NullableNotNullManager manager = NullableNotNullManager.getInstance(typeParameter.getProject());
|
||||
// If there's no bound, we assume an implicit `extends Object` bound, which is subject to default annotation if any.
|
||||
@@ -60,11 +67,6 @@ public final class JavaTypeNullabilityUtil {
|
||||
if (typeUseNullability != null) {
|
||||
return typeUseNullability.toTypeNullability().inherited();
|
||||
}
|
||||
} else {
|
||||
Set<PsiClassType> nextVisited = visited == null ? new HashSet<>() : visited;
|
||||
nextVisited.add(type);
|
||||
List<TypeNullability> nullabilities = ContainerUtil.map(extendTypes, t -> getTypeNullability(t, nextVisited, checkContainer));
|
||||
return TypeNullability.intersect(nullabilities).inherited();
|
||||
}
|
||||
}
|
||||
return TypeNullability.UNKNOWN;
|
||||
|
||||
@@ -16,6 +16,8 @@ import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.augment.PsiAugmentProvider;
|
||||
import com.intellij.psi.augment.PsiExtensionMethod;
|
||||
import com.intellij.psi.impl.cache.ExternalTypeAnnotationContainer;
|
||||
import com.intellij.psi.impl.cache.TypeAnnotationContainer;
|
||||
import com.intellij.psi.impl.java.stubs.PsiClassReferenceListStub;
|
||||
import com.intellij.psi.impl.java.stubs.PsiClassStub;
|
||||
import com.intellij.psi.impl.java.stubs.impl.PsiClassStubImpl;
|
||||
@@ -845,6 +847,12 @@ public final class PsiClassImplUtil {
|
||||
}
|
||||
PsiManager manager = psiClass.getManager();
|
||||
PsiClassType objectType = PsiType.getJavaLangObject(manager, psiClass.getResolveScope());
|
||||
if (psiClass instanceof PsiTypeParameter && psiClass.getParent() instanceof PsiTypeParameterList &&
|
||||
psiClass.getParent().getParent() instanceof PsiCompiledElement) {
|
||||
TypeAnnotationContainer annotations = ExternalTypeAnnotationContainer.create((PsiTypeParameter)psiClass);
|
||||
annotations = annotations.forBound().forConjunction(0);
|
||||
objectType = objectType.annotate(annotations.getProvider(psiClass));
|
||||
}
|
||||
result[0] = objectType;
|
||||
}
|
||||
System.arraycopy(implementsTypes, 0, result, extendsListLength, implementsTypes.length);
|
||||
|
||||
+19
-7
@@ -2,19 +2,18 @@
|
||||
package com.intellij.psi.impl.cache;
|
||||
|
||||
import com.intellij.codeInsight.ExternalAnnotationsManager;
|
||||
import com.intellij.psi.PsiAnnotation;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiModifierListOwner;
|
||||
import com.intellij.psi.TypeAnnotationProvider;
|
||||
import com.intellij.psi.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* A container that reports external type annotations. External type annotations are described in annotation.xml files
|
||||
* with additional {@code typePath} attribute. The attribute contains several components starting with '/' and separated with '/'
|
||||
* (no ending '/' is allowed). The allowed components are the following:
|
||||
* with additional {@code typePath} attribute. The attribute contains several components starting with '/' or '-' and separated with '/'
|
||||
* (no ending '/' is allowed).
|
||||
* '-' indicates that type parameters are considered.
|
||||
* The allowed components are the following:
|
||||
* <ul>
|
||||
* <li>{@code number} - one-based type argument index (1-255)
|
||||
* <li>{@code *} (asterisk) - bound of a wildcard type
|
||||
* <li>{@code *} (asterisk) - go to a bound
|
||||
* <li>{@code []} (square brackets) - array element (also works for varargs)
|
||||
* <li>{@code .} (dot) - enclosing type of inner type
|
||||
* </ul>
|
||||
@@ -70,4 +69,17 @@ public final class ExternalTypeAnnotationContainer implements TypeAnnotationCont
|
||||
public static @NotNull TypeAnnotationContainer create(@NotNull PsiModifierListOwner owner) {
|
||||
return new ExternalTypeAnnotationContainer("", owner);
|
||||
}
|
||||
|
||||
public static @NotNull TypeAnnotationContainer create(@NotNull PsiTypeParameter typeParameter) {
|
||||
PsiElement parent = typeParameter.getParent();
|
||||
if (parent instanceof PsiTypeParameterList &&
|
||||
parent.getParent() instanceof PsiModifierListOwner &&
|
||||
parent.getParent() instanceof PsiTypeParameterListOwner) {
|
||||
PsiTypeParameterList parameterList = (PsiTypeParameterList)parent;
|
||||
int index = parameterList.getTypeParameterIndex(typeParameter);
|
||||
String path = "-/" + (index + 1);
|
||||
return new ExternalTypeAnnotationContainer(path, (PsiModifierListOwner)parent.getParent());
|
||||
}
|
||||
return EMPTY;
|
||||
}
|
||||
}
|
||||
|
||||
+13
@@ -75,6 +75,18 @@ public interface TypeAnnotationContainer {
|
||||
*/
|
||||
@NotNull TypeAnnotationContainer forTypeArgument(int index);
|
||||
|
||||
/**
|
||||
* Returns a type annotation container for the given conjunction index.
|
||||
* Used for type parameters.
|
||||
*
|
||||
* @param i type argument index, zero-based
|
||||
* @return type annotation container for a given type argument
|
||||
* (assuming that this type annotation container is used for a class type with type arguments)
|
||||
*/
|
||||
default @NotNull TypeAnnotationContainer forConjunction(int i) {
|
||||
return forTypeArgument(i);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param parent parent PSI element for context
|
||||
* @return TypeAnnotationProvider
|
||||
@@ -85,4 +97,5 @@ public interface TypeAnnotationContainer {
|
||||
* Appends to StringBuilder annotation text that applicable to this element immediately (not to sub-elements)
|
||||
*/
|
||||
void appendImmediateText(@NotNull StringBuilder sb);
|
||||
|
||||
}
|
||||
|
||||
+8
@@ -2,6 +2,7 @@
|
||||
package com.intellij.psi.impl.java.stubs.impl;
|
||||
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.cache.ExternalTypeAnnotationContainer;
|
||||
import com.intellij.psi.impl.cache.TypeAnnotationContainer;
|
||||
import com.intellij.psi.impl.cache.TypeInfo;
|
||||
import com.intellij.psi.impl.compiled.ClsJavaCodeReferenceElementImpl;
|
||||
@@ -65,6 +66,13 @@ public class PsiClassReferenceListStubImpl extends StubBase<PsiReferenceList> im
|
||||
for (int i = 0; i < types.length; i++) {
|
||||
TypeInfo info = myInfos[i];
|
||||
TypeAnnotationContainer annotations = info.getTypeAnnotations();
|
||||
if (annotations == TypeAnnotationContainer.EMPTY) {
|
||||
PsiElement psi = myParent.getPsi();
|
||||
if (psi instanceof PsiTypeParameter) {
|
||||
annotations = ExternalTypeAnnotationContainer.create((PsiTypeParameter)psi);
|
||||
annotations = annotations.forBound().forConjunction(i);
|
||||
}
|
||||
}
|
||||
ClsJavaCodeReferenceElementImpl reference = new ClsJavaCodeReferenceElementImpl(getPsi(), info.text(), annotations);
|
||||
types[i] = new PsiClassReferenceType(reference, null).annotate(annotations.getProvider(reference));
|
||||
}
|
||||
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
package org.example;
|
||||
|
||||
import org.jspecify.annotations.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@NullMarked
|
||||
class CustomOptionalTest {
|
||||
@Nullable
|
||||
public String a;
|
||||
|
||||
Optional<String> returnNotNullableDelegate() {
|
||||
return Delegate.ofNullable(a);
|
||||
}
|
||||
|
||||
Optional<String> returnNotNullable() {
|
||||
return Optional.ofNullable(a);
|
||||
}
|
||||
|
||||
Comparator<String> getComparator() {
|
||||
return Comparator.<@Nullable String>naturalOrder();
|
||||
}
|
||||
}
|
||||
|
||||
class TestList{
|
||||
static void test(String a) {
|
||||
if (List.<error descr="Cannot resolve method 'of' in 'List'">of</error>("1", a).getFirst() == null) {
|
||||
System.out.println("null");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Delegate {
|
||||
static <L extends String> Optional<L> ofNullable(@Nullable L t) {
|
||||
return Optional.ofNullable(t);
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ import org.jspecify.annotations.NullMarked;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.util.Comparator;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@NullMarked
|
||||
@@ -13,6 +14,10 @@ class Main {
|
||||
|
||||
}
|
||||
|
||||
Comparator<String> getComparator() {
|
||||
return Comparator.<<warning descr="Non-null type parameter 'T' cannot be instantiated with @Nullable type">@Nullable</warning> String>naturalOrder();
|
||||
}
|
||||
|
||||
static <T extends @Nullable Object> T fNullableBound(Supplier<T> supplier){
|
||||
return supplier.get();
|
||||
}
|
||||
|
||||
+55
-1
@@ -117,7 +117,22 @@ public class ExternalAnnotationsManagerTest extends LightPlatformTestCase {
|
||||
assertClassFqn(nameText, psiFile, externalName, null);
|
||||
|
||||
String typePath = annotationData.getTypePath();
|
||||
if (typePath != null) {
|
||||
if (typePath != null && typePath.startsWith("-")) {
|
||||
PsiTypeParameterList typeParameterList;
|
||||
if (listOwner instanceof PsiClass variable) {
|
||||
typeParameterList = variable.getTypeParameterList();
|
||||
} else if (listOwner instanceof PsiMethod method) {
|
||||
typeParameterList = method.getTypeParameterList();
|
||||
} else {
|
||||
fail("typePath is not allowed for " + listOwner.getClass().getSimpleName(), psiFile, externalName);
|
||||
break;
|
||||
}
|
||||
String error = validatePath(typePath, typeParameterList);
|
||||
if (error != null) {
|
||||
fail("Invalid typePath: " + error, psiFile, externalName);
|
||||
}
|
||||
}
|
||||
else if (typePath != null) {
|
||||
PsiType type;
|
||||
if (listOwner instanceof PsiVariable variable) {
|
||||
type = variable.getType();
|
||||
@@ -191,6 +206,45 @@ public class ExternalAnnotationsManagerTest extends LightPlatformTestCase {
|
||||
return Objects.requireNonNull(PsiUtil.getTypeByPsiElement(listOwner), () -> String.valueOf(listOwner));
|
||||
}
|
||||
|
||||
private static String validatePath(@NotNull String pathString, @NotNull PsiTypeParameterList typeParameterList) {
|
||||
if (!pathString.startsWith("-/")) {
|
||||
return "Must start with '-/'";
|
||||
}
|
||||
String[] components = pathString.split("/", -1);
|
||||
String component = components[1];
|
||||
int i;
|
||||
try {
|
||||
i = Integer.parseInt(component);
|
||||
}
|
||||
catch (NumberFormatException ignored) {
|
||||
return "Invalid path: " + pathString + "; invalid component: " + component;
|
||||
}
|
||||
PsiTypeParameter[] parameters = typeParameterList.getTypeParameters();
|
||||
if (i <= 0 || parameters.length < i) {
|
||||
return "Invalid path: " + pathString + "; type parameter index out of bounds: " + i;
|
||||
}
|
||||
PsiTypeParameter parameter = parameters[i - 1];
|
||||
String asterix = components[2];
|
||||
if (!asterix.equals("*")) {
|
||||
return "Invalid path: " + pathString + "; only '*' is allowed for type parameter " + parameter.getName();
|
||||
}
|
||||
String nextIndex = components[3];
|
||||
try {
|
||||
i = Integer.parseInt(nextIndex);
|
||||
}
|
||||
catch (NumberFormatException ignored) {
|
||||
return "Invalid path: " + pathString + "; invalid extends component: " + nextIndex;
|
||||
}
|
||||
PsiClassType[] types = parameter.getExtendsList().getReferencedTypes();
|
||||
if (components.length == 4 && i == 1 && types.length == 0) return null;
|
||||
if (i <= 0 || types.length < i) {
|
||||
return "Invalid path: " + pathString + "; extends index out of bounds: " + i;
|
||||
}
|
||||
String rest = StringUtil.join(components, 4, components.length, "/");
|
||||
if (rest.isEmpty()) return null;
|
||||
return validatePath(rest, types[i - 1]);
|
||||
}
|
||||
|
||||
private static String validatePath(String pathString, PsiType type) {
|
||||
if (!pathString.startsWith("/")) {
|
||||
return "Must start with '/'";
|
||||
|
||||
+1
-1
@@ -115,7 +115,7 @@ import java.util.stream.Stream;
|
||||
import jdk.internal.ValueBased;
|
||||
|
||||
@ValueBased
|
||||
public final class Optional<T> {
|
||||
public final class Optional</*<# @NotNull #>*/T> {
|
||||
private static final Optional<?> EMPTY = new Optional((Object)null);
|
||||
private final T value;
|
||||
|
||||
|
||||
@@ -374,4 +374,9 @@ public class DataFlowInspection8Test extends DataFlowInspectionTestCase {
|
||||
public void testNewMethodReferenceMustBeNonNull() {
|
||||
doTestWith((insp, __) -> insp.TREAT_UNKNOWN_MEMBERS_AS_NULLABLE = true);
|
||||
}
|
||||
public void testExternalTypeParameterAnnotations() {
|
||||
addJSpecifyNullMarked(myFixture);
|
||||
setupTypeUseAnnotations("org.jspecify.annotations", myFixture);
|
||||
doTest();
|
||||
}
|
||||
}
|
||||
@@ -2752,7 +2752,7 @@
|
||||
</item>
|
||||
<item name='java.util.Comparator java.util.Comparator<T> naturalOrder()'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
<annotation name='org.jetbrains.annotations.NotNull' typePath="/1"/>
|
||||
<annotation name='org.jetbrains.annotations.NotNull' typePath="-/1/*/1"/>
|
||||
<annotation name='org.jetbrains.annotations.Contract'>
|
||||
<val name="pure" val="true"/>
|
||||
</annotation>
|
||||
@@ -3517,7 +3517,7 @@
|
||||
</item>
|
||||
<item name='java.util.List java.util.List<E> of(E, E)'>
|
||||
<annotation name="org.jetbrains.annotations.NotNull"/>
|
||||
<annotation name="org.jetbrains.annotations.NotNull" typePath="/1"/>
|
||||
<annotation name="org.jetbrains.annotations.NotNull" typePath="-/1/*/1"/>
|
||||
<annotation name='org.jetbrains.annotations.Contract'>
|
||||
<val name="value" val=""_,_->new""/>
|
||||
<val name="pure" val="true"/>
|
||||
@@ -4416,6 +4416,9 @@
|
||||
<val name="pure" val="true"/>
|
||||
</annotation>
|
||||
</item>
|
||||
<item name='java.util.Optional'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull' typePath='-/1/*/1'/>
|
||||
</item>
|
||||
<item name='java.util.Optional T get()'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
<annotation name='org.jetbrains.annotations.Contract'>
|
||||
|
||||
Reference in New Issue
Block a user