@NotNull public JetTypeInfo getSimpleNameExpressionTypeInfo( @NotNull JetSimpleNameExpression nameExpression, @NotNull ReceiverValue receiver, @Nullable ASTNode callOperationNode, @NotNull ResolutionContext context) { boolean[] result = new boolean[1]; TemporaryBindingTrace traceForVariable = TemporaryBindingTrace.create(context.trace, "trace to resolve as variable", nameExpression); JetType type = getVariableType( nameExpression, receiver, callOperationNode, context.replaceBindingTrace(traceForVariable), result); if (result[0]) { traceForVariable.commit(); if (type instanceof NamespaceType && context.expressionPosition == ExpressionPosition.FREE) { type = null; } return JetTypeInfo.create(type, context.dataFlowInfo); } Call call = CallMaker.makeCall( nameExpression, receiver, callOperationNode, nameExpression, Collections.<ValueArgument>emptyList()); TemporaryBindingTrace traceForFunction = TemporaryBindingTrace.create(context.trace, "trace to resolve as function", nameExpression); ResolvedCall<FunctionDescriptor> resolvedCall = getResolvedCallForFunction( call, nameExpression, receiver, context, ResolveMode.TOP_LEVEL_CALL, ResolutionResultsCache.create(), result); if (result[0]) { FunctionDescriptor functionDescriptor = resolvedCall != null ? resolvedCall.getResultingDescriptor() : null; traceForFunction.commit(); boolean hasValueParameters = functionDescriptor == null || functionDescriptor.getValueParameters().size() > 0; context.trace.report( FUNCTION_CALL_EXPECTED.on(nameExpression, nameExpression, hasValueParameters)); type = functionDescriptor != null ? functionDescriptor.getReturnType() : null; return JetTypeInfo.create(type, context.dataFlowInfo); } traceForVariable.commit(); return JetTypeInfo.create(null, context.dataFlowInfo); }
@NotNull @Override public String render( @NotNull Collection<? extends ResolvedCall<? extends CallableDescriptor>> argument) { StringBuilder stringBuilder = new StringBuilder("\n"); for (ResolvedCall<? extends CallableDescriptor> call : argument) { stringBuilder .append(DescriptorRenderer.TEXT.render(call.getResultingDescriptor())) .append("\n"); } return stringBuilder.toString(); }
@Override public void visitReferenceExpression(@NotNull JetReferenceExpression expression) { super.visitReferenceExpression(expression); ResolvedCall resolvedCall = CallUtilPackage.getResolvedCall(expression, bindingContext); if (resolvedCall != null && resolvedCall instanceof VariableAsFunctionResolvedCall) { // Deprecated for invoke() JetCallExpression parent = PsiTreeUtil.getParentOfType(expression, JetCallExpression.class); if (parent != null) { reportAnnotationIfNeeded(parent, resolvedCall.getResultingDescriptor(), true); } } if (expression.getNode().getElementType() == JetNodeTypes.OPERATION_REFERENCE) { // Deprecated for operations (mark as warning) checkDeprecatedForOperations(expression); } else { checkDeprecatedForReferenceExpression(expression); } }
public static void genNotNullAssertionForMethod( @NotNull InstructionAdapter v, @NotNull GenerationState state, @NotNull ResolvedCall resolvedCall) { CallableDescriptor descriptor = resolvedCall.getResultingDescriptor(); if (descriptor instanceof ConstructorDescriptor) return; genNotNullAssertion(v, state, descriptor, "checkReturnedValueIsNotNull"); }
private CallParametersResolver( @Nullable JsExpression qualifier, @Nullable JsExpression callee, @NotNull CallableDescriptor descriptor, @NotNull ResolvedCall<? extends CallableDescriptor> call, @NotNull TranslationContext context) { this.qualifier = qualifier; this.callee = callee; this.descriptor = descriptor; this.context = context; this.resolvedCall = call; this.isExtensionCall = resolvedCall.getReceiverArgument().exists(); }
@NotNull private CallTranslator finish() { if (resolvedCall == null) { assert descriptor != null; resolvedCall = ResolvedCallImpl.create( ResolutionCandidate.create( descriptor, DescriptorUtils.safeGetValue(descriptor.getExpectedThisObject()), DescriptorUtils.safeGetValue(descriptor.getReceiverParameter()), ExplicitReceiverKind.THIS_OBJECT, false), TemporaryBindingTrace.create( new BindingTraceContext(), "trace to resolve call (in js)")); } if (descriptor == null) { descriptor = resolvedCall.getCandidateDescriptor().getOriginal(); } assert resolvedCall != null; return new CallTranslator(receiver, callee, args, resolvedCall, descriptor, callType, context); }
@NotNull public TypeInfoForCall getCallExpressionTypeInfoForCallWithoutFinalTypeCheck( @NotNull JetCallExpression callExpression, @NotNull ReceiverValue receiver, @Nullable ASTNode callOperationNode, @NotNull ResolutionContext context, @NotNull ResolveMode resolveMode) { boolean[] result = new boolean[1]; Call call = CallMaker.makeCall(receiver, callOperationNode, callExpression); TemporaryBindingTrace traceForFunction = TemporaryBindingTrace.create( context.trace, "trace to resolve as function call", callExpression); ResolvedCall<FunctionDescriptor> resolvedCall = getResolvedCallForFunction( call, callExpression, receiver, context.replaceBindingTrace(traceForFunction), resolveMode, result); if (result[0]) { FunctionDescriptor functionDescriptor = resolvedCall != null ? resolvedCall.getResultingDescriptor() : null; traceForFunction.commit(); if (callExpression.getValueArgumentList() == null && callExpression.getFunctionLiteralArguments().isEmpty()) { // there are only type arguments boolean hasValueParameters = functionDescriptor == null || functionDescriptor.getValueParameters().size() > 0; context.trace.report( FUNCTION_CALL_EXPECTED.on(callExpression, callExpression, hasValueParameters)); } if (functionDescriptor == null) { return TypeInfoForCall.create(null, context.dataFlowInfo); } JetType type = functionDescriptor.getReturnType(); return TypeInfoForCall.create( type, resolvedCall.getDataFlowInfo(), resolvedCall, call, context, resolveMode); } JetExpression calleeExpression = callExpression.getCalleeExpression(); if (calleeExpression instanceof JetSimpleNameExpression && callExpression.getTypeArgumentList() == null) { TemporaryBindingTrace traceForVariable = TemporaryBindingTrace.create( context.trace, "trace to resolve as variable with 'invoke' call", callExpression); JetType type = getVariableType( (JetSimpleNameExpression) calleeExpression, receiver, callOperationNode, context.replaceBindingTrace(traceForVariable), result); if (result[0]) { traceForVariable.commit(); context.trace.report( FUNCTION_EXPECTED.on( (JetReferenceExpression) calleeExpression, calleeExpression, type != null ? type : ErrorUtils.createErrorType(""))); return TypeInfoForCall.create(null, context.dataFlowInfo); } } traceForFunction.commit(); return TypeInfoForCall.create(null, context.dataFlowInfo); }
@NotNull protected JetTypeInfo visitAssignmentOperation( JetBinaryExpression expression, ExpressionTypingContext contextWithExpectedType) { // There is a temporary binding trace for an opportunity to resolve set method for array if // needed (the initial trace should be used there) TemporaryBindingTrace temporaryBindingTrace = TemporaryBindingTrace.create( contextWithExpectedType.trace, "trace to resolve array set method for binary expression", expression); ExpressionTypingContext context = contextWithExpectedType .replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE) .replaceBindingTrace(temporaryBindingTrace); JetSimpleNameExpression operationSign = expression.getOperationReference(); IElementType operationType = operationSign.getReferencedNameElementType(); JetTypeInfo leftInfo = facade.getTypeInfo(expression.getLeft(), context); JetType leftType = leftInfo.getType(); DataFlowInfo dataFlowInfo = leftInfo.getDataFlowInfo(); JetExpression right = expression.getRight(); JetExpression left = JetPsiUtil.deparenthesizeWithNoTypeResolution(expression.getLeft()); if (right == null || left == null) { temporaryBindingTrace.commit(); return JetTypeInfo.create(null, dataFlowInfo); } if (leftType == null) { dataFlowInfo = facade.getTypeInfo(right, context.replaceDataFlowInfo(dataFlowInfo)).getDataFlowInfo(); context.trace.report(UNRESOLVED_REFERENCE.on(operationSign)); temporaryBindingTrace.commit(); return JetTypeInfo.create(null, dataFlowInfo); } ExpressionReceiver receiver = new ExpressionReceiver(left, leftType); // We check that defined only one of '+=' and '+' operations, and call it (in the case '+' we // then also assign) // Check for '+=' Name name = OperatorConventions.ASSIGNMENT_OPERATIONS.get(operationType); TemporaryBindingTrace assignmentOperationTrace = TemporaryBindingTrace.create( context.trace, "trace to check assignment operation like '+=' for", expression); OverloadResolutionResults<FunctionDescriptor> assignmentOperationDescriptors = basic.getResolutionResultsForBinaryCall( scope, name, context.replaceBindingTrace(assignmentOperationTrace), expression, receiver); JetType assignmentOperationType = OverloadResolutionResultsUtil.getResultType(assignmentOperationDescriptors); // Check for '+' Name counterpartName = OperatorConventions.BINARY_OPERATION_NAMES.get( OperatorConventions.ASSIGNMENT_OPERATION_COUNTERPARTS.get(operationType)); TemporaryBindingTrace binaryOperationTrace = TemporaryBindingTrace.create( context.trace, "trace to check binary operation like '+' for", expression); OverloadResolutionResults<FunctionDescriptor> binaryOperationDescriptors = basic.getResolutionResultsForBinaryCall( scope, counterpartName, context.replaceBindingTrace(binaryOperationTrace), expression, receiver); JetType binaryOperationType = OverloadResolutionResultsUtil.getResultType(binaryOperationDescriptors); JetType type = assignmentOperationType != null ? assignmentOperationType : binaryOperationType; if (assignmentOperationType != null && binaryOperationType != null) { OverloadResolutionResults<FunctionDescriptor> ambiguityResolutionResults = OverloadResolutionResultsUtil.ambiguity( assignmentOperationDescriptors, binaryOperationDescriptors); context.trace.report( ASSIGN_OPERATOR_AMBIGUITY.on( operationSign, ambiguityResolutionResults.getResultingCalls())); Collection<DeclarationDescriptor> descriptors = Sets.newHashSet(); for (ResolvedCall<? extends FunctionDescriptor> call : ambiguityResolutionResults.getResultingCalls()) { descriptors.add(call.getResultingDescriptor()); } dataFlowInfo = facade.getTypeInfo(right, context.replaceDataFlowInfo(dataFlowInfo)).getDataFlowInfo(); context.trace.record(AMBIGUOUS_REFERENCE_TARGET, operationSign, descriptors); } else if (assignmentOperationType != null) { assignmentOperationTrace.commit(); if (!KotlinBuiltIns.getInstance().isUnit(assignmentOperationType)) { context.trace.report( ASSIGNMENT_OPERATOR_SHOULD_RETURN_UNIT.on( operationSign, assignmentOperationDescriptors.getResultingDescriptor(), operationSign)); } } else { binaryOperationTrace.commit(); context.trace.record(VARIABLE_REASSIGNMENT, expression); if (left instanceof JetArrayAccessExpression) { ExpressionTypingContext contextForResolve = context .replaceScope(scope) .replaceBindingTrace( TemporaryBindingTrace.create( contextWithExpectedType.trace, "trace to resolve array set method for assignment", expression)); basic.resolveArrayAccessSetMethod( (JetArrayAccessExpression) left, right, contextForResolve, context.trace); } dataFlowInfo = facade.getTypeInfo(right, context.replaceDataFlowInfo(dataFlowInfo)).getDataFlowInfo(); } basic.checkLValue(context.trace, expression.getLeft()); temporaryBindingTrace.commit(); return JetTypeInfo.create( checkAssignmentType(type, expression, contextWithExpectedType), dataFlowInfo); }