| OLD | NEW |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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_analysis_test; | 5 library dart2js.serialization_analysis_test; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 import 'package:async_helper/async_helper.dart'; | 8 import 'package:async_helper/async_helper.dart'; |
| 9 import 'package:expect/expect.dart'; | 9 import 'package:expect/expect.dart'; |
| 10 import 'package:compiler/src/commandline_options.dart'; | 10 import 'package:compiler/src/commandline_options.dart'; |
| 11 import 'package:compiler/src/common/names.dart'; |
| 12 import 'package:compiler/src/common/resolution.dart'; |
| 13 import 'package:compiler/src/compiler.dart'; |
| 11 import 'package:compiler/src/elements/elements.dart'; | 14 import 'package:compiler/src/elements/elements.dart'; |
| 12 import 'package:compiler/src/compiler.dart'; | |
| 13 import 'package:compiler/src/filenames.dart'; | 15 import 'package:compiler/src/filenames.dart'; |
| 16 import 'package:compiler/src/serialization/element_serialization.dart'; |
| 17 import 'package:compiler/src/serialization/impact_serialization.dart'; |
| 18 import 'package:compiler/src/serialization/json_serializer.dart'; |
| 14 import 'package:compiler/src/serialization/serialization.dart'; | 19 import 'package:compiler/src/serialization/serialization.dart'; |
| 15 import 'package:compiler/src/serialization/json_serializer.dart'; | |
| 16 import 'package:compiler/src/serialization/task.dart'; | 20 import 'package:compiler/src/serialization/task.dart'; |
| 17 import 'package:compiler/src/universe/world_impact.dart'; | 21 import 'package:compiler/src/universe/world_impact.dart'; |
| 18 import 'memory_compiler.dart'; | 22 import 'memory_compiler.dart'; |
| 19 | 23 |
| 20 const List<Test> TESTS = const <Test>[ | 24 const List<Test> TESTS = const <Test>[ |
| 21 const Test(const { | 25 const Test(const { |
| 22 'main.dart': 'main() => print("Hello World");' | 26 'main.dart': 'main() => print("Hello World");' |
| 23 }), | 27 }), |
| 24 | 28 |
| 25 const Test(const { | 29 const Test(const { |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 135 'main.dart': r''' | 139 'main.dart': r''' |
| 136 class Class implements Comparable { | 140 class Class implements Comparable { |
| 137 bool compareTo(a, b) => true; | 141 bool compareTo(a, b) => true; |
| 138 } | 142 } |
| 139 main() { | 143 main() { |
| 140 print(new Class().compareTo(null, null)); | 144 print(new Class().compareTo(null, null)); |
| 141 }''' | 145 }''' |
| 142 }, | 146 }, |
| 143 expectedWarningCount: 1, | 147 expectedWarningCount: 1, |
| 144 expectedInfoCount: 1), | 148 expectedInfoCount: 1), |
| 149 |
| 150 const Test(const { |
| 151 'main.dart': r''' |
| 152 import 'dart:math'; |
| 153 |
| 154 class MyRandom implements Random { |
| 155 int nextInt(int max) { |
| 156 return max.length; |
| 157 } |
| 158 bool nextBool() => true; |
| 159 double nextDouble() => 0.0; |
| 160 } |
| 161 main() { |
| 162 new MyRandom().nextInt(0); |
| 163 }''' |
| 164 }, |
| 165 expectedWarningCount: 1, |
| 166 expectedInfoCount: 0), |
| 167 |
| 168 const Test(const { |
| 169 'main.dart': r''' |
| 170 import 'dart:math'; |
| 171 |
| 172 class MyRandom implements Random { |
| 173 int nextInt(int max) { |
| 174 return max.length; |
| 175 } |
| 176 bool nextBool() => true; |
| 177 double nextDouble() => 0.0; |
| 178 } |
| 179 main() { |
| 180 new MyRandom(); |
| 181 }''' |
| 182 }), |
| 183 |
| 184 const Test(const { |
| 185 'main.dart': r''' |
| 186 import 'dart:math'; |
| 187 |
| 188 class MyRandom implements Random { |
| 189 int nextInt(int max) { |
| 190 return max.length; |
| 191 } |
| 192 bool nextBool() => true; |
| 193 double nextDouble() => 0.0; |
| 194 } |
| 195 main() { |
| 196 // Invocation of `MyRandom.nextInt` is only detected knowing the actual |
| 197 // implementation class for `List` and the world impact of its `shuffle` |
| 198 // method. |
| 199 [].shuffle(new MyRandom()); |
| 200 }''' |
| 201 }, |
| 202 expectedWarningCount: 1, |
| 203 expectedInfoCount: 0), |
| 145 ]; | 204 ]; |
| 146 | 205 |
| 147 main(List<String> arguments) { | 206 main(List<String> arguments) { |
| 148 asyncTest(() async { | 207 asyncTest(() async { |
| 149 String serializedData = await serializeDartCore(); | 208 String serializedData = await serializeDartCore(); |
| 150 | 209 |
| 151 if (arguments.isNotEmpty) { | 210 if (arguments.isNotEmpty) { |
| 152 Uri entryPoint = Uri.base.resolve(nativeToUriPath(arguments.last)); | 211 Uri entryPoint = Uri.base.resolve(nativeToUriPath(arguments.last)); |
| 153 await analyze(serializedData, entryPoint, null); | 212 await analyze(serializedData, entryPoint, null); |
| 154 } else { | 213 } else { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 168 final int expectedInfoCount; | 227 final int expectedInfoCount; |
| 169 | 228 |
| 170 const Test(this.sourceFiles, { | 229 const Test(this.sourceFiles, { |
| 171 this.expectedErrorCount: 0, | 230 this.expectedErrorCount: 0, |
| 172 this.expectedWarningCount: 0, | 231 this.expectedWarningCount: 0, |
| 173 this.expectedHintCount: 0, | 232 this.expectedHintCount: 0, |
| 174 this.expectedInfoCount: 0}); | 233 this.expectedInfoCount: 0}); |
| 175 } | 234 } |
| 176 | 235 |
| 177 Future analyze(String serializedData, Uri entryPoint, Test test) async { | 236 Future analyze(String serializedData, Uri entryPoint, Test test) async { |
| 178 Deserializer deserializer = new Deserializer.fromText( | |
| 179 serializedData, const JsonSerializationDecoder()); | |
| 180 DiagnosticCollector diagnosticCollector = new DiagnosticCollector(); | 237 DiagnosticCollector diagnosticCollector = new DiagnosticCollector(); |
| 181 await runCompiler( | 238 await runCompiler( |
| 182 entryPoint: entryPoint, | 239 entryPoint: entryPoint, |
| 183 memorySourceFiles: test != null ? test.sourceFiles : const {}, | 240 memorySourceFiles: test != null ? test.sourceFiles : const {}, |
| 184 options: [Flags.analyzeOnly], | 241 options: [Flags.analyzeOnly], |
| 185 diagnosticHandler: diagnosticCollector, | 242 diagnosticHandler: diagnosticCollector, |
| 186 beforeRun: (Compiler compiler) { | 243 beforeRun: (Compiler compiler) { |
| 244 Deserializer deserializer = new Deserializer.fromText( |
| 245 serializedData, |
| 246 const JsonSerializationDecoder()); |
| 247 deserializer.plugins.add(compiler.backend.serialization.deserializer); |
| 187 compiler.serialization.deserializer = | 248 compiler.serialization.deserializer = |
| 188 new _DeserializerSystem(deserializer); | 249 new _DeserializerSystem(deserializer); |
| 189 }); | 250 }); |
| 190 if (test != null) { | 251 if (test != null) { |
| 191 Expect.equals(test.expectedErrorCount, diagnosticCollector.errors.length, | 252 Expect.equals(test.expectedErrorCount, diagnosticCollector.errors.length, |
| 192 "Unexpected error count."); | 253 "Unexpected error count."); |
| 193 Expect.equals( | 254 Expect.equals( |
| 194 test.expectedWarningCount, | 255 test.expectedWarningCount, |
| 195 diagnosticCollector.warnings.length, | 256 diagnosticCollector.warnings.length, |
| 196 "Unexpected warning count."); | 257 "Unexpected warning count."); |
| 197 Expect.equals(test.expectedHintCount, diagnosticCollector.hints.length, | 258 Expect.equals(test.expectedHintCount, diagnosticCollector.hints.length, |
| 198 "Unexpected hint count."); | 259 "Unexpected hint count."); |
| 199 Expect.equals(test.expectedInfoCount, diagnosticCollector.infos.length, | 260 Expect.equals(test.expectedInfoCount, diagnosticCollector.infos.length, |
| 200 "Unexpected info count."); | 261 "Unexpected info count."); |
| 201 } | 262 } |
| 202 } | 263 } |
| 203 | 264 |
| 204 Future<String> serializeDartCore() async { | 265 Future<String> serializeDartCore() async { |
| 205 Compiler compiler = compilerFor( | 266 Compiler compiler = compilerFor( |
| 206 options: ['--analyze-all']); | 267 options: [Flags.analyzeAll]); |
| 207 await compiler.run(Uri.parse('dart:core')); | 268 compiler.serialization.supportSerialization = true; |
| 208 return serialize(compiler.libraryLoader.libraries); | 269 await compiler.run(Uris.dart_core); |
| 270 return serialize(compiler); |
| 209 } | 271 } |
| 210 | 272 |
| 211 String serialize(Iterable<LibraryElement> libraries) { | 273 String serialize(Compiler compiler) { |
| 212 Serializer serializer = new Serializer(const JsonSerializationEncoder()); | 274 Serializer serializer = new Serializer(const JsonSerializationEncoder()); |
| 213 for (LibraryElement library in libraries) { | 275 serializer.plugins.add(compiler.backend.serialization.serializer); |
| 276 serializer.plugins.add(new WorldImpactSerializer(compiler.resolution)); |
| 277 |
| 278 for (LibraryElement library in compiler.libraryLoader.libraries) { |
| 214 serializer.serialize(library); | 279 serializer.serialize(library); |
| 215 } | 280 } |
| 216 return serializer.toText(); | 281 return serializer.toText(); |
| 217 } | 282 } |
| 218 | 283 |
| 284 const String WORLD_IMPACT_TAG = 'worldImpact'; |
| 285 |
| 286 class WorldImpactSerializer extends SerializerPlugin { |
| 287 final Resolution resolution; |
| 288 |
| 289 WorldImpactSerializer(this.resolution); |
| 290 |
| 291 @override |
| 292 void onElement(Element element, ObjectEncoder createEncoder(String tag)) { |
| 293 if (resolution.hasBeenResolved(element)) { |
| 294 WorldImpact impact = resolution.getWorldImpact(element); |
| 295 ObjectEncoder encoder = createEncoder(WORLD_IMPACT_TAG); |
| 296 impact.apply(new ImpactSerializer(encoder)); |
| 297 } |
| 298 } |
| 299 } |
| 300 |
| 301 class WorldImpactDeserializer extends DeserializerPlugin { |
| 302 Map<Element, WorldImpact> impactMap = <Element, WorldImpact>{}; |
| 303 |
| 304 @override |
| 305 void onElement(Element element, ObjectDecoder getDecoder(String tag)) { |
| 306 ObjectDecoder decoder = getDecoder(WORLD_IMPACT_TAG); |
| 307 if (decoder != null) { |
| 308 impactMap[element] = ImpactDeserializer.deserializeImpact(decoder); |
| 309 } |
| 310 } |
| 311 } |
| 312 |
| 219 class _DeserializerSystem extends DeserializerSystem { | 313 class _DeserializerSystem extends DeserializerSystem { |
| 220 final Deserializer _deserializer; | 314 final Deserializer _deserializer; |
| 221 final List<LibraryElement> deserializedLibraries = <LibraryElement>[]; | 315 final List<LibraryElement> deserializedLibraries = <LibraryElement>[]; |
| 316 final WorldImpactDeserializer _worldImpactDeserializer = |
| 317 new WorldImpactDeserializer(); |
| 222 | 318 |
| 223 _DeserializerSystem(this._deserializer); | 319 _DeserializerSystem(this._deserializer) { |
| 320 _deserializer.plugins.add(_worldImpactDeserializer); |
| 321 } |
| 224 | 322 |
| 225 LibraryElement readLibrary(Uri resolvedUri) { | 323 LibraryElement readLibrary(Uri resolvedUri) { |
| 226 LibraryElement library = _deserializer.lookupLibrary(resolvedUri); | 324 LibraryElement library = _deserializer.lookupLibrary(resolvedUri); |
| 227 if (library != null) { | 325 if (library != null) { |
| 228 deserializedLibraries.add(library); | 326 deserializedLibraries.add(library); |
| 229 } | 327 } |
| 230 return library; | 328 return library; |
| 231 } | 329 } |
| 232 | 330 |
| 233 @override | 331 @override |
| 234 WorldImpact computeWorldImpact(Element element) { | 332 WorldImpact computeWorldImpact(Element element) { |
| 235 return const WorldImpact(); | 333 WorldImpact impact = _worldImpactDeserializer.impactMap[element]; |
| 334 if (impact == null) { |
| 335 print('No impact found for $element (${element.library})'); |
| 336 impact = const WorldImpact(); |
| 337 } |
| 338 return impact; |
| 236 } | 339 } |
| 237 | 340 |
| 238 @override | 341 @override |
| 239 bool isDeserialized(Element element) { | 342 bool isDeserialized(Element element) { |
| 240 return deserializedLibraries.contains(element.library); | 343 return deserializedLibraries.contains(element.library); |
| 241 } | 344 } |
| 242 } | 345 } |
| OLD | NEW |