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