Introduce Type Parameter
#KT-13155 Fixed
This commit is contained in:
@@ -118,6 +118,10 @@ These artifacts include extensions for the types available in the latter JDKs, s
|
||||
- [`KT-13216`](https://youtrack.jetbrains.com/issue/KT-13216) Move: Report separate conflicts for each property accessor
|
||||
- [`KT-13216`](https://youtrack.jetbrains.com/issue/KT-13216) Move: Forbid moving of enum entries
|
||||
|
||||
##### New features
|
||||
|
||||
- [`KT-13155`](https://youtrack.jetbrains.com/issue/KT-13155) Implement "Introduce Type Parameter" refactoring
|
||||
|
||||
## 1.0.4
|
||||
|
||||
### Compiler
|
||||
|
||||
@@ -32,7 +32,9 @@ import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
|
||||
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.takeSnapshot
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.expressions.typeInfoFactory.noTypeInfo
|
||||
import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
|
||||
import org.jetbrains.kotlin.util.slicedMap.ReadOnlySlice
|
||||
|
||||
operator fun <K, V: Any> BindingContext.get(slice: ReadOnlySlice<K, V>, key: K): V? = get(slice, key)
|
||||
@@ -98,4 +100,16 @@ fun KtExpression.getReferenceTargets(context: BindingContext): Collection<Declar
|
||||
}
|
||||
|
||||
fun KtTypeReference.getAbbreviatedTypeOrType(context: BindingContext) =
|
||||
context[BindingContext.ABBREVIATED_TYPE, this] ?: context[BindingContext.TYPE, this]
|
||||
context[BindingContext.ABBREVIATED_TYPE, this] ?: context[BindingContext.TYPE, this]
|
||||
|
||||
fun KtTypeElement.getAbbreviatedTypeOrType(context: BindingContext): KotlinType? {
|
||||
val parent = parent
|
||||
return when (parent) {
|
||||
is KtTypeReference -> parent.getAbbreviatedTypeOrType(context)
|
||||
is KtNullableType -> {
|
||||
val outerType = parent.getAbbreviatedTypeOrType(context)
|
||||
if (this is KtNullableType) outerType else outerType?.makeNotNullable()
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
@@ -782,6 +782,7 @@ fun main(args: Array<String>) {
|
||||
model("refactoring/introduceParameter", pattern = KT_OR_KTS, testMethod = "doIntroduceSimpleParameterTest")
|
||||
model("refactoring/introduceLambdaParameter", pattern = KT_OR_KTS, testMethod = "doIntroduceLambdaParameterTest")
|
||||
model("refactoring/introduceJavaParameter", extension = "java", testMethod = "doIntroduceJavaParameterTest")
|
||||
model("refactoring/introduceTypeParameter", pattern = KT_OR_KTS, testMethod = "doIntroduceTypeParameterTest")
|
||||
model("refactoring/introduceTypeAlias", pattern = KT_OR_KTS, testMethod = "doIntroduceTypeAliasTest")
|
||||
}
|
||||
|
||||
|
||||
@@ -162,10 +162,16 @@
|
||||
<add-to-group group-id="IntroduceActionsGroup" anchor="after" relative-to-action="ExtractFunction"/>
|
||||
</action>
|
||||
|
||||
<action id="IntroduceTypeParameter" class="org.jetbrains.kotlin.idea.refactoring.introduce.introduceTypeParameter.IntroduceTypeParameterAction"
|
||||
text="T_ype Parameter...">
|
||||
<keyboard-shortcut keymap="$default" first-keystroke="control alt shift Y"/>
|
||||
<add-to-group group-id="IntroduceActionsGroup" anchor="after" relative-to-action="ExtractFunctionToScope"/>
|
||||
</action>
|
||||
|
||||
<action id="IntroduceTypeAlias" class="org.jetbrains.kotlin.idea.refactoring.introduce.introduceTypeAlias.IntroduceTypeAliasAction"
|
||||
text="Type _Alias...">
|
||||
<keyboard-shortcut keymap="$default" first-keystroke="control alt shift A"/>
|
||||
<add-to-group group-id="IntroduceActionsGroup" anchor="after" relative-to-action="ExtractFunctionToScope"/>
|
||||
<add-to-group group-id="IntroduceActionsGroup" anchor="after" relative-to-action="IntroduceTypeParameter"/>
|
||||
</action>
|
||||
|
||||
<!-- Kotlin Console REPL-->
|
||||
|
||||
+8
-4
@@ -53,18 +53,22 @@ object CreateTypeParameterByRefActionFactory : KotlinIntentionActionFactoryWithD
|
||||
return ktUserType
|
||||
}
|
||||
|
||||
override fun extractFixData(element: KtUserType, diagnostic: Diagnostic): CreateTypeParameterData? {
|
||||
val name = element.referencedName ?: return null
|
||||
fun extractFixData(element: KtTypeElement, newName: String): CreateTypeParameterData? {
|
||||
val declaration = element.parents.firstOrNull {
|
||||
it is KtProperty || it is KtNamedFunction || it is KtClass
|
||||
} as? KtTypeParameterListOwner ?: return null
|
||||
val containingDescriptor = declaration.resolveToDescriptor()
|
||||
val fakeTypeParameter = createFakeTypeParameterDescriptor(containingDescriptor, name)
|
||||
val fakeTypeParameter = createFakeTypeParameterDescriptor(containingDescriptor, newName)
|
||||
val upperBoundType = getUnsubstitutedTypeConstraintInfo(element)?.let {
|
||||
it.performSubstitution(it.typeParameter.typeConstructor to TypeProjectionImpl(fakeTypeParameter.defaultType))?.upperBound
|
||||
}
|
||||
if (upperBoundType != null && upperBoundType.containsError()) return null
|
||||
return CreateTypeParameterData(name, declaration, upperBoundType, fakeTypeParameter)
|
||||
return CreateTypeParameterData(newName, declaration, upperBoundType, fakeTypeParameter)
|
||||
}
|
||||
|
||||
override fun extractFixData(element: KtUserType, diagnostic: Diagnostic): CreateTypeParameterData? {
|
||||
val name = element.referencedName ?: return null
|
||||
return extractFixData(element, name)
|
||||
}
|
||||
|
||||
override fun createFixes(
|
||||
|
||||
+13
-5
@@ -42,16 +42,21 @@ import org.jetbrains.kotlin.types.typeUtil.isNullableAny
|
||||
import org.jetbrains.kotlin.utils.SmartList
|
||||
|
||||
class CreateTypeParameterFromUsageFix(
|
||||
originalElement: KtUserType,
|
||||
originalElement: KtTypeElement,
|
||||
private val data: CreateTypeParameterData
|
||||
) : CreateFromUsageFixBase<KtUserType>(originalElement) {
|
||||
) : CreateFromUsageFixBase<KtTypeElement>(originalElement) {
|
||||
override fun getText() = "Create type parameter '${data.name}' in " +
|
||||
ElementDescriptionUtil.getElementDescription(data.declaration, UsageViewTypeLocation.INSTANCE) + " '${data.declaration.name}'"
|
||||
|
||||
override fun startInWriteAction() = false
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
doInvoke()
|
||||
}
|
||||
|
||||
fun doInvoke(): KtTypeParameter? {
|
||||
val declaration = data.declaration
|
||||
val project = declaration.project
|
||||
val usages = project.runSynchronouslyWithProgress("Searching ${declaration.name}...", true) {
|
||||
runReadAction {
|
||||
ReferencesSearch
|
||||
@@ -62,9 +67,9 @@ class CreateTypeParameterFromUsageFix(
|
||||
}
|
||||
.toSet()
|
||||
}
|
||||
} ?: return
|
||||
} ?: return null
|
||||
|
||||
runWriteAction {
|
||||
return runWriteAction {
|
||||
val psiFactory = KtPsiFactory(project)
|
||||
|
||||
val elementsToShorten = SmartList<KtElement>()
|
||||
@@ -76,7 +81,8 @@ class CreateTypeParameterFromUsageFix(
|
||||
else null
|
||||
val upperBound = upperBoundText?.let { psiFactory.createType(it) }
|
||||
val newTypeParameterText = if (upperBound != null) "${data.name} : ${upperBound.text}" else data.name
|
||||
elementsToShorten += declaration.addTypeParameter(psiFactory.createTypeParameter(newTypeParameterText))!!
|
||||
val newTypeParameter = declaration.addTypeParameter(psiFactory.createTypeParameter(newTypeParameterText))!!
|
||||
elementsToShorten += newTypeParameter
|
||||
|
||||
val anonymizedTypeParameter = createFakeTypeParameterDescriptor(data.fakeTypeParameter.containingDeclaration, "_")
|
||||
val anonymizedUpperBoundText = upperBoundType?.let {
|
||||
@@ -132,6 +138,8 @@ class CreateTypeParameterFromUsageFix(
|
||||
}
|
||||
|
||||
ShortenReferences.DEFAULT.process(elementsToShorten)
|
||||
|
||||
newTypeParameter
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -25,7 +25,7 @@ cannot.refactor.synthesized.function=Cannot refactor synthesized function ''{0}'
|
||||
error.types.in.generated.function=Cannot generate function with erroneous return type
|
||||
cannot.introduce.parameter.of.0.type=Cannot introduce parameter of type ''{0}''
|
||||
|
||||
0.has.detected.1.code.fragments.in.this.file.that.can.be.replaced.with.a.call.to.extracted.declaration={0} has detected {1} code {1,choice,1#fragment|2#fragments} in this file that can be replaced with a call to extracted declaration. Would you like to review and replace {1,choice,1#it|2#them}?
|
||||
0.has.detected.1.code.fragments.in.this.file.that.can.be.replaced.with.a.call.to.extracted.declaration={0} has detected {1} code {1,choice,1#fragment|2#fragments} in this file that can be replaced with a usage of extracted declaration. Would you like to review and replace {1,choice,1#it|2#them}?
|
||||
|
||||
error.wrong.caret.position.function.or.constructor.name=The caret should be positioned at the name of the function or constructor to be refactored.
|
||||
error.cant.refactor.vararg.functions=Can't refactor the function with variable arguments
|
||||
|
||||
-2
@@ -176,8 +176,6 @@ fun IntroduceParameterDescriptor.performRefactoring() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun isObjectOrNonInnerClass(e: PsiElement): Boolean = e is KtObjectDeclaration || (e is KtClass && !e.isInner())
|
||||
|
||||
fun selectNewParameterContext(
|
||||
editor: Editor,
|
||||
file: KtFile,
|
||||
|
||||
+144
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
* Copyright 2010-2016 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.refactoring.introduce.introduceTypeParameter
|
||||
|
||||
import com.intellij.lang.refactoring.RefactoringSupportProvider
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys
|
||||
import com.intellij.openapi.actionSystem.DataContext
|
||||
import com.intellij.openapi.actionSystem.impl.SimpleDataContext
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.editor.ex.EditorEx
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.refactoring.RefactoringActionHandler
|
||||
import com.intellij.refactoring.rename.inplace.VariableInplaceRenameHandler
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.codeInsight.CodeInsightUtils
|
||||
import org.jetbrains.kotlin.idea.core.KotlinNameSuggester
|
||||
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.createTypeParameter.CreateTypeParameterByRefActionFactory
|
||||
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.createTypeParameter.CreateTypeParameterFromUsageFix
|
||||
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.createTypeParameter.getPossibleTypeParameterContainers
|
||||
import org.jetbrains.kotlin.idea.refactoring.introduce.AbstractIntroduceAction
|
||||
import org.jetbrains.kotlin.idea.refactoring.introduce.extractionEngine.processDuplicates
|
||||
import org.jetbrains.kotlin.idea.refactoring.introduce.introduceTypeAlias.KotlinIntroduceTypeAliasHandler
|
||||
import org.jetbrains.kotlin.idea.refactoring.introduce.selectElementsWithTargetParent
|
||||
import org.jetbrains.kotlin.idea.refactoring.introduce.showErrorHint
|
||||
import org.jetbrains.kotlin.idea.util.application.executeCommand
|
||||
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
||||
import org.jetbrains.kotlin.idea.util.getResolutionScope
|
||||
import org.jetbrains.kotlin.idea.util.psi.patternMatching.KotlinPsiUnifier
|
||||
import org.jetbrains.kotlin.idea.util.psi.patternMatching.toRange
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.KtPsiFactory
|
||||
import org.jetbrains.kotlin.psi.KtTypeElement
|
||||
import org.jetbrains.kotlin.psi.KtTypeParameterListOwner
|
||||
import org.jetbrains.kotlin.resolve.bindingContextUtil.getAbbreviatedTypeOrType
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.findClassifier
|
||||
import org.jetbrains.kotlin.utils.keysToMap
|
||||
import java.lang.AssertionError
|
||||
|
||||
object KotlinIntroduceTypeParameterHandler : RefactoringActionHandler {
|
||||
@JvmField
|
||||
val REFACTORING_NAME = "Introduce Type Parameter"
|
||||
|
||||
fun selectElements(editor: Editor, file: KtFile, continuation: (elements: List<PsiElement>, targetParent: PsiElement) -> Unit) {
|
||||
selectElementsWithTargetParent(
|
||||
REFACTORING_NAME,
|
||||
editor,
|
||||
file,
|
||||
"Introduce type parameter to declaration",
|
||||
listOf(CodeInsightUtils.ElementKind.TYPE_ELEMENT),
|
||||
{ elements, parent -> getPossibleTypeParameterContainers(parent) },
|
||||
continuation
|
||||
)
|
||||
}
|
||||
|
||||
fun doInvoke(project: Project, editor: Editor, elements: List<PsiElement>, targetParent: PsiElement) {
|
||||
val targetOwner = targetParent as KtTypeParameterListOwner
|
||||
val typeElementToExtract = elements.singleOrNull() as? KtTypeElement
|
||||
?: return showErrorHint(project, editor, "No type to refactor", REFACTORING_NAME)
|
||||
|
||||
val scope = targetOwner.getResolutionScope()
|
||||
val suggestedNames = KotlinNameSuggester.suggestNamesForTypeParameters(1) {
|
||||
scope.findClassifier(Name.identifier(it), NoLookupLocation.FROM_IDE) == null
|
||||
}
|
||||
val defaultName = suggestedNames.single()
|
||||
|
||||
val context = typeElementToExtract.analyze(BodyResolveMode.PARTIAL)
|
||||
val originalType = typeElementToExtract.getAbbreviatedTypeOrType(context)
|
||||
|
||||
val createTypeParameterData =
|
||||
CreateTypeParameterByRefActionFactory.extractFixData(typeElementToExtract, defaultName)
|
||||
?.copy(upperBoundType = originalType, declaration = targetOwner)
|
||||
?: return showErrorHint(project, editor, "Refactoring is not applicable in the current context", REFACTORING_NAME)
|
||||
|
||||
val parameterRefElement = KtPsiFactory(project).createType(defaultName).typeElement!!
|
||||
|
||||
val duplicateRanges = typeElementToExtract
|
||||
.toRange()
|
||||
.match(targetParent, KotlinPsiUnifier.DEFAULT)
|
||||
.filterNot {
|
||||
val textRange = it.range.getTextRange()
|
||||
typeElementToExtract.textRange.intersects(textRange) || targetOwner.typeParameterList?.textRange?.intersects(textRange) ?: false
|
||||
}
|
||||
.mapNotNull { it.range.elements.toRange() }
|
||||
|
||||
project.executeCommand(REFACTORING_NAME) {
|
||||
runWriteAction {
|
||||
typeElementToExtract.replace(parameterRefElement)
|
||||
|
||||
processDuplicates(
|
||||
duplicateRanges.keysToMap {
|
||||
{
|
||||
it.elements.singleOrNull()?.replace(parameterRefElement)
|
||||
Unit
|
||||
}
|
||||
},
|
||||
project,
|
||||
editor
|
||||
)
|
||||
}
|
||||
|
||||
val newTypeParameter = CreateTypeParameterFromUsageFix(typeElementToExtract, createTypeParameterData).doInvoke()
|
||||
?: return@executeCommand
|
||||
|
||||
if (!ApplicationManager.getApplication().isUnitTestMode) {
|
||||
val dataContext = SimpleDataContext.getSimpleContext(CommonDataKeys.PSI_ELEMENT.name, newTypeParameter,
|
||||
(editor as? EditorEx)?.dataContext)
|
||||
VariableInplaceRenameHandler().doRename(newTypeParameter, editor, dataContext)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun invoke(project: Project, editor: Editor, file: PsiFile, dataContext: DataContext?) {
|
||||
if (file !is KtFile) return
|
||||
selectElements(editor, file) { elements, targetParent -> doInvoke(project, editor, elements, targetParent) }
|
||||
}
|
||||
|
||||
override fun invoke(project: Project, elements: Array<out PsiElement>, dataContext: DataContext?) {
|
||||
throw AssertionError("${KotlinIntroduceTypeAliasHandler.REFACTORING_NAME} can only be invoked from editor")
|
||||
}
|
||||
}
|
||||
|
||||
class IntroduceTypeParameterAction : AbstractIntroduceAction() {
|
||||
override fun getRefactoringHandler(provider: RefactoringSupportProvider) = KotlinIntroduceTypeParameterHandler
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
class A
|
||||
|
||||
fun foo(x: List<A>, f: (<selection>A</selection>) -> Int) {
|
||||
val a: A? = x.firstOrNull()
|
||||
}
|
||||
|
||||
fun test() {
|
||||
foo(listOf(A())) { 1 }
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
class A
|
||||
|
||||
fun <T : A> foo(x: List<T>, f: (T) -> Int) {
|
||||
val a: T? = x.firstOrNull()
|
||||
}
|
||||
|
||||
fun test() {
|
||||
foo(listOf(A())) { 1 }
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
class A
|
||||
|
||||
fun foo(x: List<<selection>(A?) -> List<Int></selection>>) {
|
||||
|
||||
}
|
||||
|
||||
fun test() {
|
||||
foo(listOf({ a -> listOf(1) }))
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
class A
|
||||
|
||||
fun <T : (A?) -> List<Int>> foo(x: List<T>) {
|
||||
|
||||
}
|
||||
|
||||
fun test() {
|
||||
foo(listOf({ a -> listOf(1) }))
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
class A
|
||||
|
||||
open class X(x: List<A>, f: (<selection>A</selection>) -> Int) {
|
||||
val a: A? = x.firstOrNull()
|
||||
}
|
||||
|
||||
class Y : X(listOf(A()), { 1 })
|
||||
|
||||
fun test() {
|
||||
X(listOf(A())) { 1 }
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
class A
|
||||
|
||||
open class X<T : A>(x: List<T>, f: (T) -> Int) {
|
||||
val a: T? = x.firstOrNull()
|
||||
}
|
||||
|
||||
class Y : X<A>(listOf(A()), { 1 })
|
||||
|
||||
fun test() {
|
||||
X(listOf(A())) { 1 }
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
class A
|
||||
|
||||
val List<<selection>A</selection>>.foo: (A) -> Int
|
||||
get() {
|
||||
val a: A? = firstOrNull()
|
||||
return { 0 }
|
||||
}
|
||||
|
||||
fun test() {
|
||||
val t = listOf(A()).foo
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
class A
|
||||
|
||||
val <T : A> List<T>.foo: (T) -> Int
|
||||
get() {
|
||||
val a: T? = firstOrNull()
|
||||
return { 0 }
|
||||
}
|
||||
|
||||
fun test() {
|
||||
val t = listOf(A()).foo
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
class A
|
||||
|
||||
fun foo(x: List<<selection>A?</selection>>) {
|
||||
|
||||
}
|
||||
|
||||
fun test() {
|
||||
foo(listOf(A()))
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
class A
|
||||
|
||||
fun <T : A?> foo(x: List<T>) {
|
||||
|
||||
}
|
||||
|
||||
fun test() {
|
||||
foo(listOf(A()))
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
class A
|
||||
|
||||
fun foo(x: (<selection>List<A?></selection>) -> Int) {
|
||||
|
||||
}
|
||||
|
||||
fun test() {
|
||||
foo { 1 }
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
class A
|
||||
|
||||
fun <T : List<A?>> foo(x: (T) -> Int) {
|
||||
|
||||
}
|
||||
|
||||
fun test() {
|
||||
foo<List<A?>> { 1 }
|
||||
}
|
||||
@@ -45,6 +45,7 @@ import org.jetbrains.kotlin.idea.refactoring.introduce.introduceParameter.*
|
||||
import org.jetbrains.kotlin.idea.refactoring.introduce.introduceProperty.INTRODUCE_PROPERTY
|
||||
import org.jetbrains.kotlin.idea.refactoring.introduce.introduceProperty.KotlinIntroducePropertyHandler
|
||||
import org.jetbrains.kotlin.idea.refactoring.introduce.introduceTypeAlias.KotlinIntroduceTypeAliasHandler
|
||||
import org.jetbrains.kotlin.idea.refactoring.introduce.introduceTypeParameter.KotlinIntroduceTypeParameterHandler
|
||||
import org.jetbrains.kotlin.idea.refactoring.introduce.introduceVariable.KotlinIntroduceVariableHandler
|
||||
import org.jetbrains.kotlin.idea.test.ConfigLibraryUtil
|
||||
import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase
|
||||
@@ -314,6 +315,18 @@ abstract class AbstractExtractionTest() : KotlinLightCodeInsightFixtureTestCase(
|
||||
}
|
||||
}
|
||||
|
||||
protected fun doIntroduceTypeParameterTest(path: String) {
|
||||
doTest(path) { file ->
|
||||
file as KtFile
|
||||
|
||||
val explicitPreviousSibling = file.findElementByCommentPrefix("// SIBLING:")
|
||||
val editor = fixture.editor
|
||||
KotlinIntroduceTypeParameterHandler.selectElements(editor, file) { elements, previousSibling ->
|
||||
KotlinIntroduceTypeParameterHandler.doInvoke(project, editor, elements, explicitPreviousSibling ?: previousSibling)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected fun doIntroduceTypeAliasTest(path: String) {
|
||||
doTest(path) { file ->
|
||||
file as KtFile
|
||||
|
||||
+45
@@ -3992,6 +3992,51 @@ public class ExtractionTestGenerated extends AbstractExtractionTest {
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/refactoring/introduceTypeParameter")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class IntroduceTypeParameter extends AbstractExtractionTest {
|
||||
public void testAllFilesPresentInIntroduceTypeParameter() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/refactoring/introduceTypeParameter"), Pattern.compile("^(.+)\\.(kt|kts)$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("duplicates.kt")
|
||||
public void testDuplicates() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/introduceTypeParameter/duplicates.kt");
|
||||
doIntroduceTypeParameterTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("functionType.kt")
|
||||
public void testFunctionType() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/introduceTypeParameter/functionType.kt");
|
||||
doIntroduceTypeParameterTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("inClass.kt")
|
||||
public void testInClass() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/introduceTypeParameter/inClass.kt");
|
||||
doIntroduceTypeParameterTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("inProperty.kt")
|
||||
public void testInProperty() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/introduceTypeParameter/inProperty.kt");
|
||||
doIntroduceTypeParameterTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("nullableType.kt")
|
||||
public void testNullableType() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/introduceTypeParameter/nullableType.kt");
|
||||
doIntroduceTypeParameterTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("userType.kt")
|
||||
public void testUserType() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/introduceTypeParameter/userType.kt");
|
||||
doIntroduceTypeParameterTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/refactoring/introduceTypeAlias")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
Reference in New Issue
Block a user