| Index: lib/src/compiler/code_generator.dart
|
| diff --git a/lib/src/compiler/code_generator.dart b/lib/src/compiler/code_generator.dart
|
| index d07bfb06619611d3aa7cb7238e7f19185343f0e9..b5c3047bcc2b7a4b68488e9c39978947db62fb3d 100644
|
| --- a/lib/src/compiler/code_generator.dart
|
| +++ b/lib/src/compiler/code_generator.dart
|
| @@ -41,7 +41,11 @@ import 'js_metalet.dart' as JS;
|
| import 'js_names.dart' as JS;
|
| import 'js_typeref_codegen.dart' show JsTypeRefCodegen;
|
| import 'module_builder.dart'
|
| - show LegacyModuleBuilder, NodeModuleBuilder, pathToJSIdentifier;
|
| + show
|
| + LegacyModuleBuilder,
|
| + NodeModuleBuilder,
|
| + pathToJSIdentifier,
|
| + toJSIdentifier;
|
| import 'nullable_type_inference.dart' show NullableTypeInference;
|
| import 'reify_coercions.dart' show CoercionReifier;
|
| import 'side_effect_analysis.dart' show ConstFieldVisitor, isStateless;
|
| @@ -124,6 +128,8 @@ class CodeGenerator extends GeneralizingAstVisitor
|
| List<JS.TemporaryId> _superHelperSymbols = <JS.TemporaryId>[];
|
| List<JS.Method> _superHelpers = <JS.Method>[];
|
|
|
| + List<TypeParameterType> _typeParamInConst = null;
|
| +
|
| /// Whether we are currently generating code for the body of a `JS()` call.
|
| bool _isInForeignJS = false;
|
|
|
| @@ -2299,6 +2305,7 @@ class CodeGenerator extends GeneralizingAstVisitor
|
| }
|
|
|
| if (type is TypeParameterType) {
|
| + _typeParamInConst?.add(type);
|
| return new JS.Identifier(name);
|
| }
|
|
|
| @@ -3385,9 +3392,22 @@ class CodeGenerator extends GeneralizingAstVisitor
|
| }
|
|
|
| JS.Expression _emitConst(JS.Expression expr()) {
|
| - // TODO(jmesserly): emit the constants at top level if possible.
|
| - // This wasn't quite working, so disabled for now.
|
| - return js.call('dart.const(#)', expr());
|
| + var savedTypeParams = _typeParamInConst;
|
| + _typeParamInConst = [];
|
| +
|
| + var jsExpr = js.call('dart.const(#)', expr());
|
| +
|
| + bool usesTypeParams = _typeParamInConst.isNotEmpty;
|
| + _typeParamInConst = savedTypeParams;
|
| +
|
| + // TODO(jmesserly): if it uses type params we can still hoist it up as far
|
| + // as it will go, e.g. at the level the generic class is defined where type
|
| + // params are available.
|
| + if (_currentFunction == null || usesTypeParams) return jsExpr;
|
| +
|
| + var temp = new JS.TemporaryId('const');
|
| + _moduleItems.add(js.statement('let #;', [temp]));
|
| + return js.call('# || (# = #)', [temp, temp, jsExpr]);
|
| }
|
|
|
| /// Returns a new expression, which can be be used safely *once* on the
|
|
|