KT-518 - array like expression via intrinsic method
This commit is contained in:
@@ -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++;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
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);
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
|
||||
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"
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user