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

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: Reformat 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/isolate.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])
vsm 2015/08/28 15:48:50 Hmm - rethinking this ... If my target type (stat
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) =>
629 (tx is FunctionType && !tx.returnType.isDynamic)
Leaf 2015/08/28 01:05:38 Why are you checking for dynamic here, and not els
630 ? _typeProvider.futureType.substitute4([tx.returnType])
631 : null;
632
633 var wait = (DartType tx) {
634 // Iterable<Future<T>> -> Future<List<T>>
635 var futureType = _findIteratedType(tx);
636 if (futureType.element.type != _typeProvider.futureType) return null;
637 var typeArguments = futureType.typeArguments;
638 if (typeArguments.length != 1) return null;
639 var baseType = typeArguments[0];
640 if (baseType.isDynamic) return null;
641 return _typeProvider.futureType.substitute4([
642 _typeProvider.listType.substitute4([baseType])
643 ]);
644 };
645
646 _genericList = [
647 // Top-level methods
648 ['dart:math', 'max', 2, minmax],
649 ['dart:math', 'min', 2, minmax],
650 // Static methods
651 [_typeProvider.futureType, 'wait', 1, wait],
652 // Instance methods
653 [_typeProvider.iterableDynamicType, 'map', 1, map],
654 [_typeProvider.iterableDynamicType, 'fold', 2, fold],
655 [_typeProvider.futureDynamicType, 'then', 1, then],
656 ];
657 }
658
659 var targetType = node.target?.staticType;
660 var arguments = node.argumentList.arguments;
661
662 for (var generic in _genericList) {
663 if (e?.name == generic[1]) {
664 if ((generic[0] is String &&
665 element?.library.source.uri.toString() == generic[0]) ||
666 (targetType == generic[0] ||
667 targetType != null && targetType.isSubtypeOf(generic[0]))) {
668 if (arguments.length == generic[2]) {
669 return Function.apply(
670 generic[3], arguments.map((arg) => arg.staticType).toList());
671 }
672 }
673 }
674 }
675
676 return null;
677 }
678
608 @override // to propagate types to identifiers 679 @override // to propagate types to identifiers
609 visitMethodInvocation(MethodInvocation node) { 680 visitMethodInvocation(MethodInvocation node) {
610 // TODO(jmesserly): we rely on having a staticType propagated to the 681 // TODO(jmesserly): we rely on having a staticType propagated to the
611 // methodName identifier. This shouldn't be necessary for method calls, so 682 // 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 683 // 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 684 // 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)`. 685 // on `node.staticElement == null` instead of `rules.isDynamicCall(node)`.
615 visitSimpleIdentifier(node.methodName); 686 visitSimpleIdentifier(node.methodName);
616 687
617 super.visitMethodInvocation(node); 688 super.visitMethodInvocation(node);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
665 // 736 //
666 // T min<T extends num>(T x, T y); 737 // T min<T extends num>(T x, T y);
667 // 738 //
668 // and infer T. In practice, this just means if the type of x and y are 739 // 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. 740 // both double or both int, we treat that as the return type.
670 // 741 //
671 // The Dart spec has similar treatment for binary operations on numbers. 742 // The Dart spec has similar treatment for binary operations on numbers.
672 // 743 //
673 // TODO(jmesserly): remove this when we have a fix for 744 // TODO(jmesserly): remove this when we have a fix for
674 // https://github.com/dart-lang/dev_compiler/issues/28 745 // https://github.com/dart-lang/dev_compiler/issues/28
675 if (isDartMathMinMax(e)) { 746 var inferred = _matchGeneric(node, e);
676 var args = node.argumentList.arguments; 747 if (inferred != null) node.staticType = inferred;
677 if (args.length == 2) {
678 var tx = args[0].staticType;
679 var ty = args[1].staticType;
680 if (tx == ty &&
681 (tx == _typeProvider.intType || tx == _typeProvider.doubleType)) {
682 node.staticType = tx;
683 }
684 }
685 }
686 } 748 }
687 749
688 void _inferObjectAccess( 750 void _inferObjectAccess(
689 Expression node, Expression target, SimpleIdentifier id) { 751 Expression node, Expression target, SimpleIdentifier id) {
690 // Search for Object accesses. 752 // Search for Object accesses.
691 var name = id.name; 753 var name = id.name;
692 if (node.staticType.isDynamic && 754 if (node.staticType.isDynamic &&
693 _objectMembers.containsKey(name) && 755 _objectMembers.containsKey(name) &&
694 isDynamicTarget(target)) { 756 isDynamicTarget(target)) {
695 target.staticType = _typeProvider.objectType; 757 target.staticType = _typeProvider.objectType;
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
736 } 798 }
737 } 799 }
738 800
739 // Review note: no longer need to override visitFunctionExpression, this is 801 // Review note: no longer need to override visitFunctionExpression, this is
740 // handled by the analyzer internally. 802 // handled by the analyzer internally.
741 // TODO(vsm): in visitbinaryExpression: check computeStaticReturnType result? 803 // TODO(vsm): in visitbinaryExpression: check computeStaticReturnType result?
742 // TODO(vsm): in visitFunctionDeclaration: Should we ever use the expression 804 // TODO(vsm): in visitFunctionDeclaration: Should we ever use the expression
743 // type in a (...) => expr or just the written type? 805 // type in a (...) => expr or just the written type?
744 806
745 } 807 }
OLDNEW
« no previous file with comments | « lib/runtime/dart/isolate.js ('k') | lib/src/dart_sdk.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698