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

Side by Side Diff: lib/src/codegen/js_codegen.dart

Issue 1752133002: Search html extension types lazily (Closed) Base URL: https://github.com/dart-lang/dev_compiler.git@master
Patch Set: Created 4 years, 9 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 | « no previous file | lib/src/codegen/js_field_storage.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 import 'dart:collection' show HashSet, HashMap, SplayTreeSet; 5 import 'dart:collection' show HashSet, HashMap, SplayTreeSet;
6 6
7 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator; 7 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator;
8 import 'package:analyzer/dart/ast/token.dart'; 8 import 'package:analyzer/dart/ast/token.dart';
9 import 'package:analyzer/src/generated/ast.dart' hide ConstantEvaluator; 9 import 'package:analyzer/src/generated/ast.dart' hide ConstantEvaluator;
10 import 'package:analyzer/src/generated/constant.dart'; 10 import 'package:analyzer/src/generated/constant.dart';
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
56 const DSEND = 'dsend'; 56 const DSEND = 'dsend';
57 57
58 class JSCodegenVisitor extends GeneralizingAstVisitor 58 class JSCodegenVisitor extends GeneralizingAstVisitor
59 with ClosureAnnotator, JsTypeRefCodegen { 59 with ClosureAnnotator, JsTypeRefCodegen {
60 final AbstractCompiler compiler; 60 final AbstractCompiler compiler;
61 final CodegenOptions options; 61 final CodegenOptions options;
62 final LibraryElement currentLibrary; 62 final LibraryElement currentLibrary;
63 final StrongTypeSystemImpl rules; 63 final StrongTypeSystemImpl rules;
64 64
65 /// The global extension type table. 65 /// The global extension type table.
66 final HashSet<ClassElement> _extensionTypes; 66 final ExtensionTypeSet _extensionTypes;
67 67
68 /// Information that is precomputed for this library, indicates which fields 68 /// Information that is precomputed for this library, indicates which fields
69 /// need storage slots. 69 /// need storage slots.
70 final HashSet<FieldElement> _fieldsNeedingStorage; 70 final HashSet<FieldElement> _fieldsNeedingStorage;
71 71
72 /// The variable for the target of the current `..` cascade expression. 72 /// The variable for the target of the current `..` cascade expression.
73 /// 73 ///
74 /// Usually a [SimpleIdentifier], but it can also be other expressions 74 /// Usually a [SimpleIdentifier], but it can also be other expressions
75 /// that are safe to evaluate multiple times, such as `this`. 75 /// that are safe to evaluate multiple times, such as `this`.
76 Expression _cascadeTarget; 76 Expression _cascadeTarget;
(...skipping 3632 matching lines...) Expand 10 before | Expand all | Expand 10 after
3709 } else if (type is InterfaceType && type.element == expectedType.element) { 3709 } else if (type is InterfaceType && type.element == expectedType.element) {
3710 return type.typeArguments[0]; 3710 return type.typeArguments[0];
3711 } else { 3711 } else {
3712 // TODO(leafp): The above only handles the case where the return type 3712 // TODO(leafp): The above only handles the case where the return type
3713 // is exactly Future/Stream/Iterable. Handle the subtype case. 3713 // is exactly Future/Stream/Iterable. Handle the subtype case.
3714 return DynamicTypeImpl.instance; 3714 return DynamicTypeImpl.instance;
3715 } 3715 }
3716 } 3716 }
3717 } 3717 }
3718 3718
3719 class _ExtensionFinder extends GeneralizingElementVisitor { 3719 class ExtensionTypeSet extends GeneralizingElementVisitor {
3720 final AnalysisContext _context; 3720 final AnalysisContext _context;
3721 final HashSet<ClassElement> _extensionTypes;
3722 final TypeProvider _types; 3721 final TypeProvider _types;
3723 3722
3724 _ExtensionFinder(this._context, this._extensionTypes, this._types); 3723 final _extensionTypes = new HashSet<ClassElement>();
3724 final _pendingLibraries = new HashSet<String>();
3725
3726 ExtensionTypeSet(AbstractCompiler compiler)
3727 : _context = compiler.context,
3728 _types = compiler.context.typeProvider;
3725 3729
3726 visitClassElement(ClassElement element) { 3730 visitClassElement(ClassElement element) {
3727 if (findAnnotation(element, isJsPeerInterface) != null || 3731 if (findAnnotation(element, isJsPeerInterface) != null ||
3728 findAnnotation(element, isNativeAnnotation) != null) { 3732 findAnnotation(element, isNativeAnnotation) != null) {
3729 _addExtensionType(element.type); 3733 _addExtensionType(element.type);
3730 } 3734 }
3731 } 3735 }
3732 3736
3733 void _addExtensionType(InterfaceType t) { 3737 void _addExtensionType(InterfaceType t) {
3734 if (t.isObject || !_extensionTypes.add(t.element)) return; 3738 if (t.isObject || !_extensionTypes.add(t.element)) return;
3735 t = fillDynamicTypeArgs(t, _types) as InterfaceType; 3739 t = fillDynamicTypeArgs(t, _types) as InterfaceType;
3736 t.interfaces.forEach(_addExtensionType); 3740 t.interfaces.forEach(_addExtensionType);
3737 t.mixins.forEach(_addExtensionType); 3741 t.mixins.forEach(_addExtensionType);
3738 _addExtensionType(t.superclass); 3742 _addExtensionType(t.superclass);
3739 } 3743 }
3740 3744
3745 void _addExtensionTypesForLibrary(String libraryUri, List<String> typeNames) {
3746 var sourceFactory = _context.sourceFactory.forUri(libraryUri);
3747 var library = _context.computeLibraryElement(sourceFactory);
3748 for (var typeName in typeNames) {
3749 var element = library.getType(typeName);
3750 _addExtensionType(element.type);
3751 }
3752 }
3753
3741 void _addExtensionTypes(String libraryUri) { 3754 void _addExtensionTypes(String libraryUri) {
3742 var sourceFactory = _context.sourceFactory.forUri(libraryUri); 3755 var sourceFactory = _context.sourceFactory.forUri(libraryUri);
3743 var library = _context.computeLibraryElement(sourceFactory); 3756 var library = _context.computeLibraryElement(sourceFactory);
3744 visitLibraryElement(library); 3757 visitLibraryElement(library);
3745 } 3758 }
3759
3760 void _addPendingExtensionTypes(String libraryUri) {
3761 _pendingLibraries.add(libraryUri);
3762 }
3763
3764 bool contains(Element element) {
3765 if (_extensionTypes.contains(element)) return true;
3766 if (_pendingLibraries.isEmpty) return false;
3767 if (element is ClassElement) {
3768 var uri = element.library.source.uri.toString();
3769 if (_pendingLibraries.contains(uri)) {
3770 // Load all pending libraries
3771 for (var libraryUri in _pendingLibraries) {
3772 _addExtensionTypes(libraryUri);
3773 }
3774 _pendingLibraries.clear();
3775 return _extensionTypes.contains(element);
3776 }
3777 }
3778 return false;
3779 }
3746 } 3780 }
3747 3781
3748 class JSGenerator extends CodeGenerator { 3782 class JSGenerator extends CodeGenerator {
3749 final _extensionTypes = new HashSet<ClassElement>(); 3783 final ExtensionTypeSet _extensionTypes;
3750 final TypeProvider _types; 3784 final TypeProvider _types;
3751 3785
3752 JSGenerator(AbstractCompiler compiler) 3786 JSGenerator(AbstractCompiler compiler)
3753 : _types = compiler.context.typeProvider, 3787 : _types = compiler.context.typeProvider,
3788 _extensionTypes = new ExtensionTypeSet(compiler),
3754 super(compiler) { 3789 super(compiler) {
3755 // TODO(vsm): Eventually, we want to make this extensible - i.e., find 3790 // TODO(vsm): Eventually, we want to make this extensible - i.e., find
3756 // annotations in user code as well. It would need to be summarized in 3791 // annotations in user code as well. It would need to be summarized in
3757 // the element model - not searched this way on every compile. 3792 // the element model - not searched this way on every compile. To make this
3758 var finder = new _ExtensionFinder(context, _extensionTypes, _types); 3793 // a little more efficient now, we do this in two phases.
3759 finder._addExtensionTypes('dart:_interceptors');
3760 finder._addExtensionTypes('dart:_native_typed_data');
3761 finder._addExtensionTypes('dart:html');
3762 finder._addExtensionTypes('dart:indexed_db');
3763 finder._addExtensionTypes('dart:svg');
3764 finder._addExtensionTypes('dart:web_audio');
3765 finder._addExtensionTypes('dart:web_gl');
3766 finder._addExtensionTypes('dart:web_sql');
3767 3794
3795 // First, core types:
3796 _extensionTypes._addExtensionTypes('dart:_interceptors');
3797 _extensionTypes._addExtensionTypes('dart:_native_typed_data');
3768 // TODO(vsm): If we're analyzing against the main SDK, those 3798 // TODO(vsm): If we're analyzing against the main SDK, those
3769 // types are not explicitly annotated. 3799 // types are not explicitly annotated.
3770 finder._addExtensionType(_types.intType); 3800 _extensionTypes._addExtensionType(_types.intType);
3771 finder._addExtensionType(_types.doubleType); 3801 _extensionTypes._addExtensionType(_types.doubleType);
3772 finder._addExtensionType(_types.boolType); 3802 _extensionTypes._addExtensionType(_types.boolType);
3773 finder._addExtensionType(_types.stringType); 3803 _extensionTypes._addExtensionType(_types.stringType);
3804 // These are used natively by dart:html but also not annotated.
3805 _extensionTypes
3806 ._addExtensionTypesForLibrary('dart:core', ['Comparable', 'Map']);
3807 _extensionTypes
3808 ._addExtensionTypesForLibrary('dart:collection', ['ListMixin']);
3809 _extensionTypes._addExtensionTypesForLibrary('dart:math', ['Rectangle']);
3810
3811 // Second, html types - these are only searched if we use dart:html, etc.:
3812 _extensionTypes._addPendingExtensionTypes('dart:html');
3813 _extensionTypes._addPendingExtensionTypes('dart:indexed_db');
3814 _extensionTypes._addPendingExtensionTypes('dart:svg');
3815 _extensionTypes._addPendingExtensionTypes('dart:web_audio');
3816 _extensionTypes._addPendingExtensionTypes('dart:web_gl');
3817 _extensionTypes._addPendingExtensionTypes('dart:web_sql');
3774 } 3818 }
3775 3819
3776 String generateLibrary(LibraryUnit unit) { 3820 String generateLibrary(LibraryUnit unit) {
3777 // Clone the AST first, so we can mutate it. 3821 // Clone the AST first, so we can mutate it.
3778 unit = unit.clone(); 3822 unit = unit.clone();
3779 var library = unit.library.element.library; 3823 var library = unit.library.element.library;
3780 var fields = findFieldsNeedingStorage(unit, _extensionTypes); 3824 var fields = findFieldsNeedingStorage(unit, _extensionTypes);
3781 var rules = new StrongTypeSystemImpl(); 3825 var rules = new StrongTypeSystemImpl();
3782 var codegen = 3826 var codegen =
3783 new JSCodegenVisitor(compiler, rules, library, _extensionTypes, fields); 3827 new JSCodegenVisitor(compiler, rules, library, _extensionTypes, fields);
(...skipping 27 matching lines...) Expand all
3811 3855
3812 /// A special kind of element created by the compiler, signifying a temporary 3856 /// A special kind of element created by the compiler, signifying a temporary
3813 /// variable. These objects use instance equality, and should be shared 3857 /// variable. These objects use instance equality, and should be shared
3814 /// everywhere in the tree where they are treated as the same variable. 3858 /// everywhere in the tree where they are treated as the same variable.
3815 class TemporaryVariableElement extends LocalVariableElementImpl { 3859 class TemporaryVariableElement extends LocalVariableElementImpl {
3816 TemporaryVariableElement.forNode(Identifier name) : super.forNode(name); 3860 TemporaryVariableElement.forNode(Identifier name) : super.forNode(name);
3817 3861
3818 int get hashCode => identityHashCode(this); 3862 int get hashCode => identityHashCode(this);
3819 bool operator ==(Object other) => identical(this, other); 3863 bool operator ==(Object other) => identical(this, other);
3820 } 3864 }
OLDNEW
« no previous file with comments | « no previous file | lib/src/codegen/js_field_storage.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698