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.Lists;
020    import com.intellij.openapi.util.Ref;
021    import com.intellij.psi.PsiElement;
022    import com.intellij.psi.tree.IElementType;
023    import com.intellij.psi.tree.TokenSet;
024    import com.intellij.psi.util.PsiTreeUtil;
025    import kotlin.collections.CollectionsKt;
026    import kotlin.jvm.functions.Function0;
027    import kotlin.jvm.functions.Function1;
028    import org.jetbrains.annotations.NotNull;
029    import org.jetbrains.annotations.Nullable;
030    import org.jetbrains.kotlin.KtNodeTypes;
031    import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
032    import org.jetbrains.kotlin.descriptors.*;
033    import org.jetbrains.kotlin.descriptors.annotations.Annotations;
034    import org.jetbrains.kotlin.diagnostics.Diagnostic;
035    import org.jetbrains.kotlin.diagnostics.DiagnosticUtilsKt;
036    import org.jetbrains.kotlin.diagnostics.Errors;
037    import org.jetbrains.kotlin.lexer.KtKeywordToken;
038    import org.jetbrains.kotlin.lexer.KtTokens;
039    import org.jetbrains.kotlin.name.Name;
040    import org.jetbrains.kotlin.psi.*;
041    import org.jetbrains.kotlin.resolve.*;
042    import org.jetbrains.kotlin.resolve.bindingContextUtil.BindingContextUtilsKt;
043    import org.jetbrains.kotlin.resolve.callableReferences.CallableReferencesResolutionUtilsKt;
044    import org.jetbrains.kotlin.resolve.calls.ArgumentTypeResolver;
045    import org.jetbrains.kotlin.resolve.calls.CallExpressionResolver;
046    import org.jetbrains.kotlin.resolve.calls.checkers.CallChecker;
047    import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext;
048    import org.jetbrains.kotlin.resolve.calls.context.CheckArgumentTypesMode;
049    import org.jetbrains.kotlin.resolve.calls.model.DataFlowInfoForArgumentsImpl;
050    import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
051    import org.jetbrains.kotlin.resolve.calls.model.ResolvedCallImpl;
052    import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResults;
053    import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResultsImpl;
054    import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResultsUtil;
055    import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo;
056    import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValue;
057    import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory;
058    import org.jetbrains.kotlin.resolve.calls.smartcasts.Nullability;
059    import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind;
060    import org.jetbrains.kotlin.resolve.calls.tasks.ResolutionCandidate;
061    import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategy;
062    import org.jetbrains.kotlin.resolve.calls.util.CallMaker;
063    import org.jetbrains.kotlin.resolve.constants.*;
064    import org.jetbrains.kotlin.resolve.scopes.LexicalScopeKind;
065    import org.jetbrains.kotlin.resolve.scopes.LexicalWritableScope;
066    import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver;
067    import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
068    import org.jetbrains.kotlin.resolve.scopes.utils.ScopeUtilsKt;
069    import org.jetbrains.kotlin.types.*;
070    import org.jetbrains.kotlin.types.checker.KotlinTypeChecker;
071    import org.jetbrains.kotlin.types.expressions.ControlStructureTypingUtils.ResolveConstruct;
072    import org.jetbrains.kotlin.types.expressions.typeInfoFactory.TypeInfoFactoryKt;
073    import org.jetbrains.kotlin.types.expressions.unqualifiedSuper.UnqualifiedSuperKt;
074    import org.jetbrains.kotlin.util.OperatorNameConventions;
075    import org.jetbrains.kotlin.util.slicedMap.WritableSlice;
076    
077    import java.util.Collection;
078    import java.util.Collections;
079    import java.util.Iterator;
080    import java.util.List;
081    
082    import static org.jetbrains.kotlin.diagnostics.Errors.*;
083    import static org.jetbrains.kotlin.lexer.KtTokens.*;
084    import static org.jetbrains.kotlin.resolve.BindingContext.*;
085    import static org.jetbrains.kotlin.resolve.calls.context.ContextDependency.DEPENDENT;
086    import static org.jetbrains.kotlin.resolve.calls.context.ContextDependency.INDEPENDENT;
087    import static org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory.createDataFlowValue;
088    import static org.jetbrains.kotlin.types.TypeUtils.NO_EXPECTED_TYPE;
089    import static org.jetbrains.kotlin.types.TypeUtils.noExpectedType;
090    import static org.jetbrains.kotlin.types.expressions.ControlStructureTypingUtils.createCallForSpecialConstruction;
091    import static org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.*;
092    import static org.jetbrains.kotlin.types.expressions.TypeReconstructionUtil.reconstructBareType;
093    
094    @SuppressWarnings("SuspiciousMethodCalls")
095    public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
096    
097        private static final TokenSet BARE_TYPES_ALLOWED = TokenSet.create(AS_KEYWORD, AS_SAFE);
098    
099        protected BasicExpressionTypingVisitor(@NotNull ExpressionTypingInternals facade) {
100            super(facade);
101        }
102    
103        private static boolean isLValueOrUnsafeReceiver(@NotNull KtSimpleNameExpression expression) {
104            PsiElement parent = PsiTreeUtil.skipParentsOfType(expression, KtParenthesizedExpression.class);
105            if (parent instanceof KtQualifiedExpression) {
106                KtQualifiedExpression qualifiedExpression = (KtQualifiedExpression) parent;
107                // See KT-10175: receiver of unsafe call is always not-null at resolver
108                // so we have to analyze its nullability here
109                return qualifiedExpression.getOperationSign() == KtTokens.DOT &&
110                       qualifiedExpression.getReceiverExpression() == KtPsiUtil.deparenthesize(expression);
111            }
112            if (parent instanceof KtBinaryExpression) {
113                KtBinaryExpression binaryExpression = (KtBinaryExpression) parent;
114                if (!OperatorConventions.BINARY_OPERATION_NAMES.containsKey(binaryExpression.getOperationToken()) &&
115                    !KtTokens.ALL_ASSIGNMENTS.contains(binaryExpression.getOperationToken())) {
116                    return false;
117                }
118                return PsiTreeUtil.isAncestor(binaryExpression.getLeft(), expression, false);
119            }
120            return false;
121        }
122    
123        private static boolean isDangerousWithNull(@NotNull KtSimpleNameExpression expression, @NotNull ExpressionTypingContext context) {
124            PsiElement parent = PsiTreeUtil.skipParentsOfType(expression, KtParenthesizedExpression.class);
125            if (parent instanceof KtUnaryExpression) {
126                // Unary: !! only
127                KtUnaryExpression unaryExpression = (KtUnaryExpression) parent;
128                return unaryExpression.getOperationToken() == KtTokens.EXCLEXCL;
129            }
130            if (parent instanceof KtBinaryExpressionWithTypeRHS) {
131                // Binary: unsafe as only
132                KtBinaryExpressionWithTypeRHS binaryExpression = (KtBinaryExpressionWithTypeRHS) parent;
133                KotlinType type = context.trace.get(TYPE, binaryExpression.getRight());
134                return type != null && !type.isMarkedNullable() &&
135                       binaryExpression.getOperationReference().getReferencedNameElementType() == KtTokens.AS_KEYWORD;
136            }
137            return false;
138        }
139    
140        private static void checkNull(
141                @NotNull KtSimpleNameExpression expression,
142                @NotNull ExpressionTypingContext context,
143                @Nullable KotlinType type
144        ) {
145            // Receivers are normally analyzed at resolve, with an exception of KT-10175
146            if (type != null && !type.isError() && !isLValueOrUnsafeReceiver(expression)) {
147                DataFlowValue dataFlowValue = DataFlowValueFactory.createDataFlowValue(expression, type, context);
148                Nullability nullability = context.dataFlowInfo.getPredictableNullability(dataFlowValue);
149                if (!nullability.canBeNonNull() && nullability.canBeNull()) {
150                    if (isDangerousWithNull(expression, context)) {
151                        context.trace.report(ALWAYS_NULL.on(expression));
152                    }
153                    else {
154                        context.trace.record(SMARTCAST_NULL, expression);
155                    }
156                }
157            }
158        }
159    
160        @Override
161        public KotlinTypeInfo visitSimpleNameExpression(@NotNull KtSimpleNameExpression expression, ExpressionTypingContext context) {
162            // TODO : other members
163            // TODO : type substitutions???
164            CallExpressionResolver callExpressionResolver = components.callExpressionResolver;
165            KotlinTypeInfo typeInfo = callExpressionResolver.getSimpleNameExpressionTypeInfo(expression, null, null, context);
166            checkNull(expression, context, typeInfo.getType());
167    
168            return components.dataFlowAnalyzer.checkType(typeInfo, expression, context); // TODO : Extensions to this
169        }
170    
171        @Override
172        public KotlinTypeInfo visitParenthesizedExpression(@NotNull KtParenthesizedExpression expression, ExpressionTypingContext context) {
173            KtExpression innerExpression = expression.getExpression();
174            if (innerExpression == null) {
175                return TypeInfoFactoryKt.noTypeInfo(context);
176            }
177            KotlinTypeInfo result = facade.getTypeInfo(innerExpression, context.replaceScope(context.scope));
178            KotlinType resultType = result.getType();
179            if (resultType != null) {
180                DataFlowValue innerValue = DataFlowValueFactory.createDataFlowValue(innerExpression, resultType, context);
181                DataFlowValue resultValue = DataFlowValueFactory.createDataFlowValue(expression, resultType, context);
182                result = result.replaceDataFlowInfo(result.getDataFlowInfo().assign(resultValue, innerValue));
183            }
184            return result;
185        }
186    
187        @Override
188        public KotlinTypeInfo visitConstantExpression(@NotNull KtConstantExpression expression, ExpressionTypingContext context) {
189            IElementType elementType = expression.getNode().getElementType();
190            if (elementType == KtNodeTypes.CHARACTER_CONSTANT
191                || elementType == KtNodeTypes.INTEGER_CONSTANT
192                || elementType == KtNodeTypes.FLOAT_CONSTANT) {
193                checkLiteralPrefixAndSuffix(expression, context);
194            }
195    
196            CompileTimeConstant<?> compileTimeConstant = components.constantExpressionEvaluator.evaluateExpression(
197                    expression, context.trace, context.expectedType
198            );
199    
200            if (!(compileTimeConstant instanceof IntegerValueTypeConstant)) {
201                CompileTimeConstantChecker constantChecker = new CompileTimeConstantChecker(context, components.builtIns, false);
202                ConstantValue constantValue =
203                        compileTimeConstant != null ? ((TypedCompileTimeConstant) compileTimeConstant).getConstantValue() : null;
204                boolean hasError = constantChecker.checkConstantExpressionType(constantValue, expression, context.expectedType);
205                if (hasError) {
206                    return TypeInfoFactoryKt.createTypeInfo(getDefaultType(elementType), context);
207                }
208            }
209    
210            assert compileTimeConstant != null :
211                    "CompileTimeConstant should be evaluated for constant expression or an error should be recorded " +
212                    expression.getText();
213            return components.dataFlowAnalyzer.createCompileTimeConstantTypeInfo(compileTimeConstant, expression, context);
214        }
215    
216        @NotNull
217        public KotlinType getDefaultType(IElementType constantType) {
218            KotlinBuiltIns builtIns = components.builtIns;
219            if (constantType == KtNodeTypes.INTEGER_CONSTANT) {
220                return builtIns.getIntType();
221            }
222            else if (constantType == KtNodeTypes.FLOAT_CONSTANT) {
223                return builtIns.getDoubleType();
224            }
225            else if (constantType == KtNodeTypes.BOOLEAN_CONSTANT) {
226                return builtIns.getBooleanType();
227            }
228            else if (constantType == KtNodeTypes.CHARACTER_CONSTANT) {
229                return builtIns.getCharType();
230            }
231            else if (constantType == KtNodeTypes.NULL) {
232                return builtIns.getNullableNothingType();
233            }
234            else {
235                throw new IllegalArgumentException("Unsupported constant type: " + constantType);
236            }
237        }
238    
239        @Override
240        public KotlinTypeInfo visitBinaryWithTypeRHSExpression(
241                @NotNull KtBinaryExpressionWithTypeRHS expression,
242                ExpressionTypingContext context
243        ) {
244            ExpressionTypingContext contextWithNoExpectedType =
245                    context.replaceExpectedType(NO_EXPECTED_TYPE).replaceContextDependency(INDEPENDENT);
246            KtExpression left = expression.getLeft();
247            KtTypeReference right = expression.getRight();
248            if (right == null) {
249                return facade.getTypeInfo(left, contextWithNoExpectedType).clearType();
250            }
251    
252            IElementType operationType = expression.getOperationReference().getReferencedNameElementType();
253    
254            boolean allowBareTypes = BARE_TYPES_ALLOWED.contains(operationType);
255            TypeResolutionContext typeResolutionContext = new TypeResolutionContext(context.scope, context.trace, true, allowBareTypes);
256            PossiblyBareType possiblyBareTarget = components.typeResolver.resolvePossiblyBareType(typeResolutionContext, right);
257    
258            KotlinTypeInfo typeInfo = facade.getTypeInfo(left, contextWithNoExpectedType);
259    
260            KotlinType subjectType = typeInfo.getType();
261            KotlinType targetType = reconstructBareType(right, possiblyBareTarget, subjectType, context.trace, components.builtIns);
262    
263            if (subjectType != null) {
264                checkBinaryWithTypeRHS(expression, contextWithNoExpectedType, targetType, subjectType);
265                DataFlowInfo dataFlowInfo = typeInfo.getDataFlowInfo();
266                if (operationType == AS_KEYWORD) {
267                    DataFlowValue value = createDataFlowValue(left, subjectType, context);
268                    typeInfo = typeInfo.replaceDataFlowInfo(dataFlowInfo.establishSubtyping(value, targetType));
269                }
270            }
271    
272            KotlinType result = operationType == AS_SAFE ? TypeUtils.makeNullable(targetType) : targetType;
273            return components.dataFlowAnalyzer.checkType(typeInfo.replaceType(result), expression, context);
274        }
275    
276        private void checkBinaryWithTypeRHS(
277                @NotNull KtBinaryExpressionWithTypeRHS expression,
278                @NotNull ExpressionTypingContext context,
279                @NotNull KotlinType targetType,
280                @Nullable KotlinType actualType
281        ) {
282            if (actualType == null) return;
283            KtSimpleNameExpression operationSign = expression.getOperationReference();
284            IElementType operationType = operationSign.getReferencedNameElementType();
285            if (operationType != KtTokens.AS_KEYWORD && operationType != KtTokens.AS_SAFE) {
286                context.trace.report(UNSUPPORTED.on(operationSign, "binary operation with type RHS"));
287                return;
288            }
289            checkForCastImpossibilityOrRedundancy(expression, actualType, targetType, context);
290        }
291    
292        private void checkForCastImpossibilityOrRedundancy(
293                KtBinaryExpressionWithTypeRHS expression,
294                KotlinType actualType,
295                KotlinType targetType,
296                ExpressionTypingContext context
297        ) {
298            if (actualType == null || noExpectedType(targetType) || targetType.isError()) return;
299    
300            DeclarationsCheckerKt.checkNotEnumEntry(expression.getRight(), context.trace);
301    
302            if (DynamicTypesKt.isDynamic(targetType)) {
303                KtTypeReference right = expression.getRight();
304                assert right != null : "We know target is dynamic, but RHS is missing";
305                context.trace.report(DYNAMIC_NOT_ALLOWED.on(right));
306                return;
307            }
308    
309            if (!CastDiagnosticsUtil.isCastPossible(actualType, targetType, components.platformToKotlinClassMap)) {
310                context.trace.report(CAST_NEVER_SUCCEEDS.on(expression.getOperationReference()));
311                return;
312            }
313            KotlinTypeChecker typeChecker = KotlinTypeChecker.DEFAULT;
314            if (actualType.equals(targetType)) {
315                // cast to itself: String as String
316                context.trace.report(USELESS_CAST.on(expression));
317                return;
318            }
319            Collection<KotlinType> possibleTypes = components.dataFlowAnalyzer.getAllPossibleTypes(
320                    expression.getLeft(), context.dataFlowInfo, actualType, context);
321    
322            boolean checkExactType = checkExactTypeForUselessCast(expression);
323            for (KotlinType possibleType : possibleTypes) {
324                boolean castIsUseless = checkExactType
325                                        ? possibleType.equals(targetType)
326                                        : typeChecker.isSubtypeOf(possibleType, targetType);
327                if (castIsUseless) {
328                    context.trace.report(USELESS_CAST.on(expression));
329                    return;
330                }
331            }
332            if (CastDiagnosticsUtil.isCastErased(actualType, targetType, typeChecker)) {
333                context.trace.report(UNCHECKED_CAST.on(expression, actualType, targetType));
334            }
335        }
336    
337        // Casting an argument or a receiver to a supertype may be useful to select an exact overload of a method.
338        // Casting to a supertype in other contexts is unlikely to be useful.
339        private static boolean checkExactTypeForUselessCast(KtBinaryExpressionWithTypeRHS expression) {
340            PsiElement parent = expression.getParent();
341            while (parent instanceof KtParenthesizedExpression ||
342                   parent instanceof KtLabeledExpression ||
343                   parent instanceof KtAnnotatedExpression) {
344                parent = parent.getParent();
345            }
346            if (parent instanceof KtValueArgument) {
347                return true;
348            }
349            if (parent instanceof KtQualifiedExpression) {
350                KtExpression receiver = ((KtQualifiedExpression) parent).getReceiverExpression();
351                return PsiTreeUtil.isAncestor(receiver, expression, false);
352            }
353            // in binary expression, left argument can be a receiver and right an argument
354            // in unary expression, left argument can be a receiver
355            if (parent instanceof KtBinaryExpression || parent instanceof KtUnaryExpression) {
356                return true;
357            }
358            return false;
359        }
360    
361        @Override
362        public KotlinTypeInfo visitThisExpression(@NotNull KtThisExpression expression, ExpressionTypingContext context) {
363            KotlinType result = null;
364            LabelResolver.LabeledReceiverResolutionResult resolutionResult = resolveToReceiver(expression, context, false);
365    
366            switch (resolutionResult.getCode()) {
367                case LABEL_RESOLUTION_ERROR:
368                    // Do nothing, the error is already reported
369                    break;
370                case NO_THIS:
371                    context.trace.report(NO_THIS.on(expression));
372                    break;
373                case SUCCESS:
374                    result = resolutionResult.getReceiverParameterDescriptor().getType();
375                    context.trace.recordType(expression.getInstanceReference(), result);
376                    break;
377            }
378            return components.dataFlowAnalyzer.createCheckedTypeInfo(result, context, expression);
379        }
380    
381        @Override
382        public KotlinTypeInfo visitSuperExpression(@NotNull KtSuperExpression expression, ExpressionTypingContext context) {
383            LabelResolver.LabeledReceiverResolutionResult resolutionResult = resolveToReceiver(expression, context, true);
384    
385            if (!KtPsiUtil.isLHSOfDot(expression)) {
386                context.trace.report(SUPER_IS_NOT_AN_EXPRESSION.on(expression, expression.getText()));
387                return errorInSuper(expression, context);
388            }
389    
390            switch (resolutionResult.getCode()) {
391                case LABEL_RESOLUTION_ERROR:
392                    // The error is already reported
393                    return errorInSuper(expression, context);
394                case NO_THIS:
395                    context.trace.report(SUPER_NOT_AVAILABLE.on(expression));
396                    return errorInSuper(expression, context);
397                case SUCCESS:
398                    KotlinType result = checkPossiblyQualifiedSuper(expression, context, resolutionResult.getReceiverParameterDescriptor());
399                    if (result != null) {
400                        context.trace.recordType(expression.getInstanceReference(), result);
401                    }
402                    return components.dataFlowAnalyzer.createCheckedTypeInfo(result, context, expression);
403            }
404            throw new IllegalStateException("Unknown code: " + resolutionResult.getCode());
405        }
406    
407        private KotlinTypeInfo errorInSuper(KtSuperExpression expression, ExpressionTypingContext context) {
408            KtTypeReference superTypeQualifier = expression.getSuperTypeQualifier();
409            if (superTypeQualifier != null) {
410                components.typeResolver.resolveType(context.scope, superTypeQualifier, context.trace, true);
411            }
412            return TypeInfoFactoryKt.noTypeInfo(context);
413        }
414    
415        private KotlinType checkPossiblyQualifiedSuper(
416                KtSuperExpression expression,
417                ExpressionTypingContext context,
418                ReceiverParameterDescriptor thisReceiver
419        ) {
420            KotlinType result = null;
421            KotlinType thisType = thisReceiver.getType();
422            Collection<KotlinType> supertypes = thisType.getConstructor().getSupertypes();
423            TypeSubstitutor substitutor = TypeSubstitutor.create(thisType);
424    
425            KtTypeReference superTypeQualifier = expression.getSuperTypeQualifier();
426            if (superTypeQualifier != null) {
427                KtTypeElement typeElement = superTypeQualifier.getTypeElement();
428    
429                DeclarationDescriptor classifierCandidate = null;
430                KotlinType supertype = null;
431                PsiElement redundantTypeArguments = null;
432                if (typeElement instanceof KtUserType) {
433                    KtUserType userType = (KtUserType) typeElement;
434                    // This may be just a superclass name even if the superclass is generic
435                    if (userType.getTypeArguments().isEmpty()) {
436                        classifierCandidate = components.typeResolver.resolveClass(context.scope, userType, context.trace);
437                    }
438                    else {
439                        supertype = components.typeResolver.resolveType(context.scope, superTypeQualifier, context.trace, true);
440                        redundantTypeArguments = userType.getTypeArgumentList();
441                    }
442                }
443                else {
444                    supertype = components.typeResolver.resolveType(context.scope, superTypeQualifier, context.trace, true);
445                }
446    
447                if (supertype != null) {
448                    if (supertypes.contains(supertype)) {
449                        result = supertype;
450                    }
451                }
452                else if (classifierCandidate instanceof ClassDescriptor) {
453                    ClassDescriptor superclass = (ClassDescriptor) classifierCandidate;
454    
455                    for (KotlinType declaredSupertype : supertypes) {
456                        if (declaredSupertype.getConstructor().equals(superclass.getTypeConstructor())) {
457                            result = substitutor.safeSubstitute(declaredSupertype, Variance.INVARIANT);
458                            break;
459                        }
460                    }
461                }
462    
463                boolean validClassifier = classifierCandidate != null && !ErrorUtils.isError(classifierCandidate);
464                boolean validType = supertype != null && !supertype.isError();
465                if (result == null && (validClassifier || validType)) {
466                    context.trace.report(NOT_A_SUPERTYPE.on(superTypeQualifier));
467                }
468                else if (redundantTypeArguments != null) {
469                    context.trace.report(TYPE_ARGUMENTS_REDUNDANT_IN_SUPER_QUALIFIER.on(redundantTypeArguments));
470                }
471            }
472            else {
473                if (UnqualifiedSuperKt.isPossiblyAmbiguousUnqualifiedSuper(expression, supertypes)) {
474                    Collection<KotlinType> supertypesResolvedFromContext =
475                            UnqualifiedSuperKt.resolveUnqualifiedSuperFromExpressionContext(
476                                    expression, supertypes, components.builtIns.getAnyType());
477                    if (supertypesResolvedFromContext.size() == 1) {
478                        KotlinType singleResolvedType = supertypesResolvedFromContext.iterator().next();
479                        result = substitutor.substitute(singleResolvedType, Variance.INVARIANT);
480                    }
481                    else if (supertypesResolvedFromContext.isEmpty()) {
482                        // No supertype found, either with concrete or abstract members.
483                        // Resolve to 'Any' (this will cause diagnostics for unresolved member reference).
484                        result = components.builtIns.getAnyType();
485                    }
486                    else {
487                        context.trace.report(AMBIGUOUS_SUPER.on(expression));
488                    }
489                }
490                else {
491                    // supertypes may be empty when all the supertypes are error types (are not resolved, for example)
492                    KotlinType type = supertypes.isEmpty()
493                                      ? components.builtIns.getAnyType()
494                                      : supertypes.iterator().next();
495                    result = substitutor.substitute(type, Variance.INVARIANT);
496                }
497            }
498            if (result != null) {
499                if (DescriptorUtils.isInterface(thisType.getConstructor().getDeclarationDescriptor())) {
500                    if (DescriptorUtils.isClass(result.getConstructor().getDeclarationDescriptor())) {
501                        context.trace.report(SUPERCLASS_NOT_ACCESSIBLE_FROM_INTERFACE.on(expression));
502                    }
503                }
504                context.trace.recordType(expression.getInstanceReference(), result);
505                context.trace.record(BindingContext.REFERENCE_TARGET, expression.getInstanceReference(),
506                                     result.getConstructor().getDeclarationDescriptor());
507            }
508    
509            BindingContextUtilsKt.recordScope(context.trace, context.scope, superTypeQualifier);
510            return result;
511        }
512    
513        @NotNull // No class receivers
514        private LabelResolver.LabeledReceiverResolutionResult resolveToReceiver(
515                KtInstanceExpressionWithLabel expression,
516                ExpressionTypingContext context,
517                boolean onlyClassReceivers
518        ) {
519            Name labelName = expression.getLabelNameAsName();
520            if (labelName != null) {
521                LabelResolver.LabeledReceiverResolutionResult resolutionResult =
522                        LabelResolver.INSTANCE.resolveThisOrSuperLabel(expression, context, labelName);
523                if (resolutionResult.success()) {
524                    ReceiverParameterDescriptor receiverParameterDescriptor = resolutionResult.getReceiverParameterDescriptor();
525                    recordThisOrSuperCallInTraceAndCallExtension(context, receiverParameterDescriptor, expression);
526                    if (onlyClassReceivers && !isDeclaredInClass(receiverParameterDescriptor)) {
527                        return LabelResolver.LabeledReceiverResolutionResult.labelResolutionSuccess(null);
528                    }
529                }
530                return resolutionResult;
531            }
532            else {
533                ReceiverParameterDescriptor result = null;
534                List<ReceiverParameterDescriptor> receivers = ScopeUtilsKt.getImplicitReceiversHierarchy(context.scope);
535                if (onlyClassReceivers) {
536                    for (ReceiverParameterDescriptor receiver : receivers) {
537                        if (isDeclaredInClass(receiver)) {
538                            result = receiver;
539                            break;
540                        }
541                    }
542                }
543                else if (!receivers.isEmpty()) {
544                    result = receivers.get(0);
545                }
546                if (result != null) {
547                    context.trace.record(REFERENCE_TARGET, expression.getInstanceReference(), result.getContainingDeclaration());
548                    recordThisOrSuperCallInTraceAndCallExtension(context, result, expression);
549                }
550                return LabelResolver.LabeledReceiverResolutionResult.labelResolutionSuccess(result);
551            }
552        }
553    
554        private void recordThisOrSuperCallInTraceAndCallExtension(
555                ExpressionTypingContext context,
556                ReceiverParameterDescriptor descriptor,
557                KtExpression expression
558        ) {
559            BindingTrace trace = context.trace;
560            Call call = CallMaker.makeCall(expression, null, null, expression, Collections.<ValueArgument>emptyList());
561            ResolutionCandidate<ReceiverParameterDescriptor> resolutionCandidate =
562                    ResolutionCandidate.create(
563                            call, descriptor, null, null, ExplicitReceiverKind.NO_EXPLICIT_RECEIVER, null);
564    
565            ResolvedCallImpl<ReceiverParameterDescriptor> resolvedCall =
566                    ResolvedCallImpl.create(resolutionCandidate,
567                                            TemporaryBindingTrace.create(trace, "Fake trace for fake 'this' or 'super' resolved call"),
568                                            TracingStrategy.EMPTY,
569                                            new DataFlowInfoForArgumentsImpl(context.dataFlowInfo, call));
570            resolvedCall.markCallAsCompleted();
571    
572            trace.record(RESOLVED_CALL, call, resolvedCall);
573            trace.record(CALL, expression, call);
574    
575            BasicCallResolutionContext resolutionContext =
576                    BasicCallResolutionContext.create(context, call, CheckArgumentTypesMode.CHECK_CALLABLE_TYPE);
577            resolutionContext.performContextDependentCallChecks(resolvedCall);
578            for (CallChecker checker : components.callCheckers) {
579                checker.check(resolvedCall, resolutionContext);
580            }
581    
582            components.symbolUsageValidator.validateCall(resolvedCall, descriptor, trace, expression);
583        }
584    
585        private static boolean isDeclaredInClass(ReceiverParameterDescriptor receiver) {
586            return receiver.getContainingDeclaration() instanceof ClassDescriptor;
587        }
588    
589        @Override
590        public KotlinTypeInfo visitBlockExpression(@NotNull KtBlockExpression expression, ExpressionTypingContext context) {
591            return components.expressionTypingServices.getBlockReturnedType(expression, context, false);
592        }
593    
594        @Override
595        public KotlinTypeInfo visitClassLiteralExpression(@NotNull KtClassLiteralExpression expression, ExpressionTypingContext c) {
596            KotlinType type = resolveClassLiteral(expression, c);
597            if (type != null && !type.isError()) {
598                return components.dataFlowAnalyzer.createCheckedTypeInfo(
599                        components.reflectionTypes.getKClassType(Annotations.Companion.getEMPTY(), type), c, expression
600                );
601            }
602    
603            return TypeInfoFactoryKt.createTypeInfo(ErrorUtils.createErrorType("Unresolved class"), c);
604        }
605    
606        @Nullable
607        private KotlinType resolveClassLiteral(@NotNull KtClassLiteralExpression expression, ExpressionTypingContext c) {
608            KtTypeReference typeReference = expression.getTypeReference();
609    
610            if (typeReference == null) {
611                // "::class" will mean "this::class", a class of "this" instance
612                c.trace.report(UNSUPPORTED.on(expression, "Class literals with empty left hand side are not yet supported"));
613                return null;
614            }
615    
616            TypeResolutionContext context =
617                    new TypeResolutionContext(c.scope, c.trace, /* checkBounds = */ false, /* allowBareTypes = */ true);
618            PossiblyBareType possiblyBareType =
619                    components.typeResolver.resolvePossiblyBareType(context, typeReference);
620    
621            KotlinType type = null;
622            if (possiblyBareType.isBare()) {
623                if (!possiblyBareType.isNullable()) {
624                    ClassifierDescriptor descriptor = possiblyBareType.getBareTypeConstructor().getDeclarationDescriptor();
625                    if (descriptor instanceof ClassDescriptor) {
626                        ClassDescriptor classDescriptor = (ClassDescriptor) descriptor;
627                        if (KotlinBuiltIns.isNonPrimitiveArray(classDescriptor)) {
628                            context.trace.report(ARRAY_CLASS_LITERAL_REQUIRES_ARGUMENT.on(expression));
629                            return null;
630                        }
631                        type = substituteWithStarProjections(classDescriptor);
632                    }
633                }
634            }
635            else {
636                KotlinType actualType = possiblyBareType.getActualType();
637                if (actualType.isError()) return null;
638                if (isAllowedInClassLiteral(actualType)) {
639                    type = actualType;
640                }
641            }
642    
643            if (type != null) {
644                return type;
645            }
646    
647            context.trace.report(CLASS_LITERAL_LHS_NOT_A_CLASS.on(expression));
648            return null;
649        }
650    
651        @NotNull
652        private static KotlinType substituteWithStarProjections(@NotNull ClassDescriptor descriptor) {
653            TypeConstructor typeConstructor = descriptor.getTypeConstructor();
654            List<TypeProjection> arguments =
655                    CollectionsKt.map(typeConstructor.getParameters(), new Function1<TypeParameterDescriptor, TypeProjection>() {
656                        @Override
657                        public TypeProjection invoke(TypeParameterDescriptor descriptor) {
658                            return TypeUtils.makeStarProjection(descriptor);
659                        }
660                    });
661    
662            return KotlinTypeImpl.create(Annotations.Companion.getEMPTY(), descriptor, false, arguments);
663        }
664    
665        private static boolean isAllowedInClassLiteral(@NotNull KotlinType type) {
666            return isClassAvailableAtRuntime(type, false);
667        }
668    
669        private static boolean isClassAvailableAtRuntime(@NotNull KotlinType type, boolean canBeNullable) {
670            if (type.isMarkedNullable() && !canBeNullable) return false;
671    
672            TypeConstructor typeConstructor = type.getConstructor();
673            ClassifierDescriptor typeDeclarationDescriptor = typeConstructor.getDeclarationDescriptor();
674            boolean typeIsArray = KotlinBuiltIns.isArray(type);
675    
676            if (typeDeclarationDescriptor instanceof ClassDescriptor) {
677                List<TypeParameterDescriptor> parameters = typeConstructor.getParameters();
678                if (parameters.size() != type.getArguments().size()) return false;
679    
680                Iterator<TypeProjection> typeArgumentsIterator = type.getArguments().iterator();
681                for (TypeParameterDescriptor parameter : parameters) {
682                    if (!typeIsArray && !parameter.isReified()) return false;
683    
684                    TypeProjection typeArgument = typeArgumentsIterator.next();
685    
686                    if (typeArgument == null) return false;
687                    if (typeArgument.isStarProjection()) return false;
688                    if (!isClassAvailableAtRuntime(typeArgument.getType(), true)) return false;
689                }
690    
691                return true;
692            }
693            else if (typeDeclarationDescriptor instanceof TypeParameterDescriptor) {
694                return ((TypeParameterDescriptor) typeDeclarationDescriptor).isReified();
695            }
696    
697            return false;
698        }
699    
700        @Override
701        public KotlinTypeInfo visitCallableReferenceExpression(@NotNull KtCallableReferenceExpression expression, ExpressionTypingContext c) {
702            KtTypeReference typeReference = expression.getTypeReference();
703    
704            KotlinType receiverType =
705                    typeReference == null
706                    ? null
707                    : components.typeResolver.resolveType(c.scope, typeReference, c.trace, false);
708    
709            KtSimpleNameExpression callableReference = expression.getCallableReference();
710            if (callableReference.getReferencedName().isEmpty()) {
711                c.trace.report(UNRESOLVED_REFERENCE.on(callableReference, callableReference));
712                KotlinType errorType = ErrorUtils.createErrorType("Empty callable reference");
713                return components.dataFlowAnalyzer.createCheckedTypeInfo(errorType, c, expression);
714            }
715    
716            KotlinType result = getCallableReferenceType(expression, receiverType, c);
717            return components.dataFlowAnalyzer.createCheckedTypeInfo(result, c, expression);
718        }
719    
720        @Override
721        public KotlinTypeInfo visitObjectLiteralExpression(
722                @NotNull final KtObjectLiteralExpression expression,
723                final ExpressionTypingContext context
724        ) {
725            final KotlinType[] result = new KotlinType[1];
726            TemporaryBindingTrace temporaryTrace = TemporaryBindingTrace.create(context.trace,
727                                                                                "trace to resolve object literal expression", expression);
728            ObservableBindingTrace.RecordHandler<PsiElement, ClassDescriptor> handler =
729                    new ObservableBindingTrace.RecordHandler<PsiElement, ClassDescriptor>() {
730    
731                        @Override
732                        public void handleRecord(
733                                WritableSlice<PsiElement, ClassDescriptor> slice,
734                                PsiElement declaration,
735                                final ClassDescriptor descriptor
736                        ) {
737                            if (slice == CLASS && declaration == expression.getObjectDeclaration()) {
738                                KotlinType defaultType = DeferredType.createRecursionIntolerant(components.globalContext.getStorageManager(),
739                                                                                                context.trace,
740                                                                                                new Function0<KotlinType>() {
741                                                                                                    @Override
742                                                                                                    public KotlinType invoke() {
743                                                                                                        return descriptor.getDefaultType();
744                                                                                                    }
745                                                                                                });
746                                result[0] = defaultType;
747                            }
748                        }
749                    };
750            ObservableBindingTrace traceAdapter = new ObservableBindingTrace(temporaryTrace);
751            traceAdapter.addHandler(CLASS, handler);
752            components.localClassifierAnalyzer.processClassOrObject(null, // don't need to add classifier of object literal to any scope
753                                                                    context.replaceBindingTrace(traceAdapter)
754                                                                           .replaceContextDependency(INDEPENDENT),
755                                                                    context.scope.getOwnerDescriptor(),
756                                                                    expression.getObjectDeclaration());
757            temporaryTrace.commit();
758            DataFlowInfo resultFlowInfo = context.dataFlowInfo;
759            for (KtSuperTypeListEntry specifier : expression.getObjectDeclaration().getSuperTypeListEntries()) {
760                if (specifier instanceof KtSuperTypeCallEntry) {
761                    KtSuperTypeCallEntry delegator = (KtSuperTypeCallEntry) specifier;
762                    KotlinTypeInfo delegatorTypeInfo = context.trace.get(EXPRESSION_TYPE_INFO, delegator.getCalleeExpression());
763                    if (delegatorTypeInfo != null) {
764                        resultFlowInfo = resultFlowInfo.and(delegatorTypeInfo.getDataFlowInfo());
765                    }
766                }
767            }
768            // Breaks are not possible inside constructor arguments, so jumpPossible or jumpFlowInfo are not necessary here
769            KotlinTypeInfo resultTypeInfo = components.dataFlowAnalyzer.checkType(TypeInfoFactoryKt.createTypeInfo(result[0], resultFlowInfo),
770                                                                                  expression,
771                                                                                  context);
772            // We have to record it here,
773            // otherwise ExpressionTypingVisitorDispatcher records wrong information
774            context.trace.record(EXPRESSION_TYPE_INFO, expression, resultTypeInfo);
775            context.trace.record(PROCESSED, expression);
776            return resultTypeInfo;
777        }
778    
779        @Nullable
780        private KotlinType getCallableReferenceType(
781                @NotNull KtCallableReferenceExpression expression,
782                @Nullable KotlinType lhsType,
783                @NotNull ExpressionTypingContext context
784        ) {
785            KtSimpleNameExpression reference = expression.getCallableReference();
786    
787            boolean[] resolved = new boolean[1];
788            CallableDescriptor descriptor = CallableReferencesResolutionUtilsKt.resolveCallableReferenceTarget(
789                    expression, lhsType, context, resolved, components.callResolver);
790            if (!resolved[0]) {
791                context.trace.report(UNRESOLVED_REFERENCE.on(reference, reference));
792            }
793            if (descriptor == null) return null;
794    
795            if (expression.getTypeReference() == null &&
796                (descriptor.getDispatchReceiverParameter() != null || descriptor.getExtensionReceiverParameter() != null)) {
797                context.trace.report(CALLABLE_REFERENCE_TO_MEMBER_OR_EXTENSION_WITH_EMPTY_LHS.on(reference));
798            }
799    
800            DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
801            if (DescriptorUtils.isObject(containingDeclaration)) {
802                context.trace.report(CALLABLE_REFERENCE_TO_OBJECT_MEMBER.on(reference));
803            }
804            if (descriptor instanceof ConstructorDescriptor && DescriptorUtils.isAnnotationClass(containingDeclaration)) {
805                context.trace.report(CALLABLE_REFERENCE_TO_ANNOTATION_CONSTRUCTOR.on(reference));
806            }
807    
808            return CallableReferencesResolutionUtilsKt.createReflectionTypeForResolvedCallableReference(
809                    expression, lhsType, descriptor, context, components.reflectionTypes
810            );
811        }
812    
813        @Override
814        public KotlinTypeInfo visitQualifiedExpression(@NotNull KtQualifiedExpression expression, ExpressionTypingContext context) {
815            CallExpressionResolver callExpressionResolver = components.callExpressionResolver;
816            return callExpressionResolver.getQualifiedExpressionTypeInfo(expression, context);
817        }
818    
819        @Override
820        public KotlinTypeInfo visitCallExpression(@NotNull KtCallExpression expression, ExpressionTypingContext context) {
821            CallExpressionResolver callExpressionResolver = components.callExpressionResolver;
822            return callExpressionResolver.getCallExpressionTypeInfo(expression, null, null, context);
823        }
824    
825        @Override
826        public KotlinTypeInfo visitUnaryExpression(@NotNull KtUnaryExpression expression, ExpressionTypingContext contextWithExpectedType) {
827            ExpressionTypingContext context = isUnaryExpressionDependentOnExpectedType(expression)
828                                              ? contextWithExpectedType
829                                              : contextWithExpectedType.replaceContextDependency(INDEPENDENT)
830                                                                       .replaceExpectedType(NO_EXPECTED_TYPE);
831    
832            KtExpression baseExpression = expression.getBaseExpression();
833            if (baseExpression == null) return TypeInfoFactoryKt.noTypeInfo(context);
834    
835            KtSimpleNameExpression operationSign = expression.getOperationReference();
836    
837            IElementType operationType = operationSign.getReferencedNameElementType();
838    
839            // Special case for expr!!
840            if (operationType == KtTokens.EXCLEXCL) {
841                return visitExclExclExpression(expression, context);
842            }
843    
844            // Type check the base expression
845            KotlinTypeInfo typeInfo = facade.safeGetTypeInfo(baseExpression, context);
846            KotlinType type = ExpressionTypingUtils.safeGetType(typeInfo);
847            ExpressionReceiver receiver = ExpressionReceiver.Companion.create(baseExpression, type, context.trace.getBindingContext());
848    
849            Call call = CallMaker.makeCall(receiver, expression);
850    
851            // Conventions for unary operations
852            Name name = OperatorConventions.UNARY_OPERATION_NAMES.get(operationType);
853            if (name == null) {
854                context.trace.report(UNSUPPORTED.on(operationSign, "visitUnaryExpression"));
855                return typeInfo.clearType();
856            }
857    
858            // a[i]++/-- takes special treatment because it is actually let j = i, arr = a in arr.set(j, a.get(j).inc())
859            if ((operationType == KtTokens.PLUSPLUS || operationType == KtTokens.MINUSMINUS) &&
860                baseExpression instanceof KtArrayAccessExpression) {
861                KtExpression stubExpression = ExpressionTypingUtils.createFakeExpressionOfType(
862                        baseExpression.getProject(), context.trace, "e", type);
863                TemporaryBindingTrace temporaryBindingTrace = TemporaryBindingTrace.create(
864                        context.trace, "trace to resolve array access set method for unary expression", expression);
865                ExpressionTypingContext newContext = context.replaceBindingTrace(temporaryBindingTrace);
866                resolveArrayAccessSetMethod((KtArrayAccessExpression) baseExpression, stubExpression, newContext, context.trace);
867            }
868    
869            // Resolve the operation reference
870            OverloadResolutionResults<FunctionDescriptor> resolutionResults = components.callResolver.resolveCallWithGivenName(
871                    context, call, expression.getOperationReference(), name);
872    
873            if (!resolutionResults.isSuccess()) {
874                return typeInfo.clearType();
875            }
876    
877            // Computing the return type
878            KotlinType returnType = resolutionResults.getResultingDescriptor().getReturnType();
879            KotlinType result;
880            if (operationType == KtTokens.PLUSPLUS || operationType == KtTokens.MINUSMINUS) {
881                assert returnType != null : "returnType is null for " + resolutionResults.getResultingDescriptor();
882                if (KotlinBuiltIns.isUnit(returnType)) {
883                    result = ErrorUtils.createErrorType(components.builtIns.getUnit().getName().asString());
884                    context.trace.report(INC_DEC_SHOULD_NOT_RETURN_UNIT.on(operationSign));
885                }
886                else {
887                    KotlinType receiverType = receiver.getType();
888                    if (!KotlinTypeChecker.DEFAULT.isSubtypeOf(returnType, receiverType)) {
889                        context.trace.report(RESULT_TYPE_MISMATCH.on(operationSign, name.asString(), receiverType, returnType));
890                    }
891                    else {
892                        context.trace.record(BindingContext.VARIABLE_REASSIGNMENT, expression);
893                        KtExpression stubExpression = ExpressionTypingUtils.createFakeExpressionOfType(
894                                baseExpression.getProject(), context.trace, "e", type);
895                        checkLValue(context.trace, context, baseExpression, stubExpression);
896                    }
897                    // x++ type is x type, but ++x type is x.inc() type
898                    DataFlowValue receiverValue = DataFlowValueFactory.createDataFlowValue(
899                            (ReceiverValue) call.getExplicitReceiver(), contextWithExpectedType);
900                    if (expression instanceof KtPrefixExpression) {
901                        result = returnType;
902                    }
903                    else {
904                        result = receiverType;
905                        // Also record data flow information for x++ value (= x)
906                        DataFlowValue returnValue = DataFlowValueFactory.createDataFlowValue(expression, receiverType, contextWithExpectedType);
907                        typeInfo = typeInfo.replaceDataFlowInfo(typeInfo.getDataFlowInfo().assign(returnValue, receiverValue));
908                    }
909                }
910            }
911            else {
912                result = returnType;
913            }
914    
915            CompileTimeConstant<?> value = components.constantExpressionEvaluator.evaluateExpression(
916                    expression, contextWithExpectedType.trace, contextWithExpectedType.expectedType
917            );
918            if (value != null) {
919                return components.dataFlowAnalyzer.createCompileTimeConstantTypeInfo(value, expression, contextWithExpectedType);
920            }
921    
922            return components.dataFlowAnalyzer.checkType(typeInfo.replaceType(result),
923                                                         expression,
924                                                         contextWithExpectedType.replaceDataFlowInfo(typeInfo.getDataFlowInfo()));
925        }
926    
927        private KotlinTypeInfo visitExclExclExpression(@NotNull KtUnaryExpression expression, @NotNull ExpressionTypingContext context) {
928            KtExpression baseExpression = expression.getBaseExpression();
929            assert baseExpression != null;
930            KtSimpleNameExpression operationSign = expression.getOperationReference();
931            assert operationSign.getReferencedNameElementType() == KtTokens.EXCLEXCL;
932    
933            // TODO: something must be done for not to lose safe call chain information here
934            // See also CallExpressionResolver.getSimpleNameExpressionTypeInfo, .getQualifiedExpressionTypeInfo
935            Call call = createCallForSpecialConstruction(
936                    expression, expression.getOperationReference(), Collections.singletonList(baseExpression));
937            components.controlStructureTypingUtils.resolveSpecialConstructionAsCall(
938                    call, ResolveConstruct.EXCL_EXCL, Collections.singletonList("baseExpr"), Collections.singletonList(true), context, null);
939            KotlinTypeInfo baseTypeInfo = BindingContextUtils.getRecordedTypeInfo(baseExpression, context.trace.getBindingContext());
940    
941            if (ArgumentTypeResolver.isFunctionLiteralArgument(baseExpression, context)) {
942                context.trace.report(NOT_NULL_ASSERTION_ON_LAMBDA_EXPRESSION.on(operationSign));
943                if (baseTypeInfo == null) {
944                    return TypeInfoFactoryKt.createTypeInfo(ErrorUtils.createErrorType("Unresolved lambda expression"), context);
945                }
946                return baseTypeInfo;
947            }
948            assert baseTypeInfo != null : "Base expression was not processed: " + expression;
949            KotlinType baseType = baseTypeInfo.getType();
950            if (baseType == null) {
951                return baseTypeInfo;
952            }
953            DataFlowInfo dataFlowInfo = baseTypeInfo.getDataFlowInfo();
954            if (isKnownToBeNotNull(baseExpression, context) && !baseType.isError()) {
955                context.trace.report(UNNECESSARY_NOT_NULL_ASSERTION.on(operationSign, TypeUtils.makeNotNullable(baseType)));
956            }
957            else {
958                DataFlowValue value = createDataFlowValue(baseExpression, baseType, context);
959                baseTypeInfo = baseTypeInfo.replaceDataFlowInfo(dataFlowInfo.disequate(value, DataFlowValue.nullValue(components.builtIns)));
960            }
961            KotlinType resultingType = TypeUtils.makeNotNullable(baseType);
962            if (context.contextDependency == DEPENDENT) {
963                return baseTypeInfo.replaceType(resultingType);
964            }
965    
966            // The call to checkType() is only needed here to execute additionalTypeCheckers, hence the NO_EXPECTED_TYPE
967            return components.dataFlowAnalyzer.checkType(
968                    baseTypeInfo.replaceType(resultingType), expression, context.replaceExpectedType(NO_EXPECTED_TYPE));
969        }
970    
971        @Override
972        public KotlinTypeInfo visitLabeledExpression(
973                @NotNull KtLabeledExpression expression, ExpressionTypingContext context
974        ) {
975            return visitLabeledExpression(expression, context, false);
976        }
977    
978        @NotNull
979        public KotlinTypeInfo visitLabeledExpression(
980                @NotNull KtLabeledExpression expression,
981                @NotNull ExpressionTypingContext context,
982                boolean isStatement
983        ) {
984            KtSimpleNameExpression labelExpression = expression.getTargetLabel();
985            if (labelExpression != null) {
986                PsiElement labelIdentifier = labelExpression.getIdentifier();
987                UnderscoreChecker.INSTANCE.checkIdentifier(labelIdentifier, context.trace);
988            }
989            KtExpression baseExpression = expression.getBaseExpression();
990            if (baseExpression == null) return TypeInfoFactoryKt.noTypeInfo(context);
991    
992            return facade.getTypeInfo(baseExpression, context, isStatement);
993        }
994    
995        private static boolean isKnownToBeNotNull(KtExpression expression, ExpressionTypingContext context) {
996            KotlinType type = context.trace.getType(expression);
997            assert type != null : "This method is only supposed to be called when the type is not null";
998            return isKnownToBeNotNull(expression, type, context);
999        }
1000    
1001        private static boolean isKnownToBeNotNull(KtExpression expression, KotlinType jetType, ExpressionTypingContext context) {
1002            DataFlowValue dataFlowValue = createDataFlowValue(expression, jetType, context);
1003            return !context.dataFlowInfo.getPredictableNullability(dataFlowValue).canBeNull();
1004        }
1005    
1006        /**
1007         * @return {@code true} iff expression can be assigned to
1008         */
1009        public boolean checkLValue(
1010                @NotNull BindingTrace trace,
1011                @NotNull ExpressionTypingContext context,
1012                @NotNull KtExpression expression,
1013                @Nullable KtExpression rightHandSide
1014        ) {
1015            return checkLValue(trace, context, expression, rightHandSide, false);
1016        }
1017    
1018        private boolean checkLValue(
1019                @NotNull BindingTrace trace,
1020                @NotNull ExpressionTypingContext context,
1021                @NotNull KtExpression expressionWithParenthesis,
1022                @Nullable KtExpression rightHandSide,
1023                boolean canBeThis
1024        ) {
1025            KtExpression expression = KtPsiUtil.deparenthesize(expressionWithParenthesis);
1026            if (expression instanceof KtArrayAccessExpression) {
1027                KtArrayAccessExpression arrayAccessExpression = (KtArrayAccessExpression) expression;
1028                KtExpression arrayExpression = arrayAccessExpression.getArrayExpression();
1029                if (arrayExpression == null || rightHandSide == null) return false;
1030    
1031                TemporaryBindingTrace ignoreReportsTrace = TemporaryBindingTrace.create(trace, "Trace for checking set function");
1032                ExpressionTypingContext findSetterContext = context.replaceBindingTrace(ignoreReportsTrace);
1033                KotlinTypeInfo info = resolveArrayAccessSetMethod(arrayAccessExpression, rightHandSide, findSetterContext, ignoreReportsTrace);
1034                return info.getType() != null;
1035            }
1036    
1037            if (canBeThis && expression instanceof KtThisExpression) return true;
1038            VariableDescriptor variable = BindingContextUtils.extractVariableDescriptorIfAny(trace.getBindingContext(), expression, true);
1039    
1040            boolean result = true;
1041            KtExpression reportOn = expression != null ? expression : expressionWithParenthesis;
1042            if (reportOn instanceof KtQualifiedExpression) {
1043                KtExpression selector = ((KtQualifiedExpression) reportOn).getSelectorExpression();
1044                if (selector != null)
1045                    reportOn = selector;
1046            }
1047    
1048            if (variable instanceof PropertyDescriptor) {
1049                PropertyDescriptor propertyDescriptor = (PropertyDescriptor) variable;
1050                PropertySetterDescriptor setter = propertyDescriptor.getSetter();
1051                if (propertyDescriptor.isSetterProjectedOut()) {
1052                    trace.report(SETTER_PROJECTED_OUT.on(reportOn, propertyDescriptor));
1053                    result = false;
1054                }
1055                else {
1056                    if (setter != null) {
1057                        components.symbolUsageValidator.validateCall(null, setter, trace, reportOn);
1058                    }
1059                }
1060            }
1061    
1062            if (variable == null) {
1063                trace.report(VARIABLE_EXPECTED.on(reportOn));
1064                result = false;
1065            }
1066            else if (!variable.isVar()) {
1067                result = false;
1068            }
1069    
1070            return result;
1071        }
1072    
1073        @Override
1074        public KotlinTypeInfo visitBinaryExpression(@NotNull KtBinaryExpression expression, ExpressionTypingContext contextWithExpectedType) {
1075            ExpressionTypingContext context = isBinaryExpressionDependentOnExpectedType(expression)
1076                                              ? contextWithExpectedType
1077                                              : contextWithExpectedType.replaceContextDependency(INDEPENDENT)
1078                                                                       .replaceExpectedType(NO_EXPECTED_TYPE);
1079    
1080            KtSimpleNameExpression operationSign = expression.getOperationReference();
1081            KtExpression left = expression.getLeft();
1082            KtExpression right = expression.getRight();
1083            IElementType operationType = operationSign.getReferencedNameElementType();
1084    
1085            KotlinTypeInfo result;
1086    
1087            //Expressions that can depend on expected type
1088            if (operationType == KtTokens.IDENTIFIER) {
1089                Name referencedName = operationSign.getReferencedNameAsName();
1090                result = getTypeInfoForBinaryCall(referencedName, context, expression);
1091            }
1092            else if (OperatorConventions.BINARY_OPERATION_NAMES.containsKey(operationType)) {
1093                Name referencedName = OperatorConventions.BINARY_OPERATION_NAMES.get(operationType);
1094                result = getTypeInfoForBinaryCall(referencedName, context, expression);
1095            }
1096            else if (operationType == KtTokens.ELVIS) {
1097                //base expression of elvis operator is checked for 'type mismatch', so the whole expression shouldn't be checked
1098                return visitElvisExpression(expression, context);
1099            }
1100    
1101            //Expressions that don't depend on expected type
1102            else if (operationType == KtTokens.EQ) {
1103                result = visitAssignment(expression, context);
1104            }
1105            else if (OperatorConventions.ASSIGNMENT_OPERATIONS.containsKey(operationType)) {
1106                result = visitAssignmentOperation(expression, context);
1107            }
1108            else if (OperatorConventions.COMPARISON_OPERATIONS.contains(operationType)) {
1109                result = visitComparison(expression, context, operationSign);
1110            }
1111            else if (OperatorConventions.EQUALS_OPERATIONS.contains(operationType)) {
1112                result = visitEquality(expression, context, operationSign, left, right);
1113            }
1114            else if (OperatorConventions.IDENTITY_EQUALS_OPERATIONS.contains(operationType)) {
1115                ensureNonemptyIntersectionOfOperandTypes(expression, context);
1116                // TODO : Check comparison pointlessness
1117                result = TypeInfoFactoryKt.createTypeInfo(components.builtIns.getBooleanType(), context);
1118            }
1119            else if (OperatorConventions.IN_OPERATIONS.contains(operationType)) {
1120                ValueArgument leftArgument = CallMaker.makeValueArgument(left, left != null ? left : operationSign);
1121                result = checkInExpression(expression, operationSign, leftArgument, right, context);
1122            }
1123            else if (OperatorConventions.BOOLEAN_OPERATIONS.containsKey(operationType)) {
1124                result = visitBooleanOperationExpression(operationType, left, right, context);
1125            }
1126            else {
1127                context.trace.report(UNSUPPORTED.on(operationSign, "Unknown operation"));
1128                result = TypeInfoFactoryKt.noTypeInfo(context);
1129            }
1130            CompileTimeConstant<?> value = components.constantExpressionEvaluator.evaluateExpression(
1131                    expression, contextWithExpectedType.trace, contextWithExpectedType.expectedType
1132            );
1133            if (value != null) {
1134                return components.dataFlowAnalyzer.createCompileTimeConstantTypeInfo(value, expression, contextWithExpectedType);
1135            }
1136            return components.dataFlowAnalyzer.checkType(result, expression, contextWithExpectedType);
1137        }
1138    
1139        private KotlinTypeInfo visitEquality(
1140                KtBinaryExpression expression,
1141                ExpressionTypingContext context,
1142                KtSimpleNameExpression operationSign,
1143                final KtExpression left,
1144                final KtExpression right
1145        ) {
1146            if (right == null || left == null) {
1147                ExpressionTypingUtils.getTypeInfoOrNullType(right, context, facade);
1148                ExpressionTypingUtils.getTypeInfoOrNullType(left, context, facade);
1149                return TypeInfoFactoryKt.createTypeInfo(components.builtIns.getBooleanType(), context);
1150            }
1151    
1152            KotlinTypeInfo leftTypeInfo = getTypeInfoOrNullType(left, context, facade);
1153    
1154            DataFlowInfo dataFlowInfo = leftTypeInfo.getDataFlowInfo();
1155            ExpressionTypingContext contextWithDataFlow = context.replaceDataFlowInfo(dataFlowInfo);
1156    
1157            KotlinTypeInfo rightTypeInfo = facade.getTypeInfo(right, contextWithDataFlow);
1158    
1159            TemporaryBindingTrace traceInterpretingRightAsNullableAny = TemporaryBindingTrace.create(
1160                    context.trace, "trace to resolve 'equals(Any?)' interpreting as of type Any? an expression:", right);
1161            traceInterpretingRightAsNullableAny.recordType(right, components.builtIns.getNullableAnyType());
1162    
1163            // Nothing? has no members, and `equals()` would be unresolved on it
1164            KotlinType leftType = leftTypeInfo.getType();
1165            if (leftType != null && KotlinBuiltIns.isNothingOrNullableNothing(leftType)) {
1166                traceInterpretingRightAsNullableAny.recordType(left, components.builtIns.getNullableAnyType());
1167            }
1168    
1169            ExpressionTypingContext newContext = context.replaceBindingTrace(traceInterpretingRightAsNullableAny);
1170            ExpressionReceiver receiver = ExpressionTypingUtils.safeGetExpressionReceiver(facade, left, newContext);
1171            Call call = CallMaker.makeCallWithExpressions(
1172                    expression,
1173                    receiver,
1174                    // semantically, a call to `==` is a safe call
1175                    new KtPsiFactory(expression.getProject()).createSafeCallNode(),
1176                    operationSign,
1177                    Collections.singletonList(right)
1178            );
1179            OverloadResolutionResults<FunctionDescriptor> resolutionResults =
1180                    components.callResolver.resolveCallWithGivenName(newContext, call, operationSign, OperatorNameConventions.EQUALS);
1181    
1182            traceInterpretingRightAsNullableAny.commit(new TraceEntryFilter() {
1183                @Override
1184                public boolean accept(@Nullable WritableSlice<?, ?> slice, @Nullable Diagnostic diagnostic, Object key) {
1185                    // the type of the right (and sometimes left) expression isn't 'Any?' actually
1186                    if ((key == right || key == left) && slice == EXPRESSION_TYPE_INFO) return false;
1187    
1188                    // a hack due to KT-678
1189                    // without this line an smartcast is reported on the receiver (if it was previously checked for not-null)
1190                    // with not-null check the resolution result changes from 'fun Any?.equals' to 'equals' member
1191                    if (key == left && slice == SMARTCAST) return false;
1192    
1193                    return true;
1194                }
1195            }, true);
1196    
1197            if (resolutionResults.isSuccess()) {
1198                FunctionDescriptor equals = resolutionResults.getResultingCall().getResultingDescriptor();
1199                if (ensureBooleanResult(operationSign, OperatorNameConventions.EQUALS, equals.getReturnType(), context)) {
1200                    ensureNonemptyIntersectionOfOperandTypes(expression, context);
1201                }
1202            }
1203            else {
1204                if (resolutionResults.isAmbiguity()) {
1205                    context.trace.report(OVERLOAD_RESOLUTION_AMBIGUITY.on(operationSign, resolutionResults.getResultingCalls()));
1206                }
1207                else {
1208                    context.trace.report(EQUALS_MISSING.on(operationSign));
1209                }
1210            }
1211            return rightTypeInfo.replaceType(components.builtIns.getBooleanType());
1212        }
1213    
1214        @NotNull
1215        private KotlinTypeInfo visitComparison(
1216                @NotNull KtBinaryExpression expression,
1217                @NotNull ExpressionTypingContext context,
1218                @NotNull KtSimpleNameExpression operationSign
1219        ) {
1220            KotlinTypeInfo typeInfo = getTypeInfoForBinaryCall(OperatorNameConventions.COMPARE_TO, context, expression);
1221            KotlinType compareToReturnType = typeInfo.getType();
1222            KotlinType type = null;
1223            if (compareToReturnType != null && !compareToReturnType.isError()) {
1224                if (KotlinTypeChecker.DEFAULT.equalTypes(components.builtIns.getIntType(), compareToReturnType)) {
1225                    type = components.builtIns.getBooleanType();
1226                }
1227                else {
1228                    context.trace.report(COMPARE_TO_TYPE_MISMATCH.on(operationSign, compareToReturnType));
1229                }
1230            }
1231            return typeInfo.replaceType(type);
1232        }
1233    
1234        @NotNull
1235        private KotlinTypeInfo visitBooleanOperationExpression(
1236                @Nullable IElementType operationType,
1237                @Nullable KtExpression left,
1238                @Nullable KtExpression right,
1239                @NotNull ExpressionTypingContext context
1240        ) {
1241            KotlinType booleanType = components.builtIns.getBooleanType();
1242            KotlinTypeInfo leftTypeInfo = getTypeInfoOrNullType(left, context.replaceExpectedType(booleanType), facade);
1243            DataFlowInfo dataFlowInfo = leftTypeInfo.getDataFlowInfo();
1244    
1245            LexicalWritableScope leftScope = newWritableScopeImpl(context, LexicalScopeKind.LEFT_BOOLEAN_EXPRESSION);
1246            // TODO: This gets computed twice: here and in extractDataFlowInfoFromCondition() for the whole condition
1247            boolean isAnd = operationType == KtTokens.ANDAND;
1248            DataFlowInfo flowInfoLeft = components.dataFlowAnalyzer.extractDataFlowInfoFromCondition(left, isAnd, context).and(dataFlowInfo);
1249            LexicalWritableScope rightScope = isAnd ? leftScope : newWritableScopeImpl(context, LexicalScopeKind.RIGHT_BOOLEAN_EXPRESSION);
1250    
1251            ExpressionTypingContext contextForRightExpr =
1252                    context.replaceDataFlowInfo(flowInfoLeft).replaceScope(rightScope).replaceExpectedType(booleanType);
1253            if (right != null) {
1254                facade.getTypeInfo(right, contextForRightExpr);
1255            }
1256            return leftTypeInfo.replaceType(booleanType);
1257        }
1258    
1259        @NotNull
1260        private KotlinTypeInfo visitElvisExpression(
1261                @NotNull KtBinaryExpression expression,
1262                @NotNull ExpressionTypingContext contextWithExpectedType
1263        ) {
1264            ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(NO_EXPECTED_TYPE);
1265            KtExpression left = expression.getLeft();
1266            KtExpression right = expression.getRight();
1267    
1268            if (left == null || right == null) {
1269                getTypeInfoOrNullType(left, context, facade);
1270                return TypeInfoFactoryKt.noTypeInfo(context);
1271            }
1272    
1273            Call call = createCallForSpecialConstruction(expression, expression.getOperationReference(), Lists.newArrayList(left, right));
1274            ResolvedCall<FunctionDescriptor> resolvedCall = components.controlStructureTypingUtils.resolveSpecialConstructionAsCall(
1275                    call, ResolveConstruct.ELVIS, Lists.newArrayList("left", "right"),
1276                    Lists.newArrayList(true, false), contextWithExpectedType, null);
1277            KotlinTypeInfo leftTypeInfo = BindingContextUtils.getRecordedTypeInfo(left, context.trace.getBindingContext());
1278            if (ArgumentTypeResolver.isFunctionLiteralArgument(left, context)) {
1279                context.trace.report(USELESS_ELVIS_ON_LAMBDA_EXPRESSION.on(expression.getOperationReference()));
1280                if (leftTypeInfo == null) return TypeInfoFactoryKt.noTypeInfo(context);
1281            }
1282            assert leftTypeInfo != null : "Left expression was not processed: " + expression;
1283            KotlinType leftType = leftTypeInfo.getType();
1284            if (leftType != null && isKnownToBeNotNull(left, leftType, context)) {
1285                context.trace.report(USELESS_ELVIS.on(expression, leftType));
1286            }
1287            KotlinTypeInfo rightTypeInfo = BindingContextUtils.getRecordedTypeInfo(right, context.trace.getBindingContext());
1288            if (rightTypeInfo == null && ArgumentTypeResolver.isFunctionLiteralArgument(right, context)) {
1289                // the type is computed later in call completer according to the '?:' semantics as a function
1290                return TypeInfoFactoryKt.noTypeInfo(context);
1291            }
1292            assert rightTypeInfo != null : "Right expression was not processed: " + expression;
1293            boolean loopBreakContinuePossible = leftTypeInfo.getJumpOutPossible() || rightTypeInfo.getJumpOutPossible();
1294            KotlinType rightType = rightTypeInfo.getType();
1295    
1296            // Only left argument DFA is taken into account here: we cannot be sure that right argument is joined
1297            // (we merge it with right DFA if right argument contains no jump outside)
1298            DataFlowInfo dataFlowInfo = resolvedCall.getDataFlowInfoForArguments().getInfo(call.getValueArguments().get(1));
1299    
1300            KotlinType type = resolvedCall.getResultingDescriptor().getReturnType();
1301            if (type == null || rightType == null) return TypeInfoFactoryKt.noTypeInfo(dataFlowInfo);
1302            if (leftType != null) {
1303                DataFlowValue leftValue = createDataFlowValue(left, leftType, context);
1304                DataFlowInfo rightDataFlowInfo = resolvedCall.getDataFlowInfoForArguments().getResultInfo();
1305                boolean jumpInRight = KotlinBuiltIns.isNothing(rightType);
1306                DataFlowValue nullValue = DataFlowValue.nullValue(components.builtIns);
1307                // left argument is considered not-null if it's not-null also in right part or if we have jump in right part
1308                if (jumpInRight || !rightDataFlowInfo.getPredictableNullability(leftValue).canBeNull()) {
1309                    dataFlowInfo = dataFlowInfo.disequate(leftValue, nullValue);
1310                }
1311                DataFlowValue resultValue = DataFlowValueFactory.createDataFlowValue(expression, type, context);
1312                dataFlowInfo = dataFlowInfo.assign(resultValue, leftValue).disequate(resultValue, nullValue);
1313                if (!jumpInRight) {
1314                    DataFlowValue rightValue = DataFlowValueFactory.createDataFlowValue(right, rightType, context);
1315                    rightDataFlowInfo = rightDataFlowInfo.assign(resultValue, rightValue);
1316                    dataFlowInfo = dataFlowInfo.or(rightDataFlowInfo);
1317                }
1318            }
1319    
1320    
1321            // Sometimes return type for special call for elvis operator might be nullable,
1322            // but result is not nullable if the right type is not nullable
1323            if (!TypeUtils.isNullableType(rightType) && TypeUtils.isNullableType(type)) {
1324                type = TypeUtils.makeNotNullable(type);
1325            }
1326            if (context.contextDependency == DEPENDENT) {
1327                return TypeInfoFactoryKt.createTypeInfo(type, dataFlowInfo);
1328            }
1329    
1330            // If break or continue was possible, take condition check info as the jump info
1331            return TypeInfoFactoryKt.createTypeInfo(components.dataFlowAnalyzer.checkType(type, expression, contextWithExpectedType),
1332                                                    dataFlowInfo,
1333                                                    loopBreakContinuePossible,
1334                                                    context.dataFlowInfo);
1335        }
1336    
1337        @NotNull
1338        public KotlinTypeInfo checkInExpression(
1339                @NotNull KtElement callElement,
1340                @NotNull KtSimpleNameExpression operationSign,
1341                @NotNull ValueArgument leftArgument,
1342                @Nullable KtExpression right,
1343                @NotNull ExpressionTypingContext context
1344        ) {
1345            KtExpression left = leftArgument.getArgumentExpression();
1346            ExpressionTypingContext contextWithNoExpectedType = context.replaceExpectedType(NO_EXPECTED_TYPE);
1347            if (right == null) {
1348                if (left != null) facade.getTypeInfo(left, contextWithNoExpectedType);
1349                return TypeInfoFactoryKt.noTypeInfo(context);
1350            }
1351    
1352            KotlinTypeInfo rightTypeInfo = facade.getTypeInfo(right, contextWithNoExpectedType);
1353            DataFlowInfo dataFlowInfo = rightTypeInfo.getDataFlowInfo();
1354    
1355            ExpressionReceiver receiver = safeGetExpressionReceiver(facade, right, contextWithNoExpectedType);
1356            ExpressionTypingContext contextWithDataFlow = context.replaceDataFlowInfo(dataFlowInfo);
1357    
1358            OverloadResolutionResults<FunctionDescriptor> resolutionResult = components.callResolver.resolveCallWithGivenName(
1359                    contextWithDataFlow,
1360                    CallMaker.makeCall(callElement, receiver, null, operationSign, Collections.singletonList(leftArgument)),
1361                    operationSign,
1362                    OperatorNameConventions.CONTAINS);
1363            KotlinType containsType = OverloadResolutionResultsUtil.getResultingType(resolutionResult, context.contextDependency);
1364            ensureBooleanResult(operationSign, OperatorNameConventions.CONTAINS, containsType, context);
1365    
1366            if (left != null) {
1367                dataFlowInfo = facade.getTypeInfo(left, contextWithDataFlow).getDataFlowInfo().and(dataFlowInfo);
1368                rightTypeInfo = rightTypeInfo.replaceDataFlowInfo(dataFlowInfo);
1369            }
1370    
1371            if (resolutionResult.isSuccess()) {
1372                return rightTypeInfo.replaceType(components.builtIns.getBooleanType());
1373            }
1374            else {
1375                return rightTypeInfo.clearType();
1376            }
1377        }
1378    
1379    
1380        private boolean ensureBooleanResult(KtExpression operationSign, Name name, KotlinType resultType, ExpressionTypingContext context) {
1381            return ensureBooleanResultWithCustomSubject(operationSign, resultType, "'" + name + "'", context);
1382        }
1383    
1384        private boolean ensureBooleanResultWithCustomSubject(
1385                KtExpression operationSign,
1386                KotlinType resultType,
1387                String subjectName,
1388                ExpressionTypingContext context
1389        ) {
1390            if (resultType != null) {
1391                // TODO : Relax?
1392                if (!components.builtIns.isBooleanOrSubtype(resultType)) {
1393                    context.trace.report(RESULT_TYPE_MISMATCH.on(operationSign, subjectName, components.builtIns.getBooleanType(), resultType));
1394                    return false;
1395                }
1396            }
1397            return true;
1398        }
1399    
1400        private void ensureNonemptyIntersectionOfOperandTypes(KtBinaryExpression expression, final ExpressionTypingContext context) {
1401            KtExpression left = expression.getLeft();
1402            if (left == null) return;
1403    
1404            KtExpression right = expression.getRight();
1405    
1406            // TODO : duplicated effort for == and !=
1407            KotlinType leftType = facade.getTypeInfo(left, context).getType();
1408            if (leftType != null && right != null) {
1409                KotlinType rightType = facade.getTypeInfo(right, context).getType();
1410    
1411                if (rightType != null) {
1412                    if (TypeIntersector.isIntersectionEmpty(leftType, rightType)) {
1413                        context.trace.report(EQUALITY_NOT_APPLICABLE.on(expression, expression.getOperationReference(), leftType, rightType));
1414                    }
1415                    SenselessComparisonChecker.checkSenselessComparisonWithNull(
1416                            expression, left, right, context,
1417                            new Function1<KtExpression, KotlinType>() {
1418                                @Override
1419                                public KotlinType invoke(KtExpression expression) {
1420                                    return facade.getTypeInfo(expression, context).getType();
1421                                }
1422                            },
1423                            new Function1<DataFlowValue, Nullability>() {
1424                                @Override
1425                                public Nullability invoke(DataFlowValue value) {
1426                                    return context.dataFlowInfo.getPredictableNullability(value);
1427                                }
1428                            });
1429                }
1430            }
1431        }
1432    
1433        @NotNull
1434        private KotlinTypeInfo visitAssignmentOperation(KtBinaryExpression expression, ExpressionTypingContext context) {
1435            return assignmentIsNotAnExpressionError(expression, context);
1436        }
1437    
1438        @NotNull
1439        private KotlinTypeInfo visitAssignment(KtBinaryExpression expression, ExpressionTypingContext context) {
1440            return assignmentIsNotAnExpressionError(expression, context);
1441        }
1442    
1443        @NotNull
1444        private KotlinTypeInfo assignmentIsNotAnExpressionError(KtBinaryExpression expression, ExpressionTypingContext context) {
1445            facade.checkStatementType(expression, context);
1446            context.trace.report(ASSIGNMENT_IN_EXPRESSION_CONTEXT.on(expression));
1447            return TypeInfoFactoryKt.noTypeInfo(context);
1448        }
1449    
1450        @Override
1451        public KotlinTypeInfo visitArrayAccessExpression(@NotNull KtArrayAccessExpression expression, ExpressionTypingContext context) {
1452            return components.dataFlowAnalyzer.checkType(resolveArrayAccessGetMethod(expression, context), expression, context);
1453        }
1454    
1455        @Override
1456        public KotlinTypeInfo visitClass(@NotNull KtClass klass, ExpressionTypingContext context) {
1457            // analyze class in illegal position and write descriptor to trace but do not write to any scope
1458            components.localClassifierAnalyzer.processClassOrObject(
1459                    null, context.replaceContextDependency(INDEPENDENT),
1460                    context.scope.getOwnerDescriptor(),
1461                    klass
1462            );
1463            return declarationInIllegalContext(klass, context);
1464        }
1465    
1466        @NotNull
1467        private static KotlinTypeInfo declarationInIllegalContext(
1468                @NotNull KtDeclaration declaration,
1469                @NotNull ExpressionTypingContext context
1470        ) {
1471            context.trace.report(DECLARATION_IN_ILLEGAL_CONTEXT.on(declaration));
1472            return TypeInfoFactoryKt.noTypeInfo(context);
1473        }
1474    
1475        @Override
1476        public KotlinTypeInfo visitProperty(@NotNull KtProperty property, ExpressionTypingContext context) {
1477            components.localVariableResolver.process(property, context, context.scope, facade);
1478            return declarationInIllegalContext(property, context);
1479        }
1480    
1481        @NotNull
1482        public KotlinTypeInfo getTypeInfoForBinaryCall(
1483                @NotNull Name name,
1484                @NotNull ExpressionTypingContext context,
1485                @NotNull KtBinaryExpression binaryExpression
1486        ) {
1487            KtExpression left = binaryExpression.getLeft();
1488            KotlinTypeInfo typeInfo;
1489            if (left != null) {
1490                //left here is a receiver, so it doesn't depend on expected type
1491                typeInfo = facade.getTypeInfo(left, context.replaceContextDependency(INDEPENDENT).replaceExpectedType(NO_EXPECTED_TYPE));
1492            }
1493            else {
1494                typeInfo = TypeInfoFactoryKt.noTypeInfo(context);
1495            }
1496            ExpressionTypingContext contextWithDataFlow = context.replaceDataFlowInfo(typeInfo.getDataFlowInfo());
1497    
1498            OverloadResolutionResults<FunctionDescriptor> resolutionResults;
1499            if (left != null) {
1500                ExpressionReceiver receiver = safeGetExpressionReceiver(facade, left, context);
1501                resolutionResults = components.callResolver.resolveBinaryCall(
1502                        contextWithDataFlow.replaceScope(context.scope),
1503                        receiver, binaryExpression, name
1504                );
1505            }
1506            else {
1507                resolutionResults = OverloadResolutionResultsImpl.nameNotFound();
1508            }
1509    
1510            if (resolutionResults.isSingleResult()) {
1511                typeInfo = typeInfo.replaceDataFlowInfo(resolutionResults.getResultingCall().getDataFlowInfoForArguments().getResultInfo());
1512            }
1513    
1514            return typeInfo.replaceType(OverloadResolutionResultsUtil.getResultingType(resolutionResults, context.contextDependency));
1515        }
1516    
1517        @Override
1518        public KotlinTypeInfo visitDeclaration(@NotNull KtDeclaration dcl, ExpressionTypingContext context) {
1519            return declarationInIllegalContext(dcl, context);
1520        }
1521    
1522        @Override
1523        public KotlinTypeInfo visitStringTemplateExpression(
1524                @NotNull KtStringTemplateExpression expression,
1525                ExpressionTypingContext contextWithExpectedType
1526        ) {
1527            final ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(NO_EXPECTED_TYPE)
1528                                                                           .replaceContextDependency(INDEPENDENT);
1529    
1530            checkLiteralPrefixAndSuffix(expression, context);
1531    
1532            class StringTemplateVisitor extends KtVisitorVoid {
1533                private KotlinTypeInfo typeInfo = TypeInfoFactoryKt.noTypeInfo(context);
1534    
1535                @Override
1536                public void visitStringTemplateEntryWithExpression(@NotNull KtStringTemplateEntryWithExpression entry) {
1537                    KtExpression entryExpression = entry.getExpression();
1538                    if (entryExpression != null) {
1539                        typeInfo = facade.getTypeInfo(entryExpression, context.replaceDataFlowInfo(typeInfo.getDataFlowInfo()));
1540                    }
1541                }
1542    
1543                @Override
1544                public void visitEscapeStringTemplateEntry(@NotNull KtEscapeStringTemplateEntry entry) {
1545                    CompileTimeConstantChecker.CharacterWithDiagnostic value =
1546                            CompileTimeConstantChecker.escapedStringToCharacter(entry.getText(), entry);
1547                    Diagnostic diagnostic = value.getDiagnostic();
1548                    if (diagnostic != null) {
1549                        context.trace.report(diagnostic);
1550                    }
1551                }
1552            }
1553            StringTemplateVisitor visitor = new StringTemplateVisitor();
1554            for (KtStringTemplateEntry entry : expression.getEntries()) {
1555                entry.accept(visitor);
1556            }
1557            components.constantExpressionEvaluator.evaluateExpression(expression, context.trace, contextWithExpectedType.expectedType);
1558            return components.dataFlowAnalyzer.checkType(visitor.typeInfo.replaceType(components.builtIns.getStringType()),
1559                                                         expression,
1560                                                         contextWithExpectedType);
1561        }
1562    
1563        private static void checkLiteralPrefixAndSuffix(@NotNull PsiElement expression, ExpressionTypingContext context) {
1564            checkLiteralPrefixOrSuffix(PsiTreeUtil.prevLeaf(expression), context);
1565            checkLiteralPrefixOrSuffix(PsiTreeUtil.nextLeaf(expression), context);
1566        }
1567    
1568        private static void checkLiteralPrefixOrSuffix(PsiElement prefixOrSuffix, ExpressionTypingContext context) {
1569            if (illegalLiteralPrefixOrSuffix(prefixOrSuffix)) {
1570                context.trace.report(Errors.UNSUPPORTED.on(prefixOrSuffix, "literal prefixes and suffixes"));
1571            }
1572        }
1573    
1574        private static boolean illegalLiteralPrefixOrSuffix(@Nullable PsiElement element) {
1575            if (element == null) return false;
1576    
1577            IElementType elementType = element.getNode().getElementType();
1578            return elementType == IDENTIFIER ||
1579                   elementType == INTEGER_LITERAL ||
1580                   elementType == FLOAT_LITERAL ||
1581                   elementType instanceof KtKeywordToken;
1582        }
1583    
1584        @Override
1585        public KotlinTypeInfo visitAnnotatedExpression(@NotNull KtAnnotatedExpression expression, ExpressionTypingContext context) {
1586            return visitAnnotatedExpression(expression, context, false);
1587        }
1588    
1589        public KotlinTypeInfo visitAnnotatedExpression(KtAnnotatedExpression expression, ExpressionTypingContext context, boolean isStatement) {
1590            if (!(expression.getBaseExpression() instanceof KtObjectLiteralExpression)) {
1591                // annotations on object literals are resolved later inside LazyClassDescriptor
1592                components.annotationResolver.resolveAnnotationsWithArguments(context.scope, expression.getAnnotationEntries(), context.trace);
1593            }
1594    
1595            KtExpression baseExpression = expression.getBaseExpression();
1596            if (baseExpression == null) {
1597                return TypeInfoFactoryKt.noTypeInfo(context);
1598            }
1599            return facade.getTypeInfo(baseExpression, context, isStatement);
1600        }
1601    
1602        @Override
1603        public KotlinTypeInfo visitKtElement(@NotNull KtElement element, ExpressionTypingContext context) {
1604            context.trace.report(UNSUPPORTED.on(element, getClass().getCanonicalName()));
1605            return TypeInfoFactoryKt.noTypeInfo(context);
1606        }
1607    
1608        @NotNull
1609        /*package*/ KotlinTypeInfo resolveArrayAccessSetMethod(
1610                @NotNull KtArrayAccessExpression arrayAccessExpression,
1611                @NotNull KtExpression rightHandSide,
1612                @NotNull ExpressionTypingContext context,
1613                @NotNull BindingTrace traceForResolveResult
1614        ) {
1615            return resolveArrayAccessSpecialMethod(arrayAccessExpression, rightHandSide, context, traceForResolveResult, false);
1616        }
1617    
1618        @NotNull
1619        /*package*/ KotlinTypeInfo resolveArrayAccessGetMethod(
1620                @NotNull KtArrayAccessExpression arrayAccessExpression,
1621                @NotNull ExpressionTypingContext context
1622        ) {
1623            return resolveArrayAccessSpecialMethod(arrayAccessExpression, null, context, context.trace, true);
1624        }
1625    
1626        @NotNull
1627        private KotlinTypeInfo resolveArrayAccessSpecialMethod(
1628                @NotNull KtArrayAccessExpression arrayAccessExpression,
1629                @Nullable KtExpression rightHandSide, //only for 'set' method
1630                @NotNull ExpressionTypingContext oldContext,
1631                @NotNull BindingTrace traceForResolveResult,
1632                boolean isGet
1633        ) {
1634            KtExpression arrayExpression = arrayAccessExpression.getArrayExpression();
1635            if (arrayExpression == null) return TypeInfoFactoryKt.noTypeInfo(oldContext);
1636    
1637    
1638            KotlinTypeInfo arrayTypeInfo = facade.safeGetTypeInfo(arrayExpression, oldContext.replaceExpectedType(NO_EXPECTED_TYPE)
1639                    .replaceContextDependency(INDEPENDENT));
1640            KotlinType arrayType = ExpressionTypingUtils.safeGetType(arrayTypeInfo);
1641    
1642            ExpressionTypingContext context = oldContext.replaceDataFlowInfo(arrayTypeInfo.getDataFlowInfo());
1643            ExpressionReceiver receiver = ExpressionReceiver.Companion.create(arrayExpression, arrayType, context.trace.getBindingContext());
1644            if (!isGet) assert rightHandSide != null;
1645    
1646            Call call = isGet
1647                        ? CallMaker.makeArrayGetCall(receiver, arrayAccessExpression, Call.CallType.ARRAY_GET_METHOD)
1648                        : CallMaker.makeArraySetCall(receiver, arrayAccessExpression, rightHandSide, Call.CallType.ARRAY_SET_METHOD);
1649            OverloadResolutionResults<FunctionDescriptor> functionResults = components.callResolver.resolveCallWithGivenName(
1650                    context, call, arrayAccessExpression, Name.identifier(isGet ? "get" : "set"));
1651    
1652            List<KtExpression> indices = arrayAccessExpression.getIndexExpressions();
1653            // The accumulated data flow info of all index expressions is saved on the last index
1654            KotlinTypeInfo resultTypeInfo = arrayTypeInfo;
1655            if (!indices.isEmpty()) {
1656                resultTypeInfo = facade.getTypeInfo(indices.get(indices.size() - 1), context);
1657            }
1658    
1659            if (!isGet) {
1660                resultTypeInfo = facade.getTypeInfo(rightHandSide, context);
1661            }
1662    
1663            if (!functionResults.isSingleResult()) {
1664                traceForResolveResult.report(isGet ? NO_GET_METHOD.on(arrayAccessExpression) : NO_SET_METHOD.on(arrayAccessExpression));
1665                return resultTypeInfo.clearType();
1666            }
1667            traceForResolveResult.record(isGet ? INDEXED_LVALUE_GET : INDEXED_LVALUE_SET, arrayAccessExpression,
1668                                         functionResults.getResultingCall());
1669            return resultTypeInfo.replaceType(functionResults.getResultingDescriptor().getReturnType());
1670        }
1671    }