Split SpecifyTypeExplicitly intention into two + refactored them completely
This commit is contained in:
@@ -0,0 +1,5 @@
|
|||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
This intention removes explicit type specification for local values, variables, properties and functions.
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
<html>
|
|
||||||
<body>
|
|
||||||
This intention adds or removes explicit type specification for local values, variables and properties.
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
fun main() {
|
||||||
|
val a <spot>: Array<Int></spot> = array(1, 2, 3)
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
fun main() {
|
||||||
|
val <spot>a</spot> = array(1, 2, 3)
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
This intention adds explicit type specification for local values, variables, properties and functions.
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -506,7 +506,12 @@
|
|||||||
</intentionAction>
|
</intentionAction>
|
||||||
|
|
||||||
<intentionAction>
|
<intentionAction>
|
||||||
<className>org.jetbrains.kotlin.idea.intentions.SpecifyTypeExplicitlyAction</className>
|
<className>org.jetbrains.kotlin.idea.intentions.SpecifyTypeExplicitlyIntention</className>
|
||||||
|
<category>Kotlin</category>
|
||||||
|
</intentionAction>
|
||||||
|
|
||||||
|
<intentionAction>
|
||||||
|
<className>org.jetbrains.kotlin.idea.intentions.RemoveExplicitTypeIntention</className>
|
||||||
<category>Kotlin</category>
|
<category>Kotlin</category>
|
||||||
</intentionAction>
|
</intentionAction>
|
||||||
|
|
||||||
|
|||||||
@@ -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<JetCallableDeclaration>(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)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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<JetTypeReference>(element, javaClass<JetTypeReference>())
|
|
||||||
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<JetTypeReference>(element, javaClass<JetTypeReference>())
|
|
||||||
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<PsiElement, DeclarationDescriptor>(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<JetType>() else Lists.newArrayList<JetType>(exprType)
|
|
||||||
types.addAll(allSupertypes)
|
|
||||||
|
|
||||||
return object : JetTypeLookupExpression<JetType>(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")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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<JetCallableDeclaration>(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<JetType>() else arrayListOf(exprType)
|
||||||
|
types.addAll(allSupertypes)
|
||||||
|
|
||||||
|
return object : JetTypeLookupExpression<JetType>(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))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -26,7 +26,7 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.kotlin.diagnostics.Diagnostic;
|
import org.jetbrains.kotlin.diagnostics.Diagnostic;
|
||||||
import org.jetbrains.kotlin.idea.JetBundle;
|
import org.jetbrains.kotlin.idea.JetBundle;
|
||||||
import org.jetbrains.kotlin.idea.core.quickfix.QuickFixUtil;
|
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.psi.*;
|
||||||
import org.jetbrains.kotlin.types.JetType;
|
import org.jetbrains.kotlin.types.JetType;
|
||||||
|
|
||||||
@@ -116,7 +116,7 @@ public class RemovePartsFromPropertyFix extends JetIntentionAction<JetProperty>
|
|||||||
}
|
}
|
||||||
element = (JetProperty) element.replace(newElement);
|
element = (JetProperty) element.replace(newElement);
|
||||||
if (typeToAdd != null) {
|
if (typeToAdd != null) {
|
||||||
SpecifyTypeExplicitlyAction.Companion.addTypeAnnotation(project, editor, element, typeToAdd);
|
SpecifyTypeExplicitlyIntention.Companion.addTypeAnnotation(editor, element, typeToAdd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import com.intellij.psi.PsiElement;
|
|||||||
import com.intellij.psi.util.PsiTreeUtil;
|
import com.intellij.psi.util.PsiTreeUtil;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.kotlin.idea.JetBundle;
|
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.JetCallableDeclaration;
|
||||||
import org.jetbrains.kotlin.psi.JetNamedFunction;
|
import org.jetbrains.kotlin.psi.JetNamedFunction;
|
||||||
import org.jetbrains.kotlin.psi.JetProperty;
|
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) {
|
public void invoke(@NotNull Project project, @NotNull Editor editor, @NotNull PsiElement element) {
|
||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
JetCallableDeclaration declaration = PsiTreeUtil.getParentOfType(element, JetProperty.class, JetNamedFunction.class);
|
JetCallableDeclaration declaration = PsiTreeUtil.getParentOfType(element, JetProperty.class, JetNamedFunction.class);
|
||||||
JetType type = SpecifyTypeExplicitlyAction.Companion.getTypeForDeclaration(declaration);
|
JetType type = SpecifyTypeExplicitlyIntention.Companion.getTypeForDeclaration(declaration);
|
||||||
SpecifyTypeExplicitlyAction.Companion.addTypeAnnotation(project, editor, declaration, type);
|
SpecifyTypeExplicitlyIntention.Companion.addTypeAnnotation(editor, declaration, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -59,6 +59,6 @@ public class SpecifyTypeExplicitlyFix extends PsiElementBaseIntentionAction {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return !SpecifyTypeExplicitlyAction.Companion.getTypeForDeclaration(declaration).isError();
|
return !SpecifyTypeExplicitlyIntention.Companion.getTypeForDeclaration(declaration).isError();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -40,7 +40,7 @@ import kotlin.Function1;
|
|||||||
import kotlin.KotlinPackage;
|
import kotlin.KotlinPackage;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
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.idea.util.IdeDescriptorRenderers;
|
||||||
import org.jetbrains.kotlin.lexer.JetTokens;
|
import org.jetbrains.kotlin.lexer.JetTokens;
|
||||||
import org.jetbrains.kotlin.psi.*;
|
import org.jetbrains.kotlin.psi.*;
|
||||||
@@ -356,7 +356,7 @@ public class KotlinInplaceVariableIntroducer<D extends JetCallableDeclaration> e
|
|||||||
if (typeReference != null) {
|
if (typeReference != null) {
|
||||||
builder.replaceElement(typeReference,
|
builder.replaceElement(typeReference,
|
||||||
TYPE_REFERENCE_VARIABLE_NAME,
|
TYPE_REFERENCE_VARIABLE_NAME,
|
||||||
SpecifyTypeExplicitlyAction.Companion.createTypeExpressionForTemplate(myExprType),
|
SpecifyTypeExplicitlyIntention.Companion.createTypeExpressionForTemplate(myExprType),
|
||||||
false);
|
false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -381,7 +381,7 @@ public class KotlinInplaceVariableIntroducer<D extends JetCallableDeclaration> e
|
|||||||
TemplateState templateState =
|
TemplateState templateState =
|
||||||
TemplateManagerImpl.getTemplateState(InjectedLanguageUtil.getTopLevelEditor(myEditor));
|
TemplateManagerImpl.getTemplateState(InjectedLanguageUtil.getTopLevelEditor(myEditor));
|
||||||
if (templateState != null && myDeclaration.getTypeReference() != null) {
|
if (templateState != null && myDeclaration.getTypeReference() != null) {
|
||||||
templateState.addTemplateStateListener(SpecifyTypeExplicitlyAction.Companion.createTypeReferencePostprocessor(myDeclaration));
|
templateState.addTemplateStateListener(SpecifyTypeExplicitlyIntention.Companion.createTypeReferencePostprocessor(myDeclaration));
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
org.jetbrains.kotlin.idea.intentions.RemoveExplicitTypeIntention
|
||||||
@@ -1 +1 @@
|
|||||||
org.jetbrains.kotlin.idea.intentions.SpecifyTypeExplicitlyAction
|
org.jetbrains.kotlin.idea.intentions.SpecifyTypeExplicitlyIntention
|
||||||
|
|||||||
@@ -1 +1,2 @@
|
|||||||
|
// IS_APPLICABLE: false
|
||||||
val x<caret> : String = ""
|
val x<caret> : String = ""
|
||||||
@@ -1 +0,0 @@
|
|||||||
val x = ""
|
|
||||||
+1
@@ -1,4 +1,5 @@
|
|||||||
// "Create class 'A'" "false"
|
// "Create class 'A'" "false"
|
||||||
// ACTION: Convert to block body
|
// ACTION: Convert to block body
|
||||||
|
// ACTION: Remove explicit type specification
|
||||||
// ERROR: Unresolved reference: A
|
// ERROR: Unresolved reference: A
|
||||||
fun foo(): J.<caret>A = throw Throwable("")
|
fun foo(): J.<caret>A = throw Throwable("")
|
||||||
+1
@@ -1,5 +1,6 @@
|
|||||||
// "Create enum constant 'A'" "false"
|
// "Create enum constant 'A'" "false"
|
||||||
// ACTION: Convert to block body
|
// ACTION: Convert to block body
|
||||||
|
// ACTION: Remove explicit type specification
|
||||||
// ACTION: Create annotation 'A'
|
// ACTION: Create annotation 'A'
|
||||||
// ACTION: Create class 'A'
|
// ACTION: Create class 'A'
|
||||||
// ACTION: Create enum 'A'
|
// ACTION: Create enum 'A'
|
||||||
|
|||||||
@@ -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")
|
@TestMetadata("idea/testData/intentions/removeExplicitTypeArguments")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
@@ -5787,24 +5808,12 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
|
|||||||
doTest(fileName);
|
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")
|
@TestMetadata("publicMember.kt")
|
||||||
public void testPublicMember() throws Exception {
|
public void testPublicMember() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/intentions/specifyType/publicMember.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/intentions/specifyType/publicMember.kt");
|
||||||
doTest(fileName);
|
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")
|
@TestMetadata("stringRedefined.kt")
|
||||||
public void testStringRedefined() throws Exception {
|
public void testStringRedefined() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/intentions/specifyType/stringRedefined.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/intentions/specifyType/stringRedefined.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user