From f7abe52af54db85f60759c935f26dd18ab4bc7e0 Mon Sep 17 00:00:00 2001 From: Alexander Zolotov Date: Wed, 7 May 2014 22:13:59 +0400 Subject: [PATCH] Delete dummy semicolon after postfix template expansion --- .../JavaPostfixTemplateProvider.java | 21 +++++++++++++++++++ .../postfix/templates/cast/chainCall.java | 5 +++++ .../templates/cast/chainCall_after.java | 5 +++++ .../templates/for/beforeAssignment.java | 7 +++++++ .../templates/for/beforeAssignment_after.java | 9 ++++++++ .../templates/CastPostfixTemplateTest.java | 4 ++++ .../templates/ForeachTemplateTest.java | 17 +++++++++++++++ .../templates/PostfixLiveTemplate.java | 11 +++++++--- .../templates/PostfixTemplateProvider.java | 6 ++++++ 9 files changed, 82 insertions(+), 3 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/template/postfix/templates/cast/chainCall.java create mode 100644 java/java-tests/testData/codeInsight/template/postfix/templates/cast/chainCall_after.java create mode 100644 java/java-tests/testData/codeInsight/template/postfix/templates/for/beforeAssignment.java create mode 100644 java/java-tests/testData/codeInsight/template/postfix/templates/for/beforeAssignment_after.java diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/JavaPostfixTemplateProvider.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/JavaPostfixTemplateProvider.java index 5fab3e7ca064..aa381af32ca0 100644 --- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/JavaPostfixTemplateProvider.java +++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/JavaPostfixTemplateProvider.java @@ -102,6 +102,27 @@ public class JavaPostfixTemplateProvider implements PostfixTemplateProvider { } } + @Override + public void afterExpand(@NotNull final PsiFile file, @NotNull final Editor editor) { + final SmartPsiElementPointer pointer = file.getUserData(ADDED_SEMICOLON); + if (pointer != null) { + final PsiElement addedSemicolon = pointer.getElement(); + file.putUserData(ADDED_SEMICOLON, null); + if (addedSemicolon != null && addedSemicolon.isValid()) { + CommandProcessor.getInstance().runUndoTransparentAction(new Runnable() { + @Override + public void run() { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + addedSemicolon.delete(); + } + }); + } + }); + } + } + } + @NotNull @Override public PsiFile preCheck(final @NotNull PsiFile copyFile, final @NotNull Editor realEditor, final int currentOffset) { diff --git a/java/java-tests/testData/codeInsight/template/postfix/templates/cast/chainCall.java b/java/java-tests/testData/codeInsight/template/postfix/templates/cast/chainCall.java new file mode 100644 index 000000000000..7b3bfb6a0ca2 --- /dev/null +++ b/java/java-tests/testData/codeInsight/template/postfix/templates/cast/chainCall.java @@ -0,0 +1,5 @@ +public class Foo { + void m(Object o) { + "test".cast.length() + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/template/postfix/templates/cast/chainCall_after.java b/java/java-tests/testData/codeInsight/template/postfix/templates/cast/chainCall_after.java new file mode 100644 index 000000000000..42663e95c67b --- /dev/null +++ b/java/java-tests/testData/codeInsight/template/postfix/templates/cast/chainCall_after.java @@ -0,0 +1,5 @@ +public class Foo { + void m(Object o) { + (() "test").length() + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/template/postfix/templates/for/beforeAssignment.java b/java/java-tests/testData/codeInsight/template/postfix/templates/for/beforeAssignment.java new file mode 100644 index 000000000000..f33c287cac3d --- /dev/null +++ b/java/java-tests/testData/codeInsight/template/postfix/templates/for/beforeAssignment.java @@ -0,0 +1,7 @@ +public class Foo { + void m() { + int[] xs = {1, 2, 3}; + xs.for + xs = new int[0]; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/template/postfix/templates/for/beforeAssignment_after.java b/java/java-tests/testData/codeInsight/template/postfix/templates/for/beforeAssignment_after.java new file mode 100644 index 000000000000..a1a961ef9844 --- /dev/null +++ b/java/java-tests/testData/codeInsight/template/postfix/templates/for/beforeAssignment_after.java @@ -0,0 +1,9 @@ +public class Foo { + void m() { + int[] xs = {1, 2, 3}; + for (int x : xs) { + + } + xs = new int[0]; + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/template/postfix/templates/CastPostfixTemplateTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/template/postfix/templates/CastPostfixTemplateTest.java index b7d4ef358823..ec68539184d8 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/template/postfix/templates/CastPostfixTemplateTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/template/postfix/templates/CastPostfixTemplateTest.java @@ -26,4 +26,8 @@ public class CastPostfixTemplateTest extends PostfixTemplateTestCase { public void testVoidExpression() { doTest(); } public void testSingleArgument() { doTest(); } public void testInsideString() { doTest(); } + + public void testChainCall() { + doTest(); + } } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/template/postfix/templates/ForeachTemplateTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/template/postfix/templates/ForeachTemplateTest.java index 46b274f7fbc1..24a2707767e5 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/template/postfix/templates/ForeachTemplateTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/template/postfix/templates/ForeachTemplateTest.java @@ -1,9 +1,26 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.intellij.codeInsight.template.postfix.templates; import org.jetbrains.annotations.NotNull; public class ForeachTemplateTest extends PostfixTemplateTestCase { public void testInts() { doTest(); } + + public void testBeforeAssignment() { doTest(); } @NotNull @Override diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixLiveTemplate.java b/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixLiveTemplate.java index 01c42752e420..631a751baf3d 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixLiveTemplate.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixLiveTemplate.java @@ -126,9 +126,14 @@ public class PostfixLiveTemplate extends CustomLiveTemplateBase { final PsiFile file = callback.getContext().getContainingFile(); if (isApplicableTemplate(provider, key, file, editor)) { int offset = deleteTemplateKey(file, editor, key); - provider.preExpand(file, editor); - PsiElement context = CustomTemplateCallback.getContext(file, positiveOffset(offset)); - expandTemplate(postfixTemplate, editor, context); + try { + provider.preExpand(file, editor); + PsiElement context = CustomTemplateCallback.getContext(file, positiveOffset(offset)); + expandTemplate(postfixTemplate, editor, context); + } + finally { + provider.afterExpand(file, editor); + } } // don't care about errors in multiCaret mode else if (editor.getCaretModel().getAllCarets().size() == 1) { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixTemplateProvider.java b/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixTemplateProvider.java index 84fa367ff09f..b9a30c5bab58 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixTemplateProvider.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixTemplateProvider.java @@ -46,6 +46,12 @@ public interface PostfixTemplateProvider { */ void preExpand(@NotNull PsiFile file, @NotNull Editor editor); + /** + * Invoked after template finished (doesn't matter if it finished successfully or not). + * E.g. java postfix template use this method for deleting inserted semicolon. + */ + void afterExpand(@NotNull PsiFile file, @NotNull Editor editor); + /** * Prepare file for checking availability of templates. * Almost the same as {@link this#preExpand(com.intellij.psi.PsiFile, com.intellij.openapi.editor.Editor)} with several differences: