| 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_helper; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 import 'dart:io'; | 8 import 'dart:io'; |
| 9 | 9 |
| 10 import 'package:compiler/src/commandline_options.dart'; | 10 import 'package:compiler/src/commandline_options.dart'; |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 96 return serializedData; | 96 return serializedData; |
| 97 } | 97 } |
| 98 | 98 |
| 99 Serializer serialize( | 99 Serializer serialize( |
| 100 Compiler compiler, | 100 Compiler compiler, |
| 101 Iterable<LibraryElement> libraries, | 101 Iterable<LibraryElement> libraries, |
| 102 {bool serializeResolvedAst: false}) { | 102 {bool serializeResolvedAst: false}) { |
| 103 assert(compiler.serialization.supportSerialization); | 103 assert(compiler.serialization.supportSerialization); |
| 104 | 104 |
| 105 Serializer serializer = new Serializer(); | 105 Serializer serializer = new Serializer(); |
| 106 serializer.plugins.add(compiler.backend.serialization.serializer); | 106 SerializerPlugin backendSerializer = |
| 107 serializer.plugins.add(new ResolutionImpactSerializer(compiler.resolution)); | 107 compiler.backend.serialization.serializer; |
| 108 serializer.plugins.add(backendSerializer); |
| 109 serializer.plugins.add(new ResolutionImpactSerializer( |
| 110 compiler.resolution, backendSerializer)); |
| 108 if (serializeResolvedAst) { | 111 if (serializeResolvedAst) { |
| 109 serializer.plugins.add( | 112 serializer.plugins.add(new ResolvedAstSerializerPlugin( |
| 110 new ResolvedAstSerializerPlugin(compiler.resolution, compiler.backend)); | 113 compiler.resolution, backendSerializer)); |
| 111 } | 114 } |
| 112 | 115 |
| 113 for (LibraryElement library in libraries) { | 116 for (LibraryElement library in libraries) { |
| 114 serializer.serialize(library); | 117 serializer.serialize(library); |
| 115 } | 118 } |
| 116 return serializer; | 119 return serializer; |
| 117 } | 120 } |
| 118 | 121 |
| 119 void deserialize(Compiler compiler, | 122 void deserialize(Compiler compiler, |
| 120 String serializedData, | 123 String serializedData, |
| 121 {bool deserializeResolvedAst: false}) { | 124 {bool deserializeResolvedAst: false}) { |
| 122 Deserializer deserializer = new Deserializer.fromText( | 125 Deserializer deserializer = new Deserializer.fromText( |
| 123 new DeserializationContext(), | 126 new DeserializationContext(), |
| 124 serializedData, | 127 serializedData, |
| 125 const JsonSerializationDecoder()); | 128 const JsonSerializationDecoder()); |
| 126 deserializer.plugins.add(compiler.backend.serialization.deserializer); | 129 deserializer.plugins.add(compiler.backend.serialization.deserializer); |
| 127 compiler.serialization.deserializer = | 130 compiler.serialization.deserializer = |
| 128 new _DeserializerSystem( | 131 new _DeserializerSystem( |
| 129 compiler, | 132 compiler, |
| 130 deserializer, | 133 deserializer, |
| 131 compiler.backend.impactTransformer, | 134 compiler.backend.impactTransformer, |
| 132 deserializeResolvedAst: deserializeResolvedAst); | 135 deserializeResolvedAst: deserializeResolvedAst); |
| 133 } | 136 } |
| 134 | 137 |
| 135 | 138 |
| 136 const String WORLD_IMPACT_TAG = 'worldImpact'; | 139 const String WORLD_IMPACT_TAG = 'worldImpact'; |
| 137 | 140 |
| 138 class ResolutionImpactSerializer extends SerializerPlugin { | 141 class ResolutionImpactSerializer extends SerializerPlugin { |
| 139 final Resolution resolution; | 142 final Resolution resolution; |
| 143 final SerializerPlugin nativeDataSerializer; |
| 140 | 144 |
| 141 ResolutionImpactSerializer(this.resolution); | 145 ResolutionImpactSerializer(this.resolution, this.nativeDataSerializer); |
| 142 | 146 |
| 143 @override | 147 @override |
| 144 void onElement(Element element, ObjectEncoder createEncoder(String tag)) { | 148 void onElement(Element element, ObjectEncoder createEncoder(String tag)) { |
| 145 if (resolution.hasBeenResolved(element)) { | 149 if (resolution.hasBeenResolved(element)) { |
| 146 ResolutionImpact impact = resolution.getResolutionImpact(element); | 150 ResolutionImpact impact = resolution.getResolutionImpact(element); |
| 147 ObjectEncoder encoder = createEncoder(WORLD_IMPACT_TAG); | 151 ObjectEncoder encoder = createEncoder(WORLD_IMPACT_TAG); |
| 148 new ImpactSerializer(element, encoder).serialize(impact); | 152 new ImpactSerializer(element, encoder, nativeDataSerializer) |
| 153 .serialize(impact); |
| 149 } | 154 } |
| 150 } | 155 } |
| 151 } | 156 } |
| 152 | 157 |
| 153 class ResolutionImpactDeserializer extends DeserializerPlugin { | 158 class ResolutionImpactDeserializer extends DeserializerPlugin { |
| 154 Map<Element, ResolutionImpact> impactMap = <Element, ResolutionImpact>{}; | 159 Map<Element, ResolutionImpact> impactMap = <Element, ResolutionImpact>{}; |
| 160 final DeserializerPlugin nativeDataDeserializer; |
| 161 |
| 162 ResolutionImpactDeserializer(this.nativeDataDeserializer); |
| 155 | 163 |
| 156 @override | 164 @override |
| 157 void onElement(Element element, ObjectDecoder getDecoder(String tag)) { | 165 void onElement(Element element, ObjectDecoder getDecoder(String tag)) { |
| 158 ObjectDecoder decoder = getDecoder(WORLD_IMPACT_TAG); | 166 ObjectDecoder decoder = getDecoder(WORLD_IMPACT_TAG); |
| 159 if (decoder != null) { | 167 if (decoder != null) { |
| 160 impactMap[element] = | 168 impactMap[element] = |
| 161 ImpactDeserializer.deserializeImpact(element, decoder); | 169 ImpactDeserializer.deserializeImpact( |
| 170 element, decoder, nativeDataDeserializer); |
| 162 } | 171 } |
| 163 } | 172 } |
| 164 } | 173 } |
| 165 | 174 |
| 166 class _DeserializerSystem extends DeserializerSystem { | 175 class _DeserializerSystem extends DeserializerSystem { |
| 167 final Compiler _compiler; | 176 final Compiler _compiler; |
| 168 final Deserializer _deserializer; | 177 final Deserializer _deserializer; |
| 169 final List<LibraryElement> deserializedLibraries = <LibraryElement>[]; | 178 final List<LibraryElement> deserializedLibraries = <LibraryElement>[]; |
| 170 final ResolutionImpactDeserializer _resolutionImpactDeserializer = | 179 final ResolutionImpactDeserializer _resolutionImpactDeserializer; |
| 171 new ResolutionImpactDeserializer(); | |
| 172 final ResolvedAstDeserializerPlugin _resolvedAstDeserializer; | 180 final ResolvedAstDeserializerPlugin _resolvedAstDeserializer; |
| 173 final ImpactTransformer _impactTransformer; | 181 final ImpactTransformer _impactTransformer; |
| 174 final bool _deserializeResolvedAst; | 182 final bool deserializeResolvedAst; |
| 175 | 183 |
| 176 _DeserializerSystem( | 184 factory _DeserializerSystem( |
| 177 Compiler compiler, | 185 Compiler compiler, |
| 186 Deserializer deserializer, |
| 187 ImpactTransformer impactTransformer, |
| 188 {bool deserializeResolvedAst: false}) { |
| 189 List<DeserializerPlugin> plugins = <DeserializerPlugin>[]; |
| 190 DeserializerPlugin backendDeserializer = |
| 191 compiler.backend.serialization.deserializer; |
| 192 deserializer.plugins.add(backendDeserializer); |
| 193 ResolutionImpactDeserializer resolutionImpactDeserializer = |
| 194 new ResolutionImpactDeserializer(backendDeserializer); |
| 195 deserializer.plugins.add(resolutionImpactDeserializer); |
| 196 ResolvedAstDeserializerPlugin resolvedAstDeserializer; |
| 197 if (deserializeResolvedAst) { |
| 198 resolvedAstDeserializer = new ResolvedAstDeserializerPlugin( |
| 199 compiler.parsingContext, backendDeserializer); |
| 200 deserializer.plugins.add(resolvedAstDeserializer); |
| 201 } |
| 202 return new _DeserializerSystem._( |
| 203 compiler, |
| 204 deserializer, |
| 205 impactTransformer, |
| 206 resolutionImpactDeserializer, |
| 207 resolvedAstDeserializer, |
| 208 deserializeResolvedAst: deserializeResolvedAst); |
| 209 } |
| 210 |
| 211 _DeserializerSystem._( |
| 212 this._compiler, |
| 178 this._deserializer, | 213 this._deserializer, |
| 179 this._impactTransformer, | 214 this._impactTransformer, |
| 180 {bool deserializeResolvedAst: false}) | 215 this._resolutionImpactDeserializer, |
| 181 : this._compiler = compiler, | 216 this._resolvedAstDeserializer, |
| 182 this._deserializeResolvedAst = deserializeResolvedAst, | 217 {this.deserializeResolvedAst: false}); |
| 183 this._resolvedAstDeserializer = deserializeResolvedAst | 218 |
| 184 ? new ResolvedAstDeserializerPlugin( | |
| 185 compiler.parsingContext, compiler.backend) : null { | |
| 186 _deserializer.plugins.add(_resolutionImpactDeserializer); | |
| 187 if (_deserializeResolvedAst) { | |
| 188 _deserializer.plugins.add(_resolvedAstDeserializer); | |
| 189 } | |
| 190 } | |
| 191 | 219 |
| 192 @override | 220 @override |
| 193 Future<LibraryElement> readLibrary(Uri resolvedUri) { | 221 Future<LibraryElement> readLibrary(Uri resolvedUri) { |
| 194 LibraryElement library = _deserializer.lookupLibrary(resolvedUri); | 222 LibraryElement library = _deserializer.lookupLibrary(resolvedUri); |
| 195 if (library != null) { | 223 if (library != null) { |
| 196 deserializedLibraries.add(library); | 224 deserializedLibraries.add(library); |
| 197 if (_deserializeResolvedAst) { | 225 if (deserializeResolvedAst) { |
| 198 return Future.forEach(library.compilationUnits, | 226 return Future.forEach(library.compilationUnits, |
| 199 (CompilationUnitElement compilationUnit) { | 227 (CompilationUnitElement compilationUnit) { |
| 200 ScriptZ script = compilationUnit.script; | 228 ScriptZ script = compilationUnit.script; |
| 201 return _compiler.readScript(script.readableUri) | 229 return _compiler.readScript(script.readableUri) |
| 202 .then((Script newScript) { | 230 .then((Script newScript) { |
| 203 script.file = newScript.file; | 231 script.file = newScript.file; |
| 204 _resolvedAstDeserializer.sourceFiles[script.resourceUri] = | 232 _resolvedAstDeserializer.sourceFiles[script.resourceUri] = |
| 205 newScript.file; | 233 newScript.file; |
| 206 }); | 234 }); |
| 207 }).then((_) => library); | 235 }).then((_) => library); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 267 @override | 295 @override |
| 268 bool isDeserialized(Element element) { | 296 bool isDeserialized(Element element) { |
| 269 return deserializedLibraries.contains(element.library); | 297 return deserializedLibraries.contains(element.library); |
| 270 } | 298 } |
| 271 } | 299 } |
| 272 | 300 |
| 273 const String RESOLVED_AST_TAG = 'resolvedAst'; | 301 const String RESOLVED_AST_TAG = 'resolvedAst'; |
| 274 | 302 |
| 275 class ResolvedAstSerializerPlugin extends SerializerPlugin { | 303 class ResolvedAstSerializerPlugin extends SerializerPlugin { |
| 276 final Resolution resolution; | 304 final Resolution resolution; |
| 277 final Backend backend; | 305 final SerializerPlugin nativeDataSerializer; |
| 278 | 306 |
| 279 ResolvedAstSerializerPlugin(this.resolution, this.backend); | 307 ResolvedAstSerializerPlugin(this.resolution, this.nativeDataSerializer); |
| 280 | 308 |
| 281 @override | 309 @override |
| 282 void onElement(Element element, ObjectEncoder createEncoder(String tag)) { | 310 void onElement(Element element, ObjectEncoder createEncoder(String tag)) { |
| 283 assert(invariant(element, element.isDeclaration, | 311 assert(invariant(element, element.isDeclaration, |
| 284 message: "Element $element must be the declaration")); | 312 message: "Element $element must be the declaration")); |
| 285 if (element is MemberElement) { | 313 if (element is MemberElement) { |
| 286 assert(invariant(element, resolution.hasResolvedAst(element), | 314 assert(invariant(element, resolution.hasResolvedAst(element), |
| 287 message: "Element $element must have a resolved ast")); | 315 message: "Element $element must have a resolved ast")); |
| 288 ResolvedAst resolvedAst = resolution.getResolvedAst(element); | 316 ResolvedAst resolvedAst = resolution.getResolvedAst(element); |
| 289 ObjectEncoder objectEncoder = createEncoder(RESOLVED_AST_TAG); | 317 ObjectEncoder objectEncoder = createEncoder(RESOLVED_AST_TAG); |
| 290 new ResolvedAstSerializer( | 318 new ResolvedAstSerializer( |
| 291 objectEncoder, | 319 objectEncoder, |
| 292 resolvedAst, | 320 resolvedAst, |
| 293 backend.serialization.serializer).serialize(); | 321 nativeDataSerializer).serialize(); |
| 294 } | 322 } |
| 295 } | 323 } |
| 296 } | 324 } |
| 297 | 325 |
| 298 class ResolvedAstDeserializerPlugin extends DeserializerPlugin { | 326 class ResolvedAstDeserializerPlugin extends DeserializerPlugin { |
| 299 final ParsingContext parsingContext; | 327 final ParsingContext parsingContext; |
| 300 final Backend backend; | 328 final DeserializerPlugin nativeDataDeserializer; |
| 301 final Map<Uri, SourceFile> sourceFiles = <Uri, SourceFile>{}; | 329 final Map<Uri, SourceFile> sourceFiles = <Uri, SourceFile>{}; |
| 302 | 330 |
| 303 Map<ExecutableElement, ResolvedAst> _resolvedAstMap = | 331 Map<ExecutableElement, ResolvedAst> _resolvedAstMap = |
| 304 <ExecutableElement, ResolvedAst>{}; | 332 <ExecutableElement, ResolvedAst>{}; |
| 305 Map<MemberElement, ObjectDecoder> _decoderMap = | 333 Map<MemberElement, ObjectDecoder> _decoderMap = |
| 306 <MemberElement, ObjectDecoder>{}; | 334 <MemberElement, ObjectDecoder>{}; |
| 307 Map<Uri, Token> beginTokenMap = <Uri, Token>{}; | 335 Map<Uri, Token> beginTokenMap = <Uri, Token>{}; |
| 308 | 336 |
| 309 ResolvedAstDeserializerPlugin(this.parsingContext, this.backend); | 337 ResolvedAstDeserializerPlugin( |
| 338 this.parsingContext, this.nativeDataDeserializer); |
| 310 | 339 |
| 311 bool hasResolvedAst(ExecutableElement element) { | 340 bool hasResolvedAst(ExecutableElement element) { |
| 312 return _resolvedAstMap.containsKey(element) || | 341 return _resolvedAstMap.containsKey(element) || |
| 313 _decoderMap.containsKey(element.memberContext); | 342 _decoderMap.containsKey(element.memberContext); |
| 314 } | 343 } |
| 315 | 344 |
| 316 ResolvedAst getResolvedAst(ExecutableElement element) { | 345 ResolvedAst getResolvedAst(ExecutableElement element) { |
| 317 ResolvedAst resolvedAst = _resolvedAstMap[element]; | 346 ResolvedAst resolvedAst = _resolvedAstMap[element]; |
| 318 if (resolvedAst == null) { | 347 if (resolvedAst == null) { |
| 319 ObjectDecoder decoder = _decoderMap[element.memberContext]; | 348 ObjectDecoder decoder = _decoderMap[element.memberContext]; |
| 320 if (decoder != null) { | 349 if (decoder != null) { |
| 321 ResolvedAstDeserializer.deserialize( | 350 ResolvedAstDeserializer.deserialize( |
| 322 element.memberContext, decoder, parsingContext, findToken, | 351 element.memberContext, decoder, parsingContext, findToken, |
| 323 backend.serialization.deserializer, | 352 nativeDataDeserializer, |
| 324 _resolvedAstMap); | 353 _resolvedAstMap); |
| 325 _decoderMap.remove(element); | 354 _decoderMap.remove(element); |
| 326 resolvedAst = _resolvedAstMap[element]; | 355 resolvedAst = _resolvedAstMap[element]; |
| 327 } | 356 } |
| 328 } | 357 } |
| 329 return resolvedAst; | 358 return resolvedAst; |
| 330 } | 359 } |
| 331 | 360 |
| 332 Token findToken(Uri uri, int offset) { | 361 Token findToken(Uri uri, int offset) { |
| 333 Token beginToken = beginTokenMap.putIfAbsent(uri, () { | 362 Token beginToken = beginTokenMap.putIfAbsent(uri, () { |
| 334 SourceFile sourceFile = sourceFiles[uri]; | 363 SourceFile sourceFile = sourceFiles[uri]; |
| 335 if (sourceFile == null) { | 364 if (sourceFile == null) { |
| 336 throw 'No source file found for $uri in:\n ' | 365 throw 'No source file found for $uri in:\n ' |
| 337 '${sourceFiles.keys.join('\n ')}'; | 366 '${sourceFiles.keys.join('\n ')}'; |
| 338 } | 367 } |
| 339 return new Scanner(sourceFile).tokenize(); | 368 return new Scanner(sourceFile).tokenize(); |
| 340 }); | 369 }); |
| 341 return ResolvedAstDeserializer.findTokenInStream(beginToken, offset); | 370 return ResolvedAstDeserializer.findTokenInStream(beginToken, offset); |
| 342 } | 371 } |
| 343 | 372 |
| 344 @override | 373 @override |
| 345 void onElement(Element element, ObjectDecoder getDecoder(String tag)) { | 374 void onElement(Element element, ObjectDecoder getDecoder(String tag)) { |
| 346 ObjectDecoder decoder = getDecoder(RESOLVED_AST_TAG); | 375 ObjectDecoder decoder = getDecoder(RESOLVED_AST_TAG); |
| 347 if (decoder != null) { | 376 if (decoder != null) { |
| 348 _decoderMap[element] = decoder; | 377 _decoderMap[element] = decoder; |
| 349 } | 378 } |
| 350 } | 379 } |
| 351 } | 380 } |
| 352 | 381 |
| OLD | NEW |