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 // 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 HashMap, HashSet; | 5 import 'dart:collection' show HashMap, HashSet; |
6 import 'dart:math' show min, max; | 6 import 'dart:math' show min, max; |
7 | 7 |
8 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator; | 8 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator; |
9 import 'package:analyzer/dart/ast/ast.dart'; | 9 import 'package:analyzer/dart/ast/ast.dart'; |
10 import 'package:analyzer/dart/ast/token.dart' show Token, TokenType; | 10 import 'package:analyzer/dart/ast/token.dart' show Token, TokenType; |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
84 new HashMap<LibraryElement, HashMap<String, JS.TemporaryId>>(); | 84 new HashMap<LibraryElement, HashMap<String, JS.TemporaryId>>(); |
85 final _initializingFormalTemps = | 85 final _initializingFormalTemps = |
86 new HashMap<ParameterElement, JS.TemporaryId>(); | 86 new HashMap<ParameterElement, JS.TemporaryId>(); |
87 | 87 |
88 final _dartxVar = new JS.Identifier('dartx'); | 88 final _dartxVar = new JS.Identifier('dartx'); |
89 final _runtimeLibVar = new JS.Identifier('dart'); | 89 final _runtimeLibVar = new JS.Identifier('dart'); |
90 final namedArgumentTemp = new JS.TemporaryId('opts'); | 90 final namedArgumentTemp = new JS.TemporaryId('opts'); |
91 | 91 |
92 final _hasDeferredSupertype = new HashSet<ClassElement>(); | 92 final _hasDeferredSupertype = new HashSet<ClassElement>(); |
93 | 93 |
94 final _eagerTopLevelFields = new HashSet<Element>.identity(); | |
95 | |
94 /// The type provider from the current Analysis [context]. | 96 /// The type provider from the current Analysis [context]. |
95 final TypeProvider types; | 97 final TypeProvider types; |
96 | 98 |
97 final LibraryElement dartCoreLibrary; | 99 final LibraryElement dartCoreLibrary; |
98 final LibraryElement dartJSLibrary; | 100 final LibraryElement dartJSLibrary; |
99 | 101 |
100 /// The dart:async `StreamIterator<>` type. | 102 /// The dart:async `StreamIterator<>` type. |
101 final InterfaceType _asyncStreamIterator; | 103 final InterfaceType _asyncStreamIterator; |
102 | 104 |
103 /// The dart:_interceptors JSArray element. | 105 /// The dart:_interceptors JSArray element. |
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
373 | 375 |
374 @override | 376 @override |
375 void visitExportDirective(ExportDirective node) { | 377 void visitExportDirective(ExportDirective node) { |
376 ExportElement element = node.element; | 378 ExportElement element = node.element; |
377 var currentLibrary = element.library; | 379 var currentLibrary = element.library; |
378 | 380 |
379 var currentNames = currentLibrary.publicNamespace.definedNames; | 381 var currentNames = currentLibrary.publicNamespace.definedNames; |
380 var exportedNames = | 382 var exportedNames = |
381 new NamespaceBuilder().createExportNamespaceForDirective(element); | 383 new NamespaceBuilder().createExportNamespaceForDirective(element); |
382 | 384 |
385 var libraryName = emitLibraryName(currentLibrary); | |
386 | |
383 // TODO(jmesserly): we could collect all of the names for bulk re-export, | 387 // TODO(jmesserly): we could collect all of the names for bulk re-export, |
384 // but this is easier to implement for now. | 388 // but this is easier to implement for now. |
385 void emitExport(Element export, {String suffix: ''}) { | 389 void emitExport(Element export, {String suffix: ''}) { |
386 var name = _emitTopLevelName(export, suffix: suffix); | 390 var name = _emitTopLevelName(export, suffix: suffix); |
387 _moduleItems.add(js.statement( | 391 |
388 '#.# = #;', [emitLibraryName(currentLibrary), name.selector, name])); | 392 if (export is TypeDefiningElement || export is FunctionElement || |
393 _eagerTopLevelFields.contains(export)) { | |
394 // classes, typedefs, functions, and eager init fields can be assigned | |
395 // directly. | |
396 // TODO(jmesserly): we don't know about eager init fields from other | |
397 // modules we import, so we will never go down this code path for them. | |
398 _moduleItems | |
399 .add(js.statement('#.# = #;', [libraryName, name.selector, name])); | |
400 } else { | |
401 // top-level fields, getters, setters need to copy the property | |
402 // descriptor. | |
403 _moduleItems.add(js.statement('dart.copyProperty(#, #, #);', | |
vsm
2016/05/03 21:59:14
From a readability standpoint, perhaps "exportProp
Jennifer Messerly
2016/05/03 23:37:28
yeah, we used to call it "dart.export". restored t
| |
404 [libraryName, name.receiver, name.selector])); | |
405 } | |
389 } | 406 } |
390 | 407 |
391 for (var export in exportedNames.definedNames.values) { | 408 for (var export in exportedNames.definedNames.values) { |
409 if (export is PropertyAccessorElement) { | |
410 export = (export as PropertyAccessorElement).variable; | |
411 } | |
412 | |
392 // Don't allow redefining names from this library. | 413 // Don't allow redefining names from this library. |
393 if (currentNames.containsKey(export.name)) continue; | 414 if (currentNames.containsKey(export.name)) continue; |
394 | 415 |
395 _loader.emitDeclaration(export); | 416 _loader.emitDeclaration(export); |
396 if (export is ClassElement && export.typeParameters.isNotEmpty) { | 417 if (export is ClassElement && export.typeParameters.isNotEmpty) { |
397 // Export the generic name as well. | 418 // Export the generic name as well. |
398 // TODO(jmesserly): revisit generic classes | 419 // TODO(jmesserly): revisit generic classes |
399 emitExport(export, suffix: r'$'); | 420 emitExport(export, suffix: r'$'); |
400 } | 421 } |
401 emitExport(export); | 422 emitExport(export); |
(...skipping 2361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2763 // later on when we emit lazy fields. That seems busted. | 2784 // later on when we emit lazy fields. That seems busted. |
2764 jsInit = _visitInitializer(field); | 2785 jsInit = _visitInitializer(field); |
2765 eagerInit = false; | 2786 eagerInit = false; |
2766 } | 2787 } |
2767 | 2788 |
2768 // Treat `final x = JS('', '...')` as a const (non-lazy) to help compile | 2789 // Treat `final x = JS('', '...')` as a const (non-lazy) to help compile |
2769 // runtime helpers. | 2790 // runtime helpers. |
2770 // TODO(jmesserly): we don't track dependencies correctly for these. | 2791 // TODO(jmesserly): we don't track dependencies correctly for these. |
2771 var isJSTopLevel = field.isFinal && _isFinalJSDecl(field); | 2792 var isJSTopLevel = field.isFinal && _isFinalJSDecl(field); |
2772 if (eagerInit || isJSTopLevel) { | 2793 if (eagerInit || isJSTopLevel) { |
2794 // Remember that we emitted it this way, so re-export can take advantage | |
2795 // of this fact. | |
2796 _eagerTopLevelFields.add(element); | |
2797 | |
2773 return annotate( | 2798 return annotate( |
2774 js.statement('# = #;', [_emitTopLevelName(element), jsInit]), | 2799 js.statement('# = #;', [_emitTopLevelName(element), jsInit]), |
2775 field, | 2800 field, |
2776 element); | 2801 element); |
2777 } | 2802 } |
2778 | 2803 |
2779 assert(element.library == currentLibrary); | 2804 assert(element.library == currentLibrary); |
2780 return _emitLazyFields(element.library, [field]); | 2805 return _emitLazyFields(element.library, [field]); |
2781 } | 2806 } |
2782 | 2807 |
(...skipping 1442 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4225 } | 4250 } |
4226 | 4251 |
4227 bool isLibraryPrefix(Expression node) => | 4252 bool isLibraryPrefix(Expression node) => |
4228 node is SimpleIdentifier && node.staticElement is PrefixElement; | 4253 node is SimpleIdentifier && node.staticElement is PrefixElement; |
4229 | 4254 |
4230 LibraryElement _getLibrary(AnalysisContext c, String uri) => | 4255 LibraryElement _getLibrary(AnalysisContext c, String uri) => |
4231 c.computeLibraryElement(c.sourceFactory.forUri(uri)); | 4256 c.computeLibraryElement(c.sourceFactory.forUri(uri)); |
4232 | 4257 |
4233 bool _isDartRuntime(LibraryElement l) => | 4258 bool _isDartRuntime(LibraryElement l) => |
4234 l.isInSdk && l.source.uri.toString() == 'dart:_runtime'; | 4259 l.isInSdk && l.source.uri.toString() == 'dart:_runtime'; |
OLD | NEW |