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