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