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