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 }