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);
}
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);
}
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);
}
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())));
}
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());
}
}
}
}
Aggregations