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

Unified Diff: lib/src/compiler/code_generator.dart

Issue 1993813003: implement top-level JS annotated getters (Closed) Base URL: git@github.com:dart-lang/dev_compiler.git@master
Patch Set: Created 4 years, 7 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | test/browser/language_tests.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/src/compiler/code_generator.dart
diff --git a/lib/src/compiler/code_generator.dart b/lib/src/compiler/code_generator.dart
index 05d603f8de8c428c91f543740d95d541006ad1c7..945945d0d38ecc2b8c2ed53b56d89b85ba4976b5 100644
--- a/lib/src/compiler/code_generator.dart
+++ b/lib/src/compiler/code_generator.dart
@@ -82,7 +82,8 @@ class CodeGenerator extends GeneralizingAstVisitor
JS.TemporaryId _asyncStarController;
/// The top-level reference to 'self' if this is a library tagged with @JS()
Jennifer Messerly 2016/05/18 22:20:26 reword this comment?
Harry Terkelsen 2016/05/19 16:56:18 Done.
- JS.TemporaryId _self;
+ JS.Expression _jsPrefix;
+ bool libraryTaggedJS = false;
Jennifer Messerly 2016/05/18 22:20:27 Perhaps call this "_isInteropLibrary" Note: I hav
Harry Terkelsen 2016/05/19 16:56:18 Done.
final _privateNames =
new HashMap<LibraryElement, HashMap<String, JS.TemporaryId>>();
@@ -90,6 +91,7 @@ class CodeGenerator extends GeneralizingAstVisitor
new HashMap<ParameterElement, JS.TemporaryId>();
final _dartxVar = new JS.Identifier('dartx');
+ final _dartGlobal = js.call('dart.global');
final _runtimeLibVar = new JS.Identifier('dart');
final namedArgumentTemp = new JS.TemporaryId('opts');
@@ -226,8 +228,12 @@ class CodeGenerator extends GeneralizingAstVisitor
}
if (findAnnotation(library, isPublicJSAnnotation) != null) {
- _self = new JS.TemporaryId('self');
- items.add(js.statement('const # = window;', [_self]));
+ libraryTaggedJS = true;
Jennifer Messerly 2016/05/18 22:20:27 is this attribute per-library or is it global for
Harry Terkelsen 2016/05/19 16:56:18 It's per-library. I made the map.
+ var prefix = getAnnotationName(library, isPublicJSAnnotation);
+ if (prefix != null && !prefix.isEmpty) {
Jennifer Messerly 2016/05/18 22:20:27 will we always have a name? in other words does it
Harry Terkelsen 2016/05/19 16:56:19 A @JS annotation on the library is required for js
+ _jsPrefix = js.call(prefix);
Jennifer Messerly 2016/05/18 22:20:27 I feel like we'd be better off validating our user
Harry Terkelsen 2016/05/19 16:56:18 I am just splitting on dots now without validation
+ assert(_isValidJSName(_jsPrefix));
Jennifer Messerly 2016/05/18 22:20:26 Should this be an error we issue? I think of "ass
Harry Terkelsen 2016/05/19 16:56:18 I think you cannot just put arbitrary strings in t
+ }
}
}
@@ -290,6 +296,49 @@ class CodeGenerator extends GeneralizingAstVisitor
}
}
+ /// Returns [true] if [jsName] is a simple identifier, a string with no dots,
+ /// or a property access where the receiver is a valid JS name and the
+ /// selector is a simple identifier.
+ bool _isValidJSName(JS.Expression jsName) {
Jennifer Messerly 2016/05/18 22:20:26 based on suggestion above, I'm not sure you'll nee
Harry Terkelsen 2016/05/19 16:56:19 Done.
+ if (jsName is JS.Identifier) {
+ return true;
+ } else if (jsName is JS.LiteralString) {
+ return !jsName.value.contains('.');
+ } else if (jsName is JS.PropertyAccess) {
+ return (jsName.selector is JS.Identifier ||
+ jsName.selector is JS.LiteralString) &&
+ _isValidJSName(jsName.receiver);
+ } else {
+ return false;
+ }
+ }
+
+ /// Returns the equivalent of separating the given names by a '.'.
+ JS.PropertyAccess _mergeJSNames(Iterable<JS.Expression> names) {
Jennifer Messerly 2016/05/18 22:20:27 same here, I don't think this will be needed
Harry Terkelsen 2016/05/19 16:56:18 Done.
+ assert(names.every(_isValidJSName));
Jennifer Messerly 2016/05/18 22:20:27 (this comment is probably moot based on my other o
Harry Terkelsen 2016/05/19 16:56:18 Done.
+ Iterable<JS.LiteralString> extractParts(JS.Expression name) sync* {
+ if (name == null) return;
+ if (name is JS.LiteralString) {
+ yield name;
+ return;
+ }
+ if (name is JS.Identifier) {
+ yield js.string(name.name);
+ return;
+ }
+ var propertyAccess = name as JS.PropertyAccess;
+ yield* extractParts(propertyAccess.receiver);
+ yield propertyAccess.selector;
+ }
+ return names.expand(extractParts).fold(null, (merged, part) {
+ if (merged == null) {
+ return new JS.Identifier(
+ part.value.substring(1, part.value.length - 1));
+ }
+ return new JS.PropertyAccess(merged, part);
+ });
+ }
+
String _libraryToModule(LibraryElement library) {
assert(!_libraries.containsKey(library));
var source = library.source;
@@ -2346,10 +2395,17 @@ class CodeGenerator extends GeneralizingAstVisitor
JS.PropertyAccess _emitTopLevelName(Element e, {String suffix: ''}) {
if (e is TopLevelVariableElement &&
e.getter != null &&
- findAnnotation(e.getter, isPublicJSAnnotation) != null) {
+ (findAnnotation(e.getter, isPublicJSAnnotation) != null ||
+ (libraryTaggedJS && e.getter.isExternal))) {
Jennifer Messerly 2016/05/18 22:20:26 `e.getter.isExternal && _libraryTaggedJS(e.library
Harry Terkelsen 2016/05/19 16:56:19 Done.
var annotationName = getAnnotationName(e.getter, isPublicJSAnnotation);
- var name = js.string(annotationName ?? e.name);
- return new JS.PropertyAccess(_self, name);
+ var name;
+ if (annotationName != null && annotationName.contains('.')) {
+ name = js.call(annotationName);
+ } else {
+ name = js.string(annotationName ?? e.name);
+ }
+ return _mergeJSNames(
Jennifer Messerly 2016/05/18 22:20:26 rather than merging js_ast structures, IMO it woul
Harry Terkelsen 2016/05/19 16:56:18 Done.
+ [_dartGlobal, _jsPrefix, name].where((x) => x != null));
Jennifer Messerly 2016/05/18 22:20:27 (probably a moot comment) _jsPrefix is the only o
Harry Terkelsen 2016/05/19 16:56:18 Done.
}
String name = getJSExportName(e) + suffix;
return new JS.PropertyAccess(
@@ -3044,8 +3100,14 @@ class CodeGenerator extends GeneralizingAstVisitor
var classElem = element.enclosingElement;
if (findAnnotation(classElem, isPublicJSAnnotation) != null) {
var annotationName = getAnnotationName(classElem, isPublicJSAnnotation);
- var typeName = js.string(annotationName ?? classElem.name);
- return new JS.PropertyAccess(_self, typeName);
+ var typeName;
Jennifer Messerly 2016/05/18 22:20:27 this code seems duplicated with above. (it sort o
Harry Terkelsen 2016/05/19 16:56:18 Done.
+ if (annotationName != null && annotationName.contains('.')) {
+ typeName = js.call(annotationName);
+ } else {
+ typeName = js.string(annotationName ?? classElem.name);
+ }
+ return _mergeJSNames(
+ [_dartGlobal, _jsPrefix, typeName].where((x) => x != null));
}
var typeName = _emitType(type);
if (name != null || element.isFactory) {
« no previous file with comments | « no previous file | test/browser/language_tests.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698