Search in sources :

Example 1 with ExpressionValueArgument

use of org.jetbrains.kotlin.resolve.calls.model.ExpressionValueArgument in project kotlin by JetBrains.

the class FunctionReferenceGenerationStrategy method doGenerateBody.

@Override
public void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature) {
    /*
         Here we need to put the arguments from our locals to the stack and invoke the referenced method. Since invocation
         of methods is highly dependent on expressions, we create a fake call expression. Then we create a new instance of
         ExpressionCodegen and, in order for it to generate code correctly, we save to its 'tempVariables' field every
         argument of our fake expression, pointing it to the corresponding index in our locals. This way generation of
         every argument boils down to calling LOAD with the corresponding index
         */
    KtCallExpression fakeExpression = CodegenUtil.constructFakeFunctionCall(state.getProject(), referencedFunction);
    final List<? extends ValueArgument> fakeArguments = fakeExpression.getValueArguments();
    final ReceiverValue dispatchReceiver = computeAndSaveReceiver(signature, codegen, referencedFunction.getDispatchReceiverParameter());
    final ReceiverValue extensionReceiver = computeAndSaveReceiver(signature, codegen, referencedFunction.getExtensionReceiverParameter());
    computeAndSaveArguments(fakeArguments, codegen);
    ResolvedCall<CallableDescriptor> fakeResolvedCall = new DelegatingResolvedCall<CallableDescriptor>(resolvedCall) {

        private final Map<ValueParameterDescriptor, ResolvedValueArgument> argumentMap;

        {
            argumentMap = new LinkedHashMap<ValueParameterDescriptor, ResolvedValueArgument>(fakeArguments.size());
            int index = 0;
            List<ValueParameterDescriptor> parameters = functionDescriptor.getValueParameters();
            for (ValueArgument argument : fakeArguments) {
                argumentMap.put(parameters.get(index), new ExpressionValueArgument(argument));
                index++;
            }
        }

        @Nullable
        @Override
        public ReceiverValue getExtensionReceiver() {
            return extensionReceiver;
        }

        @Nullable
        @Override
        public ReceiverValue getDispatchReceiver() {
            return dispatchReceiver;
        }

        @NotNull
        @Override
        public List<ResolvedValueArgument> getValueArgumentsByIndex() {
            return new ArrayList<ResolvedValueArgument>(argumentMap.values());
        }

        @NotNull
        @Override
        public Map<ValueParameterDescriptor, ResolvedValueArgument> getValueArguments() {
            return argumentMap;
        }
    };
    StackValue result;
    Type returnType = codegen.getReturnType();
    if (referencedFunction instanceof ConstructorDescriptor) {
        if (returnType.getSort() == Type.ARRAY) {
            //noinspection ConstantConditions
            result = codegen.generateNewArray(fakeExpression, referencedFunction.getReturnType(), fakeResolvedCall);
        } else {
            result = codegen.generateConstructorCall(fakeResolvedCall, returnType);
        }
    } else {
        Call call = CallMaker.makeCall(fakeExpression, null, null, fakeExpression, fakeArguments);
        result = codegen.invokeFunction(call, fakeResolvedCall, StackValue.none());
    }
    InstructionAdapter v = codegen.v;
    result.put(returnType, v);
    v.areturn(returnType);
}
Also used : ResolvedValueArgument(org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument) ExpressionValueArgument(org.jetbrains.kotlin.resolve.calls.model.ExpressionValueArgument) ResolvedCall(org.jetbrains.kotlin.resolve.calls.model.ResolvedCall) DelegatingResolvedCall(org.jetbrains.kotlin.resolve.calls.model.DelegatingResolvedCall) Type(org.jetbrains.org.objectweb.asm.Type) DelegatingResolvedCall(org.jetbrains.kotlin.resolve.calls.model.DelegatingResolvedCall) InstructionAdapter(org.jetbrains.org.objectweb.asm.commons.InstructionAdapter) ExpressionValueArgument(org.jetbrains.kotlin.resolve.calls.model.ExpressionValueArgument) ResolvedValueArgument(org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument) ReceiverValue(org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue)

Example 2 with ExpressionValueArgument

use of org.jetbrains.kotlin.resolve.calls.model.ExpressionValueArgument in project kotlin by JetBrains.

the class CodegenAnnotatingVisitor method recordSamConstructorIfNeeded.

private void recordSamConstructorIfNeeded(@NotNull KtCallElement expression, @NotNull ResolvedCall<?> call) {
    CallableDescriptor callableDescriptor = call.getResultingDescriptor();
    if (!(callableDescriptor.getOriginal() instanceof SamConstructorDescriptor))
        return;
    List<ResolvedValueArgument> valueArguments = call.getValueArgumentsByIndex();
    if (valueArguments == null || valueArguments.size() != 1)
        return;
    ResolvedValueArgument valueArgument = valueArguments.get(0);
    if (!(valueArgument instanceof ExpressionValueArgument))
        return;
    ValueArgument argument = ((ExpressionValueArgument) valueArgument).getValueArgument();
    if (argument == null)
        return;
    KtExpression argumentExpression = argument.getArgumentExpression();
    bindingTrace.record(SAM_CONSTRUCTOR_TO_ARGUMENT, expression, argumentExpression);
    //noinspection ConstantConditions
    SamType samType = SamType.create(callableDescriptor.getReturnType());
    bindingTrace.record(SAM_VALUE, argumentExpression, samType);
}
Also used : ResolvedValueArgument(org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument) ExpressionValueArgument(org.jetbrains.kotlin.resolve.calls.model.ExpressionValueArgument) SamConstructorDescriptor(org.jetbrains.kotlin.load.java.descriptors.SamConstructorDescriptor) ExpressionValueArgument(org.jetbrains.kotlin.resolve.calls.model.ExpressionValueArgument) ResolvedValueArgument(org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument)

Example 3 with ExpressionValueArgument

use of org.jetbrains.kotlin.resolve.calls.model.ExpressionValueArgument in project kotlin by JetBrains.

the class ClassInitializerTranslator method emulateSuperCallToNativeError.

public static void emulateSuperCallToNativeError(@NotNull TranslationContext context, @NotNull ClassDescriptor classDescriptor, @NotNull ResolvedCall<? extends FunctionDescriptor> superCall, @NotNull JsExpression receiver) {
    ClassDescriptor superClass = DescriptorUtilsKt.getSuperClassOrAny(classDescriptor);
    JsExpression superClassRef = ReferenceTranslator.translateAsTypeReference(superClass, context);
    JsExpression superInvocation = new JsInvocation(Namer.getFunctionCallRef(superClassRef), receiver.deepCopy());
    List<JsStatement> statements = context.getCurrentBlock().getStatements();
    statements.add(JsAstUtils.asSyntheticStatement(superInvocation));
    JsExpression messageArgument = Namer.getUndefinedExpression();
    JsExpression causeArgument = JsLiteral.NULL;
    for (ValueParameterDescriptor param : superCall.getResultingDescriptor().getValueParameters()) {
        ResolvedValueArgument argument = superCall.getValueArguments().get(param);
        if (!(argument instanceof ExpressionValueArgument))
            continue;
        ExpressionValueArgument exprArgument = (ExpressionValueArgument) argument;
        assert exprArgument.getValueArgument() != null;
        KtExpression value = exprArgument.getValueArgument().getArgumentExpression();
        assert value != null;
        JsExpression jsValue = Translation.translateAsExpression(value, context);
        if (KotlinBuiltIns.isStringOrNullableString(param.getType())) {
            messageArgument = context.cacheExpressionIfNeeded(jsValue);
        } else if (TypeUtilsKt.isConstructedFromClassWithGivenFqName(param.getType(), KotlinBuiltIns.FQ_NAMES.throwable)) {
            causeArgument = context.cacheExpressionIfNeeded(jsValue);
        } else {
            statements.add(JsAstUtils.asSyntheticStatement(jsValue));
        }
    }
    PropertyDescriptor messageProperty = DescriptorUtils.getPropertyByName(classDescriptor.getUnsubstitutedMemberScope(), Name.identifier("message"));
    JsExpression messageRef = pureFqn(context.getNameForBackingField(messageProperty), receiver.deepCopy());
    JsExpression messageIsUndefined = JsAstUtils.typeOfIs(messageArgument, context.program().getStringLiteral("undefined"));
    JsExpression causeIsNull = new JsBinaryOperation(JsBinaryOperator.NEQ, causeArgument, JsLiteral.NULL);
    JsExpression causeToStringCond = JsAstUtils.and(messageIsUndefined, causeIsNull);
    JsExpression causeToString = new JsInvocation(pureFqn("toString", Namer.kotlinObject()), causeArgument.deepCopy());
    JsExpression correctedMessage;
    if (causeArgument == JsLiteral.NULL) {
        correctedMessage = messageArgument.deepCopy();
    } else {
        if (JsAstUtils.isUndefinedExpression(messageArgument)) {
            causeToStringCond = causeIsNull;
        }
        correctedMessage = new JsConditional(causeToStringCond, causeToString, messageArgument);
    }
    statements.add(JsAstUtils.asSyntheticStatement(JsAstUtils.assignment(messageRef, correctedMessage)));
    PropertyDescriptor causeProperty = DescriptorUtils.getPropertyByName(classDescriptor.getUnsubstitutedMemberScope(), Name.identifier("cause"));
    JsExpression causeRef = pureFqn(context.getNameForBackingField(causeProperty), receiver.deepCopy());
    statements.add(JsAstUtils.asSyntheticStatement(JsAstUtils.assignment(causeRef, causeArgument.deepCopy())));
}
Also used : ResolvedValueArgument(org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument) ExpressionValueArgument(org.jetbrains.kotlin.resolve.calls.model.ExpressionValueArgument) KtExpression(org.jetbrains.kotlin.psi.KtExpression)

Example 4 with ExpressionValueArgument

use of org.jetbrains.kotlin.resolve.calls.model.ExpressionValueArgument in project kotlin by JetBrains.

the class CodegenAnnotatingVisitor method checkSamCall.

private void checkSamCall(@NotNull KtCallElement expression) {
    ResolvedCall<?> call = CallUtilKt.getResolvedCall(expression, bindingContext);
    if (call == null)
        return;
    CallableDescriptor descriptor = call.getResultingDescriptor();
    if (!(descriptor instanceof FunctionDescriptor))
        return;
    recordSamConstructorIfNeeded(expression, call);
    FunctionDescriptor original = SamCodegenUtil.getOriginalIfSamAdapter((FunctionDescriptor) descriptor);
    if (original == null)
        return;
    List<ResolvedValueArgument> valueArguments = call.getValueArgumentsByIndex();
    if (valueArguments == null)
        return;
    for (ValueParameterDescriptor valueParameter : original.getValueParameters()) {
        SamType samType = SamType.create(TypeMapperUtilsKt.removeExternalProjections(valueParameter.getType()));
        if (samType == null)
            continue;
        ResolvedValueArgument resolvedValueArgument = valueArguments.get(valueParameter.getIndex());
        assert resolvedValueArgument instanceof ExpressionValueArgument : resolvedValueArgument;
        ValueArgument valueArgument = ((ExpressionValueArgument) resolvedValueArgument).getValueArgument();
        assert valueArgument != null;
        KtExpression argumentExpression = valueArgument.getArgumentExpression();
        assert argumentExpression != null : valueArgument.asElement().getText();
        bindingTrace.record(CodegenBinding.SAM_VALUE, argumentExpression, samType);
    }
}
Also used : ResolvedValueArgument(org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument) ExpressionValueArgument(org.jetbrains.kotlin.resolve.calls.model.ExpressionValueArgument) ExpressionValueArgument(org.jetbrains.kotlin.resolve.calls.model.ExpressionValueArgument) ResolvedValueArgument(org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument)

Example 5 with ExpressionValueArgument

use of org.jetbrains.kotlin.resolve.calls.model.ExpressionValueArgument in project kotlin by JetBrains.

the class ArrayAccessTranslator method contextWithValueParameterAliasInArrayGetAccess.

// 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;
    KtExpression element = valueArgument.getArgumentExpression();
    return context().innerContextWithAliasesForExpressions(Collections.singletonMap(element, toSetTo));
}
Also used : ResolvedValueArgument(org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument) ExpressionValueArgument(org.jetbrains.kotlin.resolve.calls.model.ExpressionValueArgument) ValueArgument(org.jetbrains.kotlin.psi.ValueArgument) ExpressionValueArgument(org.jetbrains.kotlin.resolve.calls.model.ExpressionValueArgument) ResolvedValueArgument(org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument) KtExpression(org.jetbrains.kotlin.psi.KtExpression) FunctionDescriptor(org.jetbrains.kotlin.descriptors.FunctionDescriptor) NotNull(org.jetbrains.annotations.NotNull)

Aggregations

ExpressionValueArgument (org.jetbrains.kotlin.resolve.calls.model.ExpressionValueArgument)5 ResolvedValueArgument (org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument)5 KtExpression (org.jetbrains.kotlin.psi.KtExpression)2 NotNull (org.jetbrains.annotations.NotNull)1 FunctionDescriptor (org.jetbrains.kotlin.descriptors.FunctionDescriptor)1 SamConstructorDescriptor (org.jetbrains.kotlin.load.java.descriptors.SamConstructorDescriptor)1 ValueArgument (org.jetbrains.kotlin.psi.ValueArgument)1 DelegatingResolvedCall (org.jetbrains.kotlin.resolve.calls.model.DelegatingResolvedCall)1 ResolvedCall (org.jetbrains.kotlin.resolve.calls.model.ResolvedCall)1 ReceiverValue (org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue)1 Type (org.jetbrains.org.objectweb.asm.Type)1 InstructionAdapter (org.jetbrains.org.objectweb.asm.commons.InstructionAdapter)1