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

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

Issue 1317933005: Some preliminary support for quasi-generics (Closed) Base URL: https://github.com/dart-lang/dev_compiler.git@master
Patch Set: Address comments Created 5 years, 3 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/typed_data.js ('k') | lib/src/dart_sdk.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 /// Encapsulates how to invoke the analyzer resolver and overrides how it 5 /// Encapsulates how to invoke the analyzer resolver and overrides how it
6 /// computes types on expressions to use our restricted set of types. 6 /// computes types on expressions to use our restricted set of types.
7 library dev_compiler.src.checker.resolver; 7 library dev_compiler.src.checker.resolver;
8 8
9 import 'package:analyzer/analyzer.dart'; 9 import 'package:analyzer/analyzer.dart';
10 import 'package:analyzer/src/generated/ast.dart'; 10 import 'package:analyzer/src/generated/ast.dart';
(...skipping 587 matching lines...) Expand 10 before | Expand all | Expand 10 after
598 if (iteratedType != null) { 598 if (iteratedType != null) {
599 element.type = iteratedType; 599 element.type = iteratedType;
600 } 600 }
601 } 601 }
602 } 602 }
603 603
604 bool _isSealed(DartType t) { 604 bool _isSealed(DartType t) {
605 return _typeProvider.nonSubtypableTypes.contains(t); 605 return _typeProvider.nonSubtypableTypes.contains(t);
606 } 606 }
607 607
608 List<List> _genericList = null;
609
610 DartType _matchGeneric(MethodInvocation node, Element element) {
611 var e = node.methodName.staticElement;
612
613 if (_genericList == null) {
614 var minmax = (DartType tx, DartType ty) => (tx == ty &&
615 (tx == _typeProvider.intType || tx == _typeProvider.doubleType))
616 ? tx
617 : null;
618
619 var map = (DartType tx) => (tx is FunctionType)
620 ? _typeProvider.iterableType.substitute4([tx.returnType])
621 : null;
622
623 // TODO(vsm): LUB?
624 var fold = (DartType tx, DartType ty) =>
625 (ty is FunctionType && tx == ty.returnType) ? tx : null;
626
627 // TODO(vsm): Flatten?
628 var then = (DartType tx) => (tx is FunctionType)
629 ? _typeProvider.futureType.substitute4([tx.returnType])
630 : null;
631
632 var wait = (DartType tx) {
633 // Iterable<Future<T>> -> Future<List<T>>
634 var futureType = _findIteratedType(tx);
635 if (futureType.element.type != _typeProvider.futureType) return null;
636 var typeArguments = futureType.typeArguments;
637 if (typeArguments.length != 1) return null;
638 var baseType = typeArguments[0];
639 if (baseType.isDynamic) return null;
640 return _typeProvider.futureType.substitute4([
641 _typeProvider.listType.substitute4([baseType])
642 ]);
643 };
644
645 _genericList = [
646 // Top-level methods
647 ['dart:math', 'max', 2, minmax],
648 ['dart:math', 'min', 2, minmax],
649 // Static methods
650 [_typeProvider.futureType, 'wait', 1, wait],
651 // Instance methods
652 [_typeProvider.iterableDynamicType, 'map', 1, map],
653 [_typeProvider.iterableDynamicType, 'fold', 2, fold],
654 [_typeProvider.futureDynamicType, 'then', 1, then],
655 ];
656 }
657
658 var targetType = node.target?.staticType;
659 var arguments = node.argumentList.arguments;
660
661 for (var generic in _genericList) {
662 if (e?.name == generic[1]) {
663 if ((generic[0] is String &&
664 element?.library.source.uri.toString() == generic[0]) ||
665 (targetType == generic[0] ||
666 targetType != null && targetType.isSubtypeOf(generic[0]))) {
667 if (arguments.length == generic[2]) {
668 return Function.apply(
669 generic[3], arguments.map((arg) => arg.staticType).toList());
670 }
671 }
672 }
673 }
674
675 return null;
676 }
677
608 @override // to propagate types to identifiers 678 @override // to propagate types to identifiers
609 visitMethodInvocation(MethodInvocation node) { 679 visitMethodInvocation(MethodInvocation node) {
610 // TODO(jmesserly): we rely on having a staticType propagated to the 680 // TODO(jmesserly): we rely on having a staticType propagated to the
611 // methodName identifier. This shouldn't be necessary for method calls, so 681 // methodName identifier. This shouldn't be necessary for method calls, so
612 // analyzer doesn't do it by default. Conceptually what we're doing here 682 // analyzer doesn't do it by default. Conceptually what we're doing here
613 // is asking for a tear off. We need this until we can fix #132, and rely 683 // is asking for a tear off. We need this until we can fix #132, and rely
614 // on `node.staticElement == null` instead of `rules.isDynamicCall(node)`. 684 // on `node.staticElement == null` instead of `rules.isDynamicCall(node)`.
615 visitSimpleIdentifier(node.methodName); 685 visitSimpleIdentifier(node.methodName);
616 686
617 super.visitMethodInvocation(node); 687 super.visitMethodInvocation(node);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
665 // 735 //
666 // T min<T extends num>(T x, T y); 736 // T min<T extends num>(T x, T y);
667 // 737 //
668 // and infer T. In practice, this just means if the type of x and y are 738 // and infer T. In practice, this just means if the type of x and y are
669 // both double or both int, we treat that as the return type. 739 // both double or both int, we treat that as the return type.
670 // 740 //
671 // The Dart spec has similar treatment for binary operations on numbers. 741 // The Dart spec has similar treatment for binary operations on numbers.
672 // 742 //
673 // TODO(jmesserly): remove this when we have a fix for 743 // TODO(jmesserly): remove this when we have a fix for
674 // https://github.com/dart-lang/dev_compiler/issues/28 744 // https://github.com/dart-lang/dev_compiler/issues/28
675 if (isDartMathMinMax(e)) { 745 var inferred = _matchGeneric(node, e);
676 var args = node.argumentList.arguments; 746 // TODO(vsm): If the inferred type is not a subtype, should we use a GLB ins tead?
Jennifer Messerly 2015/08/28 21:49:07 long line?
677 if (args.length == 2) { 747 if (inferred != null && inferred.isSubtypeOf(node.staticType)) {
678 var tx = args[0].staticType; 748 node.staticType = inferred;
679 var ty = args[1].staticType;
680 if (tx == ty &&
681 (tx == _typeProvider.intType || tx == _typeProvider.doubleType)) {
682 node.staticType = tx;
683 }
684 }
685 } 749 }
686 } 750 }
687 751
688 void _inferObjectAccess( 752 void _inferObjectAccess(
689 Expression node, Expression target, SimpleIdentifier id) { 753 Expression node, Expression target, SimpleIdentifier id) {
690 // Search for Object accesses. 754 // Search for Object accesses.
691 var name = id.name; 755 var name = id.name;
692 if (node.staticType.isDynamic && 756 if (node.staticType.isDynamic &&
693 _objectMembers.containsKey(name) && 757 _objectMembers.containsKey(name) &&
694 isDynamicTarget(target)) { 758 isDynamicTarget(target)) {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
736 } 800 }
737 } 801 }
738 802
739 // Review note: no longer need to override visitFunctionExpression, this is 803 // Review note: no longer need to override visitFunctionExpression, this is
740 // handled by the analyzer internally. 804 // handled by the analyzer internally.
741 // TODO(vsm): in visitbinaryExpression: check computeStaticReturnType result? 805 // TODO(vsm): in visitbinaryExpression: check computeStaticReturnType result?
742 // TODO(vsm): in visitFunctionDeclaration: Should we ever use the expression 806 // TODO(vsm): in visitFunctionDeclaration: Should we ever use the expression
743 // type in a (...) => expr or just the written type? 807 // type in a (...) => expr or just the written type?
744 808
745 } 809 }
OLDNEW
« no previous file with comments | « lib/runtime/dart/typed_data.js ('k') | lib/src/dart_sdk.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698