32
32
import org .jetbrains .kotlin .resolve .calls .context .CheckArgumentTypesMode ;
33
33
import org .jetbrains .kotlin .resolve .calls .context .ResolutionContext ;
34
34
import org .jetbrains .kotlin .resolve .calls .context .TemporaryTraceAndCache ;
35
+ import org .jetbrains .kotlin .resolve .calls .model .DataFlowInfoForArgumentsImpl ;
35
36
import org .jetbrains .kotlin .resolve .calls .model .ResolvedCall ;
36
37
import org .jetbrains .kotlin .resolve .calls .results .OverloadResolutionResults ;
37
38
import org .jetbrains .kotlin .resolve .calls .results .OverloadResolutionResultsUtil ;
@@ -95,13 +96,15 @@ public void setExpressionTypingServices(@NotNull ExpressionTypingServices expres
95
96
}
96
97
97
98
@ Nullable
98
- public ResolvedCall <FunctionDescriptor > getResolvedCallForFunction (
99
+ private ResolvedCall <FunctionDescriptor > getResolvedCallForFunction (
99
100
@ NotNull Call call ,
100
101
@ NotNull ResolutionContext context , @ NotNull CheckArgumentTypesMode checkArguments ,
101
- @ NotNull boolean [] result
102
+ @ NotNull boolean [] result ,
103
+ @ NotNull DataFlowInfo initialDataFlowInfoForArguments
102
104
) {
103
105
OverloadResolutionResults <FunctionDescriptor > results = callResolver .resolveFunctionCall (
104
- BasicCallResolutionContext .create (context , call , checkArguments ));
106
+ BasicCallResolutionContext .create (context , call , checkArguments ,
107
+ new DataFlowInfoForArgumentsImpl (initialDataFlowInfoForArguments , call )));
105
108
if (!results .isNothing ()) {
106
109
result [0 ] = true ;
107
110
return OverloadResolutionResultsUtil .getResultingCall (results , context .contextDependency );
@@ -145,6 +148,15 @@ private KotlinType getVariableType(
145
148
public KotlinTypeInfo getSimpleNameExpressionTypeInfo (
146
149
@ NotNull KtSimpleNameExpression nameExpression , @ Nullable Receiver receiver ,
147
150
@ Nullable ASTNode callOperationNode , @ NotNull ExpressionTypingContext context
151
+ ) {
152
+ return getSimpleNameExpressionTypeInfo (nameExpression , receiver , callOperationNode , context , context .dataFlowInfo );
153
+ }
154
+
155
+ @ NotNull
156
+ private KotlinTypeInfo getSimpleNameExpressionTypeInfo (
157
+ @ NotNull KtSimpleNameExpression nameExpression , @ Nullable Receiver receiver ,
158
+ @ Nullable ASTNode callOperationNode , @ NotNull ExpressionTypingContext context ,
159
+ @ NotNull DataFlowInfo initialDataFlowInfoForArguments
148
160
) {
149
161
boolean [] result = new boolean [1 ];
150
162
@@ -155,15 +167,15 @@ public KotlinTypeInfo getSimpleNameExpressionTypeInfo(
155
167
156
168
if (result [0 ]) {
157
169
temporaryForVariable .commit ();
158
- return TypeInfoFactoryKt .createTypeInfo (type , context );
170
+ return TypeInfoFactoryKt .createTypeInfo (type , initialDataFlowInfoForArguments );
159
171
}
160
172
161
173
Call call = CallMaker .makeCall (nameExpression , receiver , callOperationNode , nameExpression , Collections .<ValueArgument >emptyList ());
162
174
TemporaryTraceAndCache temporaryForFunction = TemporaryTraceAndCache .create (
163
175
context , "trace to resolve as function" , nameExpression );
164
176
ResolutionContext newContext = context .replaceTraceAndCache (temporaryForFunction );
165
177
ResolvedCall <FunctionDescriptor > resolvedCall = getResolvedCallForFunction (
166
- call , newContext , CheckArgumentTypesMode .CHECK_VALUE_ARGUMENTS , result );
178
+ call , newContext , CheckArgumentTypesMode .CHECK_VALUE_ARGUMENTS , result , initialDataFlowInfoForArguments );
167
179
if (result [0 ]) {
168
180
FunctionDescriptor functionDescriptor = resolvedCall != null ? resolvedCall .getResultingDescriptor () : null ;
169
181
if (!(functionDescriptor instanceof ConstructorDescriptor )) {
@@ -193,7 +205,8 @@ public KotlinTypeInfo getCallExpressionTypeInfo(
193
205
@ NotNull KtCallExpression callExpression , @ Nullable ReceiverValue receiver ,
194
206
@ Nullable ASTNode callOperationNode , @ NotNull ExpressionTypingContext context
195
207
) {
196
- KotlinTypeInfo typeInfo = getCallExpressionTypeInfoWithoutFinalTypeCheck (callExpression , receiver , callOperationNode , context );
208
+ KotlinTypeInfo typeInfo = getCallExpressionTypeInfoWithoutFinalTypeCheck (
209
+ callExpression , receiver , callOperationNode , context , context .dataFlowInfo );
197
210
if (context .contextDependency == INDEPENDENT ) {
198
211
dataFlowAnalyzer .checkType (typeInfo .getType (), callExpression , context );
199
212
}
@@ -207,7 +220,8 @@ public KotlinTypeInfo getCallExpressionTypeInfo(
207
220
@ NotNull
208
221
private KotlinTypeInfo getCallExpressionTypeInfoWithoutFinalTypeCheck (
209
222
@ NotNull KtCallExpression callExpression , @ Nullable Receiver receiver ,
210
- @ Nullable ASTNode callOperationNode , @ NotNull ExpressionTypingContext context
223
+ @ Nullable ASTNode callOperationNode , @ NotNull ExpressionTypingContext context ,
224
+ @ NotNull DataFlowInfo initialDataFlowInfoForArguments
211
225
) {
212
226
boolean [] result = new boolean [1 ];
213
227
Call call = CallMaker .makeCall (receiver , callOperationNode , callExpression );
@@ -217,7 +231,9 @@ private KotlinTypeInfo getCallExpressionTypeInfoWithoutFinalTypeCheck(
217
231
ResolvedCall <FunctionDescriptor > resolvedCall = getResolvedCallForFunction (
218
232
call ,
219
233
context .replaceTraceAndCache (temporaryForFunction ),
220
- CheckArgumentTypesMode .CHECK_VALUE_ARGUMENTS , result );
234
+ CheckArgumentTypesMode .CHECK_VALUE_ARGUMENTS ,
235
+ result ,
236
+ initialDataFlowInfoForArguments );
221
237
if (result [0 ]) {
222
238
FunctionDescriptor functionDescriptor = resolvedCall != null ? resolvedCall .getResultingDescriptor () : null ;
223
239
temporaryForFunction .commit ();
@@ -311,14 +327,16 @@ private KotlinTypeInfo getSelectorReturnTypeInfo(
311
327
@ NotNull Receiver receiver ,
312
328
@ Nullable ASTNode callOperationNode ,
313
329
@ Nullable KtExpression selectorExpression ,
314
- @ NotNull ExpressionTypingContext context
330
+ @ NotNull ExpressionTypingContext context ,
331
+ @ NotNull DataFlowInfo initialDataFlowInfoForArguments
315
332
) {
316
333
if (selectorExpression instanceof KtCallExpression ) {
317
334
return getCallExpressionTypeInfoWithoutFinalTypeCheck ((KtCallExpression ) selectorExpression , receiver ,
318
- callOperationNode , context );
335
+ callOperationNode , context , initialDataFlowInfoForArguments );
319
336
}
320
337
else if (selectorExpression instanceof KtSimpleNameExpression ) {
321
- return getSimpleNameExpressionTypeInfo ((KtSimpleNameExpression ) selectorExpression , receiver , callOperationNode , context );
338
+ return getSimpleNameExpressionTypeInfo (
339
+ (KtSimpleNameExpression ) selectorExpression , receiver , callOperationNode , context , initialDataFlowInfoForArguments );
322
340
}
323
341
else if (selectorExpression != null ) {
324
342
expressionTypingServices .getTypeInfo (selectorExpression , context );
@@ -422,15 +440,15 @@ public Boolean invoke(KtSimpleNameExpression nameExpression) {
422
440
contextForSelector = contextForSelector .replaceDataFlowInfo (receiverDataFlowInfo );
423
441
}
424
442
443
+ DataFlowInfo initialDataFlowInfoForArguments = contextForSelector .dataFlowInfo ;
425
444
if (receiver instanceof ReceiverValue ) {
426
445
DataFlowValue receiverDataFlowValue = DataFlowValueFactory .createDataFlowValue ((ReceiverValue ) receiver , context );
427
446
// Additional "receiver != null" information
428
447
// Should be applied if we consider a safe call
429
448
if (element .getSafe ()) {
430
- DataFlowInfo dataFlowInfo = contextForSelector .dataFlowInfo ;
431
- if (dataFlowInfo .getPredictableNullability (receiverDataFlowValue ).canBeNull ()) {
432
- contextForSelector = contextForSelector .replaceDataFlowInfo (
433
- dataFlowInfo .disequate (receiverDataFlowValue , DataFlowValue .nullValue (builtIns )));
449
+ if (initialDataFlowInfoForArguments .getPredictableNullability (receiverDataFlowValue ).canBeNull ()) {
450
+ initialDataFlowInfoForArguments = initialDataFlowInfoForArguments .disequate (
451
+ receiverDataFlowValue , DataFlowValue .nullValue (builtIns ));
434
452
}
435
453
else {
436
454
reportUnnecessarySafeCall (trace , receiverType , element .getNode (), receiver );
@@ -439,8 +457,8 @@ public Boolean invoke(KtSimpleNameExpression nameExpression) {
439
457
}
440
458
441
459
KtExpression selectorExpression = element .getSelector ();
442
- KotlinTypeInfo selectorReturnTypeInfo =
443
- getSelectorReturnTypeInfo ( receiver , element .getNode (), selectorExpression , contextForSelector );
460
+ KotlinTypeInfo selectorReturnTypeInfo = getSelectorReturnTypeInfo (
461
+ receiver , element .getNode (), selectorExpression , contextForSelector , initialDataFlowInfoForArguments );
444
462
KotlinType selectorReturnType = selectorReturnTypeInfo .getType ();
445
463
446
464
if (qualifierReceiver != null ) {
0 commit comments