Added reference to array set method for expression like 'array[0]++'
This commit is contained in:
@@ -155,13 +155,13 @@ public class CallMaker {
|
||||
return makeCall(expression, baseAsReceiver, null, expression.getOperationReference(), Collections.<ValueArgument>emptyList());
|
||||
}
|
||||
|
||||
public static Call makeArraySetCall(@NotNull ReceiverDescriptor arrayAsReceiver, JetArrayAccessExpression arrayAccessExpression, JetExpression rightHandSide) {
|
||||
public static Call makeArraySetCall(@NotNull ReceiverDescriptor arrayAsReceiver, @NotNull JetArrayAccessExpression arrayAccessExpression, @NotNull JetExpression rightHandSide) {
|
||||
List<JetExpression> arguments = Lists.newArrayList(arrayAccessExpression.getIndexExpressions());
|
||||
arguments.add(rightHandSide);
|
||||
return makeCallWithExpressions(arrayAccessExpression, arrayAsReceiver, null, arrayAccessExpression, arguments);
|
||||
}
|
||||
|
||||
public static Call makeArrayGetCall(@NotNull ReceiverDescriptor arrayAsReceiver, JetArrayAccessExpression arrayAccessExpression) {
|
||||
public static Call makeArrayGetCall(@NotNull ReceiverDescriptor arrayAsReceiver, @NotNull JetArrayAccessExpression arrayAccessExpression) {
|
||||
return makeCallWithExpressions(arrayAccessExpression, arrayAsReceiver, null, arrayAccessExpression, arrayAccessExpression.getIndexExpressions());
|
||||
}
|
||||
|
||||
|
||||
@@ -28,10 +28,6 @@ public class ResolutionDebugInfo {
|
||||
public static final WritableSlice<ResolvedCall<? extends CallableDescriptor>, ConstraintSystemSolution> SOLUTION = Slices.createSimpleSlice();
|
||||
public static final WritableSlice<ResolvedCall<? extends CallableDescriptor>, Collection<TypeParameterDescriptor>> UNKNOWNS = Slices.createSimpleSlice();
|
||||
|
||||
static {
|
||||
BasicWritableSlice.initSliceDebugNames(ResolutionDebugInfo.class);
|
||||
}
|
||||
|
||||
public static boolean RESOLUTION_DEBUG_INFO_ENABLED = false;
|
||||
|
||||
public static boolean isResolutionDebugEnabled() {
|
||||
@@ -113,4 +109,8 @@ public class ResolutionDebugInfo {
|
||||
System.out.println(message);
|
||||
}
|
||||
}
|
||||
|
||||
static {
|
||||
BasicWritableSlice.initSliceDebugNames(ResolutionDebugInfo.class);
|
||||
}
|
||||
}
|
||||
|
||||
+63
-4
@@ -30,8 +30,7 @@ import org.jetbrains.jet.lexer.JetTokens;
|
||||
import java.util.*;
|
||||
|
||||
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
|
||||
import static org.jetbrains.jet.lang.resolve.BindingContext.INDEXED_LVALUE_GET;
|
||||
import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET;
|
||||
import static org.jetbrains.jet.lang.resolve.BindingContext.*;
|
||||
import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor.NO_RECEIVER;
|
||||
import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE;
|
||||
import static org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils.*;
|
||||
@@ -662,8 +661,26 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
||||
context.trace.report(UNSUPPORTED.on(operationSign, "visitUnaryExpression"));
|
||||
return null;
|
||||
}
|
||||
ExpressionReceiver receiver = getExpressionReceiver(facade, baseExpression, context.replaceExpectedType(NO_EXPECTED_TYPE).replaceScope(context.scope));
|
||||
if (receiver == null) return null;
|
||||
JetType type = null;
|
||||
|
||||
if ((operationType == JetTokens.PLUSPLUS || operationType == JetTokens.MINUSMINUS) && baseExpression instanceof JetArrayAccessExpression) {
|
||||
TemporaryBindingTrace temporaryTrace = TemporaryBindingTrace.create(context.trace);
|
||||
JetType expressionType = facade.getType(baseExpression, context.replaceExpectedType(NO_EXPECTED_TYPE).replaceBindingTrace(temporaryTrace));
|
||||
if (expressionType != null) {
|
||||
JetExpression stubExpression = ExpressionTypingUtils.createStubExpressionOfNecessaryType(baseExpression.getProject(), expressionType, context.trace);
|
||||
type = resolveArrayAccessToLValue((JetArrayAccessExpression) baseExpression, stubExpression, context, true);
|
||||
}
|
||||
else {
|
||||
temporaryTrace.commit();
|
||||
context.trace.report(UNRESOLVED_REFERENCE.on(operationSign));
|
||||
}
|
||||
}
|
||||
else {
|
||||
type = facade.getType(baseExpression, context.replaceExpectedType(NO_EXPECTED_TYPE));
|
||||
}
|
||||
if (type == null) return null;
|
||||
|
||||
ExpressionReceiver receiver = new ExpressionReceiver(baseExpression, type);
|
||||
|
||||
OverloadResolutionResults<FunctionDescriptor> functionDescriptor = context.resolveCallWithGivenNameToDescriptor(
|
||||
CallMaker.makeCall(receiver, expression),
|
||||
@@ -891,6 +908,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
||||
return DataFlowUtils.checkType(results.getResultingDescriptor().getReturnType(), expression, contextWithExpectedType);
|
||||
}
|
||||
}
|
||||
context.trace.report(NO_GET_METHOD.on(expression.getIndicesNode()));
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -981,4 +999,45 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
||||
context.trace.report(UNSUPPORTED.on(element, getClass().getCanonicalName()));
|
||||
return null;
|
||||
}
|
||||
|
||||
/*package*/ JetType resolveArrayAccessToLValue(@NotNull JetArrayAccessExpression arrayAccessExpression, @NotNull JetExpression right, @NotNull ExpressionTypingContext context, final boolean getterNeeded) {
|
||||
ExpressionReceiver receiver = getExpressionReceiver(facade, arrayAccessExpression.getArrayExpression(), context.replaceExpectedType(NO_EXPECTED_TYPE));
|
||||
if (receiver == null) return null;
|
||||
|
||||
OverloadResolutionResults<FunctionDescriptor> getFunctionResults = null;
|
||||
if (getterNeeded) {
|
||||
TemporaryBindingTrace temporaryTrace = TemporaryBindingTrace.create(context.trace);
|
||||
getFunctionResults = context.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE).replaceBindingTrace(temporaryTrace).resolveCallWithGivenName(
|
||||
CallMaker.makeArrayGetCall(receiver, arrayAccessExpression),
|
||||
arrayAccessExpression,
|
||||
"get");
|
||||
if (!getFunctionResults.isSuccess()) {
|
||||
temporaryTrace.commit();
|
||||
context.trace.report(NO_GET_METHOD.on(arrayAccessExpression.getIndicesNode()));
|
||||
return null;
|
||||
}
|
||||
context.trace.record(INDEXED_LVALUE_GET, arrayAccessExpression, getFunctionResults.getResultingCall());
|
||||
}
|
||||
|
||||
Call call = CallMaker.makeArraySetCall(receiver, arrayAccessExpression, right);
|
||||
OverloadResolutionResults<FunctionDescriptor> setFunctionResults = context.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE).resolveCallWithGivenName(
|
||||
call,
|
||||
arrayAccessExpression,
|
||||
"set");
|
||||
if (!setFunctionResults.isSuccess()) {
|
||||
context.trace.report(NO_SET_METHOD.on(arrayAccessExpression.getIndicesNode()));
|
||||
if (getterNeeded) {
|
||||
return getFunctionResults.getResultingDescriptor().getReturnType();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
FunctionDescriptor setFunctionDescriptor = setFunctionResults.getResultingDescriptor();
|
||||
context.trace.record(INDEXED_LVALUE_SET, arrayAccessExpression, setFunctionResults.getResultingCall());
|
||||
|
||||
if (getterNeeded) {
|
||||
return getFunctionResults.getResultingDescriptor().getReturnType();
|
||||
}
|
||||
|
||||
return setFunctionDescriptor.getReturnType();
|
||||
}
|
||||
}
|
||||
+19
-6
@@ -1,5 +1,6 @@
|
||||
package org.jetbrains.jet.lang.types.expressions;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.tree.TokenSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -10,8 +11,10 @@ import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetPsiFactory;
|
||||
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
|
||||
import org.jetbrains.jet.lang.resolve.BindingTrace;
|
||||
import org.jetbrains.jet.lang.resolve.TraceBasedRedeclarationHandler;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl;
|
||||
@@ -20,20 +23,22 @@ import org.jetbrains.jet.lang.types.JetStandardClasses;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
|
||||
import static org.jetbrains.jet.lang.diagnostics.Errors.RESULT_TYPE_MISMATCH;
|
||||
import static org.jetbrains.jet.lang.resolve.BindingContext.MUST_BE_WRAPPED_IN_A_REF;
|
||||
import static org.jetbrains.jet.lang.resolve.BindingContext.*;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class ExpressionTypingUtils {
|
||||
|
||||
@Nullable
|
||||
protected static ExpressionReceiver getExpressionReceiver(@NotNull JetExpression expression, @Nullable JetType type) {
|
||||
if (type == null) return null;
|
||||
return new ExpressionReceiver(expression, type);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected static ExpressionReceiver getExpressionReceiver(@NotNull ExpressionTypingFacade facade, @NotNull JetExpression expression, ExpressionTypingContext context) {
|
||||
JetType type = facade.getType(expression, context);
|
||||
if (type == null) {
|
||||
return null;
|
||||
}
|
||||
return new ExpressionReceiver(expression, type);
|
||||
return getExpressionReceiver(expression, facade.getType(expression, context));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -113,4 +118,12 @@ public class ExpressionTypingUtils {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JetExpression createStubExpressionOfNecessaryType(@NotNull Project project, @NotNull JetType type, @NotNull BindingTrace trace) {
|
||||
JetExpression expression = JetPsiFactory.createExpression(project, "$e");
|
||||
trace.record(PROCESSED, expression);
|
||||
trace.record(EXPRESSION_TYPE, expression, type);
|
||||
return expression;
|
||||
}
|
||||
}
|
||||
|
||||
+2
-34
@@ -10,20 +10,15 @@ import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||
import org.jetbrains.jet.lang.resolve.TemporaryBindingTrace;
|
||||
import org.jetbrains.jet.lang.resolve.TopDownAnalyzer;
|
||||
import org.jetbrains.jet.lang.resolve.calls.CallMaker;
|
||||
import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResults;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver;
|
||||
import org.jetbrains.jet.lang.types.JetStandardClasses;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.TypeUtils;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
|
||||
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
|
||||
import static org.jetbrains.jet.lang.resolve.BindingContext.INDEXED_LVALUE_SET;
|
||||
import static org.jetbrains.jet.lang.resolve.BindingContext.VARIABLE_REASSIGNMENT;
|
||||
import static org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils.getExpressionReceiver;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
@@ -161,7 +156,7 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
|
||||
|
||||
if (left instanceof JetArrayAccessExpression) {
|
||||
JetArrayAccessExpression arrayAccessExpression = (JetArrayAccessExpression) left;
|
||||
resolveArrayAccessToLValue(arrayAccessExpression, expression.getRight(), operationSign, context);
|
||||
basic.resolveArrayAccessToLValue(arrayAccessExpression, expression.getRight(), context.replaceScope(scope), false);
|
||||
}
|
||||
assignmentOperationType = basic.getTypeForBinaryCall(scope, counterpartName, context, expression);
|
||||
if (assignmentOperationType != null) {
|
||||
@@ -201,7 +196,7 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
|
||||
JetExpression right = expression.getRight();
|
||||
if (left instanceof JetArrayAccessExpression) {
|
||||
JetArrayAccessExpression arrayAccessExpression = (JetArrayAccessExpression) left;
|
||||
JetType assignmentType = resolveArrayAccessToLValue(arrayAccessExpression, right, expression.getOperationReference(), context);
|
||||
JetType assignmentType = basic.resolveArrayAccessToLValue(arrayAccessExpression, right, context.replaceScope(scope), false); //todo
|
||||
basic.checkLValue(context.trace, arrayAccessExpression);
|
||||
return checkAssignmentType(assignmentType, expression, contextWithExpectedType);
|
||||
}
|
||||
@@ -218,33 +213,6 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
|
||||
return DataFlowUtils.checkStatementType(expression, contextWithExpectedType);
|
||||
}
|
||||
|
||||
private JetType resolveArrayAccessToLValue(JetArrayAccessExpression arrayAccessExpression, JetExpression rightHandSide, JetSimpleNameExpression operationSign, ExpressionTypingContext context) {
|
||||
ExpressionReceiver receiver = getExpressionReceiver(facade, arrayAccessExpression.getArrayExpression(), context.replaceScope(scope));
|
||||
if (receiver == null) return null;
|
||||
|
||||
Call call = CallMaker.makeArraySetCall(receiver, arrayAccessExpression, rightHandSide);
|
||||
OverloadResolutionResults<FunctionDescriptor> setFunctionResults = context.replaceScope(scope).replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE).resolveCallWithGivenName(
|
||||
call,
|
||||
arrayAccessExpression,
|
||||
"set");
|
||||
if (!setFunctionResults.isSuccess()) return null;
|
||||
FunctionDescriptor setFunctionDescriptor = setFunctionResults.getResultingDescriptor();
|
||||
|
||||
context.trace.record(INDEXED_LVALUE_SET, arrayAccessExpression, setFunctionResults.getResultingCall());
|
||||
|
||||
// if (getterNeeded) {
|
||||
// ResolvedCall<FunctionDescriptor> getFunctionCall = context.replaceScope(scope).replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE).resolveCallWithGivenName(
|
||||
// CallMaker.makeArrayGetCall(receiver, arrayAccessExpression),
|
||||
// arrayAccessExpression,
|
||||
// "get");
|
||||
// if (getFunctionCall == null) return null;
|
||||
// context.trace.record(INDEXED_LVALUE_GET, arrayAccessExpression, getFunctionCall);
|
||||
// }
|
||||
// else {
|
||||
// context.trace.record(REFERENCE_TARGET, operationSign, setFunctionDescriptor);
|
||||
// }
|
||||
return setFunctionDescriptor.getReturnType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JetType visitExpression(JetExpression expression, ExpressionTypingContext context) {
|
||||
|
||||
@@ -37,7 +37,7 @@ fun test4() : Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
fun test5() : Boolean {
|
||||
/*fun test5() : Boolean {
|
||||
var mnr = Array<MyNumber>(2,{MyNumber(42)})
|
||||
mnr[0]++
|
||||
if (mnr[0].i != 43) return false
|
||||
@@ -52,7 +52,6 @@ fun test6() : Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
/*
|
||||
fun test7() : Boolean {
|
||||
var mnr = ArrayList<MyNumber>()
|
||||
mnr.add(MyNumber(42))
|
||||
@@ -79,9 +78,9 @@ fun box() : String {
|
||||
if (!test2()) return "fail test 2"
|
||||
if (!test3()) return "fail test 3"
|
||||
if (!test4()) return "fail test 4"
|
||||
/*
|
||||
if (!test5()) return "fail test 5"
|
||||
if (!test6()) return "fail test 6"
|
||||
/*
|
||||
if (!test7()) return "fail test 7"
|
||||
if (!test8()) return "fail test 8"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user