generate Java constructors
This commit is contained in:
@@ -277,7 +277,7 @@ public class ExpressionCodegen extends JetVisitor {
|
||||
PsiField psiField = (PsiField) declaration;
|
||||
if (psiField.hasModifierProperty(PsiModifier.STATIC)) {
|
||||
v.visitFieldInsn(Opcodes.GETSTATIC,
|
||||
jvmName(psiField.getContainingClass()),
|
||||
JetTypeMapper.jvmName(psiField.getContainingClass()),
|
||||
psiField.getName(),
|
||||
psiTypeToAsm(psiField.getType()).getDescriptor());
|
||||
}
|
||||
@@ -342,23 +342,17 @@ public class ExpressionCodegen extends JetVisitor {
|
||||
PsiElement declarationPsiElement = bindingContext.getDeclarationPsiElement(funDescriptor);
|
||||
if (declarationPsiElement instanceof PsiMethod) {
|
||||
PsiMethod method = (PsiMethod) declarationPsiElement;
|
||||
PsiParameter[] parameters = method.getParameterList().getParameters();
|
||||
|
||||
List<JetArgument> args = expression.getValueArguments();
|
||||
for (int i = 0, argsSize = args.size(); i < argsSize; i++) {
|
||||
JetArgument arg = args.get(i);
|
||||
gen(arg.getArgumentExpression(), psiTypeToAsm(parameters[i].getType()));
|
||||
}
|
||||
pushMethodArguments(expression, method);
|
||||
|
||||
if (method.hasModifierProperty(PsiModifier.STATIC)) {
|
||||
v.visitMethodInsn(Opcodes.INVOKESTATIC,
|
||||
jvmName(method.getContainingClass()),
|
||||
JetTypeMapper.jvmName(method.getContainingClass()),
|
||||
method.getName(),
|
||||
getMethodDescriptor(method));
|
||||
}
|
||||
else {
|
||||
v.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
|
||||
jvmName(method.getContainingClass()),
|
||||
JetTypeMapper.jvmName(method.getContainingClass()),
|
||||
method.getName(),
|
||||
getMethodDescriptor(method));
|
||||
}
|
||||
@@ -380,8 +374,14 @@ public class ExpressionCodegen extends JetVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
private static String jvmName(PsiClass containingClass) {
|
||||
return containingClass.getQualifiedName().replace(".", "/");
|
||||
private void pushMethodArguments(JetCall expression, PsiMethod method) {
|
||||
PsiParameter[] parameters = method.getParameterList().getParameters();
|
||||
|
||||
List<JetArgument> args = expression.getValueArguments();
|
||||
for (int i = 0, argsSize = args.size(); i < argsSize; i++) {
|
||||
JetArgument arg = args.get(i);
|
||||
gen(arg.getArgumentExpression(), psiTypeToAsm(parameters[i].getType()));
|
||||
}
|
||||
}
|
||||
|
||||
private void unbox(PsiType type) {
|
||||
@@ -396,7 +396,7 @@ public class ExpressionCodegen extends JetVisitor {
|
||||
}
|
||||
|
||||
private static String getMethodDescriptor(PsiMethod method) {
|
||||
Type returnType = psiTypeToAsm(method.getReturnType());
|
||||
Type returnType = method.isConstructor() ? Type.VOID_TYPE : psiTypeToAsm(method.getReturnType());
|
||||
PsiParameter[] parameters = method.getParameterList().getParameters();
|
||||
Type[] parameterTypes = new Type[parameters.length];
|
||||
for (int i = 0; i < parameters.length; i++) {
|
||||
@@ -449,9 +449,9 @@ public class ExpressionCodegen extends JetVisitor {
|
||||
if (psiClass == null) {
|
||||
throw new UnsupportedOperationException("unresolved PsiClassType: " + type);
|
||||
}
|
||||
return Type.getType("L" + jvmName(psiClass) + ";");
|
||||
return JetTypeMapper.psiClassType(psiClass);
|
||||
}
|
||||
throw new UnsupportedOperationException("don't know how to map type " + type + " to ASM");
|
||||
throw new UnsupportedOperationException("don't know how to map type " + type + " to ASM");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -726,6 +726,7 @@ public class ExpressionCodegen extends JetVisitor {
|
||||
else {
|
||||
int oldStackSize = myStack.size();
|
||||
gen(expression.getBaseExpression(), asmType);
|
||||
generateIncrement(op, asmType, expression.getBaseExpression());
|
||||
myStack.push(StackValue.onStack(asmType));
|
||||
assert myStack.size() == oldStackSize+1;
|
||||
}
|
||||
@@ -810,6 +811,26 @@ public class ExpressionCodegen extends JetVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitNewExpression(JetNewExpression expression) {
|
||||
final JetUserType constructorType = (JetUserType) expression.getTypeReference().getTypeElement();
|
||||
final JetSimpleNameExpression constructorReference = constructorType.getReferenceExpression();
|
||||
final PsiElement declaration = bindingContext.getDeclarationPsiElement(bindingContext.resolveReferenceExpression(constructorReference));
|
||||
if (declaration instanceof PsiMethod) {
|
||||
final PsiMethod constructor = (PsiMethod) declaration;
|
||||
PsiClass javaClass = constructor.getContainingClass();
|
||||
Type type = JetTypeMapper.psiClassType(javaClass);
|
||||
v.anew(type);
|
||||
v.dup();
|
||||
pushMethodArguments(expression, constructor);
|
||||
v.invokespecial(JetTypeMapper.jvmName(javaClass), "<init>", getMethodDescriptor(constructor));
|
||||
myStack.push(StackValue.onStack(type));
|
||||
return;
|
||||
}
|
||||
|
||||
throw new UnsupportedOperationException("don't know how to generate this new expression");
|
||||
}
|
||||
|
||||
private static class CompilationException extends RuntimeException {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ public class FunctionCodegen {
|
||||
this.v = v;
|
||||
this.bindingContext = bindingContext;
|
||||
this.standardLibrary = standardLibrary;
|
||||
typeMapper = new JetTypeMapper(standardLibrary);
|
||||
typeMapper = new JetTypeMapper(standardLibrary, bindingContext);
|
||||
}
|
||||
|
||||
public void gen(JetFunction f, JetNamespace owner) {
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
package org.jetbrains.jet.codegen;
|
||||
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.types.*;
|
||||
import org.objectweb.asm.Type;
|
||||
|
||||
@@ -8,9 +11,19 @@ import org.objectweb.asm.Type;
|
||||
*/
|
||||
public class JetTypeMapper {
|
||||
private final JetStandardLibrary standardLibrary;
|
||||
private final BindingContext bindingContext;
|
||||
|
||||
public JetTypeMapper(JetStandardLibrary standardLibrary) {
|
||||
public JetTypeMapper(JetStandardLibrary standardLibrary, BindingContext bindingContext) {
|
||||
this.standardLibrary = standardLibrary;
|
||||
this.bindingContext = bindingContext;
|
||||
}
|
||||
|
||||
static String jvmName(PsiClass psiClass) {
|
||||
return psiClass.getQualifiedName().replace(".", "/");
|
||||
}
|
||||
|
||||
static Type psiClassType(PsiClass psiClass) {
|
||||
return Type.getType("L" + jvmName(psiClass) + ";");
|
||||
}
|
||||
|
||||
public Type mapType(final JetType jetType) {
|
||||
@@ -83,6 +96,10 @@ public class JetTypeMapper {
|
||||
}
|
||||
|
||||
if (descriptor instanceof ClassDescriptor) {
|
||||
final PsiElement declaration = bindingContext.getDeclarationPsiElement(descriptor);
|
||||
if (declaration instanceof PsiClass) {
|
||||
return psiClassType((PsiClass) declaration);
|
||||
}
|
||||
return Type.getObjectType(CodeGenUtil.getInternalInterfaceName((ClassDescriptor) descriptor));
|
||||
}
|
||||
|
||||
|
||||
@@ -494,6 +494,7 @@ public class NamespaceGenTest extends LightCodeInsightFixtureTestCase {
|
||||
|
||||
public void testJavaConstructor() throws Exception {
|
||||
loadText("fun foo(): StringBuilder = new StringBuilder()");
|
||||
System.out.println(generateToText());
|
||||
final Method main = generateFunction();
|
||||
final Object result = main.invoke(null);
|
||||
assertTrue(result instanceof StringBuilder);
|
||||
|
||||
Reference in New Issue
Block a user