| Index: lib/src/codegen/js_codegen.dart
|
| diff --git a/lib/src/codegen/js_codegen.dart b/lib/src/codegen/js_codegen.dart
|
| index 913eea26fc1fe6d678b7514a4b7688faa6ab1661..802b7a686a2d36c3261a049af5462e416a2bdac9 100644
|
| --- a/lib/src/codegen/js_codegen.dart
|
| +++ b/lib/src/codegen/js_codegen.dart
|
| @@ -63,7 +63,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor
|
| final StrongTypeSystemImpl rules;
|
|
|
| /// The global extension type table.
|
| - final HashSet<ClassElement> _extensionTypes;
|
| + final ExtensionTypeSet _extensionTypes;
|
|
|
| /// Information that is precomputed for this library, indicates which fields
|
| /// need storage slots.
|
| @@ -3716,12 +3716,16 @@ class JSCodegenVisitor extends GeneralizingAstVisitor
|
| }
|
| }
|
|
|
| -class _ExtensionFinder extends GeneralizingElementVisitor {
|
| +class ExtensionTypeSet extends GeneralizingElementVisitor {
|
| final AnalysisContext _context;
|
| - final HashSet<ClassElement> _extensionTypes;
|
| final TypeProvider _types;
|
|
|
| - _ExtensionFinder(this._context, this._extensionTypes, this._types);
|
| + final _extensionTypes = new HashSet<ClassElement>();
|
| + final _pendingLibraries = new HashSet<String>();
|
| +
|
| + ExtensionTypeSet(AbstractCompiler compiler)
|
| + : _context = compiler.context,
|
| + _types = compiler.context.typeProvider;
|
|
|
| visitClassElement(ClassElement element) {
|
| if (findAnnotation(element, isJsPeerInterface) != null ||
|
| @@ -3738,39 +3742,79 @@ class _ExtensionFinder extends GeneralizingElementVisitor {
|
| _addExtensionType(t.superclass);
|
| }
|
|
|
| + void _addExtensionTypesForLibrary(String libraryUri, List<String> typeNames) {
|
| + var sourceFactory = _context.sourceFactory.forUri(libraryUri);
|
| + var library = _context.computeLibraryElement(sourceFactory);
|
| + for (var typeName in typeNames) {
|
| + var element = library.getType(typeName);
|
| + _addExtensionType(element.type);
|
| + }
|
| + }
|
| +
|
| void _addExtensionTypes(String libraryUri) {
|
| var sourceFactory = _context.sourceFactory.forUri(libraryUri);
|
| var library = _context.computeLibraryElement(sourceFactory);
|
| visitLibraryElement(library);
|
| }
|
| +
|
| + void _addPendingExtensionTypes(String libraryUri) {
|
| + _pendingLibraries.add(libraryUri);
|
| + }
|
| +
|
| + bool contains(Element element) {
|
| + if (_extensionTypes.contains(element)) return true;
|
| + if (_pendingLibraries.isEmpty) return false;
|
| + if (element is ClassElement) {
|
| + var uri = element.library.source.uri.toString();
|
| + if (_pendingLibraries.contains(uri)) {
|
| + // Load all pending libraries
|
| + for (var libraryUri in _pendingLibraries) {
|
| + _addExtensionTypes(libraryUri);
|
| + }
|
| + _pendingLibraries.clear();
|
| + return _extensionTypes.contains(element);
|
| + }
|
| + }
|
| + return false;
|
| + }
|
| }
|
|
|
| class JSGenerator extends CodeGenerator {
|
| - final _extensionTypes = new HashSet<ClassElement>();
|
| + final ExtensionTypeSet _extensionTypes;
|
| final TypeProvider _types;
|
|
|
| JSGenerator(AbstractCompiler compiler)
|
| : _types = compiler.context.typeProvider,
|
| + _extensionTypes = new ExtensionTypeSet(compiler),
|
| super(compiler) {
|
| // TODO(vsm): Eventually, we want to make this extensible - i.e., find
|
| // annotations in user code as well. It would need to be summarized in
|
| - // the element model - not searched this way on every compile.
|
| - var finder = new _ExtensionFinder(context, _extensionTypes, _types);
|
| - finder._addExtensionTypes('dart:_interceptors');
|
| - finder._addExtensionTypes('dart:_native_typed_data');
|
| - finder._addExtensionTypes('dart:html');
|
| - finder._addExtensionTypes('dart:indexed_db');
|
| - finder._addExtensionTypes('dart:svg');
|
| - finder._addExtensionTypes('dart:web_audio');
|
| - finder._addExtensionTypes('dart:web_gl');
|
| - finder._addExtensionTypes('dart:web_sql');
|
| + // the element model - not searched this way on every compile. To make this
|
| + // a little more efficient now, we do this in two phases.
|
|
|
| + // First, core types:
|
| + _extensionTypes._addExtensionTypes('dart:_interceptors');
|
| + _extensionTypes._addExtensionTypes('dart:_native_typed_data');
|
| // TODO(vsm): If we're analyzing against the main SDK, those
|
| // types are not explicitly annotated.
|
| - finder._addExtensionType(_types.intType);
|
| - finder._addExtensionType(_types.doubleType);
|
| - finder._addExtensionType(_types.boolType);
|
| - finder._addExtensionType(_types.stringType);
|
| + _extensionTypes._addExtensionType(_types.intType);
|
| + _extensionTypes._addExtensionType(_types.doubleType);
|
| + _extensionTypes._addExtensionType(_types.boolType);
|
| + _extensionTypes._addExtensionType(_types.stringType);
|
| + // These are used natively by dart:html but also not annotated.
|
| + _extensionTypes
|
| + ._addExtensionTypesForLibrary('dart:core', ['Comparable', 'Map']);
|
| + _extensionTypes
|
| + ._addExtensionTypesForLibrary('dart:collection', ['ListMixin']);
|
| + _extensionTypes._addExtensionTypesForLibrary('dart:math', ['Rectangle']);
|
| +
|
| + // Second, html types - these are only searched if we use dart:html, etc.:
|
| + _extensionTypes._addPendingExtensionTypes('dart:html');
|
| + _extensionTypes._addPendingExtensionTypes('dart:indexed_db');
|
| + _extensionTypes._addPendingExtensionTypes('dart:svg');
|
| + _extensionTypes._addPendingExtensionTypes('dart:web_audio');
|
| + _extensionTypes._addPendingExtensionTypes('dart:web_gl');
|
| + _extensionTypes._addPendingExtensionTypes('dart:web_sql');
|
| }
|
|
|
| String generateLibrary(LibraryUnit unit) {
|
|
|