 Chromium Code Reviews
 Chromium Code Reviews Issue 1580413002:
  Add a `@JSExportName` annotation for internal use in the runtime (use it to export dart.assert inst…  (Closed) 
  Base URL: git@github.com:dart-lang/dev_compiler.git@master
    
  
    Issue 1580413002:
  Add a `@JSExportName` annotation for internal use in the runtime (use it to export dart.assert inst…  (Closed) 
  Base URL: git@github.com:dart-lang/dev_compiler.git@master| 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` |