ResolvedCalls for indexed expressions
This commit is contained in:
@@ -12,7 +12,6 @@ import org.jetbrains.jet.lang.descriptors.*;
|
|||||||
import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils;
|
import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
|
|
||||||
import org.jetbrains.jet.lang.resolve.calls.*;
|
import org.jetbrains.jet.lang.resolve.calls.*;
|
||||||
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
|
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
|
||||||
import org.jetbrains.jet.lang.resolve.java.JavaClassDescriptor;
|
import org.jetbrains.jet.lang.resolve.java.JavaClassDescriptor;
|
||||||
@@ -1976,14 +1975,16 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
boolean isGetter = accessor.getSignature().getName().equals("get");
|
boolean isGetter = accessor.getSignature().getName().equals("get");
|
||||||
|
|
||||||
if(isGetter) {
|
if(isGetter) {
|
||||||
FunctionDescriptor setterDescriptor = bindingContext.get(BindingContext.INDEXED_LVALUE_SET, expression);
|
ResolvedCall<FunctionDescriptor> resolvedCall = bindingContext.get(BindingContext.INDEXED_LVALUE_SET, expression);
|
||||||
|
FunctionDescriptor setterDescriptor = resolvedCall == null ? null : resolvedCall.getResultingDescriptor();
|
||||||
return StackValue.collectionElement(
|
return StackValue.collectionElement(
|
||||||
accessor.getSignature().getReturnType(),
|
accessor.getSignature().getReturnType(),
|
||||||
accessor,
|
accessor,
|
||||||
setterDescriptor != null ? typeMapper.mapToCallableMethod(setterDescriptor, OwnerKind.IMPLEMENTATION) : null);
|
setterDescriptor != null ? typeMapper.mapToCallableMethod(setterDescriptor, OwnerKind.IMPLEMENTATION) : null);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
FunctionDescriptor getterDescriptor = bindingContext.get(BindingContext.INDEXED_LVALUE_GET, expression);
|
ResolvedCall<FunctionDescriptor> resolvedCall = bindingContext.get(BindingContext.INDEXED_LVALUE_GET, expression);
|
||||||
|
FunctionDescriptor getterDescriptor = resolvedCall == null ? null : resolvedCall.getResultingDescriptor();
|
||||||
return StackValue.collectionElement(
|
return StackValue.collectionElement(
|
||||||
accessor.getSignature().getArgumentTypes()[1],
|
accessor.getSignature().getArgumentTypes()[1],
|
||||||
getterDescriptor != null ? typeMapper.mapToCallableMethod(getterDescriptor, OwnerKind.IMPLEMENTATION) : null,
|
getterDescriptor != null ? typeMapper.mapToCallableMethod(getterDescriptor, OwnerKind.IMPLEMENTATION) : null,
|
||||||
|
|||||||
@@ -36,8 +36,8 @@ public interface BindingContext {
|
|||||||
WritableSlice<JetExpression, CallableDescriptor> LOOP_RANGE_HAS_NEXT = Slices.createSimpleSlice("LOOP_RANGE_HAS_NEXT");
|
WritableSlice<JetExpression, CallableDescriptor> LOOP_RANGE_HAS_NEXT = Slices.createSimpleSlice("LOOP_RANGE_HAS_NEXT");
|
||||||
WritableSlice<JetExpression, FunctionDescriptor> LOOP_RANGE_NEXT = Slices.createSimpleSlice("LOOP_RANGE_NEXT");
|
WritableSlice<JetExpression, FunctionDescriptor> LOOP_RANGE_NEXT = Slices.createSimpleSlice("LOOP_RANGE_NEXT");
|
||||||
|
|
||||||
WritableSlice<JetExpression, FunctionDescriptor> INDEXED_LVALUE_GET = Slices.createSimpleSlice("INDEXED_LVALUE_GET");
|
WritableSlice<JetExpression, ResolvedCall<FunctionDescriptor>> INDEXED_LVALUE_GET = Slices.createSimpleSlice("INDEXED_LVALUE_GET");
|
||||||
WritableSlice<JetExpression, FunctionDescriptor> INDEXED_LVALUE_SET = Slices.createSimpleSlice("INDEXED_LVALUE_SET");
|
WritableSlice<JetExpression, ResolvedCall<FunctionDescriptor>> INDEXED_LVALUE_SET = Slices.createSimpleSlice("INDEXED_LVALUE_SET");
|
||||||
|
|
||||||
WritableSlice<JetExpression, JetType> AUTOCAST = Slices.createSimpleSlice("AUTOCAST");
|
WritableSlice<JetExpression, JetType> AUTOCAST = Slices.createSimpleSlice("AUTOCAST");
|
||||||
WritableSlice<JetExpression, JetScope> RESOLUTION_SCOPE = Slices.createSimpleSlice("RESOLUTION_SCOPE");
|
WritableSlice<JetExpression, JetScope> RESOLUTION_SCOPE = Slices.createSimpleSlice("RESOLUTION_SCOPE");
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ public class CallResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public FunctionDescriptor resolveCallWithGivenName(
|
public ResolvedCall<FunctionDescriptor> resolveCallWithGivenName(
|
||||||
@NotNull BindingTrace trace,
|
@NotNull BindingTrace trace,
|
||||||
@NotNull JetScope scope,
|
@NotNull JetScope scope,
|
||||||
@NotNull final Call call,
|
@NotNull final Call call,
|
||||||
@@ -86,7 +86,7 @@ public class CallResolver {
|
|||||||
@NotNull String name,
|
@NotNull String name,
|
||||||
@NotNull JetType expectedType) {
|
@NotNull JetType expectedType) {
|
||||||
List<ResolutionTask<FunctionDescriptor>> tasks = TaskPrioritizers.FUNCTION_TASK_PRIORITIZER.computePrioritizedTasks(scope, call, name, trace.getBindingContext(), dataFlowInfo);
|
List<ResolutionTask<FunctionDescriptor>> tasks = TaskPrioritizers.FUNCTION_TASK_PRIORITIZER.computePrioritizedTasks(scope, call, name, trace.getBindingContext(), dataFlowInfo);
|
||||||
return resolveCallToDescriptor(trace, scope, call, expectedType, tasks, functionReference);
|
return doResolveCall(trace, scope, call, expectedType, tasks, functionReference);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -174,7 +174,8 @@ public class CallResolver {
|
|||||||
prioritizedTasks = Collections.singletonList(new ResolutionTask<FunctionDescriptor>(ResolvedCallImpl.convertCollection(constructors), call, DataFlowInfo.EMPTY));
|
prioritizedTasks = Collections.singletonList(new ResolutionTask<FunctionDescriptor>(ResolvedCallImpl.convertCollection(constructors), call, DataFlowInfo.EMPTY));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw new UnsupportedOperationException("Type argument inference not implemented for " + call);
|
trace.report(UNSUPPORTED.on(call.getCallNode(), "Type argument inference is not supported for this callee: " + calleeExpression));
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+14
-14
@@ -11,6 +11,7 @@ import org.jetbrains.jet.lang.descriptors.*;
|
|||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.jet.lang.resolve.*;
|
import org.jetbrains.jet.lang.resolve.*;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.CallMaker;
|
import org.jetbrains.jet.lang.resolve.calls.CallMaker;
|
||||||
|
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
|
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResults;
|
import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResults;
|
||||||
import org.jetbrains.jet.lang.resolve.constants.*;
|
import org.jetbrains.jet.lang.resolve.constants.*;
|
||||||
@@ -559,11 +560,10 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
|||||||
ExpressionReceiver receiver = getExpressionReceiver(facade, baseExpression, context.replaceExpectedType(NO_EXPECTED_TYPE).replaceScope(context.scope));
|
ExpressionReceiver receiver = getExpressionReceiver(facade, baseExpression, context.replaceExpectedType(NO_EXPECTED_TYPE).replaceScope(context.scope));
|
||||||
if (receiver == null) return null;
|
if (receiver == null) return null;
|
||||||
|
|
||||||
FunctionDescriptor functionDescriptor = context.resolveCallWithGivenName(
|
FunctionDescriptor functionDescriptor = context.resolveCallWithGivenNameToDescriptor(
|
||||||
CallMaker.makeCall(receiver, expression),
|
CallMaker.makeCall(receiver, expression),
|
||||||
expression.getOperationSign(),
|
expression.getOperationSign(),
|
||||||
name,
|
name);
|
||||||
receiver);
|
|
||||||
|
|
||||||
if (functionDescriptor == null) return null;
|
if (functionDescriptor == null) return null;
|
||||||
JetType returnType = functionDescriptor.getReturnType();
|
JetType returnType = functionDescriptor.getReturnType();
|
||||||
@@ -705,10 +705,10 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
|||||||
public void checkInExpression(JetElement callElement, @NotNull JetSimpleNameExpression operationSign, @NotNull JetExpression left, @NotNull JetExpression right, ExpressionTypingContext context) {
|
public void checkInExpression(JetElement callElement, @NotNull JetSimpleNameExpression operationSign, @NotNull JetExpression left, @NotNull JetExpression right, ExpressionTypingContext context) {
|
||||||
String name = "contains";
|
String name = "contains";
|
||||||
ExpressionReceiver receiver = safeGetExpressionReceiver(facade, right, context.replaceExpectedType(NO_EXPECTED_TYPE));
|
ExpressionReceiver receiver = safeGetExpressionReceiver(facade, right, context.replaceExpectedType(NO_EXPECTED_TYPE));
|
||||||
FunctionDescriptor functionDescriptor = context.resolveCallWithGivenName(
|
FunctionDescriptor functionDescriptor = context.resolveCallWithGivenNameToDescriptor(
|
||||||
CallMaker.makeCallWithExpressions(callElement, receiver, null, operationSign, Collections.singletonList(left)),
|
CallMaker.makeCallWithExpressions(callElement, receiver, null, operationSign, Collections.singletonList(left)),
|
||||||
operationSign,
|
operationSign,
|
||||||
name, receiver);
|
name);
|
||||||
JetType containsType = functionDescriptor != null ? functionDescriptor.getReturnType() : null;
|
JetType containsType = functionDescriptor != null ? functionDescriptor.getReturnType() : null;
|
||||||
ensureBooleanResult(operationSign, name, containsType, context);
|
ensureBooleanResult(operationSign, name, containsType, context);
|
||||||
}
|
}
|
||||||
@@ -752,14 +752,14 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
|||||||
ExpressionReceiver receiver = getExpressionReceiver(facade, arrayExpression, context.replaceScope(context.scope));
|
ExpressionReceiver receiver = getExpressionReceiver(facade, arrayExpression, context.replaceScope(context.scope));
|
||||||
|
|
||||||
if (receiver != null) {
|
if (receiver != null) {
|
||||||
FunctionDescriptor functionDescriptor = context.resolveCallWithGivenName(
|
ResolvedCall<FunctionDescriptor> resolvedCall = context.resolveCallWithGivenName(
|
||||||
CallMaker.makeCallWithExpressions(expression, receiver, null, expression, expression.getIndexExpressions()),
|
CallMaker.makeCallWithExpressions(expression, receiver, null, expression, expression.getIndexExpressions()),
|
||||||
expression,
|
expression,
|
||||||
"get",
|
"get"
|
||||||
receiver);
|
);
|
||||||
if (functionDescriptor != null) {
|
if (resolvedCall != null) {
|
||||||
context.trace.record(INDEXED_LVALUE_GET, expression, functionDescriptor);
|
context.trace.record(INDEXED_LVALUE_GET, expression, resolvedCall);
|
||||||
return DataFlowUtils.checkType(functionDescriptor.getReturnType(), expression, contextWithExpectedType);
|
return DataFlowUtils.checkType(resolvedCall.getResultingDescriptor().getReturnType(), expression, contextWithExpectedType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@@ -768,11 +768,11 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
|||||||
@Nullable
|
@Nullable
|
||||||
protected JetType getTypeForBinaryCall(JetScope scope, String name, ExpressionTypingContext context, JetBinaryExpression binaryExpression) {
|
protected JetType getTypeForBinaryCall(JetScope scope, String name, ExpressionTypingContext context, JetBinaryExpression binaryExpression) {
|
||||||
ExpressionReceiver receiver = safeGetExpressionReceiver(facade, binaryExpression.getLeft(), context.replaceScope(scope));
|
ExpressionReceiver receiver = safeGetExpressionReceiver(facade, binaryExpression.getLeft(), context.replaceScope(scope));
|
||||||
FunctionDescriptor functionDescriptor = context.replaceScope(scope).resolveCallWithGivenName(
|
FunctionDescriptor functionDescriptor = context.replaceScope(scope).resolveCallWithGivenNameToDescriptor(
|
||||||
CallMaker.makeCall(receiver, binaryExpression),
|
CallMaker.makeCall(receiver, binaryExpression),
|
||||||
binaryExpression.getOperationReference(),
|
binaryExpression.getOperationReference(),
|
||||||
name,
|
name
|
||||||
receiver);
|
);
|
||||||
if (functionDescriptor != null) {
|
if (functionDescriptor != null) {
|
||||||
return functionDescriptor.getReturnType();
|
return functionDescriptor.getReturnType();
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-1
@@ -12,6 +12,7 @@ import org.jetbrains.jet.lang.resolve.ClassDescriptorResolver;
|
|||||||
import org.jetbrains.jet.lang.resolve.TypeResolver;
|
import org.jetbrains.jet.lang.resolve.TypeResolver;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.CallMaker;
|
import org.jetbrains.jet.lang.resolve.calls.CallMaker;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.CallResolver;
|
import org.jetbrains.jet.lang.resolve.calls.CallResolver;
|
||||||
|
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
|
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResults;
|
import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResults;
|
||||||
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstantResolver;
|
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstantResolver;
|
||||||
@@ -172,10 +173,16 @@ import java.util.Map;
|
|||||||
////////// Call resolution utilities
|
////////// Call resolution utilities
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public FunctionDescriptor resolveCallWithGivenName(@NotNull Call call, @NotNull JetReferenceExpression functionReference, @NotNull String name, @NotNull ReceiverDescriptor receiver) {
|
public ResolvedCall<FunctionDescriptor> resolveCallWithGivenName(@NotNull Call call, @NotNull JetReferenceExpression functionReference, @NotNull String name) {
|
||||||
return getCallResolver().resolveCallWithGivenName(trace, scope, call, functionReference, name, expectedType);
|
return getCallResolver().resolveCallWithGivenName(trace, scope, call, functionReference, name, expectedType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public FunctionDescriptor resolveCallWithGivenNameToDescriptor(@NotNull Call call, @NotNull JetReferenceExpression functionReference, @NotNull String name) {
|
||||||
|
ResolvedCall<FunctionDescriptor> resolvedCall = resolveCallWithGivenName(call, functionReference, name);
|
||||||
|
return resolvedCall == null ? null : resolvedCall.getResultingDescriptor();
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public JetType resolveCall(@NotNull ReceiverDescriptor receiver, @Nullable ASTNode callOperationNode, @NotNull JetCallExpression callExpression) {
|
public JetType resolveCall(@NotNull ReceiverDescriptor receiver, @Nullable ASTNode callOperationNode, @NotNull JetCallExpression callExpression) {
|
||||||
return getCallResolver().resolveCall(trace, scope, CallMaker.makeCall(receiver, callOperationNode, callExpression), expectedType);
|
return getCallResolver().resolveCall(trace, scope, CallMaker.makeCall(receiver, callOperationNode, callExpression), expectedType);
|
||||||
|
|||||||
+25
-22
@@ -9,15 +9,16 @@ import org.jetbrains.jet.lang.resolve.BindingContext;
|
|||||||
import org.jetbrains.jet.lang.resolve.TemporaryBindingTrace;
|
import org.jetbrains.jet.lang.resolve.TemporaryBindingTrace;
|
||||||
import org.jetbrains.jet.lang.resolve.TopDownAnalyzer;
|
import org.jetbrains.jet.lang.resolve.TopDownAnalyzer;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.CallMaker;
|
import org.jetbrains.jet.lang.resolve.calls.CallMaker;
|
||||||
|
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
|
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver;
|
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver;
|
||||||
|
import org.jetbrains.jet.lang.types.ErrorUtils;
|
||||||
import org.jetbrains.jet.lang.types.JetStandardClasses;
|
import org.jetbrains.jet.lang.types.JetStandardClasses;
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
import org.jetbrains.jet.lang.types.TypeUtils;
|
import org.jetbrains.jet.lang.types.TypeUtils;
|
||||||
import org.jetbrains.jet.lexer.JetTokens;
|
import org.jetbrains.jet.lexer.JetTokens;
|
||||||
|
|
||||||
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
|
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.INDEXED_LVALUE_SET;
|
import static org.jetbrains.jet.lang.resolve.BindingContext.INDEXED_LVALUE_SET;
|
||||||
import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET;
|
import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET;
|
||||||
import static org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils.getExpressionReceiver;
|
import static org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils.getExpressionReceiver;
|
||||||
@@ -123,7 +124,7 @@ public class ExpressionTypingVisitorForStatements extends BasicExpressionTypingV
|
|||||||
if (typeForBinaryCall != null) {
|
if (typeForBinaryCall != null) {
|
||||||
JetExpression left = JetPsiUtil.deparenthesize(expression.getLeft());
|
JetExpression left = JetPsiUtil.deparenthesize(expression.getLeft());
|
||||||
if (left instanceof JetArrayAccessExpression) {
|
if (left instanceof JetArrayAccessExpression) {
|
||||||
resolveArrayAccessToLValue((JetArrayAccessExpression) left, expression.getRight(), expression.getOperationReference(), context, true);
|
resolveArrayAccessToLValue((JetArrayAccessExpression) left, expression.getRight(), expression.getOperationReference(), context);
|
||||||
}
|
}
|
||||||
|
|
||||||
context.trace.record(BindingContext.VARIABLE_REASSIGNMENT, expression);
|
context.trace.record(BindingContext.VARIABLE_REASSIGNMENT, expression);
|
||||||
@@ -138,14 +139,14 @@ public class ExpressionTypingVisitorForStatements extends BasicExpressionTypingV
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected JetType visitAssignment(JetBinaryExpression expression, ExpressionTypingContext context) {
|
protected JetType visitAssignment(JetBinaryExpression expression, ExpressionTypingContext context) {
|
||||||
boolean getterNeeded = false;
|
|
||||||
JetExpression left = JetPsiUtil.deparenthesize(expression.getLeft());
|
JetExpression left = JetPsiUtil.deparenthesize(expression.getLeft());
|
||||||
JetExpression right = expression.getRight();
|
JetExpression right = expression.getRight();
|
||||||
if (left instanceof JetArrayAccessExpression) {
|
if (left instanceof JetArrayAccessExpression) {
|
||||||
JetArrayAccessExpression arrayAccessExpression = (JetArrayAccessExpression) left;
|
JetArrayAccessExpression arrayAccessExpression = (JetArrayAccessExpression) left;
|
||||||
return resolveArrayAccessToLValue(arrayAccessExpression, right, expression.getOperationReference(), context, getterNeeded);
|
return resolveArrayAccessToLValue(arrayAccessExpression, right, expression.getOperationReference(), context);
|
||||||
}
|
}
|
||||||
JetType leftType = facade.getType(left, context.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE).replaceScope(scope));
|
JetType leftType = left == null ? ErrorUtils.createErrorType("No expression")
|
||||||
|
: facade.getType(left, context.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE).replaceScope(scope));
|
||||||
if (right != null) {
|
if (right != null) {
|
||||||
JetType rightType = facade.getType(right, context.replaceExpectedType(leftType).replaceScope(scope));
|
JetType rightType = facade.getType(right, context.replaceExpectedType(leftType).replaceScope(scope));
|
||||||
}
|
}
|
||||||
@@ -164,30 +165,32 @@ public class ExpressionTypingVisitorForStatements extends BasicExpressionTypingV
|
|||||||
return checkExpectedType(expression, context);
|
return checkExpectedType(expression, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
private JetType resolveArrayAccessToLValue(JetArrayAccessExpression arrayAccessExpression, JetExpression rightHandSide, JetSimpleNameExpression operationSign, ExpressionTypingContext context, boolean getterNeeded) {
|
private JetType resolveArrayAccessToLValue(JetArrayAccessExpression arrayAccessExpression, JetExpression rightHandSide, JetSimpleNameExpression operationSign, ExpressionTypingContext context) {
|
||||||
ExpressionReceiver receiver = getExpressionReceiver(facade, arrayAccessExpression.getArrayExpression(), context.replaceScope(scope));
|
ExpressionReceiver receiver = getExpressionReceiver(facade, arrayAccessExpression.getArrayExpression(), context.replaceScope(scope));
|
||||||
if (receiver == null) return null;
|
if (receiver == null) return null;
|
||||||
|
|
||||||
Call call = CallMaker.makeArraySetCall(receiver, arrayAccessExpression, rightHandSide);
|
Call call = CallMaker.makeArraySetCall(receiver, arrayAccessExpression, rightHandSide);
|
||||||
FunctionDescriptor setFunction = context.replaceScope(scope).replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE).resolveCallWithGivenName(
|
ResolvedCall<FunctionDescriptor> setFunctionCall = context.replaceScope(scope).replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE).resolveCallWithGivenName(
|
||||||
call,
|
call,
|
||||||
arrayAccessExpression,
|
arrayAccessExpression,
|
||||||
"set", receiver);
|
"set");
|
||||||
if (setFunction == null) return null;
|
if (setFunctionCall == null) return null;
|
||||||
context.trace.record(INDEXED_LVALUE_SET, arrayAccessExpression, setFunction);
|
FunctionDescriptor setFunctionDescriptor = setFunctionCall.getResultingDescriptor();
|
||||||
|
|
||||||
if (getterNeeded) {
|
context.trace.record(INDEXED_LVALUE_SET, arrayAccessExpression, setFunctionCall);
|
||||||
FunctionDescriptor getFunction = context.replaceScope(scope).replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE).resolveCallWithGivenName(
|
|
||||||
CallMaker.makeArrayGetCall(receiver, arrayAccessExpression),
|
// if (getterNeeded) {
|
||||||
arrayAccessExpression,
|
// ResolvedCall<FunctionDescriptor> getFunctionCall = context.replaceScope(scope).replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE).resolveCallWithGivenName(
|
||||||
"get", receiver);
|
// CallMaker.makeArrayGetCall(receiver, arrayAccessExpression),
|
||||||
if (getFunction == null) return null;
|
// arrayAccessExpression,
|
||||||
context.trace.record(INDEXED_LVALUE_GET, arrayAccessExpression, getFunction);
|
// "get");
|
||||||
}
|
// if (getFunctionCall == null) return null;
|
||||||
else {
|
// context.trace.record(INDEXED_LVALUE_GET, arrayAccessExpression, getFunctionCall);
|
||||||
context.trace.record(REFERENCE_TARGET, operationSign, setFunction);
|
// }
|
||||||
}
|
// else {
|
||||||
return DataFlowUtils.checkType(setFunction.getReturnType(), arrayAccessExpression, context);
|
context.trace.record(REFERENCE_TARGET, operationSign, setFunctionDescriptor);
|
||||||
|
// }
|
||||||
|
return DataFlowUtils.checkType(setFunctionDescriptor.getReturnType(), arrayAccessExpression, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import org.jetbrains.jet.lang.psi.JetArrayAccessExpression;
|
|||||||
import org.jetbrains.jet.lang.psi.JetContainerNode;
|
import org.jetbrains.jet.lang.psi.JetContainerNode;
|
||||||
import org.jetbrains.jet.lang.psi.JetFile;
|
import org.jetbrains.jet.lang.psi.JetFile;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
|
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
|
||||||
import org.jetbrains.jet.lexer.JetTokens;
|
import org.jetbrains.jet.lexer.JetTokens;
|
||||||
import org.jetbrains.jet.plugin.compiler.WholeProjectAnalyzerFacade;
|
import org.jetbrains.jet.plugin.compiler.WholeProjectAnalyzerFacade;
|
||||||
|
|
||||||
@@ -40,8 +41,8 @@ class JetArrayAccessReference extends JetPsiReference implements MultiRangeRefer
|
|||||||
@Override
|
@Override
|
||||||
protected PsiElement doResolve() {
|
protected PsiElement doResolve() {
|
||||||
BindingContext bindingContext = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile((JetFile) getElement().getContainingFile());
|
BindingContext bindingContext = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile((JetFile) getElement().getContainingFile());
|
||||||
FunctionDescriptor getFunction = bindingContext.get(INDEXED_LVALUE_GET, expression);
|
ResolvedCall<FunctionDescriptor> getFunction = bindingContext.get(INDEXED_LVALUE_GET, expression);
|
||||||
FunctionDescriptor setFunction = bindingContext.get(INDEXED_LVALUE_SET, expression);
|
ResolvedCall<FunctionDescriptor> setFunction = bindingContext.get(INDEXED_LVALUE_SET, expression);
|
||||||
if (getFunction != null && setFunction != null) {
|
if (getFunction != null && setFunction != null) {
|
||||||
return null; // Call doMultiResolve
|
return null; // Call doMultiResolve
|
||||||
}
|
}
|
||||||
@@ -51,10 +52,10 @@ class JetArrayAccessReference extends JetPsiReference implements MultiRangeRefer
|
|||||||
@Override
|
@Override
|
||||||
protected ResolveResult[] doMultiResolve() {
|
protected ResolveResult[] doMultiResolve() {
|
||||||
BindingContext bindingContext = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile((JetFile) getElement().getContainingFile());
|
BindingContext bindingContext = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile((JetFile) getElement().getContainingFile());
|
||||||
FunctionDescriptor getFunction = bindingContext.get(INDEXED_LVALUE_GET, expression);
|
ResolvedCall<FunctionDescriptor> getFunction = bindingContext.get(INDEXED_LVALUE_GET, expression);
|
||||||
PsiElement getFunctionElement = bindingContext.get(DESCRIPTOR_TO_DECLARATION, getFunction);
|
PsiElement getFunctionElement = bindingContext.get(DESCRIPTOR_TO_DECLARATION, getFunction.getResultingDescriptor());
|
||||||
FunctionDescriptor setFunction = bindingContext.get(INDEXED_LVALUE_SET, expression);
|
ResolvedCall<FunctionDescriptor> setFunction = bindingContext.get(INDEXED_LVALUE_SET, expression);
|
||||||
PsiElement setFunctionElement = bindingContext.get(DESCRIPTOR_TO_DECLARATION, setFunction);
|
PsiElement setFunctionElement = bindingContext.get(DESCRIPTOR_TO_DECLARATION, setFunction.getResultingDescriptor());
|
||||||
return new ResolveResult[] {new PsiElementResolveResult(getFunctionElement, true), new PsiElementResolveResult(setFunctionElement, true)};
|
return new ResolveResult[] {new PsiElementResolveResult(getFunctionElement, true), new PsiElementResolveResult(setFunctionElement, true)};
|
||||||
// return super.doMultiResolve();
|
// return super.doMultiResolve();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user