diff --git a/idea/src/org/jetbrains/kotlin/idea/codeInsight/surroundWith/MoveDeclarationsOutHelper.kt b/idea/src/org/jetbrains/kotlin/idea/codeInsight/surroundWith/MoveDeclarationsOutHelper.kt index 12048146225..ee23d664826 100644 --- a/idea/src/org/jetbrains/kotlin/idea/codeInsight/surroundWith/MoveDeclarationsOutHelper.kt +++ b/idea/src/org/jetbrains/kotlin/idea/codeInsight/surroundWith/MoveDeclarationsOutHelper.kt @@ -14,143 +14,122 @@ * limitations under the License. */ -package org.jetbrains.kotlin.idea.codeInsight.surroundWith; +package org.jetbrains.kotlin.idea.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.kotlin.descriptors.VariableDescriptor; -import org.jetbrains.kotlin.idea.caches.resolve.ResolutionUtils; -import org.jetbrains.kotlin.idea.codeInsight.CodeInsightUtils; -import org.jetbrains.kotlin.idea.core.ShortenReferences; -import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers; -import org.jetbrains.kotlin.psi.*; -import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode; -import org.jetbrains.kotlin.types.KotlinType; -import org.jetbrains.kotlin.types.KotlinTypeKt; +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.kotlin.idea.caches.resolve.resolveToDescriptorIfAny +import org.jetbrains.kotlin.idea.codeInsight.CodeInsightUtils +import org.jetbrains.kotlin.idea.core.ShortenReferences +import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers +import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode +import org.jetbrains.kotlin.types.KotlinType +import org.jetbrains.kotlin.types.isError +import java.util.* -import java.util.ArrayList; -import java.util.List; - -public class MoveDeclarationsOutHelper { - - public static PsiElement[] move(@NotNull PsiElement container, @NotNull PsiElement[] statements, boolean generateDefaultInitializers) { - if (statements.length == 0) { - return statements; +object MoveDeclarationsOutHelper { + fun move(container: PsiElement, statements: Array, generateDefaultInitializers: Boolean): Array { + if (statements.isEmpty()) { + return statements } - Project project = container.getProject(); + val project = container.project - List resultStatements = new ArrayList(); - List propertiesDeclarations = new ArrayList(); + val resultStatements = ArrayList() + val propertiesDeclarations = ArrayList() // Dummy element to add new declarations at the beginning - KtPsiFactory psiFactory = KtPsiFactoryKt.KtPsiFactory(project); - PsiElement dummyFirstStatement = container.addBefore(psiFactory.createExpression("dummyStatement"), statements[0]); + val psiFactory = KtPsiFactory(project) + val dummyFirstStatement = container.addBefore(psiFactory.createExpression("dummyStatement"), statements[0]) try { - SearchScope scope = new LocalSearchScope(container); - int lastStatementOffset = statements[statements.length - 1].getTextRange().getEndOffset(); + val scope = LocalSearchScope(container) + val lastStatementOffset = statements[statements.size - 1].textRange.endOffset - for (PsiElement statement : statements) { + for (statement in statements) { if (needToDeclareOut(statement, lastStatementOffset, scope)) { - if (statement instanceof KtProperty && ((KtProperty) statement).getInitializer() != null) { - KtProperty property = (KtProperty) statement; - KtProperty declaration = createVariableDeclaration(property, generateDefaultInitializers); - declaration = (KtProperty) container.addBefore(declaration, dummyFirstStatement); - propertiesDeclarations.add(declaration); - container.addAfter(psiFactory.createNewLine(), declaration); + val property = statement as? KtProperty + if (property?.initializer != null) { + var declaration = createVariableDeclaration(property, generateDefaultInitializers) + declaration = container.addBefore(declaration, dummyFirstStatement) as KtProperty + propertiesDeclarations.add(declaration) + container.addAfter(psiFactory.createNewLine(), declaration) - KtBinaryExpression assignment = createVariableAssignment(property); - resultStatements.add(property.replace(assignment)); + val assignment = createVariableAssignment(property) + resultStatements.add(property.replace(assignment)) + } else { + val newStatement = container.addBefore(statement, dummyFirstStatement) + container.addAfter(psiFactory.createNewLine(), newStatement) + container.deleteChildRange(statement, statement) } - else { - PsiElement newStatement = container.addBefore(statement, dummyFirstStatement); - container.addAfter(psiFactory.createNewLine(), newStatement); - container.deleteChildRange(statement, statement); - } - } - else { - resultStatements.add(statement); + } else { + resultStatements.add(statement) } } - } - finally { - dummyFirstStatement.delete(); + } finally { + dummyFirstStatement.delete() } - ShortenReferences.DEFAULT.process(propertiesDeclarations); + ShortenReferences.DEFAULT.process(propertiesDeclarations) - return PsiUtilCore.toPsiElementArray(resultStatements); + return PsiUtilCore.toPsiElementArray(resultStatements) } - @NotNull - private static KtBinaryExpression createVariableAssignment(@NotNull KtProperty property) { - String propertyName = property.getName(); - assert propertyName != null : "Property should have a name " + property.getText(); - KtBinaryExpression assignment = (KtBinaryExpression) KtPsiFactoryKt - .KtPsiFactory(property).createExpression(propertyName + " = x"); - KtExpression right = assignment.getRight(); - assert right != null : "Created binary expression should have a right part " + assignment.getText(); - KtExpression initializer = property.getInitializer(); - assert initializer != null : "Initializer should exist for property " + property.getText(); - right.replace(initializer); - return assignment; + private fun createVariableAssignment(property: KtProperty): KtBinaryExpression { + val propertyName = property.name ?: error("Property should have a name " + property.text) + val assignment = KtPsiFactory(property).createExpression("$propertyName = x") as KtBinaryExpression + val right = assignment.right ?: error("Created binary expression should have a right part " + assignment.text) + val initializer = property.initializer ?: error("Initializer should exist for property " + property.text) + right.replace(initializer) + return assignment } - @NotNull - private static KtProperty createVariableDeclaration(@NotNull KtProperty property, boolean generateDefaultInitializers) { - KotlinType propertyType = getPropertyType(property); - String defaultInitializer = null; - if (generateDefaultInitializers && property.isVar()) { - defaultInitializer = CodeInsightUtils.defaultInitializer(propertyType); + private fun createVariableDeclaration(property: KtProperty, generateDefaultInitializers: Boolean): KtProperty { + val propertyType = getPropertyType(property) + var defaultInitializer: String? = null + if (generateDefaultInitializers && property.isVar) { + defaultInitializer = CodeInsightUtils.defaultInitializer(propertyType) } - return createProperty(property, propertyType, defaultInitializer); + return createProperty(property, propertyType, defaultInitializer) } - @NotNull - private static KotlinType getPropertyType(@NotNull KtProperty property) { - VariableDescriptor variableDescriptor = ResolutionUtils.resolveToDescriptorIfAny(property, BodyResolveMode.PARTIAL); - assert variableDescriptor != null : "Couldn't resolve property to property descriptor " + property.getText(); - return variableDescriptor.getType(); + private fun getPropertyType(property: KtProperty): KotlinType { + val variableDescriptor = property.resolveToDescriptorIfAny(BodyResolveMode.PARTIAL) + ?: error("Couldn't resolve property to property descriptor " + property.text) + return variableDescriptor.type } - @NotNull - private static KtProperty createProperty(@NotNull KtProperty property, @NotNull KotlinType propertyType, @Nullable String initializer) { - KtTypeReference typeRef = property.getTypeReference(); - String typeString = null; + private fun createProperty(property: KtProperty, propertyType: KotlinType, initializer: String?): KtProperty { + val typeRef = property.typeReference + var typeString: String? = null if (typeRef != null) { - typeString = typeRef.getText(); - } - else if (!KotlinTypeKt.isError(propertyType)) { - typeString = IdeDescriptorRenderers.SOURCE_CODE.renderType(propertyType); + typeString = typeRef.text + } else if (!propertyType.isError) { + typeString = IdeDescriptorRenderers.SOURCE_CODE.renderType(propertyType) } - return KtPsiFactoryKt.KtPsiFactory(property).createProperty(property.getName(), typeString, property.isVar(), initializer); + return KtPsiFactory(property).createProperty(property.name!!, typeString, property.isVar, initializer) } - private static boolean needToDeclareOut(@NotNull PsiElement element, int lastStatementOffset, @NotNull SearchScope scope) { - if (element instanceof KtProperty || - element instanceof KtClassOrObject || - element instanceof KtFunction) { - - 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; + private fun needToDeclareOut(element: PsiElement, lastStatementOffset: Int, scope: SearchScope): Boolean { + if (element is KtProperty || + element is KtClassOrObject || + element is KtFunction + ) { + val refs = ReferencesSearch.search(element, scope, false).toArray(PsiReference.EMPTY_ARRAY) + if (refs.isNotEmpty()) { + val lastRef = refs[refs.size - 1] + if (lastRef.element.textOffset > lastStatementOffset) { + return true } } } - return false; - } - private MoveDeclarationsOutHelper() { + return false } } diff --git a/idea/src/org/jetbrains/kotlin/idea/codeInsight/surroundWith/statement/KotlinFunctionLiteralSurrounder.java b/idea/src/org/jetbrains/kotlin/idea/codeInsight/surroundWith/statement/KotlinFunctionLiteralSurrounder.java index 6388efa20c4..4629c6858a3 100644 --- a/idea/src/org/jetbrains/kotlin/idea/codeInsight/surroundWith/statement/KotlinFunctionLiteralSurrounder.java +++ b/idea/src/org/jetbrains/kotlin/idea/codeInsight/surroundWith/statement/KotlinFunctionLiteralSurrounder.java @@ -31,7 +31,7 @@ public class KotlinFunctionLiteralSurrounder extends KotlinStatementsSurrounder @Nullable @Override protected TextRange surroundStatements(Project project, Editor editor, PsiElement container, PsiElement[] statements) { - statements = MoveDeclarationsOutHelper.move(container, statements, true); + statements = MoveDeclarationsOutHelper.INSTANCE.move(container, statements, true); if (statements.length == 0) { KotlinSurrounderUtils.showErrorHint(project, editor, KotlinSurrounderUtils.SURROUND_WITH_ERROR); diff --git a/idea/src/org/jetbrains/kotlin/idea/codeInsight/surroundWith/statement/KotlinIfSurrounderBase.java b/idea/src/org/jetbrains/kotlin/idea/codeInsight/surroundWith/statement/KotlinIfSurrounderBase.java index 0b9fabf9f77..c6ae6d716f4 100644 --- a/idea/src/org/jetbrains/kotlin/idea/codeInsight/surroundWith/statement/KotlinIfSurrounderBase.java +++ b/idea/src/org/jetbrains/kotlin/idea/codeInsight/surroundWith/statement/KotlinIfSurrounderBase.java @@ -41,7 +41,7 @@ public abstract class KotlinIfSurrounderBase extends KotlinStatementsSurrounder @Nullable @Override protected TextRange surroundStatements(Project project, Editor editor, PsiElement container, PsiElement[] statements) { - statements = MoveDeclarationsOutHelper.move(container, statements, isGenerateDefaultInitializers()); + statements = MoveDeclarationsOutHelper.INSTANCE.move(container, statements, isGenerateDefaultInitializers()); if (statements.length == 0) { KotlinSurrounderUtils.showErrorHint(project, editor, KotlinSurrounderUtils.SURROUND_WITH_ERROR); diff --git a/idea/src/org/jetbrains/kotlin/idea/codeInsight/surroundWith/statement/KotlinTrySurrounderBase.java b/idea/src/org/jetbrains/kotlin/idea/codeInsight/surroundWith/statement/KotlinTrySurrounderBase.java index d472aaf4cf3..d6ac0936551 100644 --- a/idea/src/org/jetbrains/kotlin/idea/codeInsight/surroundWith/statement/KotlinTrySurrounderBase.java +++ b/idea/src/org/jetbrains/kotlin/idea/codeInsight/surroundWith/statement/KotlinTrySurrounderBase.java @@ -37,7 +37,7 @@ public abstract class KotlinTrySurrounderBase extends KotlinStatementsSurrounder @Nullable @Override protected TextRange surroundStatements(@NotNull Project project, @NotNull Editor editor, @NotNull PsiElement container, @NotNull PsiElement[] statements) { - statements = MoveDeclarationsOutHelper.move(container, statements, true); + statements = MoveDeclarationsOutHelper.INSTANCE.move(container, statements, true); if (statements.length == 0) { KotlinSurrounderUtils.showErrorHint(project, editor, KotlinSurrounderUtils.SURROUND_WITH_ERROR);