PlatformStaticGenerator reworked to use FunctionCodegen.generateMethod()
This commit is contained in:
@@ -143,19 +143,32 @@ public class CodegenUtil {
|
||||
|
||||
// inheritedMember can be abstract here. In order for FunctionCodegen to generate the method body, we're creating a copy here
|
||||
// with traitMember's modality
|
||||
CallableMemberDescriptor copy =
|
||||
inheritedMember.copy(inheritedMember.getContainingDeclaration(), traitMember.getModality(), Visibilities.PUBLIC,
|
||||
CallableMemberDescriptor.Kind.DECLARATION, true);
|
||||
result.putAll(copyFunctions(inheritedMember, traitMember, inheritedMember.getContainingDeclaration(), traitMember.getModality(), Visibilities.PUBLIC,
|
||||
CallableMemberDescriptor.Kind.DECLARATION, true));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
if (traitMember instanceof SimpleFunctionDescriptor) {
|
||||
result.put((FunctionDescriptor) traitMember, (FunctionDescriptor) copy);
|
||||
}
|
||||
else if (traitMember instanceof PropertyDescriptor) {
|
||||
for (PropertyAccessorDescriptor traitAccessor : ((PropertyDescriptor) traitMember).getAccessors()) {
|
||||
for (PropertyAccessorDescriptor inheritedAccessor : ((PropertyDescriptor) copy).getAccessors()) {
|
||||
if (inheritedAccessor.getClass() == traitAccessor.getClass()) { // same accessor kind
|
||||
result.put(traitAccessor, inheritedAccessor);
|
||||
}
|
||||
@NotNull
|
||||
public static Map<FunctionDescriptor, FunctionDescriptor> copyFunctions(
|
||||
@NotNull CallableMemberDescriptor inheritedMember,
|
||||
@NotNull CallableMemberDescriptor traitMember,
|
||||
DeclarationDescriptor newOwner,
|
||||
Modality modality,
|
||||
Visibility visibility,
|
||||
CallableMemberDescriptor.Kind kind,
|
||||
boolean copyOverrides
|
||||
) {
|
||||
CallableMemberDescriptor copy = inheritedMember.copy(newOwner, modality, visibility, kind, copyOverrides);
|
||||
Map<FunctionDescriptor, FunctionDescriptor> result = new LinkedHashMap<FunctionDescriptor, FunctionDescriptor>(0);
|
||||
if (traitMember instanceof SimpleFunctionDescriptor) {
|
||||
result.put((FunctionDescriptor) traitMember, (FunctionDescriptor) copy);
|
||||
}
|
||||
else if (traitMember instanceof PropertyDescriptor) {
|
||||
for (PropertyAccessorDescriptor traitAccessor : ((PropertyDescriptor) traitMember).getAccessors()) {
|
||||
for (PropertyAccessorDescriptor inheritedAccessor : ((PropertyDescriptor) copy).getAccessors()) {
|
||||
if (inheritedAccessor.getClass() == traitAccessor.getClass()) { // same accessor kind
|
||||
result.put(traitAccessor, inheritedAccessor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -173,7 +173,7 @@ public class AsmUtil {
|
||||
public static boolean isStaticMethod(OwnerKind kind, CallableMemberDescriptor functionDescriptor) {
|
||||
return isStaticKind(kind) ||
|
||||
JetTypeMapper.isAccessor(functionDescriptor) ||
|
||||
AnnotationsPackage.isPlatformStaticInObject(functionDescriptor);
|
||||
AnnotationsPackage.isPlatformStaticInObjectOrClass(functionDescriptor);
|
||||
}
|
||||
|
||||
public static boolean isStaticKind(OwnerKind kind) {
|
||||
|
||||
@@ -2419,7 +2419,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
if (isSingleton) {
|
||||
if (context.hasThisDescriptor() &&
|
||||
context.getThisDescriptor().equals(calleeContainingClass) &&
|
||||
!AnnotationsPackage.isPlatformStaticInObject(context.getContextDescriptor())) {
|
||||
!AnnotationsPackage.isPlatformStaticInObjectOrClass(context.getContextDescriptor())) {
|
||||
return StackValue.local(0, typeMapper.mapType(calleeContainingClass));
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -17,12 +17,18 @@
|
||||
package org.jetbrains.jet.codegen
|
||||
|
||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
import org.jetbrains.jet.codegen.state.GenerationState
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor
|
||||
import org.jetbrains.jet.lang.resolve.java.diagnostics.JvmDeclarationOrigin
|
||||
import org.jetbrains.jet.lang.resolve.java.diagnostics.Synthetic
|
||||
import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor
|
||||
import org.jetbrains.jet.lang.resolve.java.jvmSignature.JvmMethodSignature
|
||||
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
|
||||
|
||||
class PlatformStaticGenerator(
|
||||
val descriptor: FunctionDescriptor,
|
||||
@@ -31,39 +37,54 @@ class PlatformStaticGenerator(
|
||||
) : Function2<ImplementationBodyCodegen, ClassBuilder, Unit> {
|
||||
|
||||
override fun invoke(codegen: ImplementationBodyCodegen, classBuilder: ClassBuilder) {
|
||||
val typeMapper = state.getTypeMapper()
|
||||
val asmMethod = typeMapper.mapSignature(descriptor).getAsmMethod()
|
||||
val flags = Opcodes.ACC_STATIC or AsmUtil.getMethodAsmFlags(descriptor, OwnerKind.IMPLEMENTATION)
|
||||
val methodVisitor = classBuilder.newMethod(
|
||||
Synthetic(declarationOrigin.element, descriptor),
|
||||
flags,
|
||||
asmMethod.getName()!!,
|
||||
asmMethod.getDescriptor()!!,
|
||||
typeMapper.mapSignature(descriptor).getGenericsSignature(),
|
||||
FunctionCodegen.getThrownExceptions(descriptor, typeMapper))
|
||||
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]!!
|
||||
|
||||
AnnotationCodegen.forMethod(methodVisitor, typeMapper)!!.genAnnotations(descriptor, asmMethod.getReturnType())
|
||||
val jvmMethodSignature = state.getTypeMapper().mapSignature(staticFunctionDescriptor)
|
||||
|
||||
if (state.getClassBuilderMode() == ClassBuilderMode.FULL && flags and Opcodes.ACC_NATIVE == 0) {
|
||||
methodVisitor.visitCode();
|
||||
val iv = InstructionAdapter(methodVisitor)
|
||||
val classDescriptor = descriptor.getContainingDeclaration() as ClassDescriptor
|
||||
val singletonValue = StackValue.singleton(classDescriptor, typeMapper)!!
|
||||
singletonValue.put(singletonValue.type, iv);
|
||||
var index = 0;
|
||||
for (paramType in asmMethod.getArgumentTypes()) {
|
||||
iv.load(index, paramType);
|
||||
index += paramType.getSize();
|
||||
}
|
||||
codegen.functionCodegen.generateMethod(
|
||||
Synthetic(declarationOrigin.element, staticFunctionDescriptor),
|
||||
jvmMethodSignature,
|
||||
staticFunctionDescriptor,
|
||||
object: FunctionGenerationStrategy() {
|
||||
override fun generateBody(
|
||||
mv: MethodVisitor,
|
||||
frameMap: FrameMap,
|
||||
signature: JvmMethodSignature,
|
||||
context: MethodContext,
|
||||
parentCodegen: MemberCodegen<out JetElement>
|
||||
) {
|
||||
val typeMapper = parentCodegen.typeMapper
|
||||
|
||||
val syntheticOrOriginalMethod = typeMapper.mapToCallableMethod(
|
||||
codegen.getContext().accessibleFunctionDescriptor(descriptor),
|
||||
false,
|
||||
codegen.getContext()
|
||||
)
|
||||
syntheticOrOriginalMethod.invokeWithoutAssertions(iv)
|
||||
iv.areturn(asmMethod.getReturnType());
|
||||
methodVisitor.visitEnd();
|
||||
}
|
||||
val iv = InstructionAdapter(mv)
|
||||
val classDescriptor = descriptor.getContainingDeclaration() as ClassDescriptor
|
||||
val singletonValue = StackValue.singleton(classDescriptor, typeMapper)
|
||||
singletonValue.put(singletonValue.type, iv);
|
||||
var index = 0;
|
||||
val asmMethod = signature.getAsmMethod()
|
||||
for (paramType in asmMethod.getArgumentTypes()) {
|
||||
iv.load(index, paramType);
|
||||
index += paramType.getSize();
|
||||
}
|
||||
|
||||
val syntheticOrOriginalMethod = typeMapper.mapToCallableMethod(
|
||||
codegen.getContext().accessibleFunctionDescriptor(descriptor),
|
||||
false,
|
||||
codegen.getContext()
|
||||
)
|
||||
syntheticOrOriginalMethod.invokeWithoutAssertions(iv)
|
||||
iv.areturn(asmMethod.getReturnType());
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -480,7 +480,7 @@ public abstract class StackValue {
|
||||
}
|
||||
|
||||
private static StackValue platformStaticCallIfPresent(@NotNull StackValue resultReceiver, @NotNull CallableDescriptor descriptor) {
|
||||
if (AnnotationsPackage.isPlatformStaticInObject(descriptor)) {
|
||||
if (AnnotationsPackage.isPlatformStaticInObjectOrClass(descriptor)) {
|
||||
if (resultReceiver.canHaveSideEffects()) {
|
||||
return coercion(resultReceiver, Type.VOID_TYPE);
|
||||
}
|
||||
@@ -1414,7 +1414,7 @@ public abstract class StackValue {
|
||||
return callableMethod != null ? callableMethod.getReceiverClass() : typeMapper.mapType(extensionReceiver.getType());
|
||||
}
|
||||
else if (dispatchReceiver != null) {
|
||||
if (AnnotationsPackage.isPlatformStaticInObject(descriptor)) {
|
||||
if (AnnotationsPackage.isPlatformStaticInObjectOrClass(descriptor)) {
|
||||
return Type.VOID_TYPE;
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -488,7 +488,7 @@ public class JetTypeMapper {
|
||||
else {
|
||||
if (isStaticDeclaration(functionDescriptor) ||
|
||||
isAccessor(functionDescriptor) ||
|
||||
AnnotationsPackage.isPlatformStaticInObject(functionDescriptor)) {
|
||||
AnnotationsPackage.isPlatformStaticInObjectOrClass(functionDescriptor)) {
|
||||
invokeOpcode = INVOKESTATIC;
|
||||
}
|
||||
else if (isInterface) {
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
package org.jetbrains.jet.lang.resolve.annotations
|
||||
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor
|
||||
import org.jetbrains.jet.lang.resolve.name.FqName
|
||||
import org.jetbrains.jet.lang.descriptors.CallableDescriptor
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils
|
||||
@@ -36,18 +35,18 @@ public fun DeclarationDescriptor.hasIntrinsicAnnotation(): Boolean {
|
||||
return getAnnotations().findAnnotation(FqName("kotlin.jvm.internal.Intrinsic")) != null
|
||||
}
|
||||
|
||||
public fun CallableDescriptor.isPlatformStaticInObject(): Boolean =
|
||||
isPlatformStaticIn(ClassKind.OBJECT)
|
||||
public fun CallableDescriptor.isPlatformStaticInObjectOrClass(): Boolean =
|
||||
isPlatformStaticIn(ClassKind.OBJECT, ClassKind.CLASS)
|
||||
|
||||
public fun CallableDescriptor.isPlatformStaticInClassObject(): Boolean =
|
||||
isPlatformStaticIn(ClassKind.CLASS_OBJECT)
|
||||
|
||||
private fun CallableDescriptor.isPlatformStaticIn(kind: ClassKind): Boolean =
|
||||
private fun CallableDescriptor.isPlatformStaticIn(vararg kinds: ClassKind): Boolean =
|
||||
when (this) {
|
||||
is PropertyAccessorDescriptor -> {
|
||||
val propertyDescriptor = getCorrespondingProperty()
|
||||
DescriptorUtils.isKindOf(propertyDescriptor.getContainingDeclaration(), kind) &&
|
||||
kinds.any { DescriptorUtils.isKindOf(propertyDescriptor.getContainingDeclaration(), it) } &&
|
||||
(hasPlatformStaticAnnotation() || propertyDescriptor.hasPlatformStaticAnnotation())
|
||||
}
|
||||
else -> DescriptorUtils.isKindOf(getContainingDeclaration(), kind) && hasPlatformStaticAnnotation()
|
||||
else -> kinds.any { DescriptorUtils.isKindOf(getContainingDeclaration(), it) } && hasPlatformStaticAnnotation()
|
||||
}
|
||||
|
||||
@@ -17,5 +17,10 @@
|
||||
package org.jetbrains.jet.lang.descriptors;
|
||||
|
||||
public interface SourceElement {
|
||||
SourceElement NO_SOURCE = new SourceElement() { };
|
||||
SourceElement NO_SOURCE = new SourceElement() {
|
||||
@Override
|
||||
public String toString() {
|
||||
return "NO_SOURCE";
|
||||
}
|
||||
};
|
||||
}
|
||||
+1
-1
@@ -92,7 +92,7 @@ public class SimpleFunctionDescriptorImpl extends FunctionDescriptorImpl impleme
|
||||
getAnnotations(),
|
||||
getName(),
|
||||
kind,
|
||||
SourceElement.NO_SOURCE
|
||||
getSource()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user