|
32 | 32 | import org.jetbrains.kotlin.descriptors.annotations.Annotations;
|
33 | 33 | import org.jetbrains.kotlin.diagnostics.Diagnostic;
|
34 | 34 | import org.jetbrains.kotlin.diagnostics.Errors;
|
| 35 | +import org.jetbrains.kotlin.diagnostics.Severity; |
35 | 36 | import org.jetbrains.kotlin.lexer.KtKeywordToken;
|
36 | 37 | import org.jetbrains.kotlin.lexer.KtTokens;
|
37 | 38 | import org.jetbrains.kotlin.name.Name;
|
|
41 | 42 | import org.jetbrains.kotlin.resolve.callableReferences.CallableReferencesResolutionUtilsKt;
|
42 | 43 | import org.jetbrains.kotlin.resolve.calls.ArgumentTypeResolver;
|
43 | 44 | import org.jetbrains.kotlin.resolve.calls.CallExpressionResolver;
|
| 45 | +import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilKt; |
44 | 46 | import org.jetbrains.kotlin.resolve.calls.checkers.CallChecker;
|
45 | 47 | import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext;
|
46 | 48 | import org.jetbrains.kotlin.resolve.calls.context.CheckArgumentTypesMode;
|
| 49 | +import org.jetbrains.kotlin.resolve.calls.context.TemporaryTraceAndCache; |
47 | 50 | import org.jetbrains.kotlin.resolve.calls.model.DataFlowInfoForArgumentsImpl;
|
48 | 51 | import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
49 | 52 | import org.jetbrains.kotlin.resolve.calls.model.ResolvedCallImpl;
|
|
58 | 61 | import org.jetbrains.kotlin.resolve.calls.tasks.ResolutionCandidate;
|
59 | 62 | import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategy;
|
60 | 63 | import org.jetbrains.kotlin.resolve.calls.util.CallMaker;
|
| 64 | +import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject; |
61 | 65 | import org.jetbrains.kotlin.resolve.constants.*;
|
62 | 66 | import org.jetbrains.kotlin.resolve.scopes.LexicalScopeKind;
|
63 | 67 | import org.jetbrains.kotlin.resolve.scopes.LexicalWritableScope;
|
@@ -711,10 +715,79 @@ public KotlinTypeInfo visitCallableReferenceExpression(@NotNull KtCallableRefere
|
711 | 715 | return components.dataFlowAnalyzer.createCheckedTypeInfo(errorType, c, expression);
|
712 | 716 | }
|
713 | 717 |
|
714 |
| - KotlinType result = getCallableReferenceType(expression, receiverType, c); |
| 718 | + TemporaryBindingTrace trace = TemporaryBindingTrace.create(c.trace, "Callable reference type"); |
| 719 | + KotlinType result = getCallableReferenceType(expression, receiverType, c.replaceBindingTrace(trace)); |
| 720 | + boolean hasErrors = hasErrors(trace); // Do not inline this local variable (execution order is important) |
| 721 | + trace.commit(); |
| 722 | + if (!hasErrors && result != null) { |
| 723 | + checkNoExpressionOnLHS(expression, c); |
| 724 | + } |
715 | 725 | return components.dataFlowAnalyzer.createCheckedTypeInfo(result, c, expression);
|
716 | 726 | }
|
717 | 727 |
|
| 728 | + private static boolean hasErrors(TemporaryBindingTrace trace) { |
| 729 | + for (Diagnostic diagnostic : trace.getBindingContext().getDiagnostics().all()) { |
| 730 | + if (diagnostic.getSeverity() == Severity.ERROR) { |
| 731 | + return true; |
| 732 | + } |
| 733 | + } |
| 734 | + return false; |
| 735 | + } |
| 736 | + |
| 737 | + private void checkNoExpressionOnLHS(@NotNull KtCallableReferenceExpression expression, @NotNull ExpressionTypingContext c) { |
| 738 | + KtTypeReference typeReference = expression.getTypeReference(); |
| 739 | + if (typeReference == null) return; |
| 740 | + KtTypeElement typeElement = typeReference.getTypeElement(); |
| 741 | + if (!(typeElement instanceof KtUserType)) return; |
| 742 | + |
| 743 | + KtUserType userType = (KtUserType) typeElement; |
| 744 | + while (true) { |
| 745 | + if (userType.getTypeArgumentList() != null) return; |
| 746 | + KtUserType qualifier = userType.getQualifier(); |
| 747 | + if (qualifier == null) break; |
| 748 | + userType = qualifier; |
| 749 | + } |
| 750 | + |
| 751 | + KtSimpleNameExpression simpleNameExpression = userType.getReferenceExpression(); |
| 752 | + if (simpleNameExpression == null) return; |
| 753 | + |
| 754 | + TemporaryTraceAndCache traceAndCache = |
| 755 | + TemporaryTraceAndCache.create(c, "Resolve expression on LHS of callable reference", simpleNameExpression); |
| 756 | + OverloadResolutionResults<VariableDescriptor> resolutionResult = |
| 757 | + components.callExpressionResolver.resolveSimpleName(c.replaceTraceAndCache(traceAndCache), simpleNameExpression); |
| 758 | + |
| 759 | + Collection<? extends ResolvedCall<VariableDescriptor>> resultingCalls = |
| 760 | + CollectionsKt.filter(resolutionResult.getResultingCalls(), new Function1<ResolvedCall<VariableDescriptor>, Boolean>() { |
| 761 | + @Override |
| 762 | + public Boolean invoke(ResolvedCall<VariableDescriptor> call) { |
| 763 | + return call.getStatus().possibleTransformToSuccess(); |
| 764 | + } |
| 765 | + }); |
| 766 | + |
| 767 | + if (resultingCalls.isEmpty()) return; |
| 768 | + |
| 769 | + if (resultingCalls.size() == 1 && |
| 770 | + resultingCalls.iterator().next().getResultingDescriptor() instanceof FakeCallableDescriptorForObject) return; |
| 771 | + |
| 772 | + ResolvedCall<?> originalResolvedCall = CallUtilKt.getResolvedCall(expression.getCallableReference(), c.trace.getBindingContext()); |
| 773 | + CallableDescriptor originalResult = originalResolvedCall == null ? null : originalResolvedCall.getResultingDescriptor(); |
| 774 | + |
| 775 | + throw new AssertionError(String.format( |
| 776 | + "Expressions on left-hand side of callable reference are not supported yet.\n" + |
| 777 | + "Resolution result: %s\n" + |
| 778 | + "Original result: %s", |
| 779 | + CollectionsKt.map( |
| 780 | + resultingCalls, new Function1<ResolvedCall<VariableDescriptor>, VariableDescriptor>() { |
| 781 | + @Override |
| 782 | + public VariableDescriptor invoke(ResolvedCall<VariableDescriptor> call) { |
| 783 | + return call.getResultingDescriptor(); |
| 784 | + } |
| 785 | + } |
| 786 | + ), |
| 787 | + originalResult |
| 788 | + )); |
| 789 | + } |
| 790 | + |
718 | 791 | @Override
|
719 | 792 | public KotlinTypeInfo visitObjectLiteralExpression(
|
720 | 793 | @NotNull final KtObjectLiteralExpression expression,
|
|
0 commit comments