Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(724)

Unified Diff: initialize/lib/build/initializer_plugin.dart

Issue 1400473008: Roll Observatory packages and add a roll script (Closed) Base URL: git@github.com:dart-lang/observatory_pub_packages.git@master
Patch Set: Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « html/pubspec.yaml ('k') | initialize/lib/build/loader_replacer.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: initialize/lib/build/initializer_plugin.dart
diff --git a/initialize/lib/build/initializer_plugin.dart b/initialize/lib/build/initializer_plugin.dart
deleted file mode 100644
index 8822dc4f7e397b7daa741de704f023c25c19ea0a..0000000000000000000000000000000000000000
--- a/initialize/lib/build/initializer_plugin.dart
+++ /dev/null
@@ -1,294 +0,0 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-library initialize.build.initializer_plugin;
-
-import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
-import 'package:barback/barback.dart';
-import 'package:code_transformers/resolver.dart';
-import 'package:initialize/transformer.dart';
-import 'package:path/path.dart' as path;
-
-/// A plug which allows an initializer to write out an [InitEntry] given some
-/// [InitializerData] from an annotation that was found.
-abstract class InitializerPlugin {
- /// Whether or not this plugin should be applied to an [Initializer] given
- /// some [InitializerData]. If [true] is returned then this plugin will take
- /// ownership of this [InitializerData] and no subsequent plugins will have
- /// an opportunity to access it.
- bool shouldApply(InitializerPluginData data);
-
- /// Returns a [String] or [null]. The [String] should represent dart code
- /// which creates a new [InitEntry] and that entry is added to the static
- /// initializers list. If [null] is returned then no entry is added at all for
- /// this [InitializerData].
- String apply(InitializerPluginData data);
-}
-
-/// A class which wraps all the default data passed to an [InitializerPlugin]
-/// for each annotation.
-class InitializerPluginData {
- final InitializerData initializer;
- final AssetId bootstrapId;
- final Map<LibraryElement, String> libraryPrefixes;
- final TransformLogger logger;
- final Resolver resolver;
- InitializerPluginData(this.initializer, this.bootstrapId,
- this.libraryPrefixes, this.resolver, this.logger);
-}
-
-/// The basic [InitializerPlugin]. This generates a new [InitEntry] to be added
-/// to the static initializers list, and applies to every item it sees.
-class DefaultInitializerPlugin implements InitializerPlugin {
- const DefaultInitializerPlugin();
-
- /// Applies to everything. Put other plugins before this one to override this
- /// behaviour.
- bool shouldApply(InitializerPluginData data) => true;
-
- /// Creates a normal [InitEntry] string.
- String apply(InitializerPluginData pluginData) {
- var target = buildTarget(pluginData);
- var meta = buildMeta(pluginData);
- return 'new InitEntry($meta, $target)';
- }
-
- /// Builds a [String] representing the meta of an [InitEntry] given an
- /// [ElementAnnotation] that was found.
- String buildMeta(InitializerPluginData pluginData) {
- var logger = pluginData.logger;
- var element = pluginData.initializer.targetElement;
- var elementAnnotation = pluginData.initializer.annotationElement;
- var elementAnnotationElement = elementAnnotation.element;
- var libraryPrefixes = pluginData.libraryPrefixes;
- if (elementAnnotationElement is ConstructorElement) {
- return buildConstructorMeta(elementAnnotation, pluginData);
- } else if (elementAnnotationElement is PropertyAccessorElement) {
- return buildPropertyMeta(elementAnnotation, pluginData);
- } else {
- logger.error('Unsupported annotation type. Only constructors and '
- 'properties are supported as initializers.');
- }
- return null;
- }
-
- /// Builds a [String] representing the meta of an [InitEntry] given an
- /// [ElementAnnotation] whose element was a [ConstructorElement].
- String buildConstructorMeta(
- ElementAnnotation elementAnnotation, InitializerPluginData pluginData) {
- var logger = pluginData.logger;
- var node = pluginData.initializer.targetNode;
- var metaPrefix =
- pluginData.libraryPrefixes[elementAnnotation.element.library];
-
- var annotation = pluginData.initializer.annotationNode;
- if (annotation == null) {
- logger.error(
- 'Initializer annotations are only supported on libraries, classes, '
- 'and top level methods. Found $node.');
- }
- var clazz = annotation.name;
- var constructor = annotation.constructorName == null
- ? ''
- : '.${annotation.constructorName}';
- var args = buildArgumentList(annotation.arguments, pluginData);
- return 'const $metaPrefix.${clazz}$constructor$args';
- }
-
- /// Builds a [String] representing the meta of an [InitEntry] given an
- /// [ElementAnnotation] whose element was a [PropertyAccessorElement].
- String buildPropertyMeta(
- ElementAnnotation annotation, InitializerPluginData pluginData) {
- var metaPrefix = pluginData.libraryPrefixes[annotation.element.library];
- return '$metaPrefix.${annotation.element.name}';
- }
-
- /// Builds a [String] for the target of an [InitEntry] given an [Element] that
- /// was annotated.
- String buildTarget(InitializerPluginData pluginData) {
- var element = pluginData.initializer.targetElement;
- var logger = pluginData.logger;
- if (element is LibraryElement) {
- return buildLibraryTarget(element, pluginData);
- } else if (element is ClassElement) {
- return buildClassTarget(element, pluginData);
- } else if (element is FunctionElement) {
- return buildFunctionTarget(element, pluginData);
- } else {
- logger.error('Initializers can only be applied to top level functions, '
- 'libraries, and classes.');
- }
- return null;
- }
-
- /// Builds a [String] for the target of an [InitEntry] given [element] which
- /// is an annotated class.
- String buildClassTarget(
- ClassElement element, InitializerPluginData pluginData) =>
- buildSimpleTarget(element, pluginData);
-
- /// Builds a [String] for the target of an [InitEntry] given [element] which
- /// is an annotated function.
- String buildFunctionTarget(
- FunctionElement element, InitializerPluginData pluginData) =>
- buildSimpleTarget(element, pluginData);
-
- /// Builds a [String] for the target of an [InitEntry] for a simple [Element].
- /// This is just the library prefix followed by the element name.
- String buildSimpleTarget(Element element, InitializerPluginData pluginData) =>
- '${pluginData.libraryPrefixes[element.library]}.${element.name}';
-
- /// Builds a [String] for the target of an [InitEntry] given [element] which
- /// is an annotated library.
- String buildLibraryTarget(
- LibraryElement element, InitializerPluginData pluginData) {
- var bootstrapId = pluginData.bootstrapId;
- var logger = pluginData.logger;
- var segments = element.source.uri.pathSegments;
- var package = segments[0];
- var libraryPath;
- var packageString;
- if (bootstrapId.package == package &&
- bootstrapId.path.startsWith('${segments[1]}/')) {
- // reset `package` to null, we will do a relative path in this case.
- packageString = 'null';
- libraryPath = path.url.relative(
- path.url.joinAll(segments.getRange(1, segments.length)),
- from: path.url.dirname(path.url.join(bootstrapId.path)));
- } else if (segments[1] == 'lib') {
- packageString = "'$package'";
- libraryPath = path.url.joinAll(segments.getRange(2, segments.length));
- } else {
- logger.error('Unable to import `${element.source.uri.path}` from '
- '${bootstrapId.path}.');
- }
-
- return "const LibraryIdentifier"
- "(#${element.name}, $packageString, '$libraryPath')";
- }
-
- /// Builds a [String] representing an [ArgumentList] taking into account the
- /// [libraryPrefixes] from [pluginData].
- String buildArgumentList(
- ArgumentList args, InitializerPluginData pluginData) {
- var buffer = new StringBuffer();
- buffer.write('(');
- var first = true;
- for (var arg in args.arguments) {
- if (!first) buffer.write(', ');
- first = false;
-
- Expression expression;
- if (arg is NamedExpression) {
- buffer.write('${arg.name.label.name}: ');
- expression = arg.expression;
- } else {
- expression = arg;
- }
-
- buffer.write(buildExpression(expression, pluginData));
- }
- buffer.write(')');
- return buffer.toString();
- }
-
- /// Builds a [String] representing [expression] taking into account the
- /// [libraryPrefixes] from [pluginData].
- String buildExpression(
- Expression expression, InitializerPluginData pluginData) {
- var logger = pluginData.logger;
- var libraryPrefixes = pluginData.libraryPrefixes;
- var buffer = new StringBuffer();
- if (expression is StringLiteral && expression.stringValue != null) {
- buffer.write(_stringValue(expression.stringValue));
- } else if (expression is BooleanLiteral ||
- expression is DoubleLiteral ||
- expression is IntegerLiteral ||
- expression is NullLiteral) {
- buffer.write('${expression}');
- } else if (expression is ListLiteral) {
- buffer.write('const [');
- var first = true;
- for (Expression listExpression in expression.elements) {
- if (!first) buffer.write(', ');
- first = false;
- buffer.write(buildExpression(listExpression, pluginData));
- }
- buffer.write(']');
- } else if (expression is MapLiteral) {
- buffer.write('const {');
- var first = true;
- for (MapLiteralEntry entry in expression.entries) {
- if (!first) buffer.write(', ');
- first = false;
- buffer.write(buildExpression(entry.key, pluginData));
- buffer.write(': ');
- buffer.write(buildExpression(entry.value, pluginData));
- }
- buffer.write('}');
- } else if (expression is Identifier) {
- var element = expression.bestElement;
- 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('${variable.name}');
- } else {
- logger.error('Unsupported argument to initializer constructor.');
- }
- }
- } else if (expression is PropertyAccess) {
- buffer.write(buildExpression(expression.target, pluginData));
- buffer.write('.${expression.propertyName}');
- } else if (expression is InstanceCreationExpression) {
- logger.error('Unsupported expression in initializer, found $expression. '
- 'Instance creation expressions are not supported (yet). Instead, '
- 'please assign it to a const variable and use that instead.');
- } else {
- 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) {
- value = value.replaceAll(r'\', r'\\').replaceAll(r"'", r"\'");
- return "'$value'";
- }
-}
« no previous file with comments | « html/pubspec.yaml ('k') | initialize/lib/build/loader_replacer.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698