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

Side by Side Diff: lib/src/checker/checker.dart

Issue 1243503007: fixes #221, initial sync*, async, async* implementation (Closed) Base URL: git@github.com:dart-lang/dev_compiler.git@master
Patch Set: Created 5 years, 4 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 | « lib/runtime/dart_runtime.js ('k') | lib/src/checker/rules.dart » ('j') | 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) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, 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 dev_compiler.src.checker.checker; 5 library dev_compiler.src.checker.checker;
6 6
7 import 'package:analyzer/analyzer.dart'; 7 import 'package:analyzer/analyzer.dart';
8 import 'package:analyzer/src/generated/ast.dart'; 8 import 'package:analyzer/src/generated/ast.dart';
9 import 'package:analyzer/src/generated/element.dart'; 9 import 'package:analyzer/src/generated/element.dart';
10 import 'package:analyzer/src/generated/scanner.dart' show Token, TokenType; 10 import 'package:analyzer/src/generated/scanner.dart' show Token, TokenType;
(...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after
399 var field = node.fieldName; 399 var field = node.fieldName;
400 DartType staticType = rules.elementType(field.staticElement); 400 DartType staticType = rules.elementType(field.staticElement);
401 checkAssignment(node.expression, staticType); 401 checkAssignment(node.expression, staticType);
402 node.visitChildren(this); 402 node.visitChildren(this);
403 } 403 }
404 404
405 @override 405 @override
406 void visitForEachStatement(ForEachStatement node) { 406 void visitForEachStatement(ForEachStatement node) {
407 // Check that the expression is an Iterable. 407 // Check that the expression is an Iterable.
408 var expr = node.iterable; 408 var expr = node.iterable;
409 var iterableType = rules.provider.iterableType; 409 var iterableType = node.awaitKeyword != null
410 ? rules.provider.streamType
411 : rules.provider.iterableType;
410 var loopVariable = node.identifier != null 412 var loopVariable = node.identifier != null
411 ? node.identifier 413 ? node.identifier
412 : node.loopVariable.identifier; 414 : node.loopVariable.identifier;
413 var iteratorType = loopVariable.staticType; 415 var iteratorType = loopVariable.staticType;
414 var checkedType = iterableType.substitute4([iteratorType]); 416 var checkedType = iterableType.substitute4([iteratorType]);
415 checkAssignment(expr, checkedType); 417 checkAssignment(expr, checkedType);
416 node.visitChildren(this); 418 node.visitChildren(this);
417 } 419 }
418 420
419 @override 421 @override
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
571 var element = node.staticElement; 573 var element = node.staticElement;
572 if (element == null) { 574 if (element == null) {
573 _recordMessage(new MissingTypeError(node)); 575 _recordMessage(new MissingTypeError(node));
574 } else { 576 } else {
575 var type = node.staticElement.type; 577 var type = node.staticElement.type;
576 checkArgumentList(node.argumentList, type); 578 checkArgumentList(node.argumentList, type);
577 } 579 }
578 node.visitChildren(this); 580 node.visitChildren(this);
579 } 581 }
580 582
581 DartType _getExpectedReturnType(FunctionBody body, bool yieldStar) {
582 FunctionType functionType;
583 var parent = body.parent;
584 if (parent is Declaration) {
585 functionType = rules.elementType(parent.element);
586 } else {
587 assert(parent is FunctionExpression);
588 functionType = rules.getStaticType(parent);
589 }
590
591 var type = functionType.returnType;
592 var provider = rules.provider;
593
594 InterfaceType expectedType = null;
595 if (body.isAsynchronous) {
596 if (body.isGenerator) {
597 // Stream<T> -> T
598 expectedType = provider.streamType;
599 } else {
600 // Future<T> -> T
601 // TODO(vsm): Revisit with issue #228.
602 expectedType = provider.futureType;
603 }
604 } else {
605 if (body.isGenerator) {
606 // Iterable<T> -> T
607 expectedType = provider.iterableType;
608 } else {
609 // T -> T
610 return type;
611 }
612 }
613 if (yieldStar) {
614 if (type.isDynamic) {
615 // Ensure it's at least a Stream / Iterable.
616 return expectedType.substitute4([provider.dynamicType]);
617 } else {
618 // Analyzer will provide a separate error if expected type
619 // is not compatible with type.
620 return type;
621 }
622 }
623 if (type.isDynamic) {
624 return type;
625 } else if (type is InterfaceType && type.element == expectedType.element) {
626 return type.typeArguments[0];
627 } else {
628 // Malformed type - fallback on analyzer error.
629 return null;
630 }
631 }
632
633 FunctionBody _getFunctionBody(AstNode node) {
634 while (node is! FunctionBody) {
635 node = node.parent;
636 }
637 return node as FunctionBody;
638 }
639
640 void _checkReturnOrYield(Expression expression, AstNode node, 583 void _checkReturnOrYield(Expression expression, AstNode node,
641 [bool yieldStar = false]) { 584 {bool yieldStar: false}) {
642 var body = _getFunctionBody(node); 585 var body = node.getAncestor((n) => n is FunctionBody);
643 var type = _getExpectedReturnType(body, yieldStar); 586 var type = rules.getExpectedReturnType(body, yieldStar: yieldStar);
644 if (type == null) { 587 if (type == null) {
645 // We have a type mismatch: the async/async*/sync* modifier does 588 // We have a type mismatch: the async/async*/sync* modifier does
646 // not match the return or yield type. We should have already gotten an 589 // not match the return or yield type. We should have already gotten an
647 // analyzer error in this case. 590 // analyzer error in this case.
648 return; 591 return;
649 } 592 }
650 // TODO(vsm): Enforce void or dynamic (to void?) when expression is null. 593 // TODO(vsm): Enforce void or dynamic (to void?) when expression is null.
651 if (expression != null) checkAssignment(expression, type); 594 if (expression != null) checkAssignment(expression, type);
652 } 595 }
653 596
654 @override 597 @override
655 void visitExpressionFunctionBody(ExpressionFunctionBody node) { 598 void visitExpressionFunctionBody(ExpressionFunctionBody node) {
656 _checkReturnOrYield(node.expression, node); 599 _checkReturnOrYield(node.expression, node);
657 node.visitChildren(this); 600 node.visitChildren(this);
658 } 601 }
659 602
660 @override 603 @override
661 void visitReturnStatement(ReturnStatement node) { 604 void visitReturnStatement(ReturnStatement node) {
662 _checkReturnOrYield(node.expression, node); 605 _checkReturnOrYield(node.expression, node);
663 node.visitChildren(this); 606 node.visitChildren(this);
664 } 607 }
665 608
666 @override 609 @override
667 void visitYieldStatement(YieldStatement node) { 610 void visitYieldStatement(YieldStatement node) {
668 _checkReturnOrYield(node.expression, node, node.star != null); 611 _checkReturnOrYield(node.expression, node, yieldStar: node.star != null);
669 node.visitChildren(this); 612 node.visitChildren(this);
670 } 613 }
671 614
672 @override 615 @override
673 void visitPropertyAccess(PropertyAccess node) { 616 void visitPropertyAccess(PropertyAccess node) {
674 var target = node.realTarget; 617 var target = node.realTarget;
675 if (rules.isDynamicTarget(target)) { 618 if (rules.isDynamicTarget(target)) {
676 _recordDynamicInvoke(node, target); 619 _recordDynamicInvoke(node, target);
677 } 620 }
678 node.visitChildren(this); 621 node.visitChildren(this);
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after
997 if (info is CoercionInfo) { 940 if (info is CoercionInfo) {
998 // TODO(jmesserly): if we're run again on the same AST, we'll produce the 941 // TODO(jmesserly): if we're run again on the same AST, we'll produce the
999 // same annotations. This should be harmless. This might go away once 942 // same annotations. This should be harmless. This might go away once
1000 // CodeChecker is integrated better with analyzer, as it will know that 943 // CodeChecker is integrated better with analyzer, as it will know that
1001 // checking has already been performed. 944 // checking has already been performed.
1002 // assert(CoercionInfo.get(info.node) == null); 945 // assert(CoercionInfo.get(info.node) == null);
1003 CoercionInfo.set(info.node, info); 946 CoercionInfo.set(info.node, info);
1004 } 947 }
1005 } 948 }
1006 } 949 }
OLDNEW
« no previous file with comments | « lib/runtime/dart_runtime.js ('k') | lib/src/checker/rules.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698