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

Side by Side Diff: pkg/compiler/lib/src/typechecker.dart

Issue 2699073003: Support `void` as generic argument.
Patch Set: Shuffle things around to have a better `voidRti` locality. Created 3 years, 7 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
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 4
5 library dart2js.typechecker; 5 library dart2js.typechecker;
6 6
7 import 'common/names.dart' show Identifiers; 7 import 'common/names.dart' show Identifiers;
8 import 'common/resolution.dart' show Resolution; 8 import 'common/resolution.dart' show Resolution;
9 import 'common/tasks.dart' show CompilerTask; 9 import 'common/tasks.dart' show CompilerTask;
10 import 'common.dart'; 10 import 'common.dart';
(...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after
410 reportedTypePromotions.add(typePromotion); 410 reportedTypePromotions.add(typePromotion);
411 for (TypePromotionMessage message in typePromotion.messages) { 411 for (TypePromotionMessage message in typePromotion.messages) {
412 reporter.reportHint(message.hint, message.infos); 412 reporter.reportHint(message.hint, message.infos);
413 } 413 }
414 } 414 }
415 } 415 }
416 416
417 // TODO(karlklose): remove these functions. 417 // TODO(karlklose): remove these functions.
418 ResolutionDartType unhandledExpression() => const ResolutionDynamicType(); 418 ResolutionDartType unhandledExpression() => const ResolutionDynamicType();
419 419
420 /// Checks that the analyzed node is not `void`.
421 ///
422 /// If it is, a warning is emitted, and the returned type is `dynamic`.
420 ResolutionDartType analyzeNonVoid(Node node) { 423 ResolutionDartType analyzeNonVoid(Node node) {
421 ResolutionDartType type = analyze(node); 424 ResolutionDartType type = analyze(node);
422 if (type.isVoid) { 425 if (type.isVoid) {
423 reportTypeWarning(node, MessageKind.VOID_EXPRESSION); 426 reportTypeWarning(node, MessageKind.VOID_EXPRESSION);
427 return const ResolutionDynamicType();
424 } 428 }
425 return type; 429 return type;
426 } 430 }
427 431
428 ResolutionDartType analyzeWithDefault( 432 ResolutionDartType analyzeWithDefault(
429 Node node, ResolutionDartType defaultValue) { 433 Node node, ResolutionDartType defaultValue) {
430 return node != null ? analyze(node) : defaultValue; 434 return node != null ? analyze(node) : defaultValue;
431 } 435 }
432 436
433 /// If [inInitializer] is true, assignment should be interpreted as write to 437 /// If [inInitializer] is true, assignment should be interpreted as write to
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
532 } 536 }
533 537
534 for (TypePromotion typePromotion in getShownTypePromotionsFor(right)) { 538 for (TypePromotion typePromotion in getShownTypePromotionsFor(right)) {
535 typePromotion = typePromotion.copy(); 539 typePromotion = typePromotion.copy();
536 checkTypePromotion(right, typePromotion); 540 checkTypePromotion(right, typePromotion);
537 showTypePromotion(node, typePromotion); 541 showTypePromotion(node, typePromotion);
538 } 542 }
539 } 543 }
540 544
541 /// Analyze [node] in the context of the known types shown in [context]. 545 /// Analyze [node] in the context of the known types shown in [context].
546 ///
547 /// If the node [mustHaveType] then it must also not be void.
542 ResolutionDartType analyzeInPromotedContext(Node context, Node node, 548 ResolutionDartType analyzeInPromotedContext(Node context, Node node,
543 {bool mustHaveType: true}) { 549 {bool mustHaveType: true}) {
544 Link<TypePromotion> knownForNode = const Link<TypePromotion>(); 550 Link<TypePromotion> knownForNode = const Link<TypePromotion>();
545 for (TypePromotion typePromotion in getShownTypePromotionsFor(context)) { 551 for (TypePromotion typePromotion in getShownTypePromotionsFor(context)) {
546 typePromotion = typePromotion.copy(); 552 typePromotion = typePromotion.copy();
547 checkTypePromotion(node, typePromotion, checkAccesses: true); 553 checkTypePromotion(node, typePromotion, checkAccesses: true);
548 knownForNode = knownForNode.prepend(typePromotion); 554 knownForNode = knownForNode.prepend(typePromotion);
549 registerKnownTypePromotion(typePromotion); 555 registerKnownTypePromotion(typePromotion);
550 } 556 }
551 557
552 final ResolutionDartType type = analyze(node, mustHaveType: mustHaveType); 558 final ResolutionDartType type = mustHaveType
559 ? analyzeNonVoid(node)
560 : analyze(node, mustHaveType: false);
553 561
554 while (!knownForNode.isEmpty) { 562 while (!knownForNode.isEmpty) {
555 unregisterKnownTypePromotion(knownForNode.head); 563 unregisterKnownTypePromotion(knownForNode.head);
556 knownForNode = knownForNode.tail; 564 knownForNode = knownForNode.tail;
557 } 565 }
558 566
559 return type; 567 return type;
560 } 568 }
561 569
562 /** 570 /**
(...skipping 11 matching lines...) Expand all
574 } else { 582 } else {
575 reporter.reportWarningMessage(spannable, MessageKind.NOT_ASSIGNABLE, 583 reporter.reportWarningMessage(spannable, MessageKind.NOT_ASSIGNABLE,
576 {'fromType': from, 'toType': to}); 584 {'fromType': from, 'toType': to});
577 } 585 }
578 return false; 586 return false;
579 } 587 }
580 return true; 588 return true;
581 } 589 }
582 590
583 checkCondition(Expression condition) { 591 checkCondition(Expression condition) {
584 checkAssignable(condition, analyze(condition), boolType); 592 checkAssignable(condition, analyzeNonVoid(condition), boolType);
585 } 593 }
586 594
587 void pushCascadeType(ResolutionDartType type) { 595 void pushCascadeType(ResolutionDartType type) {
588 cascadeTypes = cascadeTypes.prepend(type); 596 cascadeTypes = cascadeTypes.prepend(type);
589 } 597 }
590 598
591 ResolutionDartType popCascadeType() { 599 ResolutionDartType popCascadeType() {
592 ResolutionDartType type = cascadeTypes.head; 600 ResolutionDartType type = cascadeTypes.head;
593 cascadeTypes = cascadeTypes.tail; 601 cascadeTypes = cascadeTypes.tail;
594 return type; 602 return type;
595 } 603 }
596 604
597 visitAssert(Assert node) { 605 visitAssert(Assert node) {
598 analyze(node.condition); 606 analyzeNonVoid(node.condition);
599 if (node.hasMessage) analyze(node.message); 607 if (node.hasMessage) analyzeNonVoid(node.message);
600 } 608 }
601 609
602 visitBlock(Block node) { 610 visitBlock(Block node) {
603 analyzeUntyped(node.statements); 611 analyzeUntyped(node.statements);
604 } 612 }
605 613
606 ResolutionDartType visitCascade(Cascade node) { 614 ResolutionDartType visitCascade(Cascade node) {
607 analyze(node.expression); 615 analyze(node.expression);
608 return popCascadeType(); 616 return popCascadeType();
609 } 617 }
610 618
611 ResolutionDartType visitCascadeReceiver(CascadeReceiver node) { 619 ResolutionDartType visitCascadeReceiver(CascadeReceiver node) {
612 ResolutionDartType type = analyze(node.expression); 620 ResolutionDartType type = analyzeNonVoid(node.expression);
613 pushCascadeType(type); 621 pushCascadeType(type);
614 return type; 622 return type;
615 } 623 }
616 624
617 visitDoWhile(DoWhile node) { 625 visitDoWhile(DoWhile node) {
618 analyzeUntyped(node.body); 626 analyzeUntyped(node.body);
619 checkCondition(node.condition); 627 checkCondition(node.condition);
620 } 628 }
621 629
622 visitExpressionStatement(ExpressionStatement node) { 630 visitExpressionStatement(ExpressionStatement node) {
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after
932 ResolutionDartType namedParameterType = 940 ResolutionDartType namedParameterType =
933 funType.getNamedParameterType(argumentName); 941 funType.getNamedParameterType(argumentName);
934 if (namedParameterType == null) { 942 if (namedParameterType == null) {
935 // TODO(johnniwinther): Provide better information on the called 943 // TODO(johnniwinther): Provide better information on the called
936 // function. 944 // function.
937 reportWarning(reporter.createMessage( 945 reportWarning(reporter.createMessage(
938 argument, 946 argument,
939 MessageKind.NAMED_ARGUMENT_NOT_FOUND, 947 MessageKind.NAMED_ARGUMENT_NOT_FOUND,
940 {'argumentName': argumentName})); 948 {'argumentName': argumentName}));
941 949
942 ResolutionDartType argumentType = analyze(argument); 950 ResolutionDartType argumentType = analyzeNonVoid(argument);
943 if (argumentTypes != null) argumentTypes.addLast(argumentType); 951 if (argumentTypes != null) argumentTypes.addLast(argumentType);
944 } else { 952 } else {
945 ResolutionDartType argumentType = analyze(argument); 953 ResolutionDartType argumentType = analyzeNonVoid(argument);
946 if (argumentTypes != null) argumentTypes.addLast(argumentType); 954 if (argumentTypes != null) argumentTypes.addLast(argumentType);
947 checkAssignable(argument, argumentType, namedParameterType); 955 checkAssignable(argument, argumentType, namedParameterType);
948 } 956 }
949 } else { 957 } else {
950 if (!parameterTypes.moveNext()) { 958 if (!parameterTypes.moveNext()) {
951 if (!optionalParameterTypes.moveNext()) { 959 if (!optionalParameterTypes.moveNext()) {
952 // TODO(johnniwinther): Provide better information on the 960 // TODO(johnniwinther): Provide better information on the
953 // called function. 961 // called function.
954 reportWarning(reporter.createMessage( 962 reportWarning(reporter.createMessage(
955 argument, MessageKind.ADDITIONAL_ARGUMENT)); 963 argument, MessageKind.ADDITIONAL_ARGUMENT));
956 964
957 ResolutionDartType argumentType = analyze(argument); 965 ResolutionDartType argumentType = analyzeNonVoid(argument);
958 if (argumentTypes != null) argumentTypes.addLast(argumentType); 966 if (argumentTypes != null) argumentTypes.addLast(argumentType);
959 } else { 967 } else {
960 ResolutionDartType argumentType = analyze(argument); 968 ResolutionDartType argumentType = analyzeNonVoid(argument);
961 if (argumentTypes != null) argumentTypes.addLast(argumentType); 969 if (argumentTypes != null) argumentTypes.addLast(argumentType);
962 checkAssignable( 970 checkAssignable(
963 argument, argumentType, optionalParameterTypes.current); 971 argument, argumentType, optionalParameterTypes.current);
964 } 972 }
965 } else { 973 } else {
966 ResolutionDartType argumentType = analyze(argument); 974 ResolutionDartType argumentType = analyzeNonVoid(argument);
967 if (argumentTypes != null) argumentTypes.addLast(argumentType); 975 if (argumentTypes != null) argumentTypes.addLast(argumentType);
968 checkAssignable(argument, argumentType, parameterTypes.current); 976 checkAssignable(argument, argumentType, parameterTypes.current);
969 } 977 }
970 } 978 }
971 arguments = arguments.tail; 979 arguments = arguments.tail;
972 } 980 }
973 if (parameterTypes.moveNext()) { 981 if (parameterTypes.moveNext()) {
974 // TODO(johnniwinther): Provide better information on the called 982 // TODO(johnniwinther): Provide better information on the called
975 // function. 983 // function.
976 reportWarning(reporter.createMessage(send, MessageKind.MISSING_ARGUMENT, 984 reportWarning(reporter.createMessage(send, MessageKind.MISSING_ARGUMENT,
977 {'argumentType': parameterTypes.current})); 985 {'argumentType': parameterTypes.current}));
978 } 986 }
979 } else { 987 } else {
980 while (!arguments.isEmpty) { 988 while (!arguments.isEmpty) {
981 ResolutionDartType argumentType = analyze(arguments.head); 989 ResolutionDartType argumentType = analyzeNonVoid(arguments.head);
982 if (argumentTypes != null) argumentTypes.addLast(argumentType); 990 if (argumentTypes != null) argumentTypes.addLast(argumentType);
983 arguments = arguments.tail; 991 arguments = arguments.tail;
984 } 992 }
985 } 993 }
986 } 994 }
987 995
988 // Analyze the invocation [node] of [elementAccess]. 996 // Analyze the invocation [node] of [elementAccess].
989 // 997 //
990 // If provided [argumentTypes] is filled with the argument types during 998 // If provided [argumentTypes] is filled with the argument types during
991 // analysis. 999 // analysis.
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1027 if (node.isConditional) { 1035 if (node.isConditional) {
1028 // Skip cases like `prefix?.topLevel`. 1036 // Skip cases like `prefix?.topLevel`.
1029 return const DynamicAccess(); 1037 return const DynamicAccess();
1030 } 1038 }
1031 assert(invariant(node, element != null, 1039 assert(invariant(node, element != null,
1032 message: 'Prefixed node has no element.')); 1040 message: 'Prefixed node has no element.'));
1033 return computeResolvedAccess(node, name, element, memberKind); 1041 return computeResolvedAccess(node, name, element, memberKind);
1034 } 1042 }
1035 } 1043 }
1036 // e.foo() for some expression e. 1044 // e.foo() for some expression e.
1037 ResolutionDartType receiverType = analyze(node.receiver); 1045 ResolutionDartType receiverType = analyzeNonVoid(node.receiver);
1038 if (receiverType.treatAsDynamic || receiverType.isVoid) { 1046 if (receiverType.treatAsDynamic) {
1039 return const DynamicAccess(); 1047 return const DynamicAccess();
1040 } 1048 }
1041 return lookupMember( 1049 return lookupMember(
1042 node, receiverType, name, memberKind, elements[node.receiver], 1050 node, receiverType, name, memberKind, elements[node.receiver],
1043 lookupClassMember: 1051 lookupClassMember:
1044 lookupClassMember || element != null && element.isStatic); 1052 lookupClassMember || element != null && element.isStatic);
1045 } else { 1053 } else {
1046 return computeResolvedAccess(node, name, element, memberKind); 1054 return computeResolvedAccess(node, name, element, memberKind);
1047 } 1055 }
1048 } 1056 }
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
1253 } 1261 }
1254 } 1262 }
1255 } 1263 }
1256 return boolType; 1264 return boolType;
1257 } 1265 }
1258 if (node.isOperator && identical(name, 'as')) { 1266 if (node.isOperator && identical(name, 'as')) {
1259 analyze(node.receiver); 1267 analyze(node.receiver);
1260 return elements.getType(node.arguments.head); 1268 return elements.getType(node.arguments.head);
1261 } else if (node.isOperator) { 1269 } else if (node.isOperator) {
1262 final Node receiver = node.receiver; 1270 final Node receiver = node.receiver;
1263 final ResolutionDartType receiverType = analyze(receiver); 1271 final ResolutionDartType receiverType = analyzeNonVoid(receiver);
1264 if (identical(name, '==') || 1272 if (identical(name, '==') ||
1265 identical(name, '!=') 1273 identical(name, '!=')
1266 // TODO(johnniwinther): Remove these. 1274 // TODO(johnniwinther): Remove these.
1267 || 1275 ||
1268 identical(name, '===') || 1276 identical(name, '===') ||
1269 identical(name, '!==')) { 1277 identical(name, '!==')) {
1270 // Analyze argument. 1278 // Analyze argument.
1271 analyze(node.arguments.head); 1279 analyzeNonVoid(node.arguments.head);
1272 return boolType; 1280 return boolType;
1273 } else if (identical(name, '||')) { 1281 } else if (identical(name, '||')) {
1274 checkAssignable(receiver, receiverType, boolType); 1282 checkAssignable(receiver, receiverType, boolType);
1275 final Node argument = node.arguments.head; 1283 final Node argument = node.arguments.head;
1276 final ResolutionDartType argumentType = analyze(argument); 1284 final ResolutionDartType argumentType = analyzeNonVoid(argument);
1277 checkAssignable(argument, argumentType, boolType); 1285 checkAssignable(argument, argumentType, boolType);
1278 return boolType; 1286 return boolType;
1279 } else if (identical(name, '&&')) { 1287 } else if (identical(name, '&&')) {
1280 checkAssignable(receiver, receiverType, boolType); 1288 checkAssignable(receiver, receiverType, boolType);
1281 final Node argument = node.arguments.head; 1289 final Node argument = node.arguments.head;
1282 1290
1283 final ResolutionDartType argumentType = 1291 final ResolutionDartType argumentType =
1284 analyzeInPromotedContext(receiver, argument); 1292 analyzeInPromotedContext(receiver, argument);
1285 1293
1286 reshowTypePromotions(node, receiver, argument); 1294 reshowTypePromotions(node, receiver, argument);
1287 1295
1288 checkAssignable(argument, argumentType, boolType); 1296 checkAssignable(argument, argumentType, boolType);
1289 return boolType; 1297 return boolType;
1290 } else if (identical(name, '!')) { 1298 } else if (identical(name, '!')) {
1291 checkAssignable(receiver, receiverType, boolType); 1299 checkAssignable(receiver, receiverType, boolType);
1292 return boolType; 1300 return boolType;
1293 } else if (identical(name, '?')) { 1301 } else if (identical(name, '?')) {
1294 return boolType; 1302 return boolType;
1295 } else if (identical(name, '??')) { 1303 } else if (identical(name, '??')) {
1296 final Node argument = node.arguments.head; 1304 final Node argument = node.arguments.head;
1297 final ResolutionDartType argumentType = analyze(argument); 1305 final ResolutionDartType argumentType = analyzeNonVoid(argument);
1298 return types.computeLeastUpperBound(receiverType, argumentType); 1306 return types.computeLeastUpperBound(receiverType, argumentType);
1299 } 1307 }
1300 String operatorName = selector.source; 1308 String operatorName = selector.source;
1301 if (identical(name, '-') && node.arguments.isEmpty) { 1309 if (identical(name, '-') && node.arguments.isEmpty) {
1302 operatorName = 'unary-'; 1310 operatorName = 'unary-';
1303 } 1311 }
1304 assert(invariant( 1312 assert(invariant(
1305 node, 1313 node,
1306 identical(name, '+') || 1314 identical(name, '+') ||
1307 identical(name, '=') || 1315 identical(name, '=') ||
1308 identical(name, '-') || 1316 identical(name, '-') ||
1309 identical(name, '*') || 1317 identical(name, '*') ||
1310 identical(name, '/') || 1318 identical(name, '/') ||
1311 identical(name, '%') || 1319 identical(name, '%') ||
1312 identical(name, '~/') || 1320 identical(name, '~/') ||
1313 identical(name, '|') || 1321 identical(name, '|') ||
1314 identical(name, '&') || 1322 identical(name, '&') ||
1315 identical(name, '^') || 1323 identical(name, '^') ||
1316 identical(name, '~') || 1324 identical(name, '~') ||
1317 identical(name, '<<') || 1325 identical(name, '<<') ||
1318 identical(name, '>>') || 1326 identical(name, '>>') ||
1319 identical(name, '<') || 1327 identical(name, '<') ||
1320 identical(name, '>') || 1328 identical(name, '>') ||
1321 identical(name, '<=') || 1329 identical(name, '<=') ||
1322 identical(name, '>=') || 1330 identical(name, '>=') ||
1323 identical(name, '[]'), 1331 identical(name, '[]'),
1324 message: 'Unexpected operator $name')); 1332 message: 'Unexpected operator $name'));
1325 1333
1326 // TODO(karlklose): handle `void` in expression context by calling 1334 ElementAccess access = lookupMember(
1327 // [analyzeNonVoid] instead of [analyze]. 1335 node, receiverType, operatorName, MemberKind.OPERATOR, null);
1328 ElementAccess access = receiverType.isVoid
1329 ? const DynamicAccess()
1330 : lookupMember(
1331 node, receiverType, operatorName, MemberKind.OPERATOR, null);
1332 LinkBuilder<ResolutionDartType> argumentTypesBuilder = 1336 LinkBuilder<ResolutionDartType> argumentTypesBuilder =
1333 new LinkBuilder<ResolutionDartType>(); 1337 new LinkBuilder<ResolutionDartType>();
1334 ResolutionDartType resultType = 1338 ResolutionDartType resultType =
1335 analyzeInvocation(node, access, argumentTypesBuilder); 1339 analyzeInvocation(node, access, argumentTypesBuilder);
1336 if (receiverType == intType) { 1340 if (receiverType == intType) {
1337 if (identical(name, '+') || 1341 if (identical(name, '+') ||
1338 identical(operatorName, '-') || 1342 identical(operatorName, '-') ||
1339 identical(name, '*') || 1343 identical(name, '*') ||
1340 identical(name, '%')) { 1344 identical(name, '%')) {
1341 ResolutionDartType argumentType = argumentTypesBuilder.toLink().head; 1345 ResolutionDartType argumentType = argumentTypesBuilder.toLink().head;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1379 * like [: target++ :]. 1383 * like [: target++ :].
1380 */ 1384 */
1381 ResolutionDartType checkAssignmentOperator(SendSet node, String operatorName, 1385 ResolutionDartType checkAssignmentOperator(SendSet node, String operatorName,
1382 Node valueNode, ResolutionDartType value) { 1386 Node valueNode, ResolutionDartType value) {
1383 assert(invariant(node, !node.isIndex)); 1387 assert(invariant(node, !node.isIndex));
1384 Element setterElement = elements[node]; 1388 Element setterElement = elements[node];
1385 Element getterElement = elements[node.selector]; 1389 Element getterElement = elements[node.selector];
1386 Identifier selector = node.selector; 1390 Identifier selector = node.selector;
1387 ResolutionDartType getter = computeAccessType( 1391 ResolutionDartType getter = computeAccessType(
1388 node, selector.source, getterElement, MemberKind.GETTER); 1392 node, selector.source, getterElement, MemberKind.GETTER);
1393 if (getter.isVoid) {
1394 reportTypeWarning(node, MessageKind.VOID_EXPRESSION);
1395 getter = const ResolutionDynamicType();
1396 }
1389 ResolutionDartType setter = computeAccessType( 1397 ResolutionDartType setter = computeAccessType(
1390 node, selector.source, setterElement, MemberKind.SETTER); 1398 node, selector.source, setterElement, MemberKind.SETTER);
1391 // [operator] is the type of operator+ or operator- on [target]. 1399 // [operator] is the type of operator+ or operator- on [target].
1392 ResolutionDartType operator = 1400 ResolutionDartType operator =
1393 lookupMemberType(node, getter, operatorName, MemberKind.OPERATOR); 1401 lookupMemberType(node, getter, operatorName, MemberKind.OPERATOR);
1394 if (operator is ResolutionFunctionType) { 1402 if (operator is ResolutionFunctionType) {
1395 ResolutionFunctionType operatorType = operator; 1403 ResolutionFunctionType operatorType = operator;
1396 // [result] is the type of target o value. 1404 // [result] is the type of target o value.
1397 ResolutionDartType result = operatorType.returnType; 1405 ResolutionDartType result = operatorType.returnType;
1398 ResolutionDartType operatorArgument = 1406 ResolutionDartType operatorArgument =
(...skipping 10 matching lines...) Expand all
1409 } 1417 }
1410 1418
1411 /** 1419 /**
1412 * Checks [: base[key] o= value :] for some operator o, and returns the type 1420 * Checks [: base[key] o= value :] for some operator o, and returns the type
1413 * of the result. This method also handles increment/decrement expressions 1421 * of the result. This method also handles increment/decrement expressions
1414 * like [: base[key]++ :]. 1422 * like [: base[key]++ :].
1415 */ 1423 */
1416 ResolutionDartType checkIndexAssignmentOperator(SendSet node, 1424 ResolutionDartType checkIndexAssignmentOperator(SendSet node,
1417 String operatorName, Node valueNode, ResolutionDartType value) { 1425 String operatorName, Node valueNode, ResolutionDartType value) {
1418 assert(invariant(node, node.isIndex)); 1426 assert(invariant(node, node.isIndex));
1419 final ResolutionDartType base = analyze(node.receiver); 1427 final ResolutionDartType base = analyzeNonVoid(node.receiver);
1420 final Node keyNode = node.arguments.head; 1428 final Node keyNode = node.arguments.head;
1421 final ResolutionDartType key = analyze(keyNode); 1429 final ResolutionDartType key = analyzeNonVoid(keyNode);
1422 1430
1423 // [indexGet] is the type of operator[] on [base]. 1431 // [indexGet] is the type of operator[] on [base].
1424 ResolutionDartType indexGet = 1432 ResolutionDartType indexGet =
1425 lookupMemberType(node, base, '[]', MemberKind.OPERATOR); 1433 lookupMemberType(node, base, '[]', MemberKind.OPERATOR);
1426 if (indexGet is ResolutionFunctionType) { 1434 if (indexGet is ResolutionFunctionType) {
1427 ResolutionFunctionType indexGetType = indexGet; 1435 ResolutionFunctionType indexGetType = indexGet;
1428 ResolutionDartType indexGetKey = firstType(indexGetType.parameterTypes); 1436 ResolutionDartType indexGetKey = firstType(indexGetType.parameterTypes);
1429 // Check base[key]. 1437 // Check base[key].
1430 bool validKey = checkAssignable(keyNode, key, indexGetKey); 1438 bool validKey = checkAssignable(keyNode, key, indexGetKey);
1431 1439
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1472 } 1480 }
1473 1481
1474 visitSendSet(SendSet node) { 1482 visitSendSet(SendSet node) {
1475 Element element = elements[node]; 1483 Element element = elements[node];
1476 Identifier selector = node.selector; 1484 Identifier selector = node.selector;
1477 final name = node.assignmentOperator.source; 1485 final name = node.assignmentOperator.source;
1478 if (identical(name, '=') || identical(name, '??=')) { 1486 if (identical(name, '=') || identical(name, '??=')) {
1479 // e1 = value 1487 // e1 = value
1480 if (node.isIndex) { 1488 if (node.isIndex) {
1481 // base[key] = value 1489 // base[key] = value
1482 final ResolutionDartType base = analyze(node.receiver); 1490 final ResolutionDartType base = analyzeNonVoid(node.receiver);
1483 final Node keyNode = node.arguments.head; 1491 final Node keyNode = node.arguments.head;
1484 final ResolutionDartType key = analyze(keyNode); 1492 final ResolutionDartType key = analyzeNonVoid(keyNode);
1485 final Node valueNode = node.arguments.tail.head; 1493 final Node valueNode = node.arguments.tail.head;
1486 final ResolutionDartType value = analyze(valueNode); 1494 final ResolutionDartType value = analyzeNonVoid(valueNode);
1487 ResolutionDartType indexSet = 1495 ResolutionDartType indexSet =
1488 lookupMemberType(node, base, '[]=', MemberKind.OPERATOR); 1496 lookupMemberType(node, base, '[]=', MemberKind.OPERATOR);
1489 ResolutionDartType indexSetValue = const ResolutionDynamicType(); 1497 ResolutionDartType indexSetValue = const ResolutionDynamicType();
1490 if (indexSet is ResolutionFunctionType) { 1498 if (indexSet is ResolutionFunctionType) {
1491 ResolutionFunctionType indexSetType = indexSet; 1499 ResolutionFunctionType indexSetType = indexSet;
1492 ResolutionDartType indexSetKey = 1500 ResolutionDartType indexSetKey =
1493 firstType(indexSetType.parameterTypes); 1501 firstType(indexSetType.parameterTypes);
1494 checkAssignable(keyNode, key, indexSetKey); 1502 checkAssignable(keyNode, key, indexSetKey);
1495 indexSetValue = secondType(indexSetType.parameterTypes); 1503 indexSetValue = secondType(indexSetType.parameterTypes);
1496 checkAssignable(node.assignmentOperator, value, indexSetValue); 1504 checkAssignable(node.assignmentOperator, value, indexSetValue);
(...skipping 10 matching lines...) Expand all
1507 // members. 1515 // members.
1508 target = computeAccessType( 1516 target = computeAccessType(
1509 node, selector.source, element, MemberKind.GETTER, 1517 node, selector.source, element, MemberKind.GETTER,
1510 lookupClassMember: true); 1518 lookupClassMember: true);
1511 } else { 1519 } else {
1512 // Normal assignment `target = value`. 1520 // Normal assignment `target = value`.
1513 target = computeAccessType( 1521 target = computeAccessType(
1514 node, selector.source, element, MemberKind.SETTER); 1522 node, selector.source, element, MemberKind.SETTER);
1515 } 1523 }
1516 final Node valueNode = node.arguments.head; 1524 final Node valueNode = node.arguments.head;
1517 final ResolutionDartType value = analyze(valueNode); 1525 final ResolutionDartType value = analyzeNonVoid(valueNode);
1518 checkAssignable(node.assignmentOperator, value, target); 1526 checkAssignable(node.assignmentOperator, value, target);
1519 return identical(name, '=') 1527 return identical(name, '=')
1520 ? value 1528 ? value
1521 : types.computeLeastUpperBound(value, target); 1529 : types.computeLeastUpperBound(value, target);
1522 } 1530 }
1523 } else if (identical(name, '++') || identical(name, '--')) { 1531 } else if (identical(name, '++') || identical(name, '--')) {
1524 // e++ or e-- 1532 // e++ or e--
1525 String operatorName = identical(name, '++') ? '+' : '-'; 1533 String operatorName = identical(name, '++') ? '+' : '-';
1526 if (node.isIndex) { 1534 if (node.isIndex) {
1527 // base[key]++, base[key]--, ++base[key], or --base[key] 1535 // base[key]++, base[key]--, ++base[key], or --base[key]
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1568 break; 1576 break;
1569 case '>>=': 1577 case '>>=':
1570 operatorName = '>>'; 1578 operatorName = '>>';
1571 break; 1579 break;
1572 default: 1580 default:
1573 reporter.internalError(node, 'Unexpected assignment operator $name.'); 1581 reporter.internalError(node, 'Unexpected assignment operator $name.');
1574 } 1582 }
1575 if (node.isIndex) { 1583 if (node.isIndex) {
1576 // base[key] o= value for some operator o. 1584 // base[key] o= value for some operator o.
1577 final Node valueNode = node.arguments.tail.head; 1585 final Node valueNode = node.arguments.tail.head;
1578 final ResolutionDartType value = analyze(valueNode); 1586 final ResolutionDartType value = analyzeNonVoid(valueNode);
1579 return checkIndexAssignmentOperator( 1587 return checkIndexAssignmentOperator(
1580 node, operatorName, valueNode, value); 1588 node, operatorName, valueNode, value);
1581 } else { 1589 } else {
1582 // target o= value for some operator o. 1590 // target o= value for some operator o.
1583 final Node valueNode = node.arguments.head; 1591 final Node valueNode = node.arguments.head;
1584 final ResolutionDartType value = analyze(valueNode); 1592 final ResolutionDartType value = analyzeNonVoid(valueNode);
1585 return checkAssignmentOperator(node, operatorName, valueNode, value); 1593 return checkAssignmentOperator(node, operatorName, valueNode, value);
1586 } 1594 }
1587 } 1595 }
1588 } 1596 }
1589 1597
1590 ResolutionDartType visitLiteralInt(LiteralInt node) { 1598 ResolutionDartType visitLiteralInt(LiteralInt node) {
1591 return intType; 1599 return intType;
1592 } 1600 }
1593 1601
1594 ResolutionDartType visitLiteralDouble(LiteralDouble node) { 1602 ResolutionDartType visitLiteralDouble(LiteralDouble node) {
1595 return doubleType; 1603 return doubleType;
1596 } 1604 }
1597 1605
1598 ResolutionDartType visitLiteralBool(LiteralBool node) { 1606 ResolutionDartType visitLiteralBool(LiteralBool node) {
1599 return boolType; 1607 return boolType;
1600 } 1608 }
1601 1609
1602 ResolutionDartType visitLiteralString(LiteralString node) { 1610 ResolutionDartType visitLiteralString(LiteralString node) {
1603 return stringType; 1611 return stringType;
1604 } 1612 }
1605 1613
1606 ResolutionDartType visitStringJuxtaposition(StringJuxtaposition node) { 1614 ResolutionDartType visitStringJuxtaposition(StringJuxtaposition node) {
1607 analyze(node.first); 1615 analyzeNonVoid(node.first);
1608 analyze(node.second); 1616 analyzeNonVoid(node.second);
1609 return stringType; 1617 return stringType;
1610 } 1618 }
1611 1619
1612 ResolutionDartType visitLiteralNull(LiteralNull node) { 1620 ResolutionDartType visitLiteralNull(LiteralNull node) {
1613 return const ResolutionDynamicType(); 1621 return const ResolutionDynamicType();
1614 } 1622 }
1615 1623
1616 ResolutionInterfaceType visitLiteralSymbol(LiteralSymbol node) { 1624 ResolutionInterfaceType visitLiteralSymbol(LiteralSymbol node) {
1617 return commonElements.symbolType; 1625 return commonElements.symbolType;
1618 } 1626 }
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1655 return newType; 1663 return newType;
1656 } 1664 }
1657 1665
1658 ResolutionDartType visitLiteralList(LiteralList node) { 1666 ResolutionDartType visitLiteralList(LiteralList node) {
1659 ResolutionInterfaceType listType = elements.getType(node); 1667 ResolutionInterfaceType listType = elements.getType(node);
1660 ResolutionDartType listElementType = firstType(listType.typeArguments); 1668 ResolutionDartType listElementType = firstType(listType.typeArguments);
1661 for (Link<Node> link = node.elements.nodes; 1669 for (Link<Node> link = node.elements.nodes;
1662 !link.isEmpty; 1670 !link.isEmpty;
1663 link = link.tail) { 1671 link = link.tail) {
1664 Node element = link.head; 1672 Node element = link.head;
1665 ResolutionDartType elementType = analyze(element); 1673 ResolutionDartType elementType = analyzeNonVoid(element);
1666 checkAssignable(element, elementType, listElementType, 1674 checkAssignable(element, elementType, listElementType,
1667 isConst: node.isConst); 1675 isConst: node.isConst);
1668 } 1676 }
1669 return listType; 1677 return listType;
1670 } 1678 }
1671 1679
1672 visitNodeList(NodeList node) { 1680 visitNodeList(NodeList node) {
1673 for (Link<Node> link = node.nodes; !link.isEmpty; link = link.tail) { 1681 for (Link<Node> link = node.nodes; !link.isEmpty; link = link.tail) {
1674 analyzeUntyped(link.head, inInitializer: analyzingInitializer); 1682 analyzeUntyped(link.head, inInitializer: analyzingInitializer);
1675 } 1683 }
(...skipping 22 matching lines...) Expand all
1698 if (expression != null) { 1706 if (expression != null) {
1699 ResolutionDartType expressionType = analyze(expression); 1707 ResolutionDartType expressionType = analyze(expression);
1700 if (executableContext.isGenerativeConstructor) { 1708 if (executableContext.isGenerativeConstructor) {
1701 // The resolver already emitted an error for this expression. 1709 // The resolver already emitted an error for this expression.
1702 } else { 1710 } else {
1703 if (currentAsyncMarker == AsyncMarker.ASYNC) { 1711 if (currentAsyncMarker == AsyncMarker.ASYNC) {
1704 ResolutionInterfaceType futureOfFlattenedType = 1712 ResolutionInterfaceType futureOfFlattenedType =
1705 commonElements.futureType(types.flatten(expressionType)); 1713 commonElements.futureType(types.flatten(expressionType));
1706 expressionType = futureOfFlattenedType; 1714 expressionType = futureOfFlattenedType;
1707 } 1715 }
1716 // TODO(floitsch): we want to break this exception.
1717 // No return x; allowed in a void function. Even if the return type is
1718 // void.
1708 if (expectedReturnType.isVoid && 1719 if (expectedReturnType.isVoid &&
1709 !types.isAssignable(expressionType, const ResolutionVoidType())) { 1720 !types.isAssignable(expressionType, const ResolutionVoidType())) {
1710 reportTypeWarning(expression, MessageKind.RETURN_VALUE_IN_VOID); 1721 reportTypeWarning(expression, MessageKind.RETURN_VALUE_IN_VOID);
1711 } else { 1722 } else {
1712 checkAssignable(expression, expressionType, expectedReturnType); 1723 checkAssignable(expression, expressionType, expectedReturnType);
1713 } 1724 }
1714 } 1725 }
1715 } else if (currentAsyncMarker != AsyncMarker.SYNC) { 1726 } else if (currentAsyncMarker != AsyncMarker.SYNC) {
1716 // `return;` is allowed. 1727 // `return;` is allowed.
1717 } else if (!types.isAssignable( 1728 } else if (!types.isAssignable(
1718 expectedReturnType, const ResolutionVoidType())) { 1729 expectedReturnType, const ResolutionVoidType())) {
1730 // TODO(floitsch): this is probably where we want to have the checks
1731 // that `void` must not have a `return` unless it returns void.
1732
1719 // Let f be the function immediately enclosing a return statement of the 1733 // Let f be the function immediately enclosing a return statement of the
1720 // form 'return;' It is a static warning if both of the following 1734 // form 'return;' It is a static warning if both of the following
1721 // conditions hold: 1735 // conditions hold:
1722 // - f is not a generative constructor. 1736 // - f is not a generative constructor.
1723 // - The return type of f may not be assigned to void. 1737 // - The return type of f may not be assigned to void.
1724 reportTypeWarning( 1738 reportTypeWarning(
1725 node, MessageKind.RETURN_NOTHING, {'returnType': expectedReturnType}); 1739 node, MessageKind.RETURN_NOTHING, {'returnType': expectedReturnType});
1726 } 1740 }
1727 } 1741 }
1728 1742
1729 ResolutionDartType visitThrow(Throw node) { 1743 ResolutionDartType visitThrow(Throw node) {
1730 // TODO(johnniwinther): Handle reachability. 1744 // TODO(johnniwinther): Handle reachability.
1731 analyze(node.expression); 1745 analyzeNonVoid(node.expression);
1732 return const ResolutionDynamicType(); 1746 return const ResolutionDynamicType();
1733 } 1747 }
1734 1748
1735 ResolutionDartType visitAwait(Await node) { 1749 ResolutionDartType visitAwait(Await node) {
1736 ResolutionDartType expressionType = analyze(node.expression); 1750 ResolutionDartType expressionType = analyze(node.expression);
1737 if (resolution.target.supportsAsyncAwait) { 1751 if (resolution.target.supportsAsyncAwait) {
1738 return types.flatten(expressionType); 1752 return types.flatten(expressionType);
1739 } else { 1753 } else {
1740 return const ResolutionDynamicType(); 1754 return const ResolutionDynamicType();
1741 } 1755 }
1742 } 1756 }
1743 1757
1744 visitYield(Yield node) { 1758 visitYield(Yield node) {
1745 ResolutionDartType resultType = analyze(node.expression); 1759 ResolutionDartType resultType = analyzeNonVoid(node.expression);
1746 if (!node.hasStar) { 1760 if (!node.hasStar) {
1747 if (currentAsyncMarker.isAsync) { 1761 if (currentAsyncMarker.isAsync) {
1748 ResolutionInterfaceType streamOfResultType = 1762 ResolutionInterfaceType streamOfResultType =
1749 commonElements.streamType(resultType); 1763 commonElements.streamType(resultType);
1750 resultType = streamOfResultType; 1764 resultType = streamOfResultType;
1751 } else { 1765 } else {
1752 ResolutionInterfaceType iterableOfResultType = 1766 ResolutionInterfaceType iterableOfResultType =
1753 commonElements.iterableType(resultType); 1767 commonElements.iterableType(resultType);
1754 resultType = iterableOfResultType; 1768 resultType = iterableOfResultType;
1755 } 1769 }
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
1834 1848
1835 ResolutionDartType visitConditional(Conditional node) { 1849 ResolutionDartType visitConditional(Conditional node) {
1836 Expression condition = node.condition; 1850 Expression condition = node.condition;
1837 Expression thenExpression = node.thenExpression; 1851 Expression thenExpression = node.thenExpression;
1838 1852
1839 checkCondition(condition); 1853 checkCondition(condition);
1840 1854
1841 ResolutionDartType thenType = 1855 ResolutionDartType thenType =
1842 analyzeInPromotedContext(condition, thenExpression); 1856 analyzeInPromotedContext(condition, thenExpression);
1843 1857
1844 ResolutionDartType elseType = analyze(node.elseExpression); 1858 ResolutionDartType elseType = analyzeNonVoid(node.elseExpression);
1845 return types.computeLeastUpperBound(thenType, elseType); 1859 return types.computeLeastUpperBound(thenType, elseType);
1846 } 1860 }
1847 1861
1848 visitStringInterpolation(StringInterpolation node) { 1862 visitStringInterpolation(StringInterpolation node) {
1849 node.visitChildren(this); 1863 node.visitChildren(this);
1850 return stringType; 1864 return stringType;
1851 } 1865 }
1852 1866
1853 visitStringInterpolationPart(StringInterpolationPart node) { 1867 visitStringInterpolationPart(StringInterpolationPart node) {
1854 node.visitChildren(this); 1868 node.visitChildren(this);
(...skipping 18 matching lines...) Expand all
1873 if (declaredIdentifier != null) { 1887 if (declaredIdentifier != null) {
1874 return analyzeWithDefault( 1888 return analyzeWithDefault(
1875 declaredIdentifier.type, const ResolutionDynamicType()); 1889 declaredIdentifier.type, const ResolutionDynamicType());
1876 } else { 1890 } else {
1877 return analyze(node.declaredIdentifier); 1891 return analyze(node.declaredIdentifier);
1878 } 1892 }
1879 } 1893 }
1880 1894
1881 visitAsyncForIn(AsyncForIn node) { 1895 visitAsyncForIn(AsyncForIn node) {
1882 ResolutionDartType elementType = computeForInElementType(node); 1896 ResolutionDartType elementType = computeForInElementType(node);
1883 ResolutionDartType expressionType = analyze(node.expression); 1897 ResolutionDartType expressionType = analyzeNonVoid(node.expression);
1884 if (resolution.target.supportsAsyncAwait) { 1898 if (resolution.target.supportsAsyncAwait) {
1885 ResolutionInterfaceType streamOfDynamic = commonElements.streamType(); 1899 ResolutionInterfaceType streamOfDynamic = commonElements.streamType();
1886 if (!types.isAssignable(expressionType, streamOfDynamic)) { 1900 if (!types.isAssignable(expressionType, streamOfDynamic)) {
1887 reportMessage(node.expression, MessageKind.NOT_ASSIGNABLE, 1901 reportMessage(node.expression, MessageKind.NOT_ASSIGNABLE,
1888 {'fromType': expressionType, 'toType': streamOfDynamic}, 1902 {'fromType': expressionType, 'toType': streamOfDynamic},
1889 isHint: true); 1903 isHint: true);
1890 } else { 1904 } else {
1891 ResolutionInterfaceType interfaceType = 1905 ResolutionInterfaceType interfaceType =
1892 Types.computeInterfaceType(resolution, expressionType); 1906 Types.computeInterfaceType(resolution, expressionType);
1893 if (interfaceType != null) { 1907 if (interfaceType != null) {
1894 ResolutionInterfaceType streamType = 1908 ResolutionInterfaceType streamType =
1895 interfaceType.asInstanceOf(streamOfDynamic.element); 1909 interfaceType.asInstanceOf(streamOfDynamic.element);
1896 if (streamType != null) { 1910 if (streamType != null) {
1897 ResolutionDartType streamElementType = 1911 ResolutionDartType streamElementType =
1898 streamType.typeArguments.first; 1912 streamType.typeArguments.first;
1899 if (!types.isAssignable(streamElementType, elementType)) { 1913 if (streamElementType.isVoid) {
1914 reportTypeWarning(
1915 node.expression, MessageKind.AWAIT_FORIN_VOID_GENERIC);
1916 } else if (!types.isAssignable(streamElementType, elementType)) {
1900 reportMessage( 1917 reportMessage(
1901 node.expression, 1918 node.expression,
1902 MessageKind.FORIN_NOT_ASSIGNABLE, 1919 MessageKind.FORIN_NOT_ASSIGNABLE,
1903 { 1920 {
1904 'currentType': streamElementType, 1921 'currentType': streamElementType,
1905 'expressionType': expressionType, 1922 'expressionType': expressionType,
1906 'elementType': elementType 1923 'elementType': elementType
1907 }, 1924 },
1908 isHint: true); 1925 isHint: true);
1909 } 1926 }
1910 } 1927 }
1911 } 1928 }
1912 } 1929 }
1913 } 1930 }
1914 analyzeUntyped(node.body); 1931 analyzeUntyped(node.body);
1915 } 1932 }
1916 1933
1917 visitSyncForIn(SyncForIn node) { 1934 visitSyncForIn(SyncForIn node) {
1918 ResolutionDartType elementType = computeForInElementType(node); 1935 ResolutionDartType elementType = computeForInElementType(node);
1919 ResolutionDartType expressionType = analyze(node.expression); 1936 ResolutionDartType expressionType = analyzeNonVoid(node.expression);
1920 ResolutionDartType iteratorType = lookupMemberType(node.expression, 1937 ResolutionDartType iteratorType = lookupMemberType(node.expression,
1921 expressionType, Identifiers.iterator, MemberKind.GETTER); 1938 expressionType, Identifiers.iterator, MemberKind.GETTER);
1922 ResolutionDartType currentType = lookupMemberType( 1939 ResolutionDartType currentType = lookupMemberType(
1923 node.expression, iteratorType, Identifiers.current, MemberKind.GETTER, 1940 node.expression, iteratorType, Identifiers.current, MemberKind.GETTER,
1924 isHint: true); 1941 isHint: true);
1925 if (!types.isAssignable(currentType, elementType)) { 1942 if (currentType.isVoid) {
1943 reportTypeWarning(node.expression, MessageKind.FORIN_VOID_GENERIC);
1944 } else if (!types.isAssignable(currentType, elementType)) {
1926 reportMessage( 1945 reportMessage(
1927 node.expression, 1946 node.expression,
1928 MessageKind.FORIN_NOT_ASSIGNABLE, 1947 MessageKind.FORIN_NOT_ASSIGNABLE,
1929 { 1948 {
1930 'currentType': currentType, 1949 'currentType': currentType,
1931 'expressionType': expressionType, 1950 'expressionType': expressionType,
1932 'elementType': elementType 1951 'elementType': elementType
1933 }, 1952 },
1934 isHint: true); 1953 isHint: true);
1935 } 1954 }
1936 analyzeUntyped(node.body); 1955 analyzeUntyped(node.body);
1937 } 1956 }
1938 1957
1939 visitLabeledStatement(LabeledStatement node) { 1958 visitLabeledStatement(LabeledStatement node) {
1940 analyzeUntyped(node.statement); 1959 analyzeUntyped(node.statement);
1941 } 1960 }
1942 1961
1943 visitLiteralMap(LiteralMap node) { 1962 visitLiteralMap(LiteralMap node) {
1944 ResolutionInterfaceType mapType = elements.getType(node); 1963 ResolutionInterfaceType mapType = elements.getType(node);
1945 ResolutionDartType mapKeyType = firstType(mapType.typeArguments); 1964 ResolutionDartType mapKeyType = firstType(mapType.typeArguments);
1946 ResolutionDartType mapValueType = secondType(mapType.typeArguments); 1965 ResolutionDartType mapValueType = secondType(mapType.typeArguments);
1947 bool isConst = node.isConst; 1966 bool isConst = node.isConst;
1948 for (Link<Node> link = node.entries.nodes; 1967 for (Link<Node> link = node.entries.nodes;
1949 !link.isEmpty; 1968 !link.isEmpty;
1950 link = link.tail) { 1969 link = link.tail) {
1951 LiteralMapEntry entry = link.head; 1970 LiteralMapEntry entry = link.head;
1952 ResolutionDartType keyType = analyze(entry.key); 1971 ResolutionDartType keyType = analyzeNonVoid(entry.key);
1953 checkAssignable(entry.key, keyType, mapKeyType, isConst: isConst); 1972 checkAssignable(entry.key, keyType, mapKeyType, isConst: isConst);
1954 ResolutionDartType valueType = analyze(entry.value); 1973 ResolutionDartType valueType = analyzeNonVoid(entry.value);
1955 checkAssignable(entry.value, valueType, mapValueType, isConst: isConst); 1974 checkAssignable(entry.value, valueType, mapValueType, isConst: isConst);
1956 } 1975 }
1957 return mapType; 1976 return mapType;
1958 } 1977 }
1959 1978
1960 visitNamedArgument(NamedArgument node) { 1979 visitNamedArgument(NamedArgument node) {
1961 // Named arguments are visited as part of analyzing invocations of 1980 // Named arguments are visited as part of analyzing invocations of
1962 // unresolved methods. For instance [: foo(a: 42); :] where 'foo' is neither 1981 // unresolved methods. For instance [: foo(a: 42); :] where 'foo' is neither
1963 // found in the enclosing scope nor through lookup on 'this' or 1982 // found in the enclosing scope nor through lookup on 'this' or
1964 // [: x.foo(b: 42); :] where 'foo' cannot be not found through lookup on 1983 // [: x.foo(b: 42); :] where 'foo' cannot be not found through lookup on
1965 // the static type of 'x'. 1984 // the static type of 'x'.
1966 return analyze(node.expression); 1985 return analyzeNonVoid(node.expression);
1967 } 1986 }
1968 1987
1969 visitSwitchStatement(SwitchStatement node) { 1988 visitSwitchStatement(SwitchStatement node) {
1970 // TODO(johnniwinther): Handle reachability based on reachability of 1989 // TODO(johnniwinther): Handle reachability based on reachability of
1971 // switch cases. 1990 // switch cases.
1972 // TODO(johnniwinther): Provide hint of duplicate case constants. 1991 // TODO(johnniwinther): Provide hint of duplicate case constants.
1973 1992
1974 ResolutionDartType expressionType = analyze(node.expression); 1993 ResolutionDartType expressionType = analyzeNonVoid(node.expression);
1975 1994
1976 // Check that all the case expressions are assignable to the expression. 1995 // Check that all the case expressions are assignable to the expression.
1977 bool hasDefaultCase = false; 1996 bool hasDefaultCase = false;
1978 for (SwitchCase switchCase in node.cases) { 1997 for (SwitchCase switchCase in node.cases) {
1979 if (switchCase.isDefaultCase) { 1998 if (switchCase.isDefaultCase) {
1980 hasDefaultCase = true; 1999 hasDefaultCase = true;
1981 } 2000 }
1982 for (Node labelOrCase in switchCase.labelsAndCases) { 2001 for (Node labelOrCase in switchCase.labelsAndCases) {
1983 CaseMatch caseMatch = labelOrCase.asCaseMatch(); 2002 CaseMatch caseMatch = labelOrCase.asCaseMatch();
1984 if (caseMatch == null) continue; 2003 if (caseMatch == null) continue;
1985 2004
1986 ResolutionDartType caseType = analyze(caseMatch.expression); 2005 ResolutionDartType caseType = analyzeNonVoid(caseMatch.expression);
1987 checkAssignable(caseMatch, expressionType, caseType); 2006 checkAssignable(caseMatch, expressionType, caseType);
1988 } 2007 }
1989 2008
1990 analyzeUntyped(switchCase); 2009 analyzeUntyped(switchCase);
1991 } 2010 }
1992 2011
1993 if (!hasDefaultCase && expressionType.isEnumType) { 2012 if (!hasDefaultCase && expressionType.isEnumType) {
1994 compiler.enqueuer.resolution 2013 compiler.enqueuer.resolution
1995 .addDeferredAction(new DeferredAction(executableContext, () { 2014 .addDeferredAction(new DeferredAction(executableContext, () {
1996 Map<ConstantValue, FieldElement> enumValues = 2015 Map<ConstantValue, FieldElement> enumValues =
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
2054 2073
2055 visitTypedef(Typedef node) { 2074 visitTypedef(Typedef node) {
2056 // Do not typecheck [Typedef] nodes. 2075 // Do not typecheck [Typedef] nodes.
2057 } 2076 }
2058 2077
2059 visitNode(Node node) { 2078 visitNode(Node node) {
2060 reporter.internalError(node, 2079 reporter.internalError(node,
2061 'Unexpected node ${node.getObjectDescription()} in the type checker.'); 2080 'Unexpected node ${node.getObjectDescription()} in the type checker.');
2062 } 2081 }
2063 } 2082 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/resolution/signatures.dart ('k') | pkg/front_end/lib/src/fasta/parser/parser.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698