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/src/generated/ast.dart'; |
7 import 'package:analyzer/src/generated/element.dart'; | 7 import 'package:analyzer/src/generated/element.dart'; |
8 import 'package:barback/barback.dart'; | 8 import 'package:barback/barback.dart'; |
9 import 'package:code_transformers/resolver.dart'; | 9 import 'package:code_transformers/resolver.dart'; |
10 import 'package:initialize/transformer.dart'; | 10 import 'package:initialize/transformer.dart'; |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
195 return buffer.toString(); | 195 return buffer.toString(); |
196 } | 196 } |
197 | 197 |
198 /// Builds a [String] representing [expression] taking into account the | 198 /// Builds a [String] representing [expression] taking into account the |
199 /// [libraryPrefixes] from [pluginData]. | 199 /// [libraryPrefixes] from [pluginData]. |
200 String buildExpression( | 200 String buildExpression( |
201 Expression expression, InitializerPluginData pluginData) { | 201 Expression expression, InitializerPluginData pluginData) { |
202 var logger = pluginData.logger; | 202 var logger = pluginData.logger; |
203 var libraryPrefixes = pluginData.libraryPrefixes; | 203 var libraryPrefixes = pluginData.libraryPrefixes; |
204 var buffer = new StringBuffer(); | 204 var buffer = new StringBuffer(); |
205 if (expression is StringLiteral) { | 205 if (expression is StringLiteral && expression.stringValue != null) { |
206 var value = expression.stringValue; | 206 buffer.write(_stringValue(expression.stringValue)); |
207 if (value == null) { | |
208 logger.error('Only const strings are allowed in initializer ' | |
209 'expressions, found $expression'); | |
210 } | |
211 value = value.replaceAll(r'\', r'\\').replaceAll(r"'", r"\'"); | |
212 buffer.write("'$value'"); | |
213 } else if (expression is BooleanLiteral || | 207 } else if (expression is BooleanLiteral || |
214 expression is DoubleLiteral || | 208 expression is DoubleLiteral || |
215 expression is IntegerLiteral || | 209 expression is IntegerLiteral || |
216 expression is NullLiteral) { | 210 expression is NullLiteral) { |
217 buffer.write('${expression}'); | 211 buffer.write('${expression}'); |
218 } else if (expression is ListLiteral) { | 212 } else if (expression is ListLiteral) { |
219 buffer.write('const ['); | 213 buffer.write('const ['); |
220 var first = true; | 214 var first = true; |
221 for (Expression listExpression in expression.elements) { | 215 for (Expression listExpression in expression.elements) { |
222 if (!first) buffer.write(', '); | 216 if (!first) buffer.write(', '); |
223 first = false; | 217 first = false; |
224 buffer.write(buildExpression(listExpression, pluginData)); | 218 buffer.write(buildExpression(listExpression, pluginData)); |
225 } | 219 } |
226 buffer.write(']'); | 220 buffer.write(']'); |
227 } else if (expression is MapLiteral) { | 221 } else if (expression is MapLiteral) { |
228 buffer.write('const {'); | 222 buffer.write('const {'); |
229 var first = true; | 223 var first = true; |
230 for (MapLiteralEntry entry in expression.entries) { | 224 for (MapLiteralEntry entry in expression.entries) { |
231 if (!first) buffer.write(', '); | 225 if (!first) buffer.write(', '); |
232 first = false; | 226 first = false; |
233 buffer.write(buildExpression(entry.key, pluginData)); | 227 buffer.write(buildExpression(entry.key, pluginData)); |
234 buffer.write(': '); | 228 buffer.write(': '); |
235 buffer.write(buildExpression(entry.value, pluginData)); | 229 buffer.write(buildExpression(entry.value, pluginData)); |
236 } | 230 } |
237 buffer.write('}'); | 231 buffer.write('}'); |
238 } else if (expression is Identifier) { | 232 } else if (expression is Identifier) { |
239 var element = expression.bestElement; | 233 var element = expression.bestElement; |
240 if (element == null || !element.isPublic) { | 234 if (element == null || !element.isPublic) { |
241 logger.error('Private constants are not supported in intializer ' | 235 logger.error('Private constants are not supported in intializer ' |
242 'constructors, found $element.'); | 236 'constructors, found $element.'); |
243 } | 237 } |
244 libraryPrefixes.putIfAbsent( | 238 libraryPrefixes.putIfAbsent( |
245 element.library, () => 'i${libraryPrefixes.length}'); | 239 element.library, () => 'i${libraryPrefixes.length}'); |
246 | 240 |
247 buffer.write('${libraryPrefixes[element.library]}.'); | 241 buffer.write('${libraryPrefixes[element.library]}.'); |
248 if (element is ClassElement) { | 242 if (element is ClassElement) { |
249 buffer.write(element.name); | 243 buffer.write(element.name); |
250 } else if (element is PropertyAccessorElement) { | 244 } else if (element is PropertyAccessorElement) { |
251 var variable = element.variable; | 245 var variable = element.variable; |
252 if (variable is FieldElement) { | 246 if (variable is FieldElement) { |
253 buffer.write('${variable.enclosingElement.name}.'); | 247 buffer.write('${variable.enclosingElement.name}.'); |
254 } | 248 } |
255 buffer.write('${variable.name}'); | 249 buffer.write('${variable.name}'); |
256 } else { | 250 } else { |
257 logger.error('Unsupported argument to initializer constructor.'); | 251 logger.error('Unsupported argument to initializer constructor.'); |
258 } | 252 } |
253 } else if (expression is InstanceCreationExpression) { | |
254 logger.error('Unsupported expression in initializer, found $expression. ' | |
255 'Instance creation expressions are not supported (yet). Instead, ' | |
256 'please assign it to a const variable and use that instead.'); | |
259 } else { | 257 } else { |
260 logger.error('Only literals and identifiers are allowed for initializer ' | 258 // Try to evaluate the constant and use that. |
261 'expressions, found $expression.'); | 259 var result = pluginData.resolver.evaluateConstant( |
260 pluginData.initializer.targetElement.library, expression); | |
261 if (!result.isValid) { | |
262 logger.error('Invalid expression in initializer, found $expression. ' | |
263 'And got the following errors: ${result.errors}.'); | |
264 } | |
265 var value = result.value.value; | |
266 if (value == null) { | |
267 logger.error('Unsupported expression in initializer, found ' | |
268 '$expression. Please file a bug at ' | |
269 'https://github.com/dart-lang/initialize/issues'); | |
270 } | |
271 | |
272 if (value is String) value = _stringValue(value); | |
Siggi Cherem (dart-lang)
2015/02/25 19:32:08
we might need to check for instance creations here
jakemac
2015/02/25 20:23:05
Above this there is a special case for Identifiers
Siggi Cherem (dart-lang)
2015/02/25 21:06:33
but is there any case where those could evaluate t
jakemac
2015/02/25 22:06:08
Done.
| |
273 buffer.write(value); | |
262 } | 274 } |
263 return buffer.toString(); | 275 return buffer.toString(); |
264 } | 276 } |
277 | |
278 // Returns an expression for a string value. Wraps it in single quotes and | |
279 // escapes existing single quotes and escapes. | |
280 _stringValue(String value) { | |
281 value = value.replaceAll(r'\', r'\\').replaceAll(r"'", r"\'"); | |
282 return "'$value'"; | |
283 } | |
265 } | 284 } |
OLD | NEW |