| OLD | NEW |
| 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 | 2 |
| 3 // for details. All rights reserved. Use of this source code is governed by a | 3 // for details. All rights reserved. Use of this source code is governed by a |
| 4 // BSD-style license that can be found in the LICENSE file. | 4 // BSD-style license that can be found in the LICENSE file. |
| 5 | 5 |
| 6 import 'dart:collection' show HashMap, HashSet; | 6 import 'dart:collection' show HashMap, HashSet; |
| 7 import 'dart:math' show min, max; | 7 import 'dart:math' show min, max; |
| 8 | 8 |
| 9 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator; | 9 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator; |
| 10 import 'package:analyzer/dart/ast/ast.dart'; | 10 import 'package:analyzer/dart/ast/ast.dart'; |
| (...skipping 734 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 745 | 745 |
| 746 // If this is a JavaScript type, emit it now and then exit. | 746 // If this is a JavaScript type, emit it now and then exit. |
| 747 var jsTypeDef = _emitJsType(classElem); | 747 var jsTypeDef = _emitJsType(classElem); |
| 748 if (jsTypeDef != null) return jsTypeDef; | 748 if (jsTypeDef != null) return jsTypeDef; |
| 749 | 749 |
| 750 var ctors = <ConstructorDeclaration>[]; | 750 var ctors = <ConstructorDeclaration>[]; |
| 751 var fields = <FieldDeclaration>[]; | 751 var fields = <FieldDeclaration>[]; |
| 752 var staticFields = <FieldDeclaration>[]; | 752 var staticFields = <FieldDeclaration>[]; |
| 753 var methods = <MethodDeclaration>[]; | 753 var methods = <MethodDeclaration>[]; |
| 754 | 754 |
| 755 // True if a "call" method or getter exists. | 755 // True if a "call" method or getter exists directly on this class. |
| 756 // If so, we need to install a Function prototype. |
| 756 bool isCallable = false; | 757 bool isCallable = false; |
| 757 for (var member in node.members) { | 758 for (var member in node.members) { |
| 758 if (member is ConstructorDeclaration) { | 759 if (member is ConstructorDeclaration) { |
| 759 ctors.add(member); | 760 ctors.add(member); |
| 760 } else if (member is FieldDeclaration) { | 761 } else if (member is FieldDeclaration) { |
| 761 (member.isStatic ? staticFields : fields).add(member); | 762 (member.isStatic ? staticFields : fields).add(member); |
| 762 } else if (member is MethodDeclaration) { | 763 } else if (member is MethodDeclaration) { |
| 763 methods.add(member); | 764 methods.add(member); |
| 764 if (member.name.name == 'call' && !member.isSetter) { | 765 if (member.name.name == 'call' && !member.isSetter) { |
| 765 // | 766 // |
| 766 // Make sure "call" has a statically known function type: | 767 // Make sure "call" has a statically known function type: |
| 767 // | 768 // |
| 768 // - if it's a method, then it does because all methods do, | 769 // - if it's a method, then it does because all methods do, |
| 769 // - if it's a getter, check the return type. | 770 // - if it's a getter, check the return type. |
| 770 // | 771 // |
| 771 // Other cases like a getter returning dynamic/Object/Function will be | 772 // Other cases like a getter returning dynamic/Object/Function will be |
| 772 // handled at runtime by the dynamic call mechanism. So we only | 773 // handled at runtime by the dynamic call mechanism. So we only |
| 773 // concern ourselves with statically known function types. | 774 // concern ourselves with statically known function types. |
| 774 // | 775 // |
| 775 // For the same reason, we can ignore "noSuchMethod". | 776 // For the same reason, we can ignore "noSuchMethod". |
| 776 // call-implemented-by-nSM will be dispatched by dcall at runtime. | 777 // call-implemented-by-nSM will be dispatched by dcall at runtime. |
| 777 // | 778 // |
| 778 isCallable = !member.isGetter || member.returnType is FunctionType; | 779 isCallable = !member.isGetter || member.returnType is FunctionType; |
| 779 } | 780 } |
| 780 } | 781 } |
| 781 } | 782 } |
| 782 | 783 |
| 784 // True if a "call" method or getter exists directly or indirectly on this |
| 785 // class. If so, we need special constructor handling. |
| 786 bool isCallableTransitive = |
| 787 classElem.lookUpMethod('call', currentLibrary) != null; |
| 788 if (!isCallableTransitive) { |
| 789 var callGetter = classElem.lookUpGetter('call', currentLibrary); |
| 790 isCallableTransitive = |
| 791 callGetter != null && callGetter.returnType is FunctionType; |
| 792 } |
| 793 |
| 783 JS.Expression className; | 794 JS.Expression className; |
| 784 if (classElem.typeParameters.isNotEmpty) { | 795 if (classElem.typeParameters.isNotEmpty) { |
| 785 // Generic classes will be defined inside a function that closes over the | 796 // Generic classes will be defined inside a function that closes over the |
| 786 // type parameter. So we can use their local variable name directly. | 797 // type parameter. So we can use their local variable name directly. |
| 787 className = new JS.Identifier(classElem.name); | 798 className = new JS.Identifier(classElem.name); |
| 788 } else { | 799 } else { |
| 789 className = _emitTopLevelName(classElem); | 800 className = _emitTopLevelName(classElem); |
| 790 } | 801 } |
| 791 | 802 |
| 792 var allFields = fields.toList()..addAll(staticFields); | 803 var allFields = fields.toList()..addAll(staticFields); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 809 // Emit the class, e.g. `core.Object = class Object { ... }` | 820 // Emit the class, e.g. `core.Object = class Object { ... }` |
| 810 _defineClass(classElem, className, classExpr, isCallable, body); | 821 _defineClass(classElem, className, classExpr, isCallable, body); |
| 811 | 822 |
| 812 // Emit things that come after the ES6 `class ... { ... }`. | 823 // Emit things that come after the ES6 `class ... { ... }`. |
| 813 var jsPeerNames = _getJSPeerNames(classElem); | 824 var jsPeerNames = _getJSPeerNames(classElem); |
| 814 JS.Statement deferredBaseClass = | 825 JS.Statement deferredBaseClass = |
| 815 _setBaseClass(classElem, className, jsPeerNames, body); | 826 _setBaseClass(classElem, className, jsPeerNames, body); |
| 816 | 827 |
| 817 _emitClassTypeTests(classElem, className, body); | 828 _emitClassTypeTests(classElem, className, body); |
| 818 | 829 |
| 819 _defineNamedConstructors(ctors, body, className, isCallable); | 830 _defineNamedConstructors(ctors, body, className, isCallableTransitive); |
| 820 body.addAll(virtualFieldSymbols); | 831 body.addAll(virtualFieldSymbols); |
| 821 _emitClassSignature( | 832 _emitClassSignature( |
| 822 methods, allFields, classElem, ctors, extensions, className, body); | 833 methods, allFields, classElem, ctors, extensions, className, body); |
| 823 _defineExtensionMembers(extensions, className, body); | 834 _defineExtensionMembers(extensions, className, body); |
| 824 _emitClassMetadata(node.metadata, className, body); | 835 _emitClassMetadata(node.metadata, className, body); |
| 825 | 836 |
| 826 JS.Statement classDef = _statement(body); | 837 JS.Statement classDef = _statement(body); |
| 827 | 838 |
| 828 var typeFormals = classElem.typeParameters; | 839 var typeFormals = classElem.typeParameters; |
| 829 if (typeFormals.isNotEmpty) { | 840 if (typeFormals.isNotEmpty) { |
| (...skipping 4969 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5799 if (targetIdentifier.staticElement is! PrefixElement) return false; | 5810 if (targetIdentifier.staticElement is! PrefixElement) return false; |
| 5800 var prefix = targetIdentifier.staticElement as PrefixElement; | 5811 var prefix = targetIdentifier.staticElement as PrefixElement; |
| 5801 | 5812 |
| 5802 // The library the prefix is referring to must come from a deferred import. | 5813 // The library the prefix is referring to must come from a deferred import. |
| 5803 var containingLibrary = resolutionMap | 5814 var containingLibrary = resolutionMap |
| 5804 .elementDeclaredByCompilationUnit(target.root as CompilationUnit) | 5815 .elementDeclaredByCompilationUnit(target.root as CompilationUnit) |
| 5805 .library; | 5816 .library; |
| 5806 var imports = containingLibrary.getImportsWithPrefix(prefix); | 5817 var imports = containingLibrary.getImportsWithPrefix(prefix); |
| 5807 return imports.length == 1 && imports[0].isDeferred; | 5818 return imports.length == 1 && imports[0].isDeferred; |
| 5808 } | 5819 } |
| OLD | NEW |