From 3d4a5256e6b34a1a0d86fd3c8daba1d123f9340f Mon Sep 17 00:00:00 2001 From: "Natalia.Ukhorskaya" Date: Wed, 20 Feb 2013 15:17:57 +0400 Subject: [PATCH] Surround with: move declaration out from block --- .../jetbrains/jet/plugin/JetBundle.properties | 2 + .../surroundWith/KotlinSurrounderUtils.java | 10 + .../MoveDeclarationsOutHelper.java | 169 ++++++++++++++ .../KotlinFunctionLiteralSurrounder.java | 8 +- .../statement/KotlinIfElseSurrounder.java | 5 + .../statement/KotlinIfSurrounder.java | 5 + .../statement/KotlinIfSurrounderBase.java | 12 +- .../statement/KotlinTryFinallySurrounder.java | 4 +- .../statement/KotlinTrySurrounderBase.java | 8 +- .../functionLiteral/moveDeclarationsOut.kt | 7 + .../moveDeclarationsOut.kt.after | 11 + .../moveDeclarationsOut/class/classInType.kt | 6 + .../class/classInType.kt.after | 8 + .../moveDeclarationsOut/class/localClass.kt | 6 + .../class/localClass.kt.after | 8 + .../function/firstChildLocalFun.kt | 5 + .../function/firstChildLocalFun.kt.after | 7 + .../moveDeclarationsOut/function/localFun.kt | 7 + .../function/localFun.kt.after | 9 + .../function/unusedLocalFun.kt | 9 + .../function/unusedLocalFun.kt.after | 11 + .../moveDeclarationsOut/object/localObject.kt | 6 + .../object/localObject.kt.after | 8 + .../moveDeclarationsOut/order/twoClasses.kt | 9 + .../order/twoClasses.kt.after | 11 + .../moveDeclarationsOut/order/valAndClass.kt | 9 + .../order/valAndClass.kt.after | 12 + .../if/moveDeclarationsOut/order/valOrder.kt | 7 + .../order/valOrder.kt.after | 11 + .../val/fullQualifiedType.kt | 5 + .../val/fullQualifiedType.kt.after | 8 + .../val/fullQualifiedTypeWithoutTypeRef.kt | 9 + .../fullQualifiedTypeWithoutTypeRef.kt.after | 12 + .../val/valWithTypeWithInitializer.kt | 5 + .../val/valWithTypeWithInitializer.kt.after | 8 + .../val/valWithTypeWoInitializer.kt | 11 + .../val/valWithTypeWoInitializer.kt.after | 13 ++ .../val/valWoTypeWithInitializer.kt | 5 + .../val/valWoTypeWithInitializer.kt.after | 8 + .../var/defaultValue/boolean.kt | 4 + .../var/defaultValue/boolean.kt.after | 7 + .../var/defaultValue/nullable.kt | 4 + .../var/defaultValue/nullable.kt.after | 7 + .../var/defaultValue/primitiveNumbers.kt | 16 ++ .../defaultValue/primitiveNumbers.kt.after | 25 +++ .../varWithNotNullableTypeWithInitializer.kt | 5 + ...ithNotNullableTypeWithInitializer.kt.after | 8 + .../var/varWithTypeWoInitializer.kt | 6 + .../var/varWithTypeWoInitializer.kt.after | 8 + .../var/varWoTypeWithInitializer.kt | 5 + .../var/varWoTypeWithInitializer.kt.after | 8 + .../ifElse/moveDeclarationsOutVal.kt | 4 + .../ifElse/moveDeclarationsOutVal.kt.after | 8 + .../ifElse/moveDeclarationsOutVar.kt | 4 + .../ifElse/moveDeclarationsOutVar.kt.after | 8 + .../tryCatch/moveDeclarationsOut.kt | 7 + .../tryCatch/moveDeclarationsOut.kt.after | 12 + .../SurroundWithTestGenerated.java | 212 +++++++++++++++++- 58 files changed, 825 insertions(+), 7 deletions(-) create mode 100644 idea/src/org/jetbrains/jet/plugin/codeInsight/surroundWith/MoveDeclarationsOutHelper.java create mode 100644 idea/testData/codeInsight/surroundWith/functionLiteral/moveDeclarationsOut.kt create mode 100644 idea/testData/codeInsight/surroundWith/functionLiteral/moveDeclarationsOut.kt.after create mode 100644 idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/class/classInType.kt create mode 100644 idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/class/classInType.kt.after create mode 100644 idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/class/localClass.kt create mode 100644 idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/class/localClass.kt.after create mode 100644 idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/function/firstChildLocalFun.kt create mode 100644 idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/function/firstChildLocalFun.kt.after create mode 100644 idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/function/localFun.kt create mode 100644 idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/function/localFun.kt.after create mode 100644 idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/function/unusedLocalFun.kt create mode 100644 idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/function/unusedLocalFun.kt.after create mode 100644 idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/object/localObject.kt create mode 100644 idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/object/localObject.kt.after create mode 100644 idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/order/twoClasses.kt create mode 100644 idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/order/twoClasses.kt.after create mode 100644 idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/order/valAndClass.kt create mode 100644 idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/order/valAndClass.kt.after create mode 100644 idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/order/valOrder.kt create mode 100644 idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/order/valOrder.kt.after create mode 100644 idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/val/fullQualifiedType.kt create mode 100644 idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/val/fullQualifiedType.kt.after create mode 100644 idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/val/fullQualifiedTypeWithoutTypeRef.kt create mode 100644 idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/val/fullQualifiedTypeWithoutTypeRef.kt.after create mode 100644 idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/val/valWithTypeWithInitializer.kt create mode 100644 idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/val/valWithTypeWithInitializer.kt.after create mode 100644 idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/val/valWithTypeWoInitializer.kt create mode 100644 idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/val/valWithTypeWoInitializer.kt.after create mode 100644 idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/val/valWoTypeWithInitializer.kt create mode 100644 idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/val/valWoTypeWithInitializer.kt.after create mode 100644 idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/defaultValue/boolean.kt create mode 100644 idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/defaultValue/boolean.kt.after create mode 100644 idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/defaultValue/nullable.kt create mode 100644 idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/defaultValue/nullable.kt.after create mode 100644 idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/defaultValue/primitiveNumbers.kt create mode 100644 idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/defaultValue/primitiveNumbers.kt.after create mode 100644 idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/varWithNotNullableTypeWithInitializer.kt create mode 100644 idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/varWithNotNullableTypeWithInitializer.kt.after create mode 100644 idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/varWithTypeWoInitializer.kt create mode 100644 idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/varWithTypeWoInitializer.kt.after create mode 100644 idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/varWoTypeWithInitializer.kt create mode 100644 idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/varWoTypeWithInitializer.kt.after create mode 100644 idea/testData/codeInsight/surroundWith/ifElse/moveDeclarationsOutVal.kt create mode 100644 idea/testData/codeInsight/surroundWith/ifElse/moveDeclarationsOutVal.kt.after create mode 100644 idea/testData/codeInsight/surroundWith/ifElse/moveDeclarationsOutVar.kt create mode 100644 idea/testData/codeInsight/surroundWith/ifElse/moveDeclarationsOutVar.kt.after create mode 100644 idea/testData/codeInsight/surroundWith/tryCatch/moveDeclarationsOut.kt create mode 100644 idea/testData/codeInsight/surroundWith/tryCatch/moveDeclarationsOut.kt.after diff --git a/idea/src/org/jetbrains/jet/plugin/JetBundle.properties b/idea/src/org/jetbrains/jet/plugin/JetBundle.properties index d1410342a6b..178a214b30e 100644 --- a/idea/src/org/jetbrains/jet/plugin/JetBundle.properties +++ b/idea/src/org/jetbrains/jet/plugin/JetBundle.properties @@ -116,8 +116,10 @@ move.when.else.branch.to.the.end.family.name=Move Else Branch to the End change.to.property.name.family.name=Change to property name change.to.property.name.action=Change ''{0}'' to ''{1}'' +surround.with=Surround with surround.with.string.template="${expr}" surround.with.when.template=when (expr) {} surround.with.function.template={ } +surround.with.cannot.perform.action=Cannot perform Surround With action to the current contextsurround.with.function.template={ } remove.variable.family.name=Remove variable remove.variable.action=Remove variable ''{0}'' diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/surroundWith/KotlinSurrounderUtils.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/surroundWith/KotlinSurrounderUtils.java index 63b53632803..a08a2501275 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/surroundWith/KotlinSurrounderUtils.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/surroundWith/KotlinSurrounderUtils.java @@ -1,5 +1,7 @@ package org.jetbrains.jet.plugin.codeInsight.surroundWith; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -10,9 +12,13 @@ import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.lazy.ResolveSession; import org.jetbrains.jet.lang.resolve.lazy.ResolveSessionUtils; import org.jetbrains.jet.lang.types.JetType; +import org.jetbrains.jet.plugin.JetBundle; +import org.jetbrains.jet.plugin.codeInsight.CodeInsightUtils; import org.jetbrains.jet.plugin.project.WholeProjectAnalyzerFacade; public class KotlinSurrounderUtils { + public static String SURROUND_WITH = JetBundle.message("surround.with"); + public static String SURROUND_WITH_ERROR = JetBundle.message("surround.with.cannot.perform.action"); public static void addStatementsInBlock( @NotNull JetBlockExpression block, @@ -28,4 +34,8 @@ public class KotlinSurrounderUtils { BindingContext expressionBindingContext = ResolveSessionUtils.resolveToExpression(resolveSession, expression); return expressionBindingContext.get(BindingContext.EXPRESSION_TYPE, expression); } + + public static void showErrorHint(@NotNull Project project, @NotNull Editor editor, @NotNull String message) { + CodeInsightUtils.showErrorHint(project, editor, message, KotlinSurrounderUtils.SURROUND_WITH, null); + } } diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/surroundWith/MoveDeclarationsOutHelper.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/surroundWith/MoveDeclarationsOutHelper.java new file mode 100644 index 00000000000..ee840914545 --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/surroundWith/MoveDeclarationsOutHelper.java @@ -0,0 +1,169 @@ +/* + * Copyright 2010-2013 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 org.jetbrains.jet.plugin.codeInsight.surroundWith; + +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiReference; +import com.intellij.psi.search.LocalSearchScope; +import com.intellij.psi.search.SearchScope; +import com.intellij.psi.search.searches.ReferencesSearch; +import com.intellij.psi.util.PsiUtilCore; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.descriptors.VariableDescriptor; +import org.jetbrains.jet.lang.psi.*; +import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.lang.resolve.lazy.ResolveSession; +import org.jetbrains.jet.lang.resolve.lazy.ResolveSessionUtils; +import org.jetbrains.jet.lang.types.ErrorUtils; +import org.jetbrains.jet.lang.types.JetType; +import org.jetbrains.jet.plugin.codeInsight.CodeInsightUtils; +import org.jetbrains.jet.plugin.codeInsight.ReferenceToClassesShortening; +import org.jetbrains.jet.plugin.project.WholeProjectAnalyzerFacade; +import org.jetbrains.jet.renderer.DescriptorRenderer; + +import java.util.ArrayList; +import java.util.List; + +import static org.jetbrains.jet.lang.psi.JetPsiFactory.*; + +public class MoveDeclarationsOutHelper { + + public static PsiElement[] move(@NotNull PsiElement container, @NotNull PsiElement[] statements, boolean generateDefaultInitializers) { + if (statements.length == 0) { + return statements; + } + + Project project = container.getProject(); + + List resultStatements = new ArrayList(); + List propertiesDeclarations = new ArrayList(); + + // Dummy element to add new declarations at the beginning + PsiElement dummyFirstStatement = container.addBefore(createExpression(project, "dummyStatement "), statements[0]); + + try { + SearchScope scope = new LocalSearchScope(container); + int lastStatementOffset = statements[statements.length - 1].getTextRange().getEndOffset(); + + for (PsiElement statement : statements) { + if (needToDeclareOut(statement, lastStatementOffset, scope)) { + if (statement instanceof JetProperty && ((JetProperty) statement).getInitializer() != null) { + JetProperty property = (JetProperty) statement; + JetProperty declaration = createVariableDeclaration(property, generateDefaultInitializers); + declaration = (JetProperty) container.addBefore(declaration, dummyFirstStatement); + propertiesDeclarations.add(declaration); + container.addAfter(createNewLine(project), declaration); + + JetBinaryExpression assignment = createVariableAssignment(property); + resultStatements.add(property.replace(assignment)); + } + else { + PsiElement newStatement = container.addBefore(statement, dummyFirstStatement); + container.addAfter(createNewLine(project), newStatement); + container.deleteChildRange(statement, statement); + } + } + else { + resultStatements.add(statement); + } + } + } + finally { + dummyFirstStatement.delete(); + } + + ReferenceToClassesShortening.compactReferenceToClasses(propertiesDeclarations); + + return PsiUtilCore.toPsiElementArray(resultStatements); + } + + @NotNull + private static JetBinaryExpression createVariableAssignment(@NotNull JetProperty property) { + String propertyName = property.getName(); + assert propertyName != null : "Property should have a name " + property.getText(); + JetBinaryExpression assignment = (JetBinaryExpression) createExpression(property.getProject(), propertyName + " = x"); + JetExpression right = assignment.getRight(); + assert right != null : "Created binary expression should have a right part " + assignment.getText(); + JetExpression initializer = property.getInitializer(); + assert initializer != null : "Initializer should exist for property " + property.getText(); + right.replace(initializer); + return assignment; + } + + @NotNull + private static JetProperty createVariableDeclaration(@NotNull JetProperty property, boolean generateDefaultInitializers) { + JetType propertyType = getPropertyType(property); + String defaultInitializer = null; + if (generateDefaultInitializers && property.isVar()) { + defaultInitializer = CodeInsightUtils.defaultInitializer(propertyType); + } + return createProperty(property, propertyType, defaultInitializer); + } + + @NotNull + private static JetType getPropertyType(@NotNull JetProperty property) { + ResolveSession resolveSession = WholeProjectAnalyzerFacade.getLazyResolveSessionForFile((JetFile) property.getContainingFile()); + BindingContext expressionBindingContext = ResolveSessionUtils.resolveToExpression(resolveSession, property); + + VariableDescriptor propertyDescriptor = expressionBindingContext.get(BindingContext.VARIABLE, property); + assert propertyDescriptor != null : "Couldn't resolve property to property descriptor " + property.getText(); + return propertyDescriptor.getType(); + } + + @NotNull + private static JetProperty createProperty(@NotNull JetProperty property, @NotNull JetType propertyType, @Nullable String initializer) { + JetTypeReference typeRef = property.getTypeRef(); + String typeString = null; + if (typeRef != null) { + typeString = typeRef.getText(); + } + else if (!ErrorUtils.isErrorType(propertyType)) { + typeString = DescriptorRenderer.TEXT.renderType(propertyType); + } + + return JetPsiFactory.createProperty(property.getProject(), property.getName(), typeString, property.isVar(), initializer); + } + + private static boolean needToDeclareOut(@NotNull PsiElement element, int lastStatementOffset, @NotNull SearchScope scope) { + if (element instanceof JetProperty || + element instanceof JetClassOrObject || + element instanceof JetFunction) { + + // Descriptor for local object is linked with JetObjectNameDeclaration + if (element instanceof JetObjectDeclaration) { + JetObjectDeclarationName declarationName = ((JetObjectDeclaration) element).getNameAsDeclaration(); + if (declarationName != null) { + element = declarationName; + } + } + + PsiReference[] refs = ReferencesSearch.search(element, scope, false).toArray(PsiReference.EMPTY_ARRAY); + if (refs.length > 0) { + PsiReference lastRef = refs[refs.length - 1]; + if (lastRef.getElement().getTextOffset() > lastStatementOffset) { + return true; + } + } + } + return false; + } + + private MoveDeclarationsOutHelper() { + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/surroundWith/statement/KotlinFunctionLiteralSurrounder.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/surroundWith/statement/KotlinFunctionLiteralSurrounder.java index a69f4abdb42..5aecec4434b 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/surroundWith/statement/KotlinFunctionLiteralSurrounder.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/surroundWith/statement/KotlinFunctionLiteralSurrounder.java @@ -25,12 +25,18 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.plugin.JetBundle; import org.jetbrains.jet.plugin.codeInsight.surroundWith.KotlinSurrounderUtils; +import org.jetbrains.jet.plugin.codeInsight.surroundWith.MoveDeclarationsOutHelper; public class KotlinFunctionLiteralSurrounder extends KotlinStatementsSurrounder { @Nullable @Override protected TextRange surroundStatements(Project project, Editor editor, PsiElement container, PsiElement[] statements) { - // TODO extract variables declaration + statements = MoveDeclarationsOutHelper.move(container, statements, true); + + if (statements.length == 0) { + KotlinSurrounderUtils.showErrorHint(project, editor, KotlinSurrounderUtils.SURROUND_WITH_ERROR); + return null; + } JetCallExpression callExpression = (JetCallExpression) JetPsiFactory.createExpression(project, "run {\n}"); callExpression = (JetCallExpression) container.addAfter(callExpression, statements[statements.length - 1]); diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/surroundWith/statement/KotlinIfElseSurrounder.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/surroundWith/statement/KotlinIfElseSurrounder.java index b393bbf5ee5..c1a55597e82 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/surroundWith/statement/KotlinIfElseSurrounder.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/surroundWith/statement/KotlinIfElseSurrounder.java @@ -32,4 +32,9 @@ public class KotlinIfElseSurrounder extends KotlinIfSurrounderBase { protected String getCodeTemplate() { return "if (a) { \n} else { \n}"; } + + @Override + protected boolean isGenerateDefaultInitializers() { + return false; + } } \ No newline at end of file diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/surroundWith/statement/KotlinIfSurrounder.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/surroundWith/statement/KotlinIfSurrounder.java index 0bf5729c3b1..59f75c92854 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/surroundWith/statement/KotlinIfSurrounder.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/surroundWith/statement/KotlinIfSurrounder.java @@ -32,4 +32,9 @@ public class KotlinIfSurrounder extends KotlinIfSurrounderBase { protected String getCodeTemplate() { return "if (a) { \n}"; } + + @Override + protected boolean isGenerateDefaultInitializers() { + return true; + } } \ No newline at end of file diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/surroundWith/statement/KotlinIfSurrounderBase.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/surroundWith/statement/KotlinIfSurrounderBase.java index cc8467b3ef2..60fbe7c763e 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/surroundWith/statement/KotlinIfSurrounderBase.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/surroundWith/statement/KotlinIfSurrounderBase.java @@ -29,15 +29,19 @@ import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetIfExpression; import org.jetbrains.jet.lang.psi.JetPsiFactory; import org.jetbrains.jet.plugin.codeInsight.surroundWith.KotlinSurrounderUtils; - -import java.lang.String; +import org.jetbrains.jet.plugin.codeInsight.surroundWith.MoveDeclarationsOutHelper; public abstract class KotlinIfSurrounderBase extends KotlinStatementsSurrounder { @Nullable @Override protected TextRange surroundStatements(Project project, Editor editor, PsiElement container, PsiElement[] statements) { - // TODO extract variables declaration + statements = MoveDeclarationsOutHelper.move(container, statements, isGenerateDefaultInitializers()); + + if (statements.length == 0) { + KotlinSurrounderUtils.showErrorHint(project, editor, KotlinSurrounderUtils.SURROUND_WITH_ERROR); + return null; + } JetIfExpression ifExpression = (JetIfExpression) JetPsiFactory.createExpression(project, getCodeTemplate()); ifExpression = (JetIfExpression) container.addAfter(ifExpression, statements[statements.length - 1]); @@ -65,4 +69,6 @@ public abstract class KotlinIfSurrounderBase extends KotlinStatementsSurrounder @NotNull protected abstract String getCodeTemplate(); + + protected abstract boolean isGenerateDefaultInitializers(); } \ No newline at end of file diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/surroundWith/statement/KotlinTryFinallySurrounder.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/surroundWith/statement/KotlinTryFinallySurrounder.java index 85e6119aed0..b10e54d7205 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/surroundWith/statement/KotlinTryFinallySurrounder.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/surroundWith/statement/KotlinTryFinallySurrounder.java @@ -38,7 +38,9 @@ public class KotlinTryFinallySurrounder extends KotlinTrySurrounderBase { @Override protected TextRange surroundStatements(@NotNull Project project, @NotNull Editor editor, @NotNull PsiElement container, @NotNull PsiElement[] statements) { TextRange textRange = super.surroundStatements(project, editor, container, statements); - assert textRange != null; + if (textRange == null) { + return null; + } // Delete dummy "b" element for caret editor.getDocument().deleteString(textRange.getStartOffset(), textRange.getEndOffset()); return new TextRange(textRange.getStartOffset(), textRange.getStartOffset()); diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/surroundWith/statement/KotlinTrySurrounderBase.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/surroundWith/statement/KotlinTrySurrounderBase.java index 429ff073406..399711b84aa 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/surroundWith/statement/KotlinTrySurrounderBase.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/surroundWith/statement/KotlinTrySurrounderBase.java @@ -25,13 +25,19 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.plugin.codeInsight.surroundWith.KotlinSurrounderUtils; +import org.jetbrains.jet.plugin.codeInsight.surroundWith.MoveDeclarationsOutHelper; public abstract class KotlinTrySurrounderBase extends KotlinStatementsSurrounder { @Nullable @Override protected TextRange surroundStatements(@NotNull Project project, @NotNull Editor editor, @NotNull PsiElement container, @NotNull PsiElement[] statements) { - // TODO extract variables declaration + statements = MoveDeclarationsOutHelper.move(container, statements, true); + + if (statements.length == 0) { + KotlinSurrounderUtils.showErrorHint(project, editor, KotlinSurrounderUtils.SURROUND_WITH_ERROR); + return null; + } JetTryExpression tryExpression = (JetTryExpression) JetPsiFactory.createExpression(project, getCodeTemplate()); tryExpression = (JetTryExpression) container.addAfter(tryExpression, statements[statements.length - 1]); diff --git a/idea/testData/codeInsight/surroundWith/functionLiteral/moveDeclarationsOut.kt b/idea/testData/codeInsight/surroundWith/functionLiteral/moveDeclarationsOut.kt new file mode 100644 index 00000000000..04667c1e267 --- /dev/null +++ b/idea/testData/codeInsight/surroundWith/functionLiteral/moveDeclarationsOut.kt @@ -0,0 +1,7 @@ +fun foo() { + val a = "aaa" + val b = "aaa" + + a.charAt(1) + b.charAt(1) +} \ No newline at end of file diff --git a/idea/testData/codeInsight/surroundWith/functionLiteral/moveDeclarationsOut.kt.after b/idea/testData/codeInsight/surroundWith/functionLiteral/moveDeclarationsOut.kt.after new file mode 100644 index 00000000000..a434fcd3681 --- /dev/null +++ b/idea/testData/codeInsight/surroundWith/functionLiteral/moveDeclarationsOut.kt.after @@ -0,0 +1,11 @@ +fun foo() { + val a: String + val b: String + run { + a = "aaa" + b = "aaa" + } + + a.charAt(1) + b.charAt(1) +} \ No newline at end of file diff --git a/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/class/classInType.kt b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/class/classInType.kt new file mode 100644 index 00000000000..12eec843882 --- /dev/null +++ b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/class/classInType.kt @@ -0,0 +1,6 @@ +fun foo() { + class A {} + "bbb" + + val myClass: A? = null +} \ No newline at end of file diff --git a/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/class/classInType.kt.after b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/class/classInType.kt.after new file mode 100644 index 00000000000..467f87df9d8 --- /dev/null +++ b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/class/classInType.kt.after @@ -0,0 +1,8 @@ +fun foo() { + class A {} + if () { + "bbb" + } + + val myClass: A? = null +} \ No newline at end of file diff --git a/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/class/localClass.kt b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/class/localClass.kt new file mode 100644 index 00000000000..5281ca19323 --- /dev/null +++ b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/class/localClass.kt @@ -0,0 +1,6 @@ +fun foo() { + class A {} + "bbb" + + val myClass = A() +} \ No newline at end of file diff --git a/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/class/localClass.kt.after b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/class/localClass.kt.after new file mode 100644 index 00000000000..58a8380460b --- /dev/null +++ b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/class/localClass.kt.after @@ -0,0 +1,8 @@ +fun foo() { + class A {} + if () { + "bbb" + } + + val myClass = A() +} \ No newline at end of file diff --git a/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/function/firstChildLocalFun.kt b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/function/firstChildLocalFun.kt new file mode 100644 index 00000000000..2f8e5c6c523 --- /dev/null +++ b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/function/firstChildLocalFun.kt @@ -0,0 +1,5 @@ +fun foo() { + fun test() {} + "aaa" + test() +} \ No newline at end of file diff --git a/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/function/firstChildLocalFun.kt.after b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/function/firstChildLocalFun.kt.after new file mode 100644 index 00000000000..53b130cbd37 --- /dev/null +++ b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/function/firstChildLocalFun.kt.after @@ -0,0 +1,7 @@ +fun foo() { + fun test() {} + if () { + "aaa" + } + test() +} \ No newline at end of file diff --git a/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/function/localFun.kt b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/function/localFun.kt new file mode 100644 index 00000000000..7638ecd5b95 --- /dev/null +++ b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/function/localFun.kt @@ -0,0 +1,7 @@ +fun foo() { + "aaa" + fun test() {} + "aaa" + + test() +} \ No newline at end of file diff --git a/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/function/localFun.kt.after b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/function/localFun.kt.after new file mode 100644 index 00000000000..297db593db1 --- /dev/null +++ b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/function/localFun.kt.after @@ -0,0 +1,9 @@ +fun foo() { + fun test() {} + if () { + "aaa" + "aaa" + } + + test() +} \ No newline at end of file diff --git a/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/function/unusedLocalFun.kt b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/function/unusedLocalFun.kt new file mode 100644 index 00000000000..7ff280d1bf1 --- /dev/null +++ b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/function/unusedLocalFun.kt @@ -0,0 +1,9 @@ +fun foo() { + + fun test() {} + "aaa" + test() + + + val a = "ss" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/function/unusedLocalFun.kt.after b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/function/unusedLocalFun.kt.after new file mode 100644 index 00000000000..4b95fac762d --- /dev/null +++ b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/function/unusedLocalFun.kt.after @@ -0,0 +1,11 @@ +fun foo() { + + if () { + fun test() {} + "aaa" + test() + } + + + val a = "ss" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/object/localObject.kt b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/object/localObject.kt new file mode 100644 index 00000000000..8d8840d6b13 --- /dev/null +++ b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/object/localObject.kt @@ -0,0 +1,6 @@ +fun foo() { + object A {} + "bbb" + + val myClass = A +} \ No newline at end of file diff --git a/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/object/localObject.kt.after b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/object/localObject.kt.after new file mode 100644 index 00000000000..ea463d0d82b --- /dev/null +++ b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/object/localObject.kt.after @@ -0,0 +1,8 @@ +fun foo() { + object A {} + if () { + "bbb" + } + + val myClass = A +} \ No newline at end of file diff --git a/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/order/twoClasses.kt b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/order/twoClasses.kt new file mode 100644 index 00000000000..f5b0635eb5f --- /dev/null +++ b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/order/twoClasses.kt @@ -0,0 +1,9 @@ +fun foo() { + "start" + open class A {} + class B: A() {} + "end" + + val c = B() + val d = A() +} \ No newline at end of file diff --git a/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/order/twoClasses.kt.after b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/order/twoClasses.kt.after new file mode 100644 index 00000000000..18fa1983766 --- /dev/null +++ b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/order/twoClasses.kt.after @@ -0,0 +1,11 @@ +fun foo() { + open class A {} + class B: A() {} + if () { + "start" + "end" + } + + val c = B() + val d = A() +} \ No newline at end of file diff --git a/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/order/valAndClass.kt b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/order/valAndClass.kt new file mode 100644 index 00000000000..93979140079 --- /dev/null +++ b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/order/valAndClass.kt @@ -0,0 +1,9 @@ +fun foo() { + class A { + fun test() {} + } + val d: A = A() + + d.test() + A() +} \ No newline at end of file diff --git a/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/order/valAndClass.kt.after b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/order/valAndClass.kt.after new file mode 100644 index 00000000000..10a8ef79e67 --- /dev/null +++ b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/order/valAndClass.kt.after @@ -0,0 +1,12 @@ +fun foo() { + class A { + fun test() {} + } + val d: A + if () { + d = A() + } + + d.test() + A() +} \ No newline at end of file diff --git a/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/order/valOrder.kt b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/order/valOrder.kt new file mode 100644 index 00000000000..c286b06540d --- /dev/null +++ b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/order/valOrder.kt @@ -0,0 +1,7 @@ +fun foo() { + val a: String = "aaa" + val b = a + + a.charAt(1) + b.charAt(1) +} diff --git a/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/order/valOrder.kt.after b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/order/valOrder.kt.after new file mode 100644 index 00000000000..bf17f1d8f79 --- /dev/null +++ b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/order/valOrder.kt.after @@ -0,0 +1,11 @@ +fun foo() { + val a: String + val b: String + if () { + a = "aaa" + b = a + } + + a.charAt(1) + b.charAt(1) +} diff --git a/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/val/fullQualifiedType.kt b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/val/fullQualifiedType.kt new file mode 100644 index 00000000000..5b3187de2b2 --- /dev/null +++ b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/val/fullQualifiedType.kt @@ -0,0 +1,5 @@ +fun foo() { + val a: kotlin.test.Asserter? = null + + a?.charAt(1) +} \ No newline at end of file diff --git a/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/val/fullQualifiedType.kt.after b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/val/fullQualifiedType.kt.after new file mode 100644 index 00000000000..946c3be5637 --- /dev/null +++ b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/val/fullQualifiedType.kt.after @@ -0,0 +1,8 @@ +fun foo() { + val a: kotlin.test.Asserter? + if () { + a = null + } + + a?.charAt(1) +} \ No newline at end of file diff --git a/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/val/fullQualifiedTypeWithoutTypeRef.kt b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/val/fullQualifiedTypeWithoutTypeRef.kt new file mode 100644 index 00000000000..7c69bfb68ea --- /dev/null +++ b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/val/fullQualifiedTypeWithoutTypeRef.kt @@ -0,0 +1,9 @@ +package test + +class A {} + +fun foo() { + val a = test.A() + + a.hashCode() +} \ No newline at end of file diff --git a/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/val/fullQualifiedTypeWithoutTypeRef.kt.after b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/val/fullQualifiedTypeWithoutTypeRef.kt.after new file mode 100644 index 00000000000..73b04f16dc9 --- /dev/null +++ b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/val/fullQualifiedTypeWithoutTypeRef.kt.after @@ -0,0 +1,12 @@ +package test + +class A {} + +fun foo() { + val a: A + if () { + a = test.A() + } + + a.hashCode() +} \ No newline at end of file diff --git a/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/val/valWithTypeWithInitializer.kt b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/val/valWithTypeWithInitializer.kt new file mode 100644 index 00000000000..88d39b01373 --- /dev/null +++ b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/val/valWithTypeWithInitializer.kt @@ -0,0 +1,5 @@ +fun foo() { + val a: String = "aaa" + + a.charAt(1) +} diff --git a/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/val/valWithTypeWithInitializer.kt.after b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/val/valWithTypeWithInitializer.kt.after new file mode 100644 index 00000000000..f9be01d644a --- /dev/null +++ b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/val/valWithTypeWithInitializer.kt.after @@ -0,0 +1,8 @@ +fun foo() { + val a: String + if () { + a = "aaa" + } + + a.charAt(1) +} diff --git a/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/val/valWithTypeWoInitializer.kt b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/val/valWithTypeWoInitializer.kt new file mode 100644 index 00000000000..107c154cd5b --- /dev/null +++ b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/val/valWithTypeWoInitializer.kt @@ -0,0 +1,11 @@ +fun foo() { + val a: String + a = "a" + a.capitalize() + val b: String + b = "b" + b.capitalize() + + a.charAt(1) + b.charAt(1) +} diff --git a/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/val/valWithTypeWoInitializer.kt.after b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/val/valWithTypeWoInitializer.kt.after new file mode 100644 index 00000000000..5db8d5d59ea --- /dev/null +++ b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/val/valWithTypeWoInitializer.kt.after @@ -0,0 +1,13 @@ +fun foo() { + val a: String + val b: String + if () { + a = "a" + a.capitalize() + b = "b" + b.capitalize() + } + + a.charAt(1) + b.charAt(1) +} diff --git a/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/val/valWoTypeWithInitializer.kt b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/val/valWoTypeWithInitializer.kt new file mode 100644 index 00000000000..9f23ad3bf58 --- /dev/null +++ b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/val/valWoTypeWithInitializer.kt @@ -0,0 +1,5 @@ +fun foo() { + val a = "aaa" + + a.charAt(1) +} diff --git a/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/val/valWoTypeWithInitializer.kt.after b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/val/valWoTypeWithInitializer.kt.after new file mode 100644 index 00000000000..f9be01d644a --- /dev/null +++ b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/val/valWoTypeWithInitializer.kt.after @@ -0,0 +1,8 @@ +fun foo() { + val a: String + if () { + a = "aaa" + } + + a.charAt(1) +} diff --git a/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/defaultValue/boolean.kt b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/defaultValue/boolean.kt new file mode 100644 index 00000000000..91e58e141e4 --- /dev/null +++ b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/defaultValue/boolean.kt @@ -0,0 +1,4 @@ +fun foo() { + var a: Boolean = true + a = true +} \ No newline at end of file diff --git a/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/defaultValue/boolean.kt.after b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/defaultValue/boolean.kt.after new file mode 100644 index 00000000000..5cebb06fe79 --- /dev/null +++ b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/defaultValue/boolean.kt.after @@ -0,0 +1,7 @@ +fun foo() { + var a: Boolean = false + if () { + a = true + } + a = true +} \ No newline at end of file diff --git a/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/defaultValue/nullable.kt b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/defaultValue/nullable.kt new file mode 100644 index 00000000000..8c56e3c7771 --- /dev/null +++ b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/defaultValue/nullable.kt @@ -0,0 +1,4 @@ +fun foo() { + var a: String? = "aaa" + a = "bbb" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/defaultValue/nullable.kt.after b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/defaultValue/nullable.kt.after new file mode 100644 index 00000000000..b6b1166c945 --- /dev/null +++ b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/defaultValue/nullable.kt.after @@ -0,0 +1,7 @@ +fun foo() { + var a: String? = null + if () { + a = "aaa" + } + a = "bbb" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/defaultValue/primitiveNumbers.kt b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/defaultValue/primitiveNumbers.kt new file mode 100644 index 00000000000..b4ff1ad98f1 --- /dev/null +++ b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/defaultValue/primitiveNumbers.kt @@ -0,0 +1,16 @@ +fun foo() { + var a: Int = 1 + var b: Char = 1 + var c: Byte = 1 + var d: Long = 1 + var e: Short = 1 + var f: Double = 1 + var g: Float = 1 + a = 2 + b = 2 + c = 2 + d = 2 + e = 2 + f = 2 + g = 2 +} \ No newline at end of file diff --git a/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/defaultValue/primitiveNumbers.kt.after b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/defaultValue/primitiveNumbers.kt.after new file mode 100644 index 00000000000..15a12edf8d4 --- /dev/null +++ b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/defaultValue/primitiveNumbers.kt.after @@ -0,0 +1,25 @@ +fun foo() { + var a: Int = 0 + var b: Char = 0 + var c: Byte = 0 + var d: Long = 0 + var e: Short = 0 + var f: Double = 0 + var g: Float = 0 + if () { + a = 1 + b = 1 + c = 1 + d = 1 + e = 1 + f = 1 + g = 1 + } + a = 2 + b = 2 + c = 2 + d = 2 + e = 2 + f = 2 + g = 2 +} \ No newline at end of file diff --git a/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/varWithNotNullableTypeWithInitializer.kt b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/varWithNotNullableTypeWithInitializer.kt new file mode 100644 index 00000000000..f7703c59a29 --- /dev/null +++ b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/varWithNotNullableTypeWithInitializer.kt @@ -0,0 +1,5 @@ +fun foo() { + var a: String = "aaa" + + a.charAt(1) +} diff --git a/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/varWithNotNullableTypeWithInitializer.kt.after b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/varWithNotNullableTypeWithInitializer.kt.after new file mode 100644 index 00000000000..2427f7e20cf --- /dev/null +++ b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/varWithNotNullableTypeWithInitializer.kt.after @@ -0,0 +1,8 @@ +fun foo() { + var a: String + if () { + a = "aaa" + } + + a.charAt(1) +} diff --git a/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/varWithTypeWoInitializer.kt b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/varWithTypeWoInitializer.kt new file mode 100644 index 00000000000..b9404e5ff42 --- /dev/null +++ b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/varWithTypeWoInitializer.kt @@ -0,0 +1,6 @@ +fun foo() { + var a: String + a.capitalize() + + a.charAt(1) +} diff --git a/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/varWithTypeWoInitializer.kt.after b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/varWithTypeWoInitializer.kt.after new file mode 100644 index 00000000000..fabe6af63a8 --- /dev/null +++ b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/varWithTypeWoInitializer.kt.after @@ -0,0 +1,8 @@ +fun foo() { + var a: String + if () { + a.capitalize() + } + + a.charAt(1) +} diff --git a/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/varWoTypeWithInitializer.kt b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/varWoTypeWithInitializer.kt new file mode 100644 index 00000000000..aeafe9edf8d --- /dev/null +++ b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/varWoTypeWithInitializer.kt @@ -0,0 +1,5 @@ +fun foo() { + var a = "aaa" + + a.charAt(1) +} diff --git a/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/varWoTypeWithInitializer.kt.after b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/varWoTypeWithInitializer.kt.after new file mode 100644 index 00000000000..2427f7e20cf --- /dev/null +++ b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/varWoTypeWithInitializer.kt.after @@ -0,0 +1,8 @@ +fun foo() { + var a: String + if () { + a = "aaa" + } + + a.charAt(1) +} diff --git a/idea/testData/codeInsight/surroundWith/ifElse/moveDeclarationsOutVal.kt b/idea/testData/codeInsight/surroundWith/ifElse/moveDeclarationsOutVal.kt new file mode 100644 index 00000000000..417a42ec090 --- /dev/null +++ b/idea/testData/codeInsight/surroundWith/ifElse/moveDeclarationsOutVal.kt @@ -0,0 +1,4 @@ +fun foo() { + val a: String? = "aaa" + a.toString() +} \ No newline at end of file diff --git a/idea/testData/codeInsight/surroundWith/ifElse/moveDeclarationsOutVal.kt.after b/idea/testData/codeInsight/surroundWith/ifElse/moveDeclarationsOutVal.kt.after new file mode 100644 index 00000000000..4168020cbe3 --- /dev/null +++ b/idea/testData/codeInsight/surroundWith/ifElse/moveDeclarationsOutVal.kt.after @@ -0,0 +1,8 @@ +fun foo() { + val a: String? + if () { + a = "aaa" + } else { + } + a.toString() +} \ No newline at end of file diff --git a/idea/testData/codeInsight/surroundWith/ifElse/moveDeclarationsOutVar.kt b/idea/testData/codeInsight/surroundWith/ifElse/moveDeclarationsOutVar.kt new file mode 100644 index 00000000000..8c56e3c7771 --- /dev/null +++ b/idea/testData/codeInsight/surroundWith/ifElse/moveDeclarationsOutVar.kt @@ -0,0 +1,4 @@ +fun foo() { + var a: String? = "aaa" + a = "bbb" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/surroundWith/ifElse/moveDeclarationsOutVar.kt.after b/idea/testData/codeInsight/surroundWith/ifElse/moveDeclarationsOutVar.kt.after new file mode 100644 index 00000000000..9de6df4a8bf --- /dev/null +++ b/idea/testData/codeInsight/surroundWith/ifElse/moveDeclarationsOutVar.kt.after @@ -0,0 +1,8 @@ +fun foo() { + var a: String? + if () { + a = "aaa" + } else { + } + a = "bbb" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/surroundWith/tryCatch/moveDeclarationsOut.kt b/idea/testData/codeInsight/surroundWith/tryCatch/moveDeclarationsOut.kt new file mode 100644 index 00000000000..04667c1e267 --- /dev/null +++ b/idea/testData/codeInsight/surroundWith/tryCatch/moveDeclarationsOut.kt @@ -0,0 +1,7 @@ +fun foo() { + val a = "aaa" + val b = "aaa" + + a.charAt(1) + b.charAt(1) +} \ No newline at end of file diff --git a/idea/testData/codeInsight/surroundWith/tryCatch/moveDeclarationsOut.kt.after b/idea/testData/codeInsight/surroundWith/tryCatch/moveDeclarationsOut.kt.after new file mode 100644 index 00000000000..5a533b6b302 --- /dev/null +++ b/idea/testData/codeInsight/surroundWith/tryCatch/moveDeclarationsOut.kt.after @@ -0,0 +1,12 @@ +fun foo() { + val a: String + val b: String + try { + a = "aaa" + b = "aaa" + } catch(e: Exception) { + } + + a.charAt(1) + b.charAt(1) +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/plugin/codeInsight/surroundWith/SurroundWithTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/codeInsight/surroundWith/SurroundWithTestGenerated.java index 787d0fde601..27ad822efb3 100644 --- a/idea/tests/org/jetbrains/jet/plugin/codeInsight/surroundWith/SurroundWithTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/codeInsight/surroundWith/SurroundWithTestGenerated.java @@ -33,6 +33,7 @@ import org.jetbrains.jet.plugin.codeInsight.surroundWith.AbstractSurroundWithTes @InnerTestClasses({SurroundWithTestGenerated.If.class, SurroundWithTestGenerated.IfElse.class, SurroundWithTestGenerated.Not.class, SurroundWithTestGenerated.Parentheses.class, SurroundWithTestGenerated.StringTemplate.class, SurroundWithTestGenerated.When.class, SurroundWithTestGenerated.TryCatch.class, SurroundWithTestGenerated.TryCatchFinally.class, SurroundWithTestGenerated.TryFinally.class, SurroundWithTestGenerated.FunctionLiteral.class}) public class SurroundWithTestGenerated extends AbstractSurroundWithTest { @TestMetadata("idea/testData/codeInsight/surroundWith/if") + @InnerTestClasses({If.MoveDeclarationsOut.class}) public static class If extends AbstractSurroundWithTest { public void testAllFilesPresentInIf() throws Exception { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/surroundWith/if"), Pattern.compile("^(.+)\\.kt$"), true); @@ -63,6 +64,195 @@ public class SurroundWithTestGenerated extends AbstractSurroundWithTest { doTestWithIfSurrounder("idea/testData/codeInsight/surroundWith/if/variable.kt"); } + @TestMetadata("idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut") + @InnerTestClasses({MoveDeclarationsOut.Class.class, MoveDeclarationsOut.Function.class, MoveDeclarationsOut.Object.class, MoveDeclarationsOut.Order.class, MoveDeclarationsOut.Val.class, MoveDeclarationsOut.Var.class}) + public static class MoveDeclarationsOut extends AbstractSurroundWithTest { + public void testAllFilesPresentInMoveDeclarationsOut() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/class") + public static class Class extends AbstractSurroundWithTest { + public void testAllFilesPresentInClass() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/class"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("classInType.kt") + public void testClassInType() throws Exception { + doTestWithIfSurrounder("idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/class/classInType.kt"); + } + + @TestMetadata("localClass.kt") + public void testLocalClass() throws Exception { + doTestWithIfSurrounder("idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/class/localClass.kt"); + } + + } + + @TestMetadata("idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/function") + public static class Function extends AbstractSurroundWithTest { + public void testAllFilesPresentInFunction() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/function"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("firstChildLocalFun.kt") + public void testFirstChildLocalFun() throws Exception { + doTestWithIfSurrounder("idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/function/firstChildLocalFun.kt"); + } + + @TestMetadata("localFun.kt") + public void testLocalFun() throws Exception { + doTestWithIfSurrounder("idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/function/localFun.kt"); + } + + @TestMetadata("unusedLocalFun.kt") + public void testUnusedLocalFun() throws Exception { + doTestWithIfSurrounder("idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/function/unusedLocalFun.kt"); + } + + } + + @TestMetadata("idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/object") + public static class Object extends AbstractSurroundWithTest { + public void testAllFilesPresentInObject() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/object"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("localObject.kt") + public void testLocalObject() throws Exception { + doTestWithIfSurrounder("idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/object/localObject.kt"); + } + + } + + @TestMetadata("idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/order") + public static class Order extends AbstractSurroundWithTest { + public void testAllFilesPresentInOrder() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/order"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("twoClasses.kt") + public void testTwoClasses() throws Exception { + doTestWithIfSurrounder("idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/order/twoClasses.kt"); + } + + @TestMetadata("valAndClass.kt") + public void testValAndClass() throws Exception { + doTestWithIfSurrounder("idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/order/valAndClass.kt"); + } + + @TestMetadata("valOrder.kt") + public void testValOrder() throws Exception { + doTestWithIfSurrounder("idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/order/valOrder.kt"); + } + + } + + @TestMetadata("idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/val") + public static class Val extends AbstractSurroundWithTest { + public void testAllFilesPresentInVal() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/val"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("fullQualifiedType.kt") + public void testFullQualifiedType() throws Exception { + doTestWithIfSurrounder("idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/val/fullQualifiedType.kt"); + } + + @TestMetadata("fullQualifiedTypeWithoutTypeRef.kt") + public void testFullQualifiedTypeWithoutTypeRef() throws Exception { + doTestWithIfSurrounder("idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/val/fullQualifiedTypeWithoutTypeRef.kt"); + } + + @TestMetadata("valWithTypeWithInitializer.kt") + public void testValWithTypeWithInitializer() throws Exception { + doTestWithIfSurrounder("idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/val/valWithTypeWithInitializer.kt"); + } + + @TestMetadata("valWithTypeWoInitializer.kt") + public void testValWithTypeWoInitializer() throws Exception { + doTestWithIfSurrounder("idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/val/valWithTypeWoInitializer.kt"); + } + + @TestMetadata("valWoTypeWithInitializer.kt") + public void testValWoTypeWithInitializer() throws Exception { + doTestWithIfSurrounder("idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/val/valWoTypeWithInitializer.kt"); + } + + } + + @TestMetadata("idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var") + @InnerTestClasses({Var.DefaultValue.class}) + public static class Var extends AbstractSurroundWithTest { + public void testAllFilesPresentInVar() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("varWithNotNullableTypeWithInitializer.kt") + public void testVarWithNotNullableTypeWithInitializer() throws Exception { + doTestWithIfSurrounder("idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/varWithNotNullableTypeWithInitializer.kt"); + } + + @TestMetadata("varWithTypeWoInitializer.kt") + public void testVarWithTypeWoInitializer() throws Exception { + doTestWithIfSurrounder("idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/varWithTypeWoInitializer.kt"); + } + + @TestMetadata("varWoTypeWithInitializer.kt") + public void testVarWoTypeWithInitializer() throws Exception { + doTestWithIfSurrounder("idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/varWoTypeWithInitializer.kt"); + } + + @TestMetadata("idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/defaultValue") + public static class DefaultValue extends AbstractSurroundWithTest { + public void testAllFilesPresentInDefaultValue() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/defaultValue"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("boolean.kt") + public void testBoolean() throws Exception { + doTestWithIfSurrounder("idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/defaultValue/boolean.kt"); + } + + @TestMetadata("nullable.kt") + public void testNullable() throws Exception { + doTestWithIfSurrounder("idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/defaultValue/nullable.kt"); + } + + @TestMetadata("primitiveNumbers.kt") + public void testPrimitiveNumbers() throws Exception { + doTestWithIfSurrounder("idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/defaultValue/primitiveNumbers.kt"); + } + + } + + public static Test innerSuite() { + TestSuite suite = new TestSuite("Var"); + suite.addTestSuite(Var.class); + suite.addTestSuite(DefaultValue.class); + return suite; + } + } + + public static Test innerSuite() { + TestSuite suite = new TestSuite("MoveDeclarationsOut"); + suite.addTestSuite(MoveDeclarationsOut.class); + suite.addTestSuite(Class.class); + suite.addTestSuite(Function.class); + suite.addTestSuite(Object.class); + suite.addTestSuite(Order.class); + suite.addTestSuite(Val.class); + suite.addTest(Var.innerSuite()); + return suite; + } + } + + public static Test innerSuite() { + TestSuite suite = new TestSuite("If"); + suite.addTestSuite(If.class); + suite.addTest(MoveDeclarationsOut.innerSuite()); + return suite; + } } @TestMetadata("idea/testData/codeInsight/surroundWith/ifElse") @@ -76,6 +266,16 @@ public class SurroundWithTestGenerated extends AbstractSurroundWithTest { doTestWithIfElseSurrounder("idea/testData/codeInsight/surroundWith/ifElse/block.kt"); } + @TestMetadata("moveDeclarationsOutVal.kt") + public void testMoveDeclarationsOutVal() throws Exception { + doTestWithIfElseSurrounder("idea/testData/codeInsight/surroundWith/ifElse/moveDeclarationsOutVal.kt"); + } + + @TestMetadata("moveDeclarationsOutVar.kt") + public void testMoveDeclarationsOutVar() throws Exception { + doTestWithIfElseSurrounder("idea/testData/codeInsight/surroundWith/ifElse/moveDeclarationsOutVar.kt"); + } + @TestMetadata("severalStatements.kt") public void testSeveralStatements() throws Exception { doTestWithIfElseSurrounder("idea/testData/codeInsight/surroundWith/ifElse/severalStatements.kt"); @@ -281,6 +481,11 @@ public class SurroundWithTestGenerated extends AbstractSurroundWithTest { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/surroundWith/tryCatch"), Pattern.compile("^(.+)\\.kt$"), true); } + @TestMetadata("moveDeclarationsOut.kt") + public void testMoveDeclarationsOut() throws Exception { + doTestWithTryCatchSurrounder("idea/testData/codeInsight/surroundWith/tryCatch/moveDeclarationsOut.kt"); + } + @TestMetadata("multiExpression.kt") public void testMultiExpression() throws Exception { doTestWithTryCatchSurrounder("idea/testData/codeInsight/surroundWith/tryCatch/multiExpression.kt"); @@ -335,6 +540,11 @@ public class SurroundWithTestGenerated extends AbstractSurroundWithTest { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/surroundWith/functionLiteral"), Pattern.compile("^(.+)\\.kt$"), true); } + @TestMetadata("moveDeclarationsOut.kt") + public void testMoveDeclarationsOut() throws Exception { + doTestWithFunctionLiteralSurrounder("idea/testData/codeInsight/surroundWith/functionLiteral/moveDeclarationsOut.kt"); + } + @TestMetadata("multiStatement.kt") public void testMultiStatement() throws Exception { doTestWithFunctionLiteralSurrounder("idea/testData/codeInsight/surroundWith/functionLiteral/multiStatement.kt"); @@ -349,7 +559,7 @@ public class SurroundWithTestGenerated extends AbstractSurroundWithTest { public static Test suite() { TestSuite suite = new TestSuite("SurroundWithTestGenerated"); - suite.addTestSuite(If.class); + suite.addTest(If.innerSuite()); suite.addTestSuite(IfElse.class); suite.addTestSuite(Not.class); suite.addTest(Parentheses.innerSuite());