Index: lib/src/codegen/js_codegen.dart |
diff --git a/lib/src/codegen/js_codegen.dart b/lib/src/codegen/js_codegen.dart |
index dc64c5bb8d44c6ac9f0f03f52a83d044e09f708f..5bd9843688b40ebb3cc54afa30ed5e4f042a27a9 100644 |
--- a/lib/src/codegen/js_codegen.dart |
+++ b/lib/src/codegen/js_codegen.dart |
@@ -1294,6 +1294,17 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { |
node.element); |
} |
+ /// Returns the name value of the `JSExportName` annotation (when compiling |
+ /// the SDK), or `null` if there's none. This is used to control the name |
+ /// under which functions are compiled and exported. |
+ String _getJSExportName(Element e) { |
+ if (e is! FunctionElement || !currentLibrary.source.isInSystemLibrary) { |
+ return null; |
+ } |
+ var jsName = findAnnotation(e, isJSExportNameAnnotation); |
+ return getConstantField(jsName, 'name', types.stringType)?.toStringValue(); |
+ } |
+ |
@override |
JS.Statement visitFunctionDeclaration(FunctionDeclaration node) { |
assert(node.parent is CompilationUnit); |
@@ -1309,7 +1320,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { |
var body = <JS.Statement>[]; |
_flushLibraryProperties(body); |
- var name = node.name.name; |
+ var name = _getJSExportName(node.element) ?? node.name.name; |
var fn = _visit(node.functionExpression); |
bool needsTagging = true; |
@@ -1575,8 +1586,6 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { |
_loader.declareBeforeUse(element); |
- var name = element.name; |
- |
// type literal |
if (element is ClassElement || |
element is DynamicElementImpl || |
@@ -1587,9 +1596,11 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { |
// library member |
if (element.enclosingElement is CompilationUnitElement) { |
- return _maybeQualifiedName(element); |
+ return _emitTopLevelName(element); |
Jennifer Messerly
2016/01/13 17:43:59
nice! it's funny how a name change makes such a di
ochafik
2016/01/13 18:51:29
Yeah, *sounds* so much more deterministic now ;-)
|
} |
+ var name = element.name; |
+ |
// Unqualified class member. This could mean implicit-this, or implicit |
// call to a static from the same class. |
if (element is ClassMemberElement && element is! ConstructorElement) { |
@@ -1757,17 +1768,17 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { |
jsArgs = []; |
} |
if (jsArgs != null) { |
- var genericName = _maybeQualifiedName(element, '$name\$'); |
+ var genericName = _emitTopLevelName(element, '$name\$'); |
return js.call('#(#)', [genericName, jsArgs]); |
} |
} |
- return _maybeQualifiedName(element); |
+ return _emitTopLevelName(element); |
} |
- JS.Expression _maybeQualifiedName(Element e, [String name]) { |
+ JS.Expression _emitTopLevelName(Element e, [String name]) { |
var libName = _libraryName(e.library); |
- var nameExpr = _propertyName(name ?? e.name); |
+ var nameExpr = _propertyName(name ?? _getJSExportName(e) ?? e.name); |
Jennifer Messerly
2016/01/13 17:44:00
oh wow, the [name] optional parameter--which was p
ochafik
2016/01/13 18:51:29
Cool! Done.
|
// Always qualify: |
// * mutable top-level fields |
@@ -2230,7 +2241,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { |
var isJSTopLevel = field.isFinal && _isFinalJSDecl(field); |
if (isJSTopLevel) eagerInit = true; |
- var fieldName = field.name.name; |
+ var fieldName = _getJSExportName(element) ?? field.name.name; |
Jennifer Messerly
2016/01/13 17:43:59
So for top-level fields, I think this works.
I wo
ochafik
2016/01/13 18:51:29
Aaaah, absolutely, thanks!
|
if ((field.isConst && eagerInit && element is TopLevelVariableElement) || |
isJSTopLevel) { |
// constant fields don't change, so we can generate them as `let` |