Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // (c) 2015, the Dart Team. All rights reserved. Use of this | 1 // (c) 2015, the Dart Team. All rights reserved. Use of this |
| 2 // source code is governed by a BSD-style license that can be found in | 2 // source code is governed by a BSD-style license that can be found in |
| 3 // the LICENSE file. | 3 // the LICENSE file. |
| 4 | 4 |
| 5 library reflectable.src.transformer_implementation; | 5 library reflectable.src.transformer_implementation; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 import 'dart:convert'; | 8 import 'dart:convert'; |
| 9 import 'dart:io'; | 9 import 'dart:io'; |
| 10 import 'dart:math' show max; | 10 import 'dart:math' show max; |
| (...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 232 if (elementAnnotation.element is ConstructorElement) { | 232 if (elementAnnotation.element is ConstructorElement) { |
| 233 // If this is a constructor call, add the otherwise implicit 'const'. | 233 // If this is a constructor call, add the otherwise implicit 'const'. |
| 234 metadataParts.add("const $source"); | 234 metadataParts.add("const $source"); |
| 235 } else { | 235 } else { |
| 236 metadataParts.add(source); | 236 metadataParts.add(source); |
| 237 } | 237 } |
| 238 } | 238 } |
| 239 return "new UnmodifiableListView([${metadataParts.join(", ")}])"; | 239 return "new UnmodifiableListView([${metadataParts.join(", ")}])"; |
| 240 } | 240 } |
| 241 | 241 |
| 242 String get newInstanceString { | |
| 243 // TODO(eernst, sigurdm, #8): Recreate the default values faithfully. | |
| 244 List<String> constructorLines = new List<String>(); | |
| 245 | |
| 246 String name(int i) { | |
| 247 String alphabet = "abcdefghijklmnopqrstuvwxyz"; | |
| 248 int alphabetLength = alphabet.length; | |
| 249 if (i < alphabetLength) { | |
| 250 return "_${alphabet[i]}"; | |
| 251 } | |
| 252 return "_${alphabet[i % alphabetLength]}${i ~/ alphabetLength}"; | |
| 253 } | |
| 254 for (ConstructorElement constructor in constructors) { | |
| 255 FunctionType type = constructor.type; | |
| 256 int positionalCount = type.normalParameterTypes.length; | |
|
eernst
2015/06/19 09:22:21
I suspect that `normalParameterTypes` delivers inf
sigurdm
2015/06/19 10:52:00
Done.
| |
| 257 int optionalCount = type.optionalParameterTypes.length; | |
|
eernst
2015/06/19 09:22:21
Similarly, since both named parameters and (some)
sigurdm
2015/06/19 10:52:00
Done.
| |
| 258 List<String> argumentNames = type.namedParameterTypes.keys.toList(); | |
| 259 String positionals = | |
| 260 new Iterable.generate(positionalCount, (int i) => name(i)).join(", "); | |
| 261 String optionalsWithDefaults = new Iterable.generate(optionalCount, | |
| 262 (int i) { | |
| 263 String defaultValueCode = | |
| 264 constructor.parameters[positionalCount + i].defaultValueCode; | |
| 265 String defaultValueString = | |
| 266 defaultValueCode == null ? "" : " = $defaultValueCode"; | |
|
eernst
2015/06/19 09:22:21
Wouldn't it be better to have the '.. faithfully'
sigurdm
2015/06/19 10:52:00
Done
| |
| 267 return "${name(i + positionalCount)}$defaultValueString"; | |
| 268 }).join(", "); | |
| 269 String namedWithDefaults = new Iterable.generate(argumentNames.length, | |
| 270 (int i) { | |
| 271 String defaultValueCode = | |
| 272 constructor.parameters[positionalCount + i].defaultValueCode; | |
| 273 String defaultValueString = | |
| 274 defaultValueCode == null ? "" : ": $defaultValueCode"; | |
| 275 return "${argumentNames[i]}$defaultValueString"; | |
| 276 }).join(", "); | |
| 277 | |
| 278 String optionalArguments = new Iterable.generate( | |
| 279 optionalCount, (int i) => name(i + positionalCount)).join(", "); | |
| 280 String namedArguments = | |
| 281 argumentNames.map((String name) => "$name: $name").join(", "); | |
| 282 List<String> parameterParts = new List<String>(); | |
| 283 List<String> argumentParts = new List<String>(); | |
| 284 if (positionalCount != 0) { | |
| 285 parameterParts.add(positionals); | |
| 286 argumentParts.add(positionals); | |
| 287 } | |
| 288 if (optionalCount != 0) { | |
| 289 parameterParts.add("[$optionalsWithDefaults]"); | |
| 290 argumentParts.add(optionalArguments); | |
| 291 } | |
| 292 if (argumentNames.isNotEmpty) { | |
| 293 parameterParts.add("{${namedWithDefaults}}"); | |
| 294 argumentParts.add(namedArguments); | |
| 295 } | |
| 296 constructorLines.add('case "${constructor.name}": ' | |
| 297 'c = (${parameterParts.join(', ')}) => ' | |
| 298 'new ${nameOfDeclaration(constructor)}' | |
| 299 '(${argumentParts.join(", ")});'); | |
| 300 constructorLines.add(' break;'); | |
| 301 } | |
| 302 return """newInstance(String constructorName, List positionalArguments, | |
| 303 [Map<Symbol, dynamic> namedArguments]) { | |
| 304 Function c; | |
| 305 switch (constructorName) { | |
| 306 ${constructorLines.join("\n ")} | |
| 307 default: throw new NoSuchInvokeCapabilityError(${classElement.name}, | |
| 308 constructorName, positionalArguments, namedArguments); | |
| 309 } | |
| 310 return Function.apply(c, positionalArguments, namedArguments); | |
| 311 }"""; | |
| 312 } | |
| 313 | |
| 242 void computeNames(Namer namer) { | 314 void computeNames(Namer namer) { |
| 243 staticClassMirrorName = namer.freshName("Static_${baseName}_ClassMirror"); | 315 staticClassMirrorName = namer.freshName("Static_${baseName}_ClassMirror"); |
| 244 staticInstanceMirrorName = | 316 staticInstanceMirrorName = |
| 245 namer.freshName("Static_${baseName}_InstanceMirror"); | 317 namer.freshName("Static_${baseName}_InstanceMirror"); |
| 246 } | 318 } |
| 247 } | 319 } |
| 248 | 320 |
| 249 /// A wrapper around a list of Capabilities. | 321 /// A wrapper around a list of Capabilities. |
| 250 /// Supports queries about the methods supported by the set of capabilities. | 322 /// Supports queries about the methods supported by the set of capabilities. |
| 251 class Capabilities { | 323 class Capabilities { |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 488 // programmers who are doing something else, intentionally. To emit a | 560 // programmers who are doing something else, intentionally. To emit a |
| 489 // diagnostic message, we must check whether there is a Reflectable | 561 // diagnostic message, we must check whether there is a Reflectable |
| 490 // somewhere inside this syntactic construct, and then emit the message | 562 // somewhere inside this syntactic construct, and then emit the message |
| 491 // in cases that we "consider likely to be misunderstood". | 563 // in cases that we "consider likely to be misunderstood". |
| 492 return null; | 564 return null; |
| 493 } | 565 } |
| 494 | 566 |
| 495 Iterable<MethodElement> declaredMethods( | 567 Iterable<MethodElement> declaredMethods( |
| 496 ClassElement classElement, Capabilities capabilities) { | 568 ClassElement classElement, Capabilities capabilities) { |
| 497 return classElement.methods.where((MethodElement method) { | 569 return classElement.methods.where((MethodElement method) { |
| 570 if (method.isAbstract) return false; | |
|
eernst
2015/06/19 09:22:21
Maybe this one was reintroduced spuriously by git?
sigurdm
2015/06/19 10:52:00
Done.
| |
| 498 if (method.isStatic) { | 571 if (method.isStatic) { |
| 499 // TODO(sigurdm): Ask capabilities about support. | 572 // TODO(sigurdm): Ask capabilities about support. |
| 500 return true; | 573 return true; |
| 501 } else { | 574 } else { |
| 502 return capabilities.supportsInstanceInvoke(method.name); | 575 return capabilities.supportsInstanceInvoke(method.name); |
| 503 } | 576 } |
| 504 }); | 577 }); |
| 505 } | 578 } |
| 506 | 579 |
| 507 Iterable<PropertyAccessorElement> declaredAccessors( | 580 Iterable<PropertyAccessorElement> declaredAccessors( |
| (...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 903 Map<String, MethodMirror> get instanceMembers { | 976 Map<String, MethodMirror> get instanceMembers { |
| 904 if (_instanceMembersCache == null) { | 977 if (_instanceMembersCache == null) { |
| 905 _instanceMembersCache = new UnmodifiableMapView($instanceMembersString); | 978 _instanceMembersCache = new UnmodifiableMapView($instanceMembersString); |
| 906 } | 979 } |
| 907 return _instanceMembersCache; | 980 return _instanceMembersCache; |
| 908 }"""); | 981 }"""); |
| 909 if (classDomain.reflectorDomain.capabilities.supportsMetadata) { | 982 if (classDomain.reflectorDomain.capabilities.supportsMetadata) { |
| 910 implementedMembers | 983 implementedMembers |
| 911 .add("List<Object> metadata = ${classDomain.metadataString};"); | 984 .add("List<Object> metadata = ${classDomain.metadataString};"); |
| 912 } | 985 } |
| 986 if (!classDomain.classElement.isAbstract) { | |
| 987 implementedMembers.add(classDomain.newInstanceString); | |
| 988 } | |
|
eernst
2015/06/19 09:22:21
Maybe this one was reintroduced spuriously by git?
sigurdm
2015/06/19 10:52:00
No this one is good. We do not want to be able to
| |
| 913 | 989 |
| 914 return """ | 990 return """ |
| 915 class ${classDomain.staticClassMirrorName} extends ClassMirrorUnimpl { | 991 class ${classDomain.staticClassMirrorName} extends ClassMirrorUnimpl { |
| 916 ${implementedMembers.join("\n\n ")} | 992 ${implementedMembers.join("\n\n ")} |
| 917 } | 993 } |
| 918 """; | 994 """; |
| 919 } | 995 } |
| 920 | 996 |
| 921 /// Perform some very simple steps that are consistent with Dart | 997 /// Perform some very simple steps that are consistent with Dart |
| 922 /// semantics for the evaluation of constant expressions, such that | 998 /// semantics for the evaluation of constant expressions, such that |
| (...skipping 559 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1482 TransformLogger get logger => _aggregateTransform.logger; | 1558 TransformLogger get logger => _aggregateTransform.logger; |
| 1483 Future<Asset> getInput(AssetId id) => _aggregateTransform.getInput(id); | 1559 Future<Asset> getInput(AssetId id) => _aggregateTransform.getInput(id); |
| 1484 Future<String> readInputAsString(AssetId id, {Encoding encoding}) { | 1560 Future<String> readInputAsString(AssetId id, {Encoding encoding}) { |
| 1485 return _aggregateTransform.readInputAsString(id, encoding: encoding); | 1561 return _aggregateTransform.readInputAsString(id, encoding: encoding); |
| 1486 } | 1562 } |
| 1487 Stream<List<int>> readInput(AssetId id) => _aggregateTransform.readInput(id); | 1563 Stream<List<int>> readInput(AssetId id) => _aggregateTransform.readInput(id); |
| 1488 Future<bool> hasInput(AssetId id) => _aggregateTransform.hasInput(id); | 1564 Future<bool> hasInput(AssetId id) => _aggregateTransform.hasInput(id); |
| 1489 void addOutput(Asset output) => _aggregateTransform.addOutput(output); | 1565 void addOutput(Asset output) => _aggregateTransform.addOutput(output); |
| 1490 void consumePrimary() => _aggregateTransform.consumePrimary(primaryInput.id); | 1566 void consumePrimary() => _aggregateTransform.consumePrimary(primaryInput.id); |
| 1491 } | 1567 } |
| OLD | NEW |