Split SpecifyTypeExplicitly intention into two + refactored them completely

This commit is contained in:
Valentin Kipyatkov
2015-05-05 14:45:52 +03:00
parent d956d31012
commit 2d90ee5cad
25 changed files with 251 additions and 215 deletions
@@ -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>
+6 -1
View File
@@ -506,7 +506,12 @@
</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>
</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.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<JetProperty>
}
element = (JetProperty) element.replace(newElement);
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 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();
}
}
@@ -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<D extends JetCallableDeclaration> 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<D extends JetCallableDeclaration> 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;
@@ -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 = ""
@@ -1 +0,0 @@
val x = ""
@@ -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.<caret>A = throw Throwable("")
@@ -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'
@@ -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");