From 8ba61ce7aa412810ca220be2effe34028337b6d4 Mon Sep 17 00:00:00 2001 From: qx Date: Wed, 3 May 2017 17:32:35 +0300 Subject: [PATCH] Fixed KT-15270 Quickfix to migrate from @native*** --- .../migration/MigrateExternalExtensionFix.kt | 121 ++++++++++++++++-- .../migration/jsExternal/nativeMemberAll01.kt | 19 +++ .../jsExternal/nativeMemberAll01.kt.after | 25 ++++ .../migration/jsExternal/nativeMemberAll02.kt | 19 +++ .../jsExternal/nativeMemberAll02.kt.after | 25 ++++ .../migration/jsExternal/nativeMemberAll03.kt | 18 +++ .../jsExternal/nativeMemberAll03.kt.after | 25 ++++ .../jsExternal/nativeMemberGetter.kt | 8 ++ .../jsExternal/nativeMemberGetter.kt.after | 10 ++ .../jsExternal/nativeMemberInvoke.kt | 8 ++ .../jsExternal/nativeMemberInvoke.kt.after | 10 ++ .../nativeMemberInvokeGenericClass.kt | 9 ++ .../nativeMemberInvokeGenericClass.kt.after | 11 ++ .../nativeMemberInvokeGenericClassAndFun.kt | 9 ++ ...iveMemberInvokeGenericClassAndFun.kt.after | 11 ++ .../nativeMemberInvokeGenericFun.kt | 8 ++ .../nativeMemberInvokeGenericFun.kt.after | 10 ++ .../jsExternal/nativeMemberNative.kt | 8 ++ .../jsExternal/nativeMemberNative.kt.after | 7 + .../jsExternal/nativeMemberSetter.kt | 8 ++ .../jsExternal/nativeMemberSetter.kt.after | 8 ++ .../idea/quickfix/QuickFixTestGenerated.java | 60 +++++++++ 22 files changed, 427 insertions(+), 10 deletions(-) create mode 100644 idea/testData/quickfix/migration/jsExternal/nativeMemberAll01.kt create mode 100644 idea/testData/quickfix/migration/jsExternal/nativeMemberAll01.kt.after create mode 100644 idea/testData/quickfix/migration/jsExternal/nativeMemberAll02.kt create mode 100644 idea/testData/quickfix/migration/jsExternal/nativeMemberAll02.kt.after create mode 100644 idea/testData/quickfix/migration/jsExternal/nativeMemberAll03.kt create mode 100644 idea/testData/quickfix/migration/jsExternal/nativeMemberAll03.kt.after create mode 100644 idea/testData/quickfix/migration/jsExternal/nativeMemberGetter.kt create mode 100644 idea/testData/quickfix/migration/jsExternal/nativeMemberGetter.kt.after create mode 100644 idea/testData/quickfix/migration/jsExternal/nativeMemberInvoke.kt create mode 100644 idea/testData/quickfix/migration/jsExternal/nativeMemberInvoke.kt.after create mode 100644 idea/testData/quickfix/migration/jsExternal/nativeMemberInvokeGenericClass.kt create mode 100644 idea/testData/quickfix/migration/jsExternal/nativeMemberInvokeGenericClass.kt.after create mode 100644 idea/testData/quickfix/migration/jsExternal/nativeMemberInvokeGenericClassAndFun.kt create mode 100644 idea/testData/quickfix/migration/jsExternal/nativeMemberInvokeGenericClassAndFun.kt.after create mode 100644 idea/testData/quickfix/migration/jsExternal/nativeMemberInvokeGenericFun.kt create mode 100644 idea/testData/quickfix/migration/jsExternal/nativeMemberInvokeGenericFun.kt.after create mode 100644 idea/testData/quickfix/migration/jsExternal/nativeMemberNative.kt create mode 100644 idea/testData/quickfix/migration/jsExternal/nativeMemberNative.kt.after create mode 100644 idea/testData/quickfix/migration/jsExternal/nativeMemberSetter.kt create mode 100644 idea/testData/quickfix/migration/jsExternal/nativeMemberSetter.kt.after diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/migration/MigrateExternalExtensionFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/migration/MigrateExternalExtensionFix.kt index 8a07d3855af..62ea975f671 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/migration/MigrateExternalExtensionFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/migration/MigrateExternalExtensionFix.kt @@ -21,15 +21,19 @@ import com.intellij.openapi.editor.Editor import com.intellij.openapi.project.Project import com.intellij.psi.PsiElement import org.jetbrains.kotlin.builtins.KotlinBuiltIns +import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.annotations.checkAnnotationName import org.jetbrains.kotlin.diagnostics.Diagnostic import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.idea.caches.resolve.analyze +import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor +import org.jetbrains.kotlin.idea.core.setReceiverType import org.jetbrains.kotlin.idea.intentions.SpecifyTypeExplicitlyIntention import org.jetbrains.kotlin.idea.project.builtIns import org.jetbrains.kotlin.idea.quickfix.CleanupFix import org.jetbrains.kotlin.idea.quickfix.KotlinQuickFixAction import org.jetbrains.kotlin.idea.quickfix.KotlinSingleIntentionActionFactory +import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.* import org.jetbrains.kotlin.idea.util.addAnnotation import org.jetbrains.kotlin.js.PredefinedAnnotation import org.jetbrains.kotlin.js.resolve.diagnostics.ErrorsJs @@ -37,6 +41,7 @@ import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode @@ -48,12 +53,95 @@ class MigrateExternalExtensionFix(declaration: KtNamedDeclaration) override fun invoke(project: Project, editor: Editor?, file: KtFile) { val declaration = element ?: return - if (isExternalMemberDeclaration(declaration)) { - fixExtensionMemberDeclaration(declaration, project, editor, file) - return + + when { + isExternalMemberDeclaration(declaration) -> fixExtensionMemberDeclaration(declaration, project, editor, file) + isMemberDeclaration(declaration) -> { + val containingClass = declaration.containingClassOrObject + if (containingClass != null) { + fixNativeClass(containingClass, project, editor, file) + } + } + declaration is KtClassOrObject -> fixNativeClass(declaration, project, editor, file) } } + private fun fixNativeClass(containingClass: KtClassOrObject, project: Project, editor: Editor?, file: KtFile) { + val membersToFix = containingClass.declarations.filterIsInstance().filter { isMemberDeclaration(it) }. map { + it to fetchJsNativeAnnotations(it) + }.filter { + it.second.annotations.isNotEmpty() + } + + var anchor: PsiElement = containingClass + membersToFix.forEach { (memberDeclaration, annotations) -> + if (annotations.nativeAnnotation != null && !annotations.isGetter && !annotations.isSetter && !annotations.isInvoke) { + convertNativeAnnotationToJsName(memberDeclaration, annotations) + annotations.nativeAnnotation.delete() + } else { + // TODO: find references + createExtensionDeclaration(memberDeclaration, project, anchor)?.let { externalDeclaration -> + memberDeclaration.delete() + fixExtensionMemberDeclaration(externalDeclaration, project, null, file) + anchor = externalDeclaration + } + } + } + + // make class external + val classAnnotations = fetchJsNativeAnnotations(containingClass) + fixAnnotations(containingClass, classAnnotations, null) + } + + private fun createExtensionDeclaration(declaration: KtNamedDeclaration, project: Project, anchor: PsiElement): KtNamedDeclaration? { + val containingClass = declaration.containingClassOrObject ?: return null + val builder = KtPsiFactory.CallableBuilder(if (declaration is KtNamedFunction) KtPsiFactory.CallableBuilder.Target.FUNCTION else KtPsiFactory.CallableBuilder.Target.READ_ONLY_PROPERTY) + + // modifiers + declaration.annotationEntries.forEach { + builder.modifier(it.text) + } + + // type parameters + builder.typeParams(containingClass.typeParameters.union((declaration as? KtTypeParameterListOwner)?.typeParameters ?: emptyList()).map { it.text }) + + // receiver + builder.receiver(containingClass.name ?: "XXX") + + // name + builder.name(declaration.nameAsSafeName.identifier) + + // parameters + (declaration as? KtCallableDeclaration)?.valueParameters?.forEach { + builder.param(it.nameAsSafeName.identifier, it.typeReference?.text ?: "XXX", it.defaultValue?.text) + } + + // return type + val returnTypeReference = declaration.getReturnTypeReference() + if (returnTypeReference != null) + builder.returnType(returnTypeReference.text) + else + builder.noReturnType() + + // body + (declaration as? KtDeclarationWithBody)?.bodyExpression?.let { + builder.blockBody(it.text) + } + + // Create function etc + var newFunctionText = builder.asString() + val psiFactory = KtPsiFactory(project) + val newFunction = psiFactory.createFunction(newFunctionText) + + val parent = anchor.parent + val result = parent.addAfter(newFunction, anchor) as KtCallableDeclaration + parent.addBefore(psiFactory.createNewLine(2), result) + + // fix receiver type + result.setReceiverType((containingClass.resolveToDescriptor(BodyResolveMode.PARTIAL) as ClassDescriptor).defaultType) + return result + } + private data class JsNativeAnnotations(val annotations: List, val nativeAnnotation: KtAnnotationEntry?, val isGetter: Boolean, val isSetter: Boolean, val isInvoke: Boolean) private fun fetchJsNativeAnnotations(declaration: KtNamedDeclaration) : JsNativeAnnotations { @@ -156,23 +244,31 @@ class MigrateExternalExtensionFix(declaration: KtNamedDeclaration) private fun fixAnnotations(declaration: KtNamedDeclaration, annotations: JsNativeAnnotations, editor: Editor?) { annotations.annotations.forEach { it.delete() } - declaration.addModifier(KtTokens.INLINE_KEYWORD) - declaration.removeModifier(KtTokens.EXTERNAL_KEYWORD) - + if (declaration is KtClassOrObject) { + declaration.addModifier(KtTokens.EXTERNAL_KEYWORD) + } else { + declaration.addModifier(KtTokens.INLINE_KEYWORD) + declaration.removeModifier(KtTokens.EXTERNAL_KEYWORD) + } if (declaration is KtFunction) { declaration.addAnnotation(KotlinBuiltIns.FQ_NAMES.suppress.toSafe(), "\"NOTHING_TO_INLINE\"") } - if (annotations.nativeAnnotation != null && annotations.nativeAnnotation.valueArguments.isNotEmpty()) { - declaration.addAnnotation(FqName("JsName"), annotations.nativeAnnotation.valueArguments.joinToString { it.asElement().text}) - } + convertNativeAnnotationToJsName(declaration, annotations) - if (declaration is KtFunction && !declaration.hasDeclaredReturnType() && !annotations.isSetter && !annotations.isInvoke) { + if (declaration is KtFunction && !declaration.hasDeclaredReturnType() && !annotations.isSetter && !annotations.isInvoke && editor != null) { SpecifyTypeExplicitlyIntention.addTypeAnnotation(editor, declaration, declaration.builtIns.unitType) } } + private fun convertNativeAnnotationToJsName(declaration: KtNamedDeclaration, annotations: JsNativeAnnotations) { + val nativeAnnotation = annotations.nativeAnnotation + if (nativeAnnotation != null && nativeAnnotation.valueArguments.isNotEmpty()) { + declaration.addAnnotation(FqName("JsName"), nativeAnnotation.valueArguments.joinToString { it.asElement().text }) + } + } + private fun BuilderByPattern.appendParameters(declaration: KtNamedFunction, lParenth: String, rParenth: String, skipLast: Boolean = false) { appendFixedText(lParenth) for ((index, param) in declaration.valueParameters.let { if (skipLast) it.take(it.size-1) else it }.withIndex()) { @@ -202,6 +298,11 @@ class MigrateExternalExtensionFix(declaration: KtNamedDeclaration) (psiElement is KtProperty && psiElement.receiverTypeReference != null) } + private fun isMemberDeclaration(psiElement: PsiElement): Boolean { + return (psiElement is KtNamedFunction && psiElement.receiverTypeReference == null) || + (psiElement is KtProperty && psiElement.receiverTypeReference == null) + } + private inline fun getContainingElement(e: PsiElement): T? { var element: PsiElement? = e while (element != null) { diff --git a/idea/testData/quickfix/migration/jsExternal/nativeMemberAll01.kt b/idea/testData/quickfix/migration/jsExternal/nativeMemberAll01.kt new file mode 100644 index 00000000000..d9a773f60cc --- /dev/null +++ b/idea/testData/quickfix/migration/jsExternal/nativeMemberAll01.kt @@ -0,0 +1,19 @@ +// "Fix with 'asDynamic'" "true" +// JS + +@native +class B { + @nativeGetter + fun foo(i: Int): B? + + @nativeSetter + fun foo(i: Int, v: B) + + @nativeInvoke + fun bar(a: B) + + @nativeInvoke + fun exp(t: T) + + fun dontTouch(): Nothing = definedExternally +} \ No newline at end of file diff --git a/idea/testData/quickfix/migration/jsExternal/nativeMemberAll01.kt.after b/idea/testData/quickfix/migration/jsExternal/nativeMemberAll01.kt.after new file mode 100644 index 00000000000..c68fec9b39b --- /dev/null +++ b/idea/testData/quickfix/migration/jsExternal/nativeMemberAll01.kt.after @@ -0,0 +1,25 @@ +// "Fix with 'asDynamic'" "true" +// JS + +external class B { + + fun dontTouch(): Nothing = definedExternally +} + +@Suppress("NOTHING_TO_INLINE") +inline fun B.foo(i: Int): B? = asDynamic()[i] + +@Suppress("NOTHING_TO_INLINE") +inline fun B.foo(i: Int, v: B) { + asDynamic()[i] = v +} + +@Suppress("NOTHING_TO_INLINE") +inline fun B.bar(a: B) { + asDynamic()(a) +} + +@Suppress("NOTHING_TO_INLINE") +inline fun B.exp(t: T) { + asDynamic()(t) +} \ No newline at end of file diff --git a/idea/testData/quickfix/migration/jsExternal/nativeMemberAll02.kt b/idea/testData/quickfix/migration/jsExternal/nativeMemberAll02.kt new file mode 100644 index 00000000000..9aca9a4c021 --- /dev/null +++ b/idea/testData/quickfix/migration/jsExternal/nativeMemberAll02.kt @@ -0,0 +1,19 @@ +// "Fix with 'asDynamic'" "true" +// JS + +@native +class B { + @nativeGetter + fun foo(i: Int): B? + + @nativeSetter + fun foo(i: Int, v: B) + + @nativeInvoke + fun bar(a: B) + + @nativeInvoke + fun exp(t: T) + + fun dontTouch(): Nothing = definedExternally +} \ No newline at end of file diff --git a/idea/testData/quickfix/migration/jsExternal/nativeMemberAll02.kt.after b/idea/testData/quickfix/migration/jsExternal/nativeMemberAll02.kt.after new file mode 100644 index 00000000000..c68fec9b39b --- /dev/null +++ b/idea/testData/quickfix/migration/jsExternal/nativeMemberAll02.kt.after @@ -0,0 +1,25 @@ +// "Fix with 'asDynamic'" "true" +// JS + +external class B { + + fun dontTouch(): Nothing = definedExternally +} + +@Suppress("NOTHING_TO_INLINE") +inline fun B.foo(i: Int): B? = asDynamic()[i] + +@Suppress("NOTHING_TO_INLINE") +inline fun B.foo(i: Int, v: B) { + asDynamic()[i] = v +} + +@Suppress("NOTHING_TO_INLINE") +inline fun B.bar(a: B) { + asDynamic()(a) +} + +@Suppress("NOTHING_TO_INLINE") +inline fun B.exp(t: T) { + asDynamic()(t) +} \ No newline at end of file diff --git a/idea/testData/quickfix/migration/jsExternal/nativeMemberAll03.kt b/idea/testData/quickfix/migration/jsExternal/nativeMemberAll03.kt new file mode 100644 index 00000000000..48885f578da --- /dev/null +++ b/idea/testData/quickfix/migration/jsExternal/nativeMemberAll03.kt @@ -0,0 +1,18 @@ +// "Fix with 'asDynamic'" "true" +// JS + +external class B { + @nativeGetter + fun foo(i: Int): B? + + @nativeSetter + fun foo(i: Int, v: B) + + @nativeInvoke + fun bar(a: B) + + @nativeInvoke + fun exp(t: T) + + fun dontTouch(): Nothing = definedExternally +} \ No newline at end of file diff --git a/idea/testData/quickfix/migration/jsExternal/nativeMemberAll03.kt.after b/idea/testData/quickfix/migration/jsExternal/nativeMemberAll03.kt.after new file mode 100644 index 00000000000..c68fec9b39b --- /dev/null +++ b/idea/testData/quickfix/migration/jsExternal/nativeMemberAll03.kt.after @@ -0,0 +1,25 @@ +// "Fix with 'asDynamic'" "true" +// JS + +external class B { + + fun dontTouch(): Nothing = definedExternally +} + +@Suppress("NOTHING_TO_INLINE") +inline fun B.foo(i: Int): B? = asDynamic()[i] + +@Suppress("NOTHING_TO_INLINE") +inline fun B.foo(i: Int, v: B) { + asDynamic()[i] = v +} + +@Suppress("NOTHING_TO_INLINE") +inline fun B.bar(a: B) { + asDynamic()(a) +} + +@Suppress("NOTHING_TO_INLINE") +inline fun B.exp(t: T) { + asDynamic()(t) +} \ No newline at end of file diff --git a/idea/testData/quickfix/migration/jsExternal/nativeMemberGetter.kt b/idea/testData/quickfix/migration/jsExternal/nativeMemberGetter.kt new file mode 100644 index 00000000000..51f87c3cf73 --- /dev/null +++ b/idea/testData/quickfix/migration/jsExternal/nativeMemberGetter.kt @@ -0,0 +1,8 @@ +// "Fix with 'asDynamic'" "true" +// JS + +@native +class B { + @nativeSetter + fun foo(i: Int, v: B) +} diff --git a/idea/testData/quickfix/migration/jsExternal/nativeMemberGetter.kt.after b/idea/testData/quickfix/migration/jsExternal/nativeMemberGetter.kt.after new file mode 100644 index 00000000000..eeceeac5128 --- /dev/null +++ b/idea/testData/quickfix/migration/jsExternal/nativeMemberGetter.kt.after @@ -0,0 +1,10 @@ +// "Fix with 'asDynamic'" "true" +// JS + +external class B { +} + +@Suppress("NOTHING_TO_INLINE") +inline fun B.foo(i: Int, v: B) { + asDynamic()[i] = v +} diff --git a/idea/testData/quickfix/migration/jsExternal/nativeMemberInvoke.kt b/idea/testData/quickfix/migration/jsExternal/nativeMemberInvoke.kt new file mode 100644 index 00000000000..2d4458861c2 --- /dev/null +++ b/idea/testData/quickfix/migration/jsExternal/nativeMemberInvoke.kt @@ -0,0 +1,8 @@ +// "Fix with 'asDynamic'" "true" +// JS + +@native +class B { + @nativeInvoke + fun bar(a: B) +} diff --git a/idea/testData/quickfix/migration/jsExternal/nativeMemberInvoke.kt.after b/idea/testData/quickfix/migration/jsExternal/nativeMemberInvoke.kt.after new file mode 100644 index 00000000000..a4278b1fe6e --- /dev/null +++ b/idea/testData/quickfix/migration/jsExternal/nativeMemberInvoke.kt.after @@ -0,0 +1,10 @@ +// "Fix with 'asDynamic'" "true" +// JS + +external class B { +} + +@Suppress("NOTHING_TO_INLINE") +inline fun B.bar(a: B) { + asDynamic()(a) +} diff --git a/idea/testData/quickfix/migration/jsExternal/nativeMemberInvokeGenericClass.kt b/idea/testData/quickfix/migration/jsExternal/nativeMemberInvokeGenericClass.kt new file mode 100644 index 00000000000..39c7d09999c --- /dev/null +++ b/idea/testData/quickfix/migration/jsExternal/nativeMemberInvokeGenericClass.kt @@ -0,0 +1,9 @@ +// "Fix with 'asDynamic'" "true" +// JS +class A + +@native +class B { + @nativeInvoke + fun exp(t: T) +} diff --git a/idea/testData/quickfix/migration/jsExternal/nativeMemberInvokeGenericClass.kt.after b/idea/testData/quickfix/migration/jsExternal/nativeMemberInvokeGenericClass.kt.after new file mode 100644 index 00000000000..2a2f4d6734c --- /dev/null +++ b/idea/testData/quickfix/migration/jsExternal/nativeMemberInvokeGenericClass.kt.after @@ -0,0 +1,11 @@ +// "Fix with 'asDynamic'" "true" +// JS +class A + +external class B { +} + +@Suppress("NOTHING_TO_INLINE") +inline fun B.exp(t: T) { + asDynamic()(t) +} diff --git a/idea/testData/quickfix/migration/jsExternal/nativeMemberInvokeGenericClassAndFun.kt b/idea/testData/quickfix/migration/jsExternal/nativeMemberInvokeGenericClassAndFun.kt new file mode 100644 index 00000000000..67a4a493ae7 --- /dev/null +++ b/idea/testData/quickfix/migration/jsExternal/nativeMemberInvokeGenericClassAndFun.kt @@ -0,0 +1,9 @@ +// "Fix with 'asDynamic'" "true" +// JS +class A + +@native +class B { + @nativeInvoke + fun exp(t: T, t2: T2) +} diff --git a/idea/testData/quickfix/migration/jsExternal/nativeMemberInvokeGenericClassAndFun.kt.after b/idea/testData/quickfix/migration/jsExternal/nativeMemberInvokeGenericClassAndFun.kt.after new file mode 100644 index 00000000000..9f2f8a8f400 --- /dev/null +++ b/idea/testData/quickfix/migration/jsExternal/nativeMemberInvokeGenericClassAndFun.kt.after @@ -0,0 +1,11 @@ +// "Fix with 'asDynamic'" "true" +// JS +class A + +external class B { +} + +@Suppress("NOTHING_TO_INLINE") +inline fun B.exp(t: T, t2: T2) { + asDynamic()(t, t2) +} diff --git a/idea/testData/quickfix/migration/jsExternal/nativeMemberInvokeGenericFun.kt b/idea/testData/quickfix/migration/jsExternal/nativeMemberInvokeGenericFun.kt new file mode 100644 index 00000000000..1c744ef54ef --- /dev/null +++ b/idea/testData/quickfix/migration/jsExternal/nativeMemberInvokeGenericFun.kt @@ -0,0 +1,8 @@ +// "Fix with 'asDynamic'" "true" +// JS + +@native +class B { + @nativeInvoke + fun exp(t: T) +} diff --git a/idea/testData/quickfix/migration/jsExternal/nativeMemberInvokeGenericFun.kt.after b/idea/testData/quickfix/migration/jsExternal/nativeMemberInvokeGenericFun.kt.after new file mode 100644 index 00000000000..97e13daee40 --- /dev/null +++ b/idea/testData/quickfix/migration/jsExternal/nativeMemberInvokeGenericFun.kt.after @@ -0,0 +1,10 @@ +// "Fix with 'asDynamic'" "true" +// JS + +external class B { +} + +@Suppress("NOTHING_TO_INLINE") +inline fun B.exp(t: T) { + asDynamic()(t) +} diff --git a/idea/testData/quickfix/migration/jsExternal/nativeMemberNative.kt b/idea/testData/quickfix/migration/jsExternal/nativeMemberNative.kt new file mode 100644 index 00000000000..e81baa9cff2 --- /dev/null +++ b/idea/testData/quickfix/migration/jsExternal/nativeMemberNative.kt @@ -0,0 +1,8 @@ +// "Fix with 'asDynamic'" "true" +// JS + +@native +class B { + @native("xx") + fun aaaa() // remove @native +} diff --git a/idea/testData/quickfix/migration/jsExternal/nativeMemberNative.kt.after b/idea/testData/quickfix/migration/jsExternal/nativeMemberNative.kt.after new file mode 100644 index 00000000000..a03b276c417 --- /dev/null +++ b/idea/testData/quickfix/migration/jsExternal/nativeMemberNative.kt.after @@ -0,0 +1,7 @@ +// "Fix with 'asDynamic'" "true" +// JS + +external class B { + @JsName("xx") + fun aaaa() // remove @native +} diff --git a/idea/testData/quickfix/migration/jsExternal/nativeMemberSetter.kt b/idea/testData/quickfix/migration/jsExternal/nativeMemberSetter.kt new file mode 100644 index 00000000000..587a68f5d36 --- /dev/null +++ b/idea/testData/quickfix/migration/jsExternal/nativeMemberSetter.kt @@ -0,0 +1,8 @@ +// "Fix with 'asDynamic'" "true" +// JS + +@native +class B { + @nativeGetter + fun foo(i: Int): B? +} diff --git a/idea/testData/quickfix/migration/jsExternal/nativeMemberSetter.kt.after b/idea/testData/quickfix/migration/jsExternal/nativeMemberSetter.kt.after new file mode 100644 index 00000000000..f8dd2eef5b0 --- /dev/null +++ b/idea/testData/quickfix/migration/jsExternal/nativeMemberSetter.kt.after @@ -0,0 +1,8 @@ +// "Fix with 'asDynamic'" "true" +// JS + +external class B { +} + +@Suppress("NOTHING_TO_INLINE") +inline fun B.foo(i: Int): B? = asDynamic()[i] diff --git a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java index 50ea6e4937b..312c6006710 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java @@ -6463,6 +6463,66 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { doTest(fileName); } + @TestMetadata("nativeMemberAll01.kt") + public void testNativeMemberAll01() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/migration/jsExternal/nativeMemberAll01.kt"); + doTest(fileName); + } + + @TestMetadata("nativeMemberAll02.kt") + public void testNativeMemberAll02() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/migration/jsExternal/nativeMemberAll02.kt"); + doTest(fileName); + } + + @TestMetadata("nativeMemberAll03.kt") + public void testNativeMemberAll03() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/migration/jsExternal/nativeMemberAll03.kt"); + doTest(fileName); + } + + @TestMetadata("nativeMemberGetter.kt") + public void testNativeMemberGetter() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/migration/jsExternal/nativeMemberGetter.kt"); + doTest(fileName); + } + + @TestMetadata("nativeMemberInvoke.kt") + public void testNativeMemberInvoke() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/migration/jsExternal/nativeMemberInvoke.kt"); + doTest(fileName); + } + + @TestMetadata("nativeMemberInvokeGenericClass.kt") + public void testNativeMemberInvokeGenericClass() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/migration/jsExternal/nativeMemberInvokeGenericClass.kt"); + doTest(fileName); + } + + @TestMetadata("nativeMemberInvokeGenericClassAndFun.kt") + public void testNativeMemberInvokeGenericClassAndFun() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/migration/jsExternal/nativeMemberInvokeGenericClassAndFun.kt"); + doTest(fileName); + } + + @TestMetadata("nativeMemberInvokeGenericFun.kt") + public void testNativeMemberInvokeGenericFun() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/migration/jsExternal/nativeMemberInvokeGenericFun.kt"); + doTest(fileName); + } + + @TestMetadata("nativeMemberNative.kt") + public void testNativeMemberNative() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/migration/jsExternal/nativeMemberNative.kt"); + doTest(fileName); + } + + @TestMetadata("nativeMemberSetter.kt") + public void testNativeMemberSetter() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/migration/jsExternal/nativeMemberSetter.kt"); + doTest(fileName); + } + @TestMetadata("nativeSetterExtensionFunJsRuntime.kt") public void testNativeSetterExtensionFunJsRuntime() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/migration/jsExternal/nativeSetterExtensionFunJsRuntime.kt");