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