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 |