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