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 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
61 annotatedClasses | 61 annotatedClasses |
62 .forEach((ClassDomain classDomain) => classDomain.computeNames(namer)); | 62 .forEach((ClassDomain classDomain) => classDomain.computeNames(namer)); |
63 } | 63 } |
64 } | 64 } |
65 | 65 |
66 /// Information about reflectability for a given class. | 66 /// Information about reflectability for a given class. |
67 class ClassDomain { | 67 class ClassDomain { |
68 final ClassElement classElement; | 68 final ClassElement classElement; |
69 final Iterable<MethodElement> invokableMethods; | 69 final Iterable<MethodElement> invokableMethods; |
70 final Iterable<MethodElement> declaredMethods; | 70 final Iterable<MethodElement> declaredMethods; |
71 final Iterable<PropertyAccessorElement> declaredAccessors; | |
72 final Iterable<ConstructorElement> constructors; | |
71 | 73 |
72 ReflectorDomain reflectorDomain; | 74 ReflectorDomain reflectorDomain; |
73 String staticClassMirrorName; | 75 String staticClassMirrorName; |
74 String staticInstanceMirrorName; | 76 String staticInstanceMirrorName; |
75 String get baseName => classElement.name; | 77 String get baseName => classElement.name; |
76 | 78 |
77 ClassDomain(this.classElement, this.invokableMethods, this.declaredMethods, | 79 ClassDomain(this.classElement, this.invokableMethods, this.declaredMethods, |
78 this.reflectorDomain); | 80 this.declaredAccessors, this.constructors, this.reflectorDomain); |
79 | 81 |
80 Iterable<ExecutableElement> get declarations { | 82 Iterable<ExecutableElement> get declarations { |
81 // TODO(sigurdm): Include constructors. | |
82 // TODO(sigurdm): Include fields. | 83 // TODO(sigurdm): Include fields. |
83 // TODO(sigurdm): Include getters and setters. | |
84 // TODO(sigurdm): Include type variables (if we decide to keep them). | 84 // TODO(sigurdm): Include type variables (if we decide to keep them). |
85 return [declaredMethods].expand((x) => x); | 85 return [declaredMethods, declaredAccessors, constructors].expand((x) => x); |
86 } | 86 } |
87 | 87 |
88 /// Returns an integer encoding the kind and attributes of the given | 88 /// Returns an integer encoding the kind and attributes of the given |
89 /// method/constructor/getter/setter. | 89 /// method/constructor/getter/setter. |
90 int _declarationDescriptor(ExecutableElement element) { | 90 int _declarationDescriptor(ExecutableElement element) { |
91 int result; | 91 int result; |
92 if (element is PropertyAccessorElement) { | 92 if (element is PropertyAccessorElement) { |
93 result = element.isGetter ? constants.getter : constants.setter; | 93 result = element.isGetter ? constants.getter : constants.setter; |
94 } else if (element is ConstructorElement) { | 94 } else if (element is ConstructorElement) { |
95 if (element.isFactory) { | 95 if (element.isFactory) { |
96 result = constants.factoryConstructor; | 96 result = constants.factoryConstructor; |
97 } else if (element.redirectedConstructor != null) { | |
98 result = constants.redirectingConstructor; | |
99 } else { | 97 } else { |
100 result = constants.generativeConstructor; | 98 result = constants.generativeConstructor; |
101 } | 99 } |
102 if (element.isConst) { | 100 if (element.isConst) { |
103 result += constants.constAttribute; | 101 result += constants.constAttribute; |
104 } | 102 } |
103 if (element.redirectedConstructor != null) { | |
104 result += constants.redirectingConstructor; | |
105 } | |
105 } else { | 106 } else { |
106 result = constants.method; | 107 result = constants.method; |
107 } | 108 } |
108 if (element.isPrivate) { | 109 if (element.isPrivate) { |
109 result += constants.privateAttribute; | 110 result += constants.privateAttribute; |
110 } | 111 } |
111 if (element.isAbstract) { | 112 assert(!element.isAbstract); |
eernst
2015/06/18 10:07:18
Seems to be enough to revert this one.
sigurdm
2015/06/18 11:04:03
Done.
| |
112 result += constants.abstractAttribute; | |
113 } | |
114 if (element.isStatic) { | 113 if (element.isStatic) { |
115 result += constants.staticAttribute; | 114 result += constants.staticAttribute; |
116 } | 115 } |
117 return result; | 116 return result; |
118 } | 117 } |
119 | 118 |
119 String nameOfDeclaration(ExecutableElement element) { | |
120 if (element is ConstructorElement) { | |
121 return element.name == "" | |
122 ? classElement.name | |
123 : "${classElement.name}.${element.name}"; | |
124 } | |
125 return element.name; | |
126 } | |
127 | |
120 /// Returns a String with the textual representation of the declarations-map. | 128 /// Returns a String with the textual representation of the declarations-map. |
121 String get declarationsString { | 129 String get declarationsString { |
122 Iterable<String> declarationParts = declarations.map( | 130 Iterable<String> declarationParts = declarations.map( |
123 (ExecutableElement instanceMember) { | 131 (ExecutableElement declaration) { |
124 return '"${instanceMember.name}": ' | 132 return '"${nameOfDeclaration(declaration)}": ' |
125 'new MethodMirrorImpl("${instanceMember.name}", ' | 133 'new MethodMirrorImpl("${declaration.name}", ' |
126 '${_declarationDescriptor(instanceMember)}, this)'; | 134 '${_declarationDescriptor(declaration)}, this)'; |
127 }); | 135 }); |
128 return "{${declarationParts.join(", ")}}"; | 136 return "{${declarationParts.join(", ")}}"; |
129 } | 137 } |
130 | 138 |
131 void computeNames(Namer namer) { | 139 void computeNames(Namer namer) { |
132 staticClassMirrorName = namer.freshName("Static_${baseName}_ClassMirror"); | 140 staticClassMirrorName = namer.freshName("Static_${baseName}_ClassMirror"); |
133 staticInstanceMirrorName = | 141 staticInstanceMirrorName = |
134 namer.freshName("Static_${baseName}_InstanceMirror"); | 142 namer.freshName("Static_${baseName}_InstanceMirror"); |
135 } | 143 } |
136 } | 144 } |
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
389 result.addAll(classElement.methods); | 397 result.addAll(classElement.methods); |
390 classElement.allSupertypes.forEach((InterfaceType superType) { | 398 classElement.allSupertypes.forEach((InterfaceType superType) { |
391 result.addAll(superType.methods); | 399 result.addAll(superType.methods); |
392 }); | 400 }); |
393 return result; | 401 return result; |
394 } | 402 } |
395 | 403 |
396 Iterable<MethodElement> declaredMethods( | 404 Iterable<MethodElement> declaredMethods( |
397 ClassElement classElement, Capabilities capabilities) { | 405 ClassElement classElement, Capabilities capabilities) { |
398 return classElement.methods.where((MethodElement method) { | 406 return classElement.methods.where((MethodElement method) { |
407 if (method.isAbstract) return false; | |
399 if (method.isStatic) { | 408 if (method.isStatic) { |
400 // TODO(sigurdm): Ask capability about support. | 409 // TODO(sigurdm): Ask capabilities about support. |
401 return true; | 410 return true; |
402 } else { | 411 } else { |
403 return capabilities.supportsInstanceInvoke(method.name); | 412 return capabilities.supportsInstanceInvoke(method.name); |
404 } | 413 } |
405 }); | 414 }); |
406 } | 415 } |
407 | 416 |
417 Iterable<PropertyAccessorElement> declaredAccessors( | |
418 ClassElement classElement, Capabilities capabilities) { | |
419 return classElement.accessors.where((PropertyAccessorElement accessor) { | |
420 if (accessor.isAbstract) return false; | |
eernst
2015/06/18 10:07:19
With abstract members included, should this line b
sigurdm
2015/06/18 11:04:03
Done.
| |
421 if (accessor.isStatic) { | |
422 // TODO(sigurdm): Ask capabilities about support. | |
423 return true; | |
424 } else { | |
425 return capabilities.supportsInstanceInvoke(accessor.name); | |
426 } | |
427 }); | |
428 } | |
429 | |
430 Iterable<ConstructorElement> declaredConstructors( | |
431 ClassElement classElement, Capabilities capabilities) { | |
432 return classElement.constructors.where((ConstructorElement constructor) { | |
433 // TODO(sigurdm): Ask capabilities about support. | |
434 return true; | |
435 }); | |
436 } | |
437 | |
408 Iterable<MethodElement> invocableInstanceMethods( | 438 Iterable<MethodElement> invocableInstanceMethods( |
409 ClassElement classElement, Capabilities capabilities) { | 439 ClassElement classElement, Capabilities capabilities) { |
410 return allMethods(classElement).where((MethodElement method) { | 440 return allMethods(classElement).where((MethodElement method) { |
411 MethodDeclaration methodDeclaration = method.node; | 441 MethodDeclaration methodDeclaration = method.node; |
412 // TODO(eernst): We currently ignore method declarations when | 442 // TODO(eernst): We currently ignore method declarations when |
413 // they are operators. One issue is generation of code (which | 443 // they are operators. One issue is generation of code (which |
414 // does not work if we go ahead naively). | 444 // does not work if we go ahead naively). |
415 if (methodDeclaration.isOperator) return false; | 445 if (methodDeclaration.isOperator) return false; |
416 String methodName = methodDeclaration.name.name; | 446 String methodName = methodDeclaration.name.name; |
417 return capabilities.supportsInstanceInvoke(methodName); | 447 return capabilities.supportsInstanceInvoke(methodName); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
464 ReflectorDomain domain = domains.putIfAbsent(reflector, () { | 494 ReflectorDomain domain = domains.putIfAbsent(reflector, () { |
465 Capabilities capabilities = | 495 Capabilities capabilities = |
466 _capabilitiesOf(capabilityLibrary, reflector); | 496 _capabilitiesOf(capabilityLibrary, reflector); |
467 return new ReflectorDomain( | 497 return new ReflectorDomain( |
468 reflector, new List<ClassDomain>(), capabilities); | 498 reflector, new List<ClassDomain>(), capabilities); |
469 }); | 499 }); |
470 List<MethodElement> instanceMethods = | 500 List<MethodElement> instanceMethods = |
471 invocableInstanceMethods(type, domain.capabilities).toList(); | 501 invocableInstanceMethods(type, domain.capabilities).toList(); |
472 List<MethodElement> declaredMethodsOfClass = | 502 List<MethodElement> declaredMethodsOfClass = |
473 declaredMethods(type, domain.capabilities).toList(); | 503 declaredMethods(type, domain.capabilities).toList(); |
474 domain.annotatedClasses.add(new ClassDomain( | 504 List<PropertyAccessorElement> declaredAccessorsOfClass = |
475 type, instanceMethods, declaredMethodsOfClass, domain)); | 505 declaredAccessors(type, domain.capabilities).toList(); |
506 List<ConstructorElement> declaredConstructorsOfClass = | |
507 declaredConstructors(type, domain.capabilities).toList(); | |
508 domain.annotatedClasses.add(new ClassDomain(type, instanceMethods, | |
509 declaredMethodsOfClass, declaredAccessorsOfClass, | |
510 declaredConstructorsOfClass, domain)); | |
476 } | 511 } |
477 } | 512 } |
478 } | 513 } |
479 } | 514 } |
480 domains.values.forEach(_collectMissingImports); | 515 domains.values.forEach(_collectMissingImports); |
481 | 516 |
482 world.reflectors.addAll(domains.values.toList()); | 517 world.reflectors.addAll(domains.values.toList()); |
483 world.computeNames(namer); | 518 world.computeNames(namer); |
484 return world; | 519 return world; |
485 } | 520 } |
(...skipping 732 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1218 TransformLogger get logger => _aggregateTransform.logger; | 1253 TransformLogger get logger => _aggregateTransform.logger; |
1219 Future<Asset> getInput(AssetId id) => _aggregateTransform.getInput(id); | 1254 Future<Asset> getInput(AssetId id) => _aggregateTransform.getInput(id); |
1220 Future<String> readInputAsString(AssetId id, {Encoding encoding}) { | 1255 Future<String> readInputAsString(AssetId id, {Encoding encoding}) { |
1221 return _aggregateTransform.readInputAsString(id, encoding: encoding); | 1256 return _aggregateTransform.readInputAsString(id, encoding: encoding); |
1222 } | 1257 } |
1223 Stream<List<int>> readInput(AssetId id) => _aggregateTransform.readInput(id); | 1258 Stream<List<int>> readInput(AssetId id) => _aggregateTransform.readInput(id); |
1224 Future<bool> hasInput(AssetId id) => _aggregateTransform.hasInput(id); | 1259 Future<bool> hasInput(AssetId id) => _aggregateTransform.hasInput(id); |
1225 void addOutput(Asset output) => _aggregateTransform.addOutput(output); | 1260 void addOutput(Asset output) => _aggregateTransform.addOutput(output); |
1226 void consumePrimary() => _aggregateTransform.consumePrimary(primaryInput.id); | 1261 void consumePrimary() => _aggregateTransform.consumePrimary(primaryInput.id); |
1227 } | 1262 } |
OLD | NEW |