Fix access to private static native functions

This commit is contained in:
Andrey Breslav
2014-12-02 14:31:46 +03:00
parent f9fea88749
commit 120c344f11
7 changed files with 85 additions and 18 deletions
@@ -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.TypeParameterDescriptorImpl;
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.types.JetType;
@@ -45,7 +46,9 @@ public class AccessorForFunctionDescriptor extends SimpleFunctionDescriptorImpl
this.calleeDescriptor = descriptor;
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),
copyValueParameters(descriptor),
descriptor.getReturnType(),
@@ -189,10 +189,11 @@ public class FunctionCodegen extends ParentCodegenAware {
else if (staticInClassObject) {
// native platformStatic foo() in class object should delegate to the static native function moved to the outer class
mv.visitCode();
ClassifierDescriptor outerClassDescriptor =
(ClassifierDescriptor) functionDescriptor.getContainingDeclaration().getContainingDeclaration();
assert outerClassDescriptor != null : "Class object has no outer class: " + functionDescriptor.getContainingDeclaration();
generateDelegateToMethodBody(false, mv, asmMethod, typeMapper.mapClass(outerClassDescriptor).getInternalName());
FunctionDescriptor staticFunctionDescriptor = PlatformStaticGenerator.createStaticFunctionDescriptor(functionDescriptor);
JvmMethodSignature jvmMethodSignature =
typeMapper.mapSignature(getParentCodegen().getContext().accessibleFunctionDescriptor(staticFunctionDescriptor));
Type owningType = typeMapper.mapClass((ClassifierDescriptor) staticFunctionDescriptor.getContainingDeclaration());
generateDelegateToMethodBody(false, mv, jvmMethodSignature.getAsmMethod(), owningType.getInternalName());
}
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.DescriptorToSourceUtils;
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.callUtil.CallUtilPackage;
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.name.Name;
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.lang.KotlinBuiltIns;
import org.jetbrains.jet.lexer.JetTokens;
@@ -982,7 +982,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
reg = 0;
}
else if (callFromAccessor) {
iv.load(0, OBJECT_TYPE);
if (!AnnotationsPackage.isPlatformStaticInObjectOrClass(functionDescriptor)) {
iv.load(0, OBJECT_TYPE);
}
}
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.backend.common.CodegenUtil
import org.jetbrains.jet.lang.descriptors.PropertyAccessorDescriptor
import kotlin.platform.platformStatic
class PlatformStaticGenerator(
val descriptor: FunctionDescriptor,
@@ -37,17 +38,7 @@ class PlatformStaticGenerator(
) : Function2<ImplementationBodyCodegen, ClassBuilder, Unit> {
override fun invoke(codegen: ImplementationBodyCodegen, classBuilder: ClassBuilder) {
val memberDescriptor = if (descriptor is PropertyAccessorDescriptor) descriptor.getCorrespondingProperty() else descriptor
val copies = CodegenUtil.copyFunctions(
memberDescriptor,
memberDescriptor,
declarationOrigin.descriptor?.getContainingDeclaration()?.getContainingDeclaration(),
descriptor.getModality(),
descriptor.getVisibility(),
CallableMemberDescriptor.Kind.SYNTHESIZED,
false
)
val staticFunctionDescriptor = copies[descriptor]!!
val staticFunctionDescriptor = createStaticFunctionDescriptor(descriptor)
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
}
@@ -1831,6 +1831,12 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode
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")
public void testSimpleNative() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/native/simpleNative.kt");
@@ -1972,6 +1978,12 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode
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")
public void testPropertyAccess() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/platformStatic/propertyAccess.kt");