Inline trait support

This commit is contained in:
Mikhael Bogdanov
2014-02-28 15:27:48 +04:00
parent 286dd50be4
commit 6d1effe981
3 changed files with 21 additions and 7 deletions
@@ -42,6 +42,7 @@ import org.jetbrains.jet.lang.descriptors.impl.AnonymousFunctionDescriptor;
import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingContextUtils; import org.jetbrains.jet.lang.resolve.BindingContextUtils;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
import org.jetbrains.jet.lang.resolve.java.AsmTypeConstants; import org.jetbrains.jet.lang.resolve.java.AsmTypeConstants;
import org.jetbrains.jet.lang.types.lang.InlineStrategy; import org.jetbrains.jet.lang.types.lang.InlineStrategy;
@@ -55,7 +56,6 @@ import java.util.*;
import static org.jetbrains.jet.codegen.AsmUtil.getMethodAsmFlags; import static org.jetbrains.jet.codegen.AsmUtil.getMethodAsmFlags;
import static org.jetbrains.jet.codegen.AsmUtil.isPrimitive; import static org.jetbrains.jet.codegen.AsmUtil.isPrimitive;
import static org.jetbrains.jet.codegen.binding.CodegenBinding.asmTypeForAnonymousClass;
public class InlineCodegen implements ParentCodegenAware, CallGenerator { public class InlineCodegen implements ParentCodegenAware, CallGenerator {
@@ -150,8 +150,12 @@ public class InlineCodegen implements ParentCodegenAware, CallGenerator {
MethodNode node; MethodNode node;
if (functionDescriptor instanceof DeserializedSimpleFunctionDescriptor) { if (functionDescriptor instanceof DeserializedSimpleFunctionDescriptor) {
VirtualFile file = InlineCodegenUtil.getVirtualFileForCallable((DeserializedSimpleFunctionDescriptor) functionDescriptor, state); VirtualFile file = InlineCodegenUtil.getVirtualFileForCallable((DeserializedSimpleFunctionDescriptor) functionDescriptor, state);
node = InlineCodegenUtil.getMethodNode(file.getInputStream(), functionDescriptor.getName().asString(), String methodDesc = callableMethod.getAsmMethod().getDescriptor();
callableMethod.getAsmMethod().getDescriptor()); DeclarationDescriptor parentDescriptor = functionDescriptor.getContainingDeclaration();
if (DescriptorUtils.isTrait(parentDescriptor)) {
methodDesc = "(" + typeMapper.mapType((ClassDescriptor) parentDescriptor).getDescriptor() + methodDesc.substring(1);
}
node = InlineCodegenUtil.getMethodNode(file.getInputStream(), functionDescriptor.getName().asString(), methodDesc);
if (node == null) { if (node == null) {
throw new RuntimeException("Couldn't obtain compiled function body for " + descriptorName(functionDescriptor)); throw new RuntimeException("Couldn't obtain compiled function body for " + descriptorName(functionDescriptor));
@@ -418,7 +422,8 @@ public class InlineCodegen implements ParentCodegenAware, CallGenerator {
CodegenContext parent = getContext(descriptor.getContainingDeclaration(), state); CodegenContext parent = getContext(descriptor.getContainingDeclaration(), state);
if (descriptor instanceof ClassDescriptor) { if (descriptor instanceof ClassDescriptor) {
return parent.intoClass((ClassDescriptor) descriptor, OwnerKind.IMPLEMENTATION, state); OwnerKind kind = DescriptorUtils.isTrait(descriptor) ? OwnerKind.TRAIT_IMPL : OwnerKind.IMPLEMENTATION;
return parent.intoClass((ClassDescriptor) descriptor, kind, state);
} }
else if (descriptor instanceof FunctionDescriptor) { else if (descriptor instanceof FunctionDescriptor) {
return parent.intoFunction((FunctionDescriptor) descriptor); return parent.intoFunction((FunctionDescriptor) descriptor);
@@ -48,6 +48,7 @@ import java.io.InputStream;
import java.util.Arrays; import java.util.Arrays;
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.getFqName; import static org.jetbrains.jet.lang.resolve.DescriptorUtils.getFqName;
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isTrait;
public class InlineCodegenUtil { public class InlineCodegenUtil {
@@ -79,7 +80,7 @@ public class InlineCodegenUtil {
@NotNull @NotNull
public static VirtualFile getVirtualFileForCallable(DeserializedSimpleFunctionDescriptor deserializedDescriptor, GenerationState state) { public static VirtualFile getVirtualFileForCallable(@NotNull DeserializedSimpleFunctionDescriptor deserializedDescriptor, @NotNull GenerationState state) {
VirtualFile file; VirtualFile file;
DeclarationDescriptor parentDeclaration = deserializedDescriptor.getContainingDeclaration(); DeclarationDescriptor parentDeclaration = deserializedDescriptor.getContainingDeclaration();
if (parentDeclaration instanceof PackageFragmentDescriptor) { if (parentDeclaration instanceof PackageFragmentDescriptor) {
@@ -124,7 +125,7 @@ public class InlineCodegenUtil {
return PackageClassUtils.getPackageClassFqName(getFqName(containerDescriptor).toSafe()); return PackageClassUtils.getPackageClassFqName(getFqName(containerDescriptor).toSafe());
} }
if (containerDescriptor instanceof ClassDescriptor) { if (containerDescriptor instanceof ClassDescriptor) {
return DeserializedResolverUtils.kotlinFqNameToJavaFqName(getFqName(containerDescriptor)); return DeserializedResolverUtils.kotlinFqNameToJavaFqName(getFqName(containerDescriptor), isTrait(containerDescriptor));
} }
return null; return null;
} }
@@ -34,13 +34,21 @@ public class DeserializedResolverUtils {
private DeserializedResolverUtils() { private DeserializedResolverUtils() {
} }
@NotNull
public static FqName kotlinFqNameToJavaFqName(@NotNull FqNameUnsafe kotlinFqName) { public static FqName kotlinFqNameToJavaFqName(@NotNull FqNameUnsafe kotlinFqName) {
return kotlinFqNameToJavaFqName(kotlinFqName, false);
}
@NotNull
public static FqName kotlinFqNameToJavaFqName(@NotNull FqNameUnsafe kotlinFqName, boolean addTraitImplSuffix) {
List<Name> segments = kotlinFqName.pathSegments(); List<Name> segments = kotlinFqName.pathSegments();
List<String> correctedSegments = new ArrayList<String>(segments.size()); List<String> correctedSegments = new ArrayList<String>(segments.size());
for (Name segment : segments) { for (Name segment : segments) {
correctedSegments.add(isClassObjectName(segment) ? JvmAbi.CLASS_OBJECT_CLASS_NAME : segment.getIdentifier()); correctedSegments.add(isClassObjectName(segment) ? JvmAbi.CLASS_OBJECT_CLASS_NAME : segment.getIdentifier());
} }
if (addTraitImplSuffix) {
int lastIndex = correctedSegments.size() - 1;
correctedSegments.set(lastIndex, correctedSegments.get(lastIndex) + JvmAbi.TRAIT_IMPL_SUFFIX);
}
return FqName.fromSegments(correctedSegments); return FqName.fromSegments(correctedSegments);
} }