Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(11)

Side by Side Diff: pkg/kernel/lib/type_checker.dart

Issue 2923653003: Change MethodInvocation.interfaceTarget from a Procedure to a Member. (Closed)
Patch Set: Update after https://codereview.chromium.org/2920223008/ Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « pkg/kernel/lib/ast.dart ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 library kernel.type_checker; 4 library kernel.type_checker;
5 5
6 import 'ast.dart'; 6 import 'ast.dart';
7 import 'class_hierarchy.dart'; 7 import 'class_hierarchy.dart';
8 import 'core_types.dart'; 8 import 'core_types.dart';
9 import 'type_algebra.dart'; 9 import 'type_algebra.dart';
10 import 'type_environment.dart'; 10 import 'type_environment.dart';
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
241 // have a declared interface target. 241 // have a declared interface target.
242 fail(access, '$member is not accessible on a receiver of type $type'); 242 fail(access, '$member is not accessible on a receiver of type $type');
243 return Substitution.bottomForClass(superclass); // Continue type checking. 243 return Substitution.bottomForClass(superclass); // Continue type checking.
244 } 244 }
245 245
246 Substitution getSuperReceiverType(Member member) { 246 Substitution getSuperReceiverType(Member member) {
247 return Substitution.fromSupertype( 247 return Substitution.fromSupertype(
248 hierarchy.getClassAsInstanceOf(currentClass, member.enclosingClass)); 248 hierarchy.getClassAsInstanceOf(currentClass, member.enclosingClass));
249 } 249 }
250 250
251 DartType handleCall(Arguments arguments, FunctionNode function, 251 DartType handleCall(Arguments arguments, DartType functionType,
252 {Substitution receiver: Substitution.empty, 252 {Substitution receiver: Substitution.empty,
253 List<TypeParameter> typeParameters}) { 253 List<TypeParameter> typeParameters}) {
254 typeParameters ??= function.typeParameters; 254 if (functionType is FunctionType) {
255 if (arguments.positional.length < function.requiredParameterCount) { 255 typeParameters ??= functionType.typeParameters;
256 fail(arguments, 'Too few positional arguments'); 256 if (arguments.positional.length < functionType.requiredParameterCount) {
257 return const BottomType(); 257 fail(arguments, 'Too few positional arguments');
258 } 258 return const BottomType();
259 if (arguments.positional.length > function.positionalParameters.length) { 259 }
260 fail(arguments, 'Too many positional arguments'); 260 if (arguments.positional.length >
261 return const BottomType(); 261 functionType.positionalParameters.length) {
262 } 262 fail(arguments, 'Too many positional arguments');
263 if (arguments.types.length != typeParameters.length) { 263 return const BottomType();
264 fail(arguments, 'Wrong number of type arguments'); 264 }
265 return const BottomType(); 265 if (arguments.types.length != typeParameters.length) {
266 } 266 fail(arguments, 'Wrong number of type arguments');
267 var instantiation = Substitution.fromPairs(typeParameters, arguments.types); 267 return const BottomType();
268 var substitution = Substitution.combine(receiver, instantiation); 268 }
269 for (int i = 0; i < typeParameters.length; ++i) { 269 var instantiation =
270 var argument = arguments.types[i]; 270 Substitution.fromPairs(typeParameters, arguments.types);
271 var bound = substitution.substituteType(typeParameters[i].bound); 271 var substitution = Substitution.combine(receiver, instantiation);
272 checkAssignable(arguments, argument, bound); 272 for (int i = 0; i < typeParameters.length; ++i) {
273 } 273 var argument = arguments.types[i];
274 for (int i = 0; i < arguments.positional.length; ++i) { 274 var bound = substitution.substituteType(typeParameters[i].bound);
275 var expectedType = substitution.substituteType( 275 checkAssignable(arguments, argument, bound);
276 function.positionalParameters[i].type, 276 }
277 contravariant: true); 277 for (int i = 0; i < arguments.positional.length; ++i) {
278 arguments.positional[i] = 278 var expectedType = substitution.substituteType(
279 checkAndDowncastExpression(arguments.positional[i], expectedType); 279 functionType.positionalParameters[i],
280 } 280 contravariant: true);
281 for (int i = 0; i < arguments.named.length; ++i) { 281 arguments.positional[i] =
282 var argument = arguments.named[i]; 282 checkAndDowncastExpression(arguments.positional[i], expectedType);
283 bool found = false; 283 }
284 for (int j = 0; j < function.namedParameters.length; ++j) { 284 for (int i = 0; i < arguments.named.length; ++i) {
285 if (argument.name == function.namedParameters[j].name) { 285 var argument = arguments.named[i];
286 var expectedType = substitution.substituteType( 286 bool found = false;
287 function.namedParameters[j].type, 287 for (int j = 0; j < functionType.namedParameters.length; ++j) {
288 contravariant: true); 288 if (argument.name == functionType.namedParameters[j].name) {
289 argument.value = 289 var expectedType = substitution.substituteType(
290 checkAndDowncastExpression(argument.value, expectedType); 290 functionType.namedParameters[j].type,
291 found = true; 291 contravariant: true);
292 break; 292 argument.value =
293 checkAndDowncastExpression(argument.value, expectedType);
294 found = true;
295 break;
296 }
297 }
298 if (!found) {
299 fail(argument.value, 'Unexpected named parameter: ${argument.name}');
300 return const BottomType();
293 } 301 }
294 } 302 }
295 if (!found) { 303 return substitution.substituteType(functionType.returnType);
296 fail(argument.value, 'Unexpected named parameter: ${argument.name}'); 304 } else {
297 return const BottomType(); 305 // Note: attempting to resolve .call() on [functionType] could lead to an
298 } 306 // infinite regress, so just assume `dynamic`.
307 return const DynamicType();
299 } 308 }
300 return substitution.substituteType(function.returnType);
301 } 309 }
302 310
303 DartType _getInternalReturnType(FunctionNode function) { 311 DartType _getInternalReturnType(FunctionNode function) {
304 switch (function.asyncMarker) { 312 switch (function.asyncMarker) {
305 case AsyncMarker.Sync: 313 case AsyncMarker.Sync:
306 return function.returnType; 314 return function.returnType;
307 315
308 case AsyncMarker.Async: 316 case AsyncMarker.Async:
309 Class container = coreTypes.futureClass; 317 Class container = coreTypes.futureClass;
310 DartType returnType = function.returnType; 318 DartType returnType = function.returnType;
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
372 node.otherwise = 380 node.otherwise =
373 checkAndDowncastExpression(node.otherwise, node.staticType); 381 checkAndDowncastExpression(node.otherwise, node.staticType);
374 return node.staticType; 382 return node.staticType;
375 } 383 }
376 384
377 @override 385 @override
378 DartType visitConstructorInvocation(ConstructorInvocation node) { 386 DartType visitConstructorInvocation(ConstructorInvocation node) {
379 Constructor target = node.target; 387 Constructor target = node.target;
380 Arguments arguments = node.arguments; 388 Arguments arguments = node.arguments;
381 Class class_ = target.enclosingClass; 389 Class class_ = target.enclosingClass;
382 handleCall(arguments, target.function, 390 handleCall(arguments, target.function.functionType,
383 typeParameters: class_.typeParameters); 391 typeParameters: class_.typeParameters);
384 return new InterfaceType(target.enclosingClass, arguments.types); 392 return new InterfaceType(target.enclosingClass, arguments.types);
385 } 393 }
386 394
387 @override 395 @override
388 DartType visitDirectMethodInvocation(DirectMethodInvocation node) { 396 DartType visitDirectMethodInvocation(DirectMethodInvocation node) {
389 return handleCall(node.arguments, node.target.function, 397 return handleCall(node.arguments, node.target.getterType,
390 receiver: getReceiverType(node, node.receiver, node.target)); 398 receiver: getReceiverType(node, node.receiver, node.target));
391 } 399 }
392 400
393 @override 401 @override
394 DartType visitDirectPropertyGet(DirectPropertyGet node) { 402 DartType visitDirectPropertyGet(DirectPropertyGet node) {
395 var receiver = getReceiverType(node, node.receiver, node.target); 403 var receiver = getReceiverType(node, node.receiver, node.target);
396 return receiver.substituteType(node.target.getterType); 404 return receiver.substituteType(node.target.getterType);
397 } 405 }
398 406
399 @override 407 @override
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
517 if (target == null) { 525 if (target == null) {
518 var receiver = visitExpression(node.receiver); 526 var receiver = visitExpression(node.receiver);
519 if (node.name.name == '==') { 527 if (node.name.name == '==') {
520 visitExpression(node.arguments.positional.single); 528 visitExpression(node.arguments.positional.single);
521 return environment.boolType; 529 return environment.boolType;
522 } 530 }
523 if (node.name.name == 'call' && receiver is FunctionType) { 531 if (node.name.name == 'call' && receiver is FunctionType) {
524 return handleFunctionCall(node, receiver, node.arguments); 532 return handleFunctionCall(node, receiver, node.arguments);
525 } 533 }
526 return handleDynamicCall(receiver, node.arguments); 534 return handleDynamicCall(receiver, node.arguments);
527 } else if (environment.isOverloadedArithmeticOperator(target)) { 535 } else if (target is Procedure &&
536 environment.isOverloadedArithmeticOperator(target)) {
528 assert(node.arguments.positional.length == 1); 537 assert(node.arguments.positional.length == 1);
529 var receiver = visitExpression(node.receiver); 538 var receiver = visitExpression(node.receiver);
530 var argument = visitExpression(node.arguments.positional[0]); 539 var argument = visitExpression(node.arguments.positional[0]);
531 return environment.getTypeOfOverloadedArithmetic(receiver, argument); 540 return environment.getTypeOfOverloadedArithmetic(receiver, argument);
532 } else { 541 } else {
533 return handleCall(node.arguments, target.function, 542 return handleCall(node.arguments, target.getterType,
534 receiver: getReceiverType(node, node.receiver, node.interfaceTarget)); 543 receiver: getReceiverType(node, node.receiver, node.interfaceTarget));
535 } 544 }
536 } 545 }
537 546
538 @override 547 @override
539 DartType visitPropertyGet(PropertyGet node) { 548 DartType visitPropertyGet(PropertyGet node) {
540 if (node.interfaceTarget == null) { 549 if (node.interfaceTarget == null) {
541 visitExpression(node.receiver); 550 visitExpression(node.receiver);
542 return const DynamicType(); 551 return const DynamicType();
543 } else { 552 } else {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
578 return const BottomType(); 587 return const BottomType();
579 } 588 }
580 589
581 @override 590 @override
582 DartType visitStaticGet(StaticGet node) { 591 DartType visitStaticGet(StaticGet node) {
583 return node.target.getterType; 592 return node.target.getterType;
584 } 593 }
585 594
586 @override 595 @override
587 DartType visitStaticInvocation(StaticInvocation node) { 596 DartType visitStaticInvocation(StaticInvocation node) {
588 return handleCall(node.arguments, node.target.function); 597 return handleCall(node.arguments, node.target.getterType);
589 } 598 }
590 599
591 @override 600 @override
592 DartType visitStaticSet(StaticSet node) { 601 DartType visitStaticSet(StaticSet node) {
593 var value = visitExpression(node.value); 602 var value = visitExpression(node.value);
594 checkAssignable(node.value, value, node.target.setterType); 603 checkAssignable(node.value, value, node.target.setterType);
595 return value; 604 return value;
596 } 605 }
597 606
598 @override 607 @override
599 DartType visitStringConcatenation(StringConcatenation node) { 608 DartType visitStringConcatenation(StringConcatenation node) {
600 node.expressions.forEach(visitExpression); 609 node.expressions.forEach(visitExpression);
601 return environment.stringType; 610 return environment.stringType;
602 } 611 }
603 612
604 @override 613 @override
605 DartType visitStringLiteral(StringLiteral node) { 614 DartType visitStringLiteral(StringLiteral node) {
606 return environment.stringType; 615 return environment.stringType;
607 } 616 }
608 617
609 @override 618 @override
610 DartType visitSuperMethodInvocation(SuperMethodInvocation node) { 619 DartType visitSuperMethodInvocation(SuperMethodInvocation node) {
611 if (node.interfaceTarget == null) { 620 if (node.interfaceTarget == null) {
612 return handleDynamicCall(environment.thisType, node.arguments); 621 return handleDynamicCall(environment.thisType, node.arguments);
613 } else { 622 } else {
614 return handleCall(node.arguments, node.interfaceTarget.function, 623 return handleCall(node.arguments, node.interfaceTarget.getterType,
615 receiver: getSuperReceiverType(node.interfaceTarget)); 624 receiver: getSuperReceiverType(node.interfaceTarget));
616 } 625 }
617 } 626 }
618 627
619 @override 628 @override
620 DartType visitSuperPropertyGet(SuperPropertyGet node) { 629 DartType visitSuperPropertyGet(SuperPropertyGet node) {
621 if (node.interfaceTarget == null) { 630 if (node.interfaceTarget == null) {
622 return const DynamicType(); 631 return const DynamicType();
623 } else { 632 } else {
624 var receiver = getSuperReceiverType(node.interfaceTarget); 633 var receiver = getSuperReceiverType(node.interfaceTarget);
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after
930 } 939 }
931 } 940 }
932 941
933 @override 942 @override
934 visitFieldInitializer(FieldInitializer node) { 943 visitFieldInitializer(FieldInitializer node) {
935 node.value = checkAndDowncastExpression(node.value, node.field.type); 944 node.value = checkAndDowncastExpression(node.value, node.field.type);
936 } 945 }
937 946
938 @override 947 @override
939 visitRedirectingInitializer(RedirectingInitializer node) { 948 visitRedirectingInitializer(RedirectingInitializer node) {
940 handleCall(node.arguments, node.target.function, 949 handleCall(node.arguments, node.target.getterType,
941 typeParameters: const <TypeParameter>[]); 950 typeParameters: const <TypeParameter>[]);
942 } 951 }
943 952
944 @override 953 @override
945 visitSuperInitializer(SuperInitializer node) { 954 visitSuperInitializer(SuperInitializer node) {
946 handleCall(node.arguments, node.target.function, 955 handleCall(node.arguments, node.target.getterType,
947 typeParameters: const <TypeParameter>[], 956 typeParameters: const <TypeParameter>[],
948 receiver: getSuperReceiverType(node.target)); 957 receiver: getSuperReceiverType(node.target));
949 } 958 }
950 959
951 @override 960 @override
952 visitLocalInitializer(LocalInitializer node) { 961 visitLocalInitializer(LocalInitializer node) {
953 visitVariableDeclaration(node.variable); 962 visitVariableDeclaration(node.variable);
954 } 963 }
955 964
956 @override 965 @override
957 visitInvalidInitializer(InvalidInitializer node) {} 966 visitInvalidInitializer(InvalidInitializer node) {}
958 } 967 }
OLDNEW
« no previous file with comments | « pkg/kernel/lib/ast.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698