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