Fixed KT-15270 Quickfix to migrate from @native***
This commit is contained in:
+111
-10
@@ -21,15 +21,19 @@ import com.intellij.openapi.editor.Editor
|
|||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.checkAnnotationName
|
import org.jetbrains.kotlin.descriptors.annotations.checkAnnotationName
|
||||||
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||||
import org.jetbrains.kotlin.diagnostics.Errors
|
import org.jetbrains.kotlin.diagnostics.Errors
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
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.intentions.SpecifyTypeExplicitlyIntention
|
||||||
import org.jetbrains.kotlin.idea.project.builtIns
|
import org.jetbrains.kotlin.idea.project.builtIns
|
||||||
import org.jetbrains.kotlin.idea.quickfix.CleanupFix
|
import org.jetbrains.kotlin.idea.quickfix.CleanupFix
|
||||||
import org.jetbrains.kotlin.idea.quickfix.KotlinQuickFixAction
|
import org.jetbrains.kotlin.idea.quickfix.KotlinQuickFixAction
|
||||||
import org.jetbrains.kotlin.idea.quickfix.KotlinSingleIntentionActionFactory
|
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.idea.util.addAnnotation
|
||||||
import org.jetbrains.kotlin.js.PredefinedAnnotation
|
import org.jetbrains.kotlin.js.PredefinedAnnotation
|
||||||
import org.jetbrains.kotlin.js.resolve.diagnostics.ErrorsJs
|
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.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||||
|
|
||||||
@@ -48,12 +53,95 @@ class MigrateExternalExtensionFix(declaration: KtNamedDeclaration)
|
|||||||
|
|
||||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||||
val declaration = element ?: return
|
val declaration = element ?: return
|
||||||
if (isExternalMemberDeclaration(declaration)) {
|
|
||||||
fixExtensionMemberDeclaration(declaration, project, editor, file)
|
when {
|
||||||
return
|
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<KtNamedDeclaration>().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<KtAnnotationEntry>, val nativeAnnotation: KtAnnotationEntry?, val isGetter: Boolean, val isSetter: Boolean, val isInvoke: Boolean)
|
private data class JsNativeAnnotations(val annotations: List<KtAnnotationEntry>, val nativeAnnotation: KtAnnotationEntry?, val isGetter: Boolean, val isSetter: Boolean, val isInvoke: Boolean)
|
||||||
|
|
||||||
private fun fetchJsNativeAnnotations(declaration: KtNamedDeclaration) : JsNativeAnnotations {
|
private fun fetchJsNativeAnnotations(declaration: KtNamedDeclaration) : JsNativeAnnotations {
|
||||||
@@ -156,23 +244,31 @@ class MigrateExternalExtensionFix(declaration: KtNamedDeclaration)
|
|||||||
private fun fixAnnotations(declaration: KtNamedDeclaration, annotations: JsNativeAnnotations, editor: Editor?) {
|
private fun fixAnnotations(declaration: KtNamedDeclaration, annotations: JsNativeAnnotations, editor: Editor?) {
|
||||||
annotations.annotations.forEach { it.delete() }
|
annotations.annotations.forEach { it.delete() }
|
||||||
|
|
||||||
declaration.addModifier(KtTokens.INLINE_KEYWORD)
|
if (declaration is KtClassOrObject) {
|
||||||
declaration.removeModifier(KtTokens.EXTERNAL_KEYWORD)
|
declaration.addModifier(KtTokens.EXTERNAL_KEYWORD)
|
||||||
|
} else {
|
||||||
|
declaration.addModifier(KtTokens.INLINE_KEYWORD)
|
||||||
|
declaration.removeModifier(KtTokens.EXTERNAL_KEYWORD)
|
||||||
|
}
|
||||||
|
|
||||||
if (declaration is KtFunction) {
|
if (declaration is KtFunction) {
|
||||||
declaration.addAnnotation(KotlinBuiltIns.FQ_NAMES.suppress.toSafe(), "\"NOTHING_TO_INLINE\"")
|
declaration.addAnnotation(KotlinBuiltIns.FQ_NAMES.suppress.toSafe(), "\"NOTHING_TO_INLINE\"")
|
||||||
}
|
}
|
||||||
|
|
||||||
if (annotations.nativeAnnotation != null && annotations.nativeAnnotation.valueArguments.isNotEmpty()) {
|
convertNativeAnnotationToJsName(declaration, annotations)
|
||||||
declaration.addAnnotation(FqName("JsName"), annotations.nativeAnnotation.valueArguments.joinToString { it.asElement().text})
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
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<KtExpression>.appendParameters(declaration: KtNamedFunction, lParenth: String, rParenth: String, skipLast: Boolean = false) {
|
private fun BuilderByPattern<KtExpression>.appendParameters(declaration: KtNamedFunction, lParenth: String, rParenth: String, skipLast: Boolean = false) {
|
||||||
appendFixedText(lParenth)
|
appendFixedText(lParenth)
|
||||||
for ((index, param) in declaration.valueParameters.let { if (skipLast) it.take(it.size-1) else it }.withIndex()) {
|
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)
|
(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<reified T: PsiElement> getContainingElement(e: PsiElement): T? {
|
private inline fun<reified T: PsiElement> getContainingElement(e: PsiElement): T? {
|
||||||
var element: PsiElement? = e
|
var element: PsiElement? = e
|
||||||
while (element != null) {
|
while (element != null) {
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
// "Fix with 'asDynamic'" "true"
|
||||||
|
// JS
|
||||||
|
|
||||||
|
@<caret>native
|
||||||
|
class B {
|
||||||
|
@nativeGetter
|
||||||
|
fun foo(i: Int): B?
|
||||||
|
|
||||||
|
@nativeSetter
|
||||||
|
fun foo(i: Int, v: B)
|
||||||
|
|
||||||
|
@nativeInvoke
|
||||||
|
fun bar(a: B)
|
||||||
|
|
||||||
|
@nativeInvoke
|
||||||
|
fun<T> exp(t: T)
|
||||||
|
|
||||||
|
fun dontTouch(): Nothing = definedExternally
|
||||||
|
}
|
||||||
@@ -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 <T> B.exp(t: T) {
|
||||||
|
asDynamic()(t)
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
// "Fix with 'asDynamic'" "true"
|
||||||
|
// JS
|
||||||
|
|
||||||
|
@<caret>native
|
||||||
|
class B {
|
||||||
|
@nativeGetter
|
||||||
|
fun foo(i: Int): B?
|
||||||
|
|
||||||
|
@na<caret>tiveSetter
|
||||||
|
fun foo(i: Int, v: B)
|
||||||
|
|
||||||
|
@nativeInvoke
|
||||||
|
fun bar(a: B)
|
||||||
|
|
||||||
|
@nativeInvoke
|
||||||
|
fun<T> exp(t: T)
|
||||||
|
|
||||||
|
fun dontTouch(): Nothing = definedExternally
|
||||||
|
}
|
||||||
@@ -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 <T> B.exp(t: T) {
|
||||||
|
asDynamic()(t)
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
// "Fix with 'asDynamic'" "true"
|
||||||
|
// JS
|
||||||
|
|
||||||
|
external class B {
|
||||||
|
@nativeGetter
|
||||||
|
fun foo(i: Int): B?
|
||||||
|
|
||||||
|
@nati<caret>veSetter
|
||||||
|
fun foo(i: Int, v: B)
|
||||||
|
|
||||||
|
@nativeInvoke
|
||||||
|
fun bar(a: B)
|
||||||
|
|
||||||
|
@nativeInvoke
|
||||||
|
fun<T> exp(t: T)
|
||||||
|
|
||||||
|
fun dontTouch(): Nothing = definedExternally
|
||||||
|
}
|
||||||
@@ -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 <T> B.exp(t: T) {
|
||||||
|
asDynamic()(t)
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
// "Fix with 'asDynamic'" "true"
|
||||||
|
// JS
|
||||||
|
|
||||||
|
@native
|
||||||
|
class B {
|
||||||
|
@na<caret>tiveSetter
|
||||||
|
fun foo(i: Int, v: B)
|
||||||
|
}
|
||||||
@@ -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
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
// "Fix with 'asDynamic'" "true"
|
||||||
|
// JS
|
||||||
|
|
||||||
|
@native
|
||||||
|
class B {
|
||||||
|
@na<caret>tiveInvoke
|
||||||
|
fun bar(a: B)
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
// "Fix with 'asDynamic'" "true"
|
||||||
|
// JS
|
||||||
|
|
||||||
|
external class B {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
|
inline fun B.bar(a: B) {
|
||||||
|
asDynamic()(a)
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
// "Fix with 'asDynamic'" "true"
|
||||||
|
// JS
|
||||||
|
class A
|
||||||
|
|
||||||
|
@native
|
||||||
|
class B<T: A> {
|
||||||
|
@nat<caret>iveInvoke
|
||||||
|
fun exp(t: T)
|
||||||
|
}
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
// "Fix with 'asDynamic'" "true"
|
||||||
|
// JS
|
||||||
|
class A
|
||||||
|
|
||||||
|
external class B<T: A> {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
|
inline fun <T : A> B<T>.exp(t: T) {
|
||||||
|
asDynamic()(t)
|
||||||
|
}
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
// "Fix with 'asDynamic'" "true"
|
||||||
|
// JS
|
||||||
|
class A
|
||||||
|
|
||||||
|
@native
|
||||||
|
class B<T: A> {
|
||||||
|
@nat<caret>iveInvoke
|
||||||
|
fun<T2> exp(t: T, t2: T2)
|
||||||
|
}
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
// "Fix with 'asDynamic'" "true"
|
||||||
|
// JS
|
||||||
|
class A
|
||||||
|
|
||||||
|
external class B<T: A> {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
|
inline fun <T : A, T2> B<T>.exp(t: T, t2: T2) {
|
||||||
|
asDynamic()(t, t2)
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
// "Fix with 'asDynamic'" "true"
|
||||||
|
// JS
|
||||||
|
|
||||||
|
@native
|
||||||
|
class B {
|
||||||
|
@nat<caret>iveInvoke
|
||||||
|
fun<T> exp(t: T)
|
||||||
|
}
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
// "Fix with 'asDynamic'" "true"
|
||||||
|
// JS
|
||||||
|
|
||||||
|
external class B {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
|
inline fun <T> B.exp(t: T) {
|
||||||
|
asDynamic()(t)
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
// "Fix with 'asDynamic'" "true"
|
||||||
|
// JS
|
||||||
|
|
||||||
|
@native
|
||||||
|
class B {
|
||||||
|
@na<caret>tive("xx")
|
||||||
|
fun aaaa() // remove @native
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
// "Fix with 'asDynamic'" "true"
|
||||||
|
// JS
|
||||||
|
|
||||||
|
external class B {
|
||||||
|
@JsName("xx")
|
||||||
|
fun aaaa() // remove @native
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
// "Fix with 'asDynamic'" "true"
|
||||||
|
// JS
|
||||||
|
|
||||||
|
@native
|
||||||
|
class B {
|
||||||
|
@nat<caret>iveGetter
|
||||||
|
fun foo(i: Int): B?
|
||||||
|
}
|
||||||
@@ -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]
|
||||||
@@ -6463,6 +6463,66 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
|||||||
doTest(fileName);
|
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")
|
@TestMetadata("nativeSetterExtensionFunJsRuntime.kt")
|
||||||
public void testNativeSetterExtensionFunJsRuntime() throws Exception {
|
public void testNativeSetterExtensionFunJsRuntime() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/migration/jsExternal/nativeSetterExtensionFunJsRuntime.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/migration/jsExternal/nativeSetterExtensionFunJsRuntime.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user