001    /*
002     * Copyright 2010-2015 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.kotlin.types.expressions;
018    
019    import com.google.common.collect.ImmutableMap;
020    import com.google.common.collect.Lists;
021    import com.google.common.collect.Maps;
022    import com.intellij.lang.ASTNode;
023    import com.intellij.openapi.diagnostic.Logger;
024    import com.intellij.openapi.util.Ref;
025    import com.intellij.psi.util.PsiTreeUtil;
026    import org.jetbrains.annotations.NotNull;
027    import org.jetbrains.annotations.Nullable;
028    import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
029    import org.jetbrains.kotlin.descriptors.*;
030    import org.jetbrains.kotlin.descriptors.annotations.Annotations;
031    import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl;
032    import org.jetbrains.kotlin.descriptors.impl.TypeParameterDescriptorImpl;
033    import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl;
034    import org.jetbrains.kotlin.lexer.KtTokens;
035    import org.jetbrains.kotlin.name.Name;
036    import org.jetbrains.kotlin.psi.*;
037    import org.jetbrains.kotlin.resolve.BindingContextUtils;
038    import org.jetbrains.kotlin.resolve.BindingTrace;
039    import org.jetbrains.kotlin.resolve.calls.CallResolver;
040    import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext;
041    import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystem;
042    import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemStatus;
043    import org.jetbrains.kotlin.resolve.calls.inference.ConstraintsUtil;
044    import org.jetbrains.kotlin.resolve.calls.inference.InferenceErrorData;
045    import org.jetbrains.kotlin.resolve.calls.model.MutableDataFlowInfoForArguments;
046    import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
047    import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResults;
048    import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo;
049    import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind;
050    import org.jetbrains.kotlin.resolve.calls.tasks.ResolutionCandidate;
051    import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategy;
052    import org.jetbrains.kotlin.resolve.calls.util.CallMaker;
053    import org.jetbrains.kotlin.resolve.descriptorUtil.AnnotationsForResolveKt;
054    import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
055    import org.jetbrains.kotlin.types.*;
056    import org.jetbrains.kotlin.types.typeUtil.TypeUtilsKt;
057    
058    import java.util.*;
059    
060    import static org.jetbrains.kotlin.diagnostics.Errors.TYPE_INFERENCE_FAILED_ON_SPECIAL_CONSTRUCT;
061    import static org.jetbrains.kotlin.resolve.BindingContext.CALL;
062    import static org.jetbrains.kotlin.resolve.BindingContext.RESOLVED_CALL;
063    import static org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.EXPECTED_TYPE_POSITION;
064    
065    public class ControlStructureTypingUtils {
066        private static final Logger LOG = Logger.getInstance(ControlStructureTypingUtils.class);
067    
068        public enum ResolveConstruct {
069            IF("if"), ELVIS("elvis"), EXCL_EXCL("ExclExcl"), WHEN("when");
070    
071            private final String name;
072    
073            ResolveConstruct(String name) {
074                this.name = name;
075            }
076    
077            public String getName() {
078                return name;
079            }
080        }
081    
082        private final CallResolver callResolver;
083        private final DataFlowAnalyzer dataFlowAnalyzer;
084        private final ModuleDescriptor moduleDescriptor;
085    
086        public ControlStructureTypingUtils(
087                @NotNull CallResolver callResolver,
088                @NotNull DataFlowAnalyzer dataFlowAnalyzer,
089                @NotNull ModuleDescriptor moduleDescriptor
090        ) {
091            this.callResolver = callResolver;
092            this.dataFlowAnalyzer = dataFlowAnalyzer;
093            this.moduleDescriptor = moduleDescriptor;
094        }
095    
096        /*package*/ ResolvedCall<FunctionDescriptor> resolveSpecialConstructionAsCall(
097                @NotNull Call call,
098                @NotNull ResolveConstruct construct,
099                @NotNull List<String> argumentNames,
100                @NotNull List<Boolean> isArgumentNullable,
101                @NotNull ExpressionTypingContext context,
102                @Nullable MutableDataFlowInfoForArguments dataFlowInfoForArguments
103        ) {
104            SimpleFunctionDescriptorImpl function = createFunctionDescriptorForSpecialConstruction(
105                    construct, argumentNames, isArgumentNullable);
106            TracingStrategy tracing = createTracingForSpecialConstruction(call, construct.getName(), context);
107            TypeSubstitutor knownTypeParameterSubstitutor = createKnownTypeParameterSubstitutorForSpecialCall(construct, function, context.expectedType);
108            ResolutionCandidate<CallableDescriptor> resolutionCandidate =
109                    ResolutionCandidate.<CallableDescriptor>create(call, function, knownTypeParameterSubstitutor);
110            OverloadResolutionResults<FunctionDescriptor> results = callResolver.resolveCallWithKnownCandidate(
111                    call, tracing, context, resolutionCandidate, dataFlowInfoForArguments);
112            assert results.isSingleResult() : "Not single result after resolving one known candidate";
113            return results.getResultingCall();
114        }
115    
116        private static @Nullable TypeSubstitutor createKnownTypeParameterSubstitutorForSpecialCall(
117                @NotNull ResolveConstruct construct,
118                @NotNull SimpleFunctionDescriptorImpl function,
119                @NotNull KotlinType expectedType
120        ) {
121            if (construct == ResolveConstruct.ELVIS
122                || TypeUtils.noExpectedType(expectedType)
123                || TypeUtils.isDontCarePlaceholder(expectedType)
124                || KotlinBuiltIns.isUnitOrNullableUnit(expectedType)
125                || KotlinBuiltIns.isAnyOrNullableAny(expectedType)
126                    ) {
127                return null;
128            }
129    
130            TypeConstructor typeParameterConstructor = function.getTypeParameters().get(0).getTypeConstructor();
131            TypeProjection typeProjection = new TypeProjectionImpl(expectedType);
132            return TypeSubstitutor.create(ImmutableMap.of(typeParameterConstructor, typeProjection));
133        }
134    
135        private SimpleFunctionDescriptorImpl createFunctionDescriptorForSpecialConstruction(
136                @NotNull ResolveConstruct construct,
137                @NotNull List<String> argumentNames,
138                @NotNull List<Boolean> isArgumentNullable
139        ) {
140            assert argumentNames.size() == isArgumentNullable.size();
141    
142            String constructionName = construct.getName().toUpperCase();
143            Name specialFunctionName = Name.identifier("<SPECIAL-FUNCTION-FOR-" + constructionName + "-RESOLVE>");
144    
145            SimpleFunctionDescriptorImpl function = SimpleFunctionDescriptorImpl.create(
146                    moduleDescriptor, Annotations.Companion.getEMPTY(), specialFunctionName, CallableMemberDescriptor.Kind.DECLARATION, SourceElement.NO_SOURCE
147            );
148    
149            TypeParameterDescriptor typeParameter = TypeParameterDescriptorImpl.createWithDefaultBound(
150                    function, Annotations.Companion.getEMPTY(), false, Variance.INVARIANT,
151                    Name.identifier("<TYPE-PARAMETER-FOR-" + constructionName + "-RESOLVE>"), 0);
152    
153            KotlinType type = typeParameter.getDefaultType();
154            KotlinType nullableType = TypeUtils.makeNullable(type);
155    
156            List<ValueParameterDescriptor> valueParameters = new ArrayList<ValueParameterDescriptor>(argumentNames.size());
157            for (int i = 0; i < argumentNames.size(); i++) {
158                KotlinType argumentType = isArgumentNullable.get(i) ? nullableType : type;
159                ValueParameterDescriptorImpl valueParameter = new ValueParameterDescriptorImpl(
160                        function, null, i, Annotations.Companion.getEMPTY(), Name.identifier(argumentNames.get(i)),
161                        argumentType,
162                        /* declaresDefaultValue = */ false,
163                        /* isCrossinline = */ false,
164                        /* isNoinline = */ false,
165                        null, SourceElement.NO_SOURCE
166                );
167                valueParameters.add(valueParameter);
168            }
169            KotlinType returnType = construct != ResolveConstruct.ELVIS ? type : TypeUtilsKt.replaceAnnotations(type, AnnotationsForResolveKt.getExactInAnnotations());
170            function.initialize(
171                    null,
172                    null,
173                    Lists.newArrayList(typeParameter),
174                    valueParameters,
175                    returnType,
176                    Modality.FINAL,
177                    Visibilities.PUBLIC
178            );
179            return function;
180        }
181    
182        /*package*/ static MutableDataFlowInfoForArguments createIndependentDataFlowInfoForArgumentsForCall(
183                @NotNull DataFlowInfo initialDataFlowInfo,
184                final Map<ValueArgument, DataFlowInfo> dataFlowInfoForArgumentsMap
185        ) {
186            return new MutableDataFlowInfoForArguments(initialDataFlowInfo) {
187    
188                @Override
189                public void updateInfo(@NotNull ValueArgument valueArgument, @NotNull DataFlowInfo dataFlowInfo) {
190                    dataFlowInfoForArgumentsMap.put(valueArgument, dataFlowInfo);
191                }
192    
193                @NotNull
194                @Override
195                public DataFlowInfo getInfo(@NotNull ValueArgument valueArgument) {
196                    return dataFlowInfoForArgumentsMap.get(valueArgument);
197                }
198            };
199        }
200    
201        public static MutableDataFlowInfoForArguments createDataFlowInfoForArgumentsForIfCall(
202                @NotNull Call callForIf,
203                @NotNull DataFlowInfo conditionInfo,
204                @NotNull DataFlowInfo thenInfo,
205                @NotNull DataFlowInfo elseInfo
206        ) {
207            Map<ValueArgument, DataFlowInfo> dataFlowInfoForArgumentsMap = Maps.newHashMap();
208            dataFlowInfoForArgumentsMap.put(callForIf.getValueArguments().get(0), thenInfo);
209            dataFlowInfoForArgumentsMap.put(callForIf.getValueArguments().get(1), elseInfo);
210            return createIndependentDataFlowInfoForArgumentsForCall(conditionInfo, dataFlowInfoForArgumentsMap);
211        }
212    
213        public static MutableDataFlowInfoForArguments createDataFlowInfoForArgumentsOfWhenCall(
214                @NotNull Call callForWhen,
215                @NotNull DataFlowInfo subjectDataFlowInfo,
216                @NotNull List<DataFlowInfo> entryDataFlowInfos
217        ) {
218            Map<ValueArgument, DataFlowInfo> dataFlowInfoForArgumentsMap = Maps.newHashMap();
219            int i = 0;
220            for (ValueArgument argument : callForWhen.getValueArguments()) {
221                DataFlowInfo entryDataFlowInfo = entryDataFlowInfos.get(i++);
222                dataFlowInfoForArgumentsMap.put(argument, entryDataFlowInfo);
223            }
224            return createIndependentDataFlowInfoForArgumentsForCall(subjectDataFlowInfo, dataFlowInfoForArgumentsMap);
225        }
226    
227        /*package*/ static Call createCallForSpecialConstruction(
228                @NotNull final KtExpression expression,
229                @NotNull final KtExpression calleeExpression,
230                @NotNull List<? extends KtExpression> arguments
231        ) {
232            final List<ValueArgument> valueArguments = Lists.newArrayList();
233            for (KtExpression argument : arguments) {
234                valueArguments.add(CallMaker.makeValueArgument(argument));
235            }
236            return new Call() {
237                @Nullable
238                @Override
239                public ASTNode getCallOperationNode() {
240                    return expression.getNode();
241                }
242    
243                @Nullable
244                @Override
245                public ReceiverValue getExplicitReceiver() {
246                    return null;
247                }
248    
249                @Nullable
250                @Override
251                public ReceiverValue getDispatchReceiver() {
252                    return null;
253                }
254    
255                @Nullable
256                @Override
257                public KtExpression getCalleeExpression() {
258                    return calleeExpression;
259                }
260    
261                @Nullable
262                @Override
263                public KtValueArgumentList getValueArgumentList() {
264                    return null;
265                }
266    
267                @NotNull
268                @Override
269                public List<? extends ValueArgument> getValueArguments() {
270                    return valueArguments;
271                }
272    
273                @NotNull
274                @Override
275                public List<LambdaArgument> getFunctionLiteralArguments() {
276                    return Collections.emptyList();
277                }
278    
279                @NotNull
280                @Override
281                public List<KtTypeProjection> getTypeArguments() {
282                    return Collections.emptyList();
283                }
284    
285                @Nullable
286                @Override
287                public KtTypeArgumentList getTypeArgumentList() {
288                    return null;
289                }
290    
291                @NotNull
292                @Override
293                public KtElement getCallElement() {
294                    return expression;
295                }
296    
297                @NotNull
298                @Override
299                public CallType getCallType() {
300                    return CallType.DEFAULT;
301                }
302            };
303        }
304    
305        @NotNull
306        /*package*/ TracingStrategy createTracingForSpecialConstruction(
307                final @NotNull Call call,
308                @NotNull String constructionName,
309                final @NotNull ExpressionTypingContext context
310        ) {
311            class CheckTypeContext {
312                public BindingTrace trace;
313                public KotlinType expectedType;
314    
315                CheckTypeContext(@NotNull BindingTrace trace, @NotNull KotlinType expectedType) {
316                    this.trace = trace;
317                    this.expectedType = expectedType;
318                }
319    
320                CheckTypeContext makeTypeNullable() {
321                    if (TypeUtils.noExpectedType(expectedType)) return this;
322                    return new CheckTypeContext(trace, TypeUtils.makeNullable(expectedType));
323                }
324            }
325    
326            final KtVisitor<Boolean, CheckTypeContext> checkTypeVisitor = new KtVisitor<Boolean, CheckTypeContext>() {
327    
328                private boolean checkExpressionType(@NotNull KtExpression expression, CheckTypeContext c) {
329                    KotlinTypeInfo typeInfo = BindingContextUtils.getRecordedTypeInfo(expression, c.trace.getBindingContext());
330                    if (typeInfo == null) return false;
331    
332                    Ref<Boolean> hasError = Ref.create();
333                    dataFlowAnalyzer.checkType(
334                            typeInfo.getType(),
335                            expression,
336                            context
337                                    .replaceExpectedType(c.expectedType)
338                                    .replaceDataFlowInfo(typeInfo.getDataFlowInfo())
339                                    .replaceBindingTrace(c.trace),
340                            hasError
341                    );
342                    return hasError.get();
343                }
344    
345                private boolean checkExpressionTypeRecursively(@Nullable KtExpression expression, CheckTypeContext c) {
346                    if (expression == null) return false;
347                    return expression.accept(this, c);
348                }
349    
350                private boolean checkSubExpressions(
351                        KtExpression firstSub, KtExpression secondSub, KtExpression expression,
352                        CheckTypeContext firstContext, CheckTypeContext secondContext, CheckTypeContext context
353                ) {
354                    boolean errorWasReported = checkExpressionTypeRecursively(firstSub, firstContext);
355                    errorWasReported |= checkExpressionTypeRecursively(secondSub, secondContext);
356                    return errorWasReported || checkExpressionType(expression, context);
357                }
358    
359                @Override
360                public Boolean visitWhenExpression(@NotNull KtWhenExpression whenExpression, CheckTypeContext c) {
361                    boolean errorWasReported = false;
362                    for (KtWhenEntry whenEntry : whenExpression.getEntries()) {
363                        KtExpression entryExpression = whenEntry.getExpression();
364                        if (entryExpression != null) {
365                            errorWasReported |= checkExpressionTypeRecursively(entryExpression, c);
366                        }
367                    }
368                    errorWasReported |= checkExpressionType(whenExpression, c);
369                    return errorWasReported;
370                }
371    
372                @Override
373                public Boolean visitIfExpression(@NotNull KtIfExpression ifExpression, CheckTypeContext c) {
374                    KtExpression thenBranch = ifExpression.getThen();
375                    KtExpression elseBranch = ifExpression.getElse();
376                    if (thenBranch == null || elseBranch == null) {
377                        return checkExpressionType(ifExpression, c);
378                    }
379                    return checkSubExpressions(thenBranch, elseBranch, ifExpression, c, c, c);
380                }
381    
382                @Override
383                public Boolean visitBlockExpression(@NotNull KtBlockExpression expression, CheckTypeContext c) {
384                    if (expression.getStatements().isEmpty()) {
385                        return checkExpressionType(expression, c);
386                    }
387                    KtExpression lastStatement = KtPsiUtil.getLastStatementInABlock(expression);
388                    if (lastStatement != null) {
389                        return checkExpressionTypeRecursively(lastStatement, c);
390                    }
391                    return false;
392                }
393    
394                @Override
395                public Boolean visitPostfixExpression(@NotNull KtPostfixExpression expression, CheckTypeContext c) {
396                    if (expression.getOperationReference().getReferencedNameElementType() == KtTokens.EXCLEXCL) {
397                        return checkExpressionTypeRecursively(expression.getBaseExpression(), c.makeTypeNullable());
398                    }
399                    return super.visitPostfixExpression(expression, c);
400                }
401    
402                @Override
403                public Boolean visitBinaryExpression(@NotNull KtBinaryExpression expression, CheckTypeContext c) {
404                    if (expression.getOperationReference().getReferencedNameElementType() == KtTokens.ELVIS) {
405    
406                        return checkSubExpressions(expression.getLeft(), expression.getRight(), expression, c.makeTypeNullable(), c, c);
407                    }
408                    return super.visitBinaryExpression(expression, c);
409                }
410    
411                @Override
412                public Boolean visitExpression(@NotNull KtExpression expression, CheckTypeContext c) {
413                    return checkExpressionType(expression, c);
414                }
415            };
416    
417            return new ThrowingOnErrorTracingStrategy("resolve " + constructionName + " as a call") {
418                @Override
419                public <D extends CallableDescriptor> void bindReference(
420                        @NotNull BindingTrace trace, @NotNull ResolvedCall<D> resolvedCall
421                ) {
422                    //do nothing
423                }
424    
425                @Override
426                public void bindCall(@NotNull BindingTrace trace, @NotNull Call call) {
427                    trace.record(CALL, call.getCalleeExpression(), call);
428                }
429    
430                @Override
431                public <D extends CallableDescriptor> void bindResolvedCall(
432                        @NotNull BindingTrace trace, @NotNull ResolvedCall<D> resolvedCall
433                ) {
434                    trace.record(RESOLVED_CALL, call, resolvedCall);
435                }
436    
437                @Override
438                public void typeInferenceFailed(
439                        @NotNull ResolutionContext<?> context, @NotNull InferenceErrorData data
440                ) {
441                    ConstraintSystem constraintSystem = data.constraintSystem;
442                    ConstraintSystemStatus status = constraintSystem.getStatus();
443                    assert !status.isSuccessful() : "Report error only for not successful constraint system";
444    
445                    if (status.hasErrorInConstrainingTypes() || status.hasUnknownParameters()) {
446                        return;
447                    }
448                    KtExpression expression = (KtExpression) call.getCallElement();
449                    if (status.hasOnlyErrorsDerivedFrom(EXPECTED_TYPE_POSITION) || status.hasConflictingConstraints()
450                            || status.hasTypeInferenceIncorporationError()) { // todo after KT-... remove this line
451                        if (Boolean.TRUE != expression.accept(checkTypeVisitor, new CheckTypeContext(context.trace, data.expectedType))) {
452                            KtExpression calleeExpression = call.getCalleeExpression();
453                            if (calleeExpression instanceof KtWhenExpression || calleeExpression instanceof KtIfExpression) {
454                                if (status.hasConflictingConstraints() || status.hasTypeInferenceIncorporationError()) {
455                                    // TODO provide comprehensible error report for hasConflictingConstraints() case (if possible)
456                                    context.trace.report(TYPE_INFERENCE_FAILED_ON_SPECIAL_CONSTRUCT.on(expression));
457                                }
458                            }
459                        }
460                        return;
461                    }
462                    KtDeclaration parentDeclaration = PsiTreeUtil.getParentOfType(expression, KtNamedDeclaration.class);
463                    logError("Expression: " + (parentDeclaration != null ? parentDeclaration.getText() : expression.getText()) +
464                             "\nConstraint system status: \n" + ConstraintsUtil.getDebugMessageForStatus(status));
465                }
466            };
467        }
468        
469        private abstract static class ThrowingOnErrorTracingStrategy implements TracingStrategy {
470            private final String debugName;
471    
472            protected ThrowingOnErrorTracingStrategy(String debugName) {
473                this.debugName = debugName;
474            }
475    
476            private void logError() {
477                logError(null);
478            }
479    
480            protected void logError(@Nullable String additionalInformation) {
481                String errorMessage = "Resolution error of this type shouldn't occur for " + debugName;
482                if (additionalInformation != null) {
483                    errorMessage += ".\n" + additionalInformation;
484                }
485                LOG.error(errorMessage);
486            }
487    
488            @Override
489            public void unresolvedReference(@NotNull BindingTrace trace) {
490                logError();
491            }
492    
493            @Override
494            public <D extends CallableDescriptor> void unresolvedReferenceWrongReceiver(
495                    @NotNull BindingTrace trace, @NotNull Collection<? extends ResolvedCall<D>> candidates
496            ) {
497                logError();
498            }
499    
500            @Override
501            public <D extends CallableDescriptor> void recordAmbiguity(
502                    @NotNull BindingTrace trace, @NotNull Collection<? extends ResolvedCall<D>> candidates
503            ) {
504                logError();
505            }
506    
507            @Override
508            public void missingReceiver(
509                    @NotNull BindingTrace trace, @NotNull ReceiverParameterDescriptor expectedReceiver
510            ) {
511                logError();
512            }
513    
514            @Override
515            public void wrongReceiverType(
516                    @NotNull BindingTrace trace,
517                    @NotNull ReceiverParameterDescriptor receiverParameter,
518                    @NotNull ReceiverValue receiverArgument,
519                    @NotNull ResolutionContext<?> c
520            ) {
521                logError();
522            }
523    
524            @Override
525            public void noReceiverAllowed(@NotNull BindingTrace trace) {
526                logError();
527            }
528    
529            @Override
530            public void noValueForParameter(
531                    @NotNull BindingTrace trace, @NotNull ValueParameterDescriptor valueParameter
532            ) {
533                logError();
534            }
535    
536            @Override
537            public void wrongNumberOfTypeArguments(@NotNull BindingTrace trace, int expectedTypeArgumentCount) {
538                logError();
539            }
540    
541            @Override
542            public <D extends CallableDescriptor> void ambiguity(
543                    @NotNull BindingTrace trace, @NotNull Collection<? extends ResolvedCall<D>> descriptors
544            ) {
545                logError();
546            }
547    
548            @Override
549            public <D extends CallableDescriptor> void noneApplicable(
550                    @NotNull BindingTrace trace, @NotNull Collection<? extends ResolvedCall<D>> descriptors
551            ) {
552                logError();
553            }
554    
555            @Override
556            public <D extends CallableDescriptor> void cannotCompleteResolve(
557                    @NotNull BindingTrace trace, @NotNull Collection<? extends ResolvedCall<D>> descriptors
558            ) {
559                logError();
560            }
561    
562            @Override
563            public void instantiationOfAbstractClass(@NotNull BindingTrace trace) {
564                logError();
565            }
566    
567            @Override
568            public void abstractSuperCall(@NotNull BindingTrace trace) {
569                logError();
570            }
571    
572            @Override
573            public void nestedClassAccessViaInstanceReference(
574                    @NotNull BindingTrace trace, @NotNull ClassDescriptor classDescriptor,
575                    @NotNull ExplicitReceiverKind explicitReceiverKind
576            ) {
577                logError();
578            }
579    
580            @Override
581            public void unsafeCall(
582                    @NotNull BindingTrace trace, @NotNull KotlinType type, boolean isCallForImplicitInvoke
583            ) {
584                logError();
585            }
586    
587            @Override
588            public void invisibleMember(
589                    @NotNull BindingTrace trace, @NotNull DeclarationDescriptorWithVisibility descriptor
590            ) {
591                logError();
592            }
593    
594            @Override
595            public void typeInferenceFailed(
596                    @NotNull ResolutionContext<?> context, @NotNull InferenceErrorData inferenceErrorData
597            ) {
598                logError();
599            }
600    
601            @Override
602            public void nonExtensionFunctionCalledAsExtension(@NotNull BindingTrace trace) {
603                logError();
604            }
605        }
606    }