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