add support for evaluating private identifiers and inlining the result into the bootstrap
diff --git a/CHANGELOG.md b/CHANGELOG.md index b9baa6b..0abd507 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md
@@ -1,3 +1,8 @@ +## 0.6.0+2 + +* Private identifiers will now be evaluated and inlined into the bootstrap file +by the transformer, [29](https://github.com/dart-lang/initialize/issues/29). + ## 0.6.0+1 * Fix for `LibraryIdentifier` paths when initializer starts from inline scripts
diff --git a/lib/build/initializer_plugin.dart b/lib/build/initializer_plugin.dart index 466065f..8822dc4 100644 --- a/lib/build/initializer_plugin.dart +++ b/lib/build/initializer_plugin.dart
@@ -229,24 +229,27 @@ buffer.write('}'); } else if (expression is Identifier) { var element = expression.bestElement; - if (element == null || !element.isPublic) { - logger.error('Private constants are not supported in intializer ' - 'constructors, found $element.'); - } - libraryPrefixes.putIfAbsent( + if (element == null) { + logger.error('Unable to get `bestElement` for expression: $expression'); + } else if (!element.isPublic) { + // Inline the evaluated value of private identifiers. + buffer.write(_evaluateExpression(expression, pluginData)); + } else { + libraryPrefixes.putIfAbsent( element.library, () => 'i${libraryPrefixes.length}'); - buffer.write('${libraryPrefixes[element.library]}.'); - if (element is ClassElement) { - buffer.write(element.name); - } else if (element is PropertyAccessorElement) { - var variable = element.variable; - if (variable is FieldElement) { - buffer.write('${variable.enclosingElement.name}.'); + buffer.write('${libraryPrefixes[element.library]}.'); + if (element is ClassElement) { + buffer.write(element.name); + } else if (element is PropertyAccessorElement) { + var variable = element.variable; + if (variable is FieldElement) { + buffer.write('${variable.enclosingElement.name}.'); + } + buffer.write('${variable.name}'); + } else { + logger.error('Unsupported argument to initializer constructor.'); } - buffer.write('${variable.name}'); - } else { - logger.error('Unsupported argument to initializer constructor.'); } } else if (expression is PropertyAccess) { buffer.write(buildExpression(expression.target, pluginData)); @@ -256,26 +259,32 @@ 'Instance creation expressions are not supported (yet). Instead, ' 'please assign it to a const variable and use that instead.'); } else { - // Try to evaluate the constant and use that. - var result = pluginData.resolver.evaluateConstant( - pluginData.initializer.targetElement.library, expression); - if (!result.isValid) { - logger.error('Invalid expression in initializer, found $expression. ' - 'And got the following errors: ${result.errors}.'); - } - var value = result.value.value; - if (value == null) { - logger.error('Unsupported expression in initializer, found ' - '$expression. Please file a bug at ' - 'https://github.com/dart-lang/initialize/issues'); - } - - if (value is String) value = _stringValue(value); - buffer.write(value); + buffer.write(_evaluateExpression(expression, pluginData)); } return buffer.toString(); } + _evaluateExpression(Expression expression, InitializerPluginData pluginData) { + var logger = pluginData.logger; + var result = pluginData.resolver.evaluateConstant( + pluginData.initializer.targetElement.library, expression); + if (!result.isValid) { + logger.error('Invalid expression in initializer, found $expression. ' + 'And got the following errors: ${result.errors}.'); + return null; + } + var value = result.value.value; + if (value == null) { + logger.error('Unsupported expression in initializer, found ' + '$expression. Please file a bug at ' + 'https://github.com/dart-lang/initialize/issues'); + return null; + } + + if (value is String) value = _stringValue(value); + return value; + } + // Returns an expression for a string value. Wraps it in single quotes and // escapes existing single quotes and escapes. _stringValue(String value) {
diff --git a/pubspec.yaml b/pubspec.yaml index 21298d9..2d0b048 100644 --- a/pubspec.yaml +++ b/pubspec.yaml
@@ -1,5 +1,5 @@ name: initialize -version: 0.6.0+1 +version: 0.6.0+2 author: Polymer.dart Authors <web@dartlang.org> description: Generic building blocks for doing static initialization. homepage: https://github.com/dart-lang/initialize
diff --git a/test/transformer_test.dart b/test/transformer_test.dart index 8b43d45..d9c6130 100644 --- a/test/transformer_test.dart +++ b/test/transformer_test.dart
@@ -116,6 +116,7 @@ testPhases('constructor arguments', phases, { 'a|web/index.dart': ''' @DynamicInit(foo) + @DynamicInit(_foo) @DynamicInit(Foo.foo) @DynamicInit(bar.Foo.bar) @DynamicInit(bar.Foo.foo) @@ -139,6 +140,7 @@ const x = 'x'; const y = 'y'; + const _foo = '_foo'; class MyConst { const MyConst; @@ -172,6 +174,7 @@ main() { initializers.addAll([ new InitEntry(const i1.DynamicInit(i2.foo), const LibraryIdentifier(#web_foo, null, 'index.dart')), + new InitEntry(const i1.DynamicInit('_foo'), const LibraryIdentifier(#web_foo, null, 'index.dart')), new InitEntry(const i1.DynamicInit(i2.Foo.foo), const LibraryIdentifier(#web_foo, null, 'index.dart')), new InitEntry(const i1.DynamicInit(i2.Foo.bar), const LibraryIdentifier(#web_foo, null, 'index.dart')), new InitEntry(const i1.DynamicInit(i2.Foo.foo), const LibraryIdentifier(#web_foo, null, 'index.dart')),