OLD | NEW |
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 library initialize.build.initializer_plugin; | 4 library initialize.build.initializer_plugin; |
5 | 5 |
6 import 'package:analyzer/src/generated/ast.dart'; | 6 import 'package:analyzer/dart/ast/ast.dart'; |
7 import 'package:analyzer/src/generated/element.dart'; | 7 import 'package:analyzer/dart/element/element.dart'; |
| 8 import 'package:analyzer/src/generated/constant.dart'; |
8 import 'package:barback/barback.dart'; | 9 import 'package:barback/barback.dart'; |
9 import 'package:code_transformers/resolver.dart'; | 10 import 'package:code_transformers/resolver.dart'; |
10 import 'package:initialize/transformer.dart'; | 11 import 'package:initialize/transformer.dart'; |
11 import 'package:path/path.dart' as path; | 12 import 'package:path/path.dart' as path; |
12 | 13 |
13 /// A plug which allows an initializer to write out an [InitEntry] given some | 14 /// A plug which allows an initializer to write out an [InitEntry] given some |
14 /// [InitializerData] from an annotation that was found. | 15 /// [InitializerData] from an annotation that was found. |
15 abstract class InitializerPlugin { | 16 abstract class InitializerPlugin { |
16 /// Whether or not this plugin should be applied to an [Initializer] given | 17 /// Whether or not this plugin should be applied to an [Initializer] given |
17 /// some [InitializerData]. If [true] is returned then this plugin will take | 18 /// some [InitializerData]. If [true] is returned then this plugin will take |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
51 String apply(InitializerPluginData pluginData) { | 52 String apply(InitializerPluginData pluginData) { |
52 var target = buildTarget(pluginData); | 53 var target = buildTarget(pluginData); |
53 var meta = buildMeta(pluginData); | 54 var meta = buildMeta(pluginData); |
54 return 'new InitEntry($meta, $target)'; | 55 return 'new InitEntry($meta, $target)'; |
55 } | 56 } |
56 | 57 |
57 /// Builds a [String] representing the meta of an [InitEntry] given an | 58 /// Builds a [String] representing the meta of an [InitEntry] given an |
58 /// [ElementAnnotation] that was found. | 59 /// [ElementAnnotation] that was found. |
59 String buildMeta(InitializerPluginData pluginData) { | 60 String buildMeta(InitializerPluginData pluginData) { |
60 var logger = pluginData.logger; | 61 var logger = pluginData.logger; |
61 var element = pluginData.initializer.targetElement; | |
62 var elementAnnotation = pluginData.initializer.annotationElement; | 62 var elementAnnotation = pluginData.initializer.annotationElement; |
63 var elementAnnotationElement = elementAnnotation.element; | 63 var elementAnnotationElement = elementAnnotation.element; |
64 var libraryPrefixes = pluginData.libraryPrefixes; | |
65 if (elementAnnotationElement is ConstructorElement) { | 64 if (elementAnnotationElement is ConstructorElement) { |
66 return buildConstructorMeta(elementAnnotation, pluginData); | 65 return buildConstructorMeta(elementAnnotation, pluginData); |
67 } else if (elementAnnotationElement is PropertyAccessorElement) { | 66 } else if (elementAnnotationElement is PropertyAccessorElement) { |
68 return buildPropertyMeta(elementAnnotation, pluginData); | 67 return buildPropertyMeta(elementAnnotation, pluginData); |
69 } else { | 68 } else { |
70 logger.error('Unsupported annotation type. Only constructors and ' | 69 logger.error('Unsupported annotation type. Only constructors and ' |
71 'properties are supported as initializers.'); | 70 'properties are supported as initializers.'); |
72 } | 71 } |
73 return null; | 72 return null; |
74 } | 73 } |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
257 } else if (expression is InstanceCreationExpression) { | 256 } else if (expression is InstanceCreationExpression) { |
258 logger.error('Unsupported expression in initializer, found $expression. ' | 257 logger.error('Unsupported expression in initializer, found $expression. ' |
259 'Instance creation expressions are not supported (yet). Instead, ' | 258 'Instance creation expressions are not supported (yet). Instead, ' |
260 'please assign it to a const variable and use that instead.'); | 259 'please assign it to a const variable and use that instead.'); |
261 } else { | 260 } else { |
262 buffer.write(_evaluateExpression(expression, pluginData)); | 261 buffer.write(_evaluateExpression(expression, pluginData)); |
263 } | 262 } |
264 return buffer.toString(); | 263 return buffer.toString(); |
265 } | 264 } |
266 | 265 |
267 _evaluateExpression(Expression expression, InitializerPluginData pluginData) { | 266 _evaluateExpression( |
| 267 Expression expression, InitializerPluginData pluginData) { |
268 var logger = pluginData.logger; | 268 var logger = pluginData.logger; |
269 var result = pluginData.resolver.evaluateConstant( | 269 var result = pluginData.resolver.evaluateConstant( |
270 pluginData.initializer.targetElement.library, expression); | 270 pluginData.initializer.targetElement.library, expression); |
271 if (!result.isValid) { | 271 if (!result.isValid) { |
272 logger.error('Invalid expression in initializer, found $expression. ' | 272 logger.error('Invalid expression in initializer, found $expression. ' |
273 'And got the following errors: ${result.errors}.'); | 273 'And got the following errors: ${result.errors}.'); |
274 return null; | 274 return null; |
275 } | 275 } |
276 var value = result.value.value; | 276 |
| 277 var value = _getValue(result.value); |
| 278 |
277 if (value == null) { | 279 if (value == null) { |
278 logger.error('Unsupported expression in initializer, found ' | 280 logger.error('Unsupported expression in initializer, found ' |
279 '$expression. Please file a bug at ' | 281 '$expression. Please file a bug at ' |
280 'https://github.com/dart-lang/initialize/issues'); | 282 'https://github.com/dart-lang/initialize/issues'); |
281 return null; | |
282 } | 283 } |
283 | 284 |
284 if (value is String) value = _stringValue(value); | 285 if (value is String) value = _stringValue(value); |
| 286 |
285 return value; | 287 return value; |
286 } | 288 } |
287 | 289 |
288 // Returns an expression for a string value. Wraps it in single quotes and | 290 // Returns an expression for a string value. Wraps it in single quotes and |
289 // escapes existing single quotes and escapes. | 291 // escapes existing single quotes and escapes. |
290 _stringValue(String value) { | 292 _stringValue(String value) { |
291 value = value.replaceAll(r'\', r'\\').replaceAll(r"'", r"\'"); | 293 value = value.replaceAll(r'\', r'\\').replaceAll(r"'", r"\'"); |
292 return "'$value'"; | 294 return "'$value'"; |
293 } | 295 } |
| 296 |
| 297 // Gets an actual value for a [DartObject]. |
| 298 _getValue(DartObject object) { |
| 299 if (object == null) return null; |
| 300 var value = object.toBoolValue() ?? |
| 301 object.toDoubleValue() ?? |
| 302 object.toIntValue() ?? |
| 303 object.toStringValue(); |
| 304 if (value == null) { |
| 305 value = object.toListValue(); |
| 306 if (value != null) { |
| 307 return value.map((DartObject element) => _getValue(element)).toList(); |
| 308 } |
| 309 Map<DartObject, DartObject> map = object.toMapValue(); |
| 310 if (map != null) { |
| 311 Map result = {}; |
| 312 map.forEach((DartObject key, DartObject value) { |
| 313 dynamic mappedKey = _getValue(key); |
| 314 if (mappedKey != null) { |
| 315 result[mappedKey] = _getValue(value); |
| 316 } |
| 317 }); |
| 318 return result; |
| 319 } |
| 320 } |
| 321 return value; |
| 322 } |
294 } | 323 } |
OLD | NEW |