From 072396cc0a2e6e4cd2ee97e86e5b795166c01949 Mon Sep 17 00:00:00 2001 From: Georgii Ustinov Date: Fri, 5 Jul 2024 14:23:17 +0300 Subject: [PATCH] [Java. Code Formatting] Merge TypeAnnotationUtil and AnnotationUtil into JavaFormatterAnnotationUtil IDEA-110857 GitOrigin-RevId: f87b5eea44a81706d7887b3c4170373c8554e066 --- .../arrangement/JavaArrangementVisitor.java | 4 +- .../psi/formatter/java/AnnotationUtil.kt | 24 -------- ...Util.kt => JavaFormatterAnnotationUtil.kt} | 55 +++++++++++++------ .../psi/formatter/java/JavaFormatterUtil.java | 2 +- .../java/JavaSpacePropertyProcessor.java | 2 +- 5 files changed, 41 insertions(+), 46 deletions(-) delete mode 100644 java/java-impl/src/com/intellij/psi/formatter/java/AnnotationUtil.kt rename java/java-impl/src/com/intellij/psi/formatter/java/{TypeAnnotationUtil.kt => JavaFormatterAnnotationUtil.kt} (59%) diff --git a/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaArrangementVisitor.java b/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaArrangementVisitor.java index 44e0617b1bae..5f488d055a26 100644 --- a/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaArrangementVisitor.java +++ b/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaArrangementVisitor.java @@ -7,7 +7,7 @@ import com.intellij.psi.*; import com.intellij.psi.codeStyle.arrangement.group.ArrangementGroupingRule; import com.intellij.psi.codeStyle.arrangement.std.ArrangementSettingsToken; import com.intellij.psi.codeStyle.arrangement.std.StdArrangementTokens; -import com.intellij.psi.formatter.java.AnnotationUtil; +import com.intellij.psi.formatter.java.JavaFormatterAnnotationUtil; import com.intellij.psi.search.searches.SuperMethodsSearch; import com.intellij.psi.util.MethodSignatureBackedByPsiMethod; import com.intellij.psi.util.PropertyUtilBase; @@ -544,7 +544,7 @@ public class JavaArrangementVisitor extends JavaRecursiveElementVisitor { } private static void parseModifierListOwner(@NotNull PsiModifierListOwner modifierListOwner, @NotNull JavaElementArrangementEntry entry) { - if (AnnotationUtil.isFieldWithAnnotations(modifierListOwner)) { + if (JavaFormatterAnnotationUtil.isFieldWithAnnotations(modifierListOwner)) { entry.setHasAnnotation(); } diff --git a/java/java-impl/src/com/intellij/psi/formatter/java/AnnotationUtil.kt b/java/java-impl/src/com/intellij/psi/formatter/java/AnnotationUtil.kt deleted file mode 100644 index 3dea530a5f63..000000000000 --- a/java/java-impl/src/com/intellij/psi/formatter/java/AnnotationUtil.kt +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2000-2024 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.lang.ASTNode -import com.intellij.lang.tree.util.children -import com.intellij.psi.PsiModifierListOwner -import com.intellij.psi.impl.source.tree.JavaElementType - -object AnnotationUtil { - @JvmStatic - fun isFieldWithAnnotations(node: ASTNode): Boolean { - if (node.elementType !== JavaElementType.FIELD) return false - - val modifierList = node.firstChildNode ?: return false - if (modifierList.elementType != JavaElementType.MODIFIER_LIST) return false - val annotations = modifierList.children().takeWhile { it.elementType == JavaElementType.ANNOTATION } - return annotations.any { !TypeAnnotationUtil.isTypeAnnotation(it) } - } - - @JvmStatic - fun isFieldWithAnnotations(field: PsiModifierListOwner): Boolean { - return isFieldWithAnnotations(field.node) - } -} \ No newline at end of file diff --git a/java/java-impl/src/com/intellij/psi/formatter/java/TypeAnnotationUtil.kt b/java/java-impl/src/com/intellij/psi/formatter/java/JavaFormatterAnnotationUtil.kt similarity index 59% rename from java/java-impl/src/com/intellij/psi/formatter/java/TypeAnnotationUtil.kt rename to java/java-impl/src/com/intellij/psi/formatter/java/JavaFormatterAnnotationUtil.kt index 60d40f1cbb53..5ecd09c8cf59 100644 --- a/java/java-impl/src/com/intellij/psi/formatter/java/TypeAnnotationUtil.kt +++ b/java/java-impl/src/com/intellij/psi/formatter/java/JavaFormatterAnnotationUtil.kt @@ -2,24 +2,18 @@ package com.intellij.psi.formatter.java import com.intellij.lang.ASTNode +import com.intellij.lang.tree.util.children import com.intellij.openapi.roots.LanguageLevelProjectExtension import com.intellij.openapi.util.text.StringUtil import com.intellij.pom.java.LanguageLevel import com.intellij.psi.* -import com.intellij.psi.formatter.java.TypeAnnotationUtil.KNOWN_TYPE_ANNOTATIONS -import com.intellij.psi.formatter.java.TypeAnnotationUtil.isTypeAnnotation +import com.intellij.psi.impl.source.tree.JavaElementType import com.intellij.psi.util.CachedValueProvider import com.intellij.psi.util.CachedValuesManager import com.intellij.psi.util.PsiModificationTracker import com.intellij.psi.util.PsiTreeUtil -/** - * This class was designed to handle detection of type annotation during building blocks phase of Java formatter. - * As there is no resolving available, it relies on local import table and known type annotations. - * @see KNOWN_TYPE_ANNOTATIONS - * @see isTypeAnnotation - */ -internal object TypeAnnotationUtil { +internal object JavaFormatterAnnotationUtil { private val KNOWN_TYPE_ANNOTATIONS: Set = setOf( "org.jetbrains.annotations.NotNull", "org.jetbrains.annotations.Nullable" @@ -27,7 +21,8 @@ internal object TypeAnnotationUtil { /** * Checks if the given ASTNode represents a type annotation. - * + * This method was designed to handle detection of type annotation during building blocks phase of Java formatter. + * As there is no resolving available, it relies on local import table and known type annotations. * @param annotation the ASTNode to check if it is a type annotation or not. * @return true if the ASTNode represents a type annotation, false otherwise */ @@ -40,7 +35,7 @@ internal object TypeAnnotationUtil { val next = PsiTreeUtil.skipSiblingsForward(node, PsiWhiteSpace::class.java, PsiAnnotation::class.java) if (next is PsiKeyword) return false - + val psiReference: PsiJavaCodeReferenceElement = node.nameReferenceElement ?: return false if (psiReference.isQualified) { return KNOWN_TYPE_ANNOTATIONS.contains(getCanonicalTextOfTheReference(psiReference)) @@ -53,13 +48,37 @@ internal object TypeAnnotationUtil { } } - private fun getImportedTypeAnnotations(file : PsiJavaFile): Set = CachedValuesManager.getCachedValue(file) { - val importList = file.importList ?: return@getCachedValue CachedValueProvider.Result(emptySet(), PsiModificationTracker.MODIFICATION_COUNT) - val filteredAnnotations = KNOWN_TYPE_ANNOTATIONS.filter { isAnnotationInImportList(it, importList) } - .mapNotNull { fqn -> fqn.split(".").lastOrNull() } - .toSet() - CachedValueProvider.Result.create(filteredAnnotations, PsiModificationTracker.MODIFICATION_COUNT) - } + /** + * Determines if the given ASTNode represents a Java field with at least one field annotation. + * @param node the ASTNode to be checked. + * @return true if the ASTNode represents a field and it has at least one field annotation, false otherwise. + */ + @JvmStatic + fun isFieldWithAnnotations(node: ASTNode): Boolean { + if (node.elementType !== JavaElementType.FIELD) return false + + val modifierList = node.firstChildNode ?: return false + if (modifierList.elementType != JavaElementType.MODIFIER_LIST) return false + val annotations = modifierList.children().takeWhile { it.elementType == JavaElementType.ANNOTATION } + return annotations.any { !isTypeAnnotation(it) } + } + + /** + * See [isFieldWithAnnotations] + */ + @JvmStatic + fun isFieldWithAnnotations(field: PsiModifierListOwner): Boolean { + return isFieldWithAnnotations(field.node) + } + + private fun getImportedTypeAnnotations(file: PsiJavaFile): Set = CachedValuesManager.getCachedValue(file) { + val importList = file.importList + ?: return@getCachedValue CachedValueProvider.Result(emptySet(), PsiModificationTracker.MODIFICATION_COUNT) + val filteredAnnotations = KNOWN_TYPE_ANNOTATIONS.filter { isAnnotationInImportList(it, importList) } + .mapNotNull { fqn -> fqn.split(".").lastOrNull() } + .toSet() + CachedValueProvider.Result.create(filteredAnnotations, PsiModificationTracker.MODIFICATION_COUNT) + } private fun isAnnotationInImportList(annotationFqn: String, importList: PsiImportList): Boolean { val packageName = StringUtil.getPackageName(annotationFqn) diff --git a/java/java-impl/src/com/intellij/psi/formatter/java/JavaFormatterUtil.java b/java/java-impl/src/com/intellij/psi/formatter/java/JavaFormatterUtil.java index dea2370ea391..e12d89d787e2 100644 --- a/java/java-impl/src/com/intellij/psi/formatter/java/JavaFormatterUtil.java +++ b/java/java-impl/src/com/intellij/psi/formatter/java/JavaFormatterUtil.java @@ -29,7 +29,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -import static com.intellij.psi.formatter.java.TypeAnnotationUtil.isTypeAnnotation; +import static com.intellij.psi.formatter.java.JavaFormatterAnnotationUtil.isTypeAnnotation; public final class JavaFormatterUtil { /** diff --git a/java/java-impl/src/com/intellij/psi/formatter/java/JavaSpacePropertyProcessor.java b/java/java-impl/src/com/intellij/psi/formatter/java/JavaSpacePropertyProcessor.java index e881cd969153..b54906e3a8da 100644 --- a/java/java-impl/src/com/intellij/psi/formatter/java/JavaSpacePropertyProcessor.java +++ b/java/java-impl/src/com/intellij/psi/formatter/java/JavaSpacePropertyProcessor.java @@ -644,7 +644,7 @@ public final class JavaSpacePropertyProcessor extends JavaElementVisitor { private int getLinesAroundField() { boolean isParentAClass = isClass(myParent); - if (isParentAClass && AnnotationUtil.isFieldWithAnnotations(myChild2)) { + if (isParentAClass && JavaFormatterAnnotationUtil.isFieldWithAnnotations(myChild2)) { return myJavaSettings.BLANK_LINES_AROUND_FIELD_WITH_ANNOTATIONS; } else if (isParentAClass) { return mySettings.BLANK_LINES_AROUND_FIELD;