提交 b054ccef 编写于 作者: A Alex Tkachman

KT-518 - array like expression via intrinsic method

上级 c8962062
......@@ -1130,7 +1130,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
return StackValue.none();
}
private Callable resolveToCallable(DeclarationDescriptor fd, boolean superCall) {
Callable resolveToCallable(DeclarationDescriptor fd, boolean superCall) {
final IntrinsicMethod intrinsic = intrinsics.getIntrinsic(fd);
if (intrinsic != null) {
return intrinsic;
......@@ -2099,11 +2099,11 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
final JetExpression array = expression.getArrayExpression();
JetType type = bindingContext.get(BindingContext.EXPRESSION_TYPE, array);
final Type arrayType = type == null ? Type.VOID_TYPE : typeMapper.mapType(type);
gen(array, arrayType);
final List<JetExpression> indices = expression.getIndexExpressions();
FunctionDescriptor operationDescriptor = (FunctionDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, expression);
assert operationDescriptor != null;
if (arrayType.getSort() == Type.ARRAY && indices.size() == 1 && operationDescriptor.getValueParameters().get(0).getOutType().equals(state.getStandardLibrary().getIntType())) {
gen(array, arrayType);
for (JetExpression index : indices) {
gen(index, Type.INT_TYPE);
}
......@@ -2132,6 +2132,12 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
Type[] argumentTypes = accessor.getSignature().getArgumentTypes();
int index = 0;
if(isGetter) {
Callable callable = resolveToCallable(getterDescriptor, false);
if(callable instanceof CallableMethod)
genThisAndReceiverFromResolvedCall((CallableMethod) callable, receiver, resolvedGetCall);
else
gen(array, typeMapper.mapType(((ClassDescriptor)getterDescriptor.getContainingDeclaration()).getDefaultType()));
assert getterDescriptor != null;
if(getterDescriptor.getReceiverParameter().exists()) {
index++;
......@@ -2145,6 +2151,12 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
asmType = accessor.getSignature().getReturnType();
}
else {
Callable callable = resolveToCallable(resolvedSetCall.getResultingDescriptor(), false);
if(callable instanceof CallableMethod)
genThisAndReceiverFromResolvedCall((CallableMethod) callable, receiver, resolvedSetCall);
else
gen(array, arrayType);
assert setterDescriptor != null;
if(setterDescriptor.getReceiverParameter().exists()) {
index++;
......
package org.jetbrains.jet.codegen;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.jet.codegen.intrinsics.IntrinsicMethod;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
......@@ -482,8 +483,8 @@ public abstract class StackValue {
}
private static class CollectionElement extends StackValue {
private final CallableMethod getter;
private final CallableMethod setter;
private final Callable getter;
private final Callable setter;
private final ExpressionCodegen codegen;
private final FrameMap frame;
private final ResolvedCall<FunctionDescriptor> resolvedGetCall;
......@@ -497,8 +498,8 @@ public abstract class StackValue {
this.resolvedSetCall = resolvedSetCall;
this.setterDescriptor = resolvedSetCall == null ? null : resolvedSetCall.getResultingDescriptor();
this.getterDescriptor = resolvedGetCall == null ? null : resolvedGetCall.getResultingDescriptor();
this.setter = resolvedSetCall == null ? null : codegen.typeMapper.mapToCallableMethod(setterDescriptor, false, OwnerKind.IMPLEMENTATION);
this.getter = resolvedGetCall == null ? null : codegen.typeMapper.mapToCallableMethod(getterDescriptor, false, OwnerKind.IMPLEMENTATION);
this.setter = resolvedSetCall == null ? null : codegen.resolveToCallable(setterDescriptor, false);
this.getter = resolvedGetCall == null ? null : codegen.resolveToCallable(getterDescriptor, false);
this.codegen = codegen;
this.frame = codegen.myFrameMap;
}
......@@ -508,7 +509,10 @@ public abstract class StackValue {
if (getter == null) {
throw new UnsupportedOperationException("no getter specified");
}
getter.invoke(v);
if(getter instanceof CallableMethod)
((CallableMethod)getter).invoke(v);
else
((IntrinsicMethod)getter).generate(codegen, v, null, null, null, null);
coerce(type, v);
}
......@@ -517,7 +521,10 @@ public abstract class StackValue {
if (setter == null) {
throw new UnsupportedOperationException("no setter specified");
}
setter.invoke(v);
if(setter instanceof CallableMethod)
((CallableMethod)setter).invoke(v);
else
((IntrinsicMethod)setter).generate(codegen, v, null, null, null, null);
}
@Override
......
......@@ -76,6 +76,7 @@ public class IntrinsicMethods {
declareIntrinsicFunction("Boolean", "not", 0, new Not());
declareIntrinsicFunction("String", "plus", 1, new Concat());
declareIntrinsicFunction("String", "get", 1, new StringGetChar());
declareOverload(myStdLib.getLibraryScope().getFunctions("toString"), 0, new ToString());
declareOverload(myStdLib.getLibraryScope().getFunctions("equals"), 1, EQUALS);
......
package org.jetbrains.jet.codegen.intrinsics;
import com.intellij.psi.PsiElement;
import org.jetbrains.jet.codegen.ExpressionCodegen;
import org.jetbrains.jet.codegen.JetTypeMapper;
import org.jetbrains.jet.codegen.StackValue;
import org.jetbrains.jet.lang.psi.JetCallExpression;
import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lexer.JetTokens;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.InstructionAdapter;
import java.util.List;
/**
* @author alex.tkachman
*/
public class StringGetChar implements IntrinsicMethod {
@Override
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver) {
if(receiver != null)
receiver.put(JetTypeMapper.TYPE_OBJECT, v);
if(arguments != null)
codegen.gen(arguments.get(0)).put(Type.INT_TYPE, v);
v.invokevirtual("java/lang/String", "charAt", "(I)C");
return StackValue.onStack(Type.CHAR_TYPE);
}
}
fun foo(i : Int?, a : Any?) {
i?.plus(1)
if (i != null) {
i + 1
if (a is String) {
a[0]
}
}
}
fun box () : String {
foo(2, "239")
return "OK"
}
\ No newline at end of file
......@@ -280,4 +280,8 @@ public class PrimitiveTypesTest extends CodegenTestCase {
public void testKt446 () throws Exception {
blackBoxFile("regressions/kt446.jet");
}
public void testKt518 () throws Exception {
blackBoxFile("regressions/kt518.jet");
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册