Search in sources :

Example 1 with ResolvedValueArgument

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

the class InlineChecker method check.

@Override
public void check(@NotNull ResolvedCall<?> resolvedCall, @NotNull PsiElement reportOn, @NotNull CallCheckerContext context) {
    KtExpression expression = resolvedCall.getCall().getCalleeExpression();
    if (expression == null) {
        return;
    }
    //checking that only invoke or inlinable extension called on function parameter
    CallableDescriptor targetDescriptor = resolvedCall.getResultingDescriptor();
    checkCallWithReceiver(context, targetDescriptor, resolvedCall.getDispatchReceiver(), expression);
    checkCallWithReceiver(context, targetDescriptor, resolvedCall.getExtensionReceiver(), expression);
    if (inlinableParameters.contains(targetDescriptor)) {
        if (!isInsideCall(expression)) {
            context.getTrace().report(USAGE_IS_NOT_INLINABLE.on(expression, expression, descriptor));
        }
    }
    for (Map.Entry<ValueParameterDescriptor, ResolvedValueArgument> entry : resolvedCall.getValueArguments().entrySet()) {
        ResolvedValueArgument value = entry.getValue();
        ValueParameterDescriptor valueDescriptor = entry.getKey();
        if (!(value instanceof DefaultValueArgument)) {
            for (ValueArgument argument : value.getArguments()) {
                checkValueParameter(context, targetDescriptor, argument, valueDescriptor);
            }
        }
    }
    checkVisibilityAndAccess(targetDescriptor, expression, context);
    checkRecursion(context, targetDescriptor, expression);
}
Also used : ResolvedValueArgument(org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument) ResolvedValueArgument(org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument) DefaultValueArgument(org.jetbrains.kotlin.resolve.calls.model.DefaultValueArgument) DefaultValueArgument(org.jetbrains.kotlin.resolve.calls.model.DefaultValueArgument) Map(java.util.Map)

Example 2 with ResolvedValueArgument

use of org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument 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 3 with ResolvedValueArgument

use of org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument 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 4 with ResolvedValueArgument

use of org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument 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 5 with ResolvedValueArgument

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

the class KotlinTypeMapper method writeSuperConstructorCallParameters.

private void writeSuperConstructorCallParameters(@NotNull JvmSignatureWriter sw, @NotNull ClassConstructorDescriptor descriptor, @NotNull ResolvedCall<ConstructorDescriptor> superCall, boolean hasOuter) {
    ConstructorDescriptor superDescriptor = SamCodegenUtil.resolveSamAdapter(superCall.getResultingDescriptor());
    List<ResolvedValueArgument> valueArguments = superCall.getValueArgumentsByIndex();
    assert valueArguments != null : "Failed to arrange value arguments by index: " + superDescriptor;
    List<JvmMethodParameterSignature> parameters = mapSignatureSkipGeneric(superDescriptor.getOriginal()).getValueParameters();
    int params = parameters.size();
    int args = valueArguments.size();
    // Mapped parameters should consist of captured values plus all of valueArguments
    assert params >= args : String.format("Incorrect number of mapped parameters vs arguments: %d < %d for %s", params, args, descriptor);
    // Include all captured values, i.e. those parameters for which there are no resolved value arguments
    for (int i = 0; i < params - args; i++) {
        JvmMethodParameterSignature parameter = parameters.get(i);
        JvmMethodParameterKind kind = parameter.getKind();
        if (kind == JvmMethodParameterKind.ENUM_NAME_OR_ORDINAL)
            continue;
        if (hasOuter && kind == JvmMethodParameterKind.OUTER)
            continue;
        writeParameter(sw, JvmMethodParameterKind.SUPER_CALL_PARAM, parameter.getAsmType());
    }
    if (isAnonymousObject(descriptor.getContainingDeclaration())) {
        // For anonymous objects, also add all real non-default value arguments passed to the super constructor
        for (int i = 0; i < args; i++) {
            ResolvedValueArgument valueArgument = valueArguments.get(i);
            JvmMethodParameterSignature parameter = parameters.get(params - args + i);
            if (!(valueArgument instanceof DefaultValueArgument)) {
                writeParameter(sw, JvmMethodParameterKind.SUPER_CALL_PARAM, parameter.getAsmType());
            }
        }
    }
}
Also used : ResolvedValueArgument(org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument) JvmMethodParameterSignature(org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature) JvmMethodParameterKind(org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind) TypeAliasConstructorDescriptor(org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor) DefaultValueArgument(org.jetbrains.kotlin.resolve.calls.model.DefaultValueArgument)

Aggregations

ResolvedValueArgument (org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument)7 ExpressionValueArgument (org.jetbrains.kotlin.resolve.calls.model.ExpressionValueArgument)5 KtExpression (org.jetbrains.kotlin.psi.KtExpression)2 DefaultValueArgument (org.jetbrains.kotlin.resolve.calls.model.DefaultValueArgument)2 Map (java.util.Map)1 NotNull (org.jetbrains.annotations.NotNull)1 FunctionDescriptor (org.jetbrains.kotlin.descriptors.FunctionDescriptor)1 TypeAliasConstructorDescriptor (org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor)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 JvmMethodParameterKind (org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind)1 JvmMethodParameterSignature (org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature)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