OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 | 4 |
5 part of dart2js; | 5 part of dart2js; |
6 | 6 |
7 /** | 7 /** |
8 * If true, print a warning for each method that was resolved, but not | 8 * If true, print a warning for each method that was resolved, but not |
9 * compiled. | 9 * compiled. |
10 */ | 10 */ |
(...skipping 14 matching lines...) Expand all Loading... |
25 * Invariant: [element] must be a declaration element. | 25 * Invariant: [element] must be a declaration element. |
26 */ | 26 */ |
27 final AstElement element; | 27 final AstElement element; |
28 | 28 |
29 TreeElements get resolutionTree; | 29 TreeElements get resolutionTree; |
30 | 30 |
31 WorkItem(this.element, this.compilationContext) { | 31 WorkItem(this.element, this.compilationContext) { |
32 assert(invariant(element, element.isDeclaration)); | 32 assert(invariant(element, element.isDeclaration)); |
33 } | 33 } |
34 | 34 |
35 void run(Compiler compiler, Enqueuer world); | 35 WorldImpact run(Compiler compiler, Enqueuer world); |
36 } | 36 } |
37 | 37 |
38 /// [WorkItem] used exclusively by the [ResolutionEnqueuer]. | 38 /// [WorkItem] used exclusively by the [ResolutionEnqueuer]. |
39 class ResolutionWorkItem extends WorkItem { | 39 class ResolutionWorkItem extends WorkItem { |
40 TreeElements resolutionTree; | 40 TreeElements resolutionTree; |
41 | 41 |
42 ResolutionWorkItem(AstElement element, | 42 ResolutionWorkItem(AstElement element, |
43 ItemCompilationContext compilationContext) | 43 ItemCompilationContext compilationContext) |
44 : super(element, compilationContext); | 44 : super(element, compilationContext); |
45 | 45 |
46 void run(Compiler compiler, ResolutionEnqueuer world) { | 46 WorldImpact run(Compiler compiler, ResolutionEnqueuer world) { |
47 compiler.analyze(this, world); | 47 WorldImpact impact = compiler.analyze(this, world); |
48 resolutionTree = element.resolvedAst.elements; | 48 resolutionTree = element.resolvedAst.elements; |
| 49 return impact; |
49 } | 50 } |
50 | 51 |
51 bool isAnalyzed() => resolutionTree != null; | 52 bool isAnalyzed() => resolutionTree != null; |
52 } | 53 } |
53 | 54 |
54 // TODO(johnniwinther): Split this class into interface and implementation. | 55 // TODO(johnniwinther): Split this class into interface and implementation. |
55 // TODO(johnniwinther): Move this implementation to the JS backend. | 56 // TODO(johnniwinther): Move this implementation to the JS backend. |
56 class CodegenRegistry extends Registry { | 57 class CodegenRegistry extends Registry { |
57 final Compiler compiler; | 58 final Compiler compiler; |
58 final TreeElements treeElements; | 59 final TreeElements treeElements; |
(...skipping 15 matching lines...) Expand all Loading... |
74 treeElements.registerDependency(element); | 75 treeElements.registerDependency(element); |
75 } | 76 } |
76 | 77 |
77 void registerInlining(Element inlinedElement, Element context) { | 78 void registerInlining(Element inlinedElement, Element context) { |
78 if (compiler.dumpInfo) { | 79 if (compiler.dumpInfo) { |
79 compiler.dumpInfoTask.registerInlined(inlinedElement, context); | 80 compiler.dumpInfoTask.registerInlined(inlinedElement, context); |
80 } | 81 } |
81 } | 82 } |
82 | 83 |
83 void registerInstantiatedClass(ClassElement element) { | 84 void registerInstantiatedClass(ClassElement element) { |
84 world.registerInstantiatedClass(element, this); | 85 world.registerInstantiatedType(element.rawType, this); |
85 } | 86 } |
86 | 87 |
87 void registerInstantiatedType(InterfaceType type) { | 88 void registerInstantiatedType(InterfaceType type) { |
88 world.registerInstantiatedType(type, this); | 89 world.registerInstantiatedType(type, this); |
89 } | 90 } |
90 | 91 |
91 void registerStaticUse(Element element) { | 92 void registerStaticUse(Element element) { |
92 world.registerStaticUse(element); | 93 world.registerStaticUse(element); |
93 } | 94 } |
94 | 95 |
(...skipping 18 matching lines...) Expand all Loading... |
113 | 114 |
114 void registerFieldGetter(Element element) { | 115 void registerFieldGetter(Element element) { |
115 world.registerFieldGetter(element); | 116 world.registerFieldGetter(element); |
116 } | 117 } |
117 | 118 |
118 void registerFieldSetter(Element element) { | 119 void registerFieldSetter(Element element) { |
119 world.registerFieldSetter(element); | 120 world.registerFieldSetter(element); |
120 } | 121 } |
121 | 122 |
122 void registerIsCheck(DartType type) { | 123 void registerIsCheck(DartType type) { |
123 world.registerIsCheck(type, this); | 124 world.registerIsCheck(type); |
124 backend.registerIsCheckForCodegen(type, world, this); | 125 backend.registerIsCheckForCodegen(type, world, this); |
125 } | 126 } |
126 | 127 |
127 void registerCompileTimeConstant(ConstantValue constant) { | 128 void registerCompileTimeConstant(ConstantValue constant) { |
128 backend.registerCompileTimeConstant(constant, this); | 129 backend.registerCompileTimeConstant(constant, this); |
129 backend.constants.addCompileTimeConstantForEmission(constant); | 130 backend.constants.addCompileTimeConstantForEmission(constant); |
130 } | 131 } |
131 | 132 |
132 void registerTypeVariableBoundsSubtypeCheck(DartType subtype, | 133 void registerTypeVariableBoundsSubtypeCheck(DartType subtype, |
133 DartType supertype) { | 134 DartType supertype) { |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
179 } | 180 } |
180 | 181 |
181 void registerAsyncMarker(FunctionElement element) { | 182 void registerAsyncMarker(FunctionElement element) { |
182 backend.registerAsyncMarker(element, world, this); | 183 backend.registerAsyncMarker(element, world, this); |
183 } | 184 } |
184 | 185 |
185 } | 186 } |
186 | 187 |
187 /// [WorkItem] used exclusively by the [CodegenEnqueuer]. | 188 /// [WorkItem] used exclusively by the [CodegenEnqueuer]. |
188 class CodegenWorkItem extends WorkItem { | 189 class CodegenWorkItem extends WorkItem { |
189 Registry registry; | 190 CodegenRegistry registry; |
190 | 191 |
191 factory CodegenWorkItem( | 192 factory CodegenWorkItem( |
192 Compiler compiler, | 193 Compiler compiler, |
193 AstElement element, | 194 AstElement element, |
194 ItemCompilationContext compilationContext) { | 195 ItemCompilationContext compilationContext) { |
195 // If this assertion fails, the resolution callbacks of the backend may be | 196 // If this assertion fails, the resolution callbacks of the backend may be |
196 // missing call of form registry.registerXXX. Alternatively, the code | 197 // missing call of form registry.registerXXX. Alternatively, the code |
197 // generation could spuriously be adding dependencies on things we know we | 198 // generation could spuriously be adding dependencies on things we know we |
198 // don't need. | 199 // don't need. |
199 assert(invariant(element, | 200 assert(invariant(element, |
200 compiler.enqueuer.resolution.hasBeenResolved(element), | 201 compiler.enqueuer.resolution.hasBeenResolved(element), |
201 message: "$element has not been resolved.")); | 202 message: "$element has not been resolved.")); |
202 assert(invariant(element, element.resolvedAst.elements != null, | 203 assert(invariant(element, element.resolvedAst.elements != null, |
203 message: 'Resolution tree is null for $element in codegen work item')); | 204 message: 'Resolution tree is null for $element in codegen work item')); |
204 return new CodegenWorkItem.internal(element, compilationContext); | 205 return new CodegenWorkItem.internal(element, compilationContext); |
205 } | 206 } |
206 | 207 |
207 CodegenWorkItem.internal( | 208 CodegenWorkItem.internal( |
208 AstElement element, | 209 AstElement element, |
209 ItemCompilationContext compilationContext) | 210 ItemCompilationContext compilationContext) |
210 : super(element, compilationContext); | 211 : super(element, compilationContext); |
211 | 212 |
212 TreeElements get resolutionTree => element.resolvedAst.elements; | 213 TreeElements get resolutionTree => element.resolvedAst.elements; |
213 | 214 |
214 void run(Compiler compiler, CodegenEnqueuer world) { | 215 WorldImpact run(Compiler compiler, CodegenEnqueuer world) { |
215 if (world.isProcessed(element)) return; | 216 if (world.isProcessed(element)) return const WorldImpact(); |
216 | 217 |
217 registry = new CodegenRegistry(compiler, resolutionTree); | 218 registry = new CodegenRegistry(compiler, resolutionTree); |
218 compiler.codegen(this, world); | 219 return compiler.codegen(this, world); |
219 } | 220 } |
220 } | 221 } |
221 | 222 |
222 typedef void DeferredAction(); | 223 typedef void DeferredAction(); |
223 | 224 |
224 class DeferredTask { | 225 class DeferredTask { |
225 final Element element; | 226 final Element element; |
226 final DeferredAction action; | 227 final DeferredAction action; |
227 | 228 |
228 DeferredTask(this.element, this.action); | 229 DeferredTask(this.element, this.action); |
(...skipping 13 matching lines...) Expand all Loading... |
242 | 243 |
243 void registerDynamicGetter(Selector selector); | 244 void registerDynamicGetter(Selector selector); |
244 | 245 |
245 void registerDynamicSetter(Selector selector); | 246 void registerDynamicSetter(Selector selector); |
246 | 247 |
247 void registerStaticInvocation(Element element); | 248 void registerStaticInvocation(Element element); |
248 | 249 |
249 void registerInstantiation(InterfaceType type); | 250 void registerInstantiation(InterfaceType type); |
250 | 251 |
251 void registerGetOfStaticFunction(FunctionElement element); | 252 void registerGetOfStaticFunction(FunctionElement element); |
252 | |
253 void registerAsyncMarker(FunctionElement element); | |
254 } | 253 } |
255 | 254 |
256 abstract class Backend { | 255 abstract class Backend { |
257 final Compiler compiler; | 256 final Compiler compiler; |
258 | 257 |
259 Backend(this.compiler); | 258 Backend(this.compiler); |
260 | 259 |
261 /// The [ConstantSystem] used to interpret compile-time constants for this | 260 /// The [ConstantSystem] used to interpret compile-time constants for this |
262 /// backend. | 261 /// backend. |
263 ConstantSystem get constantSystem; | 262 ConstantSystem get constantSystem; |
(...skipping 16 matching lines...) Expand all Loading... |
280 /// otherwise visible during resolution. | 279 /// otherwise visible during resolution. |
281 Iterable<ClassElement> classesRequiredForReflection = const []; | 280 Iterable<ClassElement> classesRequiredForReflection = const []; |
282 | 281 |
283 // Given a [FunctionElement], return a buffer with the code generated for it | 282 // Given a [FunctionElement], return a buffer with the code generated for it |
284 // or null if no code was generated. | 283 // or null if no code was generated. |
285 CodeBuffer codeOf(Element element) => null; | 284 CodeBuffer codeOf(Element element) => null; |
286 | 285 |
287 void initializeHelperClasses() {} | 286 void initializeHelperClasses() {} |
288 | 287 |
289 void enqueueHelpers(ResolutionEnqueuer world, Registry registry); | 288 void enqueueHelpers(ResolutionEnqueuer world, Registry registry); |
290 void codegen(CodegenWorkItem work); | 289 WorldImpact codegen(CodegenWorkItem work); |
291 | 290 |
292 // The backend determines the native resolution enqueuer, with a no-op | 291 // The backend determines the native resolution enqueuer, with a no-op |
293 // default, so tools like dart2dart can ignore the native classes. | 292 // default, so tools like dart2dart can ignore the native classes. |
294 native.NativeEnqueuer nativeResolutionEnqueuer(world) { | 293 native.NativeEnqueuer nativeResolutionEnqueuer(world) { |
295 return new native.NativeEnqueuer(); | 294 return new native.NativeEnqueuer(); |
296 } | 295 } |
297 native.NativeEnqueuer nativeCodegenEnqueuer(world) { | 296 native.NativeEnqueuer nativeCodegenEnqueuer(world) { |
298 return new native.NativeEnqueuer(); | 297 return new native.NativeEnqueuer(); |
299 } | 298 } |
300 | 299 |
(...skipping 1390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1691 fullyEnqueueTopLevelElement(element, world); | 1690 fullyEnqueueTopLevelElement(element, world); |
1692 } | 1691 } |
1693 library.implementation.forEachLocalMember(enqueueAll); | 1692 library.implementation.forEachLocalMember(enqueueAll); |
1694 } | 1693 } |
1695 | 1694 |
1696 void fullyEnqueueTopLevelElement(Element element, Enqueuer world) { | 1695 void fullyEnqueueTopLevelElement(Element element, Enqueuer world) { |
1697 if (element.isClass) { | 1696 if (element.isClass) { |
1698 ClassElement cls = element; | 1697 ClassElement cls = element; |
1699 cls.ensureResolved(this); | 1698 cls.ensureResolved(this); |
1700 cls.forEachLocalMember(enqueuer.resolution.addToWorkList); | 1699 cls.forEachLocalMember(enqueuer.resolution.addToWorkList); |
1701 world.registerInstantiatedClass(element, globalDependencies); | 1700 world.registerInstantiatedType(cls.rawType, globalDependencies); |
1702 } else { | 1701 } else { |
1703 world.addToWorkList(element); | 1702 world.addToWorkList(element); |
1704 } | 1703 } |
1705 } | 1704 } |
1706 | 1705 |
1707 // Resolves metadata on library elements. This is necessary in order to | 1706 // Resolves metadata on library elements. This is necessary in order to |
1708 // resolve metadata classes referenced only from metadata on library tags. | 1707 // resolve metadata classes referenced only from metadata on library tags. |
1709 // TODO(ahe): Figure out how to do this lazily. | 1708 // TODO(ahe): Figure out how to do this lazily. |
1710 void resolveLibraryMetadata() { | 1709 void resolveLibraryMetadata() { |
1711 for (LibraryElement library in libraryLoader.libraries) { | 1710 for (LibraryElement library in libraryLoader.libraries) { |
1712 if (library.metadata != null) { | 1711 if (library.metadata != null) { |
1713 for (MetadataAnnotation metadata in library.metadata) { | 1712 for (MetadataAnnotation metadata in library.metadata) { |
1714 metadata.ensureResolved(this); | 1713 metadata.ensureResolved(this); |
1715 } | 1714 } |
1716 } | 1715 } |
1717 } | 1716 } |
1718 } | 1717 } |
1719 | 1718 |
1720 void processQueue(Enqueuer world, Element main) { | 1719 void processQueue(Enqueuer world, Element main) { |
1721 world.nativeEnqueuer.processNativeClasses(libraryLoader.libraries); | 1720 world.nativeEnqueuer.processNativeClasses(libraryLoader.libraries); |
1722 if (main != null && !main.isErroneous) { | 1721 if (main != null && !main.isErroneous) { |
1723 FunctionElement mainMethod = main; | 1722 FunctionElement mainMethod = main; |
1724 if (mainMethod.computeSignature(this).parameterCount != 0) { | 1723 if (mainMethod.computeSignature(this).parameterCount != 0) { |
1725 // The first argument could be a list of strings. | 1724 // The first argument could be a list of strings. |
1726 world.registerInstantiatedClass( | 1725 backend.listImplementation.ensureResolved(this); |
1727 backend.listImplementation, globalDependencies); | 1726 world.registerInstantiatedType( |
1728 world.registerInstantiatedClass( | 1727 backend.listImplementation.rawType, globalDependencies); |
1729 backend.stringImplementation, globalDependencies); | 1728 backend.stringImplementation.ensureResolved(this); |
| 1729 world.registerInstantiatedType( |
| 1730 backend.stringImplementation.rawType, globalDependencies); |
1730 | 1731 |
1731 backend.registerMainHasArguments(world); | 1732 backend.registerMainHasArguments(world); |
1732 } | 1733 } |
1733 world.addToWorkList(main); | 1734 world.addToWorkList(main); |
1734 } | 1735 } |
1735 if (verbose) { | 1736 if (verbose) { |
1736 progress.reset(); | 1737 progress.reset(); |
1737 } | 1738 } |
1738 world.forEach((WorkItem work) { | 1739 world.forEach((WorkItem work) { |
1739 withCurrentElement(work.element, () => work.run(this, world)); | 1740 withCurrentElement(work.element, () { |
| 1741 world.applyImpact(work.element, work.run(this, world)); |
| 1742 }); |
1740 }); | 1743 }); |
1741 world.queueIsClosed = true; | 1744 world.queueIsClosed = true; |
1742 assert(compilationFailed || world.checkNoEnqueuedInvokedInstanceMethods()); | 1745 assert(compilationFailed || world.checkNoEnqueuedInvokedInstanceMethods()); |
1743 } | 1746 } |
1744 | 1747 |
1745 /** | 1748 /** |
1746 * Perform various checks of the queues. This includes checking that | 1749 * Perform various checks of the queues. This includes checking that |
1747 * the queues are empty (nothing was added after we stopped | 1750 * the queues are empty (nothing was added after we stopped |
1748 * processing the queues). Also compute the number of methods that | 1751 * processing the queues). Also compute the number of methods that |
1749 * were resolved, but not compiled (aka excess resolution). | 1752 * were resolved, but not compiled (aka excess resolution). |
(...skipping 25 matching lines...) Expand all Loading... |
1775 } | 1778 } |
1776 } | 1779 } |
1777 log('Excess resolution work: ${resolved.length}.'); | 1780 log('Excess resolution work: ${resolved.length}.'); |
1778 for (Element e in resolved) { | 1781 for (Element e in resolved) { |
1779 reportWarning(e, | 1782 reportWarning(e, |
1780 MessageKind.GENERIC, | 1783 MessageKind.GENERIC, |
1781 {'text': 'Warning: $e resolved but not compiled.'}); | 1784 {'text': 'Warning: $e resolved but not compiled.'}); |
1782 } | 1785 } |
1783 } | 1786 } |
1784 | 1787 |
1785 void analyzeElement(Element element) { | 1788 WorldImpact analyzeElement(Element element) { |
1786 assert(invariant(element, | 1789 assert(invariant(element, |
1787 element.impliesType || | 1790 element.impliesType || |
1788 element.isField || | 1791 element.isField || |
1789 element.isFunction || | 1792 element.isFunction || |
1790 element.isGenerativeConstructor || | 1793 element.isGenerativeConstructor || |
1791 element.isGetter || | 1794 element.isGetter || |
1792 element.isSetter, | 1795 element.isSetter, |
1793 message: 'Unexpected element kind: ${element.kind}')); | 1796 message: 'Unexpected element kind: ${element.kind}')); |
1794 assert(invariant(element, element is AnalyzableElement, | 1797 assert(invariant(element, element is AnalyzableElement, |
1795 message: 'Element $element is not analyzable.')); | 1798 message: 'Element $element is not analyzable.')); |
1796 assert(invariant(element, element.isDeclaration)); | 1799 assert(invariant(element, element.isDeclaration)); |
1797 ResolutionEnqueuer world = enqueuer.resolution; | 1800 ResolutionEnqueuer world = enqueuer.resolution; |
1798 if (world.hasBeenResolved(element)) return; | 1801 if (world.hasBeenResolved(element)) { |
| 1802 return const WorldImpact(); |
| 1803 } |
1799 assert(parser != null); | 1804 assert(parser != null); |
1800 Node tree = parser.parse(element); | 1805 Node tree = parser.parse(element); |
1801 assert(invariant(element, !element.isSynthesized || tree == null)); | 1806 assert(invariant(element, !element.isSynthesized || tree == null)); |
1802 TreeElements elements = resolver.resolve(element); | 1807 WorldImpact worldImpact = resolver.resolve(element); |
1803 if (elements != null) { | 1808 if (tree != null && !analyzeSignaturesOnly && |
1804 if (tree != null && !analyzeSignaturesOnly && | 1809 !suppressWarnings) { |
1805 !suppressWarnings) { | 1810 // Only analyze nodes with a corresponding [TreeElements]. |
1806 // Only analyze nodes with a corresponding [TreeElements]. | 1811 checker.check(element); |
1807 checker.check(elements); | |
1808 } | |
1809 world.registerResolvedElement(element); | |
1810 } | 1812 } |
| 1813 world.registerResolvedElement(element); |
| 1814 return worldImpact; |
1811 } | 1815 } |
1812 | 1816 |
1813 void analyze(ResolutionWorkItem work, ResolutionEnqueuer world) { | 1817 WorldImpact analyze(ResolutionWorkItem work, ResolutionEnqueuer world) { |
1814 assert(invariant(work.element, identical(world, enqueuer.resolution))); | 1818 assert(invariant(work.element, identical(world, enqueuer.resolution))); |
1815 assert(invariant(work.element, !work.isAnalyzed(), | 1819 assert(invariant(work.element, !work.isAnalyzed(), |
1816 message: 'Element ${work.element} has already been analyzed')); | 1820 message: 'Element ${work.element} has already been analyzed')); |
1817 if (shouldPrintProgress) { | 1821 if (shouldPrintProgress) { |
1818 // TODO(ahe): Add structured diagnostics to the compiler API and | 1822 // TODO(ahe): Add structured diagnostics to the compiler API and |
1819 // use it to separate this from the --verbose option. | 1823 // use it to separate this from the --verbose option. |
1820 if (phase == PHASE_RESOLVING) { | 1824 if (phase == PHASE_RESOLVING) { |
1821 log('Resolved ${enqueuer.resolution.resolvedElements.length} ' | 1825 log('Resolved ${enqueuer.resolution.resolvedElements.length} ' |
1822 'elements.'); | 1826 'elements.'); |
1823 progress.reset(); | 1827 progress.reset(); |
1824 } | 1828 } |
1825 } | 1829 } |
1826 AstElement element = work.element; | 1830 AstElement element = work.element; |
1827 if (world.hasBeenResolved(element)) return; | 1831 if (world.hasBeenResolved(element)) { |
1828 analyzeElement(element); | 1832 return const WorldImpact(); |
| 1833 } |
| 1834 WorldImpact worldImpact = analyzeElement(element); |
1829 backend.onElementResolved(element, element.resolvedAst.elements); | 1835 backend.onElementResolved(element, element.resolvedAst.elements); |
| 1836 return worldImpact; |
1830 } | 1837 } |
1831 | 1838 |
1832 void codegen(CodegenWorkItem work, CodegenEnqueuer world) { | 1839 WorldImpact codegen(CodegenWorkItem work, CodegenEnqueuer world) { |
1833 assert(invariant(work.element, identical(world, enqueuer.codegen))); | 1840 assert(invariant(work.element, identical(world, enqueuer.codegen))); |
1834 if (shouldPrintProgress) { | 1841 if (shouldPrintProgress) { |
1835 // TODO(ahe): Add structured diagnostics to the compiler API and | 1842 // TODO(ahe): Add structured diagnostics to the compiler API and |
1836 // use it to separate this from the --verbose option. | 1843 // use it to separate this from the --verbose option. |
1837 log('Compiled ${enqueuer.codegen.generatedCode.length} methods.'); | 1844 log('Compiled ${enqueuer.codegen.generatedCode.length} methods.'); |
1838 progress.reset(); | 1845 progress.reset(); |
1839 } | 1846 } |
1840 backend.codegen(work); | 1847 return backend.codegen(work); |
1841 } | 1848 } |
1842 | 1849 |
1843 void reportError(Spannable node, | 1850 void reportError(Spannable node, |
1844 MessageKind messageKind, | 1851 MessageKind messageKind, |
1845 [Map arguments = const {}]) { | 1852 [Map arguments = const {}]) { |
1846 reportDiagnosticInternal( | 1853 reportDiagnosticInternal( |
1847 node, messageKind, arguments, api.Diagnostic.ERROR); | 1854 node, messageKind, arguments, api.Diagnostic.ERROR); |
1848 } | 1855 } |
1849 | 1856 |
1850 void reportWarning(Spannable node, MessageKind messageKind, | 1857 void reportWarning(Spannable node, MessageKind messageKind, |
(...skipping 608 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2459 return futureClass.computeType(compiler).createInstantiation([elementType]); | 2466 return futureClass.computeType(compiler).createInstantiation([elementType]); |
2460 } | 2467 } |
2461 | 2468 |
2462 @override | 2469 @override |
2463 InterfaceType streamType([DartType elementType = const DynamicType()]) { | 2470 InterfaceType streamType([DartType elementType = const DynamicType()]) { |
2464 return streamClass.computeType(compiler).createInstantiation([elementType]); | 2471 return streamClass.computeType(compiler).createInstantiation([elementType]); |
2465 } | 2472 } |
2466 } | 2473 } |
2467 | 2474 |
2468 typedef void InternalErrorFunction(Spannable location, String message); | 2475 typedef void InternalErrorFunction(Spannable location, String message); |
OLD | NEW |