OLD | NEW |
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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 library dart2js.serialization_helper; | 5 library dart2js.serialization_system; |
6 | 6 |
7 import 'dart:async'; | 7 import 'dart:async'; |
8 import 'dart:io'; | 8 import '../commandline_options.dart'; |
| 9 import '../common.dart'; |
| 10 import '../common/backend_api.dart'; |
| 11 import '../common/names.dart'; |
| 12 import '../common/resolution.dart'; |
| 13 import '../compiler.dart'; |
| 14 import '../elements/elements.dart'; |
| 15 import '../io/source_file.dart'; |
| 16 import '../scanner/scanner.dart'; |
| 17 import '../script.dart'; |
| 18 import '../serialization/impact_serialization.dart'; |
| 19 import '../tokens/token.dart'; |
| 20 import '../universe/call_structure.dart'; |
| 21 import '../universe/world_impact.dart'; |
| 22 import '../universe/use.dart'; |
| 23 import 'json_serializer.dart'; |
| 24 import 'modelz.dart'; |
| 25 import 'resolved_ast_serialization.dart'; |
| 26 import 'serialization.dart'; |
| 27 import 'task.dart'; |
9 | 28 |
10 import 'package:compiler/src/commandline_options.dart'; | 29 class DeserializerSystemImpl extends DeserializerSystem { |
11 import 'package:compiler/src/common.dart'; | |
12 import 'package:compiler/src/common/backend_api.dart'; | |
13 import 'package:compiler/src/common/names.dart'; | |
14 import 'package:compiler/src/common/resolution.dart'; | |
15 import 'package:compiler/src/compiler.dart'; | |
16 import 'package:compiler/src/elements/elements.dart'; | |
17 import 'package:compiler/src/io/source_file.dart'; | |
18 import 'package:compiler/src/scanner/scanner.dart'; | |
19 import 'package:compiler/src/script.dart'; | |
20 import 'package:compiler/src/serialization/impact_serialization.dart'; | |
21 import 'package:compiler/src/serialization/json_serializer.dart'; | |
22 import 'package:compiler/src/serialization/modelz.dart'; | |
23 import 'package:compiler/src/serialization/resolved_ast_serialization.dart'; | |
24 import 'package:compiler/src/serialization/serialization.dart'; | |
25 import 'package:compiler/src/serialization/task.dart'; | |
26 import 'package:compiler/src/tokens/token.dart'; | |
27 import 'package:compiler/src/universe/call_structure.dart'; | |
28 import 'package:compiler/src/universe/world_impact.dart'; | |
29 import 'package:compiler/src/universe/use.dart'; | |
30 | |
31 import '../memory_compiler.dart'; | |
32 | |
33 class Arguments { | |
34 final String filename; | |
35 final int index; | |
36 final bool loadSerializedData; | |
37 final bool saveSerializedData; | |
38 final String serializedDataFileName; | |
39 final bool verbose; | |
40 | |
41 const Arguments({ | |
42 this.filename, | |
43 this.index, | |
44 this.loadSerializedData: false, | |
45 this.saveSerializedData: false, | |
46 this.serializedDataFileName: 'out.data', | |
47 this.verbose: false}); | |
48 | |
49 factory Arguments.from(List<String> arguments) { | |
50 String filename; | |
51 int index; | |
52 for (String arg in arguments) { | |
53 if (!arg.startsWith('-')) { | |
54 index = int.parse(arg); | |
55 if (index == null) { | |
56 filename = arg; | |
57 } | |
58 } | |
59 } | |
60 bool verbose = arguments.contains('-v'); | |
61 bool loadSerializedData = arguments.contains('-l'); | |
62 bool saveSerializedData = arguments.contains('-s'); | |
63 return new Arguments( | |
64 filename: filename, | |
65 index: index, | |
66 verbose: verbose, | |
67 loadSerializedData: loadSerializedData, | |
68 saveSerializedData: saveSerializedData); | |
69 } | |
70 } | |
71 | |
72 | |
73 Future<String> serializeDartCore( | |
74 {Arguments arguments: const Arguments()}) async { | |
75 print('------------------------------------------------------------------'); | |
76 print('serialize dart:core'); | |
77 print('------------------------------------------------------------------'); | |
78 String serializedData; | |
79 if (arguments.loadSerializedData) { | |
80 File file = new File(arguments.serializedDataFileName); | |
81 if (file.existsSync()) { | |
82 print('Loading data from $file'); | |
83 serializedData = file.readAsStringSync(); | |
84 } | |
85 } | |
86 if (serializedData == null) { | |
87 Compiler compiler = compilerFor( | |
88 options: [Flags.analyzeAll]); | |
89 compiler.serialization.supportSerialization = true; | |
90 await compiler.run(Uris.dart_core); | |
91 serializedData = serialize( | |
92 compiler, | |
93 compiler.libraryLoader.libraries) | |
94 .toText(const JsonSerializationEncoder()); | |
95 if (arguments.saveSerializedData) { | |
96 File file = new File(arguments.serializedDataFileName); | |
97 print('Saving data to $file'); | |
98 file.writeAsStringSync(serializedData); | |
99 } | |
100 } | |
101 return serializedData; | |
102 } | |
103 | |
104 Serializer serialize( | |
105 Compiler compiler, | |
106 Iterable<LibraryElement> libraries) { | |
107 assert(compiler.serialization.supportSerialization); | |
108 | |
109 Serializer serializer = new Serializer(); | |
110 SerializerPlugin backendSerializer = | |
111 compiler.backend.serialization.serializer; | |
112 serializer.plugins.add(backendSerializer); | |
113 serializer.plugins.add(new ResolutionImpactSerializer( | |
114 compiler.resolution, backendSerializer)); | |
115 serializer.plugins.add(new ResolvedAstSerializerPlugin( | |
116 compiler.resolution, backendSerializer)); | |
117 | |
118 for (LibraryElement library in libraries) { | |
119 serializer.serialize(library); | |
120 } | |
121 return serializer; | |
122 } | |
123 | |
124 void deserialize(Compiler compiler, | |
125 String serializedData) { | |
126 Deserializer deserializer = new Deserializer.fromText( | |
127 new DeserializationContext(), | |
128 serializedData, | |
129 const JsonSerializationDecoder()); | |
130 deserializer.plugins.add(compiler.backend.serialization.deserializer); | |
131 compiler.serialization.deserializer = | |
132 new _DeserializerSystem( | |
133 compiler, | |
134 deserializer, | |
135 compiler.backend.impactTransformer); | |
136 } | |
137 | |
138 | |
139 const String WORLD_IMPACT_TAG = 'worldImpact'; | |
140 | |
141 class ResolutionImpactSerializer extends SerializerPlugin { | |
142 final Resolution resolution; | |
143 final SerializerPlugin nativeDataSerializer; | |
144 | |
145 ResolutionImpactSerializer(this.resolution, this.nativeDataSerializer); | |
146 | |
147 @override | |
148 void onElement(Element element, ObjectEncoder createEncoder(String tag)) { | |
149 if (resolution.hasBeenResolved(element)) { | |
150 ResolutionImpact impact = resolution.getResolutionImpact(element); | |
151 ObjectEncoder encoder = createEncoder(WORLD_IMPACT_TAG); | |
152 new ImpactSerializer(element, encoder, nativeDataSerializer) | |
153 .serialize(impact); | |
154 } | |
155 } | |
156 } | |
157 | |
158 class ResolutionImpactDeserializer extends DeserializerPlugin { | |
159 Map<Element, ResolutionImpact> impactMap = <Element, ResolutionImpact>{}; | |
160 final DeserializerPlugin nativeDataDeserializer; | |
161 | |
162 ResolutionImpactDeserializer(this.nativeDataDeserializer); | |
163 | |
164 @override | |
165 void onElement(Element element, ObjectDecoder getDecoder(String tag)) { | |
166 ObjectDecoder decoder = getDecoder(WORLD_IMPACT_TAG); | |
167 if (decoder != null) { | |
168 impactMap[element] = | |
169 ImpactDeserializer.deserializeImpact( | |
170 element, decoder, nativeDataDeserializer); | |
171 } | |
172 } | |
173 } | |
174 | |
175 class _DeserializerSystem extends DeserializerSystem { | |
176 final Compiler _compiler; | 30 final Compiler _compiler; |
177 final Deserializer _deserializer; | 31 final Deserializer _deserializer; |
178 final List<LibraryElement> deserializedLibraries = <LibraryElement>[]; | 32 final List<LibraryElement> deserializedLibraries = <LibraryElement>[]; |
179 final ResolutionImpactDeserializer _resolutionImpactDeserializer; | 33 final ResolutionImpactDeserializer _resolutionImpactDeserializer; |
180 final ResolvedAstDeserializerPlugin _resolvedAstDeserializer; | 34 final ResolvedAstDeserializerPlugin _resolvedAstDeserializer; |
181 final ImpactTransformer _impactTransformer; | 35 final ImpactTransformer _impactTransformer; |
182 | 36 |
183 factory _DeserializerSystem( | 37 factory DeserializerSystemImpl(Compiler compiler, Deserializer deserializer, |
184 Compiler compiler, | |
185 Deserializer deserializer, | |
186 ImpactTransformer impactTransformer) { | 38 ImpactTransformer impactTransformer) { |
187 List<DeserializerPlugin> plugins = <DeserializerPlugin>[]; | 39 List<DeserializerPlugin> plugins = <DeserializerPlugin>[]; |
188 DeserializerPlugin backendDeserializer = | 40 DeserializerPlugin backendDeserializer = |
189 compiler.backend.serialization.deserializer; | 41 compiler.backend.serialization.deserializer; |
190 deserializer.plugins.add(backendDeserializer); | 42 deserializer.plugins.add(backendDeserializer); |
191 ResolutionImpactDeserializer resolutionImpactDeserializer = | 43 ResolutionImpactDeserializer resolutionImpactDeserializer = |
192 new ResolutionImpactDeserializer(backendDeserializer); | 44 new ResolutionImpactDeserializer(backendDeserializer); |
193 deserializer.plugins.add(resolutionImpactDeserializer); | 45 deserializer.plugins.add(resolutionImpactDeserializer); |
194 ResolvedAstDeserializerPlugin resolvedAstDeserializer | 46 ResolvedAstDeserializerPlugin resolvedAstDeserializer = |
195 = new ResolvedAstDeserializerPlugin( | 47 new ResolvedAstDeserializerPlugin( |
196 compiler.parsingContext, backendDeserializer); | 48 compiler.parsingContext, backendDeserializer); |
197 deserializer.plugins.add(resolvedAstDeserializer); | 49 deserializer.plugins.add(resolvedAstDeserializer); |
198 return new _DeserializerSystem._( | 50 return new DeserializerSystemImpl._( |
199 compiler, | 51 compiler, |
200 deserializer, | 52 deserializer, |
201 impactTransformer, | 53 impactTransformer, |
202 resolutionImpactDeserializer, | 54 resolutionImpactDeserializer, |
203 resolvedAstDeserializer); | 55 resolvedAstDeserializer); |
204 } | 56 } |
205 | 57 |
206 _DeserializerSystem._( | 58 DeserializerSystemImpl._( |
207 this._compiler, | 59 this._compiler, |
208 this._deserializer, | 60 this._deserializer, |
209 this._impactTransformer, | 61 this._impactTransformer, |
210 this._resolutionImpactDeserializer, | 62 this._resolutionImpactDeserializer, |
211 this._resolvedAstDeserializer); | 63 this._resolvedAstDeserializer); |
212 | 64 |
213 | |
214 @override | 65 @override |
215 Future<LibraryElement> readLibrary(Uri resolvedUri) { | 66 Future<LibraryElement> readLibrary(Uri resolvedUri) { |
216 LibraryElement library = _deserializer.lookupLibrary(resolvedUri); | 67 LibraryElement library = _deserializer.lookupLibrary(resolvedUri); |
217 if (library != null) { | 68 if (library != null) { |
218 deserializedLibraries.add(library); | 69 deserializedLibraries.add(library); |
219 return Future.forEach(library.compilationUnits, | 70 return Future.forEach(library.compilationUnits, |
220 (CompilationUnitElement compilationUnit) { | 71 (CompilationUnitElement compilationUnit) { |
221 ScriptZ script = compilationUnit.script; | 72 ScriptZ script = compilationUnit.script; |
222 return _compiler.readScript(script.readableUri) | 73 return _compiler |
| 74 .readScript(script.readableUri) |
223 .then((Script newScript) { | 75 .then((Script newScript) { |
224 script.file = newScript.file; | 76 script.file = newScript.file; |
225 _resolvedAstDeserializer.sourceFiles[script.resourceUri] = | 77 _resolvedAstDeserializer.sourceFiles[script.resourceUri] = |
226 newScript.file; | 78 newScript.file; |
227 }); | 79 }); |
228 }).then((_) => library); | 80 }).then((_) => library); |
229 } | 81 } |
230 return new Future<LibraryElement>.value(library); | 82 return new Future<LibraryElement>.value(library); |
231 } | 83 } |
232 | 84 |
233 // TODO(johnniwinther): Remove the need for this method. | 85 // TODO(johnniwinther): Remove the need for this method. |
234 @override | 86 @override |
235 bool hasResolvedAst(ExecutableElement element) { | 87 bool hasResolvedAst(ExecutableElement element) { |
236 return getResolvedAst(element) != null; | 88 return getResolvedAst(element) != null; |
237 } | 89 } |
238 | 90 |
239 @override | 91 @override |
240 ResolvedAst getResolvedAst(ExecutableElement element) { | 92 ResolvedAst getResolvedAst(ExecutableElement element) { |
241 return _resolvedAstDeserializer.getResolvedAst(element); | 93 return _resolvedAstDeserializer.getResolvedAst(element); |
242 } | 94 } |
243 | 95 |
244 @override | 96 @override |
245 bool hasResolutionImpact(Element element) { | 97 bool hasResolutionImpact(Element element) { |
246 if (element.isConstructor && | 98 if (element.isConstructor && |
247 element.enclosingClass.isUnnamedMixinApplication) { | 99 element.enclosingClass.isUnnamedMixinApplication) { |
248 return true; | 100 return true; |
249 } | 101 } |
250 return _resolutionImpactDeserializer.impactMap.containsKey(element); | 102 return _resolutionImpactDeserializer.impactMap.containsKey(element); |
251 } | 103 } |
252 | 104 |
253 @override | 105 @override |
254 ResolutionImpact getResolutionImpact(Element element) { | 106 ResolutionImpact getResolutionImpact(Element element) { |
255 if (element.isConstructor && | 107 if (element.isConstructor && |
256 element.enclosingClass.isUnnamedMixinApplication) { | 108 element.enclosingClass.isUnnamedMixinApplication) { |
257 ClassElement superclass = element.enclosingClass.superclass; | 109 ClassElement superclass = element.enclosingClass.superclass; |
258 ConstructorElement superclassConstructor = | 110 ConstructorElement superclassConstructor = |
259 superclass.lookupConstructor(element.name); | 111 superclass.lookupConstructor(element.name); |
260 assert(invariant(element, superclassConstructor != null, | 112 assert(invariant(element, superclassConstructor != null, |
261 message: "Superclass constructor '${element.name}' called from " | 113 message: "Superclass constructor '${element.name}' called from " |
262 "${element} not found in ${superclass}.")); | 114 "${element} not found in ${superclass}.")); |
263 // TODO(johnniwinther): Compute callStructure. Currently not used. | 115 // TODO(johnniwinther): Compute callStructure. Currently not used. |
264 CallStructure callStructure; | 116 CallStructure callStructure; |
265 return _resolutionImpactDeserializer.impactMap.putIfAbsent(element, () { | 117 return _resolutionImpactDeserializer.impactMap.putIfAbsent(element, () { |
266 return new DeserializedResolutionImpact( | 118 return new DeserializedResolutionImpact(staticUses: <StaticUse>[ |
267 staticUses: <StaticUse>[new StaticUse.superConstructorInvoke( | 119 new StaticUse.superConstructorInvoke( |
268 superclassConstructor, callStructure)]); | 120 superclassConstructor, callStructure) |
| 121 ]); |
269 }); | 122 }); |
270 } | 123 } |
271 return _resolutionImpactDeserializer.impactMap[element]; | 124 return _resolutionImpactDeserializer.impactMap[element]; |
272 } | 125 } |
273 | 126 |
274 @override | 127 @override |
275 WorldImpact computeWorldImpact(Element element) { | 128 WorldImpact computeWorldImpact(Element element) { |
276 ResolutionImpact resolutionImpact = getResolutionImpact(element); | 129 ResolutionImpact resolutionImpact = getResolutionImpact(element); |
277 assert(invariant(element, resolutionImpact != null, | 130 assert(invariant(element, resolutionImpact != null, |
278 message: 'No impact found for $element (${element.library})')); | 131 message: 'No impact found for $element (${element.library})')); |
279 if (element is ExecutableElement) { | 132 if (element is ExecutableElement) { |
280 getResolvedAst(element); | 133 getResolvedAst(element); |
281 } | 134 } |
282 return _impactTransformer.transformResolutionImpact(resolutionImpact); | 135 return _impactTransformer.transformResolutionImpact(resolutionImpact); |
283 } | 136 } |
284 | 137 |
285 @override | 138 @override |
286 bool isDeserialized(Element element) { | 139 bool isDeserialized(Element element) { |
287 return deserializedLibraries.contains(element.library); | 140 return deserializedLibraries.contains(element.library); |
288 } | 141 } |
289 } | 142 } |
290 | 143 |
| 144 const String WORLD_IMPACT_TAG = 'worldImpact'; |
| 145 |
| 146 class ResolutionImpactSerializer extends SerializerPlugin { |
| 147 final Resolution resolution; |
| 148 final SerializerPlugin nativeDataSerializer; |
| 149 |
| 150 ResolutionImpactSerializer(this.resolution, this.nativeDataSerializer); |
| 151 |
| 152 @override |
| 153 void onElement(Element element, ObjectEncoder createEncoder(String tag)) { |
| 154 if (resolution.hasBeenResolved(element)) { |
| 155 ResolutionImpact impact = resolution.getResolutionImpact(element); |
| 156 ObjectEncoder encoder = createEncoder(WORLD_IMPACT_TAG); |
| 157 new ImpactSerializer(element, encoder, nativeDataSerializer) |
| 158 .serialize(impact); |
| 159 } |
| 160 } |
| 161 } |
| 162 |
| 163 class ResolutionImpactDeserializer extends DeserializerPlugin { |
| 164 Map<Element, ResolutionImpact> impactMap = <Element, ResolutionImpact>{}; |
| 165 final DeserializerPlugin nativeDataDeserializer; |
| 166 |
| 167 ResolutionImpactDeserializer(this.nativeDataDeserializer); |
| 168 |
| 169 @override |
| 170 void onElement(Element element, ObjectDecoder getDecoder(String tag)) { |
| 171 ObjectDecoder decoder = getDecoder(WORLD_IMPACT_TAG); |
| 172 if (decoder != null) { |
| 173 impactMap[element] = ImpactDeserializer.deserializeImpact( |
| 174 element, decoder, nativeDataDeserializer); |
| 175 } |
| 176 } |
| 177 } |
| 178 |
291 const String RESOLVED_AST_TAG = 'resolvedAst'; | 179 const String RESOLVED_AST_TAG = 'resolvedAst'; |
292 | 180 |
293 class ResolvedAstSerializerPlugin extends SerializerPlugin { | 181 class ResolvedAstSerializerPlugin extends SerializerPlugin { |
294 final Resolution resolution; | 182 final Resolution resolution; |
295 final SerializerPlugin nativeDataSerializer; | 183 final SerializerPlugin nativeDataSerializer; |
296 | 184 |
297 ResolvedAstSerializerPlugin(this.resolution, this.nativeDataSerializer); | 185 ResolvedAstSerializerPlugin(this.resolution, this.nativeDataSerializer); |
298 | 186 |
299 @override | 187 @override |
300 void onElement(Element element, ObjectEncoder createEncoder(String tag)) { | 188 void onElement(Element element, ObjectEncoder createEncoder(String tag)) { |
301 assert(invariant(element, element.isDeclaration, | 189 assert(invariant(element, element.isDeclaration, |
302 message: "Element $element must be the declaration")); | 190 message: "Element $element must be the declaration")); |
303 if (element is MemberElement) { | 191 if (element is MemberElement) { |
304 assert(invariant(element, resolution.hasResolvedAst(element), | 192 assert(invariant(element, resolution.hasResolvedAst(element), |
305 message: "Element $element must have a resolved ast")); | 193 message: "Element $element must have a resolved ast")); |
306 ResolvedAst resolvedAst = resolution.getResolvedAst(element); | 194 ResolvedAst resolvedAst = resolution.getResolvedAst(element); |
307 ObjectEncoder objectEncoder = createEncoder(RESOLVED_AST_TAG); | 195 ObjectEncoder objectEncoder = createEncoder(RESOLVED_AST_TAG); |
308 new ResolvedAstSerializer( | 196 new ResolvedAstSerializer( |
309 objectEncoder, | 197 objectEncoder, resolvedAst, nativeDataSerializer) |
310 resolvedAst, | 198 .serialize(); |
311 nativeDataSerializer).serialize(); | |
312 } | 199 } |
313 } | 200 } |
314 } | 201 } |
315 | 202 |
316 class ResolvedAstDeserializerPlugin extends DeserializerPlugin { | 203 class ResolvedAstDeserializerPlugin extends DeserializerPlugin { |
317 final ParsingContext parsingContext; | 204 final ParsingContext parsingContext; |
318 final DeserializerPlugin nativeDataDeserializer; | 205 final DeserializerPlugin nativeDataDeserializer; |
319 final Map<Uri, SourceFile> sourceFiles = <Uri, SourceFile>{}; | 206 final Map<Uri, SourceFile> sourceFiles = <Uri, SourceFile>{}; |
320 | 207 |
321 Map<MemberElement, ObjectDecoder> _decoderMap = | 208 Map<MemberElement, ObjectDecoder> _decoderMap = |
322 <MemberElement, ObjectDecoder>{}; | 209 <MemberElement, ObjectDecoder>{}; |
323 Map<Uri, Token> beginTokenMap = <Uri, Token>{}; | 210 Map<Uri, Token> beginTokenMap = <Uri, Token>{}; |
324 | 211 |
325 ResolvedAstDeserializerPlugin( | 212 ResolvedAstDeserializerPlugin( |
326 this.parsingContext, this.nativeDataDeserializer); | 213 this.parsingContext, this.nativeDataDeserializer); |
327 | 214 |
328 bool hasResolvedAst(ExecutableElement element) { | 215 bool hasResolvedAst(ExecutableElement element) { |
329 return getResolvedAst(element) != null; | 216 return getResolvedAst(element) != null; |
330 } | 217 } |
331 | 218 |
332 ResolvedAst getResolvedAst(ExecutableElement element) { | 219 ResolvedAst getResolvedAst(ExecutableElement element) { |
333 if (element.hasResolvedAst) { | 220 if (element.hasResolvedAst) { |
334 return element.resolvedAst; | 221 return element.resolvedAst; |
335 } | 222 } |
336 | 223 |
337 ObjectDecoder decoder = _decoderMap[element.memberContext]; | 224 ObjectDecoder decoder = _decoderMap[element.memberContext]; |
338 if (decoder != null) { | 225 if (decoder != null) { |
339 ResolvedAstDeserializer.deserialize( | 226 ResolvedAstDeserializer.deserialize(element.memberContext, decoder, |
340 element.memberContext, decoder, parsingContext, findToken, | 227 parsingContext, findToken, nativeDataDeserializer); |
341 nativeDataDeserializer); | |
342 _decoderMap.remove(element); | 228 _decoderMap.remove(element); |
343 assert(invariant(element, element.hasResolvedAst, | 229 assert(invariant(element, element.hasResolvedAst, |
344 message: "ResolvedAst not computed for $element.")); | 230 message: "ResolvedAst not computed for $element.")); |
345 return element.resolvedAst; | 231 return element.resolvedAst; |
346 } | 232 } |
347 return null; | 233 return null; |
348 } | 234 } |
349 | 235 |
350 Token findToken(Uri uri, int offset) { | 236 Token findToken(Uri uri, int offset) { |
351 Token beginToken = beginTokenMap.putIfAbsent(uri, () { | 237 Token beginToken = beginTokenMap.putIfAbsent(uri, () { |
352 SourceFile sourceFile = sourceFiles[uri]; | 238 SourceFile sourceFile = sourceFiles[uri]; |
353 if (sourceFile == null) { | 239 if (sourceFile == null) { |
354 throw 'No source file found for $uri in:\n ' | 240 throw 'No source file found for $uri in:\n ' |
355 '${sourceFiles.keys.join('\n ')}'; | 241 '${sourceFiles.keys.join('\n ')}'; |
356 } | 242 } |
357 return new Scanner(sourceFile).tokenize(); | 243 return new Scanner(sourceFile).tokenize(); |
358 }); | 244 }); |
359 return ResolvedAstDeserializer.findTokenInStream(beginToken, offset); | 245 return ResolvedAstDeserializer.findTokenInStream(beginToken, offset); |
360 } | 246 } |
361 | 247 |
362 @override | 248 @override |
363 void onElement(Element element, ObjectDecoder getDecoder(String tag)) { | 249 void onElement(Element element, ObjectDecoder getDecoder(String tag)) { |
364 ObjectDecoder decoder = getDecoder(RESOLVED_AST_TAG); | 250 ObjectDecoder decoder = getDecoder(RESOLVED_AST_TAG); |
365 if (decoder != null) { | 251 if (decoder != null) { |
366 _decoderMap[element] = decoder; | 252 _decoderMap[element] = decoder; |
367 } | 253 } |
368 } | 254 } |
369 } | 255 } |
370 | |
OLD | NEW |