mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-04-03 00:21:31 +00:00
Create from Usage: Support adding type parameters to the referenced type
#KT-11760 Fixed
This commit is contained in:
@@ -341,6 +341,7 @@ These artifacts include extensions for the types available in the latter JDKs, s
|
||||
##### New features
|
||||
|
||||
- [`KT-14729`](https://youtrack.jetbrains.com/issue/KT-14729) Implement "Add names to call arguments" intention
|
||||
- [`KT-11760`](https://youtrack.jetbrains.com/issue/KT-11760) Create from Usage: Support adding type parameters to the referenced type
|
||||
|
||||
#### Refactorings
|
||||
|
||||
|
||||
@@ -29,7 +29,8 @@ import org.jetbrains.kotlin.idea.quickfix.createFromUsage.createClass.CreateClas
|
||||
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.createClass.CreateClassFromReferenceExpressionActionFactory
|
||||
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.createClass.CreateClassFromTypeReferenceActionFactory
|
||||
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.createTypeAlias.CreateTypeAliasFromTypeReferenceActionFactory
|
||||
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.createTypeParameter.CreateTypeParameterByRefActionFactory
|
||||
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.createTypeParameter.CreateTypeParameterByUnresolvedRefActionFactory
|
||||
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.createTypeParameter.CreateTypeParameterUnmatchedTypeArgumentActionFactory
|
||||
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.createVariable.CreateLocalVariableActionFactory
|
||||
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.createVariable.CreateParameterByNamedArgumentActionFactory
|
||||
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.createVariable.CreateParameterByRefActionFactory
|
||||
@@ -429,7 +430,8 @@ class QuickFixRegistrar : QuickFixContributor {
|
||||
|
||||
VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION.registerFactory(AddTypeAnnotationToValueParameterFix)
|
||||
|
||||
UNRESOLVED_REFERENCE.registerFactory(CreateTypeParameterByRefActionFactory)
|
||||
UNRESOLVED_REFERENCE.registerFactory(CreateTypeParameterByUnresolvedRefActionFactory)
|
||||
WRONG_NUMBER_OF_TYPE_ARGUMENTS.registerFactory(CreateTypeParameterUnmatchedTypeArgumentActionFactory)
|
||||
|
||||
FINAL_UPPER_BOUND.registerFactory(InlineTypeParameterFix)
|
||||
FINAL_UPPER_BOUND.registerFactory(RemoveFinalUpperBoundFix)
|
||||
|
||||
@@ -37,14 +37,18 @@ import org.jetbrains.kotlin.types.TypeProjectionImpl
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import org.jetbrains.kotlin.types.typeUtil.containsError
|
||||
|
||||
data class CreateTypeParameterData(
|
||||
data class TypeParameterInfo(
|
||||
val name: String,
|
||||
val declaration: KtTypeParameterListOwner,
|
||||
val upperBoundType: KotlinType?,
|
||||
val fakeTypeParameter: TypeParameterDescriptor
|
||||
)
|
||||
|
||||
object CreateTypeParameterByRefActionFactory : KotlinIntentionActionFactoryWithDelegate<KtUserType, CreateTypeParameterData>() {
|
||||
data class CreateTypeParameterData(
|
||||
val declaration: KtTypeParameterListOwner,
|
||||
val typeParameters: List<TypeParameterInfo>
|
||||
)
|
||||
|
||||
object CreateTypeParameterByUnresolvedRefActionFactory : KotlinIntentionActionFactoryWithDelegate<KtUserType, CreateTypeParameterData>() {
|
||||
override fun getElementOfInterest(diagnostic: Diagnostic): KtUserType? {
|
||||
val ktUserType = diagnostic.psiElement.getParentOfTypeAndBranch<KtUserType> { referenceExpression } ?: return null
|
||||
if (ktUserType.qualifier != null) return null
|
||||
@@ -63,7 +67,7 @@ object CreateTypeParameterByRefActionFactory : KotlinIntentionActionFactoryWithD
|
||||
it.performSubstitution(it.typeParameter.typeConstructor to TypeProjectionImpl(fakeTypeParameter.defaultType))?.upperBound
|
||||
}
|
||||
if (upperBoundType != null && upperBoundType.containsError()) return null
|
||||
return CreateTypeParameterData(newName, declaration, upperBoundType, fakeTypeParameter)
|
||||
return CreateTypeParameterData(declaration, listOf(TypeParameterInfo(newName, upperBoundType, fakeTypeParameter)))
|
||||
}
|
||||
|
||||
override fun extractFixData(element: KtUserType, diagnostic: Diagnostic): CreateTypeParameterData? {
|
||||
@@ -84,7 +88,7 @@ object CreateTypeParameterByRefActionFactory : KotlinIntentionActionFactoryWithD
|
||||
QuickFixWithDelegateFactory factory@ {
|
||||
val originalElement = originalElementPointer.element ?: return@factory null
|
||||
val data = quickFixDataFactory()?.copy(declaration = it) ?: return@factory null
|
||||
CreateTypeParameterFromUsageFix(originalElement, data)
|
||||
CreateTypeParameterFromUsageFix(originalElement, data, presentTypeParameterNames = true)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.idea.quickfix.createFromUsage.createTypeParameter
|
||||
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
import com.intellij.psi.ElementDescriptionUtil
|
||||
import com.intellij.psi.search.searches.ReferencesSearch
|
||||
import com.intellij.usageView.UsageViewTypeLocation
|
||||
@@ -42,11 +43,17 @@ import org.jetbrains.kotlin.types.typeUtil.isNullableAny
|
||||
import org.jetbrains.kotlin.utils.SmartList
|
||||
|
||||
class CreateTypeParameterFromUsageFix(
|
||||
originalElement: KtTypeElement,
|
||||
private val data: CreateTypeParameterData
|
||||
) : CreateFromUsageFixBase<KtTypeElement>(originalElement) {
|
||||
override fun getText() = "Create type parameter '${data.name}' in " +
|
||||
ElementDescriptionUtil.getElementDescription(data.declaration, UsageViewTypeLocation.INSTANCE) + " '${data.declaration.name}'"
|
||||
originalElement: KtElement,
|
||||
private val data: CreateTypeParameterData,
|
||||
private val presentTypeParameterNames: Boolean
|
||||
) : CreateFromUsageFixBase<KtElement>(originalElement) {
|
||||
override fun getText(): String {
|
||||
val prefix = "type parameter".let { if (data.typeParameters.size > 1) StringUtil.pluralize(it) else it }
|
||||
val typeParametersText = if (presentTypeParameterNames) data.typeParameters.joinToString(prefix = " ") { "'${it.name}'" } else ""
|
||||
val containerText = ElementDescriptionUtil.getElementDescription(data.declaration, UsageViewTypeLocation.INSTANCE) +
|
||||
" '${data.declaration.name}'"
|
||||
return "Create $prefix$typeParametersText in $containerText"
|
||||
}
|
||||
|
||||
override fun startInWriteAction() = false
|
||||
|
||||
@@ -54,92 +61,105 @@ class CreateTypeParameterFromUsageFix(
|
||||
doInvoke()
|
||||
}
|
||||
|
||||
fun doInvoke(): KtTypeParameter? {
|
||||
fun doInvoke(): List<KtTypeParameter> {
|
||||
val declaration = data.declaration
|
||||
val project = declaration.project
|
||||
val usages = project.runSynchronouslyWithProgress("Searching ${declaration.name}...", true) {
|
||||
runReadAction {
|
||||
val expectedTypeArgumentCount = declaration.typeParameters.size + data.typeParameters.size
|
||||
ReferencesSearch
|
||||
.search(declaration)
|
||||
.mapNotNull {
|
||||
it.element.getParentOfTypeAndBranch<KtUserType> { referenceExpression } ?:
|
||||
it.element.getParentOfTypeAndBranch<KtCallElement> { calleeExpression }
|
||||
}
|
||||
.filter {
|
||||
val arguments = when (it) {
|
||||
is KtUserType -> it.typeArguments
|
||||
is KtCallElement -> it.typeArguments
|
||||
else -> return@filter false
|
||||
}
|
||||
arguments.size != expectedTypeArgumentCount
|
||||
}
|
||||
.toSet()
|
||||
}
|
||||
} ?: return null
|
||||
} ?: return emptyList()
|
||||
|
||||
return runWriteAction {
|
||||
val psiFactory = KtPsiFactory(project)
|
||||
|
||||
val elementsToShorten = SmartList<KtElement>()
|
||||
|
||||
val upperBoundType = data.upperBoundType
|
||||
val upperBoundText = if (upperBoundType != null && !upperBoundType.isNullableAny()) {
|
||||
IdeDescriptorRenderers.SOURCE_CODE.renderType(upperBoundType)
|
||||
}
|
||||
else null
|
||||
val upperBound = upperBoundText?.let { psiFactory.createType(it) }
|
||||
val newTypeParameterText = if (upperBound != null) "${data.name} : ${upperBound.text}" else data.name
|
||||
val newTypeParameter = declaration.addTypeParameter(psiFactory.createTypeParameter(newTypeParameterText))!!
|
||||
elementsToShorten += newTypeParameter
|
||||
val newTypeParameters = data.typeParameters.map { typeParameter ->
|
||||
val upperBoundType = typeParameter.upperBoundType
|
||||
val upperBoundText = if (upperBoundType != null && !upperBoundType.isNullableAny()) {
|
||||
IdeDescriptorRenderers.SOURCE_CODE.renderType(upperBoundType)
|
||||
}
|
||||
else null
|
||||
val upperBound = upperBoundText?.let { psiFactory.createType(it) }
|
||||
val newTypeParameterText = if (upperBound != null) "${typeParameter.name} : ${upperBound.text}" else typeParameter.name
|
||||
val newTypeParameter = declaration.addTypeParameter(psiFactory.createTypeParameter(newTypeParameterText))!!
|
||||
elementsToShorten += newTypeParameter
|
||||
|
||||
val anonymizedTypeParameter = createFakeTypeParameterDescriptor(data.fakeTypeParameter.containingDeclaration, "_")
|
||||
val anonymizedUpperBoundText = upperBoundType?.let {
|
||||
TypeSubstitutor
|
||||
.create(mapOf(data.fakeTypeParameter.typeConstructor to TypeProjectionImpl(anonymizedTypeParameter.defaultType)))
|
||||
.substitute(upperBoundType, Variance.INVARIANT)
|
||||
}?.let {
|
||||
IdeDescriptorRenderers.SOURCE_CODE.renderType(it)
|
||||
}
|
||||
val anonymizedTypeParameter = createFakeTypeParameterDescriptor(typeParameter.fakeTypeParameter.containingDeclaration, "_")
|
||||
val anonymizedUpperBoundText = upperBoundType?.let {
|
||||
TypeSubstitutor
|
||||
.create(mapOf(typeParameter.fakeTypeParameter.typeConstructor to TypeProjectionImpl(anonymizedTypeParameter.defaultType)))
|
||||
.substitute(upperBoundType, Variance.INVARIANT)
|
||||
}?.let {
|
||||
IdeDescriptorRenderers.SOURCE_CODE.renderType(it)
|
||||
}
|
||||
|
||||
val anonymizedUpperBoundAsTypeArg = psiFactory.createTypeArgument(anonymizedUpperBoundText ?: "kotlin.Any?")
|
||||
val anonymizedUpperBoundAsTypeArg = psiFactory.createTypeArgument(anonymizedUpperBoundText ?: "kotlin.Any?")
|
||||
|
||||
val callsToExplicateArguments = SmartList<KtCallElement>()
|
||||
usages.forEach {
|
||||
when (it) {
|
||||
is KtUserType -> {
|
||||
val typeArgumentList = it.typeArgumentList
|
||||
elementsToShorten += if (typeArgumentList != null) {
|
||||
typeArgumentList.addArgument(anonymizedUpperBoundAsTypeArg)
|
||||
val callsToExplicateArguments = SmartList<KtCallElement>()
|
||||
usages.forEach {
|
||||
when (it) {
|
||||
is KtUserType -> {
|
||||
val typeArgumentList = it.typeArgumentList
|
||||
elementsToShorten += if (typeArgumentList != null) {
|
||||
typeArgumentList.addArgument(anonymizedUpperBoundAsTypeArg)
|
||||
}
|
||||
else {
|
||||
it.addAfter(
|
||||
psiFactory.createTypeArguments("<${anonymizedUpperBoundAsTypeArg.text}>"),
|
||||
it.referenceExpression!!
|
||||
) as KtTypeArgumentList
|
||||
}
|
||||
}
|
||||
else {
|
||||
it.addAfter(
|
||||
psiFactory.createTypeArguments("<${anonymizedUpperBoundAsTypeArg.text}>"),
|
||||
it.referenceExpression!!
|
||||
) as KtTypeArgumentList
|
||||
}
|
||||
}
|
||||
is KtCallElement -> {
|
||||
if (it.analyze(BodyResolveMode.PARTIAL_WITH_DIAGNOSTICS).diagnostics.forElement(it.calleeExpression!!).any {
|
||||
it.factory in Errors.TYPE_INFERENCE_ERRORS
|
||||
}) {
|
||||
callsToExplicateArguments += it
|
||||
is KtCallElement -> {
|
||||
if (it.analyze(BodyResolveMode.PARTIAL_WITH_DIAGNOSTICS).diagnostics.forElement(it.calleeExpression!!).any {
|
||||
it.factory in Errors.TYPE_INFERENCE_ERRORS
|
||||
}) {
|
||||
callsToExplicateArguments += it
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
callsToExplicateArguments.forEach {
|
||||
val typeArgumentList = it.typeArgumentList
|
||||
if (typeArgumentList == null) {
|
||||
InsertExplicitTypeArgumentsIntention.applyTo(it, shortenReferences = false)
|
||||
callsToExplicateArguments.forEach {
|
||||
val typeArgumentList = it.typeArgumentList
|
||||
if (typeArgumentList == null) {
|
||||
InsertExplicitTypeArgumentsIntention.applyTo(it, shortenReferences = false)
|
||||
|
||||
val newTypeArgument = it.typeArguments.lastOrNull()
|
||||
if (anonymizedUpperBoundText != null && newTypeArgument != null && newTypeArgument.text == "kotlin.Any") {
|
||||
newTypeArgument.replaced(anonymizedUpperBoundAsTypeArg)
|
||||
val newTypeArgument = it.typeArguments.lastOrNull()
|
||||
if (anonymizedUpperBoundText != null && newTypeArgument != null && newTypeArgument.text == "kotlin.Any") {
|
||||
newTypeArgument.replaced(anonymizedUpperBoundAsTypeArg)
|
||||
}
|
||||
|
||||
elementsToShorten += it.typeArgumentList
|
||||
}
|
||||
else {
|
||||
elementsToShorten += typeArgumentList.addArgument(anonymizedUpperBoundAsTypeArg)
|
||||
}
|
||||
}
|
||||
|
||||
elementsToShorten += it.typeArgumentList
|
||||
}
|
||||
else {
|
||||
elementsToShorten += typeArgumentList.addArgument(anonymizedUpperBoundAsTypeArg)
|
||||
}
|
||||
newTypeParameter
|
||||
}
|
||||
|
||||
ShortenReferences.DEFAULT.process(elementsToShorten)
|
||||
|
||||
newTypeParameter
|
||||
newTypeParameters
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* 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.quickfix.createFromUsage.createTypeParameter
|
||||
|
||||
import com.intellij.psi.SmartPsiElementPointer
|
||||
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde
|
||||
import org.jetbrains.kotlin.idea.core.CollectingNameValidator
|
||||
import org.jetbrains.kotlin.idea.core.KotlinNameSuggester
|
||||
import org.jetbrains.kotlin.idea.quickfix.KotlinIntentionActionFactoryWithDelegate
|
||||
import org.jetbrains.kotlin.idea.quickfix.QuickFixWithDelegateFactory
|
||||
import org.jetbrains.kotlin.idea.util.getResolutionScope
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtCallElement
|
||||
import org.jetbrains.kotlin.psi.KtTypeArgumentList
|
||||
import org.jetbrains.kotlin.psi.KtTypeParameterListOwner
|
||||
import org.jetbrains.kotlin.psi.KtUserType
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.findClassifier
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.singletonList
|
||||
|
||||
object CreateTypeParameterUnmatchedTypeArgumentActionFactory : KotlinIntentionActionFactoryWithDelegate<KtTypeArgumentList, CreateTypeParameterData>() {
|
||||
override fun getElementOfInterest(diagnostic: Diagnostic) = diagnostic.psiElement as? KtTypeArgumentList
|
||||
|
||||
override fun extractFixData(element: KtTypeArgumentList, diagnostic: Diagnostic): CreateTypeParameterData? {
|
||||
val project = element.project
|
||||
val typeArguments = element.arguments
|
||||
val context = element.analyze()
|
||||
val parent = element.parent
|
||||
val referencedDescriptor = when (parent) {
|
||||
is KtUserType -> context[BindingContext.REFERENCE_TARGET, parent.referenceExpression]
|
||||
is KtCallElement -> parent.getResolvedCall(context)?.resultingDescriptor
|
||||
else -> null
|
||||
} ?: return null
|
||||
val referencedDeclaration = DescriptorToSourceUtilsIde.getAnyDeclaration(project, referencedDescriptor) as? KtTypeParameterListOwner
|
||||
?: return null
|
||||
|
||||
val missingParameterCount = typeArguments.size - referencedDeclaration.typeParameters.size
|
||||
if (missingParameterCount <= 0) return null
|
||||
|
||||
val scope = referencedDeclaration.getResolutionScope()
|
||||
val suggestedNames = KotlinNameSuggester.suggestNamesForTypeParameters(
|
||||
missingParameterCount,
|
||||
CollectingNameValidator(referencedDeclaration.typeParameters.mapNotNull { it.name }) {
|
||||
scope.findClassifier(Name.identifier(it), NoLookupLocation.FROM_IDE) == null
|
||||
}
|
||||
)
|
||||
val typeParameterInfos = suggestedNames.map { name ->
|
||||
TypeParameterInfo(
|
||||
name,
|
||||
null,
|
||||
createFakeTypeParameterDescriptor(referencedDescriptor, name)
|
||||
)
|
||||
}
|
||||
return CreateTypeParameterData(referencedDeclaration, typeParameterInfos)
|
||||
}
|
||||
|
||||
override fun createFixes(
|
||||
originalElementPointer: SmartPsiElementPointer<KtTypeArgumentList>,
|
||||
diagnostic: Diagnostic,
|
||||
quickFixDataFactory: () -> CreateTypeParameterData?
|
||||
): List<QuickFixWithDelegateFactory> {
|
||||
return QuickFixWithDelegateFactory factory@ {
|
||||
val originalElement = originalElementPointer.element ?: return@factory null
|
||||
val data = quickFixDataFactory() ?: return@factory null
|
||||
CreateTypeParameterFromUsageFix(originalElement, data, false)
|
||||
}.singletonList()
|
||||
}
|
||||
}
|
||||
@@ -33,7 +33,7 @@ import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.codeInsight.CodeInsightUtils
|
||||
import org.jetbrains.kotlin.idea.core.CollectingNameValidator
|
||||
import org.jetbrains.kotlin.idea.core.KotlinNameSuggester
|
||||
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.createTypeParameter.CreateTypeParameterByRefActionFactory
|
||||
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.createTypeParameter.CreateTypeParameterByUnresolvedRefActionFactory
|
||||
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
|
||||
@@ -99,12 +99,12 @@ object KotlinIntroduceTypeParameterHandler : RefactoringActionHandler {
|
||||
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)
|
||||
CreateTypeParameterByUnresolvedRefActionFactory.extractFixData(typeElementToExtract, defaultName)?.let {
|
||||
it.copy(typeParameters = listOf(it.typeParameters.single().copy(upperBoundType = originalType)), declaration = targetOwner)
|
||||
} ?: return showErrorHint(project, editor, "Refactoring is not applicable in the current context", REFACTORING_NAME)
|
||||
|
||||
project.executeCommand(REFACTORING_NAME) {
|
||||
val newTypeParameter = CreateTypeParameterFromUsageFix(typeElementToExtract, createTypeParameterData).doInvoke()
|
||||
val newTypeParameter = CreateTypeParameterFromUsageFix(typeElementToExtract, createTypeParameterData, false).doInvoke().singleOrNull()
|
||||
?: return@executeCommand
|
||||
val newTypeParameterPointer = newTypeParameter.createSmartPointer()
|
||||
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
// "Create type parameters in class 'X'" "true"
|
||||
|
||||
class X<T>
|
||||
|
||||
fun foo(x: X<<caret>String, Int, Boolean>) {}
|
||||
@@ -0,0 +1,5 @@
|
||||
// "Create type parameters in class 'X'" "true"
|
||||
|
||||
class X<T, U, V>
|
||||
|
||||
fun foo(x: X<<caret>String, Int, Boolean>) {}
|
||||
@@ -0,0 +1,5 @@
|
||||
// "Create type parameter in class 'X'" "true"
|
||||
|
||||
class X
|
||||
|
||||
fun foo(x: X<<caret>String>) {}
|
||||
@@ -0,0 +1,5 @@
|
||||
// "Create type parameter in class 'X'" "true"
|
||||
|
||||
class X<T>
|
||||
|
||||
fun foo(x: X<<caret>String>) {}
|
||||
@@ -0,0 +1,9 @@
|
||||
// "Create type parameter in function 'bar'" "true"
|
||||
|
||||
fun bar() {
|
||||
|
||||
}
|
||||
|
||||
fun foo() {
|
||||
bar<<caret>String>()
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// "Create type parameter in function 'bar'" "true"
|
||||
|
||||
fun <T> bar() {
|
||||
|
||||
}
|
||||
|
||||
fun foo() {
|
||||
bar<<caret>String>()
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// "Create type parameter in class 'X'" "false"
|
||||
// ERROR: 2 type arguments expected for class X<T, U> defined in root package
|
||||
class X<T, U>
|
||||
fun Y(x: X<<caret>String>) {}
|
||||
@@ -0,0 +1,6 @@
|
||||
// "Create type parameter in class 'X'" "false"
|
||||
// ERROR: No type arguments expected for class X defined in root package
|
||||
|
||||
class X
|
||||
|
||||
fun foo(x: <caret>X<String>) {}
|
||||
@@ -1308,6 +1308,16 @@ public class QuickFixMultiFileTestGenerated extends AbstractQuickFixMultiFileTes
|
||||
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/quickfix/createFromUsage/createTypeParameter")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class CreateTypeParameter extends AbstractQuickFixMultiFileTest {
|
||||
public void testAllFilesPresentInCreateTypeParameter() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/createFromUsage/createTypeParameter"), Pattern.compile("^(\\w+)\\.((before\\.Main\\.\\w+)|(test))$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/quickfix/createFromUsage/createVariable")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
@@ -3174,70 +3174,118 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/createFromUsage/createTypeParameter"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("classNoExplication.kt")
|
||||
public void testClassNoExplication() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createTypeParameter/classNoExplication.kt");
|
||||
doTest(fileName);
|
||||
@TestMetadata("idea/testData/quickfix/createFromUsage/createTypeParameter/inContainingDeclaration")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class InContainingDeclaration extends AbstractQuickFixTest {
|
||||
public void testAllFilesPresentInInContainingDeclaration() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/createFromUsage/createTypeParameter/inContainingDeclaration"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("classNoExplication.kt")
|
||||
public void testClassNoExplication() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createTypeParameter/inContainingDeclaration/classNoExplication.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("classWithExplication.kt")
|
||||
public void testClassWithExplication() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createTypeParameter/inContainingDeclaration/classWithExplication.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("classWithExplicationAndRecursiveUpperBound.kt")
|
||||
public void testClassWithExplicationAndRecursiveUpperBound() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createTypeParameter/inContainingDeclaration/classWithExplicationAndRecursiveUpperBound.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("classWithExplicationAndUpperBound.kt")
|
||||
public void testClassWithExplicationAndUpperBound() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createTypeParameter/inContainingDeclaration/classWithExplicationAndUpperBound.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("functionNoExplication.kt")
|
||||
public void testFunctionNoExplication() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createTypeParameter/inContainingDeclaration/functionNoExplication.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("functionWithExplication.kt")
|
||||
public void testFunctionWithExplication() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createTypeParameter/inContainingDeclaration/functionWithExplication.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("functionWithExplicationAndRecursiveUpperBound.kt")
|
||||
public void testFunctionWithExplicationAndRecursiveUpperBound() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createTypeParameter/inContainingDeclaration/functionWithExplicationAndRecursiveUpperBound.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("functionWithExplicationAndUpperBound.kt")
|
||||
public void testFunctionWithExplicationAndUpperBound() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createTypeParameter/inContainingDeclaration/functionWithExplicationAndUpperBound.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("qualifiedType.kt")
|
||||
public void testQualifiedType() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createTypeParameter/inContainingDeclaration/qualifiedType.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("typeQualifier.kt")
|
||||
public void testTypeQualifier() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createTypeParameter/inContainingDeclaration/typeQualifier.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("withTypeArguments.kt")
|
||||
public void testWithTypeArguments() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createTypeParameter/inContainingDeclaration/withTypeArguments.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("classWithExplication.kt")
|
||||
public void testClassWithExplication() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createTypeParameter/classWithExplication.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
@TestMetadata("idea/testData/quickfix/createFromUsage/createTypeParameter/inReferencedDeclaration")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class InReferencedDeclaration extends AbstractQuickFixTest {
|
||||
@TestMetadata("addMultiple.kt")
|
||||
public void testAddMultiple() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createTypeParameter/inReferencedDeclaration/addMultiple.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("classWithExplicationAndRecursiveUpperBound.kt")
|
||||
public void testClassWithExplicationAndRecursiveUpperBound() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createTypeParameter/classWithExplicationAndRecursiveUpperBound.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
@TestMetadata("addSingle.kt")
|
||||
public void testAddSingle() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createTypeParameter/inReferencedDeclaration/addSingle.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("classWithExplicationAndUpperBound.kt")
|
||||
public void testClassWithExplicationAndUpperBound() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createTypeParameter/classWithExplicationAndUpperBound.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
@TestMetadata("addToFunction.kt")
|
||||
public void testAddToFunction() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createTypeParameter/inReferencedDeclaration/addToFunction.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("functionNoExplication.kt")
|
||||
public void testFunctionNoExplication() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createTypeParameter/functionNoExplication.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
public void testAllFilesPresentInInReferencedDeclaration() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/createFromUsage/createTypeParameter/inReferencedDeclaration"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("functionWithExplication.kt")
|
||||
public void testFunctionWithExplication() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createTypeParameter/functionWithExplication.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
@TestMetadata("missingArguments.kt")
|
||||
public void testMissingArguments() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createTypeParameter/inReferencedDeclaration/missingArguments.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("functionWithExplicationAndRecursiveUpperBound.kt")
|
||||
public void testFunctionWithExplicationAndRecursiveUpperBound() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createTypeParameter/functionWithExplicationAndRecursiveUpperBound.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("functionWithExplicationAndUpperBound.kt")
|
||||
public void testFunctionWithExplicationAndUpperBound() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createTypeParameter/functionWithExplicationAndUpperBound.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("qualifiedType.kt")
|
||||
public void testQualifiedType() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createTypeParameter/qualifiedType.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("typeQualifier.kt")
|
||||
public void testTypeQualifier() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createTypeParameter/typeQualifier.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("withTypeArguments.kt")
|
||||
public void testWithTypeArguments() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createTypeParameter/withTypeArguments.kt");
|
||||
doTest(fileName);
|
||||
@TestMetadata("notOnTypeArgumentList.kt")
|
||||
public void testNotOnTypeArgumentList() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createTypeParameter/inReferencedDeclaration/notOnTypeArgumentList.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user