Chromium Code Reviews| Index: lib/src/compiler/code_generator.dart |
| diff --git a/lib/src/compiler/code_generator.dart b/lib/src/compiler/code_generator.dart |
| index 8a97a278c6114a34e3a048de9a9dd36cedc82799..e6453263e95f46b0676c1633cf63880efac3b18f 100644 |
| --- a/lib/src/compiler/code_generator.dart |
| +++ b/lib/src/compiler/code_generator.dart |
| @@ -81,8 +81,12 @@ class CodeGenerator extends GeneralizingAstVisitor |
| /// In an async* function, this represents the stream controller parameter. |
| JS.TemporaryId _asyncStarController; |
| - /// The top-level reference to 'self' if this is a library tagged with @JS() |
| - JS.TemporaryId _self; |
| + /// A mapping of libraries to the contents of their corresponding |
| + /// library-level @JS() annotation, if the library is annotated. The |
| + /// @JS annotation contains a dot-separated identifier or is empty. The |
| + /// library is then associated with a list of Strings, which represents |
| + /// the list of dotted identifiers. |
| + final _libraryJsPrefixes = new HashMap<LibraryElement, List<String>>(); |
|
Jennifer Messerly
2016/05/19 17:38:04
BTW, we're not consistent yet, but naming conventi
Harry Terkelsen
2016/05/19 18:10:10
Done.
|
| final _privateNames = |
| new HashMap<LibraryElement, HashMap<String, JS.TemporaryId>>(); |
| @@ -226,8 +230,12 @@ class CodeGenerator extends GeneralizingAstVisitor |
| } |
| if (findAnnotation(library, isPublicJSAnnotation) != null) { |
| - _self = new JS.TemporaryId('self'); |
| - items.add(js.statement('const # = window;', [_self])); |
| + var libraryJsPrefix = <String>[]; |
| + var prefix = getAnnotationName(library, isPublicJSAnnotation); |
| + if (prefix != null && !prefix.isEmpty) { |
| + libraryJsPrefix.addAll(prefix.split('.')); |
| + } |
| + _libraryJsPrefixes[library] = libraryJsPrefix; |
|
Jennifer Messerly
2016/05/19 17:38:04
I think you'll need to compute these on-demand, be
Harry Terkelsen
2016/05/19 18:10:10
Done.
|
| } |
| } |
| @@ -276,6 +284,39 @@ class CodeGenerator extends GeneralizingAstVisitor |
| } |
| } |
| + String _getJsName(Element e) { |
|
Jennifer Messerly
2016/05/19 17:38:04
_getJSName
Harry Terkelsen
2016/05/19 18:10:10
Done.
|
| + if (!_libraryJsPrefixes.containsKey(e.library)) return null; |
|
Jennifer Messerly
2016/05/19 17:38:04
I think this is where you can implement the cache,
Harry Terkelsen
2016/05/19 18:10:10
Done.
|
| + if (findAnnotation(e, isPublicJSAnnotation) != null) { |
| + return getAnnotationName(e, isPublicJSAnnotation) ?? ''; |
| + } |
| + if (e is TopLevelVariableElement && |
| + e.getter != null && |
| + (e.getter.isExternal || |
| + findAnnotation(e.getter, isPublicJSAnnotation) != null)) { |
| + return getAnnotationName(e.getter, isPublicJSAnnotation) ?? ''; |
| + } |
| + return null; |
| + } |
| + |
| + JS.Expression _emitJsInterop(Element e) { |
|
Jennifer Messerly
2016/05/19 17:38:05
_emitJSInterop
Harry Terkelsen
2016/05/19 18:10:10
Done.
|
| + var jsName = _getJsName(e); |
| + if (jsName == null) return null; |
| + var name; |
| + if (jsName.isEmpty) { |
| + name = [e.name]; |
| + } else { |
| + name = jsName.split('.'); |
| + } |
| + var fullName = ['global'] |
| + ..addAll(_libraryJsPrefixes[e.library]) |
| + ..addAll(name); |
| + var access = _runtimeLibVar; |
| + for (var part in fullName) { |
| + access = new JS.PropertyAccess(access, js.string(part)); |
| + } |
| + return access; |
| + } |
| + |
| /// Flattens blocks in [items] to a single list. |
| /// |
| /// This will not flatten blocks that are marked as being scopes. |
| @@ -2341,13 +2382,8 @@ class CodeGenerator extends GeneralizingAstVisitor |
| } |
| JS.PropertyAccess _emitTopLevelName(Element e, {String suffix: ''}) { |
| - if (e is TopLevelVariableElement && |
| - e.getter != null && |
| - findAnnotation(e.getter, isPublicJSAnnotation) != null) { |
| - var annotationName = getAnnotationName(e.getter, isPublicJSAnnotation); |
| - var name = js.string(annotationName ?? e.name); |
| - return new JS.PropertyAccess(_self, name); |
| - } |
| + var interop = _emitJsInterop(e); |
| + if (interop != null) return interop; |
| String name = getJSExportName(e) + suffix; |
| return new JS.PropertyAccess( |
| emitLibraryName(e.library), _propertyName(name)); |
| @@ -3039,11 +3075,8 @@ class CodeGenerator extends GeneralizingAstVisitor |
| JS.Expression _emitConstructorName( |
| ConstructorElement element, DartType type, SimpleIdentifier name) { |
| var classElem = element.enclosingElement; |
| - if (findAnnotation(classElem, isPublicJSAnnotation) != null) { |
| - var annotationName = getAnnotationName(classElem, isPublicJSAnnotation); |
|
Jennifer Messerly
2016/05/19 17:38:04
fyi Siggi made a change to this in: https://codere
|
| - var typeName = js.string(annotationName ?? classElem.name); |
| - return new JS.PropertyAccess(_self, typeName); |
| - } |
| + var interop = _emitJsInterop(classElem); |
| + if (interop != null) return interop; |
| var typeName = _emitType(type); |
| if (name != null || element.isFactory) { |
| var namedCtor = _constructorName(element); |