From 26d8e8e45dcc0752f7bbf471cb7cbc2be6ae4d82 Mon Sep 17 00:00:00 2001 From: Georgii Ustinov Date: Wed, 23 Oct 2024 15:55:38 +0300 Subject: [PATCH] [Java. Intention Actions] Make possible to return null from CreateFieldFromUsageHelper#setupTemplate IDEA-361230 GitOrigin-RevId: f11e7c102aa849141dcb81c802fef87b7249fdcb --- .../daemon/impl/quickfix/CreateFieldFromUsageFix.java | 2 +- .../impl/quickfix/CreateFieldFromUsageHelper.java | 6 +++--- .../impl/quickfix/JavaCreateFieldFromUsageHelper.java | 11 ++++++++--- .../intellij/lang/java/actions/CreateFieldAction.kt | 6 +++--- .../lang/java/actions/CreateFieldActionBase.kt | 2 +- .../groovy/annotator/intentions/CreateFieldFix.java | 3 +++ .../intentions/GroovyCreateFieldFromUsageHelper.java | 11 +++++++++-- .../intentions/elements/CreateFieldAction.kt | 6 +++--- 8 files changed, 31 insertions(+), 16 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFieldFromUsageFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFieldFromUsageFix.java index 6b38f31ab316..000a08134ece 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFieldFromUsageFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFieldFromUsageFix.java @@ -103,7 +103,7 @@ public class CreateFieldFromUsageFix extends CreateVarFromUsageFix { if (newEditor == null) return; Template template = CreateFieldFromUsageHelper.setupTemplate(field, expectedTypes, targetClass, newEditor, context, createConstantField); - + if (template == null) return; startTemplate(newEditor, template, project, new TemplateEditingAdapter() { @Override public void templateFinished(@NotNull Template template, boolean brokenOff) { diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFieldFromUsageHelper.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFieldFromUsageHelper.java index deabe60995da..b3beddf9f2a1 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFieldFromUsageHelper.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFieldFromUsageHelper.java @@ -32,7 +32,7 @@ public abstract class CreateFieldFromUsageHelper { private static final LanguageExtension EP_NAME = new LanguageExtension<>("com.intellij.codeInsight.createFieldFromUsageHelper"); - public static Template setupTemplate(PsiField field, + public static @Nullable Template setupTemplate(@NotNull PsiField field, Object expectedTypes, PsiClass targetClass, Editor editor, @@ -41,7 +41,7 @@ public abstract class CreateFieldFromUsageHelper { return setupTemplate(field, expectedTypes, targetClass, editor, context, createConstantField, true); } - public static Template setupTemplate(PsiField field, + public static @Nullable Template setupTemplate(@NotNull PsiField field, Object expectedTypes, PsiClass targetClass, Editor editor, @@ -62,7 +62,7 @@ public abstract class CreateFieldFromUsageHelper { public abstract PsiField insertFieldImpl(@NotNull PsiClass targetClass, @NotNull PsiField field, @NotNull PsiElement place); - public abstract Template setupTemplateImpl(PsiField field, + public abstract @Nullable Template setupTemplateImpl(@NotNull PsiField field, Object expectedTypes, PsiClass targetClass, Editor editor, diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/JavaCreateFieldFromUsageHelper.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/JavaCreateFieldFromUsageHelper.java index 89f3b4834864..2ba544b3a7ce 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/JavaCreateFieldFromUsageHelper.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/JavaCreateFieldFromUsageHelper.java @@ -15,13 +15,15 @@ import com.intellij.util.CommonJavaRefactoringUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Objects; + /** * @author Max Medvedev */ public final class JavaCreateFieldFromUsageHelper extends CreateFieldFromUsageHelper { @Override - public Template setupTemplateImpl(PsiField field, + public @Nullable Template setupTemplateImpl(@NotNull PsiField field, Object expectedTypes, PsiClass targetClass, Editor editor, @@ -33,23 +35,26 @@ public final class JavaCreateFieldFromUsageHelper extends CreateFieldFromUsageHe PsiElementFactory factory = JavaPsiFacade.getElementFactory(project); field = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(field); + if (field == null) return null; + TemplateBuilderImpl builder = new TemplateBuilderImpl(field); builder.setScrollToTemplate(isScrollToTemplate); if (!(expectedTypes instanceof ExpectedTypeInfo[])) { expectedTypes = ExpectedTypeInfo.EMPTY_ARRAY; } new GuessTypeParameters(project, factory, builder, substitutor).setupTypeElement( - field.getTypeElement(), (ExpectedTypeInfo[])expectedTypes, context, targetClass + Objects.requireNonNull(field.getTypeElement()), (ExpectedTypeInfo[])expectedTypes, context, targetClass ); if (createConstantField && !field.hasInitializer()) { field.setInitializer(factory.createExpressionFromText("0", null)); - builder.replaceElement(field.getInitializer(), new EmptyExpression()); + builder.replaceElement(Objects.requireNonNull(field.getInitializer()), new EmptyExpression()); PsiIdentifier identifier = field.getNameIdentifier(); builder.setEndVariableAfter(identifier); } field = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(field); + if (field == null) return null; editor.getCaretModel().moveToOffset(field.getTextRange().getStartOffset()); Template template = builder.buildInlineTemplate(); diff --git a/java/java-impl/src/com/intellij/lang/java/actions/CreateFieldAction.kt b/java/java-impl/src/com/intellij/lang/java/actions/CreateFieldAction.kt index c900513656a9..7bd47dbc09e2 100644 --- a/java/java-impl/src/com/intellij/lang/java/actions/CreateFieldAction.kt +++ b/java/java-impl/src/com/intellij/lang/java/actions/CreateFieldAction.kt @@ -63,7 +63,7 @@ internal class JavaFieldRenderer( var field = renderField() field = insertField(field, javaUsage?.anchor) if (request.fieldType.isEmpty() || request.fieldType.size > 1 || request.isStartTemplate) { - startTemplate(field) + tryStartTemplate(field) } } @@ -101,11 +101,11 @@ internal class JavaFieldRenderer( return helper.insertFieldImpl(targetClass, field, anchor) } - internal fun startTemplate(field: PsiField) { + internal fun tryStartTemplate(field: PsiField) { val targetFile = targetClass.containingFile ?: return val newEditor = positionCursor(field.project, targetFile, field) ?: return val substitutor = request.targetSubstitutor.toPsiSubstitutor(project) - val template = helper.setupTemplateImpl(field, expectedTypes, targetClass, newEditor, javaUsage?.reference, constantField, request.isStartTemplate, substitutor) + val template = helper.setupTemplateImpl(field, expectedTypes, targetClass, newEditor, javaUsage?.reference, constantField, request.isStartTemplate, substitutor) ?: return val listener = MyTemplateListener(project, newEditor, targetFile) startTemplate(newEditor, template, project, listener, null) } diff --git a/java/java-impl/src/com/intellij/lang/java/actions/CreateFieldActionBase.kt b/java/java-impl/src/com/intellij/lang/java/actions/CreateFieldActionBase.kt index 6c6acfca1170..076f7c6bb4cd 100644 --- a/java/java-impl/src/com/intellij/lang/java/actions/CreateFieldActionBase.kt +++ b/java/java-impl/src/com/intellij/lang/java/actions/CreateFieldActionBase.kt @@ -31,7 +31,7 @@ internal abstract class CreateFieldActionBase( val javaFieldRenderer = JavaFieldRenderer(project, isConstant(), copyClass, request) var field = javaFieldRenderer.renderField() field = javaFieldRenderer.insertField(field, PsiTreeUtil.findSameElementInCopy((request as? CreateFieldFromJavaUsageRequest)?.anchor, file)) - javaFieldRenderer.startTemplate(field) + javaFieldRenderer.tryStartTemplate(field) return IntentionPreviewInfo.DIFF } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/CreateFieldFix.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/CreateFieldFix.java index 5c917d9219f3..f946803714ee 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/CreateFieldFix.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/CreateFieldFix.java @@ -38,8 +38,11 @@ public class CreateFieldFix { if (field == null) return; Editor newEditor = IntentionUtils.positionCursor(project, myTargetClass.getContainingFile(), field); + if (newEditor == null) return; Template template = CreateFieldFromUsageHelper.setupTemplate(field, typeConstraints, myTargetClass, newEditor, context, false); + if (template == null) return; + TemplateManager manager = TemplateManager.getInstance(project); manager.startTemplate(newEditor, template); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/GroovyCreateFieldFromUsageHelper.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/GroovyCreateFieldFromUsageHelper.java index 8027173a4fd6..8adc4b1bcbdb 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/GroovyCreateFieldFromUsageHelper.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/GroovyCreateFieldFromUsageHelper.java @@ -24,12 +24,14 @@ import org.jetbrains.plugins.groovy.lang.psi.expectedTypes.TypeConstraint; import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GroovyScriptClass; import org.jetbrains.plugins.groovy.template.expressions.ChooseTypeExpression; +import java.util.Objects; + /** * @author Max Medvedev */ public final class GroovyCreateFieldFromUsageHelper extends CreateFieldFromUsageHelper { @Override - public Template setupTemplateImpl(PsiField f, + public @Nullable Template setupTemplateImpl(@NotNull PsiField f, Object expectedTypes, PsiClass targetClass, Editor editor, @@ -40,7 +42,10 @@ public final class GroovyCreateFieldFromUsageHelper extends CreateFieldFromUsage GrVariableDeclaration fieldDecl = (GrVariableDeclaration)f.getParent(); GrField field = (GrField)fieldDecl.getVariables()[0]; Project project = field.getProject(); + fieldDecl = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(fieldDecl); + if (fieldDecl == null) return null; + TemplateBuilderImpl builder = new TemplateBuilderImpl(fieldDecl); builder.setScrollToTemplate(isScrollToTemplate); @@ -55,7 +60,7 @@ public final class GroovyCreateFieldFromUsageHelper extends CreateFieldFromUsage } else if (expectedTypes instanceof ExpectedTypeInfo[]) { new GuessTypeParameters(project, factory, builder, substitutor) - .setupTypeElement(field.getTypeElement(), (ExpectedTypeInfo[])expectedTypes, context, targetClass); + .setupTypeElement(Objects.requireNonNull(field.getTypeElement()), (ExpectedTypeInfo[])expectedTypes, context, targetClass); } GrExpression initializer = field.getInitializerGroovy(); @@ -67,6 +72,8 @@ public final class GroovyCreateFieldFromUsageHelper extends CreateFieldFromUsage } fieldDecl = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(fieldDecl); + if (fieldDecl == null) return null; + Template template = builder.buildTemplate(); TextRange range = fieldDecl.getTextRange(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/elements/CreateFieldAction.kt b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/elements/CreateFieldAction.kt index 8ca111bff002..a2e18051ea6d 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/elements/CreateFieldAction.kt +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/elements/CreateFieldAction.kt @@ -90,7 +90,7 @@ private class GroovyFieldRenderer( fun doRender() { var field = renderField() field = insertField(field) - startTemplate(field) + tryStartTemplate(field) } fun renderField(): GrField { @@ -132,11 +132,11 @@ private class GroovyFieldRenderer( } - private fun startTemplate(field: GrField) { + private fun tryStartTemplate(field: GrField) { val targetFile = targetClass.containingFile ?: return val newEditor = positionCursor(field.project, targetFile, field) ?: return val substitutor = request.targetSubstitutor.toPsiSubstitutor(project) - val template = helper.setupTemplateImpl(field, typeConstraints, targetClass, newEditor, null, constantField, request.isStartTemplate, substitutor) + val template = helper.setupTemplateImpl(field, typeConstraints, targetClass, newEditor, null, constantField, request.isStartTemplate, substitutor) ?: return val listener = MyTemplateListener(project, newEditor, targetFile) startTemplate(newEditor, template, project, listener, null) }