mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-13 15:52:01 +07:00
georgii-ustinov/252/IDEA-168035
This MR duplicates the https://code.jetbrains.team/p/ij/repositories/ultimate/reviews/173952/timeline, but fixes the conflicts community/java/java-tests/testSrc/com/intellij/codeInsight/daemon/impl/quickfix/AnnotateMethodInGeneratedFilesTest.java Merge-request: IJ-MR-175150 Merged-by: Georgii Ustinov <georgii.ustinov@jetbrains.com> GitOrigin-RevId: 69f1417a59be188fab171f8d7bfdbd57d40eddc7
This commit is contained in:
committed by
intellij-monorepo-bot
parent
773f837fff
commit
dd035bc29f
@@ -1,10 +1,10 @@
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.psi.formatter.java
|
||||
|
||||
import com.intellij.codeInsight.AnnotationUtil
|
||||
import com.intellij.codeInsight.DumbAwareAnnotationUtil
|
||||
import com.intellij.lang.ASTNode
|
||||
import com.intellij.openapi.roots.LanguageLevelProjectExtension
|
||||
import com.intellij.pom.java.LanguageLevel
|
||||
import com.intellij.pom.java.JavaFeature
|
||||
import com.intellij.psi.PsiAnnotation
|
||||
import com.intellij.psi.PsiKeyword
|
||||
import com.intellij.psi.PsiModifierListOwner
|
||||
@@ -13,11 +13,14 @@ import com.intellij.psi.formatter.FormatterUtil
|
||||
import com.intellij.psi.formatter.java.JavaFormatterAnnotationUtil.isFieldWithAnnotations
|
||||
import com.intellij.psi.impl.source.tree.JavaElementType
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import com.intellij.psi.util.PsiUtil
|
||||
|
||||
internal object JavaFormatterAnnotationUtil {
|
||||
private val KNOWN_TYPE_ANNOTATIONS: Set<String> = setOf(
|
||||
"org.jetbrains.annotations.NotNull",
|
||||
"org.jetbrains.annotations.Nullable"
|
||||
AnnotationUtil.NOT_NULL,
|
||||
AnnotationUtil.NULLABLE,
|
||||
AnnotationUtil.J_SPECIFY_NON_NULL,
|
||||
AnnotationUtil.J_SPECIFY_NULLABLE,
|
||||
)
|
||||
|
||||
/**
|
||||
@@ -31,8 +34,7 @@ internal object JavaFormatterAnnotationUtil {
|
||||
fun isTypeAnnotation(annotation: ASTNode): Boolean {
|
||||
val node = annotation.psi as? PsiAnnotation ?: return false
|
||||
|
||||
val languageLevel = LanguageLevelProjectExtension.getInstance(node.project).languageLevel
|
||||
if (languageLevel.isLessThan(LanguageLevel.JDK_1_8)) return false
|
||||
if (!PsiUtil.isAvailable(JavaFeature.TYPE_ANNOTATIONS, node)) return false
|
||||
|
||||
val next = PsiTreeUtil.skipSiblingsForward(node, PsiWhiteSpace::class.java, PsiAnnotation::class.java)
|
||||
if (next is PsiKeyword) return false
|
||||
|
||||
@@ -26,6 +26,9 @@ public class AnnotationUtil {
|
||||
public static final String NOT_NULL = "org.jetbrains.annotations.NotNull";
|
||||
public static final String NOT_NULL_BY_DEFAULT = "org.jetbrains.annotations.NotNullByDefault";
|
||||
|
||||
public static final String J_SPECIFY_NON_NULL = "org.jspecify.annotations.NonNull";
|
||||
public static final String J_SPECIFY_NULLABLE = "org.jspecify.annotations.Nullable";
|
||||
|
||||
public static final String NON_NLS = "org.jetbrains.annotations.NonNls";
|
||||
public static final String NLS = "org.jetbrains.annotations.Nls";
|
||||
|
||||
|
||||
@@ -5,10 +5,12 @@ import com.intellij.codeInsight.DumbAwareAnnotationUtil.KNOWN_ANNOTATIONS
|
||||
import com.intellij.codeInsight.DumbAwareAnnotationUtil.hasAnnotation
|
||||
import com.intellij.openapi.util.NlsSafe
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
import com.intellij.pom.java.JavaFeature
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.util.CachedValueProvider
|
||||
import com.intellij.psi.util.CachedValuesManager
|
||||
import com.intellij.psi.util.PsiModificationTracker
|
||||
import com.intellij.psi.util.PsiUtil
|
||||
|
||||
/**
|
||||
* Utility which helps to detect annotation in `Dumb mode`.
|
||||
@@ -16,10 +18,24 @@ import com.intellij.psi.util.PsiModificationTracker
|
||||
object DumbAwareAnnotationUtil {
|
||||
private const val JAVA_LANG_PACKAGE = "java.lang"
|
||||
|
||||
/**
|
||||
* Represents a list of fully qualified names for annotations that are treated as a type annotations.
|
||||
*/
|
||||
private val KNOWN_ANNOTATIONS = setOf(
|
||||
AnnotationUtil.NOT_NULL,
|
||||
AnnotationUtil.NULLABLE,
|
||||
AnnotationUtil.NON_NLS
|
||||
AnnotationUtil.NON_NLS,
|
||||
AnnotationUtil.J_SPECIFY_NON_NULL,
|
||||
AnnotationUtil.J_SPECIFY_NULLABLE
|
||||
)
|
||||
|
||||
/**
|
||||
* Represents a mapping from a fully qualified name of a module to a set of fully qualified names of annotations
|
||||
* that are treated as type annotations and located in this module
|
||||
*/
|
||||
private val KNOWN_MODULE_TO_ANNOTATIONS_MAP = mapOf(
|
||||
"org.jetbrains.annotations" to setOf(AnnotationUtil.NOT_NULL, AnnotationUtil.NULLABLE, AnnotationUtil.NON_NLS),
|
||||
"org.jspecify" to setOf(AnnotationUtil.J_SPECIFY_NON_NULL, AnnotationUtil.J_SPECIFY_NULLABLE)
|
||||
)
|
||||
|
||||
/**
|
||||
@@ -57,12 +73,12 @@ object DumbAwareAnnotationUtil {
|
||||
* Formats the given fully qualified name (FQN) by trimming whitespace around each segment.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun getFormattedReferenceFqn(referenceText: @NlsSafe String) = referenceText.split(".").joinToString(separator = ".") { pathPart -> pathPart.trim() }
|
||||
fun getFormattedReferenceFqn(referenceText: @NlsSafe String): String = referenceText.split(".").joinToString(separator = ".") { pathPart -> pathPart.trim() }
|
||||
|
||||
private fun getImportedKnownAnnotations(file: PsiJavaFile): Set<String> = CachedValuesManager.getCachedValue(file) {
|
||||
val importList = file.importList
|
||||
?: return@getCachedValue CachedValueProvider.Result(emptySet(), PsiModificationTracker.MODIFICATION_COUNT)
|
||||
val filteredAnnotations = KNOWN_ANNOTATIONS.filter { isAnnotationInImportList(it, importList) }
|
||||
val filteredAnnotations = KNOWN_ANNOTATIONS.filter { isAnnotationInImportList(it, importList) || isAnnotationInModuleImportList(it, importList) }
|
||||
.mapNotNull { fqn -> fqn.split(".").lastOrNull() }
|
||||
.toSet()
|
||||
CachedValueProvider.Result.create(filteredAnnotations, PsiModificationTracker.MODIFICATION_COUNT)
|
||||
@@ -77,6 +93,16 @@ object DumbAwareAnnotationUtil {
|
||||
}
|
||||
}
|
||||
|
||||
private fun isAnnotationInModuleImportList(annotationFqn: String, moduleList: PsiImportList): Boolean {
|
||||
if (!PsiUtil.isAvailable(JavaFeature.MODULE_IMPORT_DECLARATIONS, moduleList)) return false
|
||||
return moduleList.importModuleStatements.any { statement: PsiImportModuleStatement ->
|
||||
val referenceName = statement.referenceName ?: return@any false
|
||||
val formattedReferenceName = getFormattedReferenceFqn(referenceName)
|
||||
if (formattedReferenceName !in KNOWN_MODULE_TO_ANNOTATIONS_MAP) return@any false
|
||||
annotationFqn in KNOWN_MODULE_TO_ANNOTATIONS_MAP.getValue(formattedReferenceName)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getAnnotationImportInfo(annotationFqn: String): AnnotationImportInfo {
|
||||
val packageName = StringUtil.getPackageName(annotationFqn)
|
||||
val className = StringUtil.getShortName(annotationFqn)
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package org.example;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Target;
|
||||
import java.util.List;
|
||||
|
||||
@Target({ElementType.TYPE_USE})
|
||||
@interface CustomAnno {}
|
||||
|
||||
public class Formatter {
|
||||
@CustomAnno String getCustomString() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@CustomAnno <T, V> List<T> getCustomList() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package org.example;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Target;
|
||||
import java.util.List;
|
||||
|
||||
@Target({ElementType.TYPE_USE})
|
||||
@interface CustomAnno {
|
||||
}
|
||||
|
||||
public class Formatter {
|
||||
@CustomAnno
|
||||
String getCustomString() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@CustomAnno
|
||||
<T, V> List<T> getCustomList() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package org.example;
|
||||
|
||||
public class Formatter {
|
||||
@org.jspecify.annotations.NonNull
|
||||
<T, V> List<T> getNotNullList() {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
@org.jspecify.annotations.Nullable
|
||||
<T, V> List<T> getNullableList() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@org.jspecify.annotations.NonNull
|
||||
String getNotNullName() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@org.jspecify.annotations.Nullable
|
||||
String getNullableName() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package org.example;
|
||||
|
||||
public class Formatter {
|
||||
@org.jspecify.annotations.NonNull <T, V> List<T> getNotNullList() {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
@org.jspecify.annotations.Nullable <T, V> List<T> getNullableList() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@org.jspecify.annotations.NonNull String getNotNullName() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@org.jspecify.annotations.Nullable String getNullableName() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package org.example;
|
||||
|
||||
import org.jspecify.annotations.*;
|
||||
import java.util.List;
|
||||
|
||||
public class Formatter {
|
||||
@NonNull @org.jspecify.annotations.Nullable
|
||||
<T, V> List<T> getNotNullList() {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
@NonNull @org.jspecify.annotations.Nullable
|
||||
String getNotNullName() {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package org.example;
|
||||
|
||||
import org.jspecify.annotations.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class Formatter {
|
||||
@NonNull @org.jspecify.annotations.Nullable <T, V> List<T> getNotNullList() {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
@NonNull @org.jspecify.annotations.Nullable String getNotNullName() {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package org.example;
|
||||
|
||||
import org.jspecify.annotations.*;
|
||||
import java.util.List;
|
||||
|
||||
public class Formatter {
|
||||
@NonNull
|
||||
<T, V> List<T> getNotNullList() {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
<T, V> List<T> getNullableList() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
String getNotNullName() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Nullable
|
||||
String getNullableName() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package org.example;
|
||||
|
||||
import org.jspecify.annotations.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class Formatter {
|
||||
@NonNull <T, V> List<T> getNotNullList() {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
@Nullable <T, V> List<T> getNullableList() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@NonNull String getNotNullName() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Nullable String getNullableName() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package org.example;
|
||||
|
||||
import org.jspecify.annotations.NonNull;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
public class Formatter {
|
||||
@NonNull
|
||||
@Nullable String breakLineBetweenAnnotations() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Nullable @NonNull
|
||||
String breakLineBetweenTypeAndAnnotations() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
<T> String breakLineBetweenTypeParameterAndAnnotation() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@NonNull
|
||||
<T> String breakLineMixed() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package org.example;
|
||||
|
||||
import org.jspecify.annotations.NonNull;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
public class Formatter {
|
||||
@NonNull
|
||||
@Nullable String breakLineBetweenAnnotations() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Nullable @NonNull
|
||||
String breakLineBetweenTypeAndAnnotations() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
<T> String breakLineBetweenTypeParameterAndAnnotation() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@NonNull
|
||||
<T> String breakLineMixed() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package org.example;
|
||||
|
||||
import org.jspecify.annotations.NonNull;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
public class Formatter {
|
||||
@NonNull String getNotNullName() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Nullable String getNullableName() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package org.example;
|
||||
|
||||
import org.jspecify.annotations.NonNull;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class Formatter {
|
||||
@NonNull <T, V> List<T> getNotNullList() {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
@Nullable <T, V> List<T> getNullableList() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package org.example;
|
||||
|
||||
import org.jspecify.annotations.NonNull;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class Formatter {
|
||||
@NonNull <T, V> List<T> getNotNullList() {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
@Nullable <T, V> List<T> getNullableList() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package org.example;
|
||||
|
||||
import org.jspecify.annotations.NonNull;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
public class Formatter {
|
||||
@NonNull String getNotNullName() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Nullable String getNullableName() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package org.example;
|
||||
|
||||
import org.jspecify.annotations.NonNull;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
public class Formatter {
|
||||
@NonNull @Nullable String breakLineBetweenAnnotations() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@NonNull String breakLineBetweenTypeAndAnnotations() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable <T> String breakLineBetweenTypeParameterAndAnnotation() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@NonNull <T> String breakLineMixed() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package org.example;
|
||||
|
||||
import module org.jspecify;
|
||||
|
||||
public class Formatter {
|
||||
@NonNull @Nullable String breakLineBetweenAnnotations() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@NonNull String breakLineBetweenTypeAndAnnotations() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable <T> String breakLineBetweenTypeParameterAndAnnotation() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@NonNull <T> String breakLineMixed() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package org.example;
|
||||
|
||||
import module org.jspecify;
|
||||
|
||||
public class Formatter {
|
||||
@NonNull
|
||||
@Nullable
|
||||
String breakLineBetweenAnnotations() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@NonNull
|
||||
String breakLineBetweenTypeAndAnnotations() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
<T> String breakLineBetweenTypeParameterAndAnnotation() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@NonNull
|
||||
<T> String breakLineMixed() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package org.example;
|
||||
|
||||
import org.jspecify.annotations.NonNull;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
public class Formatter {
|
||||
@NonNull
|
||||
@Nullable
|
||||
String breakLineBetweenAnnotations() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@NonNull
|
||||
String breakLineBetweenTypeAndAnnotations() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
<T> String breakLineBetweenTypeParameterAndAnnotation() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@NonNull
|
||||
<T> String breakLineMixed() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package org.example;
|
||||
|
||||
import org.jspecify.annotations.NonNull;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class Formatter {
|
||||
@Nullable @NonNull String getCustomString() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable @NonNull <T, V> List<T> getCustomList() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package org.example;
|
||||
|
||||
import org.jspecify.annotations.NonNull;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class Formatter {
|
||||
@Nullable @NonNull String getCustomString() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable @NonNull <T, V> List<T> getCustomList() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package org.example;
|
||||
|
||||
import module org.jspecify;
|
||||
|
||||
public class Formatter {
|
||||
@NonNull
|
||||
@Nullable
|
||||
String breakLineBetweenAnnotations() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@NonNull String breakLineBetweenTypeAndAnnotations() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
<T> String breakLineBetweenTypeParameterAndAnnotation() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@NonNull
|
||||
<T> String breakLineMixed() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package org.example;
|
||||
|
||||
|
||||
import module org.jspecify;
|
||||
|
||||
public class Formatter {
|
||||
@NonNull
|
||||
@org.jspecify.annotations.Nullable
|
||||
String breakLineBetweenAnnotations() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@org.jspecify.annotations.Nullable
|
||||
@NonNull String breakLineBetweenTypeAndAnnotations() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@org.jspecify.annotations.Nullable
|
||||
<T> String breakLineBetweenTypeParameterAndAnnotation() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@org.jspecify.annotations.Nullable
|
||||
@NonNull
|
||||
<T> String breakLineMixed() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package org.example;
|
||||
|
||||
|
||||
import module org.jspecify;
|
||||
|
||||
public class Formatter {
|
||||
@NonNull @org.jspecify.annotations.Nullable String breakLineBetweenAnnotations() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@org.jspecify.annotations.Nullable @NonNull String breakLineBetweenTypeAndAnnotations() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@org.jspecify.annotations.Nullable <T> String breakLineBetweenTypeParameterAndAnnotation() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@org.jspecify.annotations.Nullable @NonNull <T> String breakLineMixed() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package org.example;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import module org.jspecify;
|
||||
|
||||
public class Formatter {
|
||||
@NonNull
|
||||
@Nullable
|
||||
String breakLineBetweenAnnotations() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@NonNull String breakLineBetweenTypeAndAnnotations() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
<T> String breakLineBetweenTypeParameterAndAnnotation() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@NonNull
|
||||
<T> String breakLineMixed() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package org.example;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import module org.jspecify;
|
||||
|
||||
public class Formatter {
|
||||
@NonNull @Nullable String breakLineBetweenAnnotations() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Nullable @NonNull String breakLineBetweenTypeAndAnnotations() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable <T> String breakLineBetweenTypeParameterAndAnnotation() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable @NonNull <T> String breakLineMixed() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package org.example;
|
||||
|
||||
import module org .
|
||||
jspecify;
|
||||
|
||||
public class Formatter {
|
||||
@NonNull
|
||||
@Nullable
|
||||
String breakLineBetweenAnnotations() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@NonNull String breakLineBetweenTypeAndAnnotations() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
<T> String breakLineBetweenTypeParameterAndAnnotation() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@NonNull
|
||||
<T> String breakLineMixed() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package org.example;
|
||||
|
||||
import module org .
|
||||
jspecify;
|
||||
|
||||
public class Formatter {
|
||||
@NonNull @Nullable String breakLineBetweenAnnotations() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Nullable @NonNull String breakLineBetweenTypeAndAnnotations() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable <T> String breakLineBetweenTypeParameterAndAnnotation() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable @NonNull <T> String breakLineMixed() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package org.example;
|
||||
|
||||
import module org.jspecify;
|
||||
|
||||
public class Formatter {
|
||||
@NonNull @Nullable String breakLineBetweenAnnotations() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Nullable @NonNull String breakLineBetweenTypeAndAnnotations() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable <T> String breakLineBetweenTypeParameterAndAnnotation() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable @NonNull <T> String breakLineMixed() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package org.example;
|
||||
|
||||
import org.jspecify.annotations.NonNull;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class Formatter {
|
||||
@NonNull
|
||||
@Nullable
|
||||
<T, V> List<T> getStrangeList() {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Nullable
|
||||
String getNotNullName() {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package org.example;
|
||||
|
||||
import org.jspecify.annotations.NonNull;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class Formatter {
|
||||
@NonNull @Nullable <T, V> List<T> getStrangeList() {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
@NonNull @Nullable String getNotNullName() {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package org.example;
|
||||
|
||||
import org.jspecify.annotations.NonNull;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class Formatter {
|
||||
@NonNull
|
||||
<T, V> List<T> getNotNullList() {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
<T, V> List<T> getNullableList() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
String getNotNullName() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Nullable
|
||||
String getNullableName() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package org.example;
|
||||
|
||||
import org.jspecify.annotations.NonNull;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class Formatter {
|
||||
@NonNull <T, V> List<T> getNotNullList() {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
@Nullable <T, V> List<T> getNullableList() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@NonNull String getNotNullName() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Nullable String getNullableName() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package org.example;
|
||||
|
||||
public class Formatter {
|
||||
@ org . jspecify .annotations . NonNull
|
||||
<T, V> List<T> getNotNullList() {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
@org. jspecify. annotations .
|
||||
Nullable
|
||||
<T, V> List<T> getNullableList() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ org. jspecify . annotations. NonNull
|
||||
String getNotNullName() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@ org . jspecify . annotations . Nullable
|
||||
String getNullableName() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package org.example;
|
||||
|
||||
public class Formatter {
|
||||
@org.jspecify.annotations.NonNull <T, V> List<T> getNotNullList() {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
@org.jspecify.annotations.Nullable <T, V> List<T> getNullableList() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@org.jspecify.annotations.NonNull String getNotNullName() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@org.jspecify.annotations.Nullable String getNullableName() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package org.example
|
||||
|
||||
import
|
||||
org . jspecify . annotations. NonNull;
|
||||
import org. jspecify . annotations.
|
||||
Nullable;
|
||||
import org . jspecify .
|
||||
annotations .*;
|
||||
|
||||
public class Formatter {
|
||||
@NonNull
|
||||
String getNotNullName() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Nullable
|
||||
String getNullableName() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package org.example
|
||||
|
||||
import org.jspecify.annotations.NonNull;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.jspecify.annotations.*;
|
||||
|
||||
public class Formatter {
|
||||
@NonNull String getNotNullName() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Nullable String getNullableName() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package org.example;
|
||||
|
||||
import module org.jspecify.annotations;
|
||||
|
||||
public class Formatter {
|
||||
@NonNull @Nullable String breakLineBetweenAnnotations() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@NonNull String breakLineBetweenTypeAndAnnotations() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable <T> String breakLineBetweenTypeParameterAndAnnotation() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@NonNull <T> String breakLineMixed() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package org.example;
|
||||
|
||||
import module org.jspecify.annotations;
|
||||
|
||||
public class Formatter {
|
||||
@NonNull
|
||||
@Nullable
|
||||
String breakLineBetweenAnnotations() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@NonNull
|
||||
String breakLineBetweenTypeAndAnnotations() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
<T> String breakLineBetweenTypeParameterAndAnnotation() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@NonNull
|
||||
<T> String breakLineMixed() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package org.example;
|
||||
|
||||
import module org.jetbrains.annotations;
|
||||
|
||||
public class Formatter {
|
||||
@NotNull
|
||||
@Nullable
|
||||
String breakLineBetweenAnnotations() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@NotNull String breakLineBetweenTypeAndAnnotations() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable <T> String breakLineBetweenTypeParameterAndAnnotation() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@NotNull
|
||||
<T> String breakLineMixed() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package org.example;
|
||||
|
||||
import module org.jetbrains.annotations;
|
||||
|
||||
public class Formatter {
|
||||
@NotNull @Nullable String breakLineBetweenAnnotations() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Nullable @NotNull String breakLineBetweenTypeAndAnnotations() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable <T> String breakLineBetweenTypeParameterAndAnnotation() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable @NotNull <T> String breakLineMixed() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,9 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.GeneratedSourcesFilter;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.testFramework.IdeaTestUtil;
|
||||
import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -38,6 +40,7 @@ public class AnnotateMethodInGeneratedFilesTest extends LightJavaCodeInsightFixt
|
||||
}
|
||||
|
||||
public void testAnnotateOverriddenMethod() {
|
||||
IdeaTestUtil.setModuleLanguageLevel(myFixture.getModule(), LanguageLevel.JDK_1_6);
|
||||
doTest("Annotate overriding methods");
|
||||
}
|
||||
|
||||
|
||||
@@ -14,12 +14,14 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.JavaModuleExternalPaths;
|
||||
import com.intellij.openapi.roots.ModuleRootModificationUtil;
|
||||
import com.intellij.openapi.vfs.VfsUtilCore;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.JavaPsiFacade;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleSettings;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.testFramework.IdeaTestUtil;
|
||||
import com.intellij.testFramework.UsefulTestCase;
|
||||
import com.intellij.testFramework.builders.JavaModuleFixtureBuilder;
|
||||
import com.intellij.testFramework.fixtures.*;
|
||||
@@ -70,6 +72,7 @@ public class ExternalAnnotationsTest extends UsefulTestCase {
|
||||
|
||||
public void testAddedAnnotationInCodeWhenAlreadyPresent() {
|
||||
myFixture.configureByFile("src/withAnnotation/Foo.java");
|
||||
IdeaTestUtil.setModuleLanguageLevel(myFixture.getModule(), LanguageLevel.JDK_1_8);
|
||||
PsiMethod method = PsiTreeUtil.getParentOfType(myFixture.getElementAtCaret(), PsiMethod.class, false);
|
||||
assertNotNull(method);
|
||||
ActionContext context = myFixture.getActionContext();
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.java.psi.formatter.java
|
||||
|
||||
import com.intellij.JavaTestUtil
|
||||
import com.intellij.application.options.CodeStyle
|
||||
import com.intellij.lang.java.JavaLanguage
|
||||
import com.intellij.openapi.command.WriteCommandAction
|
||||
import com.intellij.openapi.roots.ModuleRootModificationUtil
|
||||
import com.intellij.pom.java.LanguageLevel
|
||||
import com.intellij.psi.codeStyle.CodeStyleManager
|
||||
import com.intellij.psi.codeStyle.CommonCodeStyleSettings
|
||||
import com.intellij.psi.codeStyle.CommonCodeStyleSettings.WRAP_ALWAYS
|
||||
import com.intellij.testFramework.IdeaTestUtil
|
||||
import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase
|
||||
import com.intellij.testFramework.fixtures.MavenDependencyUtil
|
||||
|
||||
class JSpecifyTypeAnnotationFormatterTest : LightJavaCodeInsightFixtureTestCase() {
|
||||
private val commonSettings: CommonCodeStyleSettings
|
||||
get() = CodeStyle.getSettings(project).getCommonSettings(JavaLanguage.INSTANCE)
|
||||
|
||||
override fun getTestDataPath() = "${JavaTestUtil.getJavaTestDataPath()}/psi/formatter/java/jSpecifyTypeAnnotation/"
|
||||
|
||||
override fun setUp() {
|
||||
super.setUp()
|
||||
commonSettings.KEEP_LINE_BREAKS = false
|
||||
commonSettings.METHOD_ANNOTATION_WRAP = WRAP_ALWAYS
|
||||
IdeaTestUtil.setModuleLanguageLevel(myFixture.module, LanguageLevel.JDK_1_8)
|
||||
ModuleRootModificationUtil.updateModel(module) { model ->
|
||||
MavenDependencyUtil.addFromMaven(model, "org.jspecify:jspecify:1.0.0")
|
||||
}
|
||||
}
|
||||
|
||||
fun testKnownAnnotationBeforeType() = doTest()
|
||||
|
||||
fun testKnownAnnotationBeforeTypeParameterList() = doTest()
|
||||
|
||||
fun testCustomAnnotation() = doTest()
|
||||
|
||||
fun testManyKnownAnnotations() = doTest()
|
||||
|
||||
fun testPreserveWrappingSingleAnnotation() = doTest()
|
||||
|
||||
fun testPreserveWrappingManyAnnotations() = doTest()
|
||||
|
||||
fun testFullyQualifiedName() = doTest()
|
||||
|
||||
fun testImportOnDemand() = doTest()
|
||||
|
||||
fun testImportMix() = doTest()
|
||||
|
||||
fun testSpacesInImportList() = doTest()
|
||||
|
||||
fun testSpacesInFqnAnnotations() = doTest()
|
||||
|
||||
fun testKeepLineBreaks() {
|
||||
commonSettings.KEEP_LINE_BREAKS = true
|
||||
doTest()
|
||||
}
|
||||
|
||||
fun testLowLanguageLevel() {
|
||||
IdeaTestUtil.setModuleLanguageLevel(myFixture.module, LanguageLevel.JDK_1_7)
|
||||
doTest()
|
||||
}
|
||||
|
||||
fun testModuleImport() {
|
||||
IdeaTestUtil.setModuleLanguageLevel(myFixture.module, LanguageLevel.JDK_25)
|
||||
doTest()
|
||||
}
|
||||
|
||||
fun testModuleImportWithSpaces() {
|
||||
IdeaTestUtil.setModuleLanguageLevel(myFixture.module, LanguageLevel.JDK_25)
|
||||
doTest()
|
||||
}
|
||||
|
||||
fun testModuleImportMixedWithPackageImport() {
|
||||
IdeaTestUtil.setModuleLanguageLevel(myFixture.module, LanguageLevel.JDK_25)
|
||||
doTest()
|
||||
}
|
||||
|
||||
fun testModuleImportMixedWithFqn() {
|
||||
IdeaTestUtil.setModuleLanguageLevel(myFixture.module, LanguageLevel.JDK_25)
|
||||
doTest()
|
||||
}
|
||||
|
||||
|
||||
fun testLowLanguageLevelForModuleImport() {
|
||||
IdeaTestUtil.setModuleLanguageLevel(myFixture.module, LanguageLevel.JDK_24)
|
||||
doTest()
|
||||
}
|
||||
|
||||
fun testUnknownModuleImport() {
|
||||
IdeaTestUtil.setModuleLanguageLevel(myFixture.module, LanguageLevel.JDK_25)
|
||||
doTest()
|
||||
}
|
||||
|
||||
private fun doTest() {
|
||||
val testName = getTestName(false)
|
||||
myFixture.configureByFile("$testName.java")
|
||||
WriteCommandAction.runWriteCommandAction(project) { CodeStyleManager.getInstance(project).reformatText(file, 0, editor.document.textLength) }
|
||||
myFixture.checkResultByFile("${testName}_after.java")
|
||||
}
|
||||
}
|
||||
@@ -24,7 +24,7 @@ class TypeAnnotationFormatterTest : LightJavaCodeInsightFixtureTestCase() {
|
||||
super.setUp()
|
||||
commonSettings.KEEP_LINE_BREAKS = false
|
||||
commonSettings.METHOD_ANNOTATION_WRAP = WRAP_ALWAYS
|
||||
IdeaTestUtil.setProjectLanguageLevel(myFixture.project, LanguageLevel.JDK_1_8)
|
||||
IdeaTestUtil.setModuleLanguageLevel(myFixture.module, LanguageLevel.JDK_1_8)
|
||||
ModuleRootModificationUtil.updateModel(module, DefaultLightProjectDescriptor::addJetBrainsAnnotations)
|
||||
}
|
||||
|
||||
@@ -56,7 +56,12 @@ class TypeAnnotationFormatterTest : LightJavaCodeInsightFixtureTestCase() {
|
||||
}
|
||||
|
||||
fun testLowLanguageLevel() {
|
||||
IdeaTestUtil.setProjectLanguageLevel(myFixture.project, LanguageLevel.JDK_1_7)
|
||||
IdeaTestUtil.setModuleLanguageLevel(myFixture.module, LanguageLevel.JDK_1_7)
|
||||
doTest()
|
||||
}
|
||||
|
||||
fun testModuleImport() {
|
||||
IdeaTestUtil.setModuleLanguageLevel(myFixture.module, LanguageLevel.JDK_25)
|
||||
doTest()
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user