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 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
43 reflectors | 43 reflectors |
44 .forEach((ReflectorDomain reflector) => reflector.computeNames(namer)); | 44 .forEach((ReflectorDomain reflector) => reflector.computeNames(namer)); |
45 } | 45 } |
46 } | 46 } |
47 | 47 |
48 /// Information about the program parts that can be reflected by a given | 48 /// Information about the program parts that can be reflected by a given |
49 /// Reflector. | 49 /// Reflector. |
50 class ReflectorDomain { | 50 class ReflectorDomain { |
51 final ClassElement reflector; | 51 final ClassElement reflector; |
52 final List<ClassDomain> annotatedClasses; | 52 final List<ClassDomain> annotatedClasses; |
53 final Map<ClassElement, ClassDomain> classMap = | |
54 new Map<ClassElement, ClassDomain>(); | |
53 final Capabilities capabilities; | 55 final Capabilities capabilities; |
54 | 56 |
55 /// Libraries that must be imported to `reflector.library`. | 57 /// Libraries that must be imported to `reflector.library`. |
56 final Set<LibraryElement> missingImports = new Set<LibraryElement>(); | 58 final Set<LibraryElement> missingImports = new Set<LibraryElement>(); |
57 | 59 |
58 ReflectorDomain(this.reflector, this.annotatedClasses, this.capabilities); | 60 ReflectorDomain(this.reflector, this.annotatedClasses, this.capabilities) { |
61 for (ClassDomain classDomain in annotatedClasses) { | |
62 classMap[classDomain.classElement] = classDomain; | |
63 } | |
64 } | |
59 | 65 |
60 void computeNames(Namer namer) { | 66 void computeNames(Namer namer) { |
61 annotatedClasses | 67 annotatedClasses |
62 .forEach((ClassDomain classDomain) => classDomain.computeNames(namer)); | 68 .forEach((ClassDomain classDomain) => classDomain.computeNames(namer)); |
63 } | 69 } |
70 | |
71 Map<ClassElement, Map<String, ExecutableElement>> _instanceMemberCache = | |
72 new Map<ClassElement, Map<String, ExecutableElement>>(); | |
eernst
2015/06/18 12:21:12
Do we need an more global mechanism to guide the e
sigurdm
2015/06/18 14:22:27
I am not sure - will leave a todo.
| |
64 } | 73 } |
65 | 74 |
66 /// Information about reflectability for a given class. | 75 /// Information about reflectability for a given class. |
67 class ClassDomain { | 76 class ClassDomain { |
68 final ClassElement classElement; | 77 final ClassElement classElement; |
69 final Iterable<MethodElement> invokableMethods; | |
70 final Iterable<MethodElement> declaredMethods; | 78 final Iterable<MethodElement> declaredMethods; |
79 final Iterable<PropertyAccessorElement> declaredAccessors; | |
80 final Iterable<ConstructorElement> constructors; | |
71 | 81 |
72 ReflectorDomain reflectorDomain; | 82 ReflectorDomain reflectorDomain; |
83 | |
84 Iterable<MethodElement> get invokableMethods => instanceMembers | |
85 .where((ExecutableElement element) => element is MethodElement); | |
86 | |
73 String staticClassMirrorName; | 87 String staticClassMirrorName; |
74 String staticInstanceMirrorName; | 88 String staticInstanceMirrorName; |
75 String get baseName => classElement.name; | 89 String get baseName => classElement.name; |
76 | 90 |
77 ClassDomain(this.classElement, this.invokableMethods, this.declaredMethods, | 91 ClassDomain(this.classElement, this.declaredMethods, |
78 this.reflectorDomain); | 92 this.declaredAccessors, this.constructors, this.reflectorDomain); |
79 | 93 |
80 Iterable<ExecutableElement> get declarations { | 94 Iterable<ExecutableElement> get declarations { |
81 // TODO(sigurdm): Include constructors. | |
82 // TODO(sigurdm): Include fields. | 95 // TODO(sigurdm): Include fields. |
83 // TODO(sigurdm): Include getters and setters. | |
84 // TODO(sigurdm): Include type variables (if we decide to keep them). | 96 // TODO(sigurdm): Include type variables (if we decide to keep them). |
85 return [declaredMethods].expand((x) => x); | 97 return [declaredMethods, declaredAccessors, constructors].expand((x) => x); |
98 } | |
99 | |
100 /// Finds all instance members by going through the class hierarchy. | |
101 Iterable<ExecutableElement> get instanceMembers { | |
102 | |
103 Map<String, ExecutableElement> helper(ClassElement classElement) { | |
104 if (reflectorDomain._instanceMemberCache[classElement] != null) { | |
105 return reflectorDomain._instanceMemberCache[classElement]; | |
106 } | |
107 Map<String, ExecutableElement> result = | |
108 new Map<String, ExecutableElement>(); | |
109 | |
110 void addIfCapable(ExecutableElement member) { | |
111 if (reflectorDomain.capabilities.supportsInstanceInvoke(member.name)) { | |
112 result[member.name] = member; | |
113 } | |
114 } | |
115 if (classElement.supertype != null) { | |
116 helper(classElement.supertype.element).forEach( | |
117 (String name, ExecutableElement member) { | |
118 addIfCapable(member); | |
119 }); | |
120 } | |
121 for (InterfaceType mixin in classElement.mixins) { | |
122 helper(mixin.element).forEach((String name, ExecutableElement member) { | |
123 addIfCapable(member); | |
124 }); | |
125 } | |
126 for (MethodElement member in classElement.methods) { | |
127 if (member.isAbstract || member.isStatic) continue; | |
128 addIfCapable(member); | |
129 } | |
130 for (PropertyAccessorElement member in classElement.accessors) { | |
131 if (member.isAbstract || member.isStatic) continue; | |
132 addIfCapable(member); | |
133 } | |
134 for (FieldElement field in classElement.fields) { | |
135 if (field.isStatic) continue; | |
136 if (field.isSynthetic) continue; | |
137 addIfCapable(field.getter); | |
138 if (!field.isFinal) { | |
139 addIfCapable(field.setter); | |
140 } | |
141 } | |
142 return result; | |
143 } | |
144 return helper(classElement).values; | |
86 } | 145 } |
87 | 146 |
88 /// Returns an integer encoding the kind and attributes of the given | 147 /// Returns an integer encoding the kind and attributes of the given |
89 /// method/constructor/getter/setter. | 148 /// method/constructor/getter/setter. |
90 int _declarationDescriptor(ExecutableElement element) { | 149 int _declarationDescriptor(ExecutableElement element) { |
91 int result; | 150 int result; |
92 if (element is PropertyAccessorElement) { | 151 if (element is PropertyAccessorElement) { |
93 result = element.isGetter ? constants.getter : constants.setter; | 152 result = element.isGetter ? constants.getter : constants.setter; |
94 } else if (element is ConstructorElement) { | 153 } else if (element is ConstructorElement) { |
95 if (element.isFactory) { | 154 if (element.isFactory) { |
96 result = constants.factoryConstructor; | 155 result = constants.factoryConstructor; |
97 } else if (element.redirectedConstructor != null) { | |
98 result = constants.redirectingConstructor; | |
99 } else { | 156 } else { |
100 result = constants.generativeConstructor; | 157 result = constants.generativeConstructor; |
101 } | 158 } |
102 if (element.isConst) { | 159 if (element.isConst) { |
103 result += constants.constAttribute; | 160 result += constants.constAttribute; |
104 } | 161 } |
162 if (element.redirectedConstructor != null) { | |
163 result += constants.redirectingConstructor; | |
164 } | |
105 } else { | 165 } else { |
106 result = constants.method; | 166 result = constants.method; |
107 } | 167 } |
108 if (element.isPrivate) { | 168 if (element.isPrivate) { |
109 result += constants.privateAttribute; | 169 result += constants.privateAttribute; |
110 } | 170 } |
111 if (element.isAbstract) { | 171 assert(!element.isAbstract); |
112 result += constants.abstractAttribute; | |
113 } | |
114 if (element.isStatic) { | 172 if (element.isStatic) { |
115 result += constants.staticAttribute; | 173 result += constants.staticAttribute; |
116 } | 174 } |
175 if (element.isSynthetic) { | |
176 result += constants.syntheticAttribute; | |
177 } | |
117 return result; | 178 return result; |
118 } | 179 } |
119 | 180 |
181 String nameOfDeclaration(ExecutableElement element) { | |
182 if (element is ConstructorElement) { | |
183 return element.name == "" | |
184 ? classElement.name | |
185 : "${classElement.name}.${element.name}"; | |
186 } | |
187 return element.name; | |
188 } | |
189 | |
120 /// Returns a String with the textual representation of the declarations-map. | 190 /// Returns a String with the textual representation of the declarations-map. |
121 String get declarationsString { | 191 String get declarationsString { |
122 Iterable<String> declarationParts = declarations.map( | 192 Iterable<String> declarationParts = declarations.map( |
123 (ExecutableElement instanceMember) { | 193 (ExecutableElement declaration) { |
124 return '"${instanceMember.name}": ' | 194 return '"${nameOfDeclaration(declaration)}": ' |
125 'new MethodMirrorImpl("${instanceMember.name}", ' | 195 'new MethodMirrorImpl("${declaration.name}", ' |
126 '${_declarationDescriptor(instanceMember)}, this)'; | 196 '${_declarationDescriptor(declaration)}, this)'; |
127 }); | 197 }); |
128 return "{${declarationParts.join(", ")}}"; | 198 return "{${declarationParts.join(", ")}}"; |
129 } | 199 } |
130 | 200 |
201 /// Returns a String with the textual representation of the | |
202 /// instanceMembers-map. | |
203 String get instanceMembersString { | |
204 // TODO(sigurdm): Find out how to set the right owner. | |
205 Iterable<String> instanceMemberParts = instanceMembers.map( | |
206 (ExecutableElement declaration) { | |
207 return '"${nameOfDeclaration(declaration)}": ' | |
208 'new MethodMirrorImpl("${declaration.name}", ' | |
209 '${_declarationDescriptor(declaration)}, null)'; | |
210 }); | |
211 return "{${instanceMemberParts.join(", ")}}"; | |
212 } | |
213 | |
131 void computeNames(Namer namer) { | 214 void computeNames(Namer namer) { |
132 staticClassMirrorName = namer.freshName("Static_${baseName}_ClassMirror"); | 215 staticClassMirrorName = namer.freshName("Static_${baseName}_ClassMirror"); |
133 staticInstanceMirrorName = | 216 staticInstanceMirrorName = |
134 namer.freshName("Static_${baseName}_InstanceMirror"); | 217 namer.freshName("Static_${baseName}_InstanceMirror"); |
135 } | 218 } |
136 } | 219 } |
137 | 220 |
138 /// A wrapper around a list of Capabilities. | 221 /// A wrapper around a list of Capabilities. |
139 /// Supports queries about the methods supported by the set of capabilities. | 222 /// Supports queries about the methods supported by the set of capabilities. |
140 class Capabilities { | 223 class Capabilities { |
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
376 // have no effect; it might be better to emit a diagnostic message (a | 459 // have no effect; it might be better to emit a diagnostic message (a |
377 // hint?) in order to notify the programmer that "it does not work". | 460 // hint?) in order to notify the programmer that "it does not work". |
378 // The trade-off is that such constructs may have been written by | 461 // The trade-off is that such constructs may have been written by |
379 // programmers who are doing something else, intentionally. To emit a | 462 // programmers who are doing something else, intentionally. To emit a |
380 // diagnostic message, we must check whether there is a Reflectable | 463 // diagnostic message, we must check whether there is a Reflectable |
381 // somewhere inside this syntactic construct, and then emit the message | 464 // somewhere inside this syntactic construct, and then emit the message |
382 // in cases that we "consider likely to be misunderstood". | 465 // in cases that we "consider likely to be misunderstood". |
383 return null; | 466 return null; |
384 } | 467 } |
385 | 468 |
386 /// Finds all the methods in the class and all super-classes. | |
387 Iterable<MethodElement> allMethods(ClassElement classElement) { | |
388 List<MethodElement> result = new List<MethodElement>(); | |
389 result.addAll(classElement.methods); | |
390 classElement.allSupertypes.forEach((InterfaceType superType) { | |
391 result.addAll(superType.methods); | |
392 }); | |
393 return result; | |
394 } | |
395 | |
396 Iterable<MethodElement> declaredMethods( | 469 Iterable<MethodElement> declaredMethods( |
397 ClassElement classElement, Capabilities capabilities) { | 470 ClassElement classElement, Capabilities capabilities) { |
398 return classElement.methods.where((MethodElement method) { | 471 return classElement.methods.where((MethodElement method) { |
472 if (method.isAbstract) return false; | |
399 if (method.isStatic) { | 473 if (method.isStatic) { |
400 // TODO(sigurdm): Ask capability about support. | 474 // TODO(sigurdm): Ask capabilities about support. |
401 return true; | 475 return true; |
402 } else { | 476 } else { |
403 return capabilities.supportsInstanceInvoke(method.name); | 477 return capabilities.supportsInstanceInvoke(method.name); |
404 } | 478 } |
405 }); | 479 }); |
406 } | 480 } |
407 | 481 |
408 Iterable<MethodElement> invocableInstanceMethods( | 482 Iterable<PropertyAccessorElement> declaredAccessors( |
409 ClassElement classElement, Capabilities capabilities) { | 483 ClassElement classElement, Capabilities capabilities) { |
410 return allMethods(classElement).where((MethodElement method) { | 484 return classElement.accessors.where((PropertyAccessorElement accessor) { |
411 MethodDeclaration methodDeclaration = method.node; | 485 if (accessor.isAbstract) return false; |
412 // TODO(eernst): We currently ignore method declarations when | 486 if (accessor.isStatic) { |
413 // they are operators. One issue is generation of code (which | 487 // TODO(sigurdm): Ask capabilities about support. |
414 // does not work if we go ahead naively). | 488 return true; |
415 if (methodDeclaration.isOperator) return false; | 489 } else { |
416 String methodName = methodDeclaration.name.name; | 490 return capabilities.supportsInstanceInvoke(accessor.name); |
417 return capabilities.supportsInstanceInvoke(methodName); | 491 } |
418 }); | 492 }); |
419 } | 493 } |
420 | 494 |
495 Iterable<ConstructorElement> declaredConstructors( | |
496 ClassElement classElement, Capabilities capabilities) { | |
497 return classElement.constructors.where((ConstructorElement constructor) { | |
498 // TODO(sigurdm): Ask capabilities about support. | |
499 return true; | |
500 }); | |
501 } | |
502 | |
421 /// Returns a [ReflectionWorld] instantiated with all the reflectors seen by | 503 /// Returns a [ReflectionWorld] instantiated with all the reflectors seen by |
422 /// [resolver] and all classes annotated by them. | 504 /// [resolver] and all classes annotated by them. |
423 /// | 505 /// |
424 /// TODO(eernst): Make sure it works also when other packages are being | 506 /// TODO(eernst): Make sure it works also when other packages are being |
425 /// used by the target program which have already been transformed by | 507 /// used by the target program which have already been transformed by |
426 /// this transformer (e.g., there would be a clash on the use of | 508 /// this transformer (e.g., there would be a clash on the use of |
427 /// reflectableClassId with values near 1000 for more than one class). | 509 /// reflectableClassId with values near 1000 for more than one class). |
428 ReflectionWorld _computeWorld(LibraryElement reflectableLibrary) { | 510 ReflectionWorld _computeWorld(LibraryElement reflectableLibrary) { |
429 ReflectionWorld world = new ReflectionWorld(reflectableLibrary); | 511 ReflectionWorld world = new ReflectionWorld(reflectableLibrary); |
430 Map<ClassElement, ReflectorDomain> domains = | 512 Map<ClassElement, ReflectorDomain> domains = |
(...skipping 29 matching lines...) Expand all Loading... | |
460 for (ElementAnnotation metadatum in type.metadata) { | 542 for (ElementAnnotation metadatum in type.metadata) { |
461 ClassElement reflector = | 543 ClassElement reflector = |
462 _getReflectableAnnotation(metadatum, focusClass); | 544 _getReflectableAnnotation(metadatum, focusClass); |
463 if (reflector == null) continue; | 545 if (reflector == null) continue; |
464 ReflectorDomain domain = domains.putIfAbsent(reflector, () { | 546 ReflectorDomain domain = domains.putIfAbsent(reflector, () { |
465 Capabilities capabilities = | 547 Capabilities capabilities = |
466 _capabilitiesOf(capabilityLibrary, reflector); | 548 _capabilitiesOf(capabilityLibrary, reflector); |
467 return new ReflectorDomain( | 549 return new ReflectorDomain( |
468 reflector, new List<ClassDomain>(), capabilities); | 550 reflector, new List<ClassDomain>(), capabilities); |
469 }); | 551 }); |
470 List<MethodElement> instanceMethods = | |
471 invocableInstanceMethods(type, domain.capabilities).toList(); | |
472 List<MethodElement> declaredMethodsOfClass = | 552 List<MethodElement> declaredMethodsOfClass = |
473 declaredMethods(type, domain.capabilities).toList(); | 553 declaredMethods(type, domain.capabilities).toList(); |
474 domain.annotatedClasses.add(new ClassDomain( | 554 List<PropertyAccessorElement> declaredAccessorsOfClass = |
475 type, instanceMethods, declaredMethodsOfClass, domain)); | 555 declaredAccessors(type, domain.capabilities).toList(); |
556 List<ConstructorElement> declaredConstructorsOfClass = | |
557 declaredConstructors(type, domain.capabilities).toList(); | |
558 domain.annotatedClasses.add(new ClassDomain(type, | |
559 declaredMethodsOfClass, declaredAccessorsOfClass, | |
560 declaredConstructorsOfClass, domain)); | |
476 } | 561 } |
477 } | 562 } |
478 } | 563 } |
479 } | 564 } |
480 domains.values.forEach(_collectMissingImports); | 565 domains.values.forEach(_collectMissingImports); |
481 | 566 |
482 world.reflectors.addAll(domains.values.toList()); | 567 world.reflectors.addAll(domains.values.toList()); |
483 world.computeNames(namer); | 568 world.computeNames(namer); |
484 return world; | 569 return world; |
485 } | 570 } |
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
764 Iterable<${prefix}ClassMirror> get annotatedClasses { | 849 Iterable<${prefix}ClassMirror> get annotatedClasses { |
765 return [${annotatedClassesStrings.join(", ")}]; | 850 return [${annotatedClassesStrings.join(", ")}]; |
766 }"""); | 851 }"""); |
767 } | 852 } |
768 | 853 |
769 /// Returns the source code for the reflection free subclass of | 854 /// Returns the source code for the reflection free subclass of |
770 /// [ClassMirror] which is specialized for a `reflectedType` which | 855 /// [ClassMirror] which is specialized for a `reflectedType` which |
771 /// is the class modeled by [classElement]. | 856 /// is the class modeled by [classElement]. |
772 String _staticClassMirrorCode(ClassDomain classDomain) { | 857 String _staticClassMirrorCode(ClassDomain classDomain) { |
773 String declarationsString = classDomain.declarationsString; | 858 String declarationsString = classDomain.declarationsString; |
859 String instanceMembersString = classDomain.instanceMembersString; | |
774 return """ | 860 return """ |
775 class ${classDomain.staticClassMirrorName} extends ClassMirrorUnimpl { | 861 class ${classDomain.staticClassMirrorName} extends ClassMirrorUnimpl { |
776 final String simpleName = "${classDomain.classElement.name}"; | 862 final String simpleName = "${classDomain.classElement.name}"; |
777 | 863 |
778 Map<String, MethodMirror> _declarationsCache; | 864 Map<String, MethodMirror> _declarationsCache; |
779 | 865 |
780 Map<String, MethodMirror> get declarations { | 866 Map<String, MethodMirror> get declarations { |
781 if (_declarationsCache == null) { | 867 if (_declarationsCache == null) { |
782 _declarationsCache = new UnmodifiableMapView($declarationsString); | 868 _declarationsCache = new UnmodifiableMapView($declarationsString); |
783 } | 869 } |
784 return _declarationsCache; | 870 return _declarationsCache; |
785 } | 871 } |
872 | |
873 Map<String, MethodMirror> _instanceMembersCache; | |
874 | |
875 Map<String, MethodMirror> get instanceMembers { | |
876 if (_instanceMembersCache == null) { | |
877 _instanceMembersCache = new UnmodifiableMapView($instanceMembersString); | |
878 } | |
879 return _instanceMembersCache; | |
880 } | |
881 | |
786 } | 882 } |
787 """; | 883 """; |
788 } | 884 } |
789 | 885 |
790 /// Perform some very simple steps that are consistent with Dart | 886 /// Perform some very simple steps that are consistent with Dart |
791 /// semantics for the evaluation of constant expressions, such that | 887 /// semantics for the evaluation of constant expressions, such that |
792 /// information about the value of a given `const` variable can be | 888 /// information about the value of a given `const` variable can be |
793 /// obtained. It is intended to help recognizing values of type | 889 /// obtained. It is intended to help recognizing values of type |
794 /// [ReflectCapability], so we only cover cases needed for that. | 890 /// [ReflectCapability], so we only cover cases needed for that. |
795 /// In particular, we cover lookup (e.g., with `const x = e` we can | 891 /// In particular, we cover lookup (e.g., with `const x = e` we can |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
938 ListLiteral listLiteral = arguments[0]; | 1034 ListLiteral listLiteral = arguments[0]; |
939 NodeList<Expression> expressions = listLiteral.elements; | 1035 NodeList<Expression> expressions = listLiteral.elements; |
940 return new Capabilities(expressions.map(capabilityOfExpression).toList()); | 1036 return new Capabilities(expressions.map(capabilityOfExpression).toList()); |
941 } | 1037 } |
942 | 1038 |
943 /// Returns a [String] containing generated code for the `invoke` | 1039 /// Returns a [String] containing generated code for the `invoke` |
944 /// method of the static `InstanceMirror` class corresponding to | 1040 /// method of the static `InstanceMirror` class corresponding to |
945 /// the given [classElement], bounded by the permissions given | 1041 /// the given [classElement], bounded by the permissions given |
946 /// in [capabilities]. | 1042 /// in [capabilities]. |
947 String _staticInstanceMirrorInvokeCode(ClassDomain classDomain) { | 1043 String _staticInstanceMirrorInvokeCode(ClassDomain classDomain) { |
1044 | |
1045 String tearOff(MethodElement methodElement) { | |
1046 if (!methodElement.isOperator) return "reflectee.${methodElement.name}"; | |
1047 if (methodElement.name == "[]=") return "(x, v) => reflectee[x] = v"; | |
1048 if (methodElement.name == "[]") return "(x) => reflectee[x]"; | |
1049 return "(x) => reflectee ${methodElement.name} x"; | |
1050 } | |
1051 | |
1052 | |
948 List<String> methodCases = new List<String>(); | 1053 List<String> methodCases = new List<String>(); |
949 for (MethodElement methodElement in classDomain.invokableMethods) { | 1054 for (MethodElement methodElement in classDomain.invokableMethods) { |
950 String methodName = methodElement.name; | 1055 methodCases.add("if (memberName == '${methodElement.name}') {" |
951 methodCases.add("if (memberName == '$methodName') {" | 1056 "method = ${tearOff(methodElement)}; }"); |
952 "method = reflectee.$methodName; }"); | |
953 } | 1057 } |
954 // TODO(eernst, sigurdm): Create an instance of [Invocation] in user code. | 1058 // TODO(eernst, sigurdm): Create an instance of [Invocation] in user code. |
955 methodCases.add("if (instanceMethodFilter.hasMatch(memberName)) {" | 1059 methodCases.add("if (instanceMethodFilter.hasMatch(memberName)) {" |
956 "throw new UnimplementedError('Should call noSuchMethod'); }"); | 1060 "throw new UnimplementedError('Should call noSuchMethod'); }"); |
957 methodCases.add("{ throw new NoSuchInvokeCapabilityError(" | 1061 methodCases.add("{ throw new NoSuchInvokeCapabilityError(" |
958 "reflectee, memberName, positionalArguments, namedArguments); }"); | 1062 "reflectee, memberName, positionalArguments, namedArguments); }"); |
959 // Handle the cases where permission is given even though there is | 1063 // Handle the cases where permission is given even though there is |
960 // no corresponding method. One case is where _all_ methods can be | 1064 // no corresponding method. One case is where _all_ methods can be |
961 // invoked. Another case is when the user has specified a name | 1065 // invoked. Another case is when the user has specified a name |
962 // `"foo"` and a reflector `@reflector` allowing for invocation | 1066 // `"foo"` and a reflector `@reflector` allowing for invocation |
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1218 TransformLogger get logger => _aggregateTransform.logger; | 1322 TransformLogger get logger => _aggregateTransform.logger; |
1219 Future<Asset> getInput(AssetId id) => _aggregateTransform.getInput(id); | 1323 Future<Asset> getInput(AssetId id) => _aggregateTransform.getInput(id); |
1220 Future<String> readInputAsString(AssetId id, {Encoding encoding}) { | 1324 Future<String> readInputAsString(AssetId id, {Encoding encoding}) { |
1221 return _aggregateTransform.readInputAsString(id, encoding: encoding); | 1325 return _aggregateTransform.readInputAsString(id, encoding: encoding); |
1222 } | 1326 } |
1223 Stream<List<int>> readInput(AssetId id) => _aggregateTransform.readInput(id); | 1327 Stream<List<int>> readInput(AssetId id) => _aggregateTransform.readInput(id); |
1224 Future<bool> hasInput(AssetId id) => _aggregateTransform.hasInput(id); | 1328 Future<bool> hasInput(AssetId id) => _aggregateTransform.hasInput(id); |
1225 void addOutput(Asset output) => _aggregateTransform.addOutput(output); | 1329 void addOutput(Asset output) => _aggregateTransform.addOutput(output); |
1226 void consumePrimary() => _aggregateTransform.consumePrimary(primaryInput.id); | 1330 void consumePrimary() => _aggregateTransform.consumePrimary(primaryInput.id); |
1227 } | 1331 } |
OLD | NEW |