Chromium Code Reviews| 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 |