From 2d90ee5cad40e2059e46a3a1e0999ee2e086d0b6 Mon Sep 17 00:00:00 2001 From: Valentin Kipyatkov Date: Tue, 5 May 2015 14:45:52 +0300 Subject: [PATCH] Split SpecifyTypeExplicitly intention into two + refactored them completely --- .../after.kt.template} | 0 .../before.kt.template} | 0 .../description.html | 5 + .../description.html | 5 - .../after.kt.template | 3 + .../before.kt.template | 3 + .../description.html | 5 + idea/src/META-INF/plugin.xml | 7 +- .../intentions/RemoveExplicitTypeIntention.kt | 60 ++++++ .../intentions/SpecifyTypeExplicitlyAction.kt | 186 ------------------ .../SpecifyTypeExplicitlyIntention.kt | 134 +++++++++++++ .../quickfix/RemovePartsFromPropertyFix.java | 4 +- .../quickfix/SpecifyTypeExplicitlyFix.java | 8 +- .../KotlinInplaceVariableIntroducer.java | 6 +- .../intentions/removeExplicitType/.intention | 1 + .../onType.kt | 0 .../onType.kt.after | 0 .../removeUnresolvedType.kt | 0 .../removeUnresolvedType.kt.after | 0 .../intentions/specifyType/.intention | 2 +- .../specifyType/typeAlreadyProvided.kt | 1 + .../specifyType/typeAlreadyProvided.kt.after | 1 - .../classGroovyTypeReceiver.before.Main.kt | 1 + .../enumEntryJavaEnumReceiver.before.Main.kt | 1 + .../intentions/IntentionTestGenerated.java | 33 ++-- 25 files changed, 251 insertions(+), 215 deletions(-) rename idea/resources/intentionDescriptions/{SpecifyTypeExplicitlyAction/before.kt.template => RemoveExplicitTypeIntention/after.kt.template} (100%) rename idea/resources/intentionDescriptions/{SpecifyTypeExplicitlyAction/after.kt.template => RemoveExplicitTypeIntention/before.kt.template} (100%) create mode 100644 idea/resources/intentionDescriptions/RemoveExplicitTypeIntention/description.html delete mode 100644 idea/resources/intentionDescriptions/SpecifyTypeExplicitlyAction/description.html create mode 100644 idea/resources/intentionDescriptions/SpecifyTypeExplicitlyIntention/after.kt.template create mode 100644 idea/resources/intentionDescriptions/SpecifyTypeExplicitlyIntention/before.kt.template create mode 100644 idea/resources/intentionDescriptions/SpecifyTypeExplicitlyIntention/description.html create mode 100644 idea/src/org/jetbrains/kotlin/idea/intentions/RemoveExplicitTypeIntention.kt delete mode 100644 idea/src/org/jetbrains/kotlin/idea/intentions/SpecifyTypeExplicitlyAction.kt create mode 100644 idea/src/org/jetbrains/kotlin/idea/intentions/SpecifyTypeExplicitlyIntention.kt create mode 100644 idea/testData/intentions/removeExplicitType/.intention rename idea/testData/intentions/{specifyType => removeExplicitType}/onType.kt (100%) rename idea/testData/intentions/{specifyType => removeExplicitType}/onType.kt.after (100%) rename idea/testData/intentions/{specifyType => removeExplicitType}/removeUnresolvedType.kt (100%) rename idea/testData/intentions/{specifyType => removeExplicitType}/removeUnresolvedType.kt.after (100%) delete mode 100644 idea/testData/intentions/specifyType/typeAlreadyProvided.kt.after diff --git a/idea/resources/intentionDescriptions/SpecifyTypeExplicitlyAction/before.kt.template b/idea/resources/intentionDescriptions/RemoveExplicitTypeIntention/after.kt.template similarity index 100% rename from idea/resources/intentionDescriptions/SpecifyTypeExplicitlyAction/before.kt.template rename to idea/resources/intentionDescriptions/RemoveExplicitTypeIntention/after.kt.template diff --git a/idea/resources/intentionDescriptions/SpecifyTypeExplicitlyAction/after.kt.template b/idea/resources/intentionDescriptions/RemoveExplicitTypeIntention/before.kt.template similarity index 100% rename from idea/resources/intentionDescriptions/SpecifyTypeExplicitlyAction/after.kt.template rename to idea/resources/intentionDescriptions/RemoveExplicitTypeIntention/before.kt.template diff --git a/idea/resources/intentionDescriptions/RemoveExplicitTypeIntention/description.html b/idea/resources/intentionDescriptions/RemoveExplicitTypeIntention/description.html new file mode 100644 index 00000000000..689bfae2280 --- /dev/null +++ b/idea/resources/intentionDescriptions/RemoveExplicitTypeIntention/description.html @@ -0,0 +1,5 @@ + + +This intention removes explicit type specification for local values, variables, properties and functions. + + \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/SpecifyTypeExplicitlyAction/description.html b/idea/resources/intentionDescriptions/SpecifyTypeExplicitlyAction/description.html deleted file mode 100644 index 60e767f56aa..00000000000 --- a/idea/resources/intentionDescriptions/SpecifyTypeExplicitlyAction/description.html +++ /dev/null @@ -1,5 +0,0 @@ - - -This intention adds or removes explicit type specification for local values, variables and properties. - - \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/SpecifyTypeExplicitlyIntention/after.kt.template b/idea/resources/intentionDescriptions/SpecifyTypeExplicitlyIntention/after.kt.template new file mode 100644 index 00000000000..d59bae419ce --- /dev/null +++ b/idea/resources/intentionDescriptions/SpecifyTypeExplicitlyIntention/after.kt.template @@ -0,0 +1,3 @@ +fun main() { + val a : Array = array(1, 2, 3) +} \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/SpecifyTypeExplicitlyIntention/before.kt.template b/idea/resources/intentionDescriptions/SpecifyTypeExplicitlyIntention/before.kt.template new file mode 100644 index 00000000000..747b9a65230 --- /dev/null +++ b/idea/resources/intentionDescriptions/SpecifyTypeExplicitlyIntention/before.kt.template @@ -0,0 +1,3 @@ +fun main() { + val a = array(1, 2, 3) +} \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/SpecifyTypeExplicitlyIntention/description.html b/idea/resources/intentionDescriptions/SpecifyTypeExplicitlyIntention/description.html new file mode 100644 index 00000000000..66a77cb1c21 --- /dev/null +++ b/idea/resources/intentionDescriptions/SpecifyTypeExplicitlyIntention/description.html @@ -0,0 +1,5 @@ + + +This intention adds explicit type specification for local values, variables, properties and functions. + + \ No newline at end of file diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index c382a5760c6..aa59c84dd27 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -506,7 +506,12 @@ - org.jetbrains.kotlin.idea.intentions.SpecifyTypeExplicitlyAction + org.jetbrains.kotlin.idea.intentions.SpecifyTypeExplicitlyIntention + Kotlin + + + + org.jetbrains.kotlin.idea.intentions.RemoveExplicitTypeIntention Kotlin diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveExplicitTypeIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveExplicitTypeIntention.kt new file mode 100644 index 00000000000..81497cc9d09 --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveExplicitTypeIntention.kt @@ -0,0 +1,60 @@ +/* + * Copyright 2010-2015 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.kotlin.idea.intentions + +import com.intellij.codeInsight.template.* +import com.intellij.openapi.editor.Editor +import com.intellij.psi.PsiDocumentManager +import com.intellij.psi.PsiElement +import org.jetbrains.kotlin.builtins.KotlinBuiltIns +import org.jetbrains.kotlin.descriptors.CallableDescriptor +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor +import org.jetbrains.kotlin.diagnostics.Errors +import org.jetbrains.kotlin.idea.JetBundle +import org.jetbrains.kotlin.idea.caches.resolve.analyzeFully +import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers +import org.jetbrains.kotlin.idea.util.ShortenReferences +import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext +import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.resolve.DescriptorUtils +import org.jetbrains.kotlin.types.ErrorUtils +import org.jetbrains.kotlin.types.JetType +import org.jetbrains.kotlin.types.TypeUtils +import java.util.* + +public class RemoveExplicitTypeIntention : JetSelfTargetingIntention(javaClass(), "Remove explicit type specification") { + override fun isApplicableTo(element: JetCallableDeclaration, caretOffset: Int): Boolean { + //TODO: check for public API + if (element.getContainingFile() is JetCodeFragment) return false + if (element.getTypeReference() == null) return false + + val initializer = (element as? JetWithExpressionInitializer)?.getInitializer() + if (initializer != null && initializer.getTextRange().containsOffset(caretOffset)) return false + + return when (element) { + is JetProperty -> true + is JetNamedFunction -> !element.hasBlockBody() && element.getBodyExpression() != null + is JetParameter -> element.isLoopParameter() + else -> false + } + } + + override fun applyTo(element: JetCallableDeclaration, editor: Editor) { + element.setTypeReference(null) + } +} \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/SpecifyTypeExplicitlyAction.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/SpecifyTypeExplicitlyAction.kt deleted file mode 100644 index d773926fd3a..00000000000 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/SpecifyTypeExplicitlyAction.kt +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright 2010-2015 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.kotlin.idea.intentions - -import com.google.common.collect.Lists -import com.intellij.codeInsight.intention.PsiElementBaseIntentionAction -import com.intellij.codeInsight.template.* -import com.intellij.openapi.editor.Editor -import com.intellij.openapi.project.Project -import com.intellij.psi.PsiDocumentManager -import com.intellij.psi.PsiElement -import com.intellij.psi.util.PsiTreeUtil -import org.jetbrains.kotlin.descriptors.CallableDescriptor -import org.jetbrains.kotlin.descriptors.DeclarationDescriptor -import org.jetbrains.kotlin.diagnostics.Errors -import org.jetbrains.kotlin.idea.JetBundle -import org.jetbrains.kotlin.idea.caches.resolve.analyzeFully -import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers -import org.jetbrains.kotlin.idea.util.ShortenReferences -import org.jetbrains.kotlin.psi.* -import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext -import org.jetbrains.kotlin.resolve.BindingContext -import org.jetbrains.kotlin.resolve.DescriptorUtils -import org.jetbrains.kotlin.types.ErrorUtils -import org.jetbrains.kotlin.types.JetType -import org.jetbrains.kotlin.types.TypeUtils -import java.util.ArrayList - -public class SpecifyTypeExplicitlyAction : PsiElementBaseIntentionAction() { - override fun getFamilyName(): String { - return JetBundle.message("specify.type.explicitly.action.family.name") - } - - override fun invoke(project: Project, editor: Editor, element: PsiElement) { - var element = element - val typeRefParent = PsiTreeUtil.getTopmostParentOfType(element, javaClass()) - if (typeRefParent != null) { - element = typeRefParent - } - val declaration = element.getParent() as JetCallableDeclaration - val type = getTypeForDeclaration(declaration) - if (declaration.getTypeReference() == null) { - addTypeAnnotation(project, editor, declaration, type) - } - else { - declaration.setTypeReference(null) - } - } - - override fun isAvailable(project: Project, editor: Editor, element: PsiElement): Boolean { - var element = element - if (element.getContainingFile() is JetCodeFragment) { - return false - } - - val typeRefParent = PsiTreeUtil.getTopmostParentOfType(element, javaClass()) - if (typeRefParent != null) { - element = typeRefParent - } - val parent = element.getParent() - if (parent !is JetCallableDeclaration) return false - - if (parent is JetProperty && !PsiTreeUtil.isAncestor(parent.getInitializer(), element, false)) { - if (parent.getTypeReference() != null) { - setText(JetBundle.message("specify.type.explicitly.remove.action.name")) - return true - } - else { - setText(JetBundle.message("specify.type.explicitly.add.action.name")) - } - } - else if (parent is JetNamedFunction && parent.getTypeReference() == null && !parent.hasBlockBody()) { - setText(JetBundle.message("specify.type.explicitly.add.return.type.action.name")) - } - else if (parent is JetParameter && parent.isLoopParameter()) { - if (parent.getTypeReference() != null) { - setText(JetBundle.message("specify.type.explicitly.remove.action.name")) - return true - } - else { - setText(JetBundle.message("specify.type.explicitly.add.action.name")) - } - } - else { - return false - } - - if (getTypeForDeclaration(parent).isError()) { - return false - } - return !hasPublicMemberDiagnostic(parent) - } - - companion object { - private fun hasPublicMemberDiagnostic(declaration: JetNamedDeclaration): Boolean { - return declaration.getContainingJetFile().analyzeFully().getDiagnostics() - .any { Errors.PUBLIC_MEMBER_SHOULD_SPECIFY_TYPE == it.getFactory() && declaration == it.getPsiElement() } - } - - public fun getTypeForDeclaration(declaration: JetCallableDeclaration): JetType { - val bindingContext = declaration.getContainingJetFile().analyzeFully() - - val type = if (bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, declaration) != null) - (bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, declaration) as CallableDescriptor).getReturnType() - else - null - return type ?: ErrorUtils.createErrorType("null type") - } - - public fun createTypeExpressionForTemplate(exprType: JetType): Expression { - val descriptor = exprType.getConstructor().getDeclarationDescriptor() - val isAnonymous = descriptor != null && DescriptorUtils.isAnonymousObject(descriptor) - - val allSupertypes = TypeUtils.getAllSupertypes(exprType) - val types = if (isAnonymous) ArrayList() else Lists.newArrayList(exprType) - types.addAll(allSupertypes) - - return object : JetTypeLookupExpression(types, types.iterator().next(), JetBundle.message("specify.type.explicitly.add.action.name")) { - override fun getLookupString(element: JetType): String { - return IdeDescriptorRenderers.SOURCE_CODE_SHORT_NAMES_IN_TYPES.renderType(element) - } - - override fun getResult(element: JetType): String { - return IdeDescriptorRenderers.SOURCE_CODE.renderType(element) - } - } - } - - public fun addTypeAnnotation(project: Project, editor: Editor?, declaration: JetCallableDeclaration, exprType: JetType) { - if (editor != null) { - addTypeAnnotationWithTemplate(project, editor, declaration, exprType) - } - else { - declaration.setTypeReference(anyTypeRef(project)) - } - } - - public fun createTypeReferencePostprocessor(declaration: JetCallableDeclaration): TemplateEditingAdapter { - return object : TemplateEditingAdapter() { - override fun templateFinished(template: Template?, brokenOff: Boolean) { - val typeRef = declaration.getTypeReference() - if (typeRef != null && typeRef.isValid()) { - ShortenReferences.DEFAULT.process(typeRef) - } - } - } - } - - private fun addTypeAnnotationWithTemplate(project: Project, editor: Editor, declaration: JetCallableDeclaration, exprType: JetType) { - assert(!exprType.isError()) { "Unexpected error type, should have been checked before: " + declaration.getElementTextWithContext() + ", type = " + exprType } - - val expression = createTypeExpressionForTemplate(exprType) - - declaration.setTypeReference(anyTypeRef(project)) - - PsiDocumentManager.getInstance(project).commitAllDocuments() - PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(editor.getDocument()) - - val newTypeRef = declaration.getTypeReference()!! - val builder = TemplateBuilderImpl(newTypeRef) - builder.replaceElement(newTypeRef, expression) - - editor.getCaretModel().moveToOffset(newTypeRef.getNode().getStartOffset()) - - TemplateManager.getInstance(project).startTemplate(editor, builder.buildInlineTemplate(), createTypeReferencePostprocessor(declaration)) - } - - private fun anyTypeRef(project: Project): JetTypeReference { - return JetPsiFactory(project).createType("Any") - } - } -} diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/SpecifyTypeExplicitlyIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/SpecifyTypeExplicitlyIntention.kt new file mode 100644 index 00000000000..8b8130375ab --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/SpecifyTypeExplicitlyIntention.kt @@ -0,0 +1,134 @@ +/* + * Copyright 2010-2015 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.kotlin.idea.intentions + +import com.google.common.collect.Lists +import com.intellij.codeInsight.intention.PsiElementBaseIntentionAction +import com.intellij.codeInsight.template.* +import com.intellij.openapi.editor.Editor +import com.intellij.openapi.project.Project +import com.intellij.psi.PsiDocumentManager +import com.intellij.psi.PsiElement +import com.intellij.psi.util.PsiTreeUtil +import org.jetbrains.kotlin.builtins.KotlinBuiltIns +import org.jetbrains.kotlin.descriptors.CallableDescriptor +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor +import org.jetbrains.kotlin.diagnostics.Errors +import org.jetbrains.kotlin.idea.JetBundle +import org.jetbrains.kotlin.idea.caches.resolve.analyze +import org.jetbrains.kotlin.idea.caches.resolve.analyzeFully +import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers +import org.jetbrains.kotlin.idea.util.ShortenReferences +import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext +import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.resolve.DescriptorUtils +import org.jetbrains.kotlin.types.ErrorUtils +import org.jetbrains.kotlin.types.JetType +import org.jetbrains.kotlin.types.TypeUtils +import java.util.ArrayList + +public class SpecifyTypeExplicitlyIntention : JetSelfTargetingIntention(javaClass(), "Specify type explicitly") { + override fun isApplicableTo(element: JetCallableDeclaration, caretOffset: Int): Boolean { + if (element.getContainingFile() is JetCodeFragment) return false + if (element.getTypeReference() != null) return false + + if (getTypeForDeclaration(element).isError() || hasPublicMemberDiagnostic(element)) return false + + val initializer = (element as? JetWithExpressionInitializer)?.getInitializer() + if (initializer != null && initializer.getTextRange().containsOffset(caretOffset)) return false + + if (element is JetNamedFunction && element.hasBlockBody()) return false + + setText(if (element is JetFunction) "Specify return type explicitly" else "Specify type explicitly") + + return true + } + + private fun hasPublicMemberDiagnostic(declaration: JetNamedDeclaration): Boolean { + return declaration.getContainingJetFile().analyzeFully().getDiagnostics() + .any { Errors.PUBLIC_MEMBER_SHOULD_SPECIFY_TYPE == it.getFactory() && declaration == it.getPsiElement() } + } + + override fun applyTo(element: JetCallableDeclaration, editor: Editor) { + val type = getTypeForDeclaration(element) + addTypeAnnotation(editor, element, type) + } + + companion object { + public fun getTypeForDeclaration(declaration: JetCallableDeclaration): JetType { + val descriptor = declaration.analyze()[BindingContext.DECLARATION_TO_DESCRIPTOR, declaration] + val type = (descriptor as? CallableDescriptor)?.getReturnType() + return type ?: ErrorUtils.createErrorType("null type") + } + + public fun createTypeExpressionForTemplate(exprType: JetType): Expression { + val descriptor = exprType.getConstructor().getDeclarationDescriptor() + val isAnonymous = descriptor != null && DescriptorUtils.isAnonymousObject(descriptor) + + val allSupertypes = TypeUtils.getAllSupertypes(exprType) + val types = if (isAnonymous) ArrayList() else arrayListOf(exprType) + types.addAll(allSupertypes) + + return object : JetTypeLookupExpression(types, types.first(), JetBundle.message("specify.type.explicitly.add.action.name")) { + override fun getLookupString(element: JetType) = IdeDescriptorRenderers.SOURCE_CODE_SHORT_NAMES_IN_TYPES.renderType(element) + override fun getResult(element: JetType) = IdeDescriptorRenderers.SOURCE_CODE.renderType(element) + } + } + + public fun addTypeAnnotation(editor: Editor?, declaration: JetCallableDeclaration, exprType: JetType) { + if (editor != null) { + addTypeAnnotationWithTemplate(editor, declaration, exprType) + } + else { + declaration.setType(KotlinBuiltIns.getInstance().getAnyType()) + } + } + + public fun createTypeReferencePostprocessor(declaration: JetCallableDeclaration): TemplateEditingAdapter { + return object : TemplateEditingAdapter() { + override fun templateFinished(template: Template?, brokenOff: Boolean) { + val typeRef = declaration.getTypeReference() + if (typeRef != null && typeRef.isValid()) { + ShortenReferences.DEFAULT.process(typeRef) + } + } + } + } + + private fun addTypeAnnotationWithTemplate(editor: Editor, declaration: JetCallableDeclaration, exprType: JetType) { + assert(!exprType.isError()) { "Unexpected error type, should have been checked before: " + declaration.getElementTextWithContext() + ", type = " + exprType } + + val project = declaration.getProject() + val expression = createTypeExpressionForTemplate(exprType) + + declaration.setType(KotlinBuiltIns.getInstance().getAnyType()) + + PsiDocumentManager.getInstance(project).commitAllDocuments() + PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(editor.getDocument()) + + val newTypeRef = declaration.getTypeReference()!! + val builder = TemplateBuilderImpl(newTypeRef) + builder.replaceElement(newTypeRef, expression) + + editor.getCaretModel().moveToOffset(newTypeRef.getNode().getStartOffset()) + + TemplateManager.getInstance(project).startTemplate(editor, builder.buildInlineTemplate(), createTypeReferencePostprocessor(declaration)) + } + } +} + diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/RemovePartsFromPropertyFix.java b/idea/src/org/jetbrains/kotlin/idea/quickfix/RemovePartsFromPropertyFix.java index a3e72ac8b84..5cfb27c2e4e 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/RemovePartsFromPropertyFix.java +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/RemovePartsFromPropertyFix.java @@ -26,7 +26,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.kotlin.diagnostics.Diagnostic; import org.jetbrains.kotlin.idea.JetBundle; import org.jetbrains.kotlin.idea.core.quickfix.QuickFixUtil; -import org.jetbrains.kotlin.idea.intentions.SpecifyTypeExplicitlyAction; +import org.jetbrains.kotlin.idea.intentions.SpecifyTypeExplicitlyIntention; import org.jetbrains.kotlin.psi.*; import org.jetbrains.kotlin.types.JetType; @@ -116,7 +116,7 @@ public class RemovePartsFromPropertyFix extends JetIntentionAction } element = (JetProperty) element.replace(newElement); if (typeToAdd != null) { - SpecifyTypeExplicitlyAction.Companion.addTypeAnnotation(project, editor, element, typeToAdd); + SpecifyTypeExplicitlyIntention.Companion.addTypeAnnotation(editor, element, typeToAdd); } } diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/SpecifyTypeExplicitlyFix.java b/idea/src/org/jetbrains/kotlin/idea/quickfix/SpecifyTypeExplicitlyFix.java index 3fcd784a2f1..db6b99906f8 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/SpecifyTypeExplicitlyFix.java +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/SpecifyTypeExplicitlyFix.java @@ -23,7 +23,7 @@ import com.intellij.psi.PsiElement; import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.kotlin.idea.JetBundle; -import org.jetbrains.kotlin.idea.intentions.SpecifyTypeExplicitlyAction; +import org.jetbrains.kotlin.idea.intentions.SpecifyTypeExplicitlyIntention; import org.jetbrains.kotlin.psi.JetCallableDeclaration; import org.jetbrains.kotlin.psi.JetNamedFunction; import org.jetbrains.kotlin.psi.JetProperty; @@ -41,8 +41,8 @@ public class SpecifyTypeExplicitlyFix extends PsiElementBaseIntentionAction { public void invoke(@NotNull Project project, @NotNull Editor editor, @NotNull PsiElement element) { //noinspection unchecked JetCallableDeclaration declaration = PsiTreeUtil.getParentOfType(element, JetProperty.class, JetNamedFunction.class); - JetType type = SpecifyTypeExplicitlyAction.Companion.getTypeForDeclaration(declaration); - SpecifyTypeExplicitlyAction.Companion.addTypeAnnotation(project, editor, declaration, type); + JetType type = SpecifyTypeExplicitlyIntention.Companion.getTypeForDeclaration(declaration); + SpecifyTypeExplicitlyIntention.Companion.addTypeAnnotation(editor, declaration, type); } @Override @@ -59,6 +59,6 @@ public class SpecifyTypeExplicitlyFix extends PsiElementBaseIntentionAction { return false; } - return !SpecifyTypeExplicitlyAction.Companion.getTypeForDeclaration(declaration).isError(); + return !SpecifyTypeExplicitlyIntention.Companion.getTypeForDeclaration(declaration).isError(); } } diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/introduceVariable/KotlinInplaceVariableIntroducer.java b/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/introduceVariable/KotlinInplaceVariableIntroducer.java index e38f9721e7f..b1ab70a611b 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/introduceVariable/KotlinInplaceVariableIntroducer.java +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/introduceVariable/KotlinInplaceVariableIntroducer.java @@ -40,7 +40,7 @@ import kotlin.Function1; import kotlin.KotlinPackage; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.kotlin.idea.intentions.SpecifyTypeExplicitlyAction; +import org.jetbrains.kotlin.idea.intentions.SpecifyTypeExplicitlyIntention; import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers; import org.jetbrains.kotlin.lexer.JetTokens; import org.jetbrains.kotlin.psi.*; @@ -356,7 +356,7 @@ public class KotlinInplaceVariableIntroducer e if (typeReference != null) { builder.replaceElement(typeReference, TYPE_REFERENCE_VARIABLE_NAME, - SpecifyTypeExplicitlyAction.Companion.createTypeExpressionForTemplate(myExprType), + SpecifyTypeExplicitlyIntention.Companion.createTypeExpressionForTemplate(myExprType), false); } } @@ -381,7 +381,7 @@ public class KotlinInplaceVariableIntroducer e TemplateState templateState = TemplateManagerImpl.getTemplateState(InjectedLanguageUtil.getTopLevelEditor(myEditor)); if (templateState != null && myDeclaration.getTypeReference() != null) { - templateState.addTemplateStateListener(SpecifyTypeExplicitlyAction.Companion.createTypeReferencePostprocessor(myDeclaration)); + templateState.addTemplateStateListener(SpecifyTypeExplicitlyIntention.Companion.createTypeReferencePostprocessor(myDeclaration)); } return result; diff --git a/idea/testData/intentions/removeExplicitType/.intention b/idea/testData/intentions/removeExplicitType/.intention new file mode 100644 index 00000000000..03140f5a376 --- /dev/null +++ b/idea/testData/intentions/removeExplicitType/.intention @@ -0,0 +1 @@ +org.jetbrains.kotlin.idea.intentions.RemoveExplicitTypeIntention diff --git a/idea/testData/intentions/specifyType/onType.kt b/idea/testData/intentions/removeExplicitType/onType.kt similarity index 100% rename from idea/testData/intentions/specifyType/onType.kt rename to idea/testData/intentions/removeExplicitType/onType.kt diff --git a/idea/testData/intentions/specifyType/onType.kt.after b/idea/testData/intentions/removeExplicitType/onType.kt.after similarity index 100% rename from idea/testData/intentions/specifyType/onType.kt.after rename to idea/testData/intentions/removeExplicitType/onType.kt.after diff --git a/idea/testData/intentions/specifyType/removeUnresolvedType.kt b/idea/testData/intentions/removeExplicitType/removeUnresolvedType.kt similarity index 100% rename from idea/testData/intentions/specifyType/removeUnresolvedType.kt rename to idea/testData/intentions/removeExplicitType/removeUnresolvedType.kt diff --git a/idea/testData/intentions/specifyType/removeUnresolvedType.kt.after b/idea/testData/intentions/removeExplicitType/removeUnresolvedType.kt.after similarity index 100% rename from idea/testData/intentions/specifyType/removeUnresolvedType.kt.after rename to idea/testData/intentions/removeExplicitType/removeUnresolvedType.kt.after diff --git a/idea/testData/intentions/specifyType/.intention b/idea/testData/intentions/specifyType/.intention index e92c448ef7c..4bbcbad257c 100644 --- a/idea/testData/intentions/specifyType/.intention +++ b/idea/testData/intentions/specifyType/.intention @@ -1 +1 @@ -org.jetbrains.kotlin.idea.intentions.SpecifyTypeExplicitlyAction +org.jetbrains.kotlin.idea.intentions.SpecifyTypeExplicitlyIntention diff --git a/idea/testData/intentions/specifyType/typeAlreadyProvided.kt b/idea/testData/intentions/specifyType/typeAlreadyProvided.kt index 305f8c0cad9..2bee95f79fc 100644 --- a/idea/testData/intentions/specifyType/typeAlreadyProvided.kt +++ b/idea/testData/intentions/specifyType/typeAlreadyProvided.kt @@ -1 +1,2 @@ +// IS_APPLICABLE: false val x : String = "" \ No newline at end of file diff --git a/idea/testData/intentions/specifyType/typeAlreadyProvided.kt.after b/idea/testData/intentions/specifyType/typeAlreadyProvided.kt.after deleted file mode 100644 index e78c75c1020..00000000000 --- a/idea/testData/intentions/specifyType/typeAlreadyProvided.kt.after +++ /dev/null @@ -1 +0,0 @@ -val x = "" \ No newline at end of file diff --git a/idea/testData/quickfix/createFromUsage/createClass/typeReference/classGroovyTypeReceiver.before.Main.kt b/idea/testData/quickfix/createFromUsage/createClass/typeReference/classGroovyTypeReceiver.before.Main.kt index 45a13c38b3a..df8d23da9d5 100644 --- a/idea/testData/quickfix/createFromUsage/createClass/typeReference/classGroovyTypeReceiver.before.Main.kt +++ b/idea/testData/quickfix/createFromUsage/createClass/typeReference/classGroovyTypeReceiver.before.Main.kt @@ -1,4 +1,5 @@ // "Create class 'A'" "false" // ACTION: Convert to block body +// ACTION: Remove explicit type specification // ERROR: Unresolved reference: A fun foo(): J.A = throw Throwable("") \ No newline at end of file diff --git a/idea/testData/quickfix/createFromUsage/createClass/typeReference/enumEntryJavaEnumReceiver.before.Main.kt b/idea/testData/quickfix/createFromUsage/createClass/typeReference/enumEntryJavaEnumReceiver.before.Main.kt index e33d903dd0d..08cfa4beaef 100644 --- a/idea/testData/quickfix/createFromUsage/createClass/typeReference/enumEntryJavaEnumReceiver.before.Main.kt +++ b/idea/testData/quickfix/createFromUsage/createClass/typeReference/enumEntryJavaEnumReceiver.before.Main.kt @@ -1,5 +1,6 @@ // "Create enum constant 'A'" "false" // ACTION: Convert to block body +// ACTION: Remove explicit type specification // ACTION: Create annotation 'A' // ACTION: Create class 'A' // ACTION: Create enum 'A' diff --git a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java index 3cd700b79e6..db86a38a7d5 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java @@ -5042,6 +5042,27 @@ public class IntentionTestGenerated extends AbstractIntentionTest { } } + @TestMetadata("idea/testData/intentions/removeExplicitType") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class RemoveExplicitType extends AbstractIntentionTest { + public void testAllFilesPresentInRemoveExplicitType() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/intentions/removeExplicitType"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("onType.kt") + public void testOnType() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/intentions/removeExplicitType/onType.kt"); + doTest(fileName); + } + + @TestMetadata("removeUnresolvedType.kt") + public void testRemoveUnresolvedType() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/intentions/removeExplicitType/removeUnresolvedType.kt"); + doTest(fileName); + } + } + @TestMetadata("idea/testData/intentions/removeExplicitTypeArguments") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) @@ -5787,24 +5808,12 @@ public class IntentionTestGenerated extends AbstractIntentionTest { doTest(fileName); } - @TestMetadata("onType.kt") - public void testOnType() throws Exception { - String fileName = JetTestUtils.navigationMetadata("idea/testData/intentions/specifyType/onType.kt"); - doTest(fileName); - } - @TestMetadata("publicMember.kt") public void testPublicMember() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/intentions/specifyType/publicMember.kt"); doTest(fileName); } - @TestMetadata("removeUnresolvedType.kt") - public void testRemoveUnresolvedType() throws Exception { - String fileName = JetTestUtils.navigationMetadata("idea/testData/intentions/specifyType/removeUnresolvedType.kt"); - doTest(fileName); - } - @TestMetadata("stringRedefined.kt") public void testStringRedefined() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/intentions/specifyType/stringRedefined.kt");