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