@NotNull private JsExpression translateAsMethodCall( @NotNull JsExpression arrayExpression, @Nullable JsExpression toSetTo) { boolean isGetter = toSetTo == null; TranslationContext context = context(); ResolvedCall<FunctionDescriptor> resolvedCall = BindingUtils.getResolvedCallForArrayAccess(bindingContext(), expression, isGetter); if (!isGetter) { context = contextWithValueParameterAliasInArrayGetAccess(toSetTo); } return CallTranslator.translate(context, resolvedCall, arrayExpression); }
// this is hack for a[b]++ -> a.set(b, a.get(b) + 1). Frontend generate fake expression for // a.get(b) + 1. @NotNull private TranslationContext contextWithValueParameterAliasInArrayGetAccess( @NotNull JsExpression toSetTo) { ResolvedCall<FunctionDescriptor> resolvedCall = BindingUtils.getResolvedCallForArrayAccess( bindingContext(), expression, /*isGetter = */ false); List<ResolvedValueArgument> arguments = resolvedCall.getValueArgumentsByIndex(); if (arguments == null) { throw new IllegalStateException( "Failed to arrange value arguments by index: " + resolvedCall.getResultingDescriptor()); } ResolvedValueArgument lastArgument = arguments.get(arguments.size() - 1); assert lastArgument instanceof ExpressionValueArgument : "Last argument of array-like setter must be ExpressionValueArgument: " + lastArgument; ValueArgument valueArgument = ((ExpressionValueArgument) lastArgument).getValueArgument(); assert valueArgument != null; JetExpression element = valueArgument.getArgumentExpression(); return context() .innerContextWithAliasesForExpressions(Collections.singletonMap(element, toSetTo)); }