| Index: lib/src/codegen/js_codegen.dart
|
| diff --git a/lib/src/codegen/js_codegen.dart b/lib/src/codegen/js_codegen.dart
|
| index 91b8c018766099a7ae1822a9b7501dbd96a481d4..2ed9de705707980906ba30db63f3219a0a0c6b3c 100644
|
| --- a/lib/src/codegen/js_codegen.dart
|
| +++ b/lib/src/codegen/js_codegen.dart
|
| @@ -1321,23 +1321,23 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator {
|
| }
|
|
|
| bool _isInlineJSFunction(FunctionExpression functionExpression) {
|
| - bool isJsInvocation(Expression expr) =>
|
| - expr is MethodInvocation && isInlineJS(expr.methodName.staticElement);
|
| -
|
| var body = functionExpression.body;
|
| if (body is ExpressionFunctionBody) {
|
| - return isJsInvocation(body.expression);
|
| + return _isJSInvocation(body.expression);
|
| } else if (body is BlockFunctionBody) {
|
| if (body.block.statements.length == 1) {
|
| var stat = body.block.statements.single;
|
| if (stat is ReturnStatement) {
|
| - return isJsInvocation(stat.expression);
|
| + return _isJSInvocation(stat.expression);
|
| }
|
| }
|
| }
|
| return false;
|
| }
|
|
|
| + bool _isJSInvocation(Expression expr) =>
|
| + expr is MethodInvocation && isInlineJS(expr.methodName.staticElement);
|
| +
|
| // Simplify `(args) => ((x, y) => { ... })(x, y)` to `(args) => { ... }`.
|
| // Note: we don't check if the top-level args match the ones passed through
|
| // the arrow function, which allows silently passing args through to the
|
| @@ -1744,7 +1744,9 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator {
|
| // Always qualify:
|
| // * mutable top-level fields
|
| // * elements from other libraries
|
| - bool mutableTopLevel = e is TopLevelVariableElement && !e.isConst;
|
| + bool mutableTopLevel = e is TopLevelVariableElement &&
|
| + !e.isConst &&
|
| + !_isFinalJSDecl(e.computeNode());
|
| bool fromAnotherLibrary = e.library != currentLibrary;
|
| if (mutableTopLevel || fromAnotherLibrary) {
|
| return new JS.PropertyAccess(libName, nameExpr);
|
| @@ -2090,6 +2092,10 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator {
|
| return new JS.VariableInitialization(name, _visitInitializer(node));
|
| }
|
|
|
| + bool _isFinalJSDecl(AstNode field) => field is VariableDeclaration &&
|
| + field.isFinal &&
|
| + _isJSInvocation(field.initializer);
|
| +
|
| /// Emits a static or top-level field.
|
| JS.Statement _emitStaticField(VariableDeclaration field) {
|
| PropertyInducingElement element = field.element;
|
| @@ -2108,8 +2114,14 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator {
|
| eagerInit = false;
|
| }
|
|
|
| + // Treat `final x = JS('', '...')` as a const (non-lazy) to help compile
|
| + // runtime helpers.
|
| + var isJSTopLevel = field.isFinal && _isFinalJSDecl(field);
|
| + if (isJSTopLevel) eagerInit = true;
|
| +
|
| var fieldName = field.name.name;
|
| - if (field.isConst && eagerInit && element is TopLevelVariableElement) {
|
| + if ((field.isConst && eagerInit && element is TopLevelVariableElement) ||
|
| + isJSTopLevel) {
|
| // constant fields don't change, so we can generate them as `let`
|
| // but add them to the module's exports. However, make sure we generate
|
| // anything they depend on first.
|
|
|