KT-11990 J2K native to external conversion (#957)
This commit is contained in:
committed by
Dmitry Jemerov
parent
293d3b4320
commit
ab2b6743df
@@ -19,7 +19,6 @@ package org.jetbrains.kotlin.j2k
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.CommonClassNames.*
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.psi.util.InheritanceUtil
|
||||
import com.intellij.psi.util.PsiMethodUtil
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
@@ -352,7 +351,10 @@ class Converter private constructor(
|
||||
if (propertyInfo.needExplicitGetter) {
|
||||
if (getMethod != null) {
|
||||
val method = convertMethod(getMethod, null, null, null, classKind)!!
|
||||
getter = PropertyAccessor(AccessorKind.GETTER, method.annotations, Modifiers.Empty, method.parameterList, method.body)
|
||||
if (method.modifiers.contains(Modifier.EXTERNAL))
|
||||
getter = PropertyAccessor(AccessorKind.GETTER, method.annotations, Modifiers(listOf(Modifier.EXTERNAL)).assignNoPrototype(), null, null)
|
||||
else
|
||||
getter = PropertyAccessor(AccessorKind.GETTER, method.annotations, Modifiers.Empty, method.parameterList, method.body)
|
||||
getter.assignPrototype(getMethod, CommentsAndSpacesInheritance.NO_SPACES)
|
||||
}
|
||||
else if (propertyInfo.modifiers.contains(Modifier.OVERRIDE) && !(propertyInfo.superInfo?.isAbstract() ?: false)) {
|
||||
@@ -374,18 +376,22 @@ class Converter private constructor(
|
||||
if (propertyInfo.needExplicitSetter) {
|
||||
val accessorModifiers = Modifiers(propertyInfo.specialSetterAccess.singletonOrEmptyList()).assignNoPrototype()
|
||||
if (setMethod != null && !propertyInfo.isSetMethodBodyFieldAccess) {
|
||||
val method = setMethod.let { convertMethod(it, null, null, null, classKind)!! }
|
||||
val convertedParameter = method.parameterList!!.parameters.single() as FunctionParameter
|
||||
val parameterAnnotations = convertedParameter.annotations
|
||||
val parameterList = if (method.body != null || !parameterAnnotations.isEmpty) {
|
||||
val parameter = FunctionParameter(convertedParameter.identifier, null, FunctionParameter.VarValModifier.None, parameterAnnotations, Modifiers.Empty)
|
||||
.assignPrototypesFrom(convertedParameter, CommentsAndSpacesInheritance.NO_SPACES)
|
||||
ParameterList.withNoPrototype(listOf(parameter))
|
||||
}
|
||||
val method = convertMethod(setMethod, null, null, null, classKind)!!
|
||||
if (method.modifiers.contains(Modifier.EXTERNAL))
|
||||
setter = PropertyAccessor(AccessorKind.SETTER, method.annotations, accessorModifiers.with(Modifier.EXTERNAL), null, null)
|
||||
else {
|
||||
null
|
||||
val convertedParameter = method.parameterList!!.parameters.single() as FunctionParameter
|
||||
val parameterAnnotations = convertedParameter.annotations
|
||||
val parameterList = if (method.body != null || !parameterAnnotations.isEmpty) {
|
||||
val parameter = FunctionParameter(convertedParameter.identifier, null, FunctionParameter.VarValModifier.None, parameterAnnotations, Modifiers.Empty)
|
||||
.assignPrototypesFrom(convertedParameter, CommentsAndSpacesInheritance.NO_SPACES)
|
||||
ParameterList.withNoPrototype(listOf(parameter))
|
||||
}
|
||||
else {
|
||||
null
|
||||
}
|
||||
setter = PropertyAccessor(AccessorKind.SETTER, method.annotations, accessorModifiers, parameterList, method.body)
|
||||
}
|
||||
setter = PropertyAccessor(AccessorKind.SETTER, method.annotations, accessorModifiers, parameterList, method.body)
|
||||
setter.assignPrototype(setMethod, CommentsAndSpacesInheritance.NO_SPACES)
|
||||
}
|
||||
else if (propertyInfo.modifiers.contains(Modifier.OVERRIDE) && !(propertyInfo.superInfo?.isAbstract() ?: false)) {
|
||||
@@ -726,6 +732,9 @@ class Converter private constructor(
|
||||
modifiers = modifiers.with(Modifier.OPEN)
|
||||
}
|
||||
|
||||
if (owner.hasModifierProperty(PsiModifier.NATIVE))
|
||||
modifiers = modifiers.with(Modifier.EXTERNAL)
|
||||
|
||||
modifiers = modifiers.adaptForContainingClassVisibility(owner.containingClass).adaptProtectedVisibility(owner)
|
||||
}
|
||||
else if (owner is PsiField) {
|
||||
|
||||
@@ -27,6 +27,7 @@ enum class Modifier(private val str: String) {
|
||||
ABSTRACT("abstract"),
|
||||
OPEN("open"),
|
||||
OVERRIDE("override"),
|
||||
EXTERNAL("external"),
|
||||
INNER("inner");
|
||||
|
||||
fun toKotlin(): String = str
|
||||
|
||||
@@ -60,7 +60,12 @@ class PropertyInfo(
|
||||
//TODO: what if annotations are not empty?
|
||||
val needExplicitGetter: Boolean
|
||||
get() {
|
||||
if (getMethod != null && getMethod.body != null && !isGetMethodBodyFieldAccess) return true
|
||||
if (getMethod != null) {
|
||||
if (getMethod.hasModifierProperty(PsiModifier.NATIVE))
|
||||
return true
|
||||
if (getMethod.body != null && !isGetMethodBodyFieldAccess)
|
||||
return true
|
||||
}
|
||||
return modifiers.contains(Modifier.OVERRIDE) && this.field == null && !modifiers.contains(Modifier.ABSTRACT)
|
||||
}
|
||||
|
||||
@@ -69,8 +74,13 @@ class PropertyInfo(
|
||||
get() {
|
||||
if (!isVar) return false
|
||||
if (specialSetterAccess != null) return true
|
||||
if (setMethod != null && setMethod.body != null && !isSetMethodBodyFieldAccess) return true
|
||||
return modifiers.contains(Modifier.OVERRIDE) && this.field == null && !modifiers.contains(Modifier.ABSTRACT)
|
||||
if (setMethod != null) {
|
||||
if (setMethod.hasModifierProperty(PsiModifier.NATIVE))
|
||||
return true
|
||||
if (setMethod.body != null && !isSetMethodBodyFieldAccess)
|
||||
return true
|
||||
}
|
||||
return modifiers.contains(Modifier.EXTERNAL) || modifiers.contains(Modifier.OVERRIDE) && this.field == null && !modifiers.contains(Modifier.ABSTRACT)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
public class Foo {
|
||||
private native final void nativeMethod();
|
||||
|
||||
public native final int getBar();
|
||||
public native final void setBar(int bar);
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
// ERROR: Property must be initialized or be abstract
|
||||
class Foo {
|
||||
private external fun nativeMethod()
|
||||
|
||||
var bar: Int
|
||||
external get
|
||||
external set
|
||||
}
|
||||
@@ -2449,6 +2449,12 @@ public class JavaToKotlinConverterForWebDemoTestGenerated extends AbstractJavaTo
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("nativeMethods.java")
|
||||
public void testNativeMethods() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("j2k/testData/fileOrElement/function/nativeMethods.java");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("open.java")
|
||||
public void testOpen() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("j2k/testData/fileOrElement/function/open.java");
|
||||
|
||||
@@ -2449,6 +2449,12 @@ public class JavaToKotlinConverterSingleFileTestGenerated extends AbstractJavaTo
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("nativeMethods.java")
|
||||
public void testNativeMethods() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("j2k/testData/fileOrElement/function/nativeMethods.java");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("open.java")
|
||||
public void testOpen() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("j2k/testData/fileOrElement/function/open.java");
|
||||
|
||||
Reference in New Issue
Block a user