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