From 3b87869bf7ef2b4a2122c5daf633734e2de95c34 Mon Sep 17 00:00:00 2001 From: Valentin Kipyatkov Date: Tue, 28 Apr 2015 16:20:34 +0300 Subject: [PATCH] ReconstructTypeInCastOrIsIntention - refactored --- .../kotlin/idea/JetBundle.properties | 2 - .../after.kt.template | 0 .../before.kt.template | 0 .../description.html | 0 idea/src/META-INF/plugin.xml | 2 +- .../ReconstructTypeInCastOrIsAction.kt | 80 ------------------- .../ReconstructTypeInCastOrIsIntention.kt | 64 +++++++++++++++ .../reconstructTypeInCastOrIs/.intention | 2 +- 8 files changed, 66 insertions(+), 84 deletions(-) rename idea/resources/intentionDescriptions/{ReconstructTypeInCastOrIsAction => ReconstructTypeInCastOrIsIntention}/after.kt.template (100%) rename idea/resources/intentionDescriptions/{ReconstructTypeInCastOrIsAction => ReconstructTypeInCastOrIsIntention}/before.kt.template (100%) rename idea/resources/intentionDescriptions/{ReconstructTypeInCastOrIsAction => ReconstructTypeInCastOrIsIntention}/description.html (100%) delete mode 100644 idea/src/org/jetbrains/kotlin/idea/intentions/ReconstructTypeInCastOrIsAction.kt create mode 100644 idea/src/org/jetbrains/kotlin/idea/intentions/ReconstructTypeInCastOrIsIntention.kt diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/JetBundle.properties b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/JetBundle.properties index 7557400a6e7..e9102323696 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/JetBundle.properties +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/JetBundle.properties @@ -412,8 +412,6 @@ hierarchy.legend.member.defined.in.superclass=Member is not defined in the class hierarchy.legend.member.should.be.defined=Member should be defined since the class is not abstract convert.to.extension=Convert to extension -replace.by.reconstructed.type.family.name=Replace by Reconstructed Type -replace.by.reconstructed.type=Replace by ''{0}'' suppress.warnings.family=Suppress Warnings suppress.warning.for=Suppress ''{0}'' for {1} {2} diff --git a/idea/resources/intentionDescriptions/ReconstructTypeInCastOrIsAction/after.kt.template b/idea/resources/intentionDescriptions/ReconstructTypeInCastOrIsIntention/after.kt.template similarity index 100% rename from idea/resources/intentionDescriptions/ReconstructTypeInCastOrIsAction/after.kt.template rename to idea/resources/intentionDescriptions/ReconstructTypeInCastOrIsIntention/after.kt.template diff --git a/idea/resources/intentionDescriptions/ReconstructTypeInCastOrIsAction/before.kt.template b/idea/resources/intentionDescriptions/ReconstructTypeInCastOrIsIntention/before.kt.template similarity index 100% rename from idea/resources/intentionDescriptions/ReconstructTypeInCastOrIsAction/before.kt.template rename to idea/resources/intentionDescriptions/ReconstructTypeInCastOrIsIntention/before.kt.template diff --git a/idea/resources/intentionDescriptions/ReconstructTypeInCastOrIsAction/description.html b/idea/resources/intentionDescriptions/ReconstructTypeInCastOrIsIntention/description.html similarity index 100% rename from idea/resources/intentionDescriptions/ReconstructTypeInCastOrIsAction/description.html rename to idea/resources/intentionDescriptions/ReconstructTypeInCastOrIsIntention/description.html diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index ad6ec126961..9041d5f7bd3 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -709,7 +709,7 @@ - org.jetbrains.kotlin.idea.intentions.ReconstructTypeInCastOrIsAction + org.jetbrains.kotlin.idea.intentions.ReconstructTypeInCastOrIsIntention Kotlin diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ReconstructTypeInCastOrIsAction.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ReconstructTypeInCastOrIsAction.kt deleted file mode 100644 index b5b3158c55a..00000000000 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/ReconstructTypeInCastOrIsAction.kt +++ /dev/null @@ -1,80 +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.intellij.codeInsight.intention.PsiElementBaseIntentionAction -import com.intellij.openapi.editor.Editor -import com.intellij.openapi.project.Project -import com.intellij.psi.PsiElement -import com.intellij.psi.util.PsiTreeUtil -import org.jetbrains.kotlin.idea.JetBundle -import org.jetbrains.kotlin.idea.caches.resolve.* -import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers -import org.jetbrains.kotlin.idea.util.ShortenReferences -import org.jetbrains.kotlin.psi.* -import org.jetbrains.kotlin.resolve.BindingContext -import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode -import org.jetbrains.kotlin.types.JetType - -public class ReconstructTypeInCastOrIsAction : PsiElementBaseIntentionAction() { - override fun getFamilyName(): String { - return JetBundle.message("replace.by.reconstructed.type.family.name") - } - - override fun invoke(project: Project, editor: Editor, element: PsiElement) { - val typeRef = PsiTreeUtil.getTopmostParentOfType(element, javaClass()) - assert(typeRef != null) { "Must be checked by isAvailable(): " + element } - - val type = getReconstructedType(typeRef) - val newType = JetPsiFactory(typeRef).createType(IdeDescriptorRenderers.SOURCE_CODE.renderType(type)) - val replaced = typeRef!!.replace(newType) as JetTypeReference - ShortenReferences.DEFAULT.process(replaced) - } - - override fun isAvailable(project: Project, editor: Editor, element: PsiElement): Boolean { - val typeRef = PsiTreeUtil.getTopmostParentOfType(element, javaClass()) - if (typeRef == null) return false - - // Only user types (like Foo) are interesting - val typeElement = typeRef.getTypeElement() - if (typeElement !is JetUserType) return false - - // If there are generic arguments already, there's nothing to reconstruct - if (!typeElement.getTypeArguments().isEmpty()) return false - - // We must be on the RHS of as/as?/is/!is or inside an is/!is-condition in when() - val outerExpression = PsiTreeUtil.getParentOfType(typeRef, javaClass()) - if (outerExpression !is JetBinaryExpressionWithTypeRHS) { - val outerIsCondition = PsiTreeUtil.getParentOfType(typeRef, javaClass()) - if (outerIsCondition == null) return false - } - - val type = getReconstructedType(typeRef) - if (type == null || type.isError()) return false - - // No type parameters expected => nothing to reconstruct - if (type.getConstructor().getParameters().isEmpty()) return false - - setText(JetBundle.message("replace.by.reconstructed.type", type)) - - return true - } - - private fun getReconstructedType(typeRef: JetTypeReference): JetType? { - return typeRef.analyze(BodyResolveMode.FULL).get(BindingContext.TYPE, typeRef) - } -} diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ReconstructTypeInCastOrIsIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ReconstructTypeInCastOrIsIntention.kt new file mode 100644 index 00000000000..cb7d54965e7 --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/ReconstructTypeInCastOrIsIntention.kt @@ -0,0 +1,64 @@ +/* + * 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.openapi.editor.Editor +import com.intellij.psi.util.PsiTreeUtil +import org.jetbrains.kotlin.idea.caches.resolve.analyze +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.getParentOfType +import org.jetbrains.kotlin.psi.psiUtil.replaced +import org.jetbrains.kotlin.renderer.DescriptorRenderer +import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.types.JetType + +public class ReconstructTypeInCastOrIsIntention : JetSelfTargetingOffsetIndependentIntention(javaClass(), "Replace by reconstructed type") { + override fun isApplicableTo(element: JetTypeReference): Boolean { + // Only user types (like Foo) are interesting + val typeElement = element.getTypeElement() as? JetUserType ?: return false + + // If there are generic arguments already, there's nothing to reconstruct + if (typeElement.getTypeArguments().isNotEmpty()) return false + + // We must be on the RHS of as/as?/is/!is or inside an is/!is-condition in when() + val expression = element.getParentOfType(true) + if (expression !is JetBinaryExpressionWithTypeRHS && element.getParentOfType(true) == null) return false + + val type = getReconstructedType(element) + if (type == null || type.isError()) return false + + // No type parameters expected => nothing to reconstruct + if (type.getConstructor().getParameters().isEmpty()) return false + + val typePresentation = IdeDescriptorRenderers.SOURCE_CODE_SHORT_NAMES_IN_TYPES.renderType(type) + setText("Replace by '$typePresentation'") + + return true + } + + override fun applyTo(element: JetTypeReference, editor: Editor) { + val type = getReconstructedType(element)!! + val newType = JetPsiFactory(element).createType(IdeDescriptorRenderers.SOURCE_CODE.renderType(type)) + ShortenReferences.DEFAULT.process(element.replaced(newType)) + } + + private fun getReconstructedType(typeRef: JetTypeReference): JetType? { + return typeRef.analyze().get(BindingContext.TYPE, typeRef) + } +} diff --git a/idea/testData/intentions/reconstructTypeInCastOrIs/.intention b/idea/testData/intentions/reconstructTypeInCastOrIs/.intention index f086e3e6a59..6e22a5ce0a1 100644 --- a/idea/testData/intentions/reconstructTypeInCastOrIs/.intention +++ b/idea/testData/intentions/reconstructTypeInCastOrIs/.intention @@ -1 +1 @@ -org.jetbrains.kotlin.idea.intentions.ReconstructTypeInCastOrIsAction +org.jetbrains.kotlin.idea.intentions.ReconstructTypeInCastOrIsIntention