提交 c943525e 编写于 作者: D Dmitry Jemerov

generate new array creation

上级 0afddb4d
......@@ -26,6 +26,7 @@ import org.objectweb.asm.Type;
import org.objectweb.asm.commons.InstructionAdapter;
import org.objectweb.asm.commons.Method;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Stack;
......@@ -1153,43 +1154,61 @@ public class ExpressionCodegen extends JetVisitor {
@Override
public void visitNewExpression(JetNewExpression expression) {
final JetUserType constructorType = (JetUserType) expression.getTypeReference().getTypeElement();
JetTypeReference typeReference = expression.getTypeReference();
final JetUserType constructorType = (JetUserType) typeReference.getTypeElement();
final JetSimpleNameExpression constructorReference = constructorType.getReferenceExpression();
DeclarationDescriptor constructorDescriptor = bindingContext.resolveReferenceExpression(constructorReference);
final PsiElement declaration = bindingContext.getDeclarationPsiElement(constructorDescriptor);
Type type;
if (declaration instanceof PsiMethod) {
final PsiMethod constructor = (PsiMethod) declaration;
PsiClass javaClass = constructor.getContainingClass();
Type type = JetTypeMapper.psiClassType(javaClass);
v.anew(type);
v.dup();
final Method jvmConstructor = getMethodDescriptor(constructor);
pushMethodArguments(expression, jvmConstructor);
v.invokespecial(JetTypeMapper.jvmName(javaClass), "<init>", jvmConstructor.getDescriptor());
myStack.push(StackValue.onStack(type));
return;
type = generateJavaConstructorCall(expression, (PsiMethod) declaration);
}
else if (constructorDescriptor instanceof ConstructorDescriptor) {
ClassDescriptor classDecl = (ClassDescriptor) constructorDescriptor.getContainingDeclaration();
Type type = JetTypeMapper.jetImplementationType(classDecl);
v.anew(type);
v.dup();
type = typeMapper.mapType(bindingContext.resolveTypeReference(typeReference), OwnerKind.IMPLEMENTATION);
if (type.getSort() == Type.ARRAY) {
generateNewArray(expression, type);
}
else {
v.anew(type);
v.dup();
Method method = typeMapper.mapConstructorSignature((ConstructorDescriptor) constructorDescriptor, OwnerKind.IMPLEMENTATION);
pushMethodArguments(expression, method);
Method method = typeMapper.mapConstructorSignature((ConstructorDescriptor) constructorDescriptor, OwnerKind.IMPLEMENTATION);
pushMethodArguments(expression, method);
for (JetTypeReference typeArgumentReference : constructorType.getTypeArgumentsAsTypes()) {
JetType typeArgument = bindingContext.resolveTypeReference(typeArgumentReference);
// TODO is the makeNullable() call correct here?
ClassCodegen.newTypeInfo(v, typeMapper.mapType(TypeUtils.makeNullable(typeArgument)));
}
for (JetTypeReference typeArgumentReference : constructorType.getTypeArgumentsAsTypes()) {
JetType typeArgument = bindingContext.resolveTypeReference(typeArgumentReference);
// TODO is the makeNullable() call correct here?
ClassCodegen.newTypeInfo(v, typeMapper.mapType(TypeUtils.makeNullable(typeArgument)));
}
v.invokespecial(JetTypeMapper.jvmNameForImplementation(classDecl), "<init>", method.getDescriptor());
myStack.push(StackValue.onStack(type));
return;
ClassDescriptor classDecl = (ClassDescriptor) constructorDescriptor.getContainingDeclaration();
v.invokespecial(JetTypeMapper.jvmNameForImplementation(classDecl), "<init>", method.getDescriptor());
}
}
else {
throw new UnsupportedOperationException("don't know how to generate this new expression");
}
myStack.push(StackValue.onStack(type));
}
throw new UnsupportedOperationException("don't know how to generate this new expression");
private Type generateJavaConstructorCall(JetNewExpression expression, PsiMethod constructor) {
PsiClass javaClass = constructor.getContainingClass();
Type type = JetTypeMapper.psiClassType(javaClass);
v.anew(type);
v.dup();
final Method jvmConstructor = getMethodDescriptor(constructor);
pushMethodArguments(expression, jvmConstructor);
v.invokespecial(JetTypeMapper.jvmName(javaClass), "<init>", jvmConstructor.getDescriptor());
return type;
}
private void generateNewArray(JetNewExpression expression, Type type) {
List<JetArgument> args = expression.getValueArguments();
if (args.size() != 1) {
throw new CompilationException("array constructor requires one value argument");
}
gen(args.get(0).getArgumentExpression(), Type.INT_TYPE);
v.newarray(type.getElementType());
}
@Override
......@@ -1308,7 +1327,7 @@ public class ExpressionCodegen extends JetVisitor {
if (!(descriptor instanceof ClassDescriptor)) {
throw new UnsupportedOperationException("don't know how to handle non-class types in as/as?");
}
Type type = typeMapper.jvmType((ClassDescriptor) descriptor, OwnerKind.INTERFACE);
Type type = typeMapper.mapType(jetType, OwnerKind.INTERFACE);
gen(expression.getLeft(), OBJECT_TYPE);
if (opToken == JetTokens.AS_SAFE) {
generateInstanceOf(new Runnable() {
......@@ -1380,7 +1399,7 @@ public class ExpressionCodegen extends JetVisitor {
if (leaveExpressionOnStack) {
v.dup();
}
Type type = typeMapper.jvmType((ClassDescriptor) descriptor, OwnerKind.INTERFACE);
Type type = typeMapper.mapType(jetType, OwnerKind.INTERFACE);
v.instanceOf(type);
}
}
......@@ -1487,5 +1506,11 @@ public class ExpressionCodegen extends JetVisitor {
}
private static class CompilationException extends RuntimeException {
private CompilationException() {
}
private CompilationException(String message) {
super(message);
}
}
}
......@@ -3,6 +3,7 @@ package org.jetbrains.jet.codegen;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import jet.typeinfo.TypeInfo;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
......@@ -118,6 +119,10 @@ public class JetTypeMapper {
}
public Type mapType(final JetType jetType) {
return mapType(jetType, OwnerKind.INTERFACE);
}
public Type mapType(final JetType jetType, OwnerKind kind) {
if (jetType.equals(JetStandardClasses.getUnitType()) || jetType.equals(JetStandardClasses.getNothingType())) {
return Type.VOID_TYPE;
}
......@@ -191,7 +196,7 @@ public class JetTypeMapper {
if (declaration instanceof PsiClass) {
return psiClassType((PsiClass) declaration);
}
return Type.getObjectType(jvmNameForInterface((ClassDescriptor) descriptor));
return Type.getObjectType(jetJvmName((ClassDescriptor) descriptor, kind));
}
throw new UnsupportedOperationException("Unknown type " + jetType);
......
......@@ -360,6 +360,13 @@ public class NamespaceGenTest extends CodegenTestCase {
assertEquals(10, data[0]);
}
public void testArrayNew() throws Exception {
loadText("fun foo() = new Array<Int>(4)");
final Method main = generateFunction();
int[] result = (int[]) main.invoke(null);
assertEquals(4, result.length);
}
public void testIntRange() throws Exception {
loadText("fun foo() = 1..10");
final Method main = generateFunction();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册