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