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 CallCheckerContext callCheckerContext = new CallCheckerContext(context, components.languageFeatureSettings);
600 for (CallChecker checker : components.callCheckers) {
601 checker.check(resolvedCall, expression, callCheckerContext);
602 }
603 }
604
605 private static boolean isDeclaredInClass(ReceiverParameterDescriptor receiver) {
606 return receiver.getContainingDeclaration() instanceof ClassDescriptor;
607 }
608
609 @Override
610 public KotlinTypeInfo visitBlockExpression(@NotNull KtBlockExpression expression, ExpressionTypingContext context) {
611 return components.expressionTypingServices.getBlockReturnedType(expression, context, false);
612 }
613
614 @Override
615 public KotlinTypeInfo visitClassLiteralExpression(@NotNull KtClassLiteralExpression expression, ExpressionTypingContext c) {
616 return components.doubleColonExpressionResolver.visitClassLiteralExpression(expression, c);
617 }
618
619 @Override
620 public KotlinTypeInfo visitCallableReferenceExpression(@NotNull KtCallableReferenceExpression expression, ExpressionTypingContext c) {
621 return components.doubleColonExpressionResolver.visitCallableReferenceExpression(expression, c);
622 }
623
624 @Override
625 public KotlinTypeInfo visitObjectLiteralExpression(
626 @NotNull final KtObjectLiteralExpression expression,
627 final ExpressionTypingContext context
628 ) {
629 final KotlinType[] result = new KotlinType[1];
630 TemporaryBindingTrace temporaryTrace = TemporaryBindingTrace.create(context.trace,
631 "trace to resolve object literal expression", expression);
632 ObservableBindingTrace.RecordHandler<PsiElement, ClassDescriptor> handler =
633 new ObservableBindingTrace.RecordHandler<PsiElement, ClassDescriptor>() {
634
635 @Override
636 public void handleRecord(
637 WritableSlice<PsiElement, ClassDescriptor> slice,
638 PsiElement declaration,
639 final ClassDescriptor descriptor
640 ) {
641 if (slice == CLASS && declaration == expression.getObjectDeclaration()) {
642 KotlinType defaultType = DeferredType.createRecursionIntolerant(components.globalContext.getStorageManager(),
643 context.trace,
644 new Function0<KotlinType>() {
645 @Override
646 public KotlinType invoke() {
647 return descriptor.getDefaultType();
648 }
649 });
650 result[0] = defaultType;
651 }
652 }
653 };
654 ObservableBindingTrace traceAdapter = new ObservableBindingTrace(temporaryTrace);
655 traceAdapter.addHandler(CLASS, handler);
656 components.localClassifierAnalyzer.processClassOrObject(null, // don't need to add classifier of object literal to any scope
657 context.replaceBindingTrace(traceAdapter)
658 .replaceContextDependency(INDEPENDENT),
659 context.scope.getOwnerDescriptor(),
660 expression.getObjectDeclaration());
661 temporaryTrace.commit();
662 DataFlowInfo resultFlowInfo = context.dataFlowInfo;
663 for (KtSuperTypeListEntry specifier : expression.getObjectDeclaration().getSuperTypeListEntries()) {
664 if (specifier instanceof KtSuperTypeCallEntry) {
665 KtSuperTypeCallEntry delegator = (KtSuperTypeCallEntry) specifier;
666 KotlinTypeInfo delegatorTypeInfo = context.trace.get(EXPRESSION_TYPE_INFO, delegator.getCalleeExpression());
667 if (delegatorTypeInfo != null) {
668 resultFlowInfo = resultFlowInfo.and(delegatorTypeInfo.getDataFlowInfo());
669 }
670 }
671 }
672 // Breaks are not possible inside constructor arguments, so jumpPossible or jumpFlowInfo are not necessary here
673 KotlinTypeInfo resultTypeInfo = components.dataFlowAnalyzer.checkType(TypeInfoFactoryKt.createTypeInfo(result[0], resultFlowInfo),
674 expression,
675 context);
676 // We have to record it here,
677 // otherwise ExpressionTypingVisitorDispatcher records wrong information
678 context.trace.record(EXPRESSION_TYPE_INFO, expression, resultTypeInfo);
679 context.trace.record(PROCESSED, expression);
680 return resultTypeInfo;
681 }
682
683 @Override
684 public KotlinTypeInfo visitQualifiedExpression(@NotNull KtQualifiedExpression expression, ExpressionTypingContext context) {
685 CallExpressionResolver callExpressionResolver = components.callExpressionResolver;
686 return callExpressionResolver.getQualifiedExpressionTypeInfo(expression, context);
687 }
688
689 @Override
690 public KotlinTypeInfo visitCallExpression(@NotNull KtCallExpression expression, ExpressionTypingContext context) {
691 CallExpressionResolver callExpressionResolver = components.callExpressionResolver;
692 return callExpressionResolver.getCallExpressionTypeInfo(expression, null, null, context);
693 }
694
695 @Override
696 public KotlinTypeInfo visitUnaryExpression(@NotNull KtUnaryExpression expression, ExpressionTypingContext contextWithExpectedType) {
697 ExpressionTypingContext context = isUnaryExpressionDependentOnExpectedType(expression)
698 ? contextWithExpectedType
699 : contextWithExpectedType.replaceContextDependency(INDEPENDENT)
700 .replaceExpectedType(NO_EXPECTED_TYPE);
701
702 KtExpression baseExpression = expression.getBaseExpression();
703 if (baseExpression == null) return TypeInfoFactoryKt.noTypeInfo(context);
704
705 KtSimpleNameExpression operationSign = expression.getOperationReference();
706
707 IElementType operationType = operationSign.getReferencedNameElementType();
708
709 // Special case for expr!!
710 if (operationType == KtTokens.EXCLEXCL) {
711 return visitExclExclExpression(expression, context);
712 }
713
714 // Type check the base expression
715 KotlinTypeInfo typeInfo = facade.safeGetTypeInfo(baseExpression, context);
716 KotlinType type = ExpressionTypingUtils.safeGetType(typeInfo);
717 ExpressionReceiver receiver = ExpressionReceiver.Companion.create(baseExpression, type, context.trace.getBindingContext());
718
719 Call call = CallMaker.makeCall(receiver, expression);
720
721 // Conventions for unary operations
722 Name name = OperatorConventions.UNARY_OPERATION_NAMES.get(operationType);
723 if (name == null) {
724 context.trace.report(UNSUPPORTED.on(operationSign, "visitUnaryExpression"));
725 return typeInfo.clearType();
726 }
727
728 // a[i]++/-- takes special treatment because it is actually let j = i, arr = a in arr.set(j, a.get(j).inc())
729 if ((operationType == KtTokens.PLUSPLUS || operationType == KtTokens.MINUSMINUS) &&
730 baseExpression instanceof KtArrayAccessExpression) {
731 KtExpression stubExpression = ExpressionTypingUtils.createFakeExpressionOfType(
732 baseExpression.getProject(), context.trace, "e", type);
733 TemporaryBindingTrace temporaryBindingTrace = TemporaryBindingTrace.create(
734 context.trace, "trace to resolve array access set method for unary expression", expression);
735 ExpressionTypingContext newContext = context.replaceBindingTrace(temporaryBindingTrace);
736 resolveImplicitArrayAccessSetMethod((KtArrayAccessExpression) baseExpression, stubExpression, newContext, context.trace);
737 }
738
739 // Resolve the operation reference
740 OverloadResolutionResults<FunctionDescriptor> resolutionResults = components.callResolver.resolveCallWithGivenName(
741 context, call, expression.getOperationReference(), name);
742
743 if (!resolutionResults.isSuccess()) {
744 return typeInfo.clearType();
745 }
746
747 // Computing the return type
748 KotlinType returnType = resolutionResults.getResultingDescriptor().getReturnType();
749 KotlinType result;
750 if (operationType == KtTokens.PLUSPLUS || operationType == KtTokens.MINUSMINUS) {
751 assert returnType != null : "returnType is null for " + resolutionResults.getResultingDescriptor();
752 if (KotlinBuiltIns.isUnit(returnType)) {
753 result = ErrorUtils.createErrorType(components.builtIns.getUnit().getName().asString());
754 context.trace.report(INC_DEC_SHOULD_NOT_RETURN_UNIT.on(operationSign));
755 }
756 else {
757 KotlinType receiverType = receiver.getType();
758 if (!KotlinTypeChecker.DEFAULT.isSubtypeOf(returnType, receiverType)) {
759 context.trace.report(RESULT_TYPE_MISMATCH.on(operationSign, name.asString(), receiverType, returnType));
760 }
761 else {
762 context.trace.record(BindingContext.VARIABLE_REASSIGNMENT, expression);
763 KtExpression stubExpression = ExpressionTypingUtils.createFakeExpressionOfType(
764 baseExpression.getProject(), context.trace, "e", type);
765 checkLValue(context.trace, context, baseExpression, stubExpression, expression);
766 }
767 // x++ type is x type, but ++x type is x.inc() type
768 DataFlowValue receiverValue = DataFlowValueFactory.createDataFlowValue(
769 (ReceiverValue) call.getExplicitReceiver(), contextWithExpectedType);
770 if (expression instanceof KtPrefixExpression) {
771 result = returnType;
772 }
773 else {
774 result = receiverType;
775 // Also record data flow information for x++ value (= x)
776 DataFlowValue returnValue = DataFlowValueFactory.createDataFlowValue(expression, receiverType, contextWithExpectedType);
777 typeInfo = typeInfo.replaceDataFlowInfo(typeInfo.getDataFlowInfo().assign(returnValue, receiverValue));
778 }
779 }
780 }
781 else {
782 result = returnType;
783 }
784
785 CompileTimeConstant<?> value = components.constantExpressionEvaluator.evaluateExpression(
786 expression, contextWithExpectedType.trace, contextWithExpectedType.expectedType
787 );
788 if (value != null) {
789 return components.dataFlowAnalyzer.createCompileTimeConstantTypeInfo(value, expression, contextWithExpectedType);
790 }
791
792 return components.dataFlowAnalyzer.checkType(typeInfo.replaceType(result),
793 expression,
794 contextWithExpectedType.replaceDataFlowInfo(typeInfo.getDataFlowInfo()));
795 }
796
797 private KotlinTypeInfo visitExclExclExpression(@NotNull KtUnaryExpression expression, @NotNull ExpressionTypingContext context) {
798 KtExpression baseExpression = expression.getBaseExpression();
799 assert baseExpression != null;
800 KtSimpleNameExpression operationSign = expression.getOperationReference();
801 assert operationSign.getReferencedNameElementType() == KtTokens.EXCLEXCL;
802
803 // TODO: something must be done for not to lose safe call chain information here
804 // See also CallExpressionResolver.getSimpleNameExpressionTypeInfo, .getQualifiedExpressionTypeInfo
805 Call call = createCallForSpecialConstruction(
806 expression, expression.getOperationReference(), Collections.singletonList(baseExpression));
807 components.controlStructureTypingUtils.resolveSpecialConstructionAsCall(
808 call, ResolveConstruct.EXCL_EXCL, Collections.singletonList("baseExpr"), Collections.singletonList(true), context, null);
809 KotlinTypeInfo baseTypeInfo = BindingContextUtils.getRecordedTypeInfo(baseExpression, context.trace.getBindingContext());
810
811 if (ArgumentTypeResolver.isFunctionLiteralArgument(baseExpression, context)) {
812 context.trace.report(NOT_NULL_ASSERTION_ON_LAMBDA_EXPRESSION.on(operationSign));
813 if (baseTypeInfo == null) {
814 return TypeInfoFactoryKt.createTypeInfo(ErrorUtils.createErrorType("Unresolved lambda expression"), context);
815 }
816 return baseTypeInfo;
817 }
818 assert baseTypeInfo != null : "Base expression was not processed: " + expression;
819 KotlinType baseType = baseTypeInfo.getType();
820 if (baseType == null) {
821 return baseTypeInfo;
822 }
823 DataFlowInfo dataFlowInfo = baseTypeInfo.getDataFlowInfo();
824 if (isKnownToBeNotNull(baseExpression, context) && !baseType.isError()) {
825 context.trace.report(UNNECESSARY_NOT_NULL_ASSERTION.on(operationSign, TypeUtils.makeNotNullable(baseType)));
826 }
827 else {
828 DataFlowValue value = createDataFlowValue(baseExpression, baseType, context);
829 baseTypeInfo = baseTypeInfo.replaceDataFlowInfo(dataFlowInfo.disequate(value, DataFlowValue.nullValue(components.builtIns)));
830 }
831 KotlinType resultingType = TypeUtils.makeNotNullable(baseType);
832 if (context.contextDependency == DEPENDENT) {
833 return baseTypeInfo.replaceType(resultingType);
834 }
835
836 // The call to checkType() is only needed here to execute additionalTypeCheckers, hence the NO_EXPECTED_TYPE
837 return components.dataFlowAnalyzer.checkType(
838 baseTypeInfo.replaceType(resultingType), expression, context.replaceExpectedType(NO_EXPECTED_TYPE));
839 }
840
841 @Override
842 public KotlinTypeInfo visitLabeledExpression(
843 @NotNull KtLabeledExpression expression, ExpressionTypingContext context
844 ) {
845 return visitLabeledExpression(expression, context, false);
846 }
847
848 @NotNull
849 public KotlinTypeInfo visitLabeledExpression(
850 @NotNull KtLabeledExpression expression,
851 @NotNull ExpressionTypingContext context,
852 boolean isStatement
853 ) {
854 KtSimpleNameExpression labelExpression = expression.getTargetLabel();
855 if (labelExpression != null) {
856 PsiElement labelIdentifier = labelExpression.getIdentifier();
857 UnderscoreChecker.INSTANCE.checkIdentifier(labelIdentifier, context.trace);
858 }
859 KtExpression baseExpression = expression.getBaseExpression();
860 if (baseExpression == null) return TypeInfoFactoryKt.noTypeInfo(context);
861
862 return facade.getTypeInfo(baseExpression, context, isStatement);
863 }
864
865 private static boolean isKnownToBeNotNull(KtExpression expression, ExpressionTypingContext context) {
866 KotlinType type = context.trace.getType(expression);
867 assert type != null : "This method is only supposed to be called when the type is not null";
868 return isKnownToBeNotNull(expression, type, context);
869 }
870
871 private static boolean isKnownToBeNotNull(KtExpression expression, KotlinType jetType, ExpressionTypingContext context) {
872 DataFlowValue dataFlowValue = createDataFlowValue(expression, jetType, context);
873 return !context.dataFlowInfo.getPredictableNullability(dataFlowValue).canBeNull();
874 }
875
876 /**
877 * @return {@code true} iff expression can be assigned to
878 */
879 public boolean checkLValue(
880 @NotNull BindingTrace trace,
881 @NotNull ExpressionTypingContext context,
882 @NotNull KtExpression expressionWithParenthesis,
883 @Nullable KtExpression rightHandSide,
884 @NotNull KtOperationExpression operationExpression
885 ) {
886 KtExpression expression = KtPsiUtil.deparenthesize(expressionWithParenthesis);
887 if (expression instanceof KtArrayAccessExpression) {
888 KtArrayAccessExpression arrayAccessExpression = (KtArrayAccessExpression) expression;
889 KtExpression arrayExpression = arrayAccessExpression.getArrayExpression();
890 if (arrayExpression == null || rightHandSide == null) return false;
891
892 TemporaryBindingTrace ignoreReportsTrace = TemporaryBindingTrace.create(trace, "Trace for checking set function");
893 ExpressionTypingContext findSetterContext = context.replaceBindingTrace(ignoreReportsTrace);
894 KotlinTypeInfo info = resolveArrayAccessSetMethod(arrayAccessExpression, rightHandSide, findSetterContext, ignoreReportsTrace);
895
896 IElementType operationType = operationExpression.getOperationReference().getReferencedNameElementType();
897 if (KtTokens.AUGMENTED_ASSIGNMENTS.contains(operationType)
898 || operationType == KtTokens.PLUSPLUS || operationType == KtTokens.MINUSMINUS) {
899 ResolvedCall<?> resolvedCall = ignoreReportsTrace.get(INDEXED_LVALUE_SET, expression);
900 if (resolvedCall != null) {
901 // Call must be validated with the actual, not temporary trace in order to report operator diagnostic
902 // Only unary assignment expressions (++, --) and +=/... must be checked, normal assignments have the proper trace
903 CallCheckerContext callCheckerContext = new CallCheckerContext(
904 trace, context.scope, components.languageFeatureSettings, context.dataFlowInfo, context.isAnnotationContext
905 );
906 for (CallChecker checker : components.callCheckers) {
907 checker.check(resolvedCall, expression, callCheckerContext);
908 }
909 }
910 }
911
912 return info.getType() != null;
913 }
914
915 VariableDescriptor variable = BindingContextUtils.extractVariableDescriptorIfAny(trace.getBindingContext(), expression, true);
916
917 boolean result = true;
918 KtExpression reportOn = expression != null ? expression : expressionWithParenthesis;
919 if (reportOn instanceof KtQualifiedExpression) {
920 KtExpression selector = ((KtQualifiedExpression) reportOn).getSelectorExpression();
921 if (selector != null)
922 reportOn = selector;
923 }
924
925 if (variable instanceof PropertyDescriptor) {
926 PropertyDescriptor propertyDescriptor = (PropertyDescriptor) variable;
927 PropertySetterDescriptor setter = propertyDescriptor.getSetter();
928 if (propertyDescriptor.isSetterProjectedOut()) {
929 trace.report(SETTER_PROJECTED_OUT.on(reportOn, propertyDescriptor));
930 result = false;
931 }
932 else if (setter != null) {
933 ResolvedCall<?> resolvedCall = CallUtilKt.getResolvedCall(expressionWithParenthesis, context.trace.getBindingContext());
934 assert resolvedCall != null
935 : "Call is not resolved for property setter: " + PsiUtilsKt.getElementTextWithContext(expressionWithParenthesis);
936 checkPropertySetterCall(context.replaceBindingTrace(trace), setter, resolvedCall, reportOn);
937 }
938 }
939
940 if (variable == null) {
941 trace.report(VARIABLE_EXPECTED.on(reportOn));
942 result = false;
943 }
944 else if (!variable.isVar()) {
945 result = false;
946 }
947
948 return result;
949 }
950
951 private void checkPropertySetterCall(
952 @NotNull ExpressionTypingContext context,
953 @NotNull PropertySetterDescriptor descriptor,
954 @NotNull ResolvedCall<?> propertyResolvedCall,
955 @NotNull KtExpression expression
956 ) {
957 Call call = propertyResolvedCall.getCall();
958
959 ResolutionCandidate<PropertySetterDescriptor> resolutionCandidate = ResolutionCandidate.create(
960 call, descriptor, propertyResolvedCall.getDispatchReceiver(), propertyResolvedCall.getExplicitReceiverKind(), null
961 );
962
963 ResolvedCallImpl<PropertySetterDescriptor> resolvedCall = ResolvedCallImpl.create(
964 resolutionCandidate,
965 TemporaryBindingTrace.create(context.trace, "Trace for fake property setter resolved call"),
966 TracingStrategy.EMPTY,
967 new DataFlowInfoForArgumentsImpl(propertyResolvedCall.getDataFlowInfoForArguments().getResultInfo(), call)
968 );
969 resolvedCall.markCallAsCompleted();
970
971 CallCheckerContext callCheckerContext = new CallCheckerContext(context, components.languageFeatureSettings);
972 for (CallChecker checker : components.callCheckers) {
973 checker.check(resolvedCall, expression, callCheckerContext);
974 }
975 }
976
977 @Override
978 public KotlinTypeInfo visitBinaryExpression(@NotNull KtBinaryExpression expression, ExpressionTypingContext contextWithExpectedType) {
979 ExpressionTypingContext context = isBinaryExpressionDependentOnExpectedType(expression)
980 ? contextWithExpectedType
981 : contextWithExpectedType.replaceContextDependency(INDEPENDENT)
982 .replaceExpectedType(NO_EXPECTED_TYPE);
983
984 KtSimpleNameExpression operationSign = expression.getOperationReference();
985 KtExpression left = expression.getLeft();
986 KtExpression right = expression.getRight();
987 IElementType operationType = operationSign.getReferencedNameElementType();
988
989 KotlinTypeInfo result;
990
991 //Expressions that can depend on expected type
992 if (operationType == KtTokens.IDENTIFIER) {
993 Name referencedName = operationSign.getReferencedNameAsName();
994 result = getTypeInfoForBinaryCall(referencedName, context, expression);
995 }
996 else if (OperatorConventions.BINARY_OPERATION_NAMES.containsKey(operationType)) {
997 Name referencedName = OperatorConventions.BINARY_OPERATION_NAMES.get(operationType);
998 result = getTypeInfoForBinaryCall(referencedName, context, expression);
999 }
1000 else if (operationType == KtTokens.ELVIS) {
1001 //base expression of elvis operator is checked for 'type mismatch', so the whole expression shouldn't be checked
1002 return visitElvisExpression(expression, context);
1003 }
1004
1005 //Expressions that don't depend on expected type
1006 else if (operationType == KtTokens.EQ) {
1007 result = visitAssignment(expression, context);
1008 }
1009 else if (OperatorConventions.ASSIGNMENT_OPERATIONS.containsKey(operationType)) {
1010 result = visitAssignmentOperation(expression, context);
1011 }
1012 else if (OperatorConventions.COMPARISON_OPERATIONS.contains(operationType)) {
1013 result = visitComparison(expression, context, operationSign);
1014 }
1015 else if (OperatorConventions.EQUALS_OPERATIONS.contains(operationType)) {
1016 result = visitEquality(expression, context, operationSign, left, right);
1017 }
1018 else if (OperatorConventions.IDENTITY_EQUALS_OPERATIONS.contains(operationType)) {
1019 ensureNonemptyIntersectionOfOperandTypes(expression, context);
1020 // TODO : Check comparison pointlessness
1021 result = TypeInfoFactoryKt.createTypeInfo(components.builtIns.getBooleanType(), context);
1022 }
1023 else if (OperatorConventions.IN_OPERATIONS.contains(operationType)) {
1024 ValueArgument leftArgument = CallMaker.makeValueArgument(left, left != null ? left : operationSign);
1025 result = checkInExpression(expression, operationSign, leftArgument, right, context);
1026 }
1027 else if (OperatorConventions.BOOLEAN_OPERATIONS.containsKey(operationType)) {
1028 result = visitBooleanOperationExpression(operationType, left, right, context);
1029 }
1030 else {
1031 context.trace.report(UNSUPPORTED.on(operationSign, "Unknown operation"));
1032 result = TypeInfoFactoryKt.noTypeInfo(context);
1033 }
1034 CompileTimeConstant<?> value = components.constantExpressionEvaluator.evaluateExpression(
1035 expression, contextWithExpectedType.trace, contextWithExpectedType.expectedType
1036 );
1037 if (value != null) {
1038 return components.dataFlowAnalyzer.createCompileTimeConstantTypeInfo(value, expression, contextWithExpectedType);
1039 }
1040 return components.dataFlowAnalyzer.checkType(result, expression, contextWithExpectedType);
1041 }
1042
1043 private KotlinTypeInfo visitEquality(
1044 KtBinaryExpression expression,
1045 ExpressionTypingContext context,
1046 KtSimpleNameExpression operationSign,
1047 final KtExpression left,
1048 final KtExpression right
1049 ) {
1050 if (right == null || left == null) {
1051 ExpressionTypingUtils.getTypeInfoOrNullType(right, context, facade);
1052 ExpressionTypingUtils.getTypeInfoOrNullType(left, context, facade);
1053 return TypeInfoFactoryKt.createTypeInfo(components.builtIns.getBooleanType(), context);
1054 }
1055
1056 KotlinTypeInfo leftTypeInfo = getTypeInfoOrNullType(left, context, facade);
1057
1058 DataFlowInfo dataFlowInfo = leftTypeInfo.getDataFlowInfo();
1059 ExpressionTypingContext contextWithDataFlow = context.replaceDataFlowInfo(dataFlowInfo);
1060
1061 KotlinTypeInfo rightTypeInfo = facade.getTypeInfo(right, contextWithDataFlow);
1062
1063 TemporaryBindingTrace traceInterpretingRightAsNullableAny = TemporaryBindingTrace.create(
1064 context.trace, "trace to resolve 'equals(Any?)' interpreting as of type Any? an expression:", right);
1065 traceInterpretingRightAsNullableAny.recordType(right, components.builtIns.getNullableAnyType());
1066
1067 // Nothing? has no members, and `equals()` would be unresolved on it
1068 KotlinType leftType = leftTypeInfo.getType();
1069 if (leftType != null && KotlinBuiltIns.isNothingOrNullableNothing(leftType)) {
1070 traceInterpretingRightAsNullableAny.recordType(left, components.builtIns.getNullableAnyType());
1071 }
1072
1073 ExpressionTypingContext newContext = context.replaceBindingTrace(traceInterpretingRightAsNullableAny);
1074 ExpressionReceiver receiver = ExpressionTypingUtils.safeGetExpressionReceiver(facade, left, newContext);
1075 Call call = CallMaker.makeCallWithExpressions(
1076 expression,
1077 receiver,
1078 // semantically, a call to `==` is a safe call
1079 new KtPsiFactory(expression.getProject()).createSafeCallNode(),
1080 operationSign,
1081 Collections.singletonList(right)
1082 );
1083 OverloadResolutionResults<FunctionDescriptor> resolutionResults =
1084 components.callResolver.resolveCallWithGivenName(newContext, call, operationSign, OperatorNameConventions.EQUALS);
1085
1086 traceInterpretingRightAsNullableAny.commit(new TraceEntryFilter() {
1087 @Override
1088 public boolean accept(@Nullable WritableSlice<?, ?> slice, Object key) {
1089 // the type of the right (and sometimes left) expression isn't 'Any?' actually
1090 if ((key == right || key == left) && slice == EXPRESSION_TYPE_INFO) return false;
1091
1092 // a hack due to KT-678
1093 // without this line an smartcast is reported on the receiver (if it was previously checked for not-null)
1094 // with not-null check the resolution result changes from 'fun Any?.equals' to 'equals' member
1095 if (key == left && slice == SMARTCAST) return false;
1096
1097 return true;
1098 }
1099 }, true);
1100
1101 if (resolutionResults.isSuccess()) {
1102 FunctionDescriptor equals = resolutionResults.getResultingCall().getResultingDescriptor();
1103 if (ensureBooleanResult(operationSign, OperatorNameConventions.EQUALS, equals.getReturnType(), context)) {
1104 ensureNonemptyIntersectionOfOperandTypes(expression, context);
1105 }
1106 }
1107 else {
1108 if (resolutionResults.isAmbiguity()) {
1109 context.trace.report(OVERLOAD_RESOLUTION_AMBIGUITY.on(operationSign, resolutionResults.getResultingCalls()));
1110 }
1111 else {
1112 context.trace.report(EQUALS_MISSING.on(operationSign));
1113 }
1114 }
1115 return rightTypeInfo.replaceType(components.builtIns.getBooleanType());
1116 }
1117
1118 @NotNull
1119 private KotlinTypeInfo visitComparison(
1120 @NotNull KtBinaryExpression expression,
1121 @NotNull ExpressionTypingContext context,
1122 @NotNull KtSimpleNameExpression operationSign
1123 ) {
1124 KotlinTypeInfo typeInfo = getTypeInfoForBinaryCall(OperatorNameConventions.COMPARE_TO, context, expression);
1125 KotlinType compareToReturnType = typeInfo.getType();
1126 KotlinType type = null;
1127 if (compareToReturnType != null && !compareToReturnType.isError()) {
1128 if (KotlinTypeChecker.DEFAULT.equalTypes(components.builtIns.getIntType(), compareToReturnType)) {
1129 type = components.builtIns.getBooleanType();
1130 }
1131 else {
1132 context.trace.report(COMPARE_TO_TYPE_MISMATCH.on(operationSign, compareToReturnType));
1133 }
1134 }
1135 return typeInfo.replaceType(type);
1136 }
1137
1138 @NotNull
1139 private KotlinTypeInfo visitBooleanOperationExpression(
1140 @Nullable IElementType operationType,
1141 @Nullable KtExpression left,
1142 @Nullable KtExpression right,
1143 @NotNull ExpressionTypingContext context
1144 ) {
1145 KotlinType booleanType = components.builtIns.getBooleanType();
1146 KotlinTypeInfo leftTypeInfo = getTypeInfoOrNullType(left, context.replaceExpectedType(booleanType), facade);
1147 DataFlowInfo dataFlowInfo = leftTypeInfo.getDataFlowInfo();
1148
1149 LexicalWritableScope leftScope = newWritableScopeImpl(context, LexicalScopeKind.LEFT_BOOLEAN_EXPRESSION);
1150 // TODO: This gets computed twice: here and in extractDataFlowInfoFromCondition() for the whole condition
1151 boolean isAnd = operationType == KtTokens.ANDAND;
1152 DataFlowInfo flowInfoLeft = components.dataFlowAnalyzer.extractDataFlowInfoFromCondition(left, isAnd, context).and(dataFlowInfo);
1153 LexicalWritableScope rightScope = isAnd ? leftScope : newWritableScopeImpl(context, LexicalScopeKind.RIGHT_BOOLEAN_EXPRESSION);
1154
1155 ExpressionTypingContext contextForRightExpr =
1156 context.replaceDataFlowInfo(flowInfoLeft).replaceScope(rightScope).replaceExpectedType(booleanType);
1157 if (right != null) {
1158 facade.getTypeInfo(right, contextForRightExpr);
1159 }
1160 return leftTypeInfo.replaceType(booleanType);
1161 }
1162
1163 @NotNull
1164 private KotlinTypeInfo visitElvisExpression(
1165 @NotNull KtBinaryExpression expression,
1166 @NotNull ExpressionTypingContext contextWithExpectedType
1167 ) {
1168 ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(NO_EXPECTED_TYPE);
1169 KtExpression left = expression.getLeft();
1170 KtExpression right = expression.getRight();
1171
1172 if (left == null || right == null) {
1173 getTypeInfoOrNullType(left, context, facade);
1174 return TypeInfoFactoryKt.noTypeInfo(context);
1175 }
1176
1177 Call call = createCallForSpecialConstruction(expression, expression.getOperationReference(), Lists.newArrayList(left, right));
1178 ResolvedCall<FunctionDescriptor> resolvedCall = components.controlStructureTypingUtils.resolveSpecialConstructionAsCall(
1179 call, ResolveConstruct.ELVIS, Lists.newArrayList("left", "right"),
1180 Lists.newArrayList(true, false), contextWithExpectedType, null);
1181 KotlinTypeInfo leftTypeInfo = BindingContextUtils.getRecordedTypeInfo(left, context.trace.getBindingContext());
1182 if (ArgumentTypeResolver.isFunctionLiteralArgument(left, context)) {
1183 context.trace.report(USELESS_ELVIS_ON_LAMBDA_EXPRESSION.on(expression.getOperationReference()));
1184 if (leftTypeInfo == null) return TypeInfoFactoryKt.noTypeInfo(context);
1185 }
1186 assert leftTypeInfo != null : "Left expression was not processed: " + expression;
1187 KotlinType leftType = leftTypeInfo.getType();
1188 if (leftType != null && isKnownToBeNotNull(left, leftType, context)) {
1189 context.trace.report(USELESS_ELVIS.on(expression, leftType));
1190 }
1191 KotlinTypeInfo rightTypeInfo = BindingContextUtils.getRecordedTypeInfo(right, context.trace.getBindingContext());
1192 if (rightTypeInfo == null && ArgumentTypeResolver.isFunctionLiteralArgument(right, context)) {
1193 // the type is computed later in call completer according to the '?:' semantics as a function
1194 return TypeInfoFactoryKt.noTypeInfo(context);
1195 }
1196 assert rightTypeInfo != null : "Right expression was not processed: " + expression;
1197 boolean loopBreakContinuePossible = leftTypeInfo.getJumpOutPossible() || rightTypeInfo.getJumpOutPossible();
1198 KotlinType rightType = rightTypeInfo.getType();
1199
1200 // Only left argument DFA is taken into account here: we cannot be sure that right argument is joined
1201 // (we merge it with right DFA if right argument contains no jump outside)
1202 DataFlowInfo dataFlowInfo = resolvedCall.getDataFlowInfoForArguments().getInfo(call.getValueArguments().get(1));
1203
1204 KotlinType type = resolvedCall.getResultingDescriptor().getReturnType();
1205 if (type == null ||
1206 rightType == null ||
1207 leftType == null && KotlinBuiltIns.isNothing(rightType)) return TypeInfoFactoryKt.noTypeInfo(dataFlowInfo);
1208
1209 if (leftType != null) {
1210 DataFlowValue leftValue = createDataFlowValue(left, leftType, context);
1211 DataFlowInfo rightDataFlowInfo = resolvedCall.getDataFlowInfoForArguments().getResultInfo();
1212 boolean jumpInRight = KotlinBuiltIns.isNothing(rightType);
1213 DataFlowValue nullValue = DataFlowValue.nullValue(components.builtIns);
1214 // left argument is considered not-null if it's not-null also in right part or if we have jump in right part
1215 if (jumpInRight || !rightDataFlowInfo.getPredictableNullability(leftValue).canBeNull()) {
1216 dataFlowInfo = dataFlowInfo.disequate(leftValue, nullValue);
1217 if (left instanceof KtBinaryExpressionWithTypeRHS) {
1218 dataFlowInfo = establishSubtypingForTypeRHS((KtBinaryExpressionWithTypeRHS) left, dataFlowInfo, context);
1219 }
1220 }
1221 DataFlowValue resultValue = DataFlowValueFactory.createDataFlowValue(expression, type, context);
1222 dataFlowInfo = dataFlowInfo.assign(resultValue, leftValue).disequate(resultValue, nullValue);
1223 if (!jumpInRight) {
1224 DataFlowValue rightValue = DataFlowValueFactory.createDataFlowValue(right, rightType, context);
1225 rightDataFlowInfo = rightDataFlowInfo.assign(resultValue, rightValue);
1226 dataFlowInfo = dataFlowInfo.or(rightDataFlowInfo);
1227 }
1228 }
1229
1230 // Sometimes return type for special call for elvis operator might be nullable,
1231 // but result is not nullable if the right type is not nullable
1232 if (!TypeUtils.isNullableType(rightType) && TypeUtils.isNullableType(type)) {
1233 type = TypeUtils.makeNotNullable(type);
1234 }
1235 if (context.contextDependency == DEPENDENT) {
1236 return TypeInfoFactoryKt.createTypeInfo(type, dataFlowInfo);
1237 }
1238
1239 // If break or continue was possible, take condition check info as the jump info
1240 return TypeInfoFactoryKt.createTypeInfo(components.dataFlowAnalyzer.checkType(type, expression, contextWithExpectedType),
1241 dataFlowInfo,
1242 loopBreakContinuePossible,
1243 context.dataFlowInfo);
1244 }
1245
1246 @NotNull
1247 private static DataFlowInfo establishSubtypingForTypeRHS(
1248 @NotNull KtBinaryExpressionWithTypeRHS left,
1249 @NotNull DataFlowInfo dataFlowInfo,
1250 @NotNull ExpressionTypingContext context
1251 ) {
1252 IElementType operationType = left.getOperationReference().getReferencedNameElementType();
1253 if (operationType == AS_SAFE) {
1254 KtExpression underSafeAs = left.getLeft();
1255 KotlinType underSafeAsType = context.trace.getType(underSafeAs);
1256 if (underSafeAsType != null) {
1257 DataFlowValue underSafeAsValue = createDataFlowValue(underSafeAs, underSafeAsType, context);
1258 KotlinType targetType = context.trace.get(BindingContext.TYPE, left.getRight());
1259 if (targetType != null) {
1260 return dataFlowInfo.establishSubtyping(underSafeAsValue, targetType);
1261 }
1262 }
1263 }
1264 return dataFlowInfo;
1265 }
1266
1267 @NotNull
1268 public KotlinTypeInfo checkInExpression(
1269 @NotNull KtElement callElement,
1270 @NotNull KtSimpleNameExpression operationSign,
1271 @NotNull ValueArgument leftArgument,
1272 @Nullable KtExpression right,
1273 @NotNull ExpressionTypingContext context
1274 ) {
1275 KtExpression left = leftArgument.getArgumentExpression();
1276 ExpressionTypingContext contextWithNoExpectedType = context.replaceExpectedType(NO_EXPECTED_TYPE);
1277 if (right == null) {
1278 if (left != null) facade.getTypeInfo(left, contextWithNoExpectedType);
1279 return TypeInfoFactoryKt.noTypeInfo(context);
1280 }
1281
1282 KotlinTypeInfo rightTypeInfo = facade.getTypeInfo(right, contextWithNoExpectedType);
1283 DataFlowInfo dataFlowInfo = rightTypeInfo.getDataFlowInfo();
1284
1285 ExpressionReceiver receiver = safeGetExpressionReceiver(facade, right, contextWithNoExpectedType);
1286 ExpressionTypingContext contextWithDataFlow = context.replaceDataFlowInfo(dataFlowInfo);
1287
1288 OverloadResolutionResults<FunctionDescriptor> resolutionResult = components.callResolver.resolveCallWithGivenName(
1289 contextWithDataFlow,
1290 CallMaker.makeCall(callElement, receiver, null, operationSign, Collections.singletonList(leftArgument)),
1291 operationSign,
1292 OperatorNameConventions.CONTAINS);
1293 KotlinType containsType = OverloadResolutionResultsUtil.getResultingType(resolutionResult, context.contextDependency);
1294 ensureBooleanResult(operationSign, OperatorNameConventions.CONTAINS, containsType, context);
1295
1296 if (left != null) {
1297 dataFlowInfo = facade.getTypeInfo(left, contextWithDataFlow).getDataFlowInfo().and(dataFlowInfo);
1298 rightTypeInfo = rightTypeInfo.replaceDataFlowInfo(dataFlowInfo);
1299 }
1300
1301 if (resolutionResult.isSuccess()) {
1302 return rightTypeInfo.replaceType(components.builtIns.getBooleanType());
1303 }
1304 else {
1305 return rightTypeInfo.clearType();
1306 }
1307 }
1308
1309
1310 private boolean ensureBooleanResult(KtExpression operationSign, Name name, KotlinType resultType, ExpressionTypingContext context) {
1311 return ensureBooleanResultWithCustomSubject(operationSign, resultType, "'" + name + "'", context);
1312 }
1313
1314 private boolean ensureBooleanResultWithCustomSubject(
1315 KtExpression operationSign,
1316 KotlinType resultType,
1317 String subjectName,
1318 ExpressionTypingContext context
1319 ) {
1320 if (resultType != null) {
1321 // TODO : Relax?
1322 if (!components.builtIns.isBooleanOrSubtype(resultType)) {
1323 context.trace.report(RESULT_TYPE_MISMATCH.on(operationSign, subjectName, components.builtIns.getBooleanType(), resultType));
1324 return false;
1325 }
1326 }
1327 return true;
1328 }
1329
1330 private void ensureNonemptyIntersectionOfOperandTypes(KtBinaryExpression expression, final ExpressionTypingContext context) {
1331 KtExpression left = expression.getLeft();
1332 if (left == null) return;
1333
1334 KtExpression right = expression.getRight();
1335
1336 // TODO : duplicated effort for == and !=
1337 KotlinType leftType = facade.getTypeInfo(left, context).getType();
1338 if (leftType != null && right != null) {
1339 KotlinType rightType = facade.getTypeInfo(right, context).getType();
1340
1341 if (rightType != null) {
1342 if (TypeIntersector.isIntersectionEmpty(leftType, rightType)) {
1343 context.trace.report(EQUALITY_NOT_APPLICABLE.on(expression, expression.getOperationReference(), leftType, rightType));
1344 }
1345 SenselessComparisonChecker.checkSenselessComparisonWithNull(
1346 expression, left, right, context,
1347 new Function1<KtExpression, KotlinType>() {
1348 @Override
1349 public KotlinType invoke(KtExpression expression) {
1350 return facade.getTypeInfo(expression, context).getType();
1351 }
1352 },
1353 new Function1<DataFlowValue, Nullability>() {
1354 @Override
1355 public Nullability invoke(DataFlowValue value) {
1356 return context.dataFlowInfo.getPredictableNullability(value);
1357 }
1358 });
1359 }
1360 }
1361 }
1362
1363 @NotNull
1364 private KotlinTypeInfo visitAssignmentOperation(KtBinaryExpression expression, ExpressionTypingContext context) {
1365 return assignmentIsNotAnExpressionError(expression, context);
1366 }
1367
1368 @NotNull
1369 private KotlinTypeInfo visitAssignment(KtBinaryExpression expression, ExpressionTypingContext context) {
1370 return assignmentIsNotAnExpressionError(expression, context);
1371 }
1372
1373 @NotNull
1374 private KotlinTypeInfo assignmentIsNotAnExpressionError(KtBinaryExpression expression, ExpressionTypingContext context) {
1375 facade.checkStatementType(expression, context);
1376 context.trace.report(ASSIGNMENT_IN_EXPRESSION_CONTEXT.on(expression));
1377 return TypeInfoFactoryKt.noTypeInfo(context);
1378 }
1379
1380 @Override
1381 public KotlinTypeInfo visitArrayAccessExpression(@NotNull KtArrayAccessExpression expression, ExpressionTypingContext context) {
1382 return components.dataFlowAnalyzer.checkType(resolveArrayAccessGetMethod(expression, context), expression, context);
1383 }
1384
1385 @Override
1386 public KotlinTypeInfo visitClass(@NotNull KtClass klass, ExpressionTypingContext context) {
1387 // analyze class in illegal position and write descriptor to trace but do not write to any scope
1388 components.localClassifierAnalyzer.processClassOrObject(
1389 null, context.replaceContextDependency(INDEPENDENT),
1390 context.scope.getOwnerDescriptor(),
1391 klass
1392 );
1393 return declarationInIllegalContext(klass, context);
1394 }
1395
1396 @NotNull
1397 private static KotlinTypeInfo declarationInIllegalContext(
1398 @NotNull KtDeclaration declaration,
1399 @NotNull ExpressionTypingContext context
1400 ) {
1401 context.trace.report(DECLARATION_IN_ILLEGAL_CONTEXT.on(declaration));
1402 return TypeInfoFactoryKt.noTypeInfo(context);
1403 }
1404
1405 @Override
1406 public KotlinTypeInfo visitProperty(@NotNull KtProperty property, ExpressionTypingContext context) {
1407 components.localVariableResolver.process(property, context, context.scope, facade);
1408 return declarationInIllegalContext(property, context);
1409 }
1410
1411 @NotNull
1412 public KotlinTypeInfo getTypeInfoForBinaryCall(
1413 @NotNull Name name,
1414 @NotNull ExpressionTypingContext context,
1415 @NotNull KtBinaryExpression binaryExpression
1416 ) {
1417 KtExpression left = binaryExpression.getLeft();
1418 KotlinTypeInfo typeInfo;
1419 if (left != null) {
1420 //left here is a receiver, so it doesn't depend on expected type
1421 typeInfo = facade.getTypeInfo(left, context.replaceContextDependency(INDEPENDENT).replaceExpectedType(NO_EXPECTED_TYPE));
1422 }
1423 else {
1424 typeInfo = TypeInfoFactoryKt.noTypeInfo(context);
1425 }
1426 ExpressionTypingContext contextWithDataFlow = context.replaceDataFlowInfo(typeInfo.getDataFlowInfo());
1427
1428 OverloadResolutionResults<FunctionDescriptor> resolutionResults;
1429 if (left != null) {
1430 ExpressionReceiver receiver = safeGetExpressionReceiver(facade, left, context);
1431 resolutionResults = components.callResolver.resolveBinaryCall(
1432 contextWithDataFlow.replaceScope(context.scope),
1433 receiver, binaryExpression, name
1434 );
1435 }
1436 else {
1437 resolutionResults = OverloadResolutionResultsImpl.nameNotFound();
1438 }
1439
1440 if (resolutionResults.isSingleResult()) {
1441 typeInfo = typeInfo.replaceDataFlowInfo(resolutionResults.getResultingCall().getDataFlowInfoForArguments().getResultInfo());
1442 }
1443
1444 return typeInfo.replaceType(OverloadResolutionResultsUtil.getResultingType(resolutionResults, context.contextDependency));
1445 }
1446
1447 @Override
1448 public KotlinTypeInfo visitDeclaration(@NotNull KtDeclaration dcl, ExpressionTypingContext context) {
1449 return declarationInIllegalContext(dcl, context);
1450 }
1451
1452 @Override
1453 public KotlinTypeInfo visitStringTemplateExpression(
1454 @NotNull KtStringTemplateExpression expression,
1455 ExpressionTypingContext contextWithExpectedType
1456 ) {
1457 final ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(NO_EXPECTED_TYPE)
1458 .replaceContextDependency(INDEPENDENT);
1459
1460 checkLiteralPrefixAndSuffix(expression, context);
1461
1462 class StringTemplateVisitor extends KtVisitorVoid {
1463 private KotlinTypeInfo typeInfo = TypeInfoFactoryKt.noTypeInfo(context);
1464
1465 @Override
1466 public void visitStringTemplateEntryWithExpression(@NotNull KtStringTemplateEntryWithExpression entry) {
1467 KtExpression entryExpression = entry.getExpression();
1468 if (entryExpression != null) {
1469 typeInfo = facade.getTypeInfo(entryExpression, context.replaceDataFlowInfo(typeInfo.getDataFlowInfo()));
1470 }
1471 }
1472
1473 @Override
1474 public void visitEscapeStringTemplateEntry(@NotNull KtEscapeStringTemplateEntry entry) {
1475 CompileTimeConstantChecker.CharacterWithDiagnostic value =
1476 CompileTimeConstantChecker.escapedStringToCharacter(entry.getText(), entry);
1477 Diagnostic diagnostic = value.getDiagnostic();
1478 if (diagnostic != null) {
1479 context.trace.report(diagnostic);
1480 }
1481 }
1482 }
1483 StringTemplateVisitor visitor = new StringTemplateVisitor();
1484 for (KtStringTemplateEntry entry : expression.getEntries()) {
1485 entry.accept(visitor);
1486 }
1487 components.constantExpressionEvaluator.evaluateExpression(expression, context.trace, contextWithExpectedType.expectedType);
1488 return components.dataFlowAnalyzer.checkType(visitor.typeInfo.replaceType(components.builtIns.getStringType()),
1489 expression,
1490 contextWithExpectedType);
1491 }
1492
1493 private static void checkLiteralPrefixAndSuffix(@NotNull PsiElement expression, ExpressionTypingContext context) {
1494 checkLiteralPrefixOrSuffix(PsiTreeUtil.prevLeaf(expression), context);
1495 checkLiteralPrefixOrSuffix(PsiTreeUtil.nextLeaf(expression), context);
1496 }
1497
1498 private static void checkLiteralPrefixOrSuffix(PsiElement prefixOrSuffix, ExpressionTypingContext context) {
1499 if (illegalLiteralPrefixOrSuffix(prefixOrSuffix)) {
1500 context.trace.report(Errors.UNSUPPORTED.on(prefixOrSuffix, "literal prefixes and suffixes"));
1501 }
1502 }
1503
1504 private static boolean illegalLiteralPrefixOrSuffix(@Nullable PsiElement element) {
1505 if (element == null) return false;
1506
1507 IElementType elementType = element.getNode().getElementType();
1508 return elementType == IDENTIFIER ||
1509 elementType == INTEGER_LITERAL ||
1510 elementType == FLOAT_LITERAL ||
1511 elementType instanceof KtKeywordToken;
1512 }
1513
1514 @Override
1515 public KotlinTypeInfo visitAnnotatedExpression(@NotNull KtAnnotatedExpression expression, ExpressionTypingContext context) {
1516 return visitAnnotatedExpression(expression, context, false);
1517 }
1518
1519 public KotlinTypeInfo visitAnnotatedExpression(KtAnnotatedExpression expression, ExpressionTypingContext context, boolean isStatement) {
1520 if (!(expression.getBaseExpression() instanceof KtObjectLiteralExpression)) {
1521 // annotations on object literals are resolved later inside LazyClassDescriptor
1522 components.annotationResolver.resolveAnnotationsWithArguments(context.scope, expression.getAnnotationEntries(), context.trace);
1523 }
1524
1525 KtExpression baseExpression = expression.getBaseExpression();
1526 if (baseExpression == null) {
1527 return TypeInfoFactoryKt.noTypeInfo(context);
1528 }
1529 return facade.getTypeInfo(baseExpression, context, isStatement);
1530 }
1531
1532 @Override
1533 public KotlinTypeInfo visitKtElement(@NotNull KtElement element, ExpressionTypingContext context) {
1534 context.trace.report(UNSUPPORTED.on(element, getClass().getCanonicalName()));
1535 return TypeInfoFactoryKt.noTypeInfo(context);
1536 }
1537
1538 @NotNull
1539 /*package*/ KotlinTypeInfo resolveArrayAccessSetMethod(
1540 @NotNull KtArrayAccessExpression arrayAccessExpression,
1541 @NotNull KtExpression rightHandSide,
1542 @NotNull ExpressionTypingContext context,
1543 @NotNull BindingTrace traceForResolveResult
1544 ) {
1545 return resolveArrayAccessSpecialMethod(arrayAccessExpression, rightHandSide, context, traceForResolveResult, false, false);
1546 }
1547
1548 @NotNull
1549 /*package*/ KotlinTypeInfo resolveImplicitArrayAccessSetMethod(
1550 @NotNull KtArrayAccessExpression arrayAccessExpression,
1551 @NotNull KtExpression rightHandSide,
1552 @NotNull ExpressionTypingContext context,
1553 @NotNull BindingTrace traceForResolveResult
1554 ) {
1555 return resolveArrayAccessSpecialMethod(arrayAccessExpression, rightHandSide, context, traceForResolveResult, false, true);
1556 }
1557
1558 @NotNull
1559 /*package*/ KotlinTypeInfo resolveArrayAccessGetMethod(
1560 @NotNull KtArrayAccessExpression arrayAccessExpression,
1561 @NotNull ExpressionTypingContext context
1562 ) {
1563 return resolveArrayAccessSpecialMethod(arrayAccessExpression, null, context, context.trace, true, false);
1564 }
1565
1566 @NotNull
1567 private KotlinTypeInfo resolveArrayAccessSpecialMethod(
1568 @NotNull KtArrayAccessExpression arrayAccessExpression,
1569 @Nullable KtExpression rightHandSide, //only for 'set' method
1570 @NotNull ExpressionTypingContext oldContext,
1571 @NotNull BindingTrace traceForResolveResult,
1572 boolean isGet,
1573 boolean isImplicit
1574 ) {
1575 KtExpression arrayExpression = arrayAccessExpression.getArrayExpression();
1576 if (arrayExpression == null) return TypeInfoFactoryKt.noTypeInfo(oldContext);
1577
1578
1579 KotlinTypeInfo arrayTypeInfo = facade.safeGetTypeInfo(arrayExpression, oldContext.replaceExpectedType(NO_EXPECTED_TYPE)
1580 .replaceContextDependency(INDEPENDENT));
1581 KotlinType arrayType = ExpressionTypingUtils.safeGetType(arrayTypeInfo);
1582
1583 ExpressionTypingContext context = oldContext.replaceDataFlowInfo(arrayTypeInfo.getDataFlowInfo());
1584 ExpressionReceiver receiver = ExpressionReceiver.Companion.create(arrayExpression, arrayType, context.trace.getBindingContext());
1585 if (!isGet) assert rightHandSide != null;
1586
1587 Call call = isGet
1588 ? CallMaker.makeArrayGetCall(receiver, arrayAccessExpression, Call.CallType.ARRAY_GET_METHOD)
1589 : CallMaker.makeArraySetCall(receiver, arrayAccessExpression, rightHandSide, Call.CallType.ARRAY_SET_METHOD);
1590 OverloadResolutionResults<FunctionDescriptor> functionResults = components.callResolver.resolveCallWithGivenName(
1591 context, call, arrayAccessExpression, Name.identifier(isGet ? "get" : "set"));
1592
1593 List<KtExpression> indices = arrayAccessExpression.getIndexExpressions();
1594 // The accumulated data flow info of all index expressions is saved on the last index
1595 KotlinTypeInfo resultTypeInfo = arrayTypeInfo;
1596 if (!indices.isEmpty()) {
1597 resultTypeInfo = facade.getTypeInfo(indices.get(indices.size() - 1), context);
1598 }
1599
1600 if (!isGet) {
1601 resultTypeInfo = facade.getTypeInfo(rightHandSide, context);
1602 }
1603
1604 if ((isImplicit && !functionResults.isSuccess()) || !functionResults.isSingleResult()) {
1605 traceForResolveResult.report(isGet ? NO_GET_METHOD.on(arrayAccessExpression) : NO_SET_METHOD.on(arrayAccessExpression));
1606 return resultTypeInfo.clearType();
1607 }
1608 traceForResolveResult.record(isGet ? INDEXED_LVALUE_GET : INDEXED_LVALUE_SET, arrayAccessExpression,
1609 functionResults.getResultingCall());
1610 return resultTypeInfo.replaceType(functionResults.getResultingDescriptor().getReturnType());
1611 }
1612 }