From 636f753d46e67420ff1309a31e5ed2781e1c9fe5 Mon Sep 17 00:00:00 2001 From: Mikhail Pyltsin Date: Fri, 14 Nov 2025 15:29:32 +0100 Subject: [PATCH] [java] IDEA-365317 simplify using PsiElements instead of AstNodes GitOrigin-RevId: 3002271840e99b5952bca6f6e5d1d98472848b5e --- .../JavaEnterAfterUnmatchedBraceHandler.java | 23 +- .../JavaEnterInTextBlockHandler.java | 25 +- .../editorActions/JavaQuoteHandler.java | 35 +- .../editorActions/JavaTypedHandlerBase.java | 87 +- .../JavadocLineStartHandler.java | 36 +- .../editorActions/JavadocTypedHandler.java | 29 +- .../moveUpDown/JavaCaseBlockMover.java | 7 +- .../moveUpDown/JavaCatchBlockMover.java | 2 +- .../moveUpDown/JavaDeclarationMover.java | 2 +- .../smartEnter/ASTNodeEnterProcessor.java | 22 - .../AbstractBasicJavaSmartEnterProcessor.java | 396 ---------- .../AbstractBasicSemicolonFixer.java | 173 ---- .../AfterSemicolonEnterProcessor.java | 81 +- .../smartEnter/BlockBraceFixer.java | 30 +- .../smartEnter/CatchDeclarationFixer.java | 25 +- .../CommentBreakerEnterProcessor.java | 26 +- .../smartEnter/DoWhileConditionFixer.java | 34 +- .../smartEnter/EnumFieldFixer.java | 12 +- .../editorActions/smartEnter/Fixer.java | 4 +- .../smartEnter/ForStatementFixer.java | 57 +- .../smartEnter/IfConditionFixer.java | 52 +- .../smartEnter/JavaSmartEnterProcessor.java | 386 +++++++-- .../LeaveCodeBlockEnterProcessor.java | 39 +- .../smartEnter/LiteralFixer.java | 22 +- .../smartEnter/MethodCallFixer.java | 5 +- .../MissingArrayConstructorBracketFixer.java | 20 +- .../MissingArrayInitializerBraceFixer.java | 42 +- .../smartEnter/MissingCatchBodyFixer.java | 24 +- .../smartEnter/MissingClassBodyFixer.java | 38 +- .../smartEnter/MissingCommaFixer.java | 6 +- .../smartEnter/MissingIfBranchesFixer.java | 38 +- .../smartEnter/MissingLambdaBodyFixer.java | 41 +- .../smartEnter/MissingLoopBodyFixer.java | 143 ++-- .../smartEnter/MissingMethodBodyFixer.java | 80 +- .../MissingReturnExpressionFixer.java | 61 +- .../smartEnter/MissingSwitchBodyFixer.java | 22 +- .../MissingSynchronizedBodyFixer.java | 17 +- .../MissingThrowExpressionFixer.java | 26 +- .../smartEnter/MissingTryBodyFixer.java | 18 +- .../smartEnter/ParameterListFixer.java | 23 +- .../smartEnter/ParenthesizedFixer.java | 15 +- .../smartEnter/PlainEnterProcessor.java | 81 +- .../smartEnter/SemicolonFixer.java | 147 +++- .../smartEnter/SwitchExpressionFixer.java | 30 +- .../smartEnter/SwitchLabelColonFixer.java | 6 +- .../smartEnter/TernaryColonFixer.java | 16 +- .../smartEnter/WhileConditionFixer.java | 32 +- .../AbstractBasicBackBasicSelectioner.java | 45 -- .../AntLikePropertySelectionHandler.java | 6 - .../wordSelection/BasicSelectioner.java | 38 + .../CaseStatementsSelectioner.java | 80 +- .../CodeBlockOrInitializerSelectioner.java | 68 +- .../wordSelection/DocCommentSelectioner.java | 33 +- .../wordSelection/DocTagSelectioner.java | 37 +- .../wordSelection/FieldSelectioner.java | 36 +- .../FinallyBlockSelectioner.java | 24 +- .../ForStatementHeaderSelectioner.java | 24 +- .../wordSelection/IfStatementSelectioner.java | 34 +- .../JavaBasicWordSelectionFilter.java | 30 +- .../wordSelection/JavaTokenSelectioner.java | 23 +- .../wordSelection/JavaWordSelectioner.java | 22 +- .../wordSelection/ListSelectioner.java | 32 +- .../wordSelection/LiteralSelectioner.java | 2 +- .../wordSelection/MethodCallSelectioner.java | 23 +- .../MethodOrClassSelectioner.java | 74 +- .../wordSelection/ReferenceSelectioner.java | 56 +- .../StatementGroupSelectioner.java | 67 +- .../wordSelection/TypeCastSelectioner.java | 25 +- .../highlighting/JavaBraceMatcher.java | 47 +- .../highlighting/JavaPairedBraceMatcher.java | 22 +- .../com/intellij/javadoc/JavadocHelper.java | 52 +- .../JavaFormatterConditionalExpressionUtil.kt | 25 +- .../psi/impl/source/BasicJavaAstTreeUtil.java | 746 ------------------ .../source/WhiteSpaceAndCommentSetHolder.java | 14 +- .../AbstractBasicJavaTypingTest.java | 1 + .../editorActions/smartEnter/XmlTagFixer.java | 4 +- .../wordSelection/BasicSelectioner.java | 5 - .../wordSelection/VarargsSelectioner.java | 2 +- 78 files changed, 1452 insertions(+), 2781 deletions(-) delete mode 100644 java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/ASTNodeEnterProcessor.java delete mode 100644 java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/AbstractBasicJavaSmartEnterProcessor.java delete mode 100644 java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/AbstractBasicSemicolonFixer.java delete mode 100644 java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/AbstractBasicBackBasicSelectioner.java create mode 100644 java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/BasicSelectioner.java delete mode 100644 java/java-impl/src/com/intellij/codeInsight/editorActions/wordSelection/BasicSelectioner.java diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/JavaEnterAfterUnmatchedBraceHandler.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/JavaEnterAfterUnmatchedBraceHandler.java index af2a0eee9526..02b8fa48e955 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/JavaEnterAfterUnmatchedBraceHandler.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/JavaEnterAfterUnmatchedBraceHandler.java @@ -3,17 +3,9 @@ package com.intellij.codeInsight.editorActions; import com.intellij.codeInsight.editorActions.enter.EnterAfterUnmatchedBraceHandler; import com.intellij.core.JavaPsiBundle; -import com.intellij.lang.ASTNode; -import com.intellij.psi.AbstractBasicJavaFile; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiErrorElement; -import com.intellij.psi.PsiFile; -import com.intellij.psi.impl.source.BasicJavaAstTreeUtil; +import com.intellij.psi.*; import org.jetbrains.annotations.NotNull; -import static com.intellij.psi.impl.source.BasicJavaElementType.BASIC_EXPRESSION_LIST_STATEMENT; -import static com.intellij.psi.impl.source.BasicJavaElementType.EXPRESSION_SET; - public final class JavaEnterAfterUnmatchedBraceHandler extends EnterAfterUnmatchedBraceHandler { private JavaEnterAfterUnmatchedBraceHandler() { @@ -30,14 +22,11 @@ public final class JavaEnterAfterUnmatchedBraceHandler extends EnterAfterUnmatch ((PsiErrorElement)element).getErrorDescription().equals(JavaPsiBundle.message("else.without.if"))) { return element.getTextRange().getStartOffset(); } - ASTNode node = BasicJavaAstTreeUtil.toNode(element); - if (BasicJavaAstTreeUtil.is(node, BASIC_EXPRESSION_LIST_STATEMENT)) { - final ASTNode list = BasicJavaAstTreeUtil.getExpressionList(node); - if (list != null) { - final ASTNode firstExpression = BasicJavaAstTreeUtil.findChildByType(list, EXPRESSION_SET); - if (firstExpression != null) { - return firstExpression.getTextRange().getEndOffset(); - } + if (element instanceof PsiExpressionListStatement) { + final PsiExpressionList list = ((PsiExpressionListStatement)element).getExpressionList(); + final PsiExpression[] expressions = list.getExpressions(); + if (expressions.length > 1) { + return expressions[0].getTextRange().getEndOffset(); } } return super.calculateOffsetToInsertClosingBraceInsideElement(element); diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/JavaEnterInTextBlockHandler.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/JavaEnterInTextBlockHandler.java index aaf5dce33f34..91fbca300625 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/JavaEnterInTextBlockHandler.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/JavaEnterInTextBlockHandler.java @@ -9,18 +9,13 @@ import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.actionSystem.EditorActionHandler; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Ref; -import com.intellij.psi.JavaTokenType; -import com.intellij.psi.PsiDocumentManager; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiFile; +import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleManager; -import com.intellij.psi.impl.source.BasicJavaAstTreeUtil; +import com.intellij.util.ObjectUtils; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import static com.intellij.psi.impl.source.BasicJavaElementType.BASIC_LITERAL_EXPRESSION; - public final class JavaEnterInTextBlockHandler extends EnterInStringLiteralHandler { @Override @@ -31,7 +26,7 @@ public final class JavaEnterInTextBlockHandler extends EnterInStringLiteralHandl @NotNull DataContext dataContext, EditorActionHandler originalHandler) { int offset = editor.getCaretModel().getOffset(); - PsiElement textBlock = getTextBlockAt(file, offset); + PsiLiteralExpression textBlock = getTextBlockAt(file, offset); if (textBlock == null) return Result.Continue; int textBlockOffset = textBlock.getTextOffset(); String text = textBlock.getText(); @@ -62,15 +57,11 @@ public final class JavaEnterInTextBlockHandler extends EnterInStringLiteralHandl } @Contract("null, _ -> null") - private static PsiElement getTextBlockAt(PsiFile file, int offset) { - if (!isJavaFile(file)) return null; - PsiElement token = file.findElementAt(offset); - if (token == null || token.getNode() == null || !BasicJavaAstTreeUtil.is(token.getNode(), JavaTokenType.TEXT_BLOCK_LITERAL)) return null; - PsiElement parent = token.getParent(); - if (!BasicJavaAstTreeUtil.is(BasicJavaAstTreeUtil.toNode(parent), BASIC_LITERAL_EXPRESSION)) { - return null; - } - return parent; + private static PsiLiteralExpression getTextBlockAt(PsiFile file, int offset) { + if (!(file instanceof AbstractBasicJavaFile)) return null; + PsiJavaToken token = ObjectUtils.tryCast(file.findElementAt(offset), PsiJavaToken.class); + if (token == null || token.getTokenType() != JavaTokenType.TEXT_BLOCK_LITERAL) return null; + return ObjectUtils.tryCast(token.getParent(), PsiLiteralExpression.class); } private static boolean isJavaFile(@Nullable PsiFile file) { diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/JavaQuoteHandler.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/JavaQuoteHandler.java index 52741669ad84..92977e233dd8 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/JavaQuoteHandler.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/JavaQuoteHandler.java @@ -10,28 +10,24 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.pom.java.JavaFeature; import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleManager; -import com.intellij.psi.impl.source.BasicJavaAstTreeUtil; +import com.intellij.psi.impl.source.tree.ElementType; import com.intellij.psi.tree.IElementType; -import com.intellij.psi.tree.ParentAwareTokenSet; import com.intellij.psi.tree.TokenSet; +import com.intellij.util.ObjectUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import static com.intellij.psi.impl.source.BasicElementTypes.BASIC_JAVA_COMMENT_OR_WHITESPACE_BIT_SET; -import static com.intellij.psi.impl.source.BasicElementTypes.BASIC_TEXT_LITERALS; -import static com.intellij.psi.impl.source.BasicJavaElementType.BASIC_LITERAL_EXPRESSION; -import static com.intellij.psi.impl.source.BasicJavaElementType.REFERENCE_EXPRESSION_SET; +import static com.intellij.psi.impl.source.tree.ElementType.TEXT_LITERALS; public class JavaQuoteHandler extends SimpleTokenSetQuoteHandler implements JavaLikeQuoteHandler, MultiCharQuoteHandler { private final TokenSet myConcatenableStrings = TokenSet.create(JavaTokenType.STRING_LITERAL); - private final ParentAwareTokenSet myAppropriateElementTypeForLiteral = ParentAwareTokenSet.orSet( - ParentAwareTokenSet.create(JavaDocTokenType.ALL_JAVADOC_TOKENS), - BASIC_JAVA_COMMENT_OR_WHITESPACE_BIT_SET, ParentAwareTokenSet.create(BASIC_TEXT_LITERALS), - ParentAwareTokenSet.create(JavaTokenType.SEMICOLON, JavaTokenType.COMMA, JavaTokenType.RPARENTH, JavaTokenType.RBRACKET, - JavaTokenType.RBRACE)); + private final TokenSet myAppropriateElementTypeForLiteral = TokenSet.orSet( + JavaDocTokenType.ALL_JAVADOC_TOKENS, + ElementType.JAVA_COMMENT_OR_WHITESPACE_BIT_SET, TEXT_LITERALS, + TokenSet.create(JavaTokenType.SEMICOLON, JavaTokenType.COMMA, JavaTokenType.RPARENTH, JavaTokenType.RBRACKET, JavaTokenType.RBRACE)); public JavaQuoteHandler() { - super(TokenSet.orSet(BASIC_TEXT_LITERALS, TokenSet.create(JavaDocTokenType.DOC_TAG_VALUE_QUOTE, JavaDocTokenType.DOC_INLINE_CODE_FENCE, JavaDocTokenType.DOC_CODE_FENCE))); + super(TokenSet.orSet(TEXT_LITERALS, TokenSet.create(JavaDocTokenType.DOC_TAG_VALUE_QUOTE, JavaDocTokenType.DOC_INLINE_CODE_FENCE, JavaDocTokenType.DOC_CODE_FENCE))); } @Override @@ -93,9 +89,7 @@ public class JavaQuoteHandler extends SimpleTokenSetQuoteHandler implements Java @Override public boolean needParenthesesAroundConcatenation(PsiElement element) { // example code: "some string".length() must become ("some" + " string").length() - return element != null && element.getParent() != null && element.getParent().getParent() != null && - BasicJavaAstTreeUtil.is(element.getParent().getNode(), BASIC_LITERAL_EXPRESSION) && - BasicJavaAstTreeUtil.is(element.getParent().getParent().getNode(), REFERENCE_EXPRESSION_SET); + return element.getParent() instanceof PsiLiteralExpression && element.getParent().getParent() instanceof PsiReferenceExpression; } @Override @@ -133,12 +127,11 @@ public class JavaQuoteHandler extends SimpleTokenSetQuoteHandler implements Java editor.getDocument().insertString(offset, "\n\"\"\""); Project project = file.getProject(); PsiDocumentManager.getInstance(project).commitDocument(editor.getDocument()); - PsiElement token = file.findElementAt(offset); + PsiJavaToken token = ObjectUtils.tryCast(file.findElementAt(offset), PsiJavaToken.class); if (token == null) return; - PsiElement parent = token.getParent(); - if (parent != null && BasicJavaAstTreeUtil.is(parent.getNode(), BASIC_LITERAL_EXPRESSION)) { - CodeStyleManager.getInstance(project).reformat(parent); - editor.getCaretModel().moveToOffset(parent.getTextRange().getEndOffset() - 3); - } + PsiLiteralExpression textBlock = ObjectUtils.tryCast(token.getParent(), PsiLiteralExpression.class); + if (textBlock == null) return; + CodeStyleManager.getInstance(project).reformat(textBlock); + editor.getCaretModel().moveToOffset(textBlock.getTextRange().getEndOffset() - 3); } } \ No newline at end of file diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/JavaTypedHandlerBase.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/JavaTypedHandlerBase.java index fd5f789a0e13..3d76ebfd437a 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/JavaTypedHandlerBase.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/JavaTypedHandlerBase.java @@ -5,7 +5,6 @@ import com.intellij.codeInsight.CodeInsightSettings; import com.intellij.codeInsight.editorActions.smartEnter.JavaSmartEnterProcessor; import com.intellij.core.JavaPsiBundle; import com.intellij.ide.highlighter.JavaFileType; -import com.intellij.lang.ASTNode; import com.intellij.lang.xml.XMLLanguage; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.command.CommandProcessor; @@ -20,19 +19,13 @@ import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleManager; -import com.intellij.psi.impl.source.BasicJavaAstTreeUtil; import com.intellij.psi.tree.IElementType; -import com.intellij.psi.tree.ParentAwareTokenSet; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; import com.intellij.util.text.CharArrayUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.Set; - -import static com.intellij.psi.impl.source.BasicJavaElementType.*; - public class JavaTypedHandlerBase extends TypedHandlerDelegate { private boolean myJavaLTTyped; @@ -41,7 +34,7 @@ public class JavaTypedHandlerBase extends TypedHandlerDelegate { } private static boolean isJavaFile(@NotNull PsiFile file) { - return file instanceof PsiJavaFile; + return file instanceof AbstractBasicJavaFile; } private static boolean isJspFile(@NotNull PsiFile file) { @@ -182,17 +175,13 @@ public class JavaTypedHandlerBase extends TypedHandlerDelegate { } PsiDocumentManager.getInstance(project).commitDocument(doc); final PsiElement leaf = file.findElementAt(offset); - if (BasicJavaAstTreeUtil.getParentOfType(leaf, BASIC_ARRAY_INITIALIZER_EXPRESSION, false, - ParentAwareTokenSet.orSet(ParentAwareTokenSet.create(BASIC_CODE_BLOCK), MEMBER_SET)) != - null) { + if (PsiTreeUtil.getParentOfType(leaf, PsiArrayInitializerExpression.class, false, PsiCodeBlock.class, PsiMember.class) != null) { return Result.CONTINUE; } PsiElement st = leaf != null ? leaf.getParent() : null; PsiElement prev = offset > 1 ? file.findElementAt(offset - 1) : null; if (CodeInsightSettings.getInstance().AUTOINSERT_PAIR_BRACKET && isRparenth(leaf) && - st != null && - (BasicJavaAstTreeUtil.is(st.getNode(), BASIC_WHILE_STATEMENT) || - BasicJavaAstTreeUtil.is(st.getNode(), BASIC_IF_STATEMENT)) && + (st instanceof PsiWhileStatement || st instanceof PsiIfStatement) && shouldInsertStatementBody(st, doc, prev)) { return processWhileAndIfStatementBody(project, editor, file); } @@ -203,7 +192,7 @@ public class JavaTypedHandlerBase extends TypedHandlerDelegate { if (stop != null) return stop; } - if (BasicJavaAstTreeUtil.getParentOfType(leaf, BASIC_CODE_BLOCK, false, MEMBER_SET) != null && + if (PsiTreeUtil.getParentOfType(leaf, PsiCodeBlock.class, false, PsiMember.class) != null && !shouldInsertPairedBrace(leaf)) { EditorModificationUtilEx.insertStringAtCaret(editor, "{"); TypedHandler.indentOpenedBrace(project, editor); @@ -218,15 +207,15 @@ public class JavaTypedHandlerBase extends TypedHandlerDelegate { @NotNull Editor editor, @NotNull PsiFile file, @NotNull PsiElement leaf) { - ASTNode rule = BasicJavaAstTreeUtil.getParentOfType(leaf.getNode(), BASIC_SWITCH_LABELED_RULE); + PsiElement rule = PsiTreeUtil.getParentOfType(leaf, PsiSwitchLabeledRuleStatement.class); if(rule != null) { while (true) { - ASTNode next = rule.getTreeNext(); - if (next.getElementType() == TokenType.WHITE_SPACE) { - next = next.getTreeNext(); + PsiElement next = rule.getNextSibling(); + if (next instanceof PsiWhiteSpace) { + next = next.getNextSibling(); } - if(BasicJavaAstTreeUtil.is(next, BASIC_THROW_STATEMENT) || - BasicJavaAstTreeUtil.is(next, BASIC_EXPRESSION_STATEMENT)) { + if(next instanceof PsiThrowStatement || + next instanceof PsiExpressionStatement) { rule = next; continue; } @@ -272,11 +261,13 @@ public class JavaTypedHandlerBase extends TypedHandlerDelegate { if (prevLeaf.getNode().getElementType() != JavaTokenType.ARROW) return false; PsiElement parent = prevLeaf.getParent(); if (parent == null) return false; - if (!BasicJavaAstTreeUtil.is(parent.getNode().getElementType(), BASIC_SWITCH_LABELED_RULE)) return false; + if (!(parent instanceof PsiSwitchLabeledRuleStatement)) return false; if (StringUtil.isEmptyOrSpaces(leaf.getText())) { leaf = PsiTreeUtil.nextVisibleLeaf(leaf); } - PsiElement body = BasicJavaAstTreeUtil.getParentOfType(leaf, Set.of(BASIC_EXPRESSION_STATEMENT, BASIC_THROW_STATEMENT), false); + PsiElement body = + leaf instanceof PsiExpressionStatement || leaf instanceof PsiThrowStatement ? leaf : + PsiTreeUtil.getParentOfType(leaf, PsiExpressionStatement.class, PsiThrowStatement.class); if (body == null) return false; return PsiTreeUtil.isAncestor(parent, body, false); } @@ -286,39 +277,20 @@ public class JavaTypedHandlerBase extends TypedHandlerDelegate { // lambda if (prevLeaf != null && prevLeaf.getNode().getElementType() == JavaTokenType.ARROW) return true; // anonymous class - ParentAwareTokenSet stopAt = ParentAwareTokenSet.orSet(MEMBER_SET, ParentAwareTokenSet.create(BASIC_CODE_BLOCK)); - if (BasicJavaAstTreeUtil.getParentOfType(prevLeaf, BASIC_NEW_EXPRESSION, true, stopAt) != null) return true; + if (PsiTreeUtil.getParentOfType(prevLeaf, PsiNewExpression.class, true, PsiCodeBlock.class, PsiMember.class) != null) return true; // local class - if (prevLeaf != null && prevLeaf.getParent() != null && BasicJavaAstTreeUtil.is(prevLeaf.getNode(), JavaTokenType.IDENTIFIER) && - BasicJavaAstTreeUtil.is(prevLeaf.getParent().getNode(), CLASS_SET)) { - return true; - } + if (prevLeaf instanceof PsiIdentifier && prevLeaf.getParent() instanceof PsiClass) return true; // local record - if (prevLeaf != null && prevLeaf.getParent() != null && prevLeaf.getNode().getElementType() == JavaTokenType.RPARENTH && - BasicJavaAstTreeUtil.is(prevLeaf.getParent().getNode(), BASIC_RECORD_HEADER)) { - return true; - } + if (PsiUtil.isJavaToken(prevLeaf, JavaTokenType.RPARENTH) && prevLeaf.getParent() instanceof PsiRecordHeader) return true; return false; } private static boolean shouldInsertStatementBody(@NotNull PsiElement statement, @NotNull Document doc, @Nullable PsiElement prev) { - - ASTNode block; - ASTNode astNodeStatement = statement.getNode(); - if (BasicJavaAstTreeUtil.is(astNodeStatement, BASIC_WHILE_STATEMENT)) { - block = BasicJavaAstTreeUtil.getBlock(astNodeStatement); - } - else { - block = BasicJavaAstTreeUtil.getThenBranch(astNodeStatement); - } - ASTNode condition = BasicJavaAstTreeUtil.findChildByType(astNodeStatement, EXPRESSION_SET); - ASTNode latestExpression = BasicJavaAstTreeUtil.getParentOfType(BasicJavaAstTreeUtil.toNode(prev), EXPRESSION_SET); - if (BasicJavaAstTreeUtil.is(latestExpression, BASIC_NEW_EXPRESSION) && - BasicJavaAstTreeUtil.getAnonymousClass(latestExpression) == null) { - return false; - } - return !(BasicJavaAstTreeUtil.is(block, BASIC_BLOCK_STATEMENT)) && - (block == null || startLine(doc, block) != startLine(doc, astNodeStatement) || condition == null); + PsiStatement block = statement instanceof PsiWhileStatement ? ((PsiWhileStatement)statement).getBody() : ((PsiIfStatement)statement).getThenBranch(); + PsiExpression condition = PsiTreeUtil.getChildOfType(statement, PsiExpression.class); + PsiExpression latestExpression = PsiTreeUtil.getParentOfType(prev, PsiExpression.class); + if (latestExpression instanceof PsiNewExpression && ((PsiNewExpression)latestExpression).getAnonymousClass() == null) return false; + return !(block instanceof PsiBlockStatement) && (block == null || startLine(doc, block) != startLine(doc, statement) || condition == null); } private static boolean isRparenth(@Nullable PsiElement leaf) { @@ -329,8 +301,8 @@ public class JavaTypedHandlerBase extends TypedHandlerDelegate { return next.getNode().getElementType() == JavaTokenType.RPARENTH; } - private static int startLine(@NotNull Document doc, @NotNull ASTNode astNode) { - return doc.getLineNumber(astNode.getTextRange().getStartOffset()); + private static int startLine(@NotNull Document doc, @NotNull PsiElement psiElement) { + return doc.getLineNumber(psiElement.getTextRange().getStartOffset()); } @Override @@ -426,19 +398,18 @@ public class JavaTypedHandlerBase extends TypedHandlerDelegate { if (!it.atEnd() && afterLastParenOffset >= 0 && afterLastParenOffset >= caretOffset) { PsiDocumentManager.getInstance(project).commitDocument(editor.getDocument()); PsiElement curElement = file.findElementAt(caretOffset); - ASTNode curStmt = BasicJavaAstTreeUtil.getParentOfType(BasicJavaAstTreeUtil.toNode(curElement), STATEMENT_SET); + PsiStatement curStmt = PsiTreeUtil.getParentOfType(curElement, PsiStatement.class); if (curStmt != null) { - if (BasicJavaAstTreeUtil.is(curStmt, BASIC_TRY_STATEMENT)) { + if (curStmt instanceof PsiTryStatement) { // try-with-resources can contain semicolons inside return false; } - if (BasicJavaAstTreeUtil.is(curStmt, BASIC_FOR_STATEMENT)) { + if (curStmt instanceof PsiForStatement) { // for loop can have semicolons inside return false; } // It may worth to check if the error element is about expecting semicolon - PsiElement curPsiElement = BasicJavaAstTreeUtil.toPsi(curStmt); - if (curPsiElement != null && PsiTreeUtil.getDeepestLast(curPsiElement) instanceof PsiErrorElement) { + if (PsiTreeUtil.getDeepestLast(curStmt) instanceof PsiErrorElement) { int stmtEndOffset = curStmt.getTextRange().getEndOffset(); if (stmtEndOffset == afterLastParenOffset || stmtEndOffset == it.getStart()) { editor.getDocument().insertString(stmtEndOffset, ";"); @@ -466,7 +437,7 @@ public class JavaTypedHandlerBase extends TypedHandlerDelegate { PsiElement currElement = file.findElementAt(offset - 1); if (currElement != null) { PsiElement parent = currElement.getParent(); - if (BasicJavaAstTreeUtil.is(BasicJavaAstTreeUtil.toNode(parent), BASIC_SWITCH_LABEL_STATEMENT)) { + if (parent instanceof PsiSwitchLabelStatement) { CodeStyleManager.getInstance(project).adjustLineIndent(file, parent.getTextOffset()); return true; } diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/JavadocLineStartHandler.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/JavadocLineStartHandler.java index 0f61342476f2..459e107179fd 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/JavadocLineStartHandler.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/JavadocLineStartHandler.java @@ -5,11 +5,12 @@ import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.editor.Caret; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.editor.EditorModificationUtilEx; +import com.intellij.openapi.editor.EditorModificationUtil; import com.intellij.openapi.editor.actionSystem.EditorActionHandler; import com.intellij.openapi.editor.ex.EditorSettingsExternalizable; import com.intellij.openapi.project.Project; import com.intellij.psi.*; +import com.intellij.psi.javadoc.PsiDocToken; import com.intellij.psi.tree.IElementType; import com.intellij.util.text.CharArrayUtil; import org.jetbrains.annotations.NotNull; @@ -45,23 +46,22 @@ public class JavadocLineStartHandler extends EditorActionHandler.ForEachCaret { if (file != null && isJavaFile(file)) { psiDocumentManager.commitDocument(document); PsiElement startElement = file.findElementAt(nonWsStartOffset); - if (startElement == null || startElement.getNode() == null) { - return; - } - IElementType type = startElement.getNode().getElementType(); - if (type == JavaDocTokenType.DOC_COMMENT_START || type == JavaDocTokenType.DOC_COMMENT_LEADING_ASTERISKS) { - int targetOffset = CharArrayUtil.shiftForward(text, startElement.getTextRange().getEndOffset(), WHITESPACE); - if (caret.getOffset() == targetOffset) targetOffset = lineStartOffset; - int selectionStartOffset = caret.getLeadSelectionOffset(); - caret.moveToOffset(targetOffset); - if (myWithSelection) { - caret.setSelection(selectionStartOffset, caret.getVisualPosition(), caret.getOffset()); + if (startElement instanceof PsiDocToken) { + IElementType type = ((PsiDocToken)startElement).getTokenType(); + if (type == JavaDocTokenType.DOC_COMMENT_START || type == JavaDocTokenType.DOC_COMMENT_LEADING_ASTERISKS) { + int targetOffset = CharArrayUtil.shiftForward(text, startElement.getTextRange().getEndOffset(), WHITESPACE); + if (caret.getOffset() == targetOffset) targetOffset = lineStartOffset; + int selectionStartOffset = caret.getLeadSelectionOffset(); + caret.moveToOffset(targetOffset); + if (myWithSelection) { + caret.setSelection(selectionStartOffset, caret.getVisualPosition(), caret.getOffset()); + } + else { + caret.removeSelection(); + } + EditorModificationUtil.scrollToCaret(editor); + return; } - else { - caret.removeSelection(); - } - EditorModificationUtilEx.scrollToCaret(editor); - return; } } } @@ -69,7 +69,7 @@ public class JavadocLineStartHandler extends EditorActionHandler.ForEachCaret { myOriginalHandler.execute(editor, caret, dataContext); } - private static boolean isJavaFile(@Nullable PsiFile file){ + private static boolean isJavaFile(@Nullable PsiFile file) { return file instanceof AbstractBasicJavaFile; } } diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/JavadocTypedHandler.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/JavadocTypedHandler.java index 3dd73c8af3a0..da9d7023860e 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/JavadocTypedHandler.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/JavadocTypedHandler.java @@ -9,8 +9,10 @@ import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.TextRange; import com.intellij.psi.*; -import com.intellij.psi.impl.source.BasicJavaAstTreeUtil; -import com.intellij.psi.tree.ParentAwareTokenSet; +import com.intellij.psi.impl.source.javadoc.PsiDocParamRef; +import com.intellij.psi.javadoc.PsiDocTag; +import com.intellij.psi.javadoc.PsiInlineDocTag; +import com.intellij.psi.util.PsiTreeUtil; import com.intellij.xml.util.BasicHtmlUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -175,21 +177,16 @@ public final class JavadocTypedHandler extends TypedHandlerDelegate { if (element == null) { return false; } - ASTNode astNode = BasicJavaAstTreeUtil.toNode(element); - if (BasicJavaAstTreeUtil.is(astNode, BASIC_DOC_PARAMETER_REF)) { - astNode = astNode.getTreeParent(); + if (element instanceof PsiDocParamRef) { + element = element.getParent(); } - if (BasicJavaAstTreeUtil.is(astNode, BASIC_DOC_TAG, BASIC_DOC_SNIPPET_TAG, BASIC_DOC_INLINE_TAG) && - "param".equals(BasicJavaAstTreeUtil.getTagName(astNode)) && - isTypeParamBracketClosedAfterParamTag(astNode, offset)) { + if (element instanceof PsiDocTag tag && "param".equals(tag.getName()) && isTypeParamBracketClosedAfterParamTag(tag, offset)) { return false; } - // The contents of inline tags is not HTML, so the paired tag completion isn't appropriate there. - if (BasicJavaAstTreeUtil.is(astNode, BASIC_DOC_INLINE_TAG, BASIC_DOC_SNIPPET_TAG) || - BasicJavaAstTreeUtil.getParentOfType(astNode, ParentAwareTokenSet.create(BASIC_DOC_INLINE_TAG, BASIC_DOC_SNIPPET_TAG)) != null) { + if (PsiTreeUtil.getParentOfType(element, PsiInlineDocTag.class, false) != null) { return false; } @@ -199,17 +196,17 @@ public final class JavadocTypedHandler extends TypedHandlerDelegate { || BASIC_ALL_JAVADOC_ELEMENTS.contains(node.getElementType())); } - private static boolean isTypeParamBracketClosedAfterParamTag(ASTNode tag, int bracketOffset) { - ASTNode paramToDocument = getDocumentingParameter(tag); + private static boolean isTypeParamBracketClosedAfterParamTag(PsiDocTag tag, int bracketOffset) { + PsiElement paramToDocument = getDocumentingParameter(tag); if (paramToDocument == null) return false; TextRange paramRange = paramToDocument.getTextRange(); return paramRange.getEndOffset() == bracketOffset; } - private static @Nullable ASTNode getDocumentingParameter(@NotNull ASTNode tag) { - for (ASTNode element = tag.getFirstChildNode(); element != null; element = element.getTreeNext()) { - if (BasicJavaAstTreeUtil.is(element, BASIC_DOC_PARAMETER_REF)) { + private static @Nullable PsiElement getDocumentingParameter(@NotNull PsiDocTag tag) { + for (PsiElement element = tag.getFirstChild(); element != null; element = element.getNextSibling()) { + if (element instanceof PsiDocParamRef) { return element; } } diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/moveUpDown/JavaCaseBlockMover.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/moveUpDown/JavaCaseBlockMover.java index 870266db82ca..7e7438b9f128 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/moveUpDown/JavaCaseBlockMover.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/moveUpDown/JavaCaseBlockMover.java @@ -4,10 +4,7 @@ package com.intellij.codeInsight.editorActions.moveUpDown; import com.intellij.codeInsight.CodeInsightFrontbackUtil; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiFile; -import com.intellij.psi.PsiJavaFile; -import com.intellij.psi.PsiSwitchLabelStatement; +import com.intellij.psi.*; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.SmartList; import com.intellij.util.text.CharArrayUtil; @@ -20,7 +17,7 @@ public final class JavaCaseBlockMover extends LineMover { @Override public boolean checkAvailable(@NotNull Editor editor, @NotNull PsiFile file, @NotNull MoveInfo info, boolean down) { - if (!(file instanceof PsiJavaFile)) return false; + if (!(file instanceof AbstractBasicJavaFile)) return false; if (!super.checkAvailable(editor, file, info, down)) return false; final Document document = editor.getDocument(); diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/moveUpDown/JavaCatchBlockMover.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/moveUpDown/JavaCatchBlockMover.java index 389ea31b6ac4..c6f517d624f2 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/moveUpDown/JavaCatchBlockMover.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/moveUpDown/JavaCatchBlockMover.java @@ -15,7 +15,7 @@ public final class JavaCatchBlockMover extends LineMover { @Override public boolean checkAvailable(@NotNull Editor editor, @NotNull PsiFile file, @NotNull MoveInfo info, boolean down) { - if (!(file instanceof PsiJavaFile)) return false; + if (!(file instanceof AbstractBasicJavaFile)) return false; if (!super.checkAvailable(editor, file, info, down)) return false; final Document document = editor.getDocument(); diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/moveUpDown/JavaDeclarationMover.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/moveUpDown/JavaDeclarationMover.java index fea1a0b1fce3..42a17c53a5a4 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/moveUpDown/JavaDeclarationMover.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/moveUpDown/JavaDeclarationMover.java @@ -98,7 +98,7 @@ final class JavaDeclarationMover extends LineMover { @Override public boolean checkAvailable(final @NotNull Editor editor, final @NotNull PsiFile file, final @NotNull MoveInfo info, final boolean down) { - if (!(file instanceof PsiJavaFile)) { + if (!(file instanceof AbstractBasicJavaFile)) { return false; } diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/ASTNodeEnterProcessor.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/ASTNodeEnterProcessor.java deleted file mode 100644 index a20527e80f71..000000000000 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/ASTNodeEnterProcessor.java +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -package com.intellij.codeInsight.editorActions.smartEnter; - -import com.intellij.lang.ASTNode; -import com.intellij.openapi.editor.Editor; -import com.intellij.psi.PsiElement; -import com.intellij.psi.impl.source.BasicJavaAstTreeUtil; -import org.jetbrains.annotations.NotNull; - -public interface ASTNodeEnterProcessor extends EnterProcessor { - boolean doEnter(@NotNull Editor editor, @NotNull ASTNode psiElement, boolean isModified); - - @Override - default boolean doEnter(Editor editor, PsiElement psiElement, boolean isModified) { - ASTNode node = BasicJavaAstTreeUtil.toNode(psiElement); - if (node == null) { - return false; - } - return doEnter(editor, node, isModified); - } -} - diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/AbstractBasicJavaSmartEnterProcessor.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/AbstractBasicJavaSmartEnterProcessor.java deleted file mode 100644 index 146eb5f5a5d4..000000000000 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/AbstractBasicJavaSmartEnterProcessor.java +++ /dev/null @@ -1,396 +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.codeInsight.editorActions.smartEnter; - -import com.intellij.application.options.CodeStyle; -import com.intellij.codeInsight.lookup.LookupManager; -import com.intellij.lang.ASTNode; -import com.intellij.lang.java.JavaLanguage; -import com.intellij.openapi.actionSystem.IdeActions; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.editor.Document; -import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.editor.RangeMarker; -import com.intellij.openapi.editor.actionSystem.EditorActionHandler; -import com.intellij.openapi.editor.actionSystem.EditorActionManager; -import com.intellij.openapi.editor.ex.util.EditorUtil; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Key; -import com.intellij.openapi.util.TextRange; -import com.intellij.psi.JavaTokenType; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiFile; -import com.intellij.psi.SyntaxTraverser; -import com.intellij.psi.codeStyle.CodeStyleManager; -import com.intellij.psi.codeStyle.CommonCodeStyleSettings; -import com.intellij.psi.impl.source.BasicJavaAstTreeUtil; -import com.intellij.psi.util.PsiTreeUtil; -import com.intellij.psi.util.PsiUtilCore; -import com.intellij.util.IncorrectOperationException; -import com.intellij.util.text.CharArrayUtil; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.ArrayList; -import java.util.List; - -import static com.intellij.psi.impl.source.BasicElementTypes.BASIC_JAVA_COMMENT_BIT_SET; -import static com.intellij.psi.impl.source.BasicJavaElementType.*; - -public abstract class AbstractBasicJavaSmartEnterProcessor extends SmartEnterProcessor { - private static final Logger LOG = Logger.getInstance(AbstractBasicJavaSmartEnterProcessor.class); - - private final List ourFixers; - private final EnterProcessor[] ourEnterProcessors; - private final EnterProcessor[] ourAfterCompletionEnterProcessors; - - protected int myFirstErrorOffset = Integer.MAX_VALUE; - protected boolean mySkipEnter; - private static final int MAX_ATTEMPTS = 20; - private static final Key SMART_ENTER_TIMESTAMP = Key.create("smartEnterOriginalTimestamp"); - private final EnterProcessor myBreakerEnterProcessor; - - protected void insertBraces(@NotNull Editor editor, int offset) { - Document document = editor.getDocument(); - document.insertString(offset, "{"); - insertCloseBrace(editor, offset + 1); - } - - protected void insertCloseBrace(@NotNull Editor editor, int offset) { - Document document = editor.getDocument(); - document.insertString(offset, "}"); - } - - protected void insertBracesWithNewLine(Editor editor, int offset) { - Document document = editor.getDocument(); - document.insertString(offset, "{\n"); - insertCloseBrace(editor, offset + 2); - } - - private static class TooManyAttemptsException extends Exception { - } - - private final JavadocFixer myJavadocFixer; - - protected AbstractBasicJavaSmartEnterProcessor(@NotNull List fixers, - EnterProcessor @NotNull [] enterProcessors, - EnterProcessor @NotNull [] afterCompletionEnterProcessors, - @NotNull JavadocFixer thinJavadocFixer, - @NotNull EnterProcessor breakerEnterProcessor) { - myBreakerEnterProcessor = breakerEnterProcessor; - ourFixers = fixers; - ourEnterProcessors = enterProcessors; - ourAfterCompletionEnterProcessors = afterCompletionEnterProcessors; - myJavadocFixer = thinJavadocFixer; - } - - @Override - public boolean process(final @NotNull Project project, final @NotNull Editor editor, final @NotNull PsiFile psiFile) { - return invokeProcessor(editor, psiFile, false); - } - - @Override - public boolean processAfterCompletion(@NotNull Editor editor, @NotNull PsiFile psiFile) { - return invokeProcessor(editor, psiFile, true); - } - - private boolean invokeProcessor(Editor editor, PsiFile psiFile, boolean afterCompletion) { - final Document document = editor.getDocument(); - final CharSequence textForRollback = document.getImmutableCharSequence(); - try { - editor.putUserData(SMART_ENTER_TIMESTAMP, editor.getDocument().getModificationStamp()); - myFirstErrorOffset = Integer.MAX_VALUE; - mySkipEnter = false; - process(editor, psiFile, 0, afterCompletion); - } - catch (TooManyAttemptsException e) { - document.replaceString(0, document.getTextLength(), textForRollback); - } - catch (Exception e) { - LOG.error(e); - } - finally { - editor.putUserData(SMART_ENTER_TIMESTAMP, null); - } - return true; - } - - private void process(final @NotNull Editor editor, final @NotNull PsiFile file, final int attempt, boolean afterCompletion) - throws TooManyAttemptsException { - if (attempt > MAX_ATTEMPTS) throw new TooManyAttemptsException(); - - try { - commit(editor); - if (myFirstErrorOffset != Integer.MAX_VALUE) { - editor.getCaretModel().moveToOffset(myFirstErrorOffset); - } - - myFirstErrorOffset = Integer.MAX_VALUE; - - PsiElement atCaret = getStatementAtCaret(editor, file); - if (atCaret == null) { - if (myJavadocFixer.process(editor, file)) { - return; - } - if (!(myBreakerEnterProcessor).doEnter(editor, file, false)) { - plainEnter(editor); - } - return; - } - - List queue = new ArrayList<>(); - ASTNode caretNode = atCaret.getNode(); - collectAllElements(caretNode, queue, true); - queue.add(caretNode); - - for (ASTNode astNode : queue) { - for (Fixer fixer : ourFixers) { - Document document = editor.getDocument(); - int offset = myFirstErrorOffset; - long stamp = document.getModificationStamp(); - fixer.apply(editor, this, astNode); - Project project = file.getProject(); - if (document.getModificationStamp() != stamp || offset != myFirstErrorOffset) { - log(fixer, project); - } - if (LookupManager.getInstance(project).getActiveLookup() != null) { - return; - } - PsiElement psi = BasicJavaAstTreeUtil.toPsi(astNode); - if (isUncommited(project) || !(psi != null && psi.isValid())) { - moveCaretInsideBracesIfAny(editor, file); - process(editor, file, attempt + 1, afterCompletion); - return; - } - } - } - - doEnter(atCaret, editor, afterCompletion); - } - catch (IncorrectOperationException e) { - LOG.error(e); - } - } - - protected abstract void log(@NotNull Fixer fixer, @NotNull Project project); - - - @Override - public void reformat(PsiElement atCaretElement) throws IncorrectOperationException { - if (atCaretElement == null) { - return; - } - ASTNode atCaret = atCaretElement.getNode(); - ASTNode parent = atCaret.getTreeParent(); - if (BasicJavaAstTreeUtil.is(parent, BASIC_FOR_STATEMENT)) { - atCaret = parent; - } - - if (BasicJavaAstTreeUtil.is(parent, BASIC_IF_STATEMENT) && - atCaret == BasicJavaAstTreeUtil.getElseBranch(parent)) { - PsiFile file = atCaretElement.getContainingFile(); - Document document = file.getViewProvider().getDocument(); - if (document != null) { - TextRange elseIfRange = atCaret.getTextRange(); - int lineStart = document.getLineStartOffset(document.getLineNumber(elseIfRange.getStartOffset())); - CodeStyleManager.getInstance(atCaretElement.getProject()).reformatText(file, lineStart, elseIfRange.getEndOffset()); - return; - } - } - - super.reformat(atCaretElement); - } - - - private void doEnter(PsiElement atCaret, Editor editor, boolean afterCompletion) throws IncorrectOperationException { - final PsiFile psiFile = atCaret.getContainingFile(); - - if (myFirstErrorOffset != Integer.MAX_VALUE) { - editor.getCaretModel().moveToOffset(myFirstErrorOffset); - reformat(atCaret); - return; - } - - final RangeMarker rangeMarker = createRangeMarker(atCaret); - reformat(atCaret); - commit(editor); - - if (!mySkipEnter) { - ASTNode atCaretNode = BasicJavaAstTreeUtil.findElementInRange(psiFile, rangeMarker.getStartOffset(), rangeMarker.getEndOffset(), - atCaret.getNode().getElementType()); - for (EnterProcessor processor : afterCompletion ? ourAfterCompletionEnterProcessors : ourEnterProcessors) { - if (atCaretNode == null) { - // Can't restore element at caret after enter processor execution! - break; - } - - if (processor.doEnter(editor, BasicJavaAstTreeUtil.toPsi(atCaretNode), isModified(editor))) { - rangeMarker.dispose(); - return; - } - } - - if (!isModified(editor) && !afterCompletion) { - plainEnter(editor); - } - else { - if (myFirstErrorOffset == Integer.MAX_VALUE) { - editor.getCaretModel().moveToOffset(rangeMarker.getEndOffset()); - } - else { - editor.getCaretModel().moveToOffset(myFirstErrorOffset); - } - } - } - rangeMarker.dispose(); - } - - private static void collectAllElements(ASTNode atCaret, List res, boolean recurse) { - res.add(0, atCaret); - if (doNotStepInto(atCaret)) { - if (!recurse) return; - recurse = false; - } - - final List children = BasicJavaAstTreeUtil.getChildren(atCaret); - for (ASTNode child : children) { - if (BasicJavaAstTreeUtil.is(atCaret, STATEMENT_SET) && - BasicJavaAstTreeUtil.is(child, STATEMENT_SET) && - !(BasicJavaAstTreeUtil.is(atCaret, BASIC_FOR_STATEMENT) - && child == (BasicJavaAstTreeUtil.getForInitialization(atCaret)))) { - continue; - } - collectAllElements(child, res, recurse); - } - } - - private static boolean doNotStepInto(ASTNode element) { - return BasicJavaAstTreeUtil.is(element, CLASS_SET) || - BasicJavaAstTreeUtil.is(element, BASIC_CODE_BLOCK) || - BasicJavaAstTreeUtil.is(element, STATEMENT_SET) || - BasicJavaAstTreeUtil.is(element, BASIC_METHOD); - } - - @Override - protected @Nullable PsiElement getStatementAtCaret(Editor editor, PsiFile psiFile) { - PsiElement atCaretElement = super.getStatementAtCaret(editor, psiFile); - if (atCaretElement == null) { - return null; - } - ASTNode atCaret = atCaretElement.getNode(); - if (BasicJavaAstTreeUtil.isWhiteSpace(atCaret)) return null; - if (BasicJavaAstTreeUtil.is(atCaret, JavaTokenType.RBRACE)) { - atCaret = atCaret.getTreeParent(); - boolean expressionEndingWithBrace = BasicJavaAstTreeUtil.is(atCaret, BASIC_ANONYMOUS_CLASS) || - BasicJavaAstTreeUtil.is(atCaret, BASIC_ARRAY_INITIALIZER_EXPRESSION) || - BasicJavaAstTreeUtil.is(atCaret, BASIC_CODE_BLOCK) && ( - BasicJavaAstTreeUtil.is(atCaret.getTreeParent(), BASIC_LAMBDA_EXPRESSION) || - BasicJavaAstTreeUtil.is(atCaret.getTreeParent(), BASIC_SWITCH_EXPRESSION)); - if (!expressionEndingWithBrace) return null; - } - - for (ASTNode each : SyntaxTraverser.astApi().parents(atCaret).skip(1)) { - PsiElement psiElement = BasicJavaAstTreeUtil.toPsi(each); - if (BasicJavaAstTreeUtil.is(each, MEMBER_SET) || - isImportStatementBase(psiElement) || - BasicJavaAstTreeUtil.is(each, BASIC_PACKAGE_STATEMENT) || - BasicJavaAstTreeUtil.is(each, BASIC_ANNOTATION) && - psiElement != null && - PsiTreeUtil.hasErrorElements(psiElement)) { - return each.getPsi(); - } - if (BasicJavaAstTreeUtil.is(each, BASIC_CODE_BLOCK) || - BasicJavaAstTreeUtil.is(each, BASIC_JAVA_COMMENT_BIT_SET)) { - return null; - } - if (BasicJavaAstTreeUtil.is(each, STATEMENT_SET)) { - return BasicJavaAstTreeUtil.is(each.getTreeParent(), BASIC_FOR_STATEMENT) && - !PsiTreeUtil.hasErrorElements(each.getPsi()) ? each.getPsi().getParent() : each.getPsi(); - } - if (BasicJavaAstTreeUtil.is(each, BASIC_CONDITIONAL_EXPRESSION) && - PsiUtilCore.hasErrorElementChild(each.getPsi())) { - return each.getPsi(); - } - } - - return null; - } - - protected abstract boolean isImportStatementBase(PsiElement el); - - protected void moveCaretInsideBracesIfAny(final @NotNull Editor editor, final @NotNull PsiFile file) throws IncorrectOperationException { - int caretOffset = editor.getCaretModel().getOffset(); - final CharSequence chars = editor.getDocument().getCharsSequence(); - - if (CharArrayUtil.regionMatches(chars, caretOffset, "{}")) { - caretOffset += 2; - } - else if (CharArrayUtil.regionMatches(chars, caretOffset, "{\n}")) { - caretOffset += 3; - } - - caretOffset = CharArrayUtil.shiftBackward(chars, caretOffset - 1, " \t") + 1; - - if (CharArrayUtil.regionMatches(chars, caretOffset - "{}".length(), "{}") || - CharArrayUtil.regionMatches(chars, caretOffset - "{\n}".length(), "{\n}")) { - commit(editor); - final CommonCodeStyleSettings settings = CodeStyle.getSettings(file).getCommonSettings(JavaLanguage.INSTANCE); - final boolean old = settings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE; - settings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE = false; - PsiElement leaf = file.findElementAt(caretOffset - 1); - PsiElement elt = BasicJavaAstTreeUtil.toPsi( - BasicJavaAstTreeUtil.getParentOfType(BasicJavaAstTreeUtil.toNode(leaf), BASIC_CODE_BLOCK)); - if (elt == null && - leaf != null && - leaf.getParent() != null && - BasicJavaAstTreeUtil.is(leaf.getParent().getNode(), CLASS_SET)) { - elt = leaf.getParent(); - } - reformatAndMove(editor, elt, caretOffset); - settings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE = old; - - reformatBlockParentIfNeeded(editor, file); - } - } - - protected void reformatAndMove(@NotNull Editor editor, @Nullable PsiElement elt, int caretOffset) { - reformat(elt); - editor.getCaretModel().moveToOffset(caretOffset - 1); - } - - private void reformatBlockParentIfNeeded(@NotNull Editor editor, @NotNull PsiFile file) { - commit(editor); - ASTNode block = - BasicJavaAstTreeUtil.findElementOfClassAtOffset(file, editor.getCaretModel().getOffset(), BASIC_CODE_BLOCK, false); - if (block != null && - BasicJavaAstTreeUtil.is(block.getTreeParent(), BASIC_BLOCK_STATEMENT) && - BasicJavaAstTreeUtil.is(block.getTreeParent().getTreeParent(), BASIC_FOR_STATEMENT)) { - reformat(block.getTreeParent().getTreeParent().getPsi()); - } - if (block != null && BasicJavaAstTreeUtil.is(block.getTreeParent(), BASIC_SWITCH_EXPRESSION)) { - reformat(block.getTreeParent().getPsi()); - } - } - - public void registerUnresolvedError(int offset) { - if (myFirstErrorOffset > offset) { - myFirstErrorOffset = offset; - } - } - - public void setSkipEnter(boolean skipEnter) { - mySkipEnter = skipEnter; - } - - protected static void plainEnter(final @NotNull Editor editor) { - getEnterHandler().execute(editor, editor.getCaretModel().getCurrentCaret(), EditorUtil.getEditorDataContext(editor)); - } - - protected static EditorActionHandler getEnterHandler() { - return EditorActionManager.getInstance().getActionHandler(IdeActions.ACTION_EDITOR_START_NEW_LINE); - } - - protected static boolean isModified(final @NotNull Editor editor) { - final Long timestamp = editor.getUserData(SMART_ENTER_TIMESTAMP); - return timestamp != null && editor.getDocument().getModificationStamp() != timestamp.longValue(); - } -} diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/AbstractBasicSemicolonFixer.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/AbstractBasicSemicolonFixer.java deleted file mode 100644 index c98b06633648..000000000000 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/AbstractBasicSemicolonFixer.java +++ /dev/null @@ -1,173 +0,0 @@ -// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -package com.intellij.codeInsight.editorActions.smartEnter; - -import com.intellij.lang.ASTNode; -import com.intellij.openapi.editor.Document; -import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.util.TextRange; -import com.intellij.openapi.util.text.StringUtil; -import com.intellij.psi.JavaTokenType; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiWhiteSpace; -import com.intellij.psi.TokenType; -import com.intellij.psi.impl.source.BasicJavaAstTreeUtil; -import com.intellij.psi.impl.source.tree.TreeUtil; -import com.intellij.psi.util.PsiTreeUtil; -import com.intellij.util.IncorrectOperationException; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import static com.intellij.psi.impl.source.BasicElementTypes.BASIC_JAVA_COMMENT_OR_WHITESPACE_BIT_SET; -import static com.intellij.psi.impl.source.BasicJavaElementType.*; - -public abstract class AbstractBasicSemicolonFixer implements Fixer { - - @Override - public void apply(Editor editor, AbstractBasicJavaSmartEnterProcessor processor, @NotNull ASTNode astNode) throws IncorrectOperationException { - PsiElement psiElement = BasicJavaAstTreeUtil.toPsi(astNode); - if (fixReturn(editor, psiElement)) return; - if (fixForUpdate(editor, astNode)) return; - fixAfterLastValidElement(editor, astNode); - } - - protected abstract boolean fixReturn(@NotNull Editor editor, @Nullable PsiElement astNode); - - protected abstract boolean getSpaceAfterSemicolon(@NotNull PsiElement psiElement); - - private boolean fixForUpdate(@NotNull Editor editor, @Nullable ASTNode astNode) { - if (!(BasicJavaAstTreeUtil.is(astNode, BASIC_FOR_STATEMENT))) { - return false; - } - - ASTNode condition = BasicJavaAstTreeUtil.getForCondition(astNode); - if (BasicJavaAstTreeUtil.getForUpdate(astNode) != null || condition == null) { - return false; - } - - TextRange range = condition.getTextRange(); - Document document = editor.getDocument(); - CharSequence text = document.getCharsSequence(); - for (int i = range.getEndOffset() - 1, max = astNode.getTextRange().getEndOffset(); i < max; i++) { - if (text.charAt(i) == ';') { - return false; - } - } - - String toInsert = ";"; - PsiElement psiElement = BasicJavaAstTreeUtil.toPsi(astNode); - if (psiElement != null && getSpaceAfterSemicolon(psiElement)) { - toInsert += " "; - } - document.insertString(range.getEndOffset(), toInsert); - return true; - } - - - private void fixAfterLastValidElement(@NotNull Editor editor, @Nullable ASTNode astNode) { - PsiElement psiElement = BasicJavaAstTreeUtil.toPsi(astNode); - if (astNode == null || psiElement == null) { - return; - } - if ( - BasicJavaAstTreeUtil.is(astNode, BASIC_EXPRESSION_STATEMENT) || - BasicJavaAstTreeUtil.is(astNode, BASIC_DECLARATION_STATEMENT) || - isImportStatementBase(psiElement) || - BasicJavaAstTreeUtil.is(astNode, BASIC_DO_WHILE_STATEMENT) || - BasicJavaAstTreeUtil.is(astNode, BASIC_RETURN_STATEMENT) || - BasicJavaAstTreeUtil.is(astNode, BASIC_THROW_STATEMENT) || - BasicJavaAstTreeUtil.is(astNode, BASIC_BREAK_STATEMENT) || - BasicJavaAstTreeUtil.is(astNode, BASIC_CONTINUE_STATEMENT) || - BasicJavaAstTreeUtil.is(astNode, BASIC_YIELD_STATEMENT) || - BasicJavaAstTreeUtil.is(astNode, BASIC_ASSERT_STATEMENT) || - BasicJavaAstTreeUtil.is(astNode, BASIC_PACKAGE_STATEMENT) || - isStandaloneField(psiElement) || - BasicJavaAstTreeUtil.is(astNode, BASIC_METHOD) && - BasicJavaAstTreeUtil.getCodeBlock(astNode) == null && - !isMethodShouldHaveBody(psiElement) || - BasicJavaAstTreeUtil.is(astNode, BASIC_REQUIRES_STATEMENT) || - BasicJavaAstTreeUtil.is(astNode, BASIC_OPENS_STATEMENT) || - BasicJavaAstTreeUtil.is(astNode, BASIC_EXPORTS_STATEMENT) || - BasicJavaAstTreeUtil.is(astNode, BASIC_USES_STATEMENT) || - BasicJavaAstTreeUtil.is(astNode, BASIC_PROVIDES_STATEMENT)) { - String text = astNode.getText(); - - int tailLength = 0; - ASTNode leaf = TreeUtil.findLastLeaf(astNode); - while (leaf != null && BASIC_JAVA_COMMENT_OR_WHITESPACE_BIT_SET.contains(leaf.getElementType())) { - tailLength += leaf.getTextLength(); - leaf = TreeUtil.prevLeaf(leaf); - } - if (leaf == null) { - return; - } - - if (tailLength > 0) { - text = text.substring(0, text.length() - tailLength); - } - - int insertionOffset = leaf.getTextRange().getEndOffset(); - Document doc = editor.getDocument(); - if (BasicJavaAstTreeUtil.is(astNode, BASIC_FIELD) && - (BasicJavaAstTreeUtil.hasModifierProperty(astNode, JavaTokenType.ABSTRACT_KEYWORD))) { - // abstract rarely seem to be field. It is rather incomplete method. - doc.insertString(insertionOffset, "()"); - insertionOffset += "()".length(); - } - - // Like: - // assert x instanceof Type - // String s = "hello"; - // Here, String is parsed as name of the pattern variable, and we have an assignment, instead of declaration - ASTNode error = astNode.getLastChildNode(); - if (BasicJavaAstTreeUtil.is(error, TokenType.ERROR_ELEMENT) && - BasicJavaAstTreeUtil.is(error.getTreePrev(), BASIC_INSTANCE_OF_EXPRESSION) && - BasicJavaAstTreeUtil.is(error.getTreePrev().getLastChildNode(), BASIC_TYPE_TEST_PATTERN)) { - ASTNode variable = BasicJavaAstTreeUtil.getPatternVariable(error.getTreePrev().getLastChildNode()); - PsiElement skipWhitespacesForward = PsiTreeUtil.skipWhitespacesForward(psiElement); - ASTNode assignmentExpr = BasicJavaAstTreeUtil.getExpression(BasicJavaAstTreeUtil.toNode(skipWhitespacesForward)); - if (variable != null && - BasicJavaAstTreeUtil.is(BasicJavaAstTreeUtil.toNode(skipWhitespacesForward), BASIC_EXPRESSION_STATEMENT) && - BasicJavaAstTreeUtil.is(assignmentExpr, BASIC_ASSIGNMENT_EXPRESSION) && - JavaTokenType.EQ.equals(BasicJavaAstTreeUtil.getAssignmentOperationTokenType(assignmentExpr))) { - ASTNode identifier = BasicJavaAstTreeUtil.getNameIdentifier(variable); - if (identifier != null && - BasicJavaAstTreeUtil.toPsi(identifier.getTreePrev()) instanceof PsiWhiteSpace ws && - ws.getText().contains("\n") && - editor.getCaretModel().getOffset() < identifier.getTextRange().getStartOffset()) { - insertionOffset = ws.getTextRange().getStartOffset(); - } - } - } - - if (!StringUtil.endsWithChar(text, ';')) { - ASTNode parent = astNode.getTreeParent(); - String toInsert = ";"; - if (BasicJavaAstTreeUtil.is(parent, BASIC_FOR_STATEMENT)) { - if (BasicJavaAstTreeUtil.getForUpdate(parent) == astNode) { - return; - } - if (getSpaceAfterSemicolon(psiElement)) { - toInsert += " "; - } - } - - doc.insertString(insertionOffset, toInsert); - } - } - } - - private static boolean isMethodShouldHaveBody(@Nullable PsiElement psiElement){ - return AfterSemicolonEnterProcessor.shouldHaveBody(BasicJavaAstTreeUtil.toNode(psiElement)); - } - - protected abstract boolean isImportStatementBase(@Nullable PsiElement psiElement); - - private static boolean isStandaloneField(@Nullable PsiElement psiElement) { - if (psiElement == null || !BasicJavaAstTreeUtil.is(BasicJavaAstTreeUtil.toNode(psiElement), BASIC_FIELD)) return false; - PsiElement node = PsiTreeUtil.nextLeaf(psiElement, true); - if (node == null) { - return false; - } - return !",".equals(node.getText()); - } -} \ No newline at end of file diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/AfterSemicolonEnterProcessor.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/AfterSemicolonEnterProcessor.java index 0c50e85a40b5..7f59f9618ac0 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/AfterSemicolonEnterProcessor.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/AfterSemicolonEnterProcessor.java @@ -1,44 +1,30 @@ // 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.codeInsight.editorActions.smartEnter; -import com.intellij.lang.ASTNode; import com.intellij.openapi.editor.Editor; -import com.intellij.psi.JavaTokenType; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiErrorElement; -import com.intellij.psi.PsiRecursiveElementWalkingVisitor; -import com.intellij.psi.impl.source.BasicJavaAstTreeUtil; +import com.intellij.psi.*; import com.intellij.util.text.CharArrayUtil; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import java.util.Set; - -import static com.intellij.psi.impl.source.BasicJavaElementType.*; - -public class AfterSemicolonEnterProcessor implements ASTNodeEnterProcessor { +public class AfterSemicolonEnterProcessor implements EnterProcessor { @Override - public boolean doEnter(@NotNull Editor editor, @NotNull ASTNode astNode, boolean isModified) { - PsiElement psiElement = BasicJavaAstTreeUtil.toPsi(astNode); - if (psiElement == null) { - return false; - } - if (BasicJavaAstTreeUtil.is(astNode, BASIC_EXPRESSION_STATEMENT) || - BasicJavaAstTreeUtil.is(astNode, BASIC_DECLARATION_STATEMENT) || - BasicJavaAstTreeUtil.is(astNode, BASIC_DO_WHILE_STATEMENT) || - BasicJavaAstTreeUtil.is(astNode, BASIC_RETURN_STATEMENT) || - BasicJavaAstTreeUtil.is(astNode, BASIC_THROW_STATEMENT) || - BasicJavaAstTreeUtil.is(astNode, BASIC_BREAK_STATEMENT) || - BasicJavaAstTreeUtil.is(astNode, BASIC_CONTINUE_STATEMENT) || - BasicJavaAstTreeUtil.is(astNode, BASIC_YIELD_STATEMENT) || - BasicJavaAstTreeUtil.is(astNode, BASIC_ASSERT_STATEMENT) || - BasicJavaAstTreeUtil.is(astNode, Set.of(BASIC_FIELD, BASIC_ENUM_CONSTANT)) || - isImportStatementBase(psiElement) || - isMethodWithoutBody(psiElement)) { + public boolean doEnter(@NotNull Editor editor, @NotNull PsiElement psiElement, boolean isModified) { + if (psiElement instanceof PsiExpressionStatement || + psiElement instanceof PsiDeclarationStatement || + psiElement instanceof PsiDoWhileStatement || + psiElement instanceof PsiReturnStatement || + psiElement instanceof PsiThrowStatement || + psiElement instanceof PsiBreakStatement || + psiElement instanceof PsiContinueStatement || + psiElement instanceof PsiYieldStatement || + psiElement instanceof PsiAssertStatement || + psiElement instanceof PsiField || + psiElement instanceof PsiImportStatementBase || + psiElement instanceof PsiMethod && !MissingMethodBodyFixer.shouldHaveBody((PsiMethod)psiElement)) { int errorOffset = getErrorElementOffset(psiElement); - int elementEndOffset = astNode.getTextRange().getEndOffset(); - if (BasicJavaAstTreeUtil.is(astNode, BASIC_ENUM_CONSTANT)) { + int elementEndOffset = psiElement.getTextRange().getEndOffset(); + if (psiElement instanceof PsiEnumConstant) { final CharSequence text = editor.getDocument().getCharsSequence(); final int commaOffset = CharArrayUtil.shiftForwardUntil(text, elementEndOffset, ","); if (commaOffset < text.length()) { @@ -59,39 +45,6 @@ public class AfterSemicolonEnterProcessor implements ASTNodeEnterProcessor { return false; } - static boolean shouldHaveBody(@Nullable ASTNode element) { - if (element == null) { - return false; - } - ASTNode containingClass = BasicJavaAstTreeUtil.getParentOfType(element, CLASS_SET); - if (containingClass == null) return false; - if (BasicJavaAstTreeUtil.hasModifierProperty(element, JavaTokenType.ABSTRACT_KEYWORD) || - BasicJavaAstTreeUtil.hasModifierProperty(element, JavaTokenType.NATIVE_KEYWORD)) { - return false; - } - if (BasicJavaAstTreeUtil.hasModifierProperty(element, JavaTokenType.PRIVATE_KEYWORD)) return true; - if (BasicJavaAstTreeUtil.isInterfaceEnumClassOrRecord(containingClass, JavaTokenType.INTERFACE_KEYWORD) && - !BasicJavaAstTreeUtil.hasModifierProperty(element, JavaTokenType.DEFAULT_KEYWORD) && - !BasicJavaAstTreeUtil.hasModifierProperty(element, JavaTokenType.STATIC_KEYWORD)) { - return false; - } - return true; - } - - private static boolean isMethodWithoutBody(@Nullable PsiElement psiElement){ - ASTNode node = BasicJavaAstTreeUtil.toNode(psiElement); - return BasicJavaAstTreeUtil.is(node, BASIC_METHOD) && - !shouldHaveBody(node); - } - - private static boolean isImportStatementBase(@Nullable PsiElement psiElement){ - ASTNode node = BasicJavaAstTreeUtil.toNode(psiElement); - return - BasicJavaAstTreeUtil.is(node, BASIC_IMPORT_STATEMENT) || - BasicJavaAstTreeUtil.is(node, BASIC_IMPORT_STATIC_STATEMENT) || - BasicJavaAstTreeUtil.is(node, BASIC_IMPORT_MODULE_STATEMENT); - } - private static int getErrorElementOffset(PsiElement elt) { final int[] offset = {-1}; elt.accept(new PsiRecursiveElementWalkingVisitor() { diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/BlockBraceFixer.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/BlockBraceFixer.java index 752e19abd9ae..18fb2f19e808 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/BlockBraceFixer.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/BlockBraceFixer.java @@ -2,33 +2,23 @@ package com.intellij.codeInsight.editorActions.smartEnter; import com.intellij.codeInsight.editorActions.enter.EnterAfterUnmatchedBraceHandler; -import com.intellij.lang.ASTNode; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.fileTypes.FileType; +import com.intellij.psi.PsiCodeBlock; import com.intellij.psi.PsiElement; -import com.intellij.psi.impl.source.BasicJavaAstTreeUtil; +import com.intellij.psi.PsiStatement; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; -import java.util.List; - -import static com.intellij.psi.impl.source.BasicJavaElementType.BASIC_CODE_BLOCK; -import static com.intellij.psi.impl.source.BasicJavaElementType.STATEMENT_SET; - -public class BlockBraceFixer implements Fixer{ +public class BlockBraceFixer implements Fixer { @Override - public void apply(Editor editor, AbstractBasicJavaSmartEnterProcessor processor, @NotNull ASTNode astNode) throws IncorrectOperationException { - PsiElement psiElement = BasicJavaAstTreeUtil.toPsi(astNode); - if (psiElement == null) { - return; - } - if (BasicJavaAstTreeUtil.is(astNode, BASIC_CODE_BLOCK) && afterUnmatchedBrace(editor, psiElement.getContainingFile().getFileType())) { - int stopOffset = astNode.getTextRange().getEndOffset(); - List statements = BasicJavaAstTreeUtil.getChildren(astNode).stream().filter(node-> - BasicJavaAstTreeUtil.is(node, STATEMENT_SET) - ).toList(); - if (!statements.isEmpty()) { - stopOffset = statements.get(0).getTextRange().getEndOffset(); + public void apply(Editor editor, JavaSmartEnterProcessor processor, + @NotNull PsiElement psiElement) throws IncorrectOperationException { + if (psiElement instanceof PsiCodeBlock block && afterUnmatchedBrace(editor, psiElement.getContainingFile().getFileType())) { + int stopOffset = block.getTextRange().getEndOffset(); + final PsiStatement[] statements = block.getStatements(); + if (statements.length > 0) { + stopOffset = statements[0].getTextRange().getEndOffset(); } editor.getDocument().insertString(stopOffset, "}"); } diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/CatchDeclarationFixer.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/CatchDeclarationFixer.java index 517fbdc4b1a3..caa6968ccd90 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/CatchDeclarationFixer.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/CatchDeclarationFixer.java @@ -1,40 +1,41 @@ // Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.codeInsight.editorActions.smartEnter; -import com.intellij.lang.ASTNode; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; -import com.intellij.psi.impl.source.BasicJavaAstTreeUtil; +import com.intellij.psi.PsiCatchSection; +import com.intellij.psi.PsiCodeBlock; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiJavaToken; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; -import static com.intellij.psi.impl.source.BasicJavaElementType.BASIC_CATCH_SECTION; - public class CatchDeclarationFixer implements Fixer { @Override - public void apply(Editor editor, AbstractBasicJavaSmartEnterProcessor processor, @NotNull ASTNode astNode) throws IncorrectOperationException { - if (BasicJavaAstTreeUtil.is(astNode, BASIC_CATCH_SECTION)) { + public void apply(Editor editor, JavaSmartEnterProcessor processor, @NotNull PsiElement psiElement) + throws IncorrectOperationException { + if (psiElement instanceof PsiCatchSection catchSection) { final Document doc = editor.getDocument(); - final int catchStart = astNode.getTextRange().getStartOffset(); + final int catchStart = catchSection.getTextRange().getStartOffset(); int stopOffset = doc.getLineEndOffset(doc.getLineNumber(catchStart)); - final ASTNode catchBlock = BasicJavaAstTreeUtil.getCatchBlock(astNode); + final PsiCodeBlock catchBlock = catchSection.getCatchBlock(); if (catchBlock != null) { stopOffset = Math.min(stopOffset, catchBlock.getTextRange().getStartOffset()); } - stopOffset = Math.min(stopOffset, astNode.getTextRange().getEndOffset()); + stopOffset = Math.min(stopOffset, catchSection.getTextRange().getEndOffset()); - final ASTNode lParenth = BasicJavaAstTreeUtil.getLParenth(astNode); + final PsiJavaToken lParenth = catchSection.getLParenth(); if (lParenth == null) { doc.replaceString(catchStart, stopOffset, "catch ()"); processor.registerUnresolvedError(catchStart + "catch (".length()); } else { - if (BasicJavaAstTreeUtil.getParameter(astNode) == null) { + if (catchSection.getParameter() == null) { processor.registerUnresolvedError(lParenth.getTextRange().getEndOffset()); } - if (BasicJavaAstTreeUtil.getRParenth(astNode) == null) { + if (catchSection.getRParenth() == null) { doc.insertString(stopOffset, ")"); } } diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/CommentBreakerEnterProcessor.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/CommentBreakerEnterProcessor.java index 7ee34f0ee95e..b4ccdec3e15c 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/CommentBreakerEnterProcessor.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/CommentBreakerEnterProcessor.java @@ -15,7 +15,6 @@ */ package com.intellij.codeInsight.editorActions.smartEnter; -import com.intellij.lang.ASTNode; import com.intellij.openapi.actionSystem.IdeActions; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.EditorModificationUtilEx; @@ -23,30 +22,19 @@ import com.intellij.openapi.editor.actionSystem.EditorActionHandler; import com.intellij.openapi.editor.actionSystem.EditorActionManager; import com.intellij.openapi.editor.ex.util.EditorUtil; import com.intellij.psi.JavaTokenType; +import com.intellij.psi.PsiComment; import com.intellij.psi.PsiElement; -import com.intellij.psi.impl.source.BasicElementTypes; -import com.intellij.psi.impl.source.BasicJavaAstTreeUtil; -import com.intellij.psi.tree.ParentAwareTokenSet; -import org.jetbrains.annotations.NotNull; - -import static com.intellij.psi.impl.source.BasicJavaDocElementType.BASIC_DOC_COMMENT; - -public class CommentBreakerEnterProcessor implements ASTNodeEnterProcessor { - - private final ParentAwareTokenSet myCommentTypes = ParentAwareTokenSet.orSet( - ParentAwareTokenSet.create(BasicElementTypes.BASIC_JAVA_PLAIN_COMMENT_BIT_SET), ParentAwareTokenSet.create(BASIC_DOC_COMMENT) - ); +import com.intellij.psi.util.PsiTreeUtil; +public class CommentBreakerEnterProcessor implements EnterProcessor { @Override - public boolean doEnter(@NotNull Editor editor, @NotNull ASTNode astNode, boolean isModified) { - PsiElement psiElement = BasicJavaAstTreeUtil.toPsi(astNode); - if (isModified || psiElement == null) return false; + public boolean doEnter(Editor editor, PsiElement psiElement, boolean isModified) { + if (isModified) return false; final PsiElement atCaret = psiElement.getContainingFile().findElementAt(editor.getCaretModel().getOffset()); - if (atCaret == null) return false; - final ASTNode comment = BasicJavaAstTreeUtil.getParentOfType(atCaret.getNode(), myCommentTypes, false); + final PsiComment comment = PsiTreeUtil.getParentOfType(atCaret, PsiComment.class, false); if (comment != null) { plainEnter(editor); - if (BasicJavaAstTreeUtil.is(comment, JavaTokenType.END_OF_LINE_COMMENT)) { + if (comment.getTokenType() == JavaTokenType.END_OF_LINE_COMMENT) { EditorModificationUtilEx.insertStringAtCaret(editor, "// "); } return true; diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/DoWhileConditionFixer.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/DoWhileConditionFixer.java index 7193d81bb04e..c4c6ca60c3e6 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/DoWhileConditionFixer.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/DoWhileConditionFixer.java @@ -1,45 +1,39 @@ // Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.codeInsight.editorActions.smartEnter; -import com.intellij.lang.ASTNode; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.util.TextRange; -import com.intellij.psi.impl.source.BasicJavaAstTreeUtil; +import com.intellij.psi.PsiBlockStatement; +import com.intellij.psi.PsiDoWhileStatement; +import com.intellij.psi.PsiElement; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; -import static com.intellij.psi.impl.source.BasicJavaElementType.BASIC_BLOCK_STATEMENT; -import static com.intellij.psi.impl.source.BasicJavaElementType.BASIC_DO_WHILE_STATEMENT; - public class DoWhileConditionFixer implements Fixer { @Override - public void apply(Editor editor, AbstractBasicJavaSmartEnterProcessor processor, @NotNull ASTNode astNode) throws IncorrectOperationException { - if (BasicJavaAstTreeUtil.is(astNode, BASIC_DO_WHILE_STATEMENT)) { + public void apply(Editor editor, JavaSmartEnterProcessor processor, @NotNull PsiElement psiElement) + throws IncorrectOperationException { + if (psiElement instanceof PsiDoWhileStatement stmt) { final Document doc = editor.getDocument(); - ASTNode whileKeyword = BasicJavaAstTreeUtil.getWhileKeyword(astNode); - ASTNode doWhileBody = BasicJavaAstTreeUtil.getDoWhileBody(astNode); - if (doWhileBody == null || !(BasicJavaAstTreeUtil.is(doWhileBody, BASIC_BLOCK_STATEMENT)) && whileKeyword == null) { - final int startOffset = astNode.getTextRange().getStartOffset(); + if (stmt.getBody() == null || !(stmt.getBody() instanceof PsiBlockStatement) && stmt.getWhileKeyword() == null) { + final int startOffset = stmt.getTextRange().getStartOffset(); doc.replaceString(startOffset, startOffset + "do".length(), "do {} while()"); return; } - if (BasicJavaAstTreeUtil.getWhileCondition(astNode) == null) { - if (whileKeyword == null) { - final int endOffset = astNode.getTextRange().getEndOffset(); + if (stmt.getCondition() == null) { + if (stmt.getWhileKeyword() == null) { + final int endOffset = stmt.getTextRange().getEndOffset(); doc.insertString(endOffset, "while()"); } - else if (BasicJavaAstTreeUtil.getLParenth(astNode) == null || BasicJavaAstTreeUtil.getRParenth(astNode) == null) { - final TextRange whileRange = whileKeyword.getTextRange(); + else if (stmt.getLParenth() == null || stmt.getRParenth() == null) { + final TextRange whileRange = stmt.getWhileKeyword().getTextRange(); doc.replaceString(whileRange.getStartOffset(), whileRange.getEndOffset(), "while()"); } else { - ASTNode lParenth = BasicJavaAstTreeUtil.getLParenth(astNode); - if (lParenth != null) { - processor.registerUnresolvedError(lParenth.getTextRange().getEndOffset()); - } + processor.registerUnresolvedError(stmt.getLParenth().getTextRange().getEndOffset()); } } } diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/EnumFieldFixer.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/EnumFieldFixer.java index 9f436cebd4af..480edfb2d586 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/EnumFieldFixer.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/EnumFieldFixer.java @@ -15,21 +15,19 @@ */ package com.intellij.codeInsight.editorActions.smartEnter; -import com.intellij.lang.ASTNode; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; -import com.intellij.psi.impl.source.BasicJavaAstTreeUtil; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiEnumConstant; import com.intellij.util.IncorrectOperationException; import com.intellij.util.text.CharArrayUtil; import org.jetbrains.annotations.NotNull; -import static com.intellij.psi.impl.source.BasicJavaElementType.BASIC_ENUM_CONSTANT; - public class EnumFieldFixer implements Fixer { @Override - public void apply(Editor editor, AbstractBasicJavaSmartEnterProcessor processor, @NotNull ASTNode astNode) throws IncorrectOperationException { - if (BasicJavaAstTreeUtil.is(astNode, BASIC_ENUM_CONSTANT)) { - int insertionOffset = astNode.getTextRange().getEndOffset(); + public void apply(Editor editor, JavaSmartEnterProcessor processor, @NotNull PsiElement psiElement) throws IncorrectOperationException { + if (psiElement instanceof PsiEnumConstant) { + int insertionOffset = psiElement.getTextRange().getEndOffset(); Document doc = editor.getDocument(); final CharSequence text = doc.getCharsSequence(); final int probableCommaOffset = CharArrayUtil.shiftForward(text, insertionOffset, " \t"); diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/Fixer.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/Fixer.java index 62fee71eb863..288403ab50e5 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/Fixer.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/Fixer.java @@ -1,11 +1,11 @@ // Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.codeInsight.editorActions.smartEnter; -import com.intellij.lang.ASTNode; import com.intellij.openapi.editor.Editor; +import com.intellij.psi.PsiElement; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; public interface Fixer { - void apply(Editor editor, AbstractBasicJavaSmartEnterProcessor processor, @NotNull ASTNode astNode) throws IncorrectOperationException; + void apply(Editor editor, JavaSmartEnterProcessor processor, @NotNull PsiElement element) throws IncorrectOperationException; } \ No newline at end of file diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/ForStatementFixer.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/ForStatementFixer.java index 2eef480fe214..56c88f46d7b7 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/ForStatementFixer.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/ForStatementFixer.java @@ -1,20 +1,17 @@ // Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.codeInsight.editorActions.smartEnter; -import com.intellij.BaseJavaJspElementType; import com.intellij.application.options.CodeStyle; import com.intellij.lang.ASTNode; import com.intellij.lang.java.JavaLanguage; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.TextRange; -import com.intellij.psi.impl.source.BasicJavaAstTreeUtil; +import com.intellij.psi.*; +import com.intellij.psi.impl.source.tree.JavaJspElementType; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; -import static com.intellij.psi.impl.source.BasicJavaElementType.BASIC_EMPTY_STATEMENT; -import static com.intellij.psi.impl.source.BasicJavaElementType.BASIC_FOR_STATEMENT; - /** * {@link Fixer} that handles use-cases like below: * before: @@ -36,38 +33,37 @@ import static com.intellij.psi.impl.source.BasicJavaElementType.BASIC_FOR_STATEM public class ForStatementFixer implements Fixer { @Override - public void apply(Editor editor, AbstractBasicJavaSmartEnterProcessor processor, @NotNull ASTNode astNode) throws IncorrectOperationException { - if (!(BasicJavaAstTreeUtil.is(astNode, BASIC_FOR_STATEMENT))) { + public void apply(Editor editor, JavaSmartEnterProcessor processor, @NotNull PsiElement psiElement) throws IncorrectOperationException { + if (!(psiElement instanceof PsiForStatement forStatement)) { return; } - final ASTNode lParenth = BasicJavaAstTreeUtil.getLParenth(astNode); - final ASTNode rParenth = BasicJavaAstTreeUtil.getRParenth(astNode); + final PsiJavaToken lParenth = forStatement.getLParenth(); + final PsiJavaToken rParenth = forStatement.getRParenth(); if (lParenth == null || rParenth == null) { - final TextRange textRange = astNode.getTextRange(); + final TextRange textRange = forStatement.getTextRange(); editor.getDocument().replaceString(textRange.getStartOffset(), textRange.getEndOffset(), "for () {\n}"); processor.registerUnresolvedError(textRange.getStartOffset() + "for (".length()); return; } - final ASTNode initialization = BasicJavaAstTreeUtil.getForInitialization(astNode); + final PsiStatement initialization = forStatement.getInitialization(); if (initialization == null) { processor.registerUnresolvedError(lParenth.getTextRange().getEndOffset()); return; } - final ASTNode condition = BasicJavaAstTreeUtil.getForCondition(astNode); + final PsiExpression condition = forStatement.getCondition(); if (condition == null) { - boolean endlessLoop = BasicJavaAstTreeUtil.is(initialization, BASIC_EMPTY_STATEMENT) && - BasicJavaAstTreeUtil.getForUpdate(astNode) == null; + boolean endlessLoop = initialization instanceof PsiEmptyStatement && forStatement.getUpdate() == null; if (!endlessLoop) { - registerErrorOffset(editor, processor, initialization, astNode); + registerErrorOffset(editor, processor, initialization, forStatement); } return; } - if (BasicJavaAstTreeUtil.getForUpdate(astNode) == null) { - registerErrorOffset(editor, processor, condition, astNode); + if (forStatement.getUpdate() == null) { + registerErrorOffset(editor, processor, condition, forStatement); } } @@ -75,23 +71,26 @@ public class ForStatementFixer implements Fixer { * {@link JavaSmartEnterProcessor#registerUnresolvedError(int) registers target offset} taking care of the situation when * current code style implies white space after 'for' part's semicolon. * - * @param editor target editor - * @param processor target smart enter processor - * @param lastValidForPart last valid element of the target 'for' loop - * @param forStatement PSI element for the target 'for' loop + * @param editor target editor + * @param processor target smart enter processor + * @param lastValidForPart last valid element of the target 'for' loop + * @param forStatement PSI element for the target 'for' loop */ - private static void registerErrorOffset(@NotNull Editor editor, @NotNull AbstractBasicJavaSmartEnterProcessor processor, - @NotNull ASTNode lastValidForPart, @NotNull ASTNode forStatement) { + private static void registerErrorOffset(@NotNull Editor editor, + @NotNull JavaSmartEnterProcessor processor, + @NotNull PsiElement lastValidForPart, @NotNull PsiForStatement forStatement) + { final Project project = editor.getProject(); int offset = lastValidForPart.getTextRange().getEndOffset(); if (project != null && CodeStyle.getSettings(editor).getCommonSettings(JavaLanguage.INSTANCE).SPACE_AFTER_COMMA) { if (editor.getDocument().getCharsSequence().charAt(lastValidForPart.getTextRange().getEndOffset() - 1) != ';') { offset++; } - for (ASTNode element = lastValidForPart.getTreeNext(); - element != null && element != BasicJavaAstTreeUtil.getRParenth(forStatement) && element.getTreeParent() == forStatement; - element = element.getTreeNext()) { - if (isWhiteSpaceIncludingJsp(element) && element.getTextLength() > 0) { + for (PsiElement element = lastValidForPart.getNextSibling(); + element != null && element != forStatement.getRParenth() && element.getParent() == forStatement; + element = element.getNextSibling()) { + final ASTNode node = element.getNode(); + if (node != null && JavaJspElementType.WHITE_SPACE_BIT_SET.contains(node.getElementType()) && element.getTextLength() > 0) { offset++; break; } @@ -100,8 +99,4 @@ public class ForStatementFixer implements Fixer { processor.registerUnresolvedError(offset); } - - private static boolean isWhiteSpaceIncludingJsp(@NotNull ASTNode node) { - return BaseJavaJspElementType.WHITE_SPACE_BIT_SET.contains(node.getElementType()); - } } diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/IfConditionFixer.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/IfConditionFixer.java index 3c33604ef0d9..ed73f870badc 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/IfConditionFixer.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/IfConditionFixer.java @@ -2,56 +2,48 @@ package com.intellij.codeInsight.editorActions.smartEnter; import com.intellij.java.syntax.parser.JavaKeywords; -import com.intellij.lang.ASTNode; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; -import com.intellij.psi.JavaTokenType; -import com.intellij.psi.PsiElement; -import com.intellij.psi.impl.source.BasicJavaAstTreeUtil; +import com.intellij.psi.*; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtilCore; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; -import static com.intellij.psi.impl.source.BasicElementTypes.BASIC_JAVA_PLAIN_COMMENT_BIT_SET; -import static com.intellij.psi.impl.source.BasicJavaDocElementType.BASIC_DOC_COMMENT; -import static com.intellij.psi.impl.source.BasicJavaElementType.*; - public class IfConditionFixer implements Fixer { @Override - public void apply(Editor editor, AbstractBasicJavaSmartEnterProcessor processor, @NotNull ASTNode astNode) throws IncorrectOperationException { - if (BasicJavaAstTreeUtil.is(astNode, BASIC_IF_STATEMENT)) { + public void apply(Editor editor, JavaSmartEnterProcessor processor, + @NotNull PsiElement psiElement) throws IncorrectOperationException { + if (psiElement instanceof PsiIfStatement ifStatement) { final Document doc = editor.getDocument(); - final ASTNode rParen = BasicJavaAstTreeUtil.getRParenth(astNode); - final ASTNode lParen = BasicJavaAstTreeUtil.getLParenth(astNode); - final ASTNode condition = BasicJavaAstTreeUtil.getIfCondition(astNode); + final PsiJavaToken rParen = ifStatement.getRParenth(); + final PsiJavaToken lParen = ifStatement.getLParenth(); + final PsiExpression condition = ifStatement.getCondition(); if (condition == null) { if (lParen == null || rParen == null) { - int stopOffset = doc.getLineEndOffset(doc.getLineNumber(astNode.getTextRange().getStartOffset())); - final ASTNode then = BasicJavaAstTreeUtil.getThenBranch(astNode); + int stopOffset = doc.getLineEndOffset(doc.getLineNumber(ifStatement.getTextRange().getStartOffset())); + final PsiStatement then = ifStatement.getThenBranch(); if (then != null) { stopOffset = Math.min(stopOffset, then.getTextRange().getStartOffset()); } - stopOffset = Math.min(stopOffset, astNode.getTextRange().getEndOffset()); + stopOffset = Math.min(stopOffset, ifStatement.getTextRange().getEndOffset()); - ASTNode lastChild = astNode.getLastChildNode(); + PsiElement lastChild = ifStatement.getLastChild(); String innerComment = ""; String lastComment = ""; if (lParen != null && PsiUtilCore.getElementType(lastChild) == JavaTokenType.C_STYLE_COMMENT) { innerComment = lastChild.getText(); } - else if (BasicJavaAstTreeUtil.is(lastChild, BASIC_DOC_COMMENT) || - BasicJavaAstTreeUtil.is(lastChild, BASIC_JAVA_PLAIN_COMMENT_BIT_SET) - ) { + else if (lastChild instanceof PsiComment) { lastComment = lastChild.getText(); } String prefix = "if (" + innerComment; - doc.replaceString(astNode.getTextRange().getStartOffset(), stopOffset, prefix + ")" + lastComment); + doc.replaceString(ifStatement.getTextRange().getStartOffset(), stopOffset, prefix + ")" + lastComment); - processor.registerUnresolvedError(astNode.getTextRange().getStartOffset() + prefix.length()); + processor.registerUnresolvedError(ifStatement.getTextRange().getStartOffset() + prefix.length()); } else { processor.registerUnresolvedError(lParen.getTextRange().getEndOffset()); @@ -61,16 +53,12 @@ public class IfConditionFixer implements Fixer { doc.insertString(condition.getTextRange().getEndOffset(), ")"); } } - else if (BasicJavaAstTreeUtil.is(astNode, EXPRESSION_SET) && - BasicJavaAstTreeUtil.is(astNode.getTreeParent(), BASIC_EXPRESSION_STATEMENT)) { - PsiElement psi = BasicJavaAstTreeUtil.toPsi(astNode); - if (psi != null) { - PsiElement prevLeaf = PsiTreeUtil.prevVisibleLeaf(psi); - if (prevLeaf != null && prevLeaf.textMatches(JavaKeywords.IF)) { - Document doc = editor.getDocument(); - doc.insertString(astNode.getTextRange().getEndOffset(), ")"); - doc.insertString(astNode.getTextRange().getStartOffset(), "("); - } + else if (psiElement instanceof PsiExpression && psiElement.getParent() instanceof PsiExpressionStatement) { + PsiElement prevLeaf = PsiTreeUtil.prevVisibleLeaf(psiElement); + if (prevLeaf != null && prevLeaf.textMatches(JavaKeywords.IF)) { + Document doc = editor.getDocument(); + doc.insertString(psiElement.getTextRange().getEndOffset(), ")"); + doc.insertString(psiElement.getTextRange().getStartOffset(), "("); } } } diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/JavaSmartEnterProcessor.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/JavaSmartEnterProcessor.java index 2aa8ecc90849..4c84472c2923 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/JavaSmartEnterProcessor.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/JavaSmartEnterProcessor.java @@ -1,54 +1,75 @@ // 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.codeInsight.editorActions.smartEnter; +import com.intellij.application.options.CodeStyle; +import com.intellij.codeInsight.CodeInsightFrontbackUtil; +import com.intellij.codeInsight.lookup.LookupManager; import com.intellij.internal.statistic.eventLog.EventLogGroup; import com.intellij.internal.statistic.eventLog.events.EventId1; import com.intellij.internal.statistic.eventLog.events.StringEventField; import com.intellij.internal.statistic.service.fus.collectors.CounterUsagesCollector; -import com.intellij.lang.ASTNode; +import com.intellij.lang.java.JavaLanguage; +import com.intellij.openapi.actionSystem.IdeActions; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.RangeMarker; import com.intellij.openapi.editor.actionSystem.EditorActionHandler; +import com.intellij.openapi.editor.actionSystem.EditorActionManager; +import com.intellij.openapi.editor.ex.util.EditorUtil; import com.intellij.openapi.project.Project; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiImportStatementBase; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.*; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.codeStyle.CommonCodeStyleSettings; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.PsiUtil; +import com.intellij.psi.util.PsiUtilCore; +import com.intellij.util.IncorrectOperationException; import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.text.CharArrayUtil; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import java.util.ArrayList; import java.util.List; -public final class JavaSmartEnterProcessor extends AbstractBasicJavaSmartEnterProcessor { +import static com.intellij.patterns.PsiJavaPatterns.psiElement; + +public class JavaSmartEnterProcessor extends SmartEnterProcessor { + private static final Logger LOG = Logger.getInstance(JavaSmartEnterProcessor.class); private static final List ourFixers = - List.of( - new LiteralFixer(), - new MethodCallFixer(), - new IfConditionFixer(), - new ForStatementFixer(), - new TernaryColonFixer(), - new WhileConditionFixer(), - new CatchDeclarationFixer(), - new SwitchExpressionFixer(), - new SwitchLabelColonFixer(), - new DoWhileConditionFixer(), - new BlockBraceFixer(), - new MissingIfBranchesFixer(), - new MissingTryBodyFixer(), - new MissingSwitchBodyFixer(), - new MissingLambdaBodyFixer(), - new MissingCatchBodyFixer(), - new MissingSynchronizedBodyFixer(), - new MissingLoopBodyFixer(), - new ParameterListFixer(), - new MissingCommaFixer(), - new MissingMethodBodyFixer(), - new MissingClassBodyFixer(), - new MissingReturnExpressionFixer(), - new MissingThrowExpressionFixer(), - new ParenthesizedFixer(), - new SemicolonFixer(), - new MissingArrayInitializerBraceFixer(), - new MissingArrayConstructorBracketFixer(), - new EnumFieldFixer()); + List.of(new LiteralFixer(), + new MethodCallFixer(), + new IfConditionFixer(), + new ForStatementFixer(), + new TernaryColonFixer(), + new WhileConditionFixer(), + new CatchDeclarationFixer(), + new SwitchExpressionFixer(), + new SwitchLabelColonFixer(), + new DoWhileConditionFixer(), + new BlockBraceFixer(), + new MissingIfBranchesFixer(), + new MissingTryBodyFixer(), + new MissingSwitchBodyFixer(), + new MissingLambdaBodyFixer(), + new MissingCatchBodyFixer(), + new MissingSynchronizedBodyFixer(), + new MissingLoopBodyFixer(), + new ParameterListFixer(), + new MissingCommaFixer(), + new MissingMethodBodyFixer(), + new MissingClassBodyFixer(), + new MissingReturnExpressionFixer(), + new MissingThrowExpressionFixer(), + new ParenthesizedFixer(), + new SemicolonFixer(), + new MissingArrayInitializerBraceFixer(), + new MissingArrayConstructorBracketFixer(), + new EnumFieldFixer()); private static final EnterProcessor[] ourEnterProcessors = { new CommentBreakerEnterProcessor(), new AfterSemicolonEnterProcessor(), @@ -57,44 +78,305 @@ public final class JavaSmartEnterProcessor extends AbstractBasicJavaSmartEnterPr }; private static final EnterProcessor[] ourAfterCompletionEnterProcessors = { new AfterSemicolonEnterProcessor(), - new ASTNodeEnterProcessor() { + new EnterProcessor() { @Override - public boolean doEnter(@NotNull Editor editor, @NotNull ASTNode astNode, boolean isModified) { - return PlainEnterProcessor.expandCodeBlock(editor, astNode); + public boolean doEnter(Editor editor, PsiElement psiElement, boolean isModified) { + return PlainEnterProcessor.expandCodeBlock(editor, psiElement); } } }; - public JavaSmartEnterProcessor() { - super(ourFixers, ourEnterProcessors, ourAfterCompletionEnterProcessors, - new JavadocFixer(), - new CommentBreakerEnterProcessor() - ); + private int myFirstErrorOffset = Integer.MAX_VALUE; + private boolean mySkipEnter; + private static final int MAX_ATTEMPTS = 20; + private static final Key SMART_ENTER_TIMESTAMP = Key.create("smartEnterOriginalTimestamp"); + + private static class TooManyAttemptsException extends Exception { + } + + private final JavadocFixer myJavadocFixer = new JavadocFixer(); + + @Override + public boolean process(@NotNull final Project project, @NotNull final Editor editor, @NotNull final PsiFile psiFile) { + return invokeProcessor(editor, psiFile, false); } @Override - protected void log(@NotNull Fixer fixer, @NotNull Project project) { - FixerUsageCollector.log(project, fixer); + public boolean processAfterCompletion(@NotNull Editor editor, @NotNull PsiFile psiFile) { + return invokeProcessor(editor, psiFile, true); + } + + private boolean invokeProcessor(Editor editor, PsiFile psiFile, boolean afterCompletion) { + final Document document = editor.getDocument(); + final CharSequence textForRollback = document.getImmutableCharSequence(); + try { + editor.putUserData(SMART_ENTER_TIMESTAMP, editor.getDocument().getModificationStamp()); + myFirstErrorOffset = Integer.MAX_VALUE; + mySkipEnter = false; + process(editor, psiFile, 0, afterCompletion); + } + catch (TooManyAttemptsException e) { + document.replaceString(0, document.getTextLength(), textForRollback); + } + finally { + editor.putUserData(SMART_ENTER_TIMESTAMP, null); + } + return true; + } + + private void process(@NotNull final Editor editor, @NotNull final PsiFile file, final int attempt, boolean afterCompletion) + throws TooManyAttemptsException { + if (attempt > MAX_ATTEMPTS) throw new TooManyAttemptsException(); + + try { + commit(editor); + if (myFirstErrorOffset != Integer.MAX_VALUE) { + editor.getCaretModel().moveToOffset(myFirstErrorOffset); + } + + myFirstErrorOffset = Integer.MAX_VALUE; + + PsiElement atCaret = getStatementAtCaret(editor, file); + if (atCaret == null) { + if (myJavadocFixer.process(editor, file)) { + return; + } + if (!new CommentBreakerEnterProcessor().doEnter(editor, file, false)) { + plainEnter(editor); + } + return; + } + + List queue = new ArrayList<>(); + collectAllElements(atCaret, queue, true); + queue.add(atCaret); + + for (PsiElement psiElement : queue) { + for (Fixer fixer : ourFixers) { + Document document = editor.getDocument(); + int offset = myFirstErrorOffset; + long stamp = document.getModificationStamp(); + fixer.apply(editor, this, psiElement); + Project project = file.getProject(); + if (document.getModificationStamp() != stamp || offset != myFirstErrorOffset) { + FixerUsageCollector.log(project, fixer); + } + if (LookupManager.getInstance(project).getActiveLookup() != null) { + return; + } + if (isUncommited(project) || !psiElement.isValid()) { + moveCaretInsideBracesIfAny(editor, file); + process(editor, file, attempt + 1, afterCompletion); + return; + } + } + } + + doEnter(atCaret, editor, afterCompletion); + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + } + + + @Override + protected void reformat(PsiElement atCaret) throws IncorrectOperationException { + if (atCaret == null) { + return; + } + PsiElement parent = atCaret.getParent(); + if (parent instanceof PsiForStatement) { + atCaret = parent; + } + + if (parent instanceof PsiIfStatement && atCaret == ((PsiIfStatement)parent).getElseBranch()) { + PsiFile file = atCaret.getContainingFile(); + Document document = file.getViewProvider().getDocument(); + if (document != null) { + TextRange elseIfRange = atCaret.getTextRange(); + int lineStart = document.getLineStartOffset(document.getLineNumber(elseIfRange.getStartOffset())); + CodeStyleManager.getInstance(atCaret.getProject()).reformatText(file, lineStart, elseIfRange.getEndOffset()); + return; + } + } + + super.reformat(atCaret); + } + + + private void doEnter(PsiElement atCaret, Editor editor, boolean afterCompletion) throws IncorrectOperationException { + final PsiFile psiFile = atCaret.getContainingFile(); + + if (myFirstErrorOffset != Integer.MAX_VALUE) { + editor.getCaretModel().moveToOffset(myFirstErrorOffset); + reformat(atCaret); + return; + } + + final RangeMarker rangeMarker = createRangeMarker(atCaret); + reformat(atCaret); + commit(editor); + + if (!mySkipEnter) { + atCaret = + CodeInsightFrontbackUtil.findElementInRange(psiFile, rangeMarker.getStartOffset(), rangeMarker.getEndOffset(), atCaret.getClass()); + for (EnterProcessor processor : afterCompletion ? ourAfterCompletionEnterProcessors : ourEnterProcessors) { + if (atCaret == null) { + // Can't restore element at caret after enter processor execution! + break; + } + + if (processor.doEnter(editor, atCaret, isModified(editor))) { + rangeMarker.dispose(); + return; + } + } + + if (!isModified(editor) && !afterCompletion) { + plainEnter(editor); + } + else { + if (myFirstErrorOffset == Integer.MAX_VALUE) { + editor.getCaretModel().moveToOffset(rangeMarker.getEndOffset()); + } + else { + editor.getCaretModel().moveToOffset(myFirstErrorOffset); + } + } + } + rangeMarker.dispose(); + } + + private static void collectAllElements(PsiElement atCaret, List res, boolean recurse) { + res.addFirst(atCaret); + if (doNotStepInto(atCaret)) { + if (!recurse) return; + recurse = false; + } + + final PsiElement[] children = atCaret.getChildren(); + for (PsiElement child : children) { + if (atCaret instanceof PsiStatement && child instanceof PsiStatement && + !(atCaret instanceof PsiForStatement && child == ((PsiForStatement)atCaret).getInitialization())) { + continue; + } + collectAllElements(child, res, recurse); + } + } + + private static boolean doNotStepInto(PsiElement element) { + return element instanceof PsiClass || + element instanceof PsiCodeBlock || + element instanceof PsiStatement || + element instanceof PsiMethod; } @Override - protected boolean isImportStatementBase(PsiElement el) { - return el instanceof PsiImportStatementBase; + @Nullable + protected PsiElement getStatementAtCaret(Editor editor, PsiFile psiFile) { + PsiElement atCaret = super.getStatementAtCaret(editor, psiFile); + + if (atCaret instanceof PsiWhiteSpace) return null; + if (PsiUtil.isJavaToken(atCaret, JavaTokenType.RBRACE)) { + atCaret = atCaret.getParent(); + boolean expressionEndingWithBrace = atCaret instanceof PsiAnonymousClass || + atCaret instanceof PsiArrayInitializerExpression || + atCaret instanceof PsiCodeBlock && ( + atCaret.getParent() instanceof PsiLambdaExpression || + atCaret.getParent() instanceof PsiSwitchExpression + ); + if (!expressionEndingWithBrace) return null; + } + + for (PsiElement each : SyntaxTraverser.psiApi().parents(atCaret).skip(1)) { + if (each instanceof PsiMember || + each instanceof PsiImportStatementBase || + each instanceof PsiPackageStatement || + each instanceof PsiAnnotation && PsiTreeUtil.hasErrorElements(each)) { + return each; + } + if (each instanceof PsiCodeBlock || each instanceof PsiComment) { + return null; + } + if (each instanceof PsiStatement) { + return each.getParent() instanceof PsiForStatement && !PsiTreeUtil.hasErrorElements(each) ? each.getParent() : each; + } + if (each instanceof PsiConditionalExpression && PsiUtilCore.hasErrorElementChild(each)) { + return each; + } + } + + return null; } - protected static void plainEnter(final @NotNull Editor editor) { - AbstractBasicJavaSmartEnterProcessor.plainEnter(editor); + protected void moveCaretInsideBracesIfAny(@NotNull final Editor editor, @NotNull final PsiFile file) throws IncorrectOperationException { + int caretOffset = editor.getCaretModel().getOffset(); + final CharSequence chars = editor.getDocument().getCharsSequence(); + + if (CharArrayUtil.regionMatches(chars, caretOffset, "{}")) { + caretOffset += 2; + } + else if (CharArrayUtil.regionMatches(chars, caretOffset, "{\n}")) { + caretOffset += 3; + } + + caretOffset = CharArrayUtil.shiftBackward(chars, caretOffset - 1, " \t") + 1; + + if (CharArrayUtil.regionMatches(chars, caretOffset - "{}".length(), "{}") || + CharArrayUtil.regionMatches(chars, caretOffset - "{\n}".length(), "{\n}")) { + commit(editor); + final CommonCodeStyleSettings settings = CodeStyle.getSettings(file).getCommonSettings(JavaLanguage.INSTANCE); + final boolean old = settings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE; + settings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE = false; + PsiElement leaf = file.findElementAt(caretOffset - 1); + PsiElement elt = PsiTreeUtil.getParentOfType(leaf, PsiCodeBlock.class); + if (elt == null && leaf != null && leaf.getParent() instanceof PsiClass) { + elt = leaf.getParent(); + } + reformat(elt); + settings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE = old; + editor.getCaretModel().moveToOffset(caretOffset - 1); + + reformatBlockParentIfNeeded(editor, file); + } + } + + private void reformatBlockParentIfNeeded(@NotNull Editor editor, @NotNull PsiFile file) { + commit(editor); + PsiCodeBlock block = PsiTreeUtil.findElementOfClassAtOffset(file, editor.getCaretModel().getOffset(), PsiCodeBlock.class, false); + if (block != null && psiElement().withParents(PsiBlockStatement.class, PsiForStatement.class).accepts(block)) { + reformat(block.getParent().getParent()); + } + if (block != null && block.getParent() instanceof PsiSwitchExpression switchExpression) { + reformat(switchExpression); + } + } + + public void registerUnresolvedError(int offset) { + if (myFirstErrorOffset > offset) { + myFirstErrorOffset = offset; + } + } + + public void setSkipEnter(boolean skipEnter) { + mySkipEnter = skipEnter; + } + + protected static void plainEnter(@NotNull final Editor editor) { + getEnterHandler().execute(editor, editor.getCaretModel().getCurrentCaret(), EditorUtil.getEditorDataContext(editor)); } protected static EditorActionHandler getEnterHandler() { - return AbstractBasicJavaSmartEnterProcessor.getEnterHandler(); + return EditorActionManager.getInstance().getActionHandler(IdeActions.ACTION_EDITOR_START_NEW_LINE); } - protected static boolean isModified(final @NotNull Editor editor) { - return AbstractBasicJavaSmartEnterProcessor.isModified(editor); + protected static boolean isModified(@NotNull final Editor editor) { + final Long timestamp = editor.getUserData(SMART_ENTER_TIMESTAMP); + if (timestamp == null) return true; + return editor.getDocument().getModificationStamp() != timestamp.longValue(); } - // looks like it might be called on both FE and BE sides. be careful with 2x numbers. private static final class FixerUsageCollector extends CounterUsagesCollector { private static final EventLogGroup GROUP = new EventLogGroup("java.smart.enter.fixer", 3); private static final EventId1 USED = GROUP.registerEvent("fixer_used", new StringEventField.ValidatedByAllowedValues( diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/LeaveCodeBlockEnterProcessor.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/LeaveCodeBlockEnterProcessor.java index 53490ce15453..b2c12a82aafb 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/LeaveCodeBlockEnterProcessor.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/LeaveCodeBlockEnterProcessor.java @@ -1,4 +1,4 @@ -// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +// 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.codeInsight.editorActions.smartEnter; import com.intellij.ide.DataManager; @@ -8,32 +8,35 @@ import com.intellij.openapi.actionSystem.IdeActions; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.actionSystem.EditorActionHandler; import com.intellij.openapi.editor.actionSystem.EditorActionManager; -import com.intellij.psi.impl.source.BasicJavaAstTreeUtil; -import com.intellij.psi.tree.ParentAwareTokenSet; +import com.intellij.psi.PsiCodeBlock; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiReturnStatement; +import com.intellij.psi.PsiThrowStatement; +import com.intellij.psi.impl.source.tree.JavaElementType; +import com.intellij.psi.tree.TokenSet; import com.intellij.util.text.CharArrayUtil; -import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import static com.intellij.psi.impl.source.BasicJavaElementType.*; - -public class LeaveCodeBlockEnterProcessor implements ASTNodeEnterProcessor { - private final ParentAwareTokenSet CONTROL_FLOW_ELEMENT_TYPES = - ParentAwareTokenSet.create(BASIC_IF_STATEMENT, BASIC_WHILE_STATEMENT, BASIC_DO_WHILE_STATEMENT, BASIC_FOR_STATEMENT, - BASIC_FOREACH_STATEMENT); +public class LeaveCodeBlockEnterProcessor implements EnterProcessor { + private static final TokenSet CONTROL_FLOW_ELEMENT_TYPES = TokenSet.create( + JavaElementType.IF_STATEMENT, JavaElementType.WHILE_STATEMENT, JavaElementType.DO_WHILE_STATEMENT, JavaElementType.FOR_STATEMENT, + JavaElementType.FOREACH_STATEMENT + ); @Override - public boolean doEnter(@NotNull Editor editor, @NotNull ASTNode astNode, boolean isModified) { - ASTNode parent = astNode.getTreeParent(); - if (!(BasicJavaAstTreeUtil.is(parent, BASIC_CODE_BLOCK))) { + public boolean doEnter(Editor editor, PsiElement psiElement, boolean isModified) { + PsiElement parent = psiElement.getParent(); + if (!(parent instanceof PsiCodeBlock)) { return false; } - if (CONTROL_FLOW_ELEMENT_TYPES.contains(astNode.getElementType())) { + final ASTNode node = psiElement.getNode(); + if (node != null && CONTROL_FLOW_ELEMENT_TYPES.contains(node.getElementType())) { return false; } - boolean leaveCodeBlock = isControlFlowBreak(astNode); + boolean leaveCodeBlock = isControlFlowBreak(psiElement); if (!leaveCodeBlock) { return false; } @@ -77,9 +80,9 @@ public class LeaveCodeBlockEnterProcessor implements ASTNodeEnterProcessor { * [caret] * } * + * */ - private static boolean isControlFlowBreak(@Nullable ASTNode element) { - return BasicJavaAstTreeUtil.is(element, BASIC_RETURN_STATEMENT) || - BasicJavaAstTreeUtil.is(element, BASIC_THROW_STATEMENT); + private static boolean isControlFlowBreak(@Nullable PsiElement element) { + return element instanceof PsiReturnStatement || element instanceof PsiThrowStatement; } } diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/LiteralFixer.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/LiteralFixer.java index 11dee639c8ae..125aabdf0419 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/LiteralFixer.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/LiteralFixer.java @@ -1,24 +1,28 @@ // Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.codeInsight.editorActions.smartEnter; -import com.intellij.lang.ASTNode; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.JavaTokenType; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiJavaToken; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; public class LiteralFixer implements Fixer { @Override - public void apply(Editor editor, AbstractBasicJavaSmartEnterProcessor processor, @NotNull ASTNode astNode) + public void apply(Editor editor, JavaSmartEnterProcessor processor, + @NotNull PsiElement psiElement) throws IncorrectOperationException { - if (astNode.getElementType() == JavaTokenType.STRING_LITERAL && - !StringUtil.endsWithChar(astNode.getText(), '\"')) { - editor.getDocument().insertString(astNode.getTextRange().getEndOffset(), "\""); - } - else if (astNode.getElementType() == JavaTokenType.CHARACTER_LITERAL && - !StringUtil.endsWithChar(astNode.getText(), '\'')) { - editor.getDocument().insertString(astNode.getTextRange().getEndOffset(), "'"); + if (psiElement instanceof PsiJavaToken) { + if (((PsiJavaToken)psiElement).getTokenType() == JavaTokenType.STRING_LITERAL && + !StringUtil.endsWithChar(psiElement.getText(), '\"')) { + editor.getDocument().insertString(psiElement.getTextRange().getEndOffset(), "\""); + } + else if (((PsiJavaToken)psiElement).getTokenType() == JavaTokenType.CHARACTER_LITERAL && + !StringUtil.endsWithChar(psiElement.getText(), '\'')) { + editor.getDocument().insertString(psiElement.getTextRange().getEndOffset(), "'"); + } } } } diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MethodCallFixer.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MethodCallFixer.java index ad1904449768..bacff47245e7 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MethodCallFixer.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MethodCallFixer.java @@ -3,13 +3,11 @@ package com.intellij.codeInsight.editorActions.smartEnter; import com.intellij.codeInspection.dataFlow.rangeSet.LongRangeSet; import com.intellij.codeInspection.dataFlow.rangeSet.LongRangeType; -import com.intellij.lang.ASTNode; import com.intellij.lang.java.JavaLanguage; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.DumbService; import com.intellij.openapi.util.TextRange; import com.intellij.psi.*; -import com.intellij.psi.impl.source.BasicJavaAstTreeUtil; import com.intellij.psi.infos.CandidateInfo; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.ArrayUtil; @@ -20,8 +18,7 @@ import org.jetbrains.annotations.NotNull; public class MethodCallFixer implements Fixer { @Override - public void apply(Editor editor, AbstractBasicJavaSmartEnterProcessor processor, @NotNull ASTNode astNode) throws IncorrectOperationException { - PsiElement psiElement = BasicJavaAstTreeUtil.toPsi(astNode); + public void apply(Editor editor, JavaSmartEnterProcessor processor, @NotNull PsiElement psiElement) throws IncorrectOperationException { PsiExpressionList argList = null; if (psiElement instanceof PsiMethodCallExpression && psiElement.getLanguage().equals(JavaLanguage.INSTANCE)) { argList = ((PsiMethodCallExpression)psiElement).getArgumentList(); diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingArrayConstructorBracketFixer.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingArrayConstructorBracketFixer.java index a5ac96006fd3..2cd36d099e61 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingArrayConstructorBracketFixer.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingArrayConstructorBracketFixer.java @@ -1,31 +1,29 @@ // Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.codeInsight.editorActions.smartEnter; -import com.intellij.lang.ASTNode; import com.intellij.openapi.editor.Editor; import com.intellij.psi.JavaTokenType; -import com.intellij.psi.impl.source.BasicJavaAstTreeUtil; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiNewExpression; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; -import static com.intellij.psi.impl.source.BasicJavaElementType.BASIC_NEW_EXPRESSION; - public class MissingArrayConstructorBracketFixer implements Fixer { - @Override - public void apply(Editor editor, AbstractBasicJavaSmartEnterProcessor processor, @NotNull ASTNode astNode) throws IncorrectOperationException { - if (!(BasicJavaAstTreeUtil.is(astNode, BASIC_NEW_EXPRESSION))) return; + public void apply(Editor editor, JavaSmartEnterProcessor processor, @NotNull PsiElement psiElement) + throws IncorrectOperationException { + if (!(psiElement instanceof PsiNewExpression expr)) return; int count = 0; - for (ASTNode element = astNode.getFirstChildNode(); element != null; element = element.getTreeNext()) { - if (BasicJavaAstTreeUtil.is(element, JavaTokenType.LBRACKET)) { + for (PsiElement element = expr.getFirstChild(); element != null; element = element.getNextSibling()) { + if (element.getNode().getElementType() == JavaTokenType.LBRACKET) { count++; } - else if (BasicJavaAstTreeUtil.is(element, JavaTokenType.RBRACKET)) { + else if (element.getNode().getElementType() == JavaTokenType.RBRACKET) { count--; } } if (count > 0) { - editor.getDocument().insertString(astNode.getTextRange().getEndOffset(), "]"); + editor.getDocument().insertString(psiElement.getTextRange().getEndOffset(), "]"); } } } \ No newline at end of file diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingArrayInitializerBraceFixer.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingArrayInitializerBraceFixer.java index 67a61856ac09..a9232291453c 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingArrayInitializerBraceFixer.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingArrayInitializerBraceFixer.java @@ -2,49 +2,35 @@ package com.intellij.codeInsight.editorActions.smartEnter; import com.intellij.codeInsight.editorActions.enter.EnterAfterUnmatchedBraceHandler; -import com.intellij.lang.ASTNode; import com.intellij.openapi.editor.Editor; -import com.intellij.psi.JavaTokenType; -import com.intellij.psi.PsiElement; -import com.intellij.psi.TokenType; -import com.intellij.psi.impl.source.BasicJavaAstTreeUtil; +import com.intellij.psi.*; import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.PsiUtil; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; -import static com.intellij.psi.impl.source.BasicJavaElementType.BASIC_ANNOTATION_ARRAY_INITIALIZER; -import static com.intellij.psi.impl.source.BasicJavaElementType.BASIC_ARRAY_INITIALIZER_EXPRESSION; - public class MissingArrayInitializerBraceFixer implements Fixer { - @Override - public void apply(Editor editor, AbstractBasicJavaSmartEnterProcessor processor, @NotNull ASTNode astNode) throws IncorrectOperationException { - if (!( - BasicJavaAstTreeUtil.is(astNode, BASIC_ARRAY_INITIALIZER_EXPRESSION) || - BasicJavaAstTreeUtil.is(astNode, BASIC_ANNOTATION_ARRAY_INITIALIZER))) { - return; - } - ASTNode child = astNode.getFirstChildNode(); - if (!child.getElementType().equals(JavaTokenType.LBRACE)) return; - PsiElement psi = BasicJavaAstTreeUtil.toPsi(astNode); - if (psi == null) { - return; - } + public void apply(Editor editor, JavaSmartEnterProcessor processor, @NotNull PsiElement psiElement) + throws IncorrectOperationException { + if (!(psiElement instanceof PsiArrayInitializerExpression || psiElement instanceof PsiArrayInitializerMemberValue)) return; + PsiElement child = psiElement.getFirstChild(); + if (!PsiUtil.isJavaToken(child, JavaTokenType.LBRACE)) return; if (!EnterAfterUnmatchedBraceHandler.isAfterUnmatchedLBrace(editor, child.getTextRange().getEndOffset(), - psi.getContainingFile().getFileType())) { + psiElement.getContainingFile().getFileType())) { return; } - ASTNode anchor = BasicJavaAstTreeUtil.findChildByType(astNode, TokenType.ERROR_ELEMENT); + PsiElement anchor = PsiTreeUtil.getChildOfType(psiElement, PsiErrorElement.class); if (anchor == null) { - PsiElement last = PsiTreeUtil.getDeepestVisibleLast(psi); - while (last != null && last.getNode().getElementType().equals(JavaTokenType.RBRACE)) { + PsiElement last = PsiTreeUtil.getDeepestVisibleLast(psiElement); + while (PsiUtil.isJavaToken(last, JavaTokenType.RBRACE)) { last = PsiTreeUtil.prevCodeLeaf(last); } - if (last != null && PsiTreeUtil.isAncestor(psi, last, true)) { - anchor = last.getNode(); + if (last != null && PsiTreeUtil.isAncestor(psiElement, last, true)) { + anchor = last; } } - int endOffset = (anchor != null ? anchor : astNode).getTextRange().getEndOffset(); + int endOffset = (anchor != null ? anchor : psiElement).getTextRange().getEndOffset(); editor.getDocument().insertString(endOffset, "}"); } } \ No newline at end of file diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingCatchBodyFixer.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingCatchBodyFixer.java index 1e3f5683d4c5..b4563c72d0ef 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingCatchBodyFixer.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingCatchBodyFixer.java @@ -1,26 +1,30 @@ // Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.codeInsight.editorActions.smartEnter; -import com.intellij.lang.ASTNode; +import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; -import com.intellij.psi.impl.source.BasicJavaAstTreeUtil; +import com.intellij.psi.PsiCatchSection; +import com.intellij.psi.PsiCodeBlock; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiJavaToken; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; -import static com.intellij.psi.impl.source.BasicJavaElementType.BASIC_CATCH_SECTION; - public class MissingCatchBodyFixer implements Fixer { @Override - public void apply(Editor editor, AbstractBasicJavaSmartEnterProcessor processor, @NotNull ASTNode astNode) throws IncorrectOperationException { - if (!(BasicJavaAstTreeUtil.is(astNode, BASIC_CATCH_SECTION))) return; + public void apply(Editor editor, JavaSmartEnterProcessor processor, @NotNull PsiElement psiElement) + throws IncorrectOperationException { + if (!(psiElement instanceof PsiCatchSection catchSection)) return; - ASTNode body = BasicJavaAstTreeUtil.getCatchBlock(astNode); - if (body != null && BasicJavaAstTreeUtil.getLBrace(body) != null && BasicJavaAstTreeUtil.getRBrace(body) != null) return; + final Document doc = editor.getDocument(); - final ASTNode rParenth = BasicJavaAstTreeUtil.getRParenth(astNode); + PsiCodeBlock body = catchSection.getCatchBlock(); + if (body != null && body.getLBrace() != null && body.getRBrace() != null) return; + + final PsiJavaToken rParenth = catchSection.getRParenth(); if (rParenth == null) return; - processor.insertBraces(editor, rParenth.getTextRange().getEndOffset()); + doc.insertString(rParenth.getTextRange().getEndOffset(), "{}"); } } \ No newline at end of file diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingClassBodyFixer.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingClassBodyFixer.java index 24fd930745dc..8a55af78bcd7 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingClassBodyFixer.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingClassBodyFixer.java @@ -1,49 +1,41 @@ // Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.codeInsight.editorActions.smartEnter; -import com.intellij.lang.ASTNode; import com.intellij.openapi.editor.Editor; -import com.intellij.psi.JavaTokenType; -import com.intellij.psi.TokenType; -import com.intellij.psi.impl.source.BasicJavaAstTreeUtil; +import com.intellij.psi.*; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; -import static com.intellij.psi.impl.source.BasicJavaElementType.*; - public class MissingClassBodyFixer implements Fixer { @Override - public void apply(Editor editor, AbstractBasicJavaSmartEnterProcessor processor, @NotNull ASTNode astNode) throws IncorrectOperationException { - if (BasicJavaAstTreeUtil.is(astNode, BASIC_RECORD_COMPONENT)) { - astNode = BasicJavaAstTreeUtil.getRecordComponentContainingClass(astNode); - } - if (!(BasicJavaAstTreeUtil.is(astNode, CLASS_SET)) || - BasicJavaAstTreeUtil.is(astNode, BASIC_TYPE_PARAMETER)) { - return; + public void apply(Editor editor, JavaSmartEnterProcessor processor, @NotNull PsiElement psiElement) + throws IncorrectOperationException { + if (psiElement instanceof PsiRecordComponent recordComponent) { + psiElement = recordComponent.getContainingClass(); } + if (!(psiElement instanceof PsiClass psiClass) || psiElement instanceof PsiTypeParameter) return; - if (BasicJavaAstTreeUtil.getLBrace(astNode) == null && astNode != null) { - ASTNode lastChild = astNode.getLastChildNode(); - int offset = astNode.getTextRange().getEndOffset(); - if (BasicJavaAstTreeUtil.is(lastChild, TokenType.ERROR_ELEMENT)) { - ASTNode previous = lastChild.getTreePrev(); - if (BasicJavaAstTreeUtil.isWhiteSpace(previous)) { + if (psiClass.getLBrace() == null) { + PsiElement lastChild = psiClass.getLastChild(); + int offset = psiClass.getTextRange().getEndOffset(); + if (lastChild instanceof PsiErrorElement) { + PsiElement previous = lastChild.getPrevSibling(); + if (previous instanceof PsiWhiteSpace) { offset = previous.getTextRange().getStartOffset(); } else { offset = lastChild.getTextRange().getStartOffset(); } } - if (BasicJavaAstTreeUtil.isInterfaceEnumClassOrRecord(astNode, JavaTokenType.RECORD_KEYWORD) && - BasicJavaAstTreeUtil.getRecordHeader(astNode) == null) { + if (psiClass.isRecord() && psiClass.getRecordHeader() == null) { editor.getDocument().insertString(offset, "() {}"); editor.getCaretModel().moveToOffset(offset + 1); processor.setSkipEnter(true); } else { - processor.insertBracesWithNewLine(editor, offset); - editor.getCaretModel().moveToOffset(offset + 1); + editor.getDocument().insertString(offset, "{\n}"); + editor.getCaretModel().moveToOffset(offset); } } } diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingCommaFixer.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingCommaFixer.java index 8a074a8bd948..fb0f0e568286 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingCommaFixer.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingCommaFixer.java @@ -2,10 +2,8 @@ package com.intellij.codeInsight.editorActions.smartEnter; import com.intellij.core.JavaPsiBundle; -import com.intellij.lang.ASTNode; import com.intellij.openapi.editor.Editor; import com.intellij.psi.*; -import com.intellij.psi.impl.source.BasicJavaAstTreeUtil; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; import com.intellij.util.IncorrectOperationException; @@ -13,8 +11,8 @@ import org.jetbrains.annotations.NotNull; public class MissingCommaFixer implements Fixer { @Override - public void apply(Editor editor, AbstractBasicJavaSmartEnterProcessor processor, @NotNull ASTNode astNode) throws IncorrectOperationException { - PsiElement psiElement = BasicJavaAstTreeUtil.toPsi(astNode); + public void apply(Editor editor, JavaSmartEnterProcessor processor, @NotNull PsiElement psiElement) + throws IncorrectOperationException { if (!(psiElement instanceof PsiErrorElement) || !((PsiErrorElement)psiElement).getErrorDescription().equals(JavaPsiBundle.message("expected.comma.or.rparen"))) { return; diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingIfBranchesFixer.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingIfBranchesFixer.java index f94ab1869473..0c9bd65162c5 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingIfBranchesFixer.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingIfBranchesFixer.java @@ -2,41 +2,35 @@ package com.intellij.codeInsight.editorActions.smartEnter; import com.intellij.java.syntax.parser.JavaKeywords; -import com.intellij.lang.ASTNode; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; -import com.intellij.psi.impl.source.BasicJavaAstTreeUtil; +import com.intellij.psi.*; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import static com.intellij.psi.impl.source.BasicJavaElementType.BASIC_BLOCK_STATEMENT; -import static com.intellij.psi.impl.source.BasicJavaElementType.BASIC_IF_STATEMENT; - public class MissingIfBranchesFixer implements Fixer { @Override - public void apply(Editor editor, AbstractBasicJavaSmartEnterProcessor processor, @NotNull ASTNode astNode) throws IncorrectOperationException { - if (!(BasicJavaAstTreeUtil.is(astNode, BASIC_IF_STATEMENT))) return; + public void apply(Editor editor, JavaSmartEnterProcessor processor, @NotNull PsiElement psiElement) + throws IncorrectOperationException { + if (!(psiElement instanceof PsiIfStatement ifStatement)) return; final Document doc = editor.getDocument(); - final ASTNode elseElement = BasicJavaAstTreeUtil.getElseElement(astNode); + final PsiKeyword elseElement = ifStatement.getElseElement(); if (elseElement != null) { - handleBranch(doc, astNode, elseElement, BasicJavaAstTreeUtil.getElseBranch(astNode)); + handleBranch(doc, ifStatement, elseElement, ifStatement.getElseBranch()); } - ASTNode rParenth = BasicJavaAstTreeUtil.getRParenth(astNode); + PsiJavaToken rParenth = ifStatement.getRParenth(); assert rParenth != null; - handleBranch(doc, astNode, rParenth, BasicJavaAstTreeUtil.getThenBranch(astNode)); + handleBranch(doc, ifStatement, rParenth, ifStatement.getThenBranch()); } private static void handleBranch(@NotNull Document doc, - @NotNull ASTNode ifStatement, - @NotNull ASTNode beforeBranch, - @Nullable ASTNode branch) { - if (BasicJavaAstTreeUtil.is(branch, BASIC_BLOCK_STATEMENT) || - JavaKeywords.ELSE.equals(beforeBranch.getText()) && BasicJavaAstTreeUtil.is(branch, BASIC_IF_STATEMENT)) { - return; - } + @NotNull PsiIfStatement ifStatement, + @NotNull PsiElement beforeBranch, + @Nullable PsiStatement branch) { + if (branch instanceof PsiBlockStatement || beforeBranch.textMatches(JavaKeywords.ELSE) && branch instanceof PsiIfStatement) return; boolean transformingOneLiner = branch != null && (startLine(doc, beforeBranch) == startLine(doc, branch) || startCol(doc, ifStatement) < startCol(doc, branch)); @@ -49,12 +43,12 @@ public class MissingIfBranchesFixer implements Fixer { } } - private static int startLine(Document doc, @NotNull ASTNode astNode) { - return doc.getLineNumber(astNode.getTextRange().getStartOffset()); + private static int startLine(Document doc, @NotNull PsiElement psiElement) { + return doc.getLineNumber(psiElement.getTextRange().getStartOffset()); } - private static int startCol(Document doc, @NotNull ASTNode astNode) { - int offset = astNode.getTextRange().getStartOffset(); + private static int startCol(Document doc, @NotNull PsiElement psiElement) { + int offset = psiElement.getTextRange().getStartOffset(); return offset - doc.getLineStartOffset(doc.getLineNumber(offset)); } } diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingLambdaBodyFixer.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingLambdaBodyFixer.java index dca421be45ab..fed3a610d799 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingLambdaBodyFixer.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingLambdaBodyFixer.java @@ -16,47 +16,36 @@ package com.intellij.codeInsight.editorActions.smartEnter; -import com.intellij.lang.ASTNode; +import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; import com.intellij.psi.JavaTokenType; import com.intellij.psi.PsiElement; -import com.intellij.psi.impl.source.BasicJavaAstTreeUtil; +import com.intellij.psi.PsiLambdaExpression; +import com.intellij.psi.PsiSwitchLabeledRuleStatement; import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.PsiUtil; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; -import static com.intellij.psi.impl.source.BasicJavaElementType.*; - public class MissingLambdaBodyFixer implements Fixer { @Override - public void apply(Editor editor, AbstractBasicJavaSmartEnterProcessor processor, @NotNull ASTNode astNode) throws IncorrectOperationException { - ASTNode body = null; - if (BasicJavaAstTreeUtil.is(astNode, BASIC_LAMBDA_EXPRESSION)) { - final ASTNode lastChild = astNode.getLastChildNode(); - if (BasicJavaAstTreeUtil.is(lastChild, EXPRESSION_SET) || - BasicJavaAstTreeUtil.is(lastChild, BASIC_CODE_BLOCK)) { - body = lastChild; - } - } - else if (BasicJavaAstTreeUtil.is(astNode, BASIC_SWITCH_LABELED_RULE)) { - body = BasicJavaAstTreeUtil.getRuleBody(astNode); - } - else { - return; - } + public void apply(Editor editor, JavaSmartEnterProcessor processor, @NotNull PsiElement psiElement) throws IncorrectOperationException { + PsiElement body; + if (psiElement instanceof PsiLambdaExpression lambda) { + body = lambda.getBody(); + } else if (psiElement instanceof PsiSwitchLabeledRuleStatement rule) { + body = rule.getBody(); + } else return; if (body != null) return; - PsiElement psiElement = BasicJavaAstTreeUtil.toPsi(astNode); - if (psiElement == null) { - return; - } + Document doc = editor.getDocument(); PsiElement arrow = PsiTreeUtil.getDeepestVisibleLast(psiElement); - if (arrow == null || !arrow.getNode().getElementType().equals(JavaTokenType.ARROW)) return; + if (!PsiUtil.isJavaToken(arrow, JavaTokenType.ARROW)) return; int offset = arrow.getTextRange().getEndOffset(); - processor.insertBracesWithNewLine(editor, offset); + doc.insertString(offset, "{\n}"); editor.getCaretModel().moveToOffset(offset + 1); processor.commit(editor); processor.reformat(psiElement); - processor.setSkipEnter(BasicJavaAstTreeUtil.is(astNode, BASIC_LAMBDA_EXPRESSION)); + processor.setSkipEnter(psiElement instanceof PsiLambdaExpression); } } \ No newline at end of file diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingLoopBodyFixer.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingLoopBodyFixer.java index 0e6c77f69563..0572acb6d4b2 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingLoopBodyFixer.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingLoopBodyFixer.java @@ -15,78 +15,70 @@ */ package com.intellij.codeInsight.editorActions.smartEnter; -import com.intellij.lang.ASTNode; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiWhiteSpace; -import com.intellij.psi.impl.source.BasicJavaAstTreeUtil; -import com.intellij.psi.tree.ParentAwareTokenSet; +import com.intellij.psi.*; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.IncorrectOperationException; import com.intellij.util.ObjectUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import static com.intellij.psi.impl.source.BasicJavaElementType.*; - public class MissingLoopBodyFixer implements Fixer { @Override - public void apply(Editor editor, AbstractBasicJavaSmartEnterProcessor processor, @NotNull ASTNode astNode) throws IncorrectOperationException { - ASTNode loopStatement = getLoopParent(astNode); + public void apply(Editor editor, JavaSmartEnterProcessor processor, @NotNull PsiElement psiElement) + throws IncorrectOperationException { + PsiLoopStatement loopStatement = getLoopParent(psiElement); if (loopStatement == null) return; final Document doc = editor.getDocument(); - ASTNode body; - if (BasicJavaAstTreeUtil.is(loopStatement, BASIC_FOR_STATEMENT)) { - body = BasicJavaAstTreeUtil.getForBody(loopStatement); + + PsiStatement body = loopStatement.getBody(); + if (body instanceof PsiBlockStatement) return; + if (body != null && startLine(doc, body) == startLine(doc, loopStatement)) return; + + PsiElement eltToInsertAfter; + if (loopStatement instanceof PsiWhileStatement psiWhileStatement) { + eltToInsertAfter = psiWhileStatement.getRParenth(); } - else if (BasicJavaAstTreeUtil.is(loopStatement, BASIC_FOREACH_STATEMENT)) { - body = BasicJavaAstTreeUtil.getForeachBody(loopStatement); + else if (loopStatement instanceof PsiForStatement psiForStatement) { + eltToInsertAfter = psiForStatement.getRParenth(); } - else if (BasicJavaAstTreeUtil.is(loopStatement, BASIC_WHILE_STATEMENT)) { - body = BasicJavaAstTreeUtil.getWhileBody(loopStatement); + else if (loopStatement instanceof PsiForeachStatement psiForeachStatement) { + eltToInsertAfter = psiForeachStatement.getRParenth(); } else { return; } - - if (BasicJavaAstTreeUtil.is(body, BASIC_BLOCK_STATEMENT)) return; - if (body != null && startLine(doc, body) == startLine(doc, loopStatement)) return; - - fixLoopBody(editor, processor, loopStatement, doc, body); + fixLoopBody(editor, processor, loopStatement, doc, body, eltToInsertAfter); } - private static ASTNode getLoopParent(@NotNull ASTNode element) { - ASTNode statement = BasicJavaAstTreeUtil.getParentOfType(element, ParentAwareTokenSet.create(BASIC_FOREACH_STATEMENT, - BASIC_FOR_STATEMENT, - BASIC_WHILE_STATEMENT)); + private static @Nullable PsiLoopStatement getLoopParent(@NotNull PsiElement element) { + PsiLoopStatement statement = PsiTreeUtil.getParentOfType(element, PsiLoopStatement.class); if (statement == null) return null; - if (BasicJavaAstTreeUtil.is(statement, BASIC_FOREACH_STATEMENT)) { - return isForEachApplicable(statement, element) ? statement : null; + if (statement instanceof PsiForeachStatement) { + return isForEachApplicable((PsiForeachStatement)statement, element) ? statement : null; } - if (BasicJavaAstTreeUtil.is(statement, BASIC_FOR_STATEMENT)) { - return isForApplicable(statement, element) ? statement : null; + if (statement instanceof PsiForStatement) { + return isForApplicable((PsiForStatement)statement, element) ? statement : null; } - if (BasicJavaAstTreeUtil.is(statement, BASIC_WHILE_STATEMENT)) { + if (statement instanceof PsiWhileStatement) { return statement; } return null; } - private static boolean isForApplicable(ASTNode statement, ASTNode astNode) { - ASTNode init = BasicJavaAstTreeUtil.getForInitialization(statement); - ASTNode update = BasicJavaAstTreeUtil.getForUpdate(statement); - ASTNode check = BasicJavaAstTreeUtil.getForCondition(statement); + private static boolean isForApplicable(PsiForStatement statement, PsiElement psiElement) { + PsiStatement init = statement.getInitialization(); + PsiStatement update = statement.getUpdate(); + PsiExpression check = statement.getCondition(); - return isValidChild(init, astNode) || isValidChild(update, astNode) || isValidChild(check, astNode); + return isValidChild(init, psiElement) || isValidChild(update, psiElement) || isValidChild(check, psiElement); } - private static boolean isValidChild(ASTNode ancestorNode, ASTNode node) { - PsiElement ancestor = BasicJavaAstTreeUtil.toPsi(ancestorNode); - PsiElement element = BasicJavaAstTreeUtil.toPsi(node); - if (ancestor != null && element != null) { - if (PsiTreeUtil.isAncestor(ancestor, element, false)) { + private static boolean isValidChild(PsiElement ancestor, PsiElement psiElement) { + if (ancestor != null) { + if (PsiTreeUtil.isAncestor(ancestor, psiElement, false)) { if (PsiTreeUtil.hasErrorElements(ancestor)) return false; return true; } @@ -95,41 +87,32 @@ public class MissingLoopBodyFixer implements Fixer { return false; } - private static boolean isForEachApplicable(ASTNode statement, ASTNode astNode) { - ASTNode iterated = BasicJavaAstTreeUtil.getForEachIteratedValue(statement); - ASTNode parameter = BasicJavaAstTreeUtil.getForEachIterationParameter(statement); - PsiElement iteratedElement = BasicJavaAstTreeUtil.toPsi(iterated); - PsiElement parameterElement = BasicJavaAstTreeUtil.toPsi(parameter); - PsiElement element = BasicJavaAstTreeUtil.toPsi(astNode); - return element != null && - (PsiTreeUtil.isAncestor(iteratedElement, element, false) || - PsiTreeUtil.isAncestor(parameterElement, element, false)); + private static boolean isForEachApplicable(PsiForeachStatement statement, PsiElement psiElement) { + PsiExpression iterated = statement.getIteratedValue(); + PsiParameter parameter = statement.getIterationParameter(); + + return PsiTreeUtil.isAncestor(iterated, psiElement, false) || PsiTreeUtil.isAncestor(parameter, psiElement, false); } - private static int startLine(Document doc, ASTNode astNode) { - return doc.getLineNumber(astNode.getTextRange().getStartOffset()); + private static int startLine(Document doc, PsiElement psiElement) { + return doc.getLineNumber(psiElement.getTextRange().getStartOffset()); } private static void fixLoopBody(@NotNull Editor editor, - @NotNull AbstractBasicJavaSmartEnterProcessor processor, - @NotNull ASTNode loop, + @NotNull JavaSmartEnterProcessor processor, + @NotNull PsiLoopStatement loop, @NotNull Document doc, - @Nullable ASTNode body) { - ASTNode eltToInsertAfter = BasicJavaAstTreeUtil.getRParenth(loop); - PsiElement loopElement = BasicJavaAstTreeUtil.toPsi(loop); - if (body != null && eltToInsertAfter != null) { - PsiElement bodyElement = BasicJavaAstTreeUtil.toPsi(body); - if (loopElement != null && bodyElement != null && bodyIsIndented(loopElement, bodyElement)) { - int endOffset = body.getTextRange().getEndOffset(); - doc.insertString(endOffset, "\n"); - processor.insertCloseBrace(editor, endOffset + 1); - int offset = eltToInsertAfter.getTextRange().getEndOffset(); - doc.insertString(offset, "{"); - editor.getCaretModel().moveToOffset(endOffset + "{".length()); - processor.setSkipEnter(true); - processor.reformat(loopElement); - return; - } + @Nullable PsiStatement body, + @Nullable PsiElement eltToInsertAfter) { + if (body != null && eltToInsertAfter != null && bodyIsIndented(loop, body)) { + int endOffset = body.getTextRange().getEndOffset(); + doc.insertString(endOffset, "\n}"); + int offset = eltToInsertAfter.getTextRange().getEndOffset(); + doc.insertString(offset, "{"); + editor.getCaretModel().moveToOffset(endOffset + "{".length()); + processor.setSkipEnter(true); + processor.reformat(loop); + return; } boolean needToClose = false; if (eltToInsertAfter == null) { @@ -138,15 +121,16 @@ public class MissingLoopBodyFixer implements Fixer { } int offset = eltToInsertAfter.getTextRange().getEndOffset(); if (needToClose) { - if (BasicJavaAstTreeUtil.getLParenth(loop) == null) { + if (getLParenth(loop) == null) { doc.insertString(offset, "()"); offset += 2; - } else { + } + else { doc.insertString(offset, ")"); offset++; } } - processor.insertBraces(editor, offset); + doc.insertString(offset, "{}"); editor.getCaretModel().moveToOffset(offset); } @@ -163,4 +147,19 @@ public class MissingLoopBodyFixer implements Fixer { if (beforeLoopLineBreak == -1) return false; return beforeBodyText.length() - beforeBodyLineBreak > beforeLoopText.length() - beforeLoopLineBreak; } + + private static PsiElement getLParenth(@Nullable PsiElement loopStatement) { + if (loopStatement instanceof PsiWhileStatement psiWhileStatement) { + return psiWhileStatement.getLParenth(); + } + else if (loopStatement instanceof PsiForStatement psiForStatement) { + return psiForStatement.getLParenth(); + } + else if (loopStatement instanceof PsiForeachStatement psiForeachStatement) { + return psiForeachStatement.getLParenth(); + } + else { + return null; + } + } } diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingMethodBodyFixer.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingMethodBodyFixer.java index 9a428c82c07f..917c03231132 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingMethodBodyFixer.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingMethodBodyFixer.java @@ -2,64 +2,55 @@ package com.intellij.codeInsight.editorActions.smartEnter; import com.intellij.core.JavaPsiBundle; -import com.intellij.lang.ASTNode; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; -import com.intellij.psi.JavaTokenType; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiErrorElement; -import com.intellij.psi.impl.source.BasicJavaAstTreeUtil; +import com.intellij.psi.*; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import static com.intellij.psi.impl.source.BasicJavaElementType.*; +import java.util.Objects; + +import static com.intellij.psi.PsiModifier.*; public class MissingMethodBodyFixer implements Fixer { - @Override - public void apply(Editor editor, AbstractBasicJavaSmartEnterProcessor processor, @NotNull ASTNode astNode) throws IncorrectOperationException { - if (BasicJavaAstTreeUtil.is(astNode, BASIC_FIELD)) { + public void apply(Editor editor, JavaSmartEnterProcessor processor, @NotNull PsiElement psiElement) + throws IncorrectOperationException { + if (psiElement instanceof PsiField field) { // replace something like `void x` with `void x() {...}` // while it's ambiguous whether user wants a field or a method, declaring a field is easier (just append a semicolon), // so completing a method looks more useful - if (BasicJavaAstTreeUtil.getInitializer(astNode) != null) return; - ASTNode lastChild = astNode.getLastChildNode(); - PsiElement psiElement = BasicJavaAstTreeUtil.toPsi(lastChild); - if (!(psiElement instanceof PsiErrorElement)) return; - if (!((PsiErrorElement)psiElement).getErrorDescription().equals(JavaPsiBundle.message("expected.semicolon"))) return; + if (field.hasInitializer()) return; + PsiElement lastChild = field.getLastChild(); + if (!(lastChild instanceof PsiErrorElement)) return; + if (!((PsiErrorElement)lastChild).getErrorDescription().equals(JavaPsiBundle.message("expected.semicolon"))) return; + PsiModifierList modifiers = field.getModifierList(); + if (modifiers == null) return; // Impossible modifiers for a method - if (BasicJavaAstTreeUtil.hasModifierProperty(astNode, JavaTokenType.TRANSIENT_KEYWORD) || - BasicJavaAstTreeUtil.hasModifierProperty(astNode, JavaTokenType.VOLATILE_KEYWORD)) { - return; - } - ASTNode typeElement = BasicJavaAstTreeUtil.getTypeElement(astNode); - if (typeElement == null || !typeElement.getText().equals("void")) return; - int endOffset = astNode.getTextRange().getEndOffset(); - editor.getDocument().insertString(endOffset, "()"); - editor.getDocument().insertString(endOffset + 2, "{}"); + if (modifiers.hasExplicitModifier(TRANSIENT) || modifiers.hasExplicitModifier(VOLATILE)) return; + if (!PsiTypes.voidType().equals(field.getType())) return; + int endOffset = field.getTextRange().getEndOffset(); + editor.getDocument().insertString(endOffset, "(){}"); editor.getCaretModel().moveToOffset(endOffset + 1); processor.registerUnresolvedError(endOffset + 1); processor.setSkipEnter(true); return; } - if (!(BasicJavaAstTreeUtil.is(astNode, BASIC_METHOD))) return; - if (!shouldMethodHaveBody(BasicJavaAstTreeUtil.toPsi(astNode))) return; + if (!(psiElement instanceof PsiMethod method)) return; + if (!shouldHaveBody(method)) return; - final ASTNode body = BasicJavaAstTreeUtil.getCodeBlock(astNode); + final PsiCodeBlock body = method.getBody(); final Document doc = editor.getDocument(); if (body != null) { // See IDEADEV-1093. This is quite hacky heuristic but it seem to be best we can do. String bodyText = body.getText(); if (bodyText.startsWith("{")) { - final ASTNode statement = BasicJavaAstTreeUtil.findChildByType(body, STATEMENT_SET); - if (statement != null) { - if (BasicJavaAstTreeUtil.is(statement, BASIC_DECLARATION_STATEMENT)) { - PsiElement psiElement = BasicJavaAstTreeUtil.toPsi(statement); - if (psiElement != null && PsiTreeUtil.getDeepestLast(psiElement) instanceof PsiErrorElement) { - ASTNode containingClass = BasicJavaAstTreeUtil.getParentOfType(astNode, CLASS_SET); - if (containingClass != null && BasicJavaAstTreeUtil.getRBrace(containingClass) == null) { + final PsiStatement[] statements = body.getStatements(); + if (statements.length > 0) { + if (statements[0] instanceof PsiDeclarationStatement) { + if (PsiTreeUtil.getDeepestLast(statements[0]) instanceof PsiErrorElement) { + if (Objects.requireNonNull(method.getContainingClass()).getRBrace() == null) { doc.insertString(body.getTextRange().getStartOffset() + 1, "\n}"); } } @@ -68,18 +59,19 @@ public class MissingMethodBodyFixer implements Fixer { } return; } - ASTNode throwList = BasicJavaAstTreeUtil.findChildByType(astNode, BASIC_THROWS_LIST); - if (throwList != null) { - int endOffset = throwList.getTextRange().getEndOffset(); - if (endOffset < doc.getTextLength() && doc.getCharsSequence().charAt(endOffset) == ';') { - doc.deleteString(endOffset, endOffset + 1); - } - processor.insertBracesWithNewLine(editor, endOffset); + int endOffset = method.getThrowsList().getTextRange().getEndOffset(); + if (endOffset < doc.getTextLength() && doc.getCharsSequence().charAt(endOffset) == ';') { + doc.deleteString(endOffset, endOffset + 1); } + doc.insertString(endOffset, "{\n}"); } - private static boolean shouldMethodHaveBody(@Nullable PsiElement method){ - return AfterSemicolonEnterProcessor.shouldHaveBody( - BasicJavaAstTreeUtil.toNode(method)); + static boolean shouldHaveBody(PsiMethod method) { + PsiClass containingClass = method.getContainingClass(); + if (containingClass == null) return false; + if (method.hasModifierProperty(ABSTRACT) || method.hasModifierProperty(NATIVE)) return false; + if (method.hasModifierProperty(PRIVATE)) return true; + if (containingClass.isInterface() && !method.hasModifierProperty(DEFAULT) && !method.hasModifierProperty(STATIC)) return false; + return true; } } diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingReturnExpressionFixer.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingReturnExpressionFixer.java index 32549232f2ff..2803a24963e1 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingReturnExpressionFixer.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingReturnExpressionFixer.java @@ -1,45 +1,39 @@ // Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.codeInsight.editorActions.smartEnter; -import com.intellij.lang.ASTNode; import com.intellij.openapi.editor.Editor; -import com.intellij.psi.JavaTokenType; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiJavaToken; -import com.intellij.psi.TokenType; -import com.intellij.psi.impl.source.BasicJavaAstTreeUtil; -import com.intellij.psi.tree.ParentAwareTokenSet; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import static com.intellij.psi.impl.source.BasicJavaElementType.*; - public class MissingReturnExpressionFixer implements Fixer { @Override - public void apply(Editor editor, AbstractBasicJavaSmartEnterProcessor processor, @NotNull ASTNode astNode) throws IncorrectOperationException { - if (!(BasicJavaAstTreeUtil.is(astNode, BASIC_RETURN_STATEMENT))) { + public void apply(Editor editor, JavaSmartEnterProcessor processor, @NotNull PsiElement psiElement) + throws IncorrectOperationException { + if (!(psiElement instanceof PsiReturnStatement retStatement)) { return; } - if (!BasicJavaAstTreeUtil.hasErrorElements(astNode)) { + if (!PsiTreeUtil.hasErrorElements(psiElement)) { return; } - if (fixMethodCallWithoutTrailingSemicolon(astNode, editor, processor)) { + if (fixMethodCallWithoutTrailingSemicolon(retStatement, editor, processor)) { return; } - ASTNode returnValue = BasicJavaAstTreeUtil.getReturnValue(astNode); + PsiExpression returnValue = retStatement.getReturnValue(); if (returnValue != null && lineNumber(editor, editor.getCaretModel().getOffset()) == lineNumber(editor, returnValue.getTextRange().getStartOffset())) { return; } - ASTNode parent = BasicJavaAstTreeUtil.getParentOfType(astNode, ParentAwareTokenSet.create(BASIC_CLASS_INITIALIZER, BASIC_METHOD)); - if (BasicJavaAstTreeUtil.is(parent, BASIC_METHOD)) { - ASTNode type = BasicJavaAstTreeUtil.findChildByType(parent, BASIC_TYPE); - if (type != null && !type.getText().equals("void")) { - final int startOffset = astNode.getTextRange().getStartOffset(); + PsiElement parent = PsiTreeUtil.getParentOfType(psiElement, PsiClassInitializer.class, PsiMethod.class); + if (parent instanceof PsiMethod) { + final PsiType returnType = ((PsiMethod)parent).getReturnType(); + if (returnType != null && !PsiTypes.voidType().equals(returnType)) { + final int startOffset = retStatement.getTextRange().getStartOffset(); if (returnValue != null) { editor.getDocument().insertString(startOffset + "return".length(), ";"); } @@ -49,29 +43,24 @@ public class MissingReturnExpressionFixer implements Fixer { } } - private static boolean fixMethodCallWithoutTrailingSemicolon(@Nullable ASTNode returnStatement, @NotNull Editor editor, - @NotNull AbstractBasicJavaSmartEnterProcessor processor) { + private static boolean fixMethodCallWithoutTrailingSemicolon(@Nullable PsiReturnStatement returnStatement, @NotNull Editor editor, + @NotNull JavaSmartEnterProcessor processor) { if (returnStatement == null) { return false; } - - final ASTNode lastChild = returnStatement.getLastChildNode(); - if (!(BasicJavaAstTreeUtil.is(lastChild, TokenType.ERROR_ELEMENT))) { + final PsiElement lastChild = returnStatement.getLastChild(); + if (!(lastChild instanceof PsiErrorElement)) { return false; } - ASTNode prev = lastChild.getTreePrev(); - if (BasicJavaAstTreeUtil.isWhiteSpace(prev)) { - prev = prev.getTreePrev(); + PsiElement prev = lastChild.getPrevSibling(); + if (prev instanceof PsiWhiteSpace) { + prev = prev.getPrevSibling(); } if (!(prev instanceof PsiJavaToken prevToken)) { int offset = returnStatement.getTextRange().getEndOffset(); - final PsiElement psiMethod = - BasicJavaAstTreeUtil.getParentOfType(BasicJavaAstTreeUtil.toPsi(returnStatement), BASIC_METHOD, true, - ParentAwareTokenSet.create(BASIC_LAMBDA_EXPRESSION)); - ASTNode method = BasicJavaAstTreeUtil.toNode(psiMethod); - ASTNode type = BasicJavaAstTreeUtil.findChildByType(method, BASIC_TYPE); - if (method != null && type != null && type.getText().equals("void")) { + final PsiMethod method = PsiTreeUtil.getParentOfType(returnStatement, PsiMethod.class, true, PsiLambdaExpression.class); + if (method != null && PsiTypes.voidType().equals(method.getReturnType())) { offset = returnStatement.getTextRange().getStartOffset() + "return".length(); } editor.getDocument().insertString(offset, ";"); @@ -86,9 +75,8 @@ public class MissingReturnExpressionFixer implements Fixer { final int offset = returnStatement.getTextRange().getEndOffset(); editor.getDocument().insertString(offset, ";"); if (prevToken.getTokenType() == JavaTokenType.RETURN_KEYWORD) { - final ASTNode method = BasicJavaAstTreeUtil.getParentOfType(returnStatement, BASIC_METHOD); - ASTNode type = BasicJavaAstTreeUtil.findChildByType(method, BASIC_TYPE); - if (method != null && type != null && !type.getText().equals("void")) { + final PsiMethod method = PsiTreeUtil.getParentOfType(returnStatement, PsiMethod.class); + if (method != null && !PsiTypes.voidType().equals(method.getReturnType())) { editor.getCaretModel().moveToOffset(offset); processor.setSkipEnter(true); } @@ -96,7 +84,6 @@ public class MissingReturnExpressionFixer implements Fixer { return true; } - private static int lineNumber(Editor editor, int offset) { return editor.getDocument().getLineNumber(offset); } diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingSwitchBodyFixer.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingSwitchBodyFixer.java index 9a862a204d57..015e247731f8 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingSwitchBodyFixer.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingSwitchBodyFixer.java @@ -2,29 +2,31 @@ package com.intellij.codeInsight.editorActions.smartEnter; -import com.intellij.lang.ASTNode; +import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; -import com.intellij.psi.impl.source.BasicJavaAstTreeUtil; +import com.intellij.psi.PsiCodeBlock; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiJavaToken; +import com.intellij.psi.PsiSwitchBlock; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; -import static com.intellij.psi.impl.source.BasicJavaElementType.BASIC_SWITCH_EXPRESSION; -import static com.intellij.psi.impl.source.BasicJavaElementType.BASIC_SWITCH_STATEMENT; - public class MissingSwitchBodyFixer implements Fixer { @Override - public void apply(Editor editor, AbstractBasicJavaSmartEnterProcessor processor, @NotNull ASTNode astNode) + public void apply(Editor editor, JavaSmartEnterProcessor processor, @NotNull PsiElement psiElement) throws IncorrectOperationException { - if (!(BasicJavaAstTreeUtil.is(astNode, BASIC_SWITCH_EXPRESSION, BASIC_SWITCH_STATEMENT))) return; + if (!(psiElement instanceof PsiSwitchBlock switchStatement)) return; - final ASTNode body = BasicJavaAstTreeUtil.getCodeBlock(astNode); + final Document doc = editor.getDocument(); + + final PsiCodeBlock body = switchStatement.getBody(); if (body != null) return; - final ASTNode rParenth = BasicJavaAstTreeUtil.getRParenth(astNode); + final PsiJavaToken rParenth = switchStatement.getRParenth(); assert rParenth != null; int offset = rParenth.getTextRange().getEndOffset(); - processor.insertBracesWithNewLine(editor, offset); + doc.insertString(offset, "{\n}"); editor.getCaretModel().moveToOffset(offset); } } \ No newline at end of file diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingSynchronizedBodyFixer.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingSynchronizedBodyFixer.java index 89d6cd758a0e..f4fb5ee77045 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingSynchronizedBodyFixer.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingSynchronizedBodyFixer.java @@ -1,23 +1,24 @@ // Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.codeInsight.editorActions.smartEnter; -import com.intellij.lang.ASTNode; +import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; -import com.intellij.psi.impl.source.BasicJavaAstTreeUtil; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiSynchronizedStatement; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; -import static com.intellij.psi.impl.source.BasicJavaElementType.BASIC_SYNCHRONIZED_STATEMENT; - public class MissingSynchronizedBodyFixer implements Fixer { @Override - public void apply(Editor editor, AbstractBasicJavaSmartEnterProcessor processor, @NotNull ASTNode astNode) throws IncorrectOperationException { - if (!(BasicJavaAstTreeUtil.is(astNode, BASIC_SYNCHRONIZED_STATEMENT))) return; + public void apply(Editor editor, JavaSmartEnterProcessor processor, @NotNull PsiElement psiElement) throws IncorrectOperationException { + if (!(psiElement instanceof PsiSynchronizedStatement syncStatement)) return; - ASTNode body = BasicJavaAstTreeUtil.getCodeBlock(astNode); + final Document doc = editor.getDocument(); + + PsiElement body = syncStatement.getBody(); if (body != null) return; - processor.insertBraces(editor, astNode.getTextRange().getEndOffset()); + doc.insertString(syncStatement.getTextRange().getEndOffset(), "{}"); } } diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingThrowExpressionFixer.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingThrowExpressionFixer.java index 8713d8396448..76ed75219c0c 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingThrowExpressionFixer.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingThrowExpressionFixer.java @@ -1,35 +1,35 @@ // Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.codeInsight.editorActions.smartEnter; -import com.intellij.lang.ASTNode; import com.intellij.openapi.editor.Editor; -import com.intellij.psi.impl.source.BasicJavaAstTreeUtil; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiExpression; +import com.intellij.psi.PsiThrowStatement; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; - -import static com.intellij.psi.impl.source.BasicJavaElementType.BASIC_THROW_STATEMENT; +import org.jetbrains.annotations.Nullable; public class MissingThrowExpressionFixer implements Fixer { @Override - public void apply(Editor editor, AbstractBasicJavaSmartEnterProcessor processor, @NotNull ASTNode astNode) + public void apply(Editor editor, JavaSmartEnterProcessor processor, @NotNull PsiElement psiElement) throws IncorrectOperationException { - if (BasicJavaAstTreeUtil.is(astNode, BASIC_THROW_STATEMENT)) { - ASTNode expression = BasicJavaAstTreeUtil.getExpression(astNode); - if (expression != null) { - int expressionLine = startLine(editor, expression); - if (startLine(editor, astNode) == expressionLine) return; + if (psiElement instanceof PsiThrowStatement throwStatement) { + @Nullable PsiExpression exception = throwStatement.getException(); + if (exception != null) { + int expressionLine = startLine(editor, exception); + if (startLine(editor, throwStatement) == expressionLine) return; if (editor.getDocument().getLineNumber(editor.getCaretModel().getOffset()) == expressionLine) return; } - final int startOffset = astNode.getTextRange().getStartOffset(); - if (expression != null) { + final int startOffset = throwStatement.getTextRange().getStartOffset(); + if (exception != null) { editor.getDocument().insertString(startOffset + "throw".length(), ";"); } processor.registerUnresolvedError(startOffset + "throw".length()); } } - private static int startLine(Editor editor, @NotNull ASTNode psiElement) { + private static int startLine(Editor editor, PsiElement psiElement) { return editor.getDocument().getLineNumber(psiElement.getTextRange().getStartOffset()); } } diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingTryBodyFixer.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingTryBodyFixer.java index 52041dd9c2d3..98e85bbcbeee 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingTryBodyFixer.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MissingTryBodyFixer.java @@ -1,23 +1,25 @@ // Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.codeInsight.editorActions.smartEnter; -import com.intellij.lang.ASTNode; +import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; -import com.intellij.psi.impl.source.BasicJavaAstTreeUtil; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiTryStatement; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; -import static com.intellij.psi.impl.source.BasicJavaElementType.BASIC_TRY_STATEMENT; - public class MissingTryBodyFixer implements Fixer { @Override - public void apply(Editor editor, AbstractBasicJavaSmartEnterProcessor processor, @NotNull ASTNode astNode) throws IncorrectOperationException { - if (!(BasicJavaAstTreeUtil.is(astNode, BASIC_TRY_STATEMENT))) return; + public void apply(Editor editor, JavaSmartEnterProcessor processor, @NotNull PsiElement psiElement) + throws IncorrectOperationException { + if (!(psiElement instanceof PsiTryStatement tryStatement)) return; - ASTNode body = BasicJavaAstTreeUtil.getCodeBlock(astNode); + final Document doc = editor.getDocument(); + + PsiElement body = tryStatement.getTryBlock(); if (body != null) return; - processor.insertBraces(editor, astNode.getTextRange().getEndOffset()); + doc.insertString(tryStatement.getTextRange().getEndOffset(), "{}"); } } diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/ParameterListFixer.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/ParameterListFixer.java index 6ac00af2fc24..8a247c45ce74 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/ParameterListFixer.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/ParameterListFixer.java @@ -1,30 +1,27 @@ // Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.codeInsight.editorActions.smartEnter; -import com.intellij.lang.ASTNode; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.psi.impl.source.BasicJavaAstTreeUtil; +import com.intellij.psi.PsiAnnotationParameterList; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiParameterList; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; -import static com.intellij.psi.impl.source.BasicJavaElementType.BASIC_ANNOTATION_PARAMETER_LIST; -import static com.intellij.psi.impl.source.BasicJavaElementType.BASIC_PARAMETER_LIST; - public class ParameterListFixer implements Fixer { @Override - public void apply(Editor editor, AbstractBasicJavaSmartEnterProcessor processor, @NotNull ASTNode astNode) throws IncorrectOperationException { - if (BasicJavaAstTreeUtil.is(astNode, BASIC_PARAMETER_LIST) || - BasicJavaAstTreeUtil.is(astNode, BASIC_ANNOTATION_PARAMETER_LIST)) { - String text = astNode.getText(); + public void apply(Editor editor, JavaSmartEnterProcessor processor, @NotNull PsiElement psiElement) + throws IncorrectOperationException { + if (psiElement instanceof PsiParameterList || psiElement instanceof PsiAnnotationParameterList) { + String text = psiElement.getText(); if (StringUtil.startsWithChar(text, '(') && !StringUtil.endsWithChar(text, ')')) { - ASTNode[] params = BasicJavaAstTreeUtil.is(astNode, BASIC_PARAMETER_LIST) ? - BasicJavaAstTreeUtil.getParameterListParameters(astNode) : - BasicJavaAstTreeUtil.getAnnotationParameterListAttributes(astNode); + PsiElement[] params = psiElement instanceof PsiParameterList ? ((PsiParameterList)psiElement).getParameters() + : ((PsiAnnotationParameterList)psiElement).getAttributes(); int offset; if (params.length == 0) { - offset = astNode.getTextRange().getStartOffset() + 1; + offset = psiElement.getTextRange().getStartOffset() + 1; } else { offset = params[params.length - 1].getTextRange().getEndOffset(); diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/ParenthesizedFixer.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/ParenthesizedFixer.java index 8134aeaf1a26..0352102e0efb 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/ParenthesizedFixer.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/ParenthesizedFixer.java @@ -1,22 +1,21 @@ // Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.codeInsight.editorActions.smartEnter; -import com.intellij.lang.ASTNode; import com.intellij.openapi.editor.Editor; -import com.intellij.psi.impl.source.BasicJavaAstTreeUtil; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiParenthesizedExpression; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; -import static com.intellij.psi.impl.source.BasicJavaElementType.BASIC_PARENTH_EXPRESSION; - public class ParenthesizedFixer implements Fixer { @Override - public void apply(Editor editor, AbstractBasicJavaSmartEnterProcessor processor, @NotNull ASTNode astNode) throws IncorrectOperationException { - if (BasicJavaAstTreeUtil.is(astNode, BASIC_PARENTH_EXPRESSION)) { - final ASTNode lastChild = astNode.getLastChildNode(); + public void apply(Editor editor, JavaSmartEnterProcessor processor, @NotNull PsiElement psiElement) + throws IncorrectOperationException { + if (psiElement instanceof PsiParenthesizedExpression) { + final PsiElement lastChild = psiElement.getLastChild(); if (lastChild != null && !")".equals(lastChild.getText())) { - editor.getDocument().insertString(astNode.getTextRange().getEndOffset(), ")"); + editor.getDocument().insertString(psiElement.getTextRange().getEndOffset(), ")"); } } } diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/PlainEnterProcessor.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/PlainEnterProcessor.java index 4c660c0fcb55..30ef1d10bd77 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/PlainEnterProcessor.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/PlainEnterProcessor.java @@ -12,32 +12,25 @@ import com.intellij.openapi.editor.actionSystem.EditorActionManager; import com.intellij.openapi.editor.ex.util.EditorUtil; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.psi.JavaTokenType; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiWhiteSpace; -import com.intellij.psi.impl.source.BasicJavaAstTreeUtil; +import com.intellij.psi.*; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.text.CharArrayUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import static com.intellij.psi.impl.source.BasicJavaElementType.*; - -public class PlainEnterProcessor implements ASTNodeEnterProcessor { - +public class PlainEnterProcessor implements EnterProcessor { @Override - public boolean doEnter(@NotNull Editor editor, @NotNull ASTNode astNode, boolean isModified) { - if (expandCodeBlock(editor, astNode)) return true; + public boolean doEnter(Editor editor, PsiElement psiElement, boolean isModified) { + if (expandCodeBlock(editor, psiElement)) return true; getEnterHandler(IdeActions.ACTION_EDITOR_START_NEW_LINE).execute(editor, editor.getCaretModel().getCurrentCaret(), EditorUtil.getEditorDataContext(editor)); return true; } - public static boolean expandCodeBlock(@NotNull Editor editor, @Nullable ASTNode astNode) { - ASTNode block = getControlStatementBlock(editor.getCaretModel().getOffset(), astNode); - PsiElement psiBlock = BasicJavaAstTreeUtil.toPsi(block); - if (processExistingBlankLine(editor, psiBlock, astNode)) { + static boolean expandCodeBlock(Editor editor, PsiElement psiElement) { + PsiCodeBlock block = getControlStatementBlock(editor.getCaretModel().getOffset(), psiElement); + if (processExistingBlankLine(editor, block, psiElement)) { return true; } if (block == null) { @@ -45,9 +38,9 @@ public class PlainEnterProcessor implements ASTNodeEnterProcessor { } EditorActionHandler enterHandler = getEnterHandler(IdeActions.ACTION_EDITOR_START_NEW_LINE); - ASTNode firstElement = BasicJavaAstTreeUtil.getFirstBodyElement(block); + PsiElement firstElement = block.getFirstBodyElement(); if (firstElement == null) { - firstElement = BasicJavaAstTreeUtil.getRBrace(block); + firstElement = block.getRBrace(); // Plain enter processor inserts enter after the end of line, hence, we don't want to use it here because the line ends with // the empty braces block. So, we get the following in case of default handler usage: // Before: @@ -68,53 +61,52 @@ public class PlainEnterProcessor implements ASTNodeEnterProcessor { return EditorActionManager.getInstance().getActionHandler(actionId); } - private static @Nullable ASTNode getControlStatementBlock(int caret, ASTNode astNode) { - if (BasicJavaAstTreeUtil.is(astNode, BASIC_TRY_STATEMENT)) { - ASTNode tryBlock = BasicJavaAstTreeUtil.getCodeBlock(astNode); + private static @Nullable PsiCodeBlock getControlStatementBlock(int caret, PsiElement element) { + if (element instanceof PsiTryStatement) { + PsiCodeBlock tryBlock = ((PsiTryStatement)element).getTryBlock(); if (tryBlock != null && caret < tryBlock.getTextRange().getEndOffset()) return tryBlock; - for (ASTNode catchBlock : BasicJavaAstTreeUtil.getCatchBlocks(astNode)) { + for (PsiCodeBlock catchBlock : ((PsiTryStatement)element).getCatchBlocks()) { if (catchBlock != null && caret < catchBlock.getTextRange().getEndOffset()) return catchBlock; } - return BasicJavaAstTreeUtil.getFinallyBlock(astNode); + return ((PsiTryStatement)element).getFinallyBlock(); } - if (BasicJavaAstTreeUtil.is(astNode, BASIC_SYNCHRONIZED_STATEMENT)) { - return BasicJavaAstTreeUtil.getCodeBlock(astNode); + if (element instanceof PsiSynchronizedStatement) { + return ((PsiSynchronizedStatement)element).getBody(); } - if (BasicJavaAstTreeUtil.is(astNode, BASIC_METHOD)) { - ASTNode methodBody = BasicJavaAstTreeUtil.getCodeBlock(astNode); + if (element instanceof PsiMethod) { + PsiCodeBlock methodBody = ((PsiMethod)element).getBody(); if (methodBody != null) return methodBody; } - if (BasicJavaAstTreeUtil.is(astNode, BASIC_SWITCH_STATEMENT)) { - return BasicJavaAstTreeUtil.getCodeBlock(astNode); + if (element instanceof PsiSwitchStatement) { + return ((PsiSwitchStatement)element).getBody(); } - ASTNode body = null; - if (BasicJavaAstTreeUtil.is(astNode, BASIC_IF_STATEMENT)) { - body = BasicJavaAstTreeUtil.getThenBranch(astNode); + PsiStatement body = null; + if (element instanceof PsiIfStatement) { + body = ((PsiIfStatement)element).getThenBranch(); if (body != null && caret > body.getTextRange().getEndOffset()) { - body = BasicJavaAstTreeUtil.getElseBranch(astNode); + body = ((PsiIfStatement)element).getElseBranch(); } } - else if (BasicJavaAstTreeUtil.is(astNode, BASIC_WHILE_STATEMENT)) { - body = BasicJavaAstTreeUtil.getBlock(astNode); + else if (element instanceof PsiWhileStatement) { + body = ((PsiWhileStatement)element).getBody(); } - else if (BasicJavaAstTreeUtil.is(astNode, BASIC_FOR_STATEMENT)) { - body = BasicJavaAstTreeUtil.getForBody(astNode); + else if (element instanceof PsiForStatement) { + body = ((PsiForStatement)element).getBody(); } - else if (BasicJavaAstTreeUtil.is(astNode, BASIC_FOREACH_STATEMENT)) { - body = BasicJavaAstTreeUtil.getBlock(astNode); + else if (element instanceof PsiForeachStatement) { + body = ((PsiForeachStatement)element).getBody(); } - else if (BasicJavaAstTreeUtil.is(astNode, BASIC_DO_WHILE_STATEMENT)) { - body = BasicJavaAstTreeUtil.getDoWhileBody(astNode); + else if (element instanceof PsiDoWhileStatement) { + body = ((PsiDoWhileStatement)element).getBody(); } - return BasicJavaAstTreeUtil.is(body, BASIC_BLOCK_STATEMENT) ? - BasicJavaAstTreeUtil.getCodeBlock(body) : null; + return body instanceof PsiBlockStatement ? ((PsiBlockStatement)body).getCodeBlock() : null; } /** @@ -135,12 +127,11 @@ public class PlainEnterProcessor implements ASTNodeEnterProcessor { * is pointed to correct position there, i.e. no additional processing is required; * {@code false} otherwise */ - private static boolean processExistingBlankLine(@NotNull Editor editor, @Nullable PsiElement codeBlock, @Nullable ASTNode element) { + private static boolean processExistingBlankLine(@NotNull Editor editor, @Nullable PsiCodeBlock codeBlock, @Nullable PsiElement element) { PsiWhiteSpace whiteSpace = null; if (codeBlock == null) { - PsiElement psiElement = BasicJavaAstTreeUtil.toPsi(element); - if (psiElement != null && !(BasicJavaAstTreeUtil.is(element, MEMBER_SET))) { - final PsiElement next = PsiTreeUtil.nextLeaf(psiElement); + if (element != null && !(element instanceof PsiMember)) { + final PsiElement next = PsiTreeUtil.nextLeaf(element); if (next instanceof PsiWhiteSpace) { whiteSpace = (PsiWhiteSpace)next; } diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/SemicolonFixer.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/SemicolonFixer.java index ed2ea144fc5b..04009520b158 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/SemicolonFixer.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/SemicolonFixer.java @@ -2,35 +2,158 @@ package com.intellij.codeInsight.editorActions.smartEnter; import com.intellij.application.options.CodeStyle; +import com.intellij.lang.ASTNode; import com.intellij.lang.java.JavaLanguage; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.patterns.PsiJavaPatterns; import com.intellij.psi.*; +import com.intellij.psi.impl.source.tree.ElementType; +import com.intellij.psi.impl.source.tree.TreeUtil; import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -public class SemicolonFixer extends AbstractBasicSemicolonFixer { +public class SemicolonFixer implements Fixer { @Override - protected boolean fixReturn(@NotNull Editor editor, @Nullable PsiElement psiElement) { + public void apply(Editor editor, JavaSmartEnterProcessor processor, @NotNull PsiElement psiElement) + throws IncorrectOperationException { + if (fixReturn(editor, psiElement)) return; + if (fixForUpdate(editor, psiElement)) return; + fixAfterLastValidElement(editor, psiElement); + } + + private static boolean fixReturn(@NotNull Editor editor, @Nullable PsiElement psiElement) { if (psiElement instanceof PsiReturnStatement stmt) { PsiMethod method = PsiTreeUtil.getParentOfType(psiElement, PsiMethod.class, true, PsiLambdaExpression.class); - if (method != null && PsiTypes.voidType().equals(method.getReturnType()) && stmt.getReturnValue() != null) { - Document doc = editor.getDocument(); - doc.insertString(stmt.getTextRange().getStartOffset() + "return".length(), ";"); - return true; + if (method != null && PsiTypes.voidType().equals(method.getReturnType())) { + if (stmt.getReturnValue() != null) { + Document doc = editor.getDocument(); + doc.insertString(stmt.getTextRange().getStartOffset() + "return".length(), ";"); + return true; + } } } return false; } - @Override - protected boolean getSpaceAfterSemicolon(@NotNull PsiElement psiElement) { - return CodeStyle.getSettings(psiElement.getContainingFile()).getCommonSettings(JavaLanguage.INSTANCE).SPACE_AFTER_SEMICOLON; + private static boolean fixForUpdate(@NotNull Editor editor, @Nullable PsiElement psiElement) { + if (!(psiElement instanceof PsiForStatement forStatement)) { + return false; + } + + PsiExpression condition = forStatement.getCondition(); + if (forStatement.getUpdate() != null || condition == null) { + return false; + } + + TextRange range = condition.getTextRange(); + Document document = editor.getDocument(); + CharSequence text = document.getCharsSequence(); + for (int i = range.getEndOffset() - 1, max = forStatement.getTextRange().getEndOffset(); i < max; i++) { + if (text.charAt(i) == ';') { + return false; + } + } + + String toInsert = ";"; + if (CodeStyle.getSettings(psiElement.getContainingFile()).getCommonSettings(JavaLanguage.INSTANCE).SPACE_AFTER_SEMICOLON) { + toInsert += " "; + } + document.insertString(range.getEndOffset(), toInsert); + return true; } - @Override - protected boolean isImportStatementBase(@Nullable PsiElement psiElement) { - return psiElement instanceof PsiImportStatementBase; + @SuppressWarnings("UnusedReturnValue") + private static boolean fixAfterLastValidElement(@NotNull Editor editor, @Nullable PsiElement psiElement) { + if (psiElement instanceof PsiExpressionStatement || + psiElement instanceof PsiDeclarationStatement || + psiElement instanceof PsiImportStatementBase || + psiElement instanceof PsiDoWhileStatement || + psiElement instanceof PsiReturnStatement || + psiElement instanceof PsiThrowStatement || + psiElement instanceof PsiBreakStatement || + psiElement instanceof PsiContinueStatement || + psiElement instanceof PsiYieldStatement || + psiElement instanceof PsiAssertStatement || + psiElement instanceof PsiPackageStatement || + isStandaloneField(psiElement) || + psiElement instanceof PsiMethod && + ((PsiMethod)psiElement).getBody() == null && + !MissingMethodBodyFixer.shouldHaveBody((PsiMethod)psiElement) || + psiElement instanceof PsiRequiresStatement || + psiElement instanceof PsiPackageAccessibilityStatement || + psiElement instanceof PsiUsesStatement || + psiElement instanceof PsiProvidesStatement) { + String text = psiElement.getText(); + + int tailLength = 0; + ASTNode leaf = TreeUtil.findLastLeaf(psiElement.getNode()); + while (leaf != null && ElementType.JAVA_COMMENT_OR_WHITESPACE_BIT_SET.contains(leaf.getElementType())) { + tailLength += leaf.getTextLength(); + leaf = TreeUtil.prevLeaf(leaf); + } + if (leaf == null) { + return false; + } + + if (tailLength > 0) { + text = text.substring(0, text.length() - tailLength); + } + + int insertionOffset = leaf.getTextRange().getEndOffset(); + Document doc = editor.getDocument(); + if (psiElement instanceof PsiField && ((PsiField)psiElement).hasModifierProperty(PsiModifier.ABSTRACT)) { + // abstract rarely seem to be field. It is rather incomplete method. + doc.insertString(insertionOffset, "()"); + insertionOffset += "()".length(); + } + + // Like: + // assert x instanceof Type + // String s = "hello"; + // Here, String is parsed as name of the pattern variable, and we have an assignment, instead of declaration + if (psiElement.getLastChild() instanceof PsiErrorElement error && + error.getPrevSibling() instanceof PsiInstanceOfExpression instanceOf && + instanceOf.getLastChild() instanceof PsiTypeTestPattern typePattern && + typePattern.getPatternVariable() != null && + PsiTreeUtil.skipWhitespacesForward(psiElement) instanceof PsiExpressionStatement exprStmt && + exprStmt.getExpression() instanceof PsiAssignmentExpression assignment && + assignment.getOperationTokenType().equals(JavaTokenType.EQ)) { + PsiPatternVariable variable = typePattern.getPatternVariable(); + PsiIdentifier identifier = variable.getNameIdentifier(); + if (identifier.getPrevSibling() instanceof PsiWhiteSpace ws && ws.getText().contains("\n") && + editor.getCaretModel().getOffset() < identifier.getTextRange().getStartOffset()) { + insertionOffset = ws.getTextRange().getStartOffset(); + } + } + + if (!StringUtil.endsWithChar(text, ';')) { + PsiElement parent = psiElement.getParent(); + String toInsert = ";"; + if (parent instanceof PsiForStatement) { + if (((PsiForStatement)parent).getUpdate() == psiElement) { + return false; + } + if (CodeStyle.getSettings(psiElement.getContainingFile()).getCommonSettings(JavaLanguage.INSTANCE).SPACE_AFTER_SEMICOLON) { + toInsert += " "; + } + } + + doc.insertString(insertionOffset, toInsert); + return true; + } + } + + return false; + } + + private static boolean isStandaloneField(@Nullable PsiElement psiElement) { + return psiElement instanceof PsiField && + !(psiElement instanceof PsiEnumConstant) && + !PsiJavaPatterns.psiElement().beforeLeaf(PsiJavaPatterns.psiElement().withText(",")).accepts(psiElement); } } \ No newline at end of file diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/SwitchExpressionFixer.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/SwitchExpressionFixer.java index 81abdebe4a7c..3eba97e97323 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/SwitchExpressionFixer.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/SwitchExpressionFixer.java @@ -1,42 +1,34 @@ // Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.codeInsight.editorActions.smartEnter; -import com.intellij.lang.ASTNode; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; -import com.intellij.psi.impl.source.BasicJavaAstTreeUtil; +import com.intellij.psi.*; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; -import static com.intellij.psi.impl.source.BasicJavaElementType.BASIC_SWITCH_EXPRESSION; -import static com.intellij.psi.impl.source.BasicJavaElementType.BASIC_SWITCH_STATEMENT; - public class SwitchExpressionFixer implements Fixer { @Override - public void apply(Editor editor, AbstractBasicJavaSmartEnterProcessor processor, @NotNull ASTNode astNode) throws IncorrectOperationException { - if (BasicJavaAstTreeUtil.is(astNode, BASIC_SWITCH_EXPRESSION) || - BasicJavaAstTreeUtil.is(astNode, BASIC_SWITCH_STATEMENT) - ) { + public void apply(Editor editor, JavaSmartEnterProcessor processor, @NotNull PsiElement psiElement) throws IncorrectOperationException { + if (psiElement instanceof PsiSwitchBlock switchStatement) { final Document doc = editor.getDocument(); - final ASTNode rParenth = BasicJavaAstTreeUtil.getRParenth(astNode); - final ASTNode lParenth = BasicJavaAstTreeUtil.getLParenth(astNode); - final ASTNode condition = BasicJavaAstTreeUtil.getExpression(astNode); + final PsiJavaToken rParenth = switchStatement.getRParenth(); + final PsiJavaToken lParenth = switchStatement.getLParenth(); + final PsiExpression condition = switchStatement.getExpression(); if (condition == null) { if (lParenth == null || rParenth == null) { - int stopOffset = doc.getLineEndOffset(doc.getLineNumber(astNode.getTextRange().getStartOffset())); - final ASTNode block = BasicJavaAstTreeUtil.getCodeBlock(astNode); + int stopOffset = doc.getLineEndOffset(doc.getLineNumber(switchStatement.getTextRange().getStartOffset())); + final PsiCodeBlock block = switchStatement.getBody(); if (block != null) { stopOffset = Math.min(stopOffset, block.getTextRange().getStartOffset()); } - doc.replaceString(astNode.getTextRange().getStartOffset(), stopOffset, "switch ()"); - } - else { + doc.replaceString(switchStatement.getTextRange().getStartOffset(), stopOffset, "switch ()"); + } else { processor.registerUnresolvedError(lParenth.getTextRange().getEndOffset()); } - } - else if (rParenth == null) { + } else if (rParenth == null) { doc.insertString(condition.getTextRange().getEndOffset(), ")"); } } diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/SwitchLabelColonFixer.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/SwitchLabelColonFixer.java index 3a2a565e6ec1..aabe8c6cb6b6 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/SwitchLabelColonFixer.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/SwitchLabelColonFixer.java @@ -1,21 +1,19 @@ // 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.codeInsight.editorActions.smartEnter; -import com.intellij.lang.ASTNode; import com.intellij.openapi.editor.Editor; import com.intellij.psi.PsiCaseLabelElementList; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiSwitchBlock; import com.intellij.psi.PsiSwitchLabelStatement; -import com.intellij.psi.impl.source.BasicJavaAstTreeUtil; import com.intellij.psi.util.PsiUtil; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; public class SwitchLabelColonFixer implements Fixer { @Override - public void apply(Editor editor, AbstractBasicJavaSmartEnterProcessor processor, @NotNull ASTNode astNode) throws IncorrectOperationException { - PsiElement psiElement = BasicJavaAstTreeUtil.toPsi(astNode); + public void apply(Editor editor, JavaSmartEnterProcessor processor, @NotNull PsiElement psiElement) + throws IncorrectOperationException { if (psiElement instanceof PsiSwitchLabelStatement statement) { PsiSwitchBlock block = statement.getEnclosingSwitchBlock(); if (block == null) return; diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/TernaryColonFixer.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/TernaryColonFixer.java index 769c52f7a411..f97c0050946a 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/TernaryColonFixer.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/TernaryColonFixer.java @@ -1,31 +1,29 @@ // Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.codeInsight.editorActions.smartEnter; -import com.intellij.lang.ASTNode; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.EditorModificationUtilEx; import com.intellij.psi.JavaTokenType; -import com.intellij.psi.impl.source.BasicJavaAstTreeUtil; +import com.intellij.psi.PsiConditionalExpression; +import com.intellij.psi.PsiElement; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; -import static com.intellij.psi.impl.source.BasicJavaElementType.BASIC_CONDITIONAL_EXPRESSION; - public class TernaryColonFixer implements Fixer { @Override - public void apply(Editor editor, AbstractBasicJavaSmartEnterProcessor processor, @NotNull ASTNode astNode) throws IncorrectOperationException { - if (!(BasicJavaAstTreeUtil.is(astNode, BASIC_CONDITIONAL_EXPRESSION))) { + public void apply(Editor editor, JavaSmartEnterProcessor processor, @NotNull PsiElement psiElement) + throws IncorrectOperationException { + if (!(psiElement instanceof PsiConditionalExpression ternary)) { return; } - if (BasicJavaAstTreeUtil.getConditionalExpressionThenExpression(astNode) == null || - astNode.findChildByType(JavaTokenType.COLON) != null) { + if (ternary.getThenExpression() == null || ternary.getNode().findChildByType(JavaTokenType.COLON) != null) { return; } - editor.getCaretModel().moveToOffset(astNode.getTextRange().getEndOffset()); + editor.getCaretModel().moveToOffset(ternary.getTextRange().getEndOffset()); EditorModificationUtilEx.insertStringAtCaret(editor, ": "); processor.setSkipEnter(true); } diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/WhileConditionFixer.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/WhileConditionFixer.java index 0d5ed3db6ff4..8af787f0365b 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/WhileConditionFixer.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/smartEnter/WhileConditionFixer.java @@ -1,39 +1,39 @@ // Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.codeInsight.editorActions.smartEnter; -import com.intellij.lang.ASTNode; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; -import com.intellij.psi.impl.source.BasicJavaAstTreeUtil; +import com.intellij.psi.*; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; -import static com.intellij.psi.impl.source.BasicJavaElementType.BASIC_WHILE_STATEMENT; - public class WhileConditionFixer implements Fixer { @Override - public void apply(Editor editor, AbstractBasicJavaSmartEnterProcessor processor, @NotNull ASTNode astNode) throws IncorrectOperationException { - if (BasicJavaAstTreeUtil.is(astNode, BASIC_WHILE_STATEMENT)) { + public void apply(Editor editor, JavaSmartEnterProcessor processor, @NotNull PsiElement psiElement) + throws IncorrectOperationException { + if (psiElement instanceof PsiWhileStatement whileStatement) { final Document doc = editor.getDocument(); - final ASTNode rParenth = BasicJavaAstTreeUtil.getRParenth(astNode); - final ASTNode lParenth = BasicJavaAstTreeUtil.getLParenth(astNode); - final ASTNode condition = BasicJavaAstTreeUtil.getWhileCondition(astNode); + final PsiJavaToken rParenth = whileStatement.getRParenth(); + final PsiJavaToken lParenth = whileStatement.getLParenth(); + final PsiExpression condition = whileStatement.getCondition(); if (condition == null) { if (lParenth == null || rParenth == null) { - int stopOffset = doc.getLineEndOffset(doc.getLineNumber(astNode.getTextRange().getStartOffset())); - final ASTNode block = BasicJavaAstTreeUtil.getWhileBody(astNode); + int stopOffset = doc.getLineEndOffset(doc.getLineNumber(whileStatement.getTextRange().getStartOffset())); + final PsiStatement block = whileStatement.getBody(); if (block != null) { stopOffset = Math.min(stopOffset, block.getTextRange().getStartOffset()); } - stopOffset = Math.min(stopOffset, astNode.getTextRange().getEndOffset()); + stopOffset = Math.min(stopOffset, whileStatement.getTextRange().getEndOffset()); - doc.replaceString(astNode.getTextRange().getStartOffset(), stopOffset, "while ()"); - processor.registerUnresolvedError(astNode.getTextRange().getStartOffset() + "while (".length()); - } else { + doc.replaceString(whileStatement.getTextRange().getStartOffset(), stopOffset, "while ()"); + processor.registerUnresolvedError(whileStatement.getTextRange().getStartOffset() + "while (".length()); + } + else { processor.registerUnresolvedError(lParenth.getTextRange().getEndOffset()); } - } else if (rParenth == null) { + } + else if (rParenth == null) { doc.insertString(condition.getTextRange().getEndOffset(), ")"); } } diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/AbstractBasicBackBasicSelectioner.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/AbstractBasicBackBasicSelectioner.java deleted file mode 100644 index 4cbb2395d5e3..000000000000 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/AbstractBasicBackBasicSelectioner.java +++ /dev/null @@ -1,45 +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.codeInsight.editorActions.wordSelection; - -import com.intellij.codeInsight.editorActions.ExtendWordSelectionHandlerBase; -import com.intellij.lang.ASTNode; -import com.intellij.lang.Language; -import com.intellij.lang.xml.XMLLanguage; -import com.intellij.psi.PsiElement; -import com.intellij.psi.TokenType; -import com.intellij.psi.impl.source.BasicJavaAstTreeUtil; -import org.jetbrains.annotations.NotNull; - -import java.util.function.Predicate; - -import static com.intellij.psi.impl.source.BasicElementTypes.BASIC_JAVA_COMMENT_BIT_SET; -import static com.intellij.psi.impl.source.BasicJavaDocElementType.*; -import static com.intellij.psi.impl.source.BasicJavaElementType.*; - -public abstract class AbstractBasicBackBasicSelectioner extends ExtendWordSelectionHandlerBase { - - private static Predicate getElementPredicate() { - return (e) -> { - Language language = e.getLanguage(); - return !(language instanceof XMLLanguage || language.isKindOf(XMLLanguage.INSTANCE)); - }; - } - - @Override - public boolean canSelect(final @NotNull PsiElement e) { - ASTNode node = BasicJavaAstTreeUtil.toNode(e); - return - !BasicJavaAstTreeUtil.is(node, TokenType.WHITE_SPACE) && - !BasicJavaAstTreeUtil.is(node, BASIC_JAVA_COMMENT_BIT_SET) && - !BasicJavaAstTreeUtil.is(node, BASIC_CODE_BLOCK) && - !BasicJavaAstTreeUtil.is(node, BASIC_ARRAY_INITIALIZER_EXPRESSION) && - !BasicJavaAstTreeUtil.is(node, BASIC_PARAMETER_LIST) && - !BasicJavaAstTreeUtil.is(node, BASIC_EXPRESSION_LIST) && - !BasicJavaAstTreeUtil.is(node, BASIC_BLOCK_STATEMENT) && - !BasicJavaAstTreeUtil.is(node, JAVA_CODE_REFERENCE_ELEMENT_SET) && - !(BasicJavaAstTreeUtil.isJavaToken(node) && - !BasicJavaAstTreeUtil.isKeyword(node)) && - !BasicJavaAstTreeUtil.is(node, BASIC_DOC_TAG, BASIC_DOC_SNIPPET_TAG, BASIC_DOC_INLINE_TAG) && - getElementPredicate().test(e); - } -} diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/AntLikePropertySelectionHandler.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/AntLikePropertySelectionHandler.java index e721c1a39335..ae2962fae142 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/AntLikePropertySelectionHandler.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/AntLikePropertySelectionHandler.java @@ -9,7 +9,6 @@ import com.intellij.openapi.editor.Editor; import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiComment; import com.intellij.psi.PsiElement; -import com.intellij.psi.impl.source.BasicJavaAstTreeUtil; import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.annotations.NotNull; @@ -17,8 +16,6 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; -import static com.intellij.psi.impl.source.BasicElementTypes.BASIC_JAVA_COMMENT_BIT_SET; - public final class AntLikePropertySelectionHandler extends ExtendWordSelectionHandlerBase { @Override public List select(@NotNull PsiElement e, @NotNull CharSequence editorText, int cursorOffset, @NotNull Editor editor) { @@ -49,9 +46,6 @@ public final class AntLikePropertySelectionHandler extends ExtendWordSelectionHa return false; } - if (BasicJavaAstTreeUtil.getParentOfType(BasicJavaAstTreeUtil.toNode(e), BASIC_JAVA_COMMENT_BIT_SET) == null) { - return true; - } return PsiTreeUtil.getParentOfType(e, PsiComment.class) == null; } } diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/BasicSelectioner.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/BasicSelectioner.java new file mode 100644 index 000000000000..1605418ba5de --- /dev/null +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/BasicSelectioner.java @@ -0,0 +1,38 @@ +// 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.codeInsight.editorActions.wordSelection; + +import com.intellij.codeInsight.editorActions.ExtendWordSelectionHandlerBase; +import com.intellij.lang.Language; +import com.intellij.lang.xml.XMLLanguage; +import com.intellij.psi.*; +import com.intellij.psi.javadoc.PsiDocTag; +import org.jetbrains.annotations.NotNull; + +import java.util.function.Predicate; + +public class BasicSelectioner extends ExtendWordSelectionHandlerBase { + + private static Predicate getElementPredicate() { + return (e) -> { + Language language = e.getLanguage(); + return !(language instanceof XMLLanguage || language.isKindOf(XMLLanguage.INSTANCE)); + }; + } + + @Override + public boolean canSelect(final @NotNull PsiElement e) { + return + !(e instanceof PsiWhiteSpace) && + !(e instanceof PsiComment) && + !(e instanceof PsiCodeBlock) && + !(e instanceof PsiArrayInitializerExpression) && + !(e instanceof PsiParameterList) && + !(e instanceof PsiExpressionList) && + !(e instanceof PsiBlockStatement) && + !(e instanceof PsiJavaCodeReferenceElement) && + !(e instanceof PsiJavaToken && + !(e instanceof PsiKeyword)) && + !(getElementPredicate().test(e)) && + !(e instanceof PsiDocTag); + } +} diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/CaseStatementsSelectioner.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/CaseStatementsSelectioner.java index 29dadbc0595d..044392e329f1 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/CaseStatementsSelectioner.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/CaseStatementsSelectioner.java @@ -1,94 +1,76 @@ // Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.codeInsight.editorActions.wordSelection; -import com.intellij.lang.ASTNode; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.util.TextRange; -import com.intellij.psi.JavaTokenType; -import com.intellij.psi.PsiElement; -import com.intellij.psi.TokenType; -import com.intellij.psi.impl.source.BasicJavaAstTreeUtil; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.PsiUtil; import com.intellij.util.DocumentUtil; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.List; -import static com.intellij.psi.impl.source.BasicJavaElementType.*; - -public final class CaseStatementsSelectioner extends AbstractBasicBackBasicSelectioner { +public final class CaseStatementsSelectioner extends BasicSelectioner { @Override public boolean canSelect(@NotNull PsiElement e) { - ASTNode node = BasicJavaAstTreeUtil.toNode(e); - return node != null && - !BasicJavaAstTreeUtil.is(node, JavaTokenType.RBRACE) && - !BasicJavaAstTreeUtil.is(node, JavaTokenType.LBRACE) && - BasicJavaAstTreeUtil.is(node.getTreeParent(), BASIC_CODE_BLOCK) && - BasicJavaAstTreeUtil.is(node.getTreeParent().getTreeParent(), BASIC_SWITCH_STATEMENT); + return + !(PsiUtil.isJavaToken(e, JavaTokenType.RBRACE)) && + !(PsiUtil.isJavaToken(e, JavaTokenType.LBRACE)) && + e.getParent() instanceof PsiCodeBlock && + e.getParent().getParent() instanceof PsiSwitchStatement; } @Override - public List select(@NotNull PsiElement elementStatement, + public List select(@NotNull PsiElement statement, @NotNull CharSequence editorText, int cursorOffset, @NotNull Editor editor) { - ASTNode statement = BasicJavaAstTreeUtil.toNode(elementStatement); - List result = new ArrayList<>(); - ASTNode caseStart = statement; - ASTNode caseEnd = statement; + PsiElement caseStart = statement; + PsiElement caseEnd = statement; - if (statement == null || - BasicJavaAstTreeUtil.is(statement, BASIC_SWITCH_STATEMENT)) { - return result; - } + if (statement instanceof PsiSwitchStatement) return result; - ASTNode labelStatement = BasicJavaAstTreeUtil.is(statement, BASIC_SWITCH_LABEL_STATEMENT) ? statement : null; - ASTNode sibling; + PsiElement labelStatement = statement instanceof PsiSwitchLabelStatement ? statement : null; + PsiElement sibling; if (labelStatement == null) { - sibling = statement.getTreePrev(); - while (sibling != null && !BasicJavaAstTreeUtil.is(sibling, BASIC_SWITCH_LABEL_STATEMENT)) { - if (!BasicJavaAstTreeUtil.isWhiteSpace(sibling)) caseStart = sibling; - sibling = sibling.getTreePrev(); + sibling = statement.getPrevSibling(); + while (sibling != null && !(sibling instanceof PsiSwitchLabelStatement)) { + if (!(sibling instanceof PsiWhiteSpace)) caseStart = sibling; + sibling = sibling.getPrevSibling(); } labelStatement = sibling; } if (labelStatement != null) { - ASTNode nextLabel = BasicJavaAstTreeUtil.skipSiblingsBackward(labelStatement, TokenType.WHITE_SPACE); - while (BasicJavaAstTreeUtil.is(nextLabel, BASIC_SWITCH_LABEL_STATEMENT)) { + PsiElement nextLabel; + while ((nextLabel = PsiTreeUtil.skipSiblingsBackward(labelStatement, PsiWhiteSpace.class)) instanceof PsiSwitchLabelStatement) { labelStatement = nextLabel; - nextLabel = BasicJavaAstTreeUtil.skipSiblingsBackward(labelStatement, TokenType.WHITE_SPACE); } } - sibling = BasicJavaAstTreeUtil.isWhiteSpace(statement) ? statement.getTreeNext() : statement; - while (BasicJavaAstTreeUtil.is(sibling, BASIC_SWITCH_LABEL_STATEMENT)) { - sibling = BasicJavaAstTreeUtil.skipSiblingsForward(sibling, TokenType.WHITE_SPACE); - } - while (sibling != null && !BasicJavaAstTreeUtil.is(sibling, BASIC_SWITCH_LABEL_STATEMENT)) { - if (!BasicJavaAstTreeUtil.isWhiteSpace(sibling) && - !BasicJavaAstTreeUtil.isJavaToken(sibling) // end of switch + sibling = statement instanceof PsiWhiteSpace ? statement.getNextSibling() : statement; + while (sibling instanceof PsiSwitchLabelStatement) sibling = PsiTreeUtil.skipSiblingsForward(sibling, PsiWhiteSpace.class); + while(sibling != null && !(sibling instanceof PsiSwitchLabelStatement)) { + if (!(sibling instanceof PsiWhiteSpace) && + !(sibling instanceof PsiJavaToken) // end of switch ) { caseEnd = sibling; } - sibling = sibling.getTreeNext(); + sibling = sibling.getNextSibling(); } Document document = editor.getDocument(); + int endOffset = DocumentUtil.getLineEndOffset(caseEnd.getTextOffset() + caseEnd.getTextLength(), document) + 1; - int endOffset = - DocumentUtil.getLineEndOffset(BasicJavaAstTreeUtil.getTextOffset(caseEnd) + caseEnd.getTextLength(), document) + 1; - - if (!BasicJavaAstTreeUtil.is(caseStart, BASIC_SWITCH_LABEL_STATEMENT)) { - result.add(new TextRange(DocumentUtil.getLineStartOffset(BasicJavaAstTreeUtil.getTextOffset(caseStart), document), - endOffset)); + if (!(caseStart instanceof PsiSwitchLabelStatement)) { + result.add(new TextRange(DocumentUtil.getLineStartOffset(caseStart.getTextOffset(), document), endOffset)); } if (labelStatement != null) { - result.add( - new TextRange(DocumentUtil.getLineStartOffset(BasicJavaAstTreeUtil.getTextOffset(labelStatement), document), - endOffset)); + result.add(new TextRange(DocumentUtil.getLineStartOffset(labelStatement.getTextOffset(), document), endOffset)); } return result; } diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/CodeBlockOrInitializerSelectioner.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/CodeBlockOrInitializerSelectioner.java index f724c12310f2..046233fac201 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/CodeBlockOrInitializerSelectioner.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/CodeBlockOrInitializerSelectioner.java @@ -1,41 +1,31 @@ // Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.codeInsight.editorActions.wordSelection; -import com.intellij.lang.ASTNode; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.util.TextRange; -import com.intellij.psi.JavaTokenType; -import com.intellij.psi.PsiElement; -import com.intellij.psi.impl.source.BasicJavaAstTreeUtil; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiUtil; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.List; -import static com.intellij.psi.impl.source.BasicJavaElementType.*; - -public final class CodeBlockOrInitializerSelectioner extends AbstractBasicBackBasicSelectioner { +public final class CodeBlockOrInitializerSelectioner extends BasicSelectioner { @Override public boolean canSelect(@NotNull PsiElement e) { - ASTNode node = BasicJavaAstTreeUtil.toNode(e); - return BasicJavaAstTreeUtil.is(node, BASIC_CODE_BLOCK) || - BasicJavaAstTreeUtil.is(node, BASIC_ARRAY_INITIALIZER_EXPRESSION) || - BasicJavaAstTreeUtil.is(node, CLASS_SET) && - !BasicJavaAstTreeUtil.is(node, BASIC_TYPE_PARAMETER); + return e instanceof PsiCodeBlock || + e instanceof PsiArrayInitializerExpression || + e instanceof PsiClass && !(e instanceof PsiTypeParameter); } + @Override public List select(@NotNull PsiElement e, @NotNull CharSequence editorText, int cursorOffset, @NotNull Editor editor) { List result = new ArrayList<>(); - ASTNode node = BasicJavaAstTreeUtil.toNode(e); - if (node == null) { - return null; - } - result.add(getElementRange(node)); + result.add(getElementRange(e)); - - List children = BasicJavaAstTreeUtil.getChildren(node); - if (!children.isEmpty()) { + PsiElement[] children = e.getChildren(); + if (children.length > 0) { int start = findOpeningBrace(children); // in non-Java PsiClasses, there can be no opening brace @@ -48,49 +38,49 @@ public final class CodeBlockOrInitializerSelectioner extends AbstractBasicBackBa return result; } - public TextRange getElementRange(@NotNull ASTNode astNode) { - if (BasicJavaAstTreeUtil.is(astNode, CLASS_SET)) { - ASTNode lBrace = BasicJavaAstTreeUtil.getLBrace(astNode); - ASTNode rBrace = BasicJavaAstTreeUtil.getRBrace(astNode); + public TextRange getElementRange(@NotNull PsiElement e) { + if (e instanceof PsiClass) { + PsiElement lBrace = ((PsiClass)e).getLBrace(); + PsiElement rBrace = ((PsiClass)e).getRBrace(); if (lBrace != null && rBrace != null) { - return new TextRange(BasicJavaAstTreeUtil.getTextOffset(lBrace), rBrace.getTextRange().getEndOffset()); + return new TextRange(lBrace.getTextOffset(), rBrace.getTextRange().getEndOffset()); } } - return astNode.getTextRange(); + return e.getTextRange(); } - public static int findOpeningBrace(List children) { + public static int findOpeningBrace(PsiElement[] children) { int start = 0; - for (int i = 0; i < children.size(); i++) { - ASTNode child = children.get(i); + for (int i = 0; i < children.length; i++) { + PsiElement child = children[i]; - if (BasicJavaAstTreeUtil.is(child, JavaTokenType.LBRACE)) { + if (PsiUtil.isJavaToken(child, JavaTokenType.LBRACE)) { int j = i + 1; - while (BasicJavaAstTreeUtil.isWhiteSpace(children.get(j))) { + while (children[j] instanceof PsiWhiteSpace) { j++; } - start = children.get(j).getTextRange().getStartOffset(); + start = children[j].getTextRange().getStartOffset(); } } return start; } - public static int findClosingBrace(List children, int startOffset) { - int end = children.getLast().getTextRange().getEndOffset(); - for (int i = 0; i < children.size(); i++) { - ASTNode child = children.get(i); + public static int findClosingBrace(PsiElement[] children, int startOffset) { + int end = children[children.length - 1].getTextRange().getEndOffset(); + for (int i = 0; i < children.length; i++) { + PsiElement child = children[i]; - if (BasicJavaAstTreeUtil.is(child, JavaTokenType.RBRACE)) { + if (PsiUtil.isJavaToken(child, JavaTokenType.RBRACE)) { int j = i - 1; - while (BasicJavaAstTreeUtil.isWhiteSpace(children.get(j)) && children.get(j).getTextRange().getStartOffset() > startOffset) { + while (children[j] instanceof PsiWhiteSpace && children[j].getTextRange().getStartOffset() > startOffset) { j--; } - end = children.get(j).getTextRange().getEndOffset(); + end = children[j].getTextRange().getEndOffset(); } } return end; diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/DocCommentSelectioner.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/DocCommentSelectioner.java index 0e59bfb11d6e..7de718ff65b7 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/DocCommentSelectioner.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/DocCommentSelectioner.java @@ -1,45 +1,36 @@ // Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.codeInsight.editorActions.wordSelection; -import com.intellij.lang.ASTNode; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.util.TextRange; import com.intellij.psi.JavaDocTokenType; import com.intellij.psi.PsiElement; -import com.intellij.psi.impl.source.BasicJavaAstTreeUtil; +import com.intellij.psi.javadoc.PsiDocComment; +import com.intellij.psi.javadoc.PsiDocToken; import com.intellij.util.text.CharArrayUtil; import org.jetbrains.annotations.NotNull; import java.util.List; -import static com.intellij.psi.impl.source.BasicJavaDocElementType.BASIC_DOC_COMMENT; - public final class DocCommentSelectioner extends LineCommentSelectioner { @Override public boolean canSelect(@NotNull PsiElement e) { - return BasicJavaAstTreeUtil.is(BasicJavaAstTreeUtil.toNode(e), BASIC_DOC_COMMENT); + return e instanceof PsiDocComment; } @Override public List select(@NotNull PsiElement e, @NotNull CharSequence editorText, int cursorOffset, @NotNull Editor editor) { List result = super.select(e, editorText, cursorOffset, editor); - if (result == null) { - return null; - } - ASTNode node = BasicJavaAstTreeUtil.toNode(e); - if (node == null) { - return null; - } - - List children = BasicJavaAstTreeUtil.getChildren(node); + if (result == null) return null; + PsiElement[] children = e.getChildren(); int startOffset = e.getTextRange().getStartOffset(); int endOffset = e.getTextRange().getEndOffset(); - for (ASTNode child : children) { - if (BasicJavaAstTreeUtil.is(child, JavaDocTokenType.DOC_COMMENT_DATA)) { - char[] chars = child.getText().toCharArray(); + for (PsiElement child : children) { + if (child instanceof PsiDocToken token && token.getTokenType() == JavaDocTokenType.DOC_COMMENT_DATA) { + char[] chars = token.getText().toCharArray(); if (CharArrayUtil.shiftForward(chars, 0, " *\n\t\r") != chars.length) { break; @@ -49,9 +40,9 @@ public final class DocCommentSelectioner extends LineCommentSelectioner { startOffset = child.getTextRange().getEndOffset(); } - for (ASTNode child : children) { - if (BasicJavaAstTreeUtil.is(child, JavaDocTokenType.DOC_COMMENT_DATA)) { - char[] chars = child.getText().toCharArray(); + for (PsiElement child : children) { + if (child instanceof PsiDocToken token && token.getTokenType() == JavaDocTokenType.DOC_COMMENT_DATA) { + char[] chars = token.getText().toCharArray(); if (CharArrayUtil.shiftForward(chars, 0, " *\n\t\r") != chars.length) { endOffset = child.getTextRange().getEndOffset(); @@ -65,4 +56,4 @@ public final class DocCommentSelectioner extends LineCommentSelectioner { return result; } -} +} \ No newline at end of file diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/DocTagSelectioner.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/DocTagSelectioner.java index 1b5e640363c7..1c7c56e9c73e 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/DocTagSelectioner.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/DocTagSelectioner.java @@ -1,65 +1,60 @@ // Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.codeInsight.editorActions.wordSelection; -import com.intellij.lang.ASTNode; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.util.TextRange; import com.intellij.psi.JavaDocTokenType; import com.intellij.psi.PsiElement; -import com.intellij.psi.impl.source.BasicJavaAstTreeUtil; +import com.intellij.psi.PsiWhiteSpace; +import com.intellij.psi.javadoc.PsiDocTag; +import com.intellij.psi.javadoc.PsiDocToken; +import com.intellij.psi.tree.IElementType; import com.intellij.util.text.CharArrayUtil; import org.jetbrains.annotations.NotNull; import java.util.List; -import static com.intellij.psi.impl.source.BasicJavaDocElementType.*; - public final class DocTagSelectioner extends WordSelectioner { @Override public boolean canSelect(@NotNull PsiElement e) { - ASTNode node = BasicJavaAstTreeUtil.toNode(e); - return BasicJavaAstTreeUtil.is(node, BASIC_DOC_TAG, BASIC_DOC_SNIPPET_TAG, BASIC_DOC_INLINE_TAG); + return e instanceof PsiDocTag; } @Override public List select(@NotNull PsiElement e, @NotNull CharSequence editorText, int cursorOffset, @NotNull Editor editor) { List result = super.select(e, editorText, cursorOffset, editor); - if (result == null) { - return null; - } - result.add(getDocTagRange(e, editorText, cursorOffset)); + if (result == null) return null; + result.add(getDocTagRange((PsiDocTag)e, editorText, cursorOffset)); return result; } - public static TextRange getDocTagRange(@NotNull PsiElement e, @NotNull CharSequence documentText, int minOffset) { + public static TextRange getDocTagRange(PsiDocTag e, CharSequence documentText, int minOffset) { TextRange range = e.getTextRange(); int endOffset = range.getEndOffset(); int startOffset = range.getStartOffset(); - ASTNode node = BasicJavaAstTreeUtil.toNode(e); - if (node == null) { - return null; - } + PsiElement[] children = e.getChildren(); - List children = BasicJavaAstTreeUtil.getChildren(node); + for (int i = children.length - 1; i >= 0; i--) { + PsiElement child = children[i]; - for (ASTNode child : children.reversed()) { int childStartOffset = child.getTextRange().getStartOffset(); if (childStartOffset <= minOffset) { break; } - if (BasicJavaAstTreeUtil.isDocToken(child)) { - CharSequence chars = child.getChars(); + if (child instanceof PsiDocToken token) { + IElementType type = token.getTokenType(); + char[] chars = token.textToCharArray(); int shift = CharArrayUtil.shiftForward(chars, 0, " \t\n\r"); - if (shift != chars.length() && !BasicJavaAstTreeUtil.is(child, JavaDocTokenType.DOC_COMMENT_LEADING_ASTERISKS)) { + if (shift != chars.length && type != JavaDocTokenType.DOC_COMMENT_LEADING_ASTERISKS) { break; } } - else if (!(BasicJavaAstTreeUtil.isWhiteSpace(child))) { + else if (!(child instanceof PsiWhiteSpace)) { break; } diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/FieldSelectioner.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/FieldSelectioner.java index 743c06ba8054..a2873873b65c 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/FieldSelectioner.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/FieldSelectioner.java @@ -1,31 +1,27 @@ // Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.codeInsight.editorActions.wordSelection; -import com.intellij.lang.ASTNode; import com.intellij.lang.java.JavaLanguage; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiElement; -import com.intellij.psi.impl.source.BasicJavaAstTreeUtil; +import com.intellij.psi.PsiField; +import com.intellij.psi.PsiIdentifier; +import com.intellij.psi.javadoc.PsiDocComment; import org.jetbrains.annotations.NotNull; -import java.util.ArrayList; import java.util.List; -import static com.intellij.psi.impl.source.BasicJavaElementType.BASIC_ENUM_CONSTANT; -import static com.intellij.psi.impl.source.BasicJavaElementType.BASIC_FIELD; - public final class FieldSelectioner extends WordSelectioner { @Override public boolean canSelect(@NotNull PsiElement e) { - return BasicJavaAstTreeUtil.is(BasicJavaAstTreeUtil.toNode(e), BASIC_FIELD, BASIC_ENUM_CONSTANT) && - e.getLanguage() == JavaLanguage.INSTANCE; + return e instanceof PsiField && e.getLanguage() == JavaLanguage.INSTANCE; } private static void addRangeElem(final List result, CharSequence editorText, - final ASTNode first, + final PsiElement first, final int end) { if (first != null) { result.addAll(expandToWholeLine(editorText, @@ -36,28 +32,22 @@ public final class FieldSelectioner extends WordSelectioner { @Override public List select(@NotNull PsiElement e, @NotNull CharSequence editorText, int cursorOffset, @NotNull Editor editor) { List result = super.select(e, editorText, cursorOffset, editor); - if (result == null) { - return null; - } - ASTNode node = BasicJavaAstTreeUtil.toNode(e); - if (node == null) { - return null; - } - TextRange fieldRange = node.getTextRange(); - ASTNode nameId = BasicJavaAstTreeUtil.getNameIdentifier(node); - if (nameId == null) return new ArrayList<>(); + if (result == null) return null; + PsiField field = (PsiField)e; + TextRange fieldRange = field.getTextRange(); + PsiIdentifier nameId = field.getNameIdentifier(); TextRange nameRange = nameId.getTextRange(); - ASTNode last = BasicJavaAstTreeUtil.getInitializer(node); + PsiElement last = field.getInitializer(); int end = last == null ? nameRange.getEndOffset() : last.getTextRange().getEndOffset(); - ASTNode comment = BasicJavaAstTreeUtil.getDocComment(node); + PsiDocComment comment = field.getDocComment(); if (comment != null) { TextRange commentTextRange = comment.getTextRange(); addRangeElem(result, editorText, comment, commentTextRange.getEndOffset()); } addRangeElem(result, editorText, nameId, end); - addRangeElem(result, editorText, BasicJavaAstTreeUtil.getTypeElement(node), nameRange.getEndOffset()); - addRangeElem(result, editorText, BasicJavaAstTreeUtil.getModifierList(node), fieldRange.getEndOffset()); + addRangeElem(result, editorText, field.getTypeElement(), nameRange.getEndOffset()); + addRangeElem(result, editorText, field.getModifierList(), fieldRange.getEndOffset()); result.addAll(expandToWholeLine(editorText, fieldRange)); return result; } diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/FinallyBlockSelectioner.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/FinallyBlockSelectioner.java index 3e2129c8b514..9bf4cb681705 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/FinallyBlockSelectioner.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/FinallyBlockSelectioner.java @@ -1,36 +1,32 @@ // Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.codeInsight.editorActions.wordSelection; -import com.intellij.lang.ASTNode; +import com.intellij.java.syntax.parser.JavaKeywords; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.util.TextRange; -import com.intellij.psi.JavaTokenType; +import com.intellij.psi.PsiCodeBlock; import com.intellij.psi.PsiElement; -import com.intellij.psi.impl.source.BasicJavaAstTreeUtil; +import com.intellij.psi.PsiKeyword; +import com.intellij.psi.PsiTryStatement; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.List; -import static com.intellij.psi.impl.source.BasicJavaElementType.BASIC_TRY_STATEMENT; - -public final class FinallyBlockSelectioner extends AbstractBasicBackBasicSelectioner { +public final class FinallyBlockSelectioner extends BasicSelectioner { @Override public boolean canSelect(@NotNull PsiElement e) { - return BasicJavaAstTreeUtil.is(BasicJavaAstTreeUtil.toNode(e), JavaTokenType.FINALLY_KEYWORD); + return e instanceof PsiKeyword && JavaKeywords.FINALLY.equals(e.getText()); } + @Override public List select(@NotNull PsiElement e, @NotNull CharSequence editorText, int cursorOffset, @NotNull Editor editor) { List result = new ArrayList<>(); - ASTNode node = BasicJavaAstTreeUtil.toNode(e); - if (node == null) { - return null; - } - final ASTNode parent = node.getTreeParent(); - if (BasicJavaAstTreeUtil.is(parent, BASIC_TRY_STATEMENT)) { - final ASTNode finallyBlock = BasicJavaAstTreeUtil.getFinallyBlock(parent); + final PsiElement parent = e.getParent(); + if (parent instanceof PsiTryStatement tryStatement) { + final PsiCodeBlock finallyBlock = tryStatement.getFinallyBlock(); if (finallyBlock != null) { result.add(new TextRange(e.getTextRange().getStartOffset(), finallyBlock.getTextRange().getEndOffset())); } diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/ForStatementHeaderSelectioner.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/ForStatementHeaderSelectioner.java index 02e44ddff7d5..4810eaaf1563 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/ForStatementHeaderSelectioner.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/ForStatementHeaderSelectioner.java @@ -2,37 +2,29 @@ package com.intellij.codeInsight.editorActions.wordSelection; import com.intellij.codeInsight.editorActions.ExtendWordSelectionHandler; -import com.intellij.lang.ASTNode; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiElement; -import com.intellij.psi.impl.source.BasicJavaAstTreeUtil; +import com.intellij.psi.PsiForStatement; +import com.intellij.psi.PsiForeachStatement; +import com.intellij.psi.PsiJavaToken; import org.jetbrains.annotations.NotNull; import java.util.Collections; import java.util.List; -import static com.intellij.psi.impl.source.BasicJavaElementType.BASIC_FOREACH_STATEMENT; -import static com.intellij.psi.impl.source.BasicJavaElementType.BASIC_FOR_STATEMENT; - public final class ForStatementHeaderSelectioner implements ExtendWordSelectionHandler { @Override public boolean canSelect(@NotNull PsiElement e) { - ASTNode node = BasicJavaAstTreeUtil.toNode(e); - return - BasicJavaAstTreeUtil.is(node, BASIC_FOR_STATEMENT) || - BasicJavaAstTreeUtil.is(node, BASIC_FOREACH_STATEMENT); + return e instanceof PsiForStatement || e instanceof PsiForeachStatement; } @Override public List select(@NotNull PsiElement e, @NotNull CharSequence editorText, int cursorOffset, @NotNull Editor editor) { - ASTNode node = BasicJavaAstTreeUtil.toNode(e); - if (node == null) { - return null; - } - - ASTNode lParen = BasicJavaAstTreeUtil.getLParenth(node); - ASTNode rParen = BasicJavaAstTreeUtil.getRParenth(node); + PsiJavaToken lParen = e instanceof PsiForStatement ? ((PsiForStatement)e).getLParenth() + : e instanceof PsiForeachStatement ? ((PsiForeachStatement)e).getLParenth() : null; + PsiJavaToken rParen = e instanceof PsiForStatement ? ((PsiForStatement)e).getRParenth() + : e instanceof PsiForeachStatement ? ((PsiForeachStatement)e).getRParenth() : null; if (lParen == null || rParen == null) return null; TextRange result = new TextRange(lParen.getTextRange().getEndOffset(), rParen.getTextRange().getStartOffset()); return result.containsOffset(cursorOffset) ? Collections.singletonList(result) : null; diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/IfStatementSelectioner.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/IfStatementSelectioner.java index c2c4d22c010d..a996bd8672de 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/IfStatementSelectioner.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/IfStatementSelectioner.java @@ -1,37 +1,35 @@ // Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.codeInsight.editorActions.wordSelection; -import com.intellij.lang.ASTNode; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiElement; -import com.intellij.psi.impl.source.BasicJavaAstTreeUtil; +import com.intellij.psi.PsiIfStatement; +import com.intellij.psi.PsiKeyword; +import com.intellij.psi.PsiStatement; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.List; -import static com.intellij.psi.impl.source.BasicJavaElementType.BASIC_IF_STATEMENT; - -public final class IfStatementSelectioner extends AbstractBasicBackBasicSelectioner { +public final class IfStatementSelectioner extends BasicSelectioner { @Override public boolean canSelect(@NotNull PsiElement e) { - return BasicJavaAstTreeUtil.is(BasicJavaAstTreeUtil.toNode(e), BASIC_IF_STATEMENT); + return e instanceof PsiIfStatement; } @Override public List select(@NotNull PsiElement e, @NotNull CharSequence editorText, int cursorOffset, @NotNull Editor editor) { List result = new ArrayList<>(expandToWholeLine(editorText, e.getTextRange(), false)); - ASTNode node = BasicJavaAstTreeUtil.toNode(e); - if (node == null) { - return null; - } - final ASTNode elseKeyword = BasicJavaAstTreeUtil.getElseElement(node); + + PsiIfStatement statement = (PsiIfStatement)e; + + final PsiKeyword elseKeyword = statement.getElseElement(); if (elseKeyword != null) { - final ASTNode then = BasicJavaAstTreeUtil.getThenBranch(node); + final PsiStatement then = statement.getThenBranch(); if (then != null) { - final TextRange thenRange = new TextRange(e.getTextRange().getStartOffset(), then.getTextRange().getEndOffset()); + final TextRange thenRange = new TextRange(statement.getTextRange().getStartOffset(), then.getTextRange().getEndOffset()); if (thenRange.contains(cursorOffset)) { result.addAll(expandToWholeLine(editorText, thenRange, false)); } @@ -39,14 +37,14 @@ public final class IfStatementSelectioner extends AbstractBasicBackBasicSelectio result.addAll(expandToWholeLine(editorText, new TextRange(elseKeyword.getTextRange().getStartOffset(), - node.getTextRange().getEndOffset()), + statement.getTextRange().getEndOffset()), false)); - final ASTNode branch = BasicJavaAstTreeUtil.getElseBranch(node); - if (BasicJavaAstTreeUtil.is(branch, BASIC_IF_STATEMENT)) { - final ASTNode element = BasicJavaAstTreeUtil.getElseElement(branch); + final PsiStatement branch = statement.getElseBranch(); + if (branch instanceof PsiIfStatement elseIf) { + final PsiKeyword element = elseIf.getElseElement(); if (element != null) { - final ASTNode elseThen = BasicJavaAstTreeUtil.getThenBranch(branch); + final PsiStatement elseThen = elseIf.getThenBranch(); if (elseThen != null) { result.addAll(expandToWholeLine(editorText, new TextRange(elseKeyword.getTextRange().getStartOffset(), diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/JavaBasicWordSelectionFilter.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/JavaBasicWordSelectionFilter.java index c214832f946f..2bf88b3cae5d 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/JavaBasicWordSelectionFilter.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/JavaBasicWordSelectionFilter.java @@ -1,14 +1,10 @@ // Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.codeInsight.editorActions.wordSelection; -import com.intellij.lang.ASTNode; import com.intellij.openapi.util.Condition; -import com.intellij.psi.JavaDocTokenType; -import com.intellij.psi.PsiElement; -import com.intellij.psi.impl.source.BasicJavaAstTreeUtil; - -import static com.intellij.psi.impl.source.BasicJavaDocElementType.*; -import static com.intellij.psi.impl.source.BasicJavaElementType.*; +import com.intellij.psi.*; +import com.intellij.psi.javadoc.PsiDocTag; +import com.intellij.psi.javadoc.PsiDocToken; public final class JavaBasicWordSelectionFilter implements Condition { @@ -18,16 +14,14 @@ public final class JavaBasicWordSelectionFilter implements Condition @Override public boolean value(final PsiElement e) { - ASTNode node = BasicJavaAstTreeUtil.toNode(e); - return !BasicJavaAstTreeUtil.is(node, BASIC_CODE_BLOCK) && - !BasicJavaAstTreeUtil.is(node, BASIC_ARRAY_INITIALIZER_EXPRESSION) && - !BasicJavaAstTreeUtil.is(node, BASIC_PARAMETER_LIST) && - !BasicJavaAstTreeUtil.is(node, BASIC_EXPRESSION_LIST) && - !BasicJavaAstTreeUtil.is(node, BASIC_BLOCK_STATEMENT) && - !BasicJavaAstTreeUtil.is(node, JAVA_CODE_REFERENCE_ELEMENT_SET) && - !BasicJavaAstTreeUtil.isJavaToken(node) && - !BasicJavaAstTreeUtil.is(node, BASIC_DOC_TAG, BASIC_DOC_SNIPPET_TAG, BASIC_DOC_INLINE_TAG) && - !(BasicJavaAstTreeUtil.isDocToken(node) && - BasicJavaAstTreeUtil.is(node, JavaDocTokenType.DOC_COMMENT_DATA)); + return !(e instanceof PsiCodeBlock) && + !(e instanceof PsiArrayInitializerExpression) && + !(e instanceof PsiParameterList) && + !(e instanceof PsiExpressionList) && + !(e instanceof PsiBlockStatement) && + !(e instanceof PsiJavaCodeReferenceElement) && + !(e instanceof PsiJavaToken) && + !(e instanceof PsiDocTag) && + !(e instanceof PsiDocToken && ((PsiDocToken)e).getTokenType() == JavaDocTokenType.DOC_COMMENT_DATA); } } diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/JavaTokenSelectioner.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/JavaTokenSelectioner.java index a4adcd77fea1..916f38f28e55 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/JavaTokenSelectioner.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/JavaTokenSelectioner.java @@ -1,38 +1,25 @@ // Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.codeInsight.editorActions.wordSelection; -import com.intellij.lang.ASTNode; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.util.TextRange; -import com.intellij.psi.JavaTokenType; -import com.intellij.psi.PsiElement; -import com.intellij.psi.impl.source.BasicJavaAstTreeUtil; +import com.intellij.psi.*; import org.jetbrains.annotations.NotNull; import java.util.List; -import static com.intellij.psi.impl.source.BasicJavaElementType.BASIC_CODE_BLOCK; -import static com.intellij.psi.impl.source.BasicJavaElementType.CLASS_SET; - -public final class JavaTokenSelectioner extends AbstractBasicBackBasicSelectioner { +public final class JavaTokenSelectioner extends BasicSelectioner { @Override public boolean canSelect(@NotNull PsiElement e) { - ASTNode node = BasicJavaAstTreeUtil.toNode(e); - return BasicJavaAstTreeUtil.isJavaToken(node) && !BasicJavaAstTreeUtil.isKeyword(node) && - !BasicJavaAstTreeUtil.is(node.getTreeParent(), BASIC_CODE_BLOCK) && - !BasicJavaAstTreeUtil.is(node.getTreeParent(), CLASS_SET); + return e instanceof PsiJavaToken && !(e instanceof PsiKeyword) && !(e.getParent()instanceof PsiCodeBlock) && !(e.getParent() instanceof PsiClass); } @Override public List select(@NotNull PsiElement e, @NotNull CharSequence editorText, int cursorOffset, @NotNull Editor editor) { - ASTNode node = BasicJavaAstTreeUtil.toNode(e); - if (node == null) { - return null; - } + PsiJavaToken token = (PsiJavaToken)e; - if (!BasicJavaAstTreeUtil.is(node, JavaTokenType.SEMICOLON) && - !BasicJavaAstTreeUtil.is(node, JavaTokenType.LPARENTH)) { + if (token.getTokenType() != JavaTokenType.SEMICOLON && token.getTokenType() != JavaTokenType.LPARENTH) { return super.select(e, editorText, cursorOffset, editor); } else { diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/JavaWordSelectioner.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/JavaWordSelectioner.java index f5bd138717d5..a1f4beb60f15 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/JavaWordSelectioner.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/JavaWordSelectioner.java @@ -1,12 +1,14 @@ // Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.codeInsight.editorActions.wordSelection; -import com.intellij.lang.ASTNode; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.util.TextRange; import com.intellij.psi.JavaTokenType; import com.intellij.psi.PsiElement; -import com.intellij.psi.impl.source.BasicJavaAstTreeUtil; +import com.intellij.psi.PsiJavaToken; +import com.intellij.psi.PsiKeyword; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.util.PsiUtil; import org.jetbrains.annotations.NotNull; import java.util.Iterator; @@ -15,12 +17,12 @@ import java.util.List; public final class JavaWordSelectioner extends AbstractWordSelectioner { @Override public boolean canSelect(@NotNull PsiElement e) { - ASTNode node = BasicJavaAstTreeUtil.toNode(e); - if (BasicJavaAstTreeUtil.isKeyword(node)) { + if (e instanceof PsiKeyword) { return true; } - if (BasicJavaAstTreeUtil.isJavaToken(node)) { - return BasicJavaAstTreeUtil.is(node, JavaTokenType.IDENTIFIER) || BasicJavaAstTreeUtil.is(node, JavaTokenType.STRING_LITERAL); + if (e instanceof PsiJavaToken) { + IElementType tokenType = ((PsiJavaToken)e).getTokenType(); + return tokenType == JavaTokenType.IDENTIFIER || tokenType == JavaTokenType.STRING_LITERAL; } return false; } @@ -28,10 +30,8 @@ public final class JavaWordSelectioner extends AbstractWordSelectioner { @Override public List select(@NotNull PsiElement e, @NotNull CharSequence editorText, int cursorOffset, @NotNull Editor editor) { List ranges = super.select(e, editorText, cursorOffset, editor); - if (ranges == null) { - return null; - } - if (BasicJavaAstTreeUtil.is(BasicJavaAstTreeUtil.toNode(e), JavaTokenType.STRING_LITERAL)) { + if (ranges == null) return null; + if (PsiUtil.isJavaToken(e, JavaTokenType.STRING_LITERAL)) { killRangesBreakingEscapes(e, ranges, e.getTextRange()); } return ranges; @@ -47,4 +47,4 @@ public final class JavaWordSelectioner extends AbstractWordSelectioner { } } } -} +} \ No newline at end of file diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/ListSelectioner.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/ListSelectioner.java index a09e64d87b49..16ef1c199ed6 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/ListSelectioner.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/ListSelectioner.java @@ -1,47 +1,35 @@ // Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.codeInsight.editorActions.wordSelection; -import com.intellij.lang.ASTNode; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.util.TextRange; -import com.intellij.psi.JavaTokenType; -import com.intellij.psi.PsiElement; -import com.intellij.psi.impl.source.BasicJavaAstTreeUtil; +import com.intellij.psi.*; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.List; -import static com.intellij.psi.impl.source.BasicJavaElementType.*; - -public final class ListSelectioner extends AbstractBasicBackBasicSelectioner { +public final class ListSelectioner extends BasicSelectioner { @Override public boolean canSelect(@NotNull PsiElement e) { - ASTNode node = BasicJavaAstTreeUtil.toNode(e); - return BasicJavaAstTreeUtil.is(node, BASIC_PARAMETER_LIST) || - BasicJavaAstTreeUtil.is(node, BASIC_EXPRESSION_LIST) || - BasicJavaAstTreeUtil.is(node, BASIC_RECORD_HEADER); + return e instanceof PsiParameterList || e instanceof PsiExpressionList || e instanceof PsiRecordHeader; } @Override public List select(@NotNull PsiElement e, @NotNull CharSequence editorText, int cursorOffset, @NotNull Editor editor) { - ASTNode node = BasicJavaAstTreeUtil.toNode(e); - if (node == null) { - return null; - } - List children = BasicJavaAstTreeUtil.getChildren(node); + PsiElement[] children = e.getChildren(); int start = 0; int end = 0; - for (ASTNode child : children) { - if (BasicJavaAstTreeUtil.isJavaToken(child)) { - if (BasicJavaAstTreeUtil.is(child, JavaTokenType.LPARENTH)) { - start = BasicJavaAstTreeUtil.getTextOffset(child) + 1; + for (PsiElement child : children) { + if (child instanceof PsiJavaToken token) { + if (token.getTokenType() == JavaTokenType.LPARENTH) { + start = token.getTextOffset() + 1; } - if (BasicJavaAstTreeUtil.is(child, JavaTokenType.RPARENTH)) { - end = BasicJavaAstTreeUtil.getTextOffset(child); + if (token.getTokenType() == JavaTokenType.RPARENTH) { + end = token.getTextOffset(); } } } diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/LiteralSelectioner.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/LiteralSelectioner.java index 4fbf44f465a4..66ad45a60b93 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/LiteralSelectioner.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/LiteralSelectioner.java @@ -16,7 +16,7 @@ import org.jetbrains.annotations.NotNull; import java.util.List; -public final class LiteralSelectioner extends AbstractBasicBackBasicSelectioner { +public final class LiteralSelectioner extends BasicSelectioner { @Override public boolean canSelect(@NotNull PsiElement e) { diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/MethodCallSelectioner.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/MethodCallSelectioner.java index 3666e324acb2..6fe64e5530c4 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/MethodCallSelectioner.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/MethodCallSelectioner.java @@ -2,42 +2,31 @@ package com.intellij.codeInsight.editorActions.wordSelection; import com.intellij.codeInsight.editorActions.ExtendWordSelectionHandler; -import com.intellij.lang.ASTNode; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiElement; -import com.intellij.psi.impl.source.BasicJavaAstTreeUtil; +import com.intellij.psi.PsiMethodCallExpression; import org.jetbrains.annotations.NotNull; -import java.util.Arrays; import java.util.List; -import static com.intellij.psi.impl.source.BasicJavaElementType.BASIC_METHOD_CALL_EXPRESSION; - public final class MethodCallSelectioner implements ExtendWordSelectionHandler { @Override public boolean canSelect(@NotNull PsiElement e) { - return BasicJavaAstTreeUtil.is(BasicJavaAstTreeUtil.toNode(e), BASIC_METHOD_CALL_EXPRESSION); + return e instanceof PsiMethodCallExpression; } @Override public List select(@NotNull PsiElement e, @NotNull CharSequence editorText, int cursorOffset, @NotNull Editor editor) { - ASTNode node = BasicJavaAstTreeUtil.toNode(e); - if (node == null) { - return null; - } - ASTNode methodExpression = BasicJavaAstTreeUtil.getMethodExpression(node); - if (methodExpression == null) { - return null; - } - ASTNode referenceNameElement = BasicJavaAstTreeUtil.getReferenceNameElement(methodExpression); + PsiMethodCallExpression methodCall = (PsiMethodCallExpression)e; + PsiElement referenceNameElement = methodCall.getMethodExpression().getReferenceNameElement(); if (referenceNameElement == null) { return null; } else { - return Arrays.asList(new TextRange(referenceNameElement.getTextRange().getStartOffset(), e.getTextRange().getEndOffset()), - e.getTextRange()); + return List.of(new TextRange(referenceNameElement.getTextRange().getStartOffset(), methodCall.getTextRange().getEndOffset()), + methodCall.getTextRange()); } } } diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/MethodOrClassSelectioner.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/MethodOrClassSelectioner.java index f74c068363cd..86dbfbeed903 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/MethodOrClassSelectioner.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/MethodOrClassSelectioner.java @@ -1,12 +1,12 @@ // Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.codeInsight.editorActions.wordSelection; -import com.intellij.lang.ASTNode; import com.intellij.lang.java.JavaLanguage; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.util.TextRange; -import com.intellij.psi.PsiElement; -import com.intellij.psi.impl.source.BasicJavaAstTreeUtil; +import com.intellij.psi.*; +import com.intellij.psi.javadoc.PsiDocComment; +import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; @@ -14,20 +14,11 @@ import java.util.Collection; import java.util.Collections; import java.util.List; -import static com.intellij.psi.impl.source.BasicElementTypes.BASIC_JAVA_COMMENT_BIT_SET; -import static com.intellij.psi.impl.source.BasicElementTypes.BASIC_JAVA_COMMENT_OR_WHITESPACE_BIT_SET; -import static com.intellij.psi.impl.source.BasicJavaDocElementType.BASIC_DOC_COMMENT; -import static com.intellij.psi.impl.source.BasicJavaElementType.*; - -public final class MethodOrClassSelectioner extends AbstractBasicBackBasicSelectioner { +public final class MethodOrClassSelectioner extends BasicSelectioner { @Override public boolean canSelect(@NotNull PsiElement e) { - ASTNode node = BasicJavaAstTreeUtil.toNode(e); - return ( - BasicJavaAstTreeUtil.is(node, CLASS_SET) && - !BasicJavaAstTreeUtil.is(node, BASIC_TYPE_PARAMETER) || - BasicJavaAstTreeUtil.is(node, BASIC_METHOD)) && + return (e instanceof PsiClass && !(e instanceof PsiTypeParameter) || e instanceof PsiMethod) && e.getLanguage() == JavaLanguage.INSTANCE; } @@ -35,67 +26,63 @@ public final class MethodOrClassSelectioner extends AbstractBasicBackBasicSelect public List select(@NotNull PsiElement e, @NotNull CharSequence editorText, int cursorOffset, @NotNull Editor editor) { List result = new ArrayList<>(); - ASTNode node = BasicJavaAstTreeUtil.toNode(e); - if (node == null) { - return result; - } - ASTNode firstChild = node.getFirstChildNode(); - List children = BasicJavaAstTreeUtil.getChildren(node); + PsiElement firstChild = e.getFirstChild(); + PsiElement[] children = e.getChildren(); int i = 1; - if (BasicJavaAstTreeUtil.is(firstChild, BASIC_DOC_COMMENT)) { - while (BasicJavaAstTreeUtil.isWhiteSpace(children.get(i))) { + if (firstChild instanceof PsiDocComment) { + while (children[i] instanceof PsiWhiteSpace) { i++; } - TextRange range = new TextRange(children.get(i).getTextRange().getStartOffset(), e.getTextRange().getEndOffset()); + TextRange range = new TextRange(children[i].getTextRange().getStartOffset(), e.getTextRange().getEndOffset()); result.add(range); result.addAll(expandToWholeLinesWithBlanks(editorText, range)); range = firstChild.getTextRange(); result.addAll(expandToWholeLinesWithBlanks(editorText, range)); - firstChild = children.get(i++); + firstChild = children[i++]; } - if (BasicJavaAstTreeUtil.is(firstChild, BASIC_JAVA_COMMENT_BIT_SET)) { - while (BasicJavaAstTreeUtil.is(children.get(i), BASIC_JAVA_COMMENT_OR_WHITESPACE_BIT_SET)) { + if (firstChild instanceof PsiComment) { + while (children[i] instanceof PsiComment || children[i] instanceof PsiWhiteSpace) { i++; } - ASTNode last = BasicJavaAstTreeUtil.isWhiteSpace(children.get(i - 1)) ? children.get(i - 2) : children.get(i - 1); + PsiElement last = children[i - 1] instanceof PsiWhiteSpace ? children[i - 2] : children[i - 1]; TextRange range = new TextRange(firstChild.getTextRange().getStartOffset(), last.getTextRange().getEndOffset()); if (range.contains(cursorOffset)) { result.addAll(expandToWholeLinesWithBlanks(editorText, range)); } - range = new TextRange(children.get(i).getTextRange().getStartOffset(), e.getTextRange().getEndOffset()); + range = new TextRange(children[i].getTextRange().getStartOffset(), e.getTextRange().getEndOffset()); result.add(range); result.addAll(expandToWholeLinesWithBlanks(editorText, range)); } - result.add(node.getTextRange()); - result.addAll(expandToWholeLinesWithBlanks(editorText, node.getTextRange())); + result.add(e.getTextRange()); + result.addAll(expandToWholeLinesWithBlanks(editorText, e.getTextRange())); - if (BasicJavaAstTreeUtil.is(node, CLASS_SET)) { - result.addAll(selectWithTypeParameters(node)); + if (e instanceof PsiClass) { + result.addAll(selectWithTypeParameters((PsiClass)e)); result.addAll(selectBetweenBracesLines(children, editorText)); } - if (BasicJavaAstTreeUtil.is(node, BASIC_ANONYMOUS_CLASS)) { - result.addAll(selectWholeBlock(node)); + if (e instanceof PsiAnonymousClass) { + result.addAll(selectWholeBlock((PsiAnonymousClass)e)); } return result; } - private static Collection selectWithTypeParameters(@NotNull ASTNode astClass) { - final ASTNode identifier = BasicJavaAstTreeUtil.getNameIdentifier(astClass); - final ASTNode list = BasicJavaAstTreeUtil.getTypeParameterList(astClass); + private static Collection selectWithTypeParameters(@NotNull PsiClass psiClass) { + final PsiIdentifier identifier = psiClass.getNameIdentifier(); + final PsiTypeParameterList list = psiClass.getTypeParameterList(); if (identifier != null && list != null) { return Collections.singletonList(new TextRange(identifier.getTextRange().getStartOffset(), list.getTextRange().getEndOffset())); } return Collections.emptyList(); } - private static Collection selectBetweenBracesLines(List children, + private static Collection selectBetweenBracesLines(PsiElement @NotNull [] children, @NotNull CharSequence editorText) { int start = CodeBlockOrInitializerSelectioner.findOpeningBrace(children); // in non-Java PsiClasses, there can be no opening brace @@ -107,11 +94,12 @@ public final class MethodOrClassSelectioner extends AbstractBasicBackBasicSelect return Collections.emptyList(); } - private static Collection selectWholeBlock(ASTNode clazz) { - ASTNode lBrace = BasicJavaAstTreeUtil.getLBrace(clazz); - ASTNode rBrace = BasicJavaAstTreeUtil.getRBrace(clazz); - if (lBrace != null && rBrace != null) { - return Collections.singleton(new TextRange(lBrace.getTextRange().getStartOffset(), rBrace.getTextRange().getEndOffset())); + private static Collection selectWholeBlock(PsiClass c) { + PsiJavaToken[] tokens = PsiTreeUtil.getChildrenOfType(c, PsiJavaToken.class); + if (tokens != null && tokens.length == 2 && + tokens[0].getTokenType() == JavaTokenType.LBRACE && + tokens[1].getTokenType() == JavaTokenType.RBRACE) { + return Collections.singleton(new TextRange(tokens[0].getTextRange().getStartOffset(), tokens[1].getTextRange().getEndOffset())); } return Collections.emptyList(); } diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/ReferenceSelectioner.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/ReferenceSelectioner.java index 19571ca2d162..2252ebe07ceb 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/ReferenceSelectioner.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/ReferenceSelectioner.java @@ -1,56 +1,46 @@ // Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.codeInsight.editorActions.wordSelection; -import com.intellij.lang.ASTNode; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.util.TextRange; -import com.intellij.psi.PsiElement; -import com.intellij.psi.impl.source.BasicJavaAstTreeUtil; +import com.intellij.psi.*; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.List; -import static com.intellij.psi.impl.source.BasicJavaElementType.*; - -public final class ReferenceSelectioner extends AbstractBasicBackBasicSelectioner { +public final class ReferenceSelectioner extends BasicSelectioner { @Override public boolean canSelect(@NotNull PsiElement e) { - ASTNode node = BasicJavaAstTreeUtil.toNode(e); - return BasicJavaAstTreeUtil.is(node, JAVA_CODE_REFERENCE_ELEMENT_SET); + return e instanceof PsiJavaCodeReferenceElement; } @Override public List select(@NotNull PsiElement e, @NotNull CharSequence editorText, int cursorOffset, @NotNull Editor editor) { - ASTNode node = BasicJavaAstTreeUtil.toNode(e); - ASTNode endElement = node; - if (endElement == null) { - return null; - } - while (BasicJavaAstTreeUtil.is(endElement, JAVA_CODE_REFERENCE_ELEMENT_SET) && - endElement.getTreeNext() != null) { - endElement = endElement.getTreeNext(); + PsiElement endElement = e; + + while (endElement instanceof PsiJavaCodeReferenceElement && endElement.getNextSibling() != null) { + endElement = endElement.getNextSibling(); } - if (!(BasicJavaAstTreeUtil.is(endElement, JAVA_CODE_REFERENCE_ELEMENT_SET)) && - !(BasicJavaAstTreeUtil.is(endElement.getTreePrev(), REFERENCE_EXPRESSION_SET) && - BasicJavaAstTreeUtil.is(endElement, BASIC_EXPRESSION_LIST))) { - endElement = endElement.getTreePrev(); + if (!(endElement instanceof PsiJavaCodeReferenceElement) && + !(endElement.getPrevSibling() instanceof PsiReferenceExpression && endElement instanceof PsiExpressionList)) { + endElement = endElement.getPrevSibling(); } - ASTNode element = node; + PsiElement element = e; List result = new ArrayList<>(); - while (BasicJavaAstTreeUtil.is(element, JAVA_CODE_REFERENCE_ELEMENT_SET)) { - ASTNode firstChild = element.getFirstChildNode(); + while (element instanceof PsiJavaCodeReferenceElement) { + PsiElement firstChild = element.getFirstChild(); - ASTNode referenceName = BasicJavaAstTreeUtil.getReferenceNameElement(element); + PsiElement referenceName = ((PsiJavaCodeReferenceElement)element).getReferenceNameElement(); if (referenceName != null) { result.addAll(expandToWholeLine(editorText, new TextRange(referenceName.getTextRange().getStartOffset(), endElement.getTextRange().getEndOffset()))); - if (BasicJavaAstTreeUtil.is(endElement, JAVA_CODE_REFERENCE_ELEMENT_SET)) { - final ASTNode endReferenceName = BasicJavaAstTreeUtil.getReferenceNameElement(endElement); + if (endElement instanceof PsiJavaCodeReferenceElement) { + final PsiElement endReferenceName = ((PsiJavaCodeReferenceElement)endElement).getReferenceNameElement(); if (endReferenceName != null) { result.addAll(expandToWholeLine(editorText, new TextRange(referenceName.getTextRange().getStartOffset(), endReferenceName.getTextRange().getEndOffset()))); @@ -67,13 +57,13 @@ public final class ReferenceSelectioner extends AbstractBasicBackBasicSelectione result.add(range); result.addAll(expandToWholeLine(editorText, range)); - if (!(BasicJavaAstTreeUtil.is(node.getTreeParent(), JAVA_CODE_REFERENCE_ELEMENT_SET))) { - if (BasicJavaAstTreeUtil.isJavaToken(node.getTreeNext()) || - BasicJavaAstTreeUtil.isWhiteSpace(node.getTreeNext()) || - BasicJavaAstTreeUtil.is(node.getTreeNext(), BASIC_EXPRESSION_LIST)) { - List superSelect = super.select(e, editorText, cursorOffset, editor); - if (superSelect != null) { - result.addAll(superSelect); + if (!(e.getParent() instanceof PsiJavaCodeReferenceElement)) { + if (e.getNextSibling() instanceof PsiJavaToken || + e.getNextSibling() instanceof PsiWhiteSpace || + e.getNextSibling() instanceof PsiExpressionList) { + List select = super.select(e, editorText, cursorOffset, editor); + if (select != null) { + result.addAll(select); } } } diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/StatementGroupSelectioner.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/StatementGroupSelectioner.java index 4f83a14f2032..949690318544 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/StatementGroupSelectioner.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/StatementGroupSelectioner.java @@ -1,89 +1,84 @@ // Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.codeInsight.editorActions.wordSelection; -import com.intellij.lang.ASTNode; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.text.LineTokenizer; -import com.intellij.psi.JavaTokenType; -import com.intellij.psi.PsiElement; -import com.intellij.psi.impl.source.BasicJavaAstTreeUtil; +import com.intellij.psi.*; +import com.intellij.psi.javadoc.PsiDocComment; +import com.intellij.psi.jsp.IJspCodeBlock; +import com.intellij.psi.util.PsiUtil; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.List; -import static com.intellij.psi.impl.source.BasicJavaElementType.*; - -public final class StatementGroupSelectioner extends AbstractBasicBackBasicSelectioner { +public final class StatementGroupSelectioner extends BasicSelectioner { @Override public boolean canSelect(@NotNull PsiElement e) { - return BasicJavaAstTreeUtil.is(BasicJavaAstTreeUtil.toNode(e), STATEMENT_SET); + return e instanceof PsiStatement || e instanceof PsiComment && !(e instanceof PsiDocComment); } @Override public List select(@NotNull PsiElement e, @NotNull CharSequence editorText, int cursorOffset, @NotNull Editor editor) { List result = new ArrayList<>(); - PsiElement parentElement = e.getParent(); - ASTNode node = BasicJavaAstTreeUtil.toNode(e); - if (node == null) { - return result; - } - ASTNode parentNode = BasicJavaAstTreeUtil.toNode(parentElement); - if (!BasicJavaAstTreeUtil.is(parentNode, BASIC_CODE_BLOCK) && - !BasicJavaAstTreeUtil.is(parentNode, BASIC_BLOCK_STATEMENT) || - BasicJavaAstTreeUtil.is(node, BASIC_SWITCH_LABEL_STATEMENT)) { + PsiElement parent = e.getParent(); + + if (!(parent instanceof PsiCodeBlock) && !(parent instanceof PsiBlockStatement) || parent instanceof IJspCodeBlock || + e instanceof PsiSwitchLabelStatement) { return result; } - ASTNode startElement = node; - ASTNode endElement = node; + PsiElement startElement = e; + PsiElement endElement = e; - while (startElement.getTreePrev() != null) { - ASTNode sibling = startElement.getTreePrev(); + while (startElement.getPrevSibling() != null) { + PsiElement sibling = startElement.getPrevSibling(); - if (BasicJavaAstTreeUtil.is(sibling, JavaTokenType.LBRACE)) break; + if (PsiUtil.isJavaToken(sibling, JavaTokenType.LBRACE)) break; - if (BasicJavaAstTreeUtil.isWhiteSpace(sibling)) { - String[] strings = LineTokenizer.tokenize(sibling.getText().toCharArray(), false); + if (sibling instanceof PsiWhiteSpace whiteSpace) { + String[] strings = LineTokenizer.tokenize(whiteSpace.getText().toCharArray(), false); if (strings.length > 2) { break; } } - if (BasicJavaAstTreeUtil.is(sibling, BASIC_SWITCH_LABEL_STATEMENT)) break; + if (sibling instanceof PsiSwitchLabelStatement) break; startElement = sibling; } - while (BasicJavaAstTreeUtil.isWhiteSpace(startElement)) { - startElement = startElement.getTreeNext(); + while (startElement instanceof PsiWhiteSpace) { + startElement = startElement.getNextSibling(); } - while (endElement.getTreeNext() != null) { - ASTNode sibling = endElement.getTreeNext(); + while (endElement.getNextSibling() != null) { + PsiElement sibling = endElement.getNextSibling(); - if (BasicJavaAstTreeUtil.is(sibling, JavaTokenType.RBRACE)) break; + if (PsiUtil.isJavaToken(sibling, JavaTokenType.RBRACE)) break; - if (BasicJavaAstTreeUtil.isWhiteSpace(sibling)) { - String[] strings = LineTokenizer.tokenize(sibling.getText().toCharArray(), false); + if (sibling instanceof PsiWhiteSpace whiteSpace) { + String[] strings = LineTokenizer.tokenize(whiteSpace.getText().toCharArray(), false); if (strings.length > 2) { break; } } - if (BasicJavaAstTreeUtil.is(sibling, BASIC_SWITCH_LABEL_STATEMENT)) break; + if (sibling instanceof PsiSwitchLabelStatement) break; endElement = sibling; } - while (BasicJavaAstTreeUtil.isWhiteSpace(endElement)) { - endElement = endElement.getTreePrev(); + while (endElement instanceof PsiWhiteSpace) { + endElement = endElement.getPrevSibling(); + } + if (endElement == null) { + return result; } - result.addAll(expandToWholeLine(editorText, new TextRange(startElement.getTextRange().getStartOffset(), endElement.getTextRange().getEndOffset()))); diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/TypeCastSelectioner.java b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/TypeCastSelectioner.java index 9e1f50337a9f..cf43aa8e8f84 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/TypeCastSelectioner.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/editorActions/wordSelection/TypeCastSelectioner.java @@ -1,36 +1,37 @@ // Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.codeInsight.editorActions.wordSelection; -import com.intellij.lang.ASTNode; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.util.TextRange; import com.intellij.psi.JavaTokenType; import com.intellij.psi.PsiElement; -import com.intellij.psi.impl.source.BasicJavaAstTreeUtil; +import com.intellij.psi.PsiJavaToken; +import com.intellij.psi.PsiTypeCastExpression; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.List; -import static com.intellij.psi.impl.source.BasicJavaElementType.BASIC_TYPE_CAST_EXPRESSION; - -public final class TypeCastSelectioner extends AbstractBasicBackBasicSelectioner { +public final class TypeCastSelectioner extends BasicSelectioner { @Override public boolean canSelect(@NotNull PsiElement e) { - return BasicJavaAstTreeUtil.is(BasicJavaAstTreeUtil.toNode(e), BASIC_TYPE_CAST_EXPRESSION); + return e instanceof PsiTypeCastExpression; } @Override public List select(@NotNull PsiElement e, @NotNull CharSequence editorText, int cursorOffset, @NotNull Editor editor) { List result = new ArrayList<>(expandToWholeLine(editorText, e.getTextRange(), false)); - List children = BasicJavaAstTreeUtil.getChildren(BasicJavaAstTreeUtil.toNode(e)); - ASTNode lParen = null; - ASTNode rParen = null; - for (ASTNode child : children) { - if (BasicJavaAstTreeUtil.is(child, JavaTokenType.LPARENTH)) lParen = child; - if (BasicJavaAstTreeUtil.is(child, JavaTokenType.RPARENTH)) rParen = child; + PsiTypeCastExpression expression = (PsiTypeCastExpression)e; + PsiElement[] children = expression.getChildren(); + PsiElement lParen = null; + PsiElement rParen = null; + for (PsiElement child : children) { + if (child instanceof PsiJavaToken token) { + if (token.getTokenType() == JavaTokenType.LPARENTH) lParen = token; + if (token.getTokenType() == JavaTokenType.RPARENTH) rParen = token; + } } if (lParen != null && rParen != null) { diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/highlighting/JavaBraceMatcher.java b/java/java-frontback-impl/src/com/intellij/codeInsight/highlighting/JavaBraceMatcher.java index 338c70af8069..6cf8c9619904 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/highlighting/JavaBraceMatcher.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/highlighting/JavaBraceMatcher.java @@ -2,22 +2,16 @@ package com.intellij.codeInsight.highlighting; import com.intellij.codeInsight.hint.DeclarationRangeUtil; -import com.intellij.lang.ASTNode; import com.intellij.lang.BracePair; import com.intellij.lang.PairedBraceMatcher; import com.intellij.openapi.util.TextRange; -import com.intellij.psi.JavaDocTokenType; -import com.intellij.psi.JavaTokenType; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiFile; -import com.intellij.psi.impl.source.BasicJavaAstTreeUtil; +import com.intellij.psi.*; +import com.intellij.psi.impl.source.tree.ElementType; import com.intellij.psi.tree.IElementType; import com.intellij.psi.tree.java.IJavaElementType; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import static com.intellij.psi.impl.source.BasicElementTypes.*; - public class JavaBraceMatcher implements PairedBraceMatcher { private final BracePair[] pairs = new BracePair[] { new BracePair(JavaTokenType.LPARENTH, JavaTokenType.RPARENTH, false), @@ -28,8 +22,7 @@ public class JavaBraceMatcher implements PairedBraceMatcher { new BracePair(JavaDocTokenType.DOC_LBRACKET, JavaDocTokenType.DOC_RBRACKET, false), new BracePair(JavaDocTokenType.DOC_LPAREN, JavaDocTokenType.DOC_RPAREN, false) }; - public JavaBraceMatcher() { - } + @Override public BracePair @NotNull [] getPairs() { @@ -37,13 +30,13 @@ public class JavaBraceMatcher implements PairedBraceMatcher { } @Override - public boolean isPairedBracesAllowedBeforeType(final @NotNull IElementType lbraceType, final @Nullable IElementType contextType) { + public boolean isPairedBracesAllowedBeforeType(@NotNull final IElementType lbraceType, @Nullable final IElementType contextType) { if (contextType instanceof IJavaElementType) return isPairedBracesAllowedBeforeTypeInJava(contextType); return true; } private static boolean isPairedBracesAllowedBeforeTypeInJava(final IElementType tokenType) { - return BASIC_JAVA_COMMENT_OR_WHITESPACE_BIT_SET.contains(tokenType) + return ElementType.JAVA_COMMENT_OR_WHITESPACE_BIT_SET.contains(tokenType) || tokenType == JavaTokenType.SEMICOLON || tokenType == JavaTokenType.COMMA || tokenType == JavaTokenType.RPARENTH @@ -58,31 +51,21 @@ public class JavaBraceMatcher implements PairedBraceMatcher { PsiElement element = file.findElementAt(openingBraceOffset); if (element == null || element instanceof PsiFile) return openingBraceOffset; PsiElement parent = element.getParent(); - if(parent==null) return openingBraceOffset; - ASTNode parentNode = parent.getNode(); - if (BasicJavaAstTreeUtil.is(parentNode, BASIC_CODE_BLOCK)) { - parentNode = parentNode.getTreeParent(); - if (BasicJavaAstTreeUtil.is(parentNode, BASIC_METHOD) || - BasicJavaAstTreeUtil.is(parentNode, BASIC_CLASS_INITIALIZER)) { - TextRange range = DeclarationRangeUtil.getPossibleDeclarationAtRange(parentNode.getPsi()); - if (range == null) { - return parentNode.getTextRange().getStartOffset(); - } + if (parent instanceof PsiCodeBlock) { + parent = parent.getParent(); + if (parent instanceof PsiMethod || parent instanceof PsiClassInitializer) { + TextRange range = DeclarationRangeUtil.getDeclarationRange(parent); return range.getStartOffset(); } - else if (BasicJavaAstTreeUtil.is(parentNode, BASIC_JAVA_STATEMENT_BIT_SET)) { - if (BasicJavaAstTreeUtil.is(parentNode, BASIC_BLOCK_STATEMENT) && - BasicJavaAstTreeUtil.is(parentNode.getTreeParent(), BASIC_JAVA_STATEMENT_BIT_SET)) { - parentNode = parentNode.getTreeParent(); + else if (parent instanceof PsiStatement) { + if (parent instanceof PsiBlockStatement && parent.getParent() instanceof PsiStatement) { + parent = parent.getParent(); } - return parentNode.getTextRange().getStartOffset(); + return parent.getTextRange().getStartOffset(); } } - else if (BasicJavaAstTreeUtil.is(parentNode, BASIC_CLASS_KEYWORD_BIT_SET)) { - TextRange range = DeclarationRangeUtil.getPossibleDeclarationAtRange(parent); - if (range == null) { - return parentNode.getTextRange().getStartOffset(); - } + else if (parent instanceof PsiClass) { + TextRange range = DeclarationRangeUtil.getDeclarationRange(parent); return range.getStartOffset(); } return openingBraceOffset; diff --git a/java/java-frontback-impl/src/com/intellij/codeInsight/highlighting/JavaPairedBraceMatcher.java b/java/java-frontback-impl/src/com/intellij/codeInsight/highlighting/JavaPairedBraceMatcher.java index 1882aa49d9e5..b3fe7057f010 100644 --- a/java/java-frontback-impl/src/com/intellij/codeInsight/highlighting/JavaPairedBraceMatcher.java +++ b/java/java-frontback-impl/src/com/intellij/codeInsight/highlighting/JavaPairedBraceMatcher.java @@ -1,24 +1,22 @@ +// 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.codeInsight.highlighting; -import com.intellij.BaseJavaJspElementType; import com.intellij.ide.highlighter.JavaFileType; import com.intellij.lang.java.JavaLanguage; import com.intellij.psi.JavaTokenType; -import com.intellij.psi.impl.source.BasicElementTypes; +import com.intellij.psi.impl.source.tree.StdTokenSets; import com.intellij.psi.tree.IElementType; -import com.intellij.psi.tree.ParentAwareTokenSet; +import com.intellij.psi.tree.TokenSet; import org.jetbrains.annotations.NotNull; -public final class JavaPairedBraceMatcher extends PairedBraceAndAnglesMatcher { - +public class JavaPairedBraceMatcher extends PairedBraceAndAnglesMatcher { private static class Holder { - private static final ParentAwareTokenSet TYPE_TOKENS = - ParentAwareTokenSet.orSet(BaseJavaJspElementType.WHITE_SPACE_BIT_SET, - BasicElementTypes.BASIC_JAVA_COMMENT_BIT_SET, - ParentAwareTokenSet.create(JavaTokenType.IDENTIFIER, JavaTokenType.COMMA, - JavaTokenType.AT,//anno - JavaTokenType.RBRACKET, JavaTokenType.LBRACKET, //arrays - JavaTokenType.QUEST, JavaTokenType.EXTENDS_KEYWORD, JavaTokenType.SUPER_KEYWORD));//wildcards + private static final TokenSet TYPE_TOKENS = + TokenSet.orSet(StdTokenSets.WHITE_SPACE_OR_COMMENT_BIT_SET, + TokenSet.create(JavaTokenType.IDENTIFIER, JavaTokenType.COMMA, + JavaTokenType.AT,//anno + JavaTokenType.RBRACKET, JavaTokenType.LBRACKET, //arrays + JavaTokenType.QUEST, JavaTokenType.EXTENDS_KEYWORD, JavaTokenType.SUPER_KEYWORD));//wildcards } public JavaPairedBraceMatcher() { diff --git a/java/java-frontback-impl/src/com/intellij/javadoc/JavadocHelper.java b/java/java-frontback-impl/src/com/intellij/javadoc/JavadocHelper.java index 7c0fd09c84d2..6daa579968bc 100644 --- a/java/java-frontback-impl/src/com/intellij/javadoc/JavadocHelper.java +++ b/java/java-frontback-impl/src/com/intellij/javadoc/JavadocHelper.java @@ -28,9 +28,11 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleSettings; import com.intellij.psi.codeStyle.JavaCodeStyleSettings; -import com.intellij.psi.impl.source.BasicJavaAstTreeUtil; +import com.intellij.psi.javadoc.PsiDocTag; +import com.intellij.psi.javadoc.PsiDocTagValue; +import com.intellij.psi.javadoc.PsiDocToken; import com.intellij.psi.tree.IElementType; -import com.intellij.psi.tree.ParentAwareTokenSet; +import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -39,8 +41,6 @@ import java.util.Collection; import java.util.Collections; import java.util.List; -import static com.intellij.psi.impl.source.BasicJavaDocElementType.*; - /** * Utility methods to support some Javadoc-related operations like formatting or navigation */ @@ -48,8 +48,6 @@ public final class JavadocHelper { private static final Pair> EMPTY = new Pair<>(null, Collections.emptyList()); private static final String PARAM_TEXT = "param"; - private static final @NotNull ParentAwareTokenSet TAG_TOKEN_SET = - ParentAwareTokenSet.create(BASIC_DOC_TAG, BASIC_DOC_SNIPPET_TAG, BASIC_DOC_INLINE_TAG); private JavadocHelper() { } @@ -134,15 +132,14 @@ public final class JavadocHelper { return EMPTY; } - ASTNode nodeAtCaret = BasicJavaAstTreeUtil.toNode(elementAtCaret); - ASTNode tag = BasicJavaAstTreeUtil.getParentOfType(nodeAtCaret, TAG_TOKEN_SET); + PsiDocTag tag = PsiTreeUtil.getParentOfType(elementAtCaret, PsiDocTag.class); if (tag == null) { // Due to javadoc PSI specifics. - if (BasicJavaAstTreeUtil.isWhiteSpace(nodeAtCaret)) { - for (ASTNode e = nodeAtCaret.getTreePrev(); e != null && tag == null; e = e.getTreePrev()) { - tag = BasicJavaAstTreeUtil.getParentOfType(e, TAG_TOKEN_SET, false); + if (elementAtCaret instanceof PsiWhiteSpace) { + for (PsiElement e = elementAtCaret.getPrevSibling(); e != null && tag == null; e = e.getPrevSibling()) { + tag = PsiTreeUtil.getParentOfType(e, PsiDocTag.class, false); if (e instanceof PsiWhiteSpace - || (e.getElementType() == JavaDocTokenType.DOC_COMMENT_LEADING_ASTERISKS)) { + || (e instanceof PsiDocToken && ((PsiDocToken)e).getTokenType() == JavaDocTokenType.DOC_COMMENT_LEADING_ASTERISKS)) { continue; } break; @@ -159,19 +156,19 @@ public final class JavadocHelper { } // Parse previous parameters. - for (ASTNode n = tag.getTreePrev(); n != null; n = n.getTreePrev()) { - JavadocParameterInfo info = parse(n, editor); + for (PsiElement e = tag.getPrevSibling(); e != null; e = e.getPrevSibling()) { + JavadocParameterInfo info = parse(e, editor); if (info == null) { break; } - result.add(0, info); + result.addFirst(info); } result.add(anchorInfo); // Parse subsequent parameters. - for (ASTNode n = tag.getTreeNext(); n != null; n = n.getTreeNext()) { - JavadocParameterInfo info = parse(n, editor); + for (PsiElement e = tag.getNextSibling(); e != null; e = e.getNextSibling()) { + JavadocParameterInfo info = parse(e, editor); if (info == null) { break; } @@ -181,27 +178,28 @@ public final class JavadocHelper { return Pair.create(anchorInfo, result); } - private static @Nullable JavadocParameterInfo parse(@NotNull ASTNode astNode, @NotNull Editor editor) { - final ASTNode tag = BasicJavaAstTreeUtil.getParentOfType(astNode, TAG_TOKEN_SET, false); - if (tag == null || !PARAM_TEXT.equals(BasicJavaAstTreeUtil.getTagName(tag))) { + private static @Nullable JavadocParameterInfo parse(@NotNull PsiElement element, @NotNull Editor editor) { + final PsiDocTag tag = PsiTreeUtil.getParentOfType(element, PsiDocTag.class, false); + if (tag == null || !PARAM_TEXT.equals(tag.getName())) { return null; } - final ASTNode paramRef = BasicJavaAstTreeUtil.findChildByType(tag, BASIC_DOC_TAG_VALUE_ELEMENT, - BASIC_DOC_METHOD_OR_FIELD_REF, - BASIC_DOC_PARAMETER_REF, - BASIC_DOC_SNIPPET_TAG_VALUE); + final PsiDocTagValue paramRef = PsiTreeUtil.getChildOfType(tag, PsiDocTagValue.class); if (paramRef == null) { return null; } - for (ASTNode node = paramRef.getTreeNext(); node != null; node = node.getTreeNext()) { + for (PsiElement e = paramRef.getNextSibling(); e != null; e = e.getNextSibling()) { + final ASTNode node = e.getNode(); + if (node == null) { + break; + } final IElementType elementType = node.getElementType(); if (elementType == JavaDocTokenType.DOC_COMMENT_DATA) { return new JavadocParameterInfo( editor.offsetToLogicalPosition(paramRef.getTextRange().getEndOffset()), - editor.offsetToLogicalPosition(node.getTextRange().getStartOffset()), - editor.getDocument().getLineNumber(node.getTextRange().getEndOffset()) + editor.offsetToLogicalPosition(e.getTextRange().getStartOffset()), + editor.getDocument().getLineNumber(e.getTextRange().getEndOffset()) ); } else if (elementType == JavaDocTokenType.DOC_COMMENT_LEADING_ASTERISKS) { diff --git a/java/java-frontback-impl/src/com/intellij/psi/formatter/java/JavaFormatterConditionalExpressionUtil.kt b/java/java-frontback-impl/src/com/intellij/psi/formatter/java/JavaFormatterConditionalExpressionUtil.kt index 34ab61156d93..cd69fe64a51a 100644 --- a/java/java-frontback-impl/src/com/intellij/psi/formatter/java/JavaFormatterConditionalExpressionUtil.kt +++ b/java/java-frontback-impl/src/com/intellij/psi/formatter/java/JavaFormatterConditionalExpressionUtil.kt @@ -2,25 +2,30 @@ package com.intellij.psi.formatter.java import com.intellij.lang.ASTNode -import com.intellij.psi.impl.source.BasicJavaAstTreeUtil -import com.intellij.psi.impl.source.tree.ChildRole +import com.intellij.psi.PsiConditionalExpression +import com.intellij.psi.PsiLocalVariable +import com.intellij.psi.PsiMethod +import com.intellij.psi.impl.source.SourceTreeToPsiMap import com.intellij.psi.impl.source.tree.CompositeElement -import com.intellij.psi.impl.source.tree.JavaElementType -import com.intellij.psi.tree.ParentAwareTokenSet +import com.intellij.psi.util.PsiTreeUtil internal object JavaFormatterConditionalExpressionUtil { - private val STOP_TOKENS = ParentAwareTokenSet.create(JavaElementType.METHOD, JavaElementType.LOCAL_VARIABLE, JavaElementType.METHOD) /** * Checks if the given AST node is inside a conditional expression then or else branch. */ @JvmStatic - fun isInsideConditionalExpression(node : ASTNode) : Boolean { - val child = BasicJavaAstTreeUtil.getAncestorWithParentOfType(node, JavaElementType.CONDITIONAL_EXPRESSION, STOP_TOKENS) + fun isInsideConditionalExpression(node: ASTNode): Boolean { + val psi = SourceTreeToPsiMap.treeElementToPsi(node) + val child = PsiTreeUtil.findFirstParent(psi) { + it.parent is PsiConditionalExpression || + it.parent is PsiMethod || + it.parent is PsiLocalVariable + } if (child == null) return false - val parent = child.treeParent + val parent = child.parent + if (parent !is PsiConditionalExpression) return false if (parent !is CompositeElement) return false - val childRole = parent.getChildRole(child) - return childRole != ChildRole.CONDITION + return parent.condition != child } } \ No newline at end of file diff --git a/java/java-frontback-psi-impl/src/com/intellij/psi/impl/source/BasicJavaAstTreeUtil.java b/java/java-frontback-psi-impl/src/com/intellij/psi/impl/source/BasicJavaAstTreeUtil.java index b35c8c7838ee..3964a66dfdcc 100644 --- a/java/java-frontback-psi-impl/src/com/intellij/psi/impl/source/BasicJavaAstTreeUtil.java +++ b/java/java-frontback-psi-impl/src/com/intellij/psi/impl/source/BasicJavaAstTreeUtil.java @@ -2,34 +2,17 @@ package com.intellij.psi.impl.source; import com.intellij.lang.ASTNode; -import com.intellij.lang.java.JavaLanguage; -import com.intellij.lang.java.parser.JavaBinaryOperations; -import com.intellij.openapi.util.TextRange; -import com.intellij.psi.*; -import com.intellij.psi.impl.source.tree.TreeUtil; import com.intellij.psi.tree.IElementType; import com.intellij.psi.tree.ParentAwareTokenSet; import com.intellij.psi.tree.ParentProviderElementType; import com.intellij.psi.tree.TokenSet; -import com.intellij.psi.tree.java.IJavaDocElementType; -import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; import java.util.Set; -import static com.intellij.psi.JavaTokenType.JAVA_TOKEN_TYPE_SET; -import static com.intellij.psi.JavaTokenType.RPARENTH; -import static com.intellij.psi.impl.source.BasicElementTypes.BASIC_KEYWORD_BIT_SET; -import static com.intellij.psi.impl.source.BasicJavaDocElementType.BASIC_DOC_COMMENT; -import static com.intellij.psi.impl.source.BasicJavaDocElementType.BASIC_DOC_SNIPPET_ATTRIBUTE_VALUE; -import static com.intellij.psi.impl.source.BasicJavaElementType.*; - public final class BasicJavaAstTreeUtil { private BasicJavaAstTreeUtil() { } @@ -98,733 +81,4 @@ public final class BasicJavaAstTreeUtil { } return false; } - - public static boolean is(@Nullable ASTNode element, IElementType... iElementTypes) { - return is(element, ParentAwareTokenSet.create(iElementTypes)); - } - - public static List getChildren(@Nullable ASTNode element) { - ArrayList results = new ArrayList<>(); - if (element == null) { - return results; - } - for (ASTNode child = element.getFirstChildNode(); child != null; child = child.getTreeNext()) { - results.add(child); - } - return results; - } - - public static @Nullable ASTNode getReferenceNameElement(@Nullable ASTNode element) { - if (element == null) { - return null; - } - IElementType type = element.getElementType(); - if (is(type, BASIC_IMPORT_STATIC_REFERENCE)) { - return findChildByType(element, JavaTokenType.IDENTIFIER); - } - else if (is(type, BASIC_JAVA_CODE_REFERENCE)) { - return TreeUtil.findChildBackward(element, JavaTokenType.IDENTIFIER); - } - else if (is(type, BASIC_METHOD_REF_EXPRESSION)) { - final ASTNode lastChild = element.getLastChildNode(); - return is(lastChild, JavaTokenType.IDENTIFIER) || is(lastChild, JavaTokenType.NEW_KEYWORD) ? lastChild : null; - } - else if (is(type, BASIC_REFERENCE_EXPRESSION)) { - ASTNode lastChild = element.getLastChildNode(); - return lastChild == null || is(lastChild, - ContainerUtil.newHashSet(JavaTokenType.IDENTIFIER, JavaTokenType.THIS_KEYWORD, - JavaTokenType.SUPER_KEYWORD)) ? - lastChild : findChildByType(element, JavaTokenType.IDENTIFIER); - } - return null; - } - - - public static @Nullable ASTNode findChildByType(@Nullable ASTNode astNode, IElementType... targets) { - return findChildByType(astNode, ParentAwareTokenSet.create(targets)); - } - - public static @Nullable ASTNode findChildByType(@Nullable ASTNode astNode, Collection targets) { - return findChildByType(astNode, ParentAwareTokenSet.create(targets)); - } - - public static @Nullable ASTNode findChildByType(@Nullable ASTNode astNode, ParentAwareTokenSet targets) { - if (astNode == null) { - return null; - } - for (ASTNode child = astNode.getFirstChildNode(); child != null; child = child.getTreeNext()) { - IElementType elementType = child.getElementType(); - if (is(elementType, targets)) return child; - } - return null; - } - - public static @Nullable ASTNode getElseElement(@NotNull ASTNode element) { - if (!is(element, BASIC_IF_STATEMENT)) { - return null; - } - return findChildByType(element, JavaTokenType.ELSE_KEYWORD); - } - - public static @Nullable ASTNode getThenBranch(@NotNull ASTNode element) { - if (!is(element, BASIC_IF_STATEMENT)) { - return null; - } - for (ASTNode child : getChildren(element)) { - if (is(child, STATEMENT_SET)) { - return child; - } - } - return null; - } - - public static ASTNode getElseBranch(@Nullable ASTNode element) { - if (!is(element, BASIC_IF_STATEMENT)) { - return null; - } - ASTNode elseKeyword = getElseElement(element); - if (elseKeyword == null) return null; - for (ASTNode child = elseKeyword.getTreeNext(); child != null; child = child.getTreeNext()) { - if (is(child, STATEMENT_SET)) return child; - } - return null; - } - - public static @Nullable ASTNode getLParenth(@Nullable ASTNode element) { - return findChildByType(element, JavaTokenType.LPARENTH); - } - - public static @Nullable ASTNode getRParenth(@Nullable ASTNode element) { - return findChildByType(element, RPARENTH); - } - - public static @Nullable ASTNode getFinallyBlock(@Nullable ASTNode element) { - if (!is(element, BASIC_TRY_STATEMENT)) { - return null; - } - ASTNode finallyKeyword = findChildByType(element, JavaTokenType.FINALLY_KEYWORD); - if (finallyKeyword == null) return null; - for (ASTNode child = finallyKeyword.getTreeNext(); child != null; child = child.getTreeNext()) { - if (is(child, BASIC_CODE_BLOCK)) { - return child; - } - } - return null; - } - - public static @Nullable ASTNode getNameIdentifier(@Nullable ASTNode element) { - return findChildByType(element, JavaTokenType.IDENTIFIER); - } - - public static @Nullable ASTNode getInitializer(@Nullable ASTNode element) { - return findChildByType(element, EXPRESSION_SET); - } - - - public static @Nullable ASTNode getDocComment(@Nullable ASTNode element) { - return findChildByType(element, BASIC_DOC_COMMENT); - } - - public static @Nullable ASTNode getTypeElement(@Nullable ASTNode element) { - return findChildByType(element, BASIC_TYPE); - } - - public static @Nullable ASTNode getModifierList(@Nullable ASTNode element) { - return findChildByType(element, BASIC_MODIFIER_LIST); - } - - public static @Nullable ASTNode getLBrace(@Nullable ASTNode element) { - return findChildByType(element, JavaTokenType.LBRACE); - } - - public static @Nullable ASTNode getRBrace(@Nullable ASTNode element) { - return findChildByType(element, JavaTokenType.RBRACE); - } - - public static boolean isJavaToken(@Nullable ASTNode element) { - if (element == null) { - return false; - } - return toPsi(element) instanceof PsiJavaToken || - is(element, JavaTokenType.IDENTIFIER) || - isKeyword(element) || - JAVA_TOKEN_TYPE_SET.contains(element.getElementType()); - } - - public static boolean isKeyword(@Nullable ASTNode element) { - return is(element, BASIC_KEYWORD_BIT_SET); - } - - public static boolean isWhiteSpace(@Nullable ASTNode element) { - return is(element, TokenType.WHITE_SPACE); - } - - public static @Nullable ASTNode skipSiblingsBackward(@Nullable ASTNode element, - IElementType... elementClasses) { - if (element != null) { - for (ASTNode e = element.getTreePrev(); e != null; e = e.getTreePrev()) { - if (!is(e, elementClasses)) { - return e; - } - } - } - return null; - } - - public static @Nullable ASTNode skipSiblingsForward(@Nullable ASTNode element, - IElementType... elementClasses) { - if (element != null) { - for (ASTNode e = element.getTreeNext(); e != null; e = e.getTreeNext()) { - if (!is(e, elementClasses)) { - return e; - } - } - } - return null; - } - - public static @Nullable PsiElement toPsi(@Nullable ASTNode astNode) { - return SourceTreeToPsiMap.treeElementToPsi(astNode); - } - - public static @Nullable ASTNode toNode(@Nullable PsiElement psiElement) { - if (psiElement == null) { - return null; - } - return psiElement.getNode(); - } - - public static @Nullable ASTNode getParentOfType(@Nullable ASTNode e, @NotNull ParentAwareTokenSet set) { - if (e == null) { - return null; - } - return findParent(e, set); - } - - private static @Nullable ASTNode findAncestorWithParentOfType(@NotNull ASTNode element, @NotNull IElementType type, @Nullable ParentAwareTokenSet stopAt) { - for (ASTNode currentElement = element, parent = element.getTreeParent(); parent != null; currentElement = parent, parent = parent.getTreeParent()) { - IElementType parentType = parent.getElementType(); - if (is(parentType, type)) return currentElement; - else if (stopAt != null && is(parentType, stopAt)) return null; - } - return null; - } - - private static @Nullable ASTNode findParent(@NotNull ASTNode element, @NotNull IElementType type, @Nullable ParentAwareTokenSet stopAt) { - for (ASTNode parent = element.getTreeParent(); parent != null; parent = parent.getTreeParent()) { - IElementType parentType = parent.getElementType(); - if (is(parentType, type)) return parent; - else if (stopAt != null && is(parentType, stopAt)) return null; - } - return null; - } - - private static @Nullable ASTNode findParent(@NotNull ASTNode element, @NotNull ParentAwareTokenSet type) { - for (ASTNode parent = element.getTreeParent(); parent != null; parent = parent.getTreeParent()) { - if (is(parent.getElementType(), type)) return parent; - } - return null; - } - - - public static @Nullable ASTNode getParentOfType(@Nullable ASTNode e, @NotNull IElementType elementType) { - return getParentOfType(e, elementType, null); - } - - /** - * Finds the first ancestor which parent element type is equals to {@code elementType} - */ - public static @Nullable ASTNode getAncestorWithParentOfType(@Nullable ASTNode e, @NotNull IElementType elementType, @Nullable ParentAwareTokenSet stopAt) { - if (e == null) { - return null; - } - return findAncestorWithParentOfType(e, elementType, stopAt); - } - - public static @Nullable ASTNode getParentOfType(@Nullable ASTNode e, @NotNull IElementType elementType, @Nullable ParentAwareTokenSet stopAt) { - if (e == null) { - return null; - } - return findParent(e, elementType, stopAt); - } - - public static @Nullable ASTNode getMethodExpression(@Nullable ASTNode element) { - if (!is(element, BASIC_METHOD_CALL_EXPRESSION)) { - return null; - } - return element.getFirstChildNode(); - } - - public static @Nullable ASTNode getExpressionList(@Nullable ASTNode element) { - return findChildByType(element, BASIC_EXPRESSION_LIST); - } - - public static @Nullable ASTNode getTypeParameterList(@Nullable ASTNode element) { - return findChildByType(element, BASIC_TYPE_PARAMETER_LIST); - } - - public static boolean isComment(@Nullable ASTNode element) { - return is(element, BasicElementTypes.BASIC_JAVA_COMMENT_BIT_SET); - } - - public static boolean isDocToken(@Nullable ASTNode element) { - return - element != null && - element.getElementType().getClass().equals(IJavaDocElementType.class) && - !is(element, BASIC_DOC_SNIPPET_ATTRIBUTE_VALUE); - } - - public static @Nullable String getTagName(@Nullable ASTNode element) { - if (element == null) { - return null; - } - ASTNode docTagName = findChildByType(element, JavaDocTokenType.DOC_TAG_NAME); - if (docTagName == null) { - return null; - } - String text = docTagName.getText(); - if (text.isEmpty()) { - return null; - } - return text.substring(1); - } - - public static @Nullable ASTNode getROperand(@Nullable ASTNode element) { - if (element == null) { - return null; - } - if (!is(element, BASIC_BINARY_EXPRESSION)) { - return null; - } - return findChildByType(element, EXPRESSION_SET); - } - - public static @Nullable ASTNode getBlock(@Nullable ASTNode statement) { - if (statement == null) return null; - return findChildByType(statement, STATEMENT_SET); - } - - public static @Nullable ASTNode getAnonymousClass(@Nullable ASTNode expression) { - if (expression == null) return null; - return findChildByType(expression, BASIC_ANONYMOUS_CLASS); - } - - - @Contract("null, _, _, _ -> null") - public static @Nullable PsiElement getParentOfType(@Nullable PsiElement element, - @NotNull IElementType target, - boolean strict, - @Nullable ParentAwareTokenSet stopAt) { - if (element == null) return null; - if (strict) { - if (element instanceof PsiFile) return null; - element = element.getParent(); - } - - while (element != null && !is(element.getNode(), target)) { - if (stopAt != null && is(element.getNode(), stopAt)) return null; - if (element instanceof PsiFile) return null; - element = element.getParent(); - } - - return element; - } - - public static @Nullable ASTNode findElementInRange(@NotNull PsiFile file, int startOffset, int endOffset, @NotNull IElementType elementType) { - PsiElement element1 = file.getViewProvider().findElementAt(startOffset, JavaLanguage.INSTANCE); - PsiElement element2 = file.getViewProvider().findElementAt(endOffset - 1, JavaLanguage.INSTANCE); - if (element1 instanceof PsiWhiteSpace) { - startOffset = element1.getTextRange().getEndOffset(); - element1 = file.getViewProvider().findElementAt(startOffset, JavaLanguage.INSTANCE); - } - if (element2 instanceof PsiWhiteSpace) { - endOffset = element2.getTextRange().getStartOffset(); - element2 = file.getViewProvider().findElementAt(endOffset - 1, JavaLanguage.INSTANCE); - } - if (element2 == null || element1 == null) return null; - final PsiElement commonParent = PsiTreeUtil.findCommonParent(element1, element2); - if (commonParent == null) { - return null; - } - ASTNode node = commonParent.getNode(); - final ASTNode element = is(node, elementType) ? node : getParentOfType(node, elementType); - if (element == null || element.getTextRange().getStartOffset() != startOffset || element.getTextRange().getEndOffset() != endOffset) { - return null; - } - return element; - } - - public static @Nullable ASTNode getForInitialization(@Nullable ASTNode forStatement) { - - if (!is(forStatement, BASIC_FOR_STATEMENT)) { - return null; - } - ASTNode initialization = findChildByType(forStatement, STATEMENT_SET); - if (initialization == null) { - return null; - } - // should be inside parens - ASTNode paren = getLParenth(forStatement); - if (paren == null) { - return null; - } - for (ASTNode child = paren; child != null; child = child.getTreeNext()) { - if (child == initialization) return initialization; - if (is(child, RPARENTH)) return null; - } - return null; - } - - @Contract(pure = true) - public static @Nullable ASTNode findElementOfClassAtOffset(@NotNull PsiFile file, - int offset, - @NotNull IElementType elementType, - boolean strictStart) { - PsiElement result = null; - for (PsiElement root : file.getViewProvider().getAllFiles()) { - PsiElement elementAt = root.findElementAt(offset); - if (elementAt != null) { - PsiElement parent = getParentOfType(elementAt, elementType, strictStart, null); - if (parent != null) { - TextRange range = parent.getTextRange(); - if (!strictStart || range.getStartOffset() == offset) { - if (result == null || result.getTextRange().getEndOffset() > range.getEndOffset()) { - result = parent; - } - } - } - } - } - return result == null ? null : result.getNode(); - } - - public static @Nullable ASTNode getParentOfType(@Nullable ASTNode e, @NotNull ParentAwareTokenSet types, boolean strict) { - if (!strict && is(e, types)) { - return e; - } - return getParentOfType(e, types); - } - - public static @Nullable PsiElement getParentOfType(@Nullable PsiElement e, @NotNull Set types, boolean strict) { - if (!strict && e != null && is(e.getNode(), types)) { - return e; - } - if (e == null) { - return null; - } - return toPsi(getParentOfType(e.getNode(), ParentAwareTokenSet.create(types))); - } - - public static @Nullable ASTNode getCatchBlock(@Nullable ASTNode element) { - if (!is(element, BASIC_CATCH_SECTION)) { - return null; - } - return findChildByType(element, BASIC_CODE_BLOCK); - } - - public static @Nullable ASTNode getParameter(@Nullable ASTNode element) { - return findChildByType(element, BASIC_PARAMETER); - } - - public static @Nullable ASTNode getWhileKeyword(@Nullable ASTNode element) { - if (element == null) { - return null; - } - return findChildByType(element, JavaTokenType.WHILE_KEYWORD); - } - - public static @Nullable ASTNode getWhileCondition(@Nullable ASTNode element) { - if (!is(element, BASIC_DO_WHILE_STATEMENT) && - !is(element, BASIC_WHILE_STATEMENT)) { - return null; - } - return findChildByType(element, EXPRESSION_SET); - } - - public static @Nullable ASTNode getDoWhileBody(@Nullable ASTNode element) { - if (!is(element, BASIC_DO_WHILE_STATEMENT)) { - return null; - } - return findChildByType(element, STATEMENT_SET); - } - - public static @Nullable ASTNode getForUpdate(@Nullable ASTNode statement) { - if (!is(statement, BASIC_FOR_STATEMENT)) { - return null; - } - ASTNode semicolon = findChildByType(statement, JavaTokenType.SEMICOLON); - if (semicolon == null) { - return null; - } - for (ASTNode child = semicolon; child != null; child = child.getTreeNext()) { - if (is(child, STATEMENT_SET)) { - return child; - } - if (is(child, RPARENTH)) break; - } - return null; - } - - public static @Nullable ASTNode getForCondition(@Nullable ASTNode element) { - if (!is(element, BASIC_FOR_STATEMENT)) { - return null; - } - return findChildByType(element, EXPRESSION_SET); - } - - public static @Nullable ASTNode getIfCondition(@Nullable ASTNode statement) { - if (!is(statement, BASIC_IF_STATEMENT)) { - return null; - } - return findChildByType(statement, EXPRESSION_SET); - } - - public static boolean hasModifierProperty(@Nullable ASTNode element, - @NotNull IElementType property) { - if (element == null) { - return false; - } - ASTNode modifierList = findChildByType(element, BASIC_MODIFIER_LIST); - if (modifierList == null) { - return false; - } - ASTNode firstChild = modifierList.getFirstChildNode(); - if (firstChild == null) { - return false; - } - for (ASTNode child = firstChild; child != null; child = child.getTreeNext()) { - if (is(child, property)) { - return true; - } - } - return false; - } - - public static boolean isInterfaceEnumClassOrRecord(@Nullable ASTNode element, - @NotNull IElementType elementType) { - if (!is(element, CLASS_SET)) { - return false; - } - if (element == null) { - return false; - } - ASTNode firstChild = element.getFirstChildNode(); - if (firstChild == null) { - return false; - } - for (ASTNode child = firstChild; child != null; child = child.getTreeNext()) { - if (is(child, elementType)) return true; - } - return false; - } - - - public static ASTNode @Nullable [] getParameterListParameters(@Nullable ASTNode element) { - if (element == null) { - return null; - } - return getChildren(element).stream().filter(ch -> is(ch, BASIC_PARAMETER)).toArray(ASTNode[]::new); - } - - public static ASTNode @Nullable [] getAnnotationParameterListAttributes(@Nullable ASTNode element) { - if (element == null) { - return null; - } - return getChildren(element).stream().filter(ch -> is(ch, BASIC_NAME_VALUE_PAIR)).toArray(ASTNode[]::new); - } - - public static @Nullable ASTNode getFirstBodyElement(@Nullable ASTNode block) { - if (block == null) { - return null; - } - final ASTNode lBrace = getLBrace(block); - if (lBrace == null) return null; - final ASTNode nextSibling = lBrace.getTreeNext(); - return nextSibling == getRBrace(block) ? null : nextSibling; - } - - public static @Nullable ASTNode getCodeBlock(@Nullable ASTNode element) { - if (element == null) return null; - return findChildByType(element, BASIC_CODE_BLOCK); - } - - public static @Nullable ASTNode getForBody(@Nullable ASTNode element) { - if (element == null) { - return null; - } - ASTNode rparenth = getRParenth(element); - if (rparenth == null) { - return null; - } - for (ASTNode child = rparenth; child != null; child = child.getTreeNext()) { - if (is(child, STATEMENT_SET)) { - return child; - } - } - return null; - } - - - public static ASTNode[] getCatchBlocks(@Nullable ASTNode element) { - ASTNode tryBlock = getCodeBlock(element); - if (tryBlock != null) { - final List catchSections = ContainerUtil.filter(getChildren(element), ch -> is(ch, BASIC_CATCH_SECTION)); - return catchSections.stream() - .map(t -> getCatchBlock(t)) - .filter(t -> t != null) - .toArray(ASTNode[]::new); - } - return ASTNode.EMPTY_ARRAY; - } - - public static @Nullable ASTNode getConditionalExpressionThenExpression(@Nullable ASTNode element) { - if (element == null) { - return null; - } - ASTNode quest = findChildByType(element, JavaTokenType.QUEST); - if (quest == null) { - return null; - } - ASTNode child = quest.getTreeNext(); - while (true) { - if (child == null) return null; - if (EXPRESSION_SET.contains(child.getElementType())) break; - child = child.getTreeNext(); - } - return child; - } - - public static @Nullable IElementType getAssignmentOperationTokenType(@Nullable ASTNode expr) { - if (expr == null) { - return null; - } - ASTNode ASTNode = findChildByType(expr, JavaBinaryOperations.ASSIGNMENT_OPS.getTypes()); - if (ASTNode == null) { - return null; - } - return ASTNode.getElementType(); - } - - public static @Nullable ASTNode getPatternVariable(@Nullable ASTNode ASTNode) { - if (ASTNode == null) { - return null; - } - return findChildByType(ASTNode, BASIC_DECONSTRUCTION_PATTERN_VARIABLE, BASIC_PATTERN_VARIABLE); - } - - public static @Nullable ASTNode getExpression(@Nullable ASTNode ASTNode) { - if (ASTNode == null) { - return null; - } - return findChildByType(ASTNode, EXPRESSION_SET); - } - - public static @Nullable ASTNode getRecordComponentContainingClass(@Nullable ASTNode element) { - if (element == null) { - return null; - } - ASTNode parent = element.getTreeParent(); - if (parent == null) { - return null; - } - ASTNode grandParent = parent.getTreeParent(); - if (is(grandParent, CLASS_SET)) { - return grandParent; - } - return null; - } - - public static @Nullable ASTNode getRecordHeader(@Nullable ASTNode element) { - if (element == null) { - return null; - } - return findChildByType(element, BASIC_RECORD_HEADER); - } - - public static @Nullable ASTNode getRuleBody(@Nullable ASTNode element) { - if (element == null) { - return null; - } - - return findChildByType(element, ParentAwareTokenSet.orSet( - ParentAwareTokenSet.create(BASIC_BLOCK_STATEMENT, BASIC_THROW_STATEMENT), EXPRESSION_SET)); - } - - public static @Nullable ASTNode getCaseLabelElementList(@Nullable ASTNode element) { - if (element == null) { - return null; - } - return findChildByType(element, BASIC_CASE_LABEL_ELEMENT_LIST); - } - - public static @Nullable ASTNode getReturnValue(@Nullable ASTNode element) { - if (element == null) { - return null; - } - return findChildByType(element, EXPRESSION_SET); - } - - public static @Nullable ASTNode getForEachIteratedValue(@Nullable ASTNode statement) { - if (!is(statement, BASIC_FOREACH_STATEMENT)) { - return null; - } - return findChildByType(statement, EXPRESSION_SET); - } - - public static @Nullable ASTNode getForEachIterationParameter(@Nullable ASTNode statement) { - if (statement == null) { - return null; - } - if (!is(statement, BASIC_FOREACH_STATEMENT)) { - return null; - } - return findChildByType(statement, BASIC_PARAMETER); - } - - public static @Nullable ASTNode getForeachBody(@Nullable ASTNode statement) { - if (statement == null) { - return null; - } - if (!is(statement, BASIC_FOREACH_STATEMENT)) { - return null; - } - return findChildByType(statement, STATEMENT_SET); - } - - public static @Nullable ASTNode getWhileBody(@Nullable ASTNode statement) { - if (statement == null) { - return null; - } - if (!is(statement, BASIC_WHILE_STATEMENT)) { - return null; - } - return findChildByType(statement, STATEMENT_SET); - } - - public static boolean hasErrorElements(@Nullable ASTNode node) { - return !SyntaxTraverser.astTraverser(node).traverse() - .filter(t -> is(t, TokenType.ERROR_ELEMENT)).isEmpty(); - } - - public static int getTextOffset(@NotNull ASTNode node) { - if (is(node, BASIC_LOCAL_VARIABLE, BASIC_PATTERN_VARIABLE, BASIC_RECORD_COMPONENT, - BASIC_RECEIVER_PARAMETER, BASIC_MODULE, - BASIC_IMPORT_STATIC_REFERENCE, BASIC_JAVA_CODE_REFERENCE)) { - ASTNode identifier = findChildByType(node, JavaTokenType.IDENTIFIER); - if (identifier != null) { - return identifier.getStartOffset(); - } - } - if (is(node, BASIC_REFERENCE_EXPRESSION)) { - ASTNode identifier = findChildByType(node, JavaTokenType.IDENTIFIER, JavaTokenType.THIS_KEYWORD, JavaTokenType.SUPER_KEYWORD); - if (identifier != null) { - return identifier.getStartOffset(); - } - } - ASTNode doc = findChildByType(node, JavaDocTokenType.DOC_TAG_VALUE_TOKEN); - if (doc != null) { - return doc.getStartOffset(); - } - return node.getStartOffset(); - } } \ No newline at end of file diff --git a/java/java-frontback-psi-impl/src/com/intellij/psi/impl/source/WhiteSpaceAndCommentSetHolder.java b/java/java-frontback-psi-impl/src/com/intellij/psi/impl/source/WhiteSpaceAndCommentSetHolder.java index f8e232a901eb..38f4f29f523a 100644 --- a/java/java-frontback-psi-impl/src/com/intellij/psi/impl/source/WhiteSpaceAndCommentSetHolder.java +++ b/java/java-frontback-psi-impl/src/com/intellij/psi/impl/source/WhiteSpaceAndCommentSetHolder.java @@ -21,7 +21,7 @@ import static com.intellij.psi.tree.ParentAwareTokenSet.orSet; public class WhiteSpaceAndCommentSetHolder { public static final WhiteSpaceAndCommentSetHolder INSTANCE = new WhiteSpaceAndCommentSetHolder(); private static final ParentAwareTokenSet PRECEDING_COMMENT_SET = - orSet(create(BasicJavaElementType.BASIC_MODULE, BasicJavaElementType.BASIC_IMPLICIT_CLASS), + orSet(create(BasicJavaElementType.BASIC_MODULE, BasicJavaElementType.BASIC_IMPLICIT_CLASS), BasicElementTypes.BASIC_FULL_MEMBER_BIT_SET); private static final ParentAwareTokenSet TRAILING_COMMENT_SET = @@ -31,10 +31,14 @@ public class WhiteSpaceAndCommentSetHolder { private WhiteSpaceAndCommentSetHolder() { } - private final WhitespacesAndCommentsBinder PRECEDING_COMMENT_BINDER_WITH_MARKDOWN = new PrecedingWhitespacesAndCommentsBinder(false, true); - private final WhitespacesAndCommentsBinder SPECIAL_PRECEDING_COMMENT_BINDER_WITH_MARKDOWN = new PrecedingWhitespacesAndCommentsBinder(true, true); - private final WhitespacesAndCommentsBinder PRECEDING_COMMENT_BINDER_WITHOUT_MARKDOWN = new PrecedingWhitespacesAndCommentsBinder(false, false); - private final WhitespacesAndCommentsBinder SPECIAL_PRECEDING_COMMENT_BINDER_WITHOUT_MARKDOWN = new PrecedingWhitespacesAndCommentsBinder(true, false); + private final WhitespacesAndCommentsBinder PRECEDING_COMMENT_BINDER_WITH_MARKDOWN = + new PrecedingWhitespacesAndCommentsBinder(false, true); + private final WhitespacesAndCommentsBinder SPECIAL_PRECEDING_COMMENT_BINDER_WITH_MARKDOWN = + new PrecedingWhitespacesAndCommentsBinder(true, true); + private final WhitespacesAndCommentsBinder PRECEDING_COMMENT_BINDER_WITHOUT_MARKDOWN = + new PrecedingWhitespacesAndCommentsBinder(false, false); + private final WhitespacesAndCommentsBinder SPECIAL_PRECEDING_COMMENT_BINDER_WITHOUT_MARKDOWN = + new PrecedingWhitespacesAndCommentsBinder(true, false); private final WhitespacesAndCommentsBinder TRAILING_COMMENT_BINDER = new TrailingWhitespacesAndCommentsBinder(); public WhitespacesAndCommentsBinder getPrecedingCommentBinder(@NotNull LanguageLevel myLanguageLevel) { diff --git a/java/java-frontback-tests/testSrc/com/intellij/codeInsight/AbstractBasicJavaTypingTest.java b/java/java-frontback-tests/testSrc/com/intellij/codeInsight/AbstractBasicJavaTypingTest.java index 8e2bef9985d1..8b217e596481 100644 --- a/java/java-frontback-tests/testSrc/com/intellij/codeInsight/AbstractBasicJavaTypingTest.java +++ b/java/java-frontback-tests/testSrc/com/intellij/codeInsight/AbstractBasicJavaTypingTest.java @@ -19,6 +19,7 @@ import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; +//todo public abstract class AbstractBasicJavaTypingTest extends BasePlatformTestCase { public void testMulticaretSkipSemicolon() { diff --git a/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/XmlTagFixer.java b/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/XmlTagFixer.java index ae253a3d78a3..2b04dcf09c38 100644 --- a/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/XmlTagFixer.java +++ b/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/XmlTagFixer.java @@ -19,7 +19,6 @@ import com.intellij.lang.ASTNode; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; import com.intellij.psi.PsiElement; -import com.intellij.psi.impl.source.BasicJavaAstTreeUtil; import com.intellij.psi.xml.XmlChildRole; import com.intellij.psi.xml.XmlTag; import com.intellij.util.IncorrectOperationException; @@ -31,8 +30,7 @@ import org.jetbrains.annotations.NotNull; */ public class XmlTagFixer implements Fixer { @Override - public void apply(Editor editor, AbstractBasicJavaSmartEnterProcessor processor, @NotNull ASTNode astNode) throws IncorrectOperationException { - PsiElement psiElement = BasicJavaAstTreeUtil.toPsi(astNode); + public void apply(Editor editor, JavaSmartEnterProcessor processor, @NotNull PsiElement psiElement) throws IncorrectOperationException { if (psiElement instanceof XmlTag) { final ASTNode emptyTagEnd = XmlChildRole.EMPTY_TAG_END_FINDER.findChild(psiElement.getNode()); final ASTNode endTagEnd = XmlChildRole.START_TAG_END_FINDER.findChild(psiElement.getNode()); diff --git a/java/java-impl/src/com/intellij/codeInsight/editorActions/wordSelection/BasicSelectioner.java b/java/java-impl/src/com/intellij/codeInsight/editorActions/wordSelection/BasicSelectioner.java deleted file mode 100644 index b06849cf86ab..000000000000 --- a/java/java-impl/src/com/intellij/codeInsight/editorActions/wordSelection/BasicSelectioner.java +++ /dev/null @@ -1,5 +0,0 @@ -// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -package com.intellij.codeInsight.editorActions.wordSelection; - -public class BasicSelectioner extends AbstractBasicBackBasicSelectioner { -} diff --git a/java/java-impl/src/com/intellij/codeInsight/editorActions/wordSelection/VarargsSelectioner.java b/java/java-impl/src/com/intellij/codeInsight/editorActions/wordSelection/VarargsSelectioner.java index 4c48a98a7105..37ff4f0c7d60 100644 --- a/java/java-impl/src/com/intellij/codeInsight/editorActions/wordSelection/VarargsSelectioner.java +++ b/java/java-impl/src/com/intellij/codeInsight/editorActions/wordSelection/VarargsSelectioner.java @@ -11,7 +11,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; -public final class VarargsSelectioner extends AbstractBasicBackBasicSelectioner { +public final class VarargsSelectioner extends BasicSelectioner { @Override public boolean canSelect(@NotNull PsiElement e) { return e instanceof PsiExpressionList;