001 /*
002 * Copyright 2010-2013 JetBrains s.r.o.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017 package org.jetbrains.jet.lang.resolve.calls;
018
019 import com.google.common.base.Function;
020 import com.google.common.collect.Lists;
021 import com.google.common.collect.Maps;
022 import com.google.common.collect.Sets;
023 import com.intellij.openapi.progress.ProgressIndicatorProvider;
024 import com.intellij.psi.PsiElement;
025 import org.jetbrains.annotations.NotNull;
026 import org.jetbrains.annotations.Nullable;
027 import org.jetbrains.jet.lang.descriptors.*;
028 import org.jetbrains.jet.lang.psi.*;
029 import org.jetbrains.jet.lang.resolve.*;
030 import org.jetbrains.jet.lang.resolve.calls.autocasts.AutoCastUtils;
031 import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
032 import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowValue;
033 import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowValueFactory;
034 import org.jetbrains.jet.lang.resolve.calls.context.*;
035 import org.jetbrains.jet.lang.resolve.calls.inference.*;
036 import org.jetbrains.jet.lang.resolve.calls.model.*;
037 import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResultsImpl;
038 import org.jetbrains.jet.lang.resolve.calls.results.ResolutionDebugInfo;
039 import org.jetbrains.jet.lang.resolve.calls.results.ResolutionStatus;
040 import org.jetbrains.jet.lang.resolve.calls.tasks.ResolutionTask;
041 import org.jetbrains.jet.lang.resolve.calls.tasks.TaskPrioritizer;
042 import org.jetbrains.jet.lang.resolve.calls.tasks.TracingStrategy;
043 import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver;
044 import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
045 import org.jetbrains.jet.lang.types.*;
046 import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
047 import org.jetbrains.jet.lang.types.expressions.DataFlowUtils;
048 import org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils;
049 import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
050
051 import javax.inject.Inject;
052 import java.util.*;
053
054 import static org.jetbrains.jet.lang.diagnostics.Errors.PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT;
055 import static org.jetbrains.jet.lang.diagnostics.Errors.SUPER_IS_NOT_AN_EXPRESSION;
056 import static org.jetbrains.jet.lang.resolve.calls.CallResolverUtil.ResolveArgumentsMode.RESOLVE_FUNCTION_ARGUMENTS;
057 import static org.jetbrains.jet.lang.resolve.calls.CallResolverUtil.ResolveArgumentsMode.SHAPE_FUNCTION_ARGUMENTS;
058 import static org.jetbrains.jet.lang.resolve.calls.CallTransformer.CallForImplicitInvoke;
059 import static org.jetbrains.jet.lang.resolve.calls.context.ContextDependency.INDEPENDENT;
060 import static org.jetbrains.jet.lang.resolve.calls.results.ResolutionStatus.*;
061 import static org.jetbrains.jet.lang.types.TypeUtils.*;
062
063 public class CandidateResolver {
064 @NotNull
065 private ArgumentTypeResolver argumentTypeResolver;
066
067 @Inject
068 public void setArgumentTypeResolver(@NotNull ArgumentTypeResolver argumentTypeResolver) {
069 this.argumentTypeResolver = argumentTypeResolver;
070 }
071
072 public <D extends CallableDescriptor, F extends D> void performResolutionForCandidateCall(
073 @NotNull CallCandidateResolutionContext<D> context,
074 @NotNull ResolutionTask<D, F> task) {
075
076 ProgressIndicatorProvider.checkCanceled();
077
078 MutableResolvedCall<D> candidateCall = context.candidateCall;
079 D candidate = candidateCall.getCandidateDescriptor();
080
081 candidateCall.addStatus(checkReceiverTypeError(context));
082
083 if (ErrorUtils.isError(candidate)) {
084 candidateCall.addStatus(SUCCESS);
085 markAllArgumentsAsUnmapped(context);
086 return;
087 }
088
089 if (!checkOuterClassMemberIsAccessible(context)) {
090 candidateCall.addStatus(OTHER_ERROR);
091 markAllArgumentsAsUnmapped(context);
092 return;
093 }
094
095
096 DeclarationDescriptorWithVisibility invisibleMember =
097 Visibilities.findInvisibleMember(candidate, context.scope.getContainingDeclaration());
098 if (invisibleMember != null) {
099 candidateCall.addStatus(OTHER_ERROR);
100 context.tracing.invisibleMember(context.trace, invisibleMember);
101 }
102
103 if (task.checkArguments == CheckValueArgumentsMode.ENABLED) {
104 Set<ValueArgument> unmappedArguments = Sets.newLinkedHashSet();
105 ValueArgumentsToParametersMapper.Status argumentMappingStatus = ValueArgumentsToParametersMapper.mapValueArgumentsToParameters(
106 context.call, context.tracing, candidateCall, unmappedArguments);
107 if (!argumentMappingStatus.isSuccess()) {
108 candidateCall.addUnmappedArguments(unmappedArguments);
109 //For the expressions like '42.(f)()' where f: () -> Unit we'd like to generate an error 'no receiver admitted',
110 //not to throw away the candidate.
111 if (argumentMappingStatus == ValueArgumentsToParametersMapper.Status.STRONG_ERROR
112 && !CallResolverUtil.isInvokeCallOnExpressionWithBothReceivers(context.call)) {
113 candidateCall.addStatus(RECEIVER_PRESENCE_ERROR);
114 return;
115 }
116 else {
117 candidateCall.addStatus(OTHER_ERROR);
118 }
119 }
120 }
121
122 List<JetTypeProjection> jetTypeArguments = context.call.getTypeArguments();
123 if (jetTypeArguments.isEmpty()) {
124 if (!candidate.getTypeParameters().isEmpty()) {
125 ResolutionStatus status = inferTypeArguments(context);
126 candidateCall.addStatus(status);
127 }
128 else {
129 candidateCall.addStatus(checkAllValueArguments(context, SHAPE_FUNCTION_ARGUMENTS).status);
130 }
131 }
132 else {
133 // Explicit type arguments passed
134
135 List<JetType> typeArguments = new ArrayList<JetType>();
136 for (JetTypeProjection projection : jetTypeArguments) {
137 if (projection.getProjectionKind() != JetProjectionKind.NONE) {
138 context.trace.report(PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT.on(projection));
139 }
140 typeArguments.add(argumentTypeResolver.resolveTypeRefWithDefault(
141 projection.getTypeReference(), context.scope, context.trace, ErrorUtils.createErrorType("Star projection in a call")));
142 }
143 int expectedTypeArgumentCount = candidate.getTypeParameters().size();
144 if (expectedTypeArgumentCount == jetTypeArguments.size()) {
145
146 checkGenericBoundsInAFunctionCall(jetTypeArguments, typeArguments, candidate, context.trace);
147
148 Map<TypeConstructor, TypeProjection>
149 substitutionContext = FunctionDescriptorUtil
150 .createSubstitutionContext((FunctionDescriptor) candidate, typeArguments);
151 TypeSubstitutor substitutor = TypeSubstitutor.create(substitutionContext);
152 candidateCall.setResultingSubstitutor(substitutor);
153
154 candidateCall.addStatus(checkAllValueArguments(context, SHAPE_FUNCTION_ARGUMENTS).status);
155 }
156 else {
157 candidateCall.addStatus(OTHER_ERROR);
158 context.tracing.wrongNumberOfTypeArguments(context.trace, expectedTypeArgumentCount);
159 }
160 }
161
162 task.performAdvancedChecks(candidate, context.trace, context.tracing);
163
164 // 'super' cannot be passed as an argument, for receiver arguments expression typer does not track this
165 // See TaskPrioritizer for more
166 JetSuperExpression superExpression = TaskPrioritizer.getReceiverSuper(candidateCall.getReceiverArgument());
167 if (superExpression != null) {
168 context.trace.report(SUPER_IS_NOT_AN_EXPRESSION.on(superExpression, superExpression.getText()));
169 candidateCall.addStatus(OTHER_ERROR);
170 }
171 }
172
173 private static void markAllArgumentsAsUnmapped(CallCandidateResolutionContext<?> context) {
174 if (context.checkArguments == CheckValueArgumentsMode.ENABLED) {
175 context.candidateCall.addUnmappedArguments(context.call.getValueArguments());
176 }
177 }
178
179 private static boolean checkOuterClassMemberIsAccessible(@NotNull CallCandidateResolutionContext<?> context) {
180 // In "this@Outer.foo()" the error will be reported on "this@Outer" instead
181 if (context.call.getExplicitReceiver().exists() || context.call.getThisObject().exists()) return true;
182
183 ClassDescriptor candidateThis = getDeclaringClass(context.candidateCall.getCandidateDescriptor());
184 if (candidateThis == null || candidateThis.getKind().isSingleton()) return true;
185
186 return DescriptorResolver.checkHasOuterClassInstance(context.scope, context.trace, context.call.getCallElement(), candidateThis);
187 }
188
189 @Nullable
190 private static ClassDescriptor getDeclaringClass(@NotNull CallableDescriptor candidate) {
191 ReceiverParameterDescriptor expectedThis = candidate.getExpectedThisObject();
192 if (expectedThis == null) return null;
193 DeclarationDescriptor descriptor = expectedThis.getContainingDeclaration();
194 return descriptor instanceof ClassDescriptor ? (ClassDescriptor) descriptor : null;
195 }
196
197 public <D extends CallableDescriptor> void completeTypeInferenceDependentOnFunctionLiteralsForCall(
198 CallCandidateResolutionContext<D> context
199 ) {
200 MutableResolvedCall<D> resolvedCall = context.candidateCall;
201 ConstraintSystem constraintSystem = resolvedCall.getConstraintSystem();
202 if (!resolvedCall.hasIncompleteTypeParameters() || constraintSystem == null) return;
203
204 // constraints for function literals
205 // Value parameters
206 for (Map.Entry<ValueParameterDescriptor, ResolvedValueArgument> entry : resolvedCall.getValueArguments().entrySet()) {
207 ResolvedValueArgument resolvedValueArgument = entry.getValue();
208 ValueParameterDescriptor valueParameterDescriptor = entry.getKey();
209
210 for (ValueArgument valueArgument : resolvedValueArgument.getArguments()) {
211 addConstraintForFunctionLiteral(valueArgument, valueParameterDescriptor, constraintSystem, context);
212 }
213 }
214 resolvedCall.setResultingSubstitutor(constraintSystem.getResultingSubstitutor());
215 }
216
217 @Nullable
218 public <D extends CallableDescriptor> JetType completeTypeInferenceDependentOnExpectedTypeForCall(
219 @NotNull CallCandidateResolutionContext<D> context,
220 boolean isInnerCall
221 ) {
222 MutableResolvedCall<D> resolvedCall = context.candidateCall;
223 if (resolvedCall.isCompleted()) {
224 return resolvedCall.getResultingDescriptor().getReturnType();
225 }
226 if (!resolvedCall.hasIncompleteTypeParameters()) {
227 completeNestedCallsInference(context);
228 checkValueArgumentTypes(context);
229 resolvedCall.markCallAsCompleted();
230 return resolvedCall.getResultingDescriptor().getReturnType();
231 }
232
233 assert resolvedCall.getConstraintSystem() != null;
234
235 JetType unsubstitutedReturnType = resolvedCall.getCandidateDescriptor().getReturnType();
236 if (unsubstitutedReturnType != null) {
237 resolvedCall.getConstraintSystem().addSupertypeConstraint(
238 context.expectedType, unsubstitutedReturnType, ConstraintPosition.EXPECTED_TYPE_POSITION);
239 }
240
241 updateSystemWithConstraintSystemCompleter(context, resolvedCall);
242
243 updateSystemIfExpectedTypeIsUnit(context, resolvedCall);
244
245 ((ConstraintSystemImpl)resolvedCall.getConstraintSystem()).processDeclaredBoundConstraints();
246
247 JetType returnType;
248 if (!resolvedCall.getConstraintSystem().getStatus().isSuccessful()) {
249 returnType = reportInferenceError(context);
250 }
251 else {
252 resolvedCall.setResultingSubstitutor(resolvedCall.getConstraintSystem().getResultingSubstitutor());
253
254 completeNestedCallsInference(context);
255 // Here we type check the arguments with inferred types expected
256 checkAllValueArguments(context, context.trace, RESOLVE_FUNCTION_ARGUMENTS);
257
258 resolvedCall.setHasIncompleteTypeParameters(false);
259 ResolutionStatus status = resolvedCall.getStatus();
260 if (status == ResolutionStatus.UNKNOWN_STATUS || status == ResolutionStatus.INCOMPLETE_TYPE_INFERENCE) {
261 resolvedCall.setStatusToSuccess();
262 }
263 returnType = resolvedCall.getResultingDescriptor().getReturnType();
264 if (isInnerCall) {
265 PsiElement callElement = context.call.getCallElement();
266 if (callElement instanceof JetCallExpression) {
267 DataFlowUtils.checkType(returnType, (JetCallExpression) callElement, context, context.dataFlowInfo);
268 }
269 }
270 }
271 resolvedCall.markCallAsCompleted();
272 return returnType;
273 }
274
275 private <D extends CallableDescriptor> void completeTypeInferenceForAllCandidatesForArgument(
276 @NotNull CallCandidateResolutionContext<D> context,
277 @Nullable JetExpression argumentExpression
278 ) {
279 // All candidates for inner calls are not needed, so there is no need to complete them
280 if (context.collectAllCandidates) return;
281
282 if (argumentExpression == null) return;
283
284 CallKey callKey = CallKey.create(argumentExpression);
285 OverloadResolutionResultsImpl<CallableDescriptor> resolutionResults = context.resolutionResultsCache.getResolutionResults(callKey);
286 if (resolutionResults == null) return;
287
288 completeTypeInferenceForAllCandidates(context.toBasic(), resolutionResults);
289 }
290
291 public <D extends CallableDescriptor> void completeTypeInferenceForAllCandidates(
292 @NotNull BasicCallResolutionContext context,
293 @NotNull OverloadResolutionResultsImpl<D> results
294 ) {
295 Collection<? extends ResolvedCall<D>> candidates;
296 if (context.collectAllCandidates) {
297 candidates = results.getAllCandidates();
298 assert candidates != null : "Should be guaranteed by collectAllCandidates == true";
299 }
300 else {
301 candidates = results.getResultingCalls();
302 }
303 for (ResolvedCall<D> resolvedCall : candidates) {
304 MutableResolvedCall<D> mutableResolvedCall = (MutableResolvedCall<D>) resolvedCall;
305 if (mutableResolvedCall.isCompleted()) continue;
306
307 TemporaryBindingTrace temporaryBindingTrace = TemporaryBindingTrace.create(
308 context.trace, "Trace to complete a candidate that is not a resulting call");
309
310 CallCandidateResolutionContext<D> callCandidateResolutionContext = CallCandidateResolutionContext.createForCallBeingAnalyzed(
311 mutableResolvedCall, context.replaceBindingTrace(temporaryBindingTrace), TracingStrategy.EMPTY);
312
313 completeTypeInferenceDependentOnExpectedTypeForCall(callCandidateResolutionContext, false);
314 }
315 }
316
317 private static <D extends CallableDescriptor> void updateSystemWithConstraintSystemCompleter(
318 @NotNull CallCandidateResolutionContext<D> context,
319 @NotNull MutableResolvedCall<D> resolvedCall
320 ) {
321 ConstraintSystem constraintSystem = resolvedCall.getConstraintSystem();
322 assert constraintSystem != null;
323 ConstraintSystemCompleter constraintSystemCompleter = context.trace.get(
324 BindingContext.CONSTRAINT_SYSTEM_COMPLETER, context.call.getCalleeExpression());
325 if (constraintSystemCompleter == null) return;
326
327 ConstraintSystem copy = constraintSystem.copy();
328
329 constraintSystemCompleter.completeConstraintSystem(copy, resolvedCall);
330
331 //todo improve error reporting with errors in constraints from completer
332 if (!copy.getStatus().hasOnlyErrorsFromPosition(ConstraintPosition.FROM_COMPLETER)) {
333 resolvedCall.setConstraintSystem(copy);
334 }
335 }
336
337 private static <D extends CallableDescriptor> void updateSystemIfExpectedTypeIsUnit(
338 @NotNull CallCandidateResolutionContext<D> context,
339 @NotNull MutableResolvedCall<D> resolvedCall
340 ) {
341 ConstraintSystem constraintSystem = resolvedCall.getConstraintSystem();
342 assert constraintSystem != null;
343 JetType returnType = resolvedCall.getCandidateDescriptor().getReturnType();
344 if (returnType == null) return;
345
346 if (!constraintSystem.getStatus().isSuccessful() && context.expectedType == TypeUtils.UNIT_EXPECTED_TYPE) {
347 ConstraintSystemImpl copy = (ConstraintSystemImpl) constraintSystem.copy();
348
349 copy.addSupertypeConstraint(KotlinBuiltIns.getInstance().getUnitType(), returnType, ConstraintPosition.EXPECTED_TYPE_POSITION);
350 if (copy.getStatus().isSuccessful()) {
351 resolvedCall.setConstraintSystem(copy);
352 }
353 }
354 }
355
356 private <D extends CallableDescriptor> JetType reportInferenceError(
357 @NotNull CallCandidateResolutionContext<D> context
358 ) {
359 MutableResolvedCall<D> resolvedCall = context.candidateCall;
360 ConstraintSystem constraintSystem = resolvedCall.getConstraintSystem();
361 assert constraintSystem != null;
362
363 resolvedCall.setResultingSubstitutor(constraintSystem.getResultingSubstitutor());
364 completeNestedCallsInference(context);
365 List<JetType> argumentTypes = checkValueArgumentTypes(
366 context, resolvedCall, context.trace, RESOLVE_FUNCTION_ARGUMENTS).argumentTypes;
367 JetType receiverType = resolvedCall.getReceiverArgument().exists() ? resolvedCall.getReceiverArgument().getType() : null;
368 InferenceErrorData errorData = InferenceErrorData
369 .create(resolvedCall.getCandidateDescriptor(), constraintSystem, argumentTypes, receiverType, context.expectedType);
370
371 context.tracing.typeInferenceFailed(context.trace, errorData);
372 resolvedCall.addStatus(ResolutionStatus.OTHER_ERROR);
373 if (!resolvedCall.hasInferredReturnType()) return null;
374 return resolvedCall.getResultingDescriptor().getReturnType();
375 }
376
377 public <D extends CallableDescriptor> void completeNestedCallsInference(
378 @NotNull CallCandidateResolutionContext<D> context
379 ) {
380 if (CallResolverUtil.isInvokeCallOnVariable(context.call)) return;
381 MutableResolvedCall<D> resolvedCall = context.candidateCall;
382 for (Map.Entry<ValueParameterDescriptor, ResolvedValueArgument> entry : resolvedCall.getValueArguments().entrySet()) {
383 ValueParameterDescriptor parameterDescriptor = entry.getKey();
384 ResolvedValueArgument resolvedArgument = entry.getValue();
385
386 for (ValueArgument argument : resolvedArgument.getArguments()) {
387 completeInferenceForArgument(argument, parameterDescriptor, context);
388 }
389 }
390 completeUnmappedArguments(context, context.candidateCall.getUnmappedArguments());
391 recordReferenceForInvokeFunction(context);
392 }
393
394 private <D extends CallableDescriptor> void completeInferenceForArgument(
395 @NotNull ValueArgument argument,
396 @NotNull ValueParameterDescriptor parameterDescriptor,
397 @NotNull CallCandidateResolutionContext<D> context
398 ) {
399 JetExpression expression = argument.getArgumentExpression();
400 if (expression == null) return;
401
402 JetType expectedType = getEffectiveExpectedType(parameterDescriptor, argument);
403 context = context.replaceExpectedType(expectedType);
404
405 JetExpression keyExpression = getDeferredComputationKeyExpression(expression);
406 CallCandidateResolutionContext<?> storedContextForArgument = context.resolutionResultsCache.getDeferredComputation(keyExpression);
407
408 PsiElement parent = expression.getParent();
409 if (parent instanceof JetWhenExpression && expression == ((JetWhenExpression) parent).getSubjectExpression()
410 || (expression instanceof JetFunctionLiteralExpression)) {
411 return;
412 }
413 if (storedContextForArgument == null) {
414 JetType type = ArgumentTypeResolver.updateResultArgumentTypeIfNotDenotable(context, expression);
415 checkResultArgumentType(type, argument, context);
416 completeTypeInferenceForAllCandidatesForArgument(context, keyExpression);
417 return;
418 }
419
420 CallCandidateResolutionContext<?> contextForArgument = storedContextForArgument
421 .replaceContextDependency(INDEPENDENT).replaceBindingTrace(context.trace).replaceExpectedType(expectedType);
422 JetType type = completeTypeInferenceDependentOnExpectedTypeForCall(contextForArgument, true);
423 JetType recordedType = context.trace.get(BindingContext.EXPRESSION_TYPE, expression);
424 if (recordedType != null && !recordedType.getConstructor().isDenotable()) {
425 type = ArgumentTypeResolver.updateResultArgumentTypeIfNotDenotable(context, expression);
426 }
427
428 JetType result = BindingContextUtils.updateRecordedType(
429 type, expression, context.trace, isFairSafeCallExpression(expression, context.trace));
430
431 completeTypeInferenceForAllCandidatesForArgument(context, keyExpression);
432
433 DataFlowUtils.checkType(result, expression, contextForArgument);
434 }
435
436 public void completeNestedCallsForNotResolvedInvocation(@NotNull CallResolutionContext<?> context) {
437 completeNestedCallsForNotResolvedInvocation(context, context.call.getValueArguments());
438 }
439
440 public void completeUnmappedArguments(@NotNull CallResolutionContext<?> context, @NotNull Collection<? extends ValueArgument> unmappedArguments) {
441 completeNestedCallsForNotResolvedInvocation(context, unmappedArguments);
442 }
443
444 private void completeNestedCallsForNotResolvedInvocation(@NotNull CallResolutionContext<?> context, @NotNull Collection<? extends ValueArgument> arguments) {
445 if (CallResolverUtil.isInvokeCallOnVariable(context.call)) return;
446 if (context.checkArguments == CheckValueArgumentsMode.DISABLED) return;
447
448 for (ValueArgument argument : arguments) {
449 JetExpression expression = argument.getArgumentExpression();
450
451 JetExpression keyExpression = getDeferredComputationKeyExpression(expression);
452
453 CallCandidateResolutionContext<?> storedContextForArgument =
454 context.resolutionResultsCache.getDeferredComputation(keyExpression);
455 if (storedContextForArgument == null) continue;
456 if (storedContextForArgument.candidateCall.isCompleted()) continue;
457
458 CallCandidateResolutionContext<?> newContext =
459 storedContextForArgument.replaceBindingTrace(context.trace).replaceContextDependency(INDEPENDENT);
460 completeTypeInferenceDependentOnExpectedTypeForCall(newContext, true);
461 }
462 }
463
464 @Nullable
465 private JetExpression getDeferredComputationKeyExpression(@Nullable JetExpression expression) {
466 if (expression == null) return null;
467 return expression.accept(new JetVisitor<JetExpression, Void>() {
468 @Nullable
469 private JetExpression visitInnerExpression(@Nullable JetElement expression) {
470 if (expression == null) return null;
471 return expression.accept(this, null);
472 }
473
474 @Override
475 public JetExpression visitQualifiedExpression(@NotNull JetQualifiedExpression expression, Void data) {
476 return visitInnerExpression(expression.getSelectorExpression());
477 }
478
479 @Override
480 public JetExpression visitExpression(@NotNull JetExpression expression, Void data) {
481 return expression;
482 }
483
484 @Override
485 public JetExpression visitParenthesizedExpression(@NotNull JetParenthesizedExpression expression, Void data) {
486 return visitInnerExpression(expression.getExpression());
487 }
488
489 @Override
490 public JetExpression visitUnaryExpression(@NotNull JetUnaryExpression expression, Void data) {
491 return ExpressionTypingUtils.isUnaryExpressionDependentOnExpectedType(expression) ? expression : null;
492 }
493
494 @Override
495 public JetExpression visitPrefixExpression(@NotNull JetPrefixExpression expression, Void data) {
496 return visitInnerExpression(JetPsiUtil.getBaseExpressionIfLabeledExpression(expression));
497 }
498
499 @Override
500 public JetExpression visitBlockExpression(@NotNull JetBlockExpression expression, Void data) {
501 JetElement lastStatement = JetPsiUtil.getLastStatementInABlock(expression);
502 if (lastStatement != null) {
503 return visitInnerExpression(lastStatement);
504 }
505 return expression;
506 }
507
508 @Override
509 public JetExpression visitBinaryExpression(@NotNull JetBinaryExpression expression, Void data) {
510 return ExpressionTypingUtils.isBinaryExpressionDependentOnExpectedType(expression) ? expression : null;
511 }
512 }, null);
513 }
514
515 private static boolean isFairSafeCallExpression(@NotNull JetExpression expression, @NotNull BindingTrace trace) {
516 // We are interested in type of the last call:
517 // 'a.b?.foo()' is safe call, but 'a?.b.foo()' is not.
518 // Since receiver is 'a.b' and selector is 'foo()',
519 // we can only check if an expression is safe call.
520 if (!(expression instanceof JetSafeQualifiedExpression)) return false;
521
522 JetSafeQualifiedExpression safeQualifiedExpression = (JetSafeQualifiedExpression) expression;
523 //If a receiver type is not null, then this safe expression is useless, and we don't need to make the result type nullable.
524 JetType type = trace.get(BindingContext.EXPRESSION_TYPE, safeQualifiedExpression.getReceiverExpression());
525 return type != null && type.isNullable();
526 }
527
528 private static <D extends CallableDescriptor> void checkResultArgumentType(
529 @Nullable JetType type,
530 @NotNull ValueArgument argument,
531 @NotNull CallCandidateResolutionContext<D> context
532 ) {
533 JetExpression expression = argument.getArgumentExpression();
534 if (expression == null) return;
535
536 DataFlowInfo dataFlowInfoForValueArgument = context.candidateCall.getDataFlowInfoForArguments().getInfo(argument);
537 ResolutionContext<?> newContext = context.replaceExpectedType(context.expectedType).replaceDataFlowInfo(
538 dataFlowInfoForValueArgument);
539 DataFlowUtils.checkType(type, expression, newContext);
540 }
541
542 private static <D extends CallableDescriptor> void recordReferenceForInvokeFunction(CallCandidateResolutionContext<D> context) {
543 PsiElement callElement = context.call.getCallElement();
544 if (!(callElement instanceof JetCallExpression)) return;
545
546 JetCallExpression callExpression = (JetCallExpression) callElement;
547 if (BindingContextUtils.isCallExpressionWithValidReference(callExpression, context.trace.getBindingContext())) {
548 CallableDescriptor resultingDescriptor = context.candidateCall.getResultingDescriptor();
549 context.trace.record(BindingContext.EXPRESSION_TYPE, callExpression, resultingDescriptor.getReturnType());
550 context.trace.record(BindingContext.REFERENCE_TARGET, callExpression, context.candidateCall.getCandidateDescriptor());
551 }
552 }
553
554 private <D extends CallableDescriptor> void addConstraintForFunctionLiteral(
555 @NotNull ValueArgument valueArgument,
556 @NotNull ValueParameterDescriptor valueParameterDescriptor,
557 @NotNull ConstraintSystem constraintSystem,
558 @NotNull CallCandidateResolutionContext<D> context
559 ) {
560 JetExpression argumentExpression = valueArgument.getArgumentExpression();
561 if (argumentExpression == null) return;
562 if (!ArgumentTypeResolver.isFunctionLiteralArgument(argumentExpression)) return;
563
564 JetFunctionLiteralExpression functionLiteralExpression = ArgumentTypeResolver.getFunctionLiteralArgument(argumentExpression);
565
566 JetType effectiveExpectedType = getEffectiveExpectedType(valueParameterDescriptor, valueArgument);
567 JetType expectedType = constraintSystem.getCurrentSubstitutor().substitute(effectiveExpectedType, Variance.INVARIANT);
568 if (expectedType == null || expectedType == DONT_CARE) {
569 expectedType = argumentTypeResolver.getShapeTypeOfFunctionLiteral(functionLiteralExpression, context.scope, context.trace, false);
570 }
571 if (expectedType == null || !KotlinBuiltIns.getInstance().isFunctionOrExtensionFunctionType(expectedType)
572 || CallResolverUtil.hasUnknownFunctionParameter(expectedType)) {
573 return;
574 }
575 MutableDataFlowInfoForArguments dataFlowInfoForArguments = context.candidateCall.getDataFlowInfoForArguments();
576 DataFlowInfo dataFlowInfoForArgument = dataFlowInfoForArguments.getInfo(valueArgument);
577
578 //todo analyze function literal body once in 'dependent' mode, then complete it with respect to expected type
579 boolean hasExpectedReturnType = !CallResolverUtil.hasUnknownReturnType(expectedType);
580 if (hasExpectedReturnType) {
581 TemporaryTraceAndCache temporaryToResolveFunctionLiteral = TemporaryTraceAndCache.create(
582 context, "trace to resolve function literal with expected return type", argumentExpression);
583
584 JetElement statementExpression = JetPsiUtil.getLastStatementInABlock(functionLiteralExpression.getBodyExpression());
585 if (statementExpression == null) return;
586 boolean[] mismatch = new boolean[1];
587 ObservableBindingTrace errorInterceptingTrace = ExpressionTypingUtils.makeTraceInterceptingTypeMismatch(
588 temporaryToResolveFunctionLiteral.trace, statementExpression, mismatch);
589 CallCandidateResolutionContext<D> newContext = context
590 .replaceBindingTrace(errorInterceptingTrace).replaceExpectedType(expectedType)
591 .replaceDataFlowInfo(dataFlowInfoForArgument).replaceResolutionResultsCache(temporaryToResolveFunctionLiteral.cache)
592 .replaceContextDependency(INDEPENDENT);
593 JetType type = argumentTypeResolver.getFunctionLiteralTypeInfo(
594 argumentExpression, functionLiteralExpression, newContext, RESOLVE_FUNCTION_ARGUMENTS).getType();
595 if (!mismatch[0]) {
596 constraintSystem.addSubtypeConstraint(
597 type, effectiveExpectedType, ConstraintPosition.getValueParameterPosition(valueParameterDescriptor.getIndex()));
598 temporaryToResolveFunctionLiteral.commit();
599 return;
600 }
601 }
602 JetType expectedTypeWithoutReturnType = hasExpectedReturnType ? CallResolverUtil.replaceReturnTypeByUnknown(expectedType) : expectedType;
603 CallCandidateResolutionContext<D> newContext = context
604 .replaceExpectedType(expectedTypeWithoutReturnType).replaceDataFlowInfo(dataFlowInfoForArgument)
605 .replaceContextDependency(INDEPENDENT);
606 JetType type = argumentTypeResolver.getFunctionLiteralTypeInfo(argumentExpression, functionLiteralExpression, newContext,
607 RESOLVE_FUNCTION_ARGUMENTS).getType();
608 constraintSystem.addSubtypeConstraint(
609 type, effectiveExpectedType, ConstraintPosition.getValueParameterPosition(valueParameterDescriptor.getIndex()));
610 }
611
612 private <D extends CallableDescriptor> ResolutionStatus inferTypeArguments(CallCandidateResolutionContext<D> context) {
613 MutableResolvedCall<D> candidateCall = context.candidateCall;
614 final D candidate = candidateCall.getCandidateDescriptor();
615
616 context.trace.get(ResolutionDebugInfo.RESOLUTION_DEBUG_INFO, context.call.getCallElement());
617
618 ConstraintSystemImpl constraintSystem = new ConstraintSystemImpl();
619
620 // If the call is recursive, e.g.
621 // fun foo<T>(t : T) : T = foo(t)
622 // we can't use same descriptor objects for T's as actual type values and same T's as unknowns,
623 // because constraints become trivial (T :< T), and inference fails
624 //
625 // Thus, we replace the parameters of our descriptor with fresh objects (perform alpha-conversion)
626 CallableDescriptor candidateWithFreshVariables = FunctionDescriptorUtil.alphaConvertTypeParameters(candidate);
627
628 Map<TypeParameterDescriptor, Variance> typeVariables = Maps.newLinkedHashMap();
629 for (TypeParameterDescriptor typeParameterDescriptor : candidateWithFreshVariables.getTypeParameters()) {
630 typeVariables.put(typeParameterDescriptor, Variance.INVARIANT); // TODO: variance of the occurrences
631 }
632 constraintSystem.registerTypeVariables(typeVariables);
633
634 TypeSubstitutor substituteDontCare =
635 makeConstantSubstitutor(candidateWithFreshVariables.getTypeParameters(), DONT_CARE);
636
637 // Value parameters
638 for (Map.Entry<ValueParameterDescriptor, ResolvedValueArgument> entry : candidateCall.getValueArguments().entrySet()) {
639 ResolvedValueArgument resolvedValueArgument = entry.getValue();
640 ValueParameterDescriptor valueParameterDescriptor = candidateWithFreshVariables.getValueParameters().get(entry.getKey().getIndex());
641
642
643 for (ValueArgument valueArgument : resolvedValueArgument.getArguments()) {
644 // TODO : more attempts, with different expected types
645
646 // Here we type check expecting an error type (DONT_CARE, substitution with substituteDontCare)
647 // and throw the results away
648 // We'll type check the arguments later, with the inferred types expected
649 boolean[] isErrorType = new boolean[1];
650 addConstraintForValueArgument(valueArgument, valueParameterDescriptor, substituteDontCare, constraintSystem,
651 context, isErrorType, SHAPE_FUNCTION_ARGUMENTS);
652 if (isErrorType[0]) {
653 candidateCall.argumentHasNoType();
654 }
655 }
656 }
657
658 // Receiver
659 // Error is already reported if something is missing
660 ReceiverValue receiverArgument = candidateCall.getReceiverArgument();
661 ReceiverParameterDescriptor receiverParameter = candidateWithFreshVariables.getReceiverParameter();
662 if (receiverArgument.exists() && receiverParameter != null) {
663 JetType receiverType =
664 context.candidateCall.isSafeCall()
665 ? TypeUtils.makeNotNullable(receiverArgument.getType())
666 : receiverArgument.getType();
667 if (receiverArgument instanceof ExpressionReceiver) {
668 receiverType = updateResultTypeForSmartCasts(receiverType, ((ExpressionReceiver) receiverArgument).getExpression(),
669 context.dataFlowInfo, context.trace);
670 }
671 constraintSystem.addSubtypeConstraint(receiverType, receiverParameter.getType(), ConstraintPosition.RECEIVER_POSITION);
672 }
673
674 // Restore type variables before alpha-conversion
675 ConstraintSystem constraintSystemWithRightTypeParameters = constraintSystem.substituteTypeVariables(
676 new Function<TypeParameterDescriptor, TypeParameterDescriptor>() {
677 @Override
678 public TypeParameterDescriptor apply(@Nullable TypeParameterDescriptor typeParameterDescriptor) {
679 assert typeParameterDescriptor != null;
680 return candidate.getTypeParameters().get(typeParameterDescriptor.getIndex());
681 }
682 });
683 candidateCall.setConstraintSystem(constraintSystemWithRightTypeParameters);
684
685
686 // Solution
687 boolean hasContradiction = constraintSystem.getStatus().hasContradiction();
688 candidateCall.setHasIncompleteTypeParameters(true);
689 if (!hasContradiction) {
690 return INCOMPLETE_TYPE_INFERENCE;
691 }
692 ValueArgumentsCheckingResult checkingResult = checkAllValueArguments(context, SHAPE_FUNCTION_ARGUMENTS);
693 ResolutionStatus argumentsStatus = checkingResult.status;
694 return OTHER_ERROR.combine(argumentsStatus);
695 }
696
697 private void addConstraintForValueArgument(
698 @NotNull ValueArgument valueArgument,
699 @NotNull ValueParameterDescriptor valueParameterDescriptor,
700 @NotNull TypeSubstitutor substitutor,
701 @NotNull ConstraintSystem constraintSystem,
702 @NotNull CallCandidateResolutionContext<?> context,
703 @Nullable boolean[] isErrorType,
704 @NotNull CallResolverUtil.ResolveArgumentsMode resolveFunctionArgumentBodies) {
705
706 JetType effectiveExpectedType = getEffectiveExpectedType(valueParameterDescriptor, valueArgument);
707 JetExpression argumentExpression = valueArgument.getArgumentExpression();
708
709 JetType expectedType = substitutor.substitute(effectiveExpectedType, Variance.INVARIANT);
710 DataFlowInfo dataFlowInfoForArgument = context.candidateCall.getDataFlowInfoForArguments().getInfo(valueArgument);
711 CallResolutionContext<?> newContext = context.replaceExpectedType(expectedType).replaceDataFlowInfo(dataFlowInfoForArgument);
712
713 JetTypeInfo typeInfoForCall = argumentTypeResolver.getArgumentTypeInfo(
714 argumentExpression, newContext, resolveFunctionArgumentBodies);
715 context.candidateCall.getDataFlowInfoForArguments().updateInfo(valueArgument, typeInfoForCall.getDataFlowInfo());
716
717 JetType type = updateResultTypeForSmartCasts(typeInfoForCall.getType(), argumentExpression, dataFlowInfoForArgument, context.trace);
718 constraintSystem.addSubtypeConstraint(type, effectiveExpectedType, ConstraintPosition.getValueParameterPosition(
719 valueParameterDescriptor.getIndex()));
720 if (isErrorType != null) {
721 isErrorType[0] = type == null || type.isError();
722 }
723 }
724
725 @Nullable
726 private static JetType updateResultTypeForSmartCasts(
727 @Nullable JetType type,
728 @Nullable JetExpression argumentExpression,
729 @NotNull DataFlowInfo dataFlowInfoForArgument,
730 @NotNull BindingTrace trace
731 ) {
732 if (argumentExpression == null || type == null) return type;
733
734 DataFlowValue dataFlowValue = DataFlowValueFactory.createDataFlowValue(
735 argumentExpression, type, trace.getBindingContext());
736 if (!dataFlowValue.isStableIdentifier()) return type;
737
738 Set<JetType> possibleTypes = dataFlowInfoForArgument.getPossibleTypes(dataFlowValue);
739 if (possibleTypes.isEmpty()) return type;
740
741 return TypeUtils.intersect(JetTypeChecker.INSTANCE, possibleTypes);
742 }
743
744 private <D extends CallableDescriptor> ValueArgumentsCheckingResult checkAllValueArguments(
745 @NotNull CallCandidateResolutionContext<D> context,
746 @NotNull CallResolverUtil.ResolveArgumentsMode resolveFunctionArgumentBodies) {
747 return checkAllValueArguments(context, context.candidateCall.getTrace(), resolveFunctionArgumentBodies);
748 }
749
750 private <D extends CallableDescriptor> ValueArgumentsCheckingResult checkAllValueArguments(
751 @NotNull CallCandidateResolutionContext<D> context,
752 @NotNull BindingTrace trace,
753 @NotNull CallResolverUtil.ResolveArgumentsMode resolveFunctionArgumentBodies
754 ) {
755 ValueArgumentsCheckingResult checkingResult = checkValueArgumentTypes(
756 context, context.candidateCall, trace, resolveFunctionArgumentBodies);
757 ResolutionStatus resultStatus = checkingResult.status;
758 resultStatus = resultStatus.combine(checkReceivers(context, trace));
759
760 return new ValueArgumentsCheckingResult(resultStatus, checkingResult.argumentTypes);
761 }
762
763 private static <D extends CallableDescriptor> ResolutionStatus checkReceivers(
764 @NotNull CallCandidateResolutionContext<D> context,
765 @NotNull BindingTrace trace
766 ) {
767 ResolutionStatus resultStatus = SUCCESS;
768 ResolvedCall<D> candidateCall = context.candidateCall;
769
770 resultStatus = resultStatus.combine(checkReceiverTypeError(context));
771
772 // Comment about a very special case.
773 // Call 'b.foo(1)' where class 'Foo' has an extension member 'fun B.invoke(Int)' should be checked two times for safe call (in 'checkReceiver'), because
774 // both 'b' (receiver) and 'foo' (this object) might be nullable. In the first case we mark dot, in the second 'foo'.
775 // Class 'CallForImplicitInvoke' helps up to recognise this case, and parameter 'implicitInvokeCheck' helps us to distinguish whether we check receiver or this object.
776
777 resultStatus = resultStatus.combine(checkReceiver(
778 context, candidateCall, trace,
779 candidateCall.getResultingDescriptor().getReceiverParameter(),
780 candidateCall.getReceiverArgument(), candidateCall.getExplicitReceiverKind().isReceiver(), false));
781
782 resultStatus = resultStatus.combine(checkReceiver(
783 context, candidateCall, trace,
784 candidateCall.getResultingDescriptor().getExpectedThisObject(), candidateCall.getThisObject(),
785 candidateCall.getExplicitReceiverKind().isThisObject(),
786 // for the invocation 'foo(1)' where foo is a variable of function type we should mark 'foo' if there is unsafe call error
787 context.call instanceof CallForImplicitInvoke));
788 return resultStatus;
789 }
790
791 public <D extends CallableDescriptor> ValueArgumentsCheckingResult checkValueArgumentTypes(
792 @NotNull CallCandidateResolutionContext<D> context
793 ) {
794 return checkValueArgumentTypes(context, context.candidateCall, context.trace, RESOLVE_FUNCTION_ARGUMENTS);
795 }
796
797 private <D extends CallableDescriptor, C extends CallResolutionContext<C>> ValueArgumentsCheckingResult checkValueArgumentTypes(
798 @NotNull CallResolutionContext<C> context,
799 @NotNull MutableResolvedCall<D> candidateCall,
800 @NotNull BindingTrace trace,
801 @NotNull CallResolverUtil.ResolveArgumentsMode resolveFunctionArgumentBodies) {
802 ResolutionStatus resultStatus = SUCCESS;
803 List<JetType> argumentTypes = Lists.newArrayList();
804 MutableDataFlowInfoForArguments infoForArguments = candidateCall.getDataFlowInfoForArguments();
805 for (Map.Entry<ValueParameterDescriptor, ResolvedValueArgument> entry : candidateCall.getValueArguments().entrySet()) {
806 ValueParameterDescriptor parameterDescriptor = entry.getKey();
807 ResolvedValueArgument resolvedArgument = entry.getValue();
808
809
810 for (ValueArgument argument : resolvedArgument.getArguments()) {
811 JetExpression expression = argument.getArgumentExpression();
812 if (expression == null) continue;
813
814 JetType expectedType = getEffectiveExpectedType(parameterDescriptor, argument);
815 if (TypeUtils.dependsOnTypeParameters(expectedType, candidateCall.getCandidateDescriptor().getTypeParameters())) {
816 expectedType = NO_EXPECTED_TYPE;
817 }
818
819 CallResolutionContext<?> newContext = context.replaceDataFlowInfo(infoForArguments.getInfo(argument))
820 .replaceBindingTrace(trace).replaceExpectedType(expectedType);
821 JetTypeInfo typeInfoForCall = argumentTypeResolver.getArgumentTypeInfo(
822 expression, newContext, resolveFunctionArgumentBodies);
823 JetType type = typeInfoForCall.getType();
824 infoForArguments.updateInfo(argument, typeInfoForCall.getDataFlowInfo());
825
826 boolean hasTypeMismatch = false;
827 if (type == null || (type.isError() && type != PLACEHOLDER_FUNCTION_TYPE)) {
828 candidateCall.argumentHasNoType();
829 argumentTypes.add(type);
830 hasTypeMismatch = true;
831 }
832 else {
833 JetType resultingType;
834 if (noExpectedType(expectedType) || ArgumentTypeResolver.isSubtypeOfForArgumentType(type, expectedType)) {
835 resultingType = type;
836 }
837 else {
838 resultingType = autocastValueArgumentTypeIfPossible(expression, expectedType, type, newContext);
839 if (resultingType == null) {
840 resultingType = type;
841 resultStatus = OTHER_ERROR;
842 hasTypeMismatch = true;
843 }
844 }
845
846 argumentTypes.add(resultingType);
847 }
848 candidateCall.recordArgumentMatch(argument, parameterDescriptor, hasTypeMismatch);
849 }
850 }
851 return new ValueArgumentsCheckingResult(resultStatus, argumentTypes);
852 }
853
854 @Nullable
855 private static JetType autocastValueArgumentTypeIfPossible(
856 @NotNull JetExpression expression,
857 @NotNull JetType expectedType,
858 @NotNull JetType actualType,
859 @NotNull ResolutionContext<?> context
860 ) {
861 ExpressionReceiver receiverToCast = new ExpressionReceiver(JetPsiUtil.safeDeparenthesize(expression, false), actualType);
862 List<JetType> variants =
863 AutoCastUtils.getAutoCastVariantsExcludingReceiver(context.trace.getBindingContext(), context.dataFlowInfo, receiverToCast);
864 for (JetType possibleType : variants) {
865 if (JetTypeChecker.INSTANCE.isSubtypeOf(possibleType, expectedType)) {
866 return possibleType;
867 }
868 }
869 return null;
870 }
871
872 private static <D extends CallableDescriptor> ResolutionStatus checkReceiverTypeError(
873 @NotNull CallCandidateResolutionContext<D> context
874 ) {
875 MutableResolvedCall<D> candidateCall = context.candidateCall;
876 D candidateDescriptor = candidateCall.getCandidateDescriptor();
877
878 ReceiverParameterDescriptor receiverDescriptor = candidateDescriptor.getReceiverParameter();
879 ReceiverParameterDescriptor expectedThisObjectDescriptor = candidateDescriptor.getExpectedThisObject();
880 ResolutionStatus status = SUCCESS;
881 // For the expressions like '42.(f)()' where f: String.() -> Unit we'd like to generate a type mismatch error on '1',
882 // not to throw away the candidate, so the following check is skipped.
883 if (!CallResolverUtil.isInvokeCallOnExpressionWithBothReceivers(context.call)) {
884 status = status.combine(checkReceiverTypeError(context, receiverDescriptor, candidateCall.getReceiverArgument()));
885 }
886 status = status.combine(checkReceiverTypeError(context, expectedThisObjectDescriptor, candidateCall.getThisObject()));
887 return status;
888 }
889
890 private static <D extends CallableDescriptor> ResolutionStatus checkReceiverTypeError(
891 @NotNull CallCandidateResolutionContext<D> context,
892 @Nullable ReceiverParameterDescriptor receiverParameterDescriptor,
893 @NotNull ReceiverValue receiverArgument
894 ) {
895 if (receiverParameterDescriptor == null || !receiverArgument.exists()) return SUCCESS;
896
897 D candidateDescriptor = context.candidateCall.getCandidateDescriptor();
898
899 JetType erasedReceiverType = CallResolverUtil.getErasedReceiverType(receiverParameterDescriptor, candidateDescriptor);
900
901 boolean isSubtypeByAutoCast = AutoCastUtils.isSubTypeByAutoCastIgnoringNullability(receiverArgument, erasedReceiverType, context);
902 if (!isSubtypeByAutoCast) {
903 return RECEIVER_TYPE_ERROR;
904 }
905
906 return SUCCESS;
907 }
908
909 private static <D extends CallableDescriptor> ResolutionStatus checkReceiver(
910 @NotNull CallCandidateResolutionContext<D> context,
911 @NotNull ResolvedCall<D> candidateCall,
912 @NotNull BindingTrace trace,
913 @Nullable ReceiverParameterDescriptor receiverParameter,
914 @NotNull ReceiverValue receiverArgument,
915 boolean isExplicitReceiver,
916 boolean implicitInvokeCheck
917 ) {
918 if (receiverParameter == null || !receiverArgument.exists()) return SUCCESS;
919 D candidateDescriptor = candidateCall.getCandidateDescriptor();
920 if (TypeUtils.dependsOnTypeParameters(receiverParameter.getType(), candidateDescriptor.getTypeParameters())) return SUCCESS;
921
922 boolean safeAccess = isExplicitReceiver && !implicitInvokeCheck && candidateCall.isSafeCall();
923 boolean isSubtypeByAutoCast = AutoCastUtils.isSubTypeByAutoCastIgnoringNullability(
924 receiverArgument, receiverParameter.getType(), context);
925 if (!isSubtypeByAutoCast) {
926 context.tracing.wrongReceiverType(trace, receiverParameter, receiverArgument);
927 return OTHER_ERROR;
928 }
929 AutoCastUtils.recordAutoCastIfNecessary(receiverArgument, receiverParameter.getType(), context, safeAccess);
930
931 JetType receiverArgumentType = receiverArgument.getType();
932
933 BindingContext bindingContext = trace.getBindingContext();
934 if (!safeAccess && !receiverParameter.getType().isNullable() && receiverArgumentType.isNullable()) {
935 if (!AutoCastUtils.isNotNull(receiverArgument, bindingContext, context.dataFlowInfo)) {
936
937 context.tracing.unsafeCall(trace, receiverArgumentType, implicitInvokeCheck);
938 return UNSAFE_CALL_ERROR;
939 }
940 }
941 DataFlowValue receiverValue = DataFlowValueFactory.createDataFlowValue(receiverArgument, bindingContext);
942 if (safeAccess && !context.dataFlowInfo.getNullability(receiverValue).canBeNull()) {
943 context.tracing.unnecessarySafeCall(trace, receiverArgumentType);
944 }
945 return SUCCESS;
946 }
947
948 private static class ValueArgumentsCheckingResult {
949
950 public final List<JetType> argumentTypes;
951 public final ResolutionStatus status;
952
953 private ValueArgumentsCheckingResult(@NotNull ResolutionStatus status, @NotNull List<JetType> argumentTypes) {
954 this.status = status;
955 this.argumentTypes = argumentTypes;
956 }
957 }
958
959 @NotNull
960 private static JetType getEffectiveExpectedType(ValueParameterDescriptor parameterDescriptor, ValueArgument argument) {
961 if (argument.getSpreadElement() != null) {
962 if (parameterDescriptor.getVarargElementType() == null) {
963 // Spread argument passed to a non-vararg parameter, an error is already reported by ValueArgumentsToParametersMapper
964 return DONT_CARE;
965 }
966 else {
967 return parameterDescriptor.getType();
968 }
969 }
970 else {
971 JetType varargElementType = parameterDescriptor.getVarargElementType();
972 if (varargElementType != null) {
973 return varargElementType;
974 }
975
976 return parameterDescriptor.getType();
977 }
978 }
979
980 private static void checkGenericBoundsInAFunctionCall(
981 @NotNull List<JetTypeProjection> jetTypeArguments,
982 @NotNull List<JetType> typeArguments,
983 @NotNull CallableDescriptor functionDescriptor,
984 @NotNull BindingTrace trace) {
985 Map<TypeConstructor, TypeProjection> context = Maps.newHashMap();
986
987 List<TypeParameterDescriptor> typeParameters = functionDescriptor.getOriginal().getTypeParameters();
988 for (int i = 0, typeParametersSize = typeParameters.size(); i < typeParametersSize; i++) {
989 TypeParameterDescriptor typeParameter = typeParameters.get(i);
990 JetType typeArgument = typeArguments.get(i);
991 context.put(typeParameter.getTypeConstructor(), new TypeProjectionImpl(typeArgument));
992 }
993 TypeSubstitutor substitutor = TypeSubstitutor.create(context);
994 for (int i = 0, typeParametersSize = typeParameters.size(); i < typeParametersSize; i++) {
995 TypeParameterDescriptor typeParameterDescriptor = typeParameters.get(i);
996 JetType typeArgument = typeArguments.get(i);
997 JetTypeReference typeReference = jetTypeArguments.get(i).getTypeReference();
998 if (typeReference != null) {
999 DescriptorResolver.checkBounds(typeReference, typeArgument, typeParameterDescriptor, substitutor, trace);
1000 }
1001 }
1002 }
1003 }