Fix access to private static native functions
This commit is contained in:
@@ -22,6 +22,7 @@ import org.jetbrains.jet.lang.descriptors.annotations.Annotations;
|
|||||||
import org.jetbrains.jet.lang.descriptors.impl.SimpleFunctionDescriptorImpl;
|
import org.jetbrains.jet.lang.descriptors.impl.SimpleFunctionDescriptorImpl;
|
||||||
import org.jetbrains.jet.lang.descriptors.impl.TypeParameterDescriptorImpl;
|
import org.jetbrains.jet.lang.descriptors.impl.TypeParameterDescriptorImpl;
|
||||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||||
|
import org.jetbrains.jet.lang.resolve.annotations.AnnotationsPackage;
|
||||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
|
|
||||||
@@ -45,7 +46,9 @@ public class AccessorForFunctionDescriptor extends SimpleFunctionDescriptorImpl
|
|||||||
this.calleeDescriptor = descriptor;
|
this.calleeDescriptor = descriptor;
|
||||||
|
|
||||||
initialize(DescriptorUtils.getReceiverParameterType(descriptor.getExtensionReceiverParameter()),
|
initialize(DescriptorUtils.getReceiverParameterType(descriptor.getExtensionReceiverParameter()),
|
||||||
descriptor instanceof ConstructorDescriptor ? NO_RECEIVER_PARAMETER : descriptor.getDispatchReceiverParameter(),
|
descriptor instanceof ConstructorDescriptor || AnnotationsPackage.isPlatformStaticInObjectOrClass(descriptor)
|
||||||
|
? NO_RECEIVER_PARAMETER
|
||||||
|
: descriptor.getDispatchReceiverParameter(),
|
||||||
copyTypeParameters(descriptor),
|
copyTypeParameters(descriptor),
|
||||||
copyValueParameters(descriptor),
|
copyValueParameters(descriptor),
|
||||||
descriptor.getReturnType(),
|
descriptor.getReturnType(),
|
||||||
|
|||||||
@@ -189,10 +189,11 @@ public class FunctionCodegen extends ParentCodegenAware {
|
|||||||
else if (staticInClassObject) {
|
else if (staticInClassObject) {
|
||||||
// native platformStatic foo() in class object should delegate to the static native function moved to the outer class
|
// native platformStatic foo() in class object should delegate to the static native function moved to the outer class
|
||||||
mv.visitCode();
|
mv.visitCode();
|
||||||
ClassifierDescriptor outerClassDescriptor =
|
FunctionDescriptor staticFunctionDescriptor = PlatformStaticGenerator.createStaticFunctionDescriptor(functionDescriptor);
|
||||||
(ClassifierDescriptor) functionDescriptor.getContainingDeclaration().getContainingDeclaration();
|
JvmMethodSignature jvmMethodSignature =
|
||||||
assert outerClassDescriptor != null : "Class object has no outer class: " + functionDescriptor.getContainingDeclaration();
|
typeMapper.mapSignature(getParentCodegen().getContext().accessibleFunctionDescriptor(staticFunctionDescriptor));
|
||||||
generateDelegateToMethodBody(false, mv, asmMethod, typeMapper.mapClass(outerClassDescriptor).getInternalName());
|
Type owningType = typeMapper.mapClass((ClassifierDescriptor) staticFunctionDescriptor.getContainingDeclaration());
|
||||||
|
generateDelegateToMethodBody(false, mv, jvmMethodSignature.getAsmMethod(), owningType.getInternalName());
|
||||||
}
|
}
|
||||||
|
|
||||||
endVisit(mv, null, origin.getElement());
|
endVisit(mv, null, origin.getElement());
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ import org.jetbrains.jet.lang.resolve.BindingContext;
|
|||||||
import org.jetbrains.jet.lang.resolve.DeclarationResolver;
|
import org.jetbrains.jet.lang.resolve.DeclarationResolver;
|
||||||
import org.jetbrains.jet.lang.resolve.DescriptorToSourceUtils;
|
import org.jetbrains.jet.lang.resolve.DescriptorToSourceUtils;
|
||||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||||
|
import org.jetbrains.jet.lang.resolve.annotations.AnnotationsPackage;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.CallResolverUtil;
|
import org.jetbrains.jet.lang.resolve.calls.CallResolverUtil;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.callUtil.CallUtilPackage;
|
import org.jetbrains.jet.lang.resolve.calls.callUtil.CallUtilPackage;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.model.DefaultValueArgument;
|
import org.jetbrains.jet.lang.resolve.calls.model.DefaultValueArgument;
|
||||||
@@ -58,7 +59,6 @@ import org.jetbrains.jet.lang.resolve.java.jvmSignature.JvmMethodParameterSignat
|
|||||||
import org.jetbrains.jet.lang.resolve.java.jvmSignature.JvmMethodSignature;
|
import org.jetbrains.jet.lang.resolve.java.jvmSignature.JvmMethodSignature;
|
||||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
import org.jetbrains.jet.lang.types.Variance;
|
|
||||||
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
|
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
|
||||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||||
import org.jetbrains.jet.lexer.JetTokens;
|
import org.jetbrains.jet.lexer.JetTokens;
|
||||||
@@ -982,7 +982,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
reg = 0;
|
reg = 0;
|
||||||
}
|
}
|
||||||
else if (callFromAccessor) {
|
else if (callFromAccessor) {
|
||||||
iv.load(0, OBJECT_TYPE);
|
if (!AnnotationsPackage.isPlatformStaticInObjectOrClass(functionDescriptor)) {
|
||||||
|
iv.load(0, OBJECT_TYPE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Type argType : callableMethod.getAsmMethod().getArgumentTypes()) {
|
for (Type argType : callableMethod.getAsmMethod().getArgumentTypes()) {
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import org.jetbrains.jet.codegen.context.MethodContext
|
|||||||
import org.jetbrains.jet.lang.psi.JetElement
|
import org.jetbrains.jet.lang.psi.JetElement
|
||||||
import org.jetbrains.jet.backend.common.CodegenUtil
|
import org.jetbrains.jet.backend.common.CodegenUtil
|
||||||
import org.jetbrains.jet.lang.descriptors.PropertyAccessorDescriptor
|
import org.jetbrains.jet.lang.descriptors.PropertyAccessorDescriptor
|
||||||
|
import kotlin.platform.platformStatic
|
||||||
|
|
||||||
class PlatformStaticGenerator(
|
class PlatformStaticGenerator(
|
||||||
val descriptor: FunctionDescriptor,
|
val descriptor: FunctionDescriptor,
|
||||||
@@ -37,17 +38,7 @@ class PlatformStaticGenerator(
|
|||||||
) : Function2<ImplementationBodyCodegen, ClassBuilder, Unit> {
|
) : Function2<ImplementationBodyCodegen, ClassBuilder, Unit> {
|
||||||
|
|
||||||
override fun invoke(codegen: ImplementationBodyCodegen, classBuilder: ClassBuilder) {
|
override fun invoke(codegen: ImplementationBodyCodegen, classBuilder: ClassBuilder) {
|
||||||
val memberDescriptor = if (descriptor is PropertyAccessorDescriptor) descriptor.getCorrespondingProperty() else descriptor
|
val staticFunctionDescriptor = createStaticFunctionDescriptor(descriptor)
|
||||||
val copies = CodegenUtil.copyFunctions(
|
|
||||||
memberDescriptor,
|
|
||||||
memberDescriptor,
|
|
||||||
declarationOrigin.descriptor?.getContainingDeclaration()?.getContainingDeclaration(),
|
|
||||||
descriptor.getModality(),
|
|
||||||
descriptor.getVisibility(),
|
|
||||||
CallableMemberDescriptor.Kind.SYNTHESIZED,
|
|
||||||
false
|
|
||||||
)
|
|
||||||
val staticFunctionDescriptor = copies[descriptor]!!
|
|
||||||
|
|
||||||
val jvmMethodSignature = state.getTypeMapper().mapSignature(staticFunctionDescriptor)
|
val jvmMethodSignature = state.getTypeMapper().mapSignature(staticFunctionDescriptor)
|
||||||
|
|
||||||
@@ -87,4 +78,22 @@ class PlatformStaticGenerator(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class object {
|
||||||
|
[platformStatic]
|
||||||
|
public fun createStaticFunctionDescriptor(descriptor: FunctionDescriptor): FunctionDescriptor {
|
||||||
|
val memberDescriptor = if (descriptor is PropertyAccessorDescriptor) descriptor.getCorrespondingProperty() else descriptor
|
||||||
|
val copies = CodegenUtil.copyFunctions(
|
||||||
|
memberDescriptor,
|
||||||
|
memberDescriptor,
|
||||||
|
descriptor.getContainingDeclaration()?.getContainingDeclaration(),
|
||||||
|
descriptor.getModality(),
|
||||||
|
descriptor.getVisibility(),
|
||||||
|
CallableMemberDescriptor.Kind.SYNTHESIZED,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
val staticFunctionDescriptor = copies[descriptor]!!
|
||||||
|
return staticFunctionDescriptor
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
import kotlin.jvm.*
|
||||||
|
import kotlin.platform.*
|
||||||
|
|
||||||
|
class C {
|
||||||
|
class object {
|
||||||
|
private platformStatic native fun foo()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun bar() {
|
||||||
|
foo()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
try {
|
||||||
|
C().bar()
|
||||||
|
return "Link error expected"
|
||||||
|
}
|
||||||
|
catch (e: java.lang.UnsatisfiedLinkError) {
|
||||||
|
if (e.getMessage() != "C.foo()V") return "Fail 1: " + e.getMessage()
|
||||||
|
}
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
import kotlin.platform.platformStatic
|
||||||
|
|
||||||
|
object A {
|
||||||
|
|
||||||
|
private platformStatic fun a(): String {
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
|
|
||||||
|
object Z {
|
||||||
|
val p = a()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
return A.Z.p
|
||||||
|
}
|
||||||
+12
@@ -1831,6 +1831,12 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode
|
|||||||
doTestWithStdlib(fileName);
|
doTestWithStdlib(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("privateStatic.kt")
|
||||||
|
public void testPrivateStatic() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/native/privateStatic.kt");
|
||||||
|
doTestWithStdlib(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("simpleNative.kt")
|
@TestMetadata("simpleNative.kt")
|
||||||
public void testSimpleNative() throws Exception {
|
public void testSimpleNative() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/native/simpleNative.kt");
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/native/simpleNative.kt");
|
||||||
@@ -1972,6 +1978,12 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode
|
|||||||
doTestWithStdlib(fileName);
|
doTestWithStdlib(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("privateMethod.kt")
|
||||||
|
public void testPrivateMethod() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/platformStatic/privateMethod.kt");
|
||||||
|
doTestWithStdlib(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("propertyAccess.kt")
|
@TestMetadata("propertyAccess.kt")
|
||||||
public void testPropertyAccess() throws Exception {
|
public void testPropertyAccess() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/platformStatic/propertyAccess.kt");
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/platformStatic/propertyAccess.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user