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.resolve.BindingContext;
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.java.AsmTypeConstants;
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.isPrimitive;
import static org.jetbrains.jet.codegen.binding.CodegenBinding.asmTypeForAnonymousClass;
public class InlineCodegen implements ParentCodegenAware, CallGenerator {
@@ -150,8 +150,12 @@ public class InlineCodegen implements ParentCodegenAware, CallGenerator {
MethodNode node;
if (functionDescriptor instanceof DeserializedSimpleFunctionDescriptor) {
VirtualFile file = InlineCodegenUtil.getVirtualFileForCallable((DeserializedSimpleFunctionDescriptor) functionDescriptor, state);
node = InlineCodegenUtil.getMethodNode(file.getInputStream(), functionDescriptor.getName().asString(),
callableMethod.getAsmMethod().getDescriptor());
String methodDesc = 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) {
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);
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) {
return parent.intoFunction((FunctionDescriptor) descriptor);
@@ -48,6 +48,7 @@ import java.io.InputStream;
import java.util.Arrays;
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.getFqName;
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isTrait;
public class InlineCodegenUtil {
@@ -79,7 +80,7 @@ public class InlineCodegenUtil {
@NotNull
public static VirtualFile getVirtualFileForCallable(DeserializedSimpleFunctionDescriptor deserializedDescriptor, GenerationState state) {
public static VirtualFile getVirtualFileForCallable(@NotNull DeserializedSimpleFunctionDescriptor deserializedDescriptor, @NotNull GenerationState state) {
VirtualFile file;
DeclarationDescriptor parentDeclaration = deserializedDescriptor.getContainingDeclaration();
if (parentDeclaration instanceof PackageFragmentDescriptor) {
@@ -124,7 +125,7 @@ public class InlineCodegenUtil {
return PackageClassUtils.getPackageClassFqName(getFqName(containerDescriptor).toSafe());
}
if (containerDescriptor instanceof ClassDescriptor) {
return DeserializedResolverUtils.kotlinFqNameToJavaFqName(getFqName(containerDescriptor));
return DeserializedResolverUtils.kotlinFqNameToJavaFqName(getFqName(containerDescriptor), isTrait(containerDescriptor));
}
return null;
}
@@ -34,13 +34,21 @@ public class DeserializedResolverUtils {
private DeserializedResolverUtils() {
}
@NotNull
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<String> correctedSegments = new ArrayList<String>(segments.size());
for (Name segment : segments) {
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);
}