| Index: tests/compiler/dart2js/serialization_model_test.dart
|
| diff --git a/tests/compiler/dart2js/serialization_model_test.dart b/tests/compiler/dart2js/serialization_model_test.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..b8cef2598d326be53a929cdd3678255d785ef0e2
|
| --- /dev/null
|
| +++ b/tests/compiler/dart2js/serialization_model_test.dart
|
| @@ -0,0 +1,224 @@
|
| +// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
|
| +// for details. All rights reserved. Use of this source code is governed by a
|
| +// BSD-style license that can be found in the LICENSE file.
|
| +
|
| +library dart2js.serialization_model_test;
|
| +
|
| +import 'dart:async';
|
| +import 'dart:io';
|
| +import 'package:async_helper/async_helper.dart';
|
| +import 'package:expect/expect.dart';
|
| +import 'package:compiler/src/commandline_options.dart';
|
| +import 'package:compiler/src/common/backend_api.dart';
|
| +import 'package:compiler/src/common/names.dart';
|
| +import 'package:compiler/src/common/resolution.dart';
|
| +import 'package:compiler/src/compiler.dart';
|
| +import 'package:compiler/src/dart_types.dart';
|
| +import 'package:compiler/src/elements/elements.dart';
|
| +import 'package:compiler/src/filenames.dart';
|
| +import 'package:compiler/src/serialization/element_serialization.dart';
|
| +import 'package:compiler/src/serialization/impact_serialization.dart';
|
| +import 'package:compiler/src/serialization/json_serializer.dart';
|
| +import 'package:compiler/src/serialization/serialization.dart';
|
| +import 'package:compiler/src/serialization/equivalence.dart';
|
| +import 'package:compiler/src/serialization/task.dart';
|
| +import 'package:compiler/src/universe/world_impact.dart';
|
| +import 'package:compiler/src/universe/class_set.dart';
|
| +import 'package:compiler/src/universe/use.dart';
|
| +import 'memory_compiler.dart';
|
| +import 'serialization_helper.dart';
|
| +import 'serialization_analysis_test.dart';
|
| +import 'serialization_impact_test.dart';
|
| +import 'serialization_test.dart';
|
| +
|
| +main(List<String> arguments) {
|
| + String filename;
|
| + for (String arg in arguments) {
|
| + if (!arg.startsWith('-')) {
|
| + filename = arg;
|
| + }
|
| + }
|
| + bool verbose = arguments.contains('-v');
|
| +
|
| + asyncTest(() async {
|
| + print('------------------------------------------------------------------');
|
| + print('serialize dart:core');
|
| + print('------------------------------------------------------------------');
|
| + String serializedData;
|
| + File file = new File('out.data');
|
| + if (arguments.contains('-l')) {
|
| + if (file.existsSync()) {
|
| + print('Loading data from $file');
|
| + serializedData = file.readAsStringSync();
|
| + }
|
| + }
|
| + if (serializedData == null) {
|
| + serializedData = await serializeDartCore();
|
| + if (arguments.contains('-s')) {
|
| + print('Saving data to $file');
|
| + file.writeAsStringSync(serializedData);
|
| + }
|
| + }
|
| + if (filename != null) {
|
| + Uri entryPoint = Uri.base.resolve(nativeToUriPath(filename));
|
| + await check(serializedData, entryPoint);
|
| + } else {
|
| + Uri entryPoint = Uri.parse('memory:main.dart');
|
| + for (Test test in TESTS) {
|
| + if (test.sourceFiles['main.dart']
|
| + .contains('main(List<String> arguments)')) {
|
| + // TODO(johnniwinther): Check this test.
|
| + continue;
|
| + }
|
| + print('==============================================================');
|
| + print(test.sourceFiles);
|
| + await check(
|
| + serializedData,
|
| + entryPoint,
|
| + sourceFiles: test.sourceFiles,
|
| + verbose: verbose);
|
| + }
|
| + }
|
| + });
|
| +}
|
| +
|
| +Future check(
|
| + String serializedData,
|
| + Uri entryPoint,
|
| + {Map<String, String> sourceFiles: const <String, String>{},
|
| + bool verbose: false}) async {
|
| +
|
| + print('------------------------------------------------------------------');
|
| + print('compile normal');
|
| + print('------------------------------------------------------------------');
|
| + Compiler compilerNormal = compilerFor(
|
| + memorySourceFiles: sourceFiles,
|
| + options: [Flags.analyzeOnly]);
|
| + compilerNormal.resolution.retainCachesForTesting = true;
|
| + await compilerNormal.run(entryPoint);
|
| + compilerNormal.world.populate();
|
| +
|
| + print('------------------------------------------------------------------');
|
| + print('compile deserialized');
|
| + print('------------------------------------------------------------------');
|
| + Compiler compilerDeserialized = compilerFor(
|
| + memorySourceFiles: sourceFiles,
|
| + options: [Flags.analyzeOnly]);
|
| + compilerDeserialized.resolution.retainCachesForTesting = true;
|
| + deserialize(compilerDeserialized, serializedData);
|
| + await compilerDeserialized.run(entryPoint);
|
| + compilerDeserialized.world.populate();
|
| +
|
| + checkResolutionImpacts(
|
| + compilerNormal, compilerDeserialized,
|
| + verbose: verbose);
|
| +
|
| + checkSets(
|
| + compilerNormal.resolverWorld.directlyInstantiatedClasses,
|
| + compilerDeserialized.resolverWorld.directlyInstantiatedClasses,
|
| + "Directly instantiated classes mismatch",
|
| + areElementsEquivalent,
|
| + verbose: verbose);
|
| +
|
| + checkSets(
|
| + compilerNormal.resolverWorld.instantiatedTypes,
|
| + compilerDeserialized.resolverWorld.instantiatedTypes,
|
| + "Instantiated types mismatch",
|
| + areTypesEquivalent,
|
| + // TODO(johnniwinther): Ensure that all instantiated types are tracked.
|
| + failOnUnfound: false,
|
| + verbose: verbose);
|
| +
|
| + checkSets(
|
| + compilerNormal.resolverWorld.isChecks,
|
| + compilerDeserialized.resolverWorld.isChecks,
|
| + "Is-check mismatch",
|
| + areTypesEquivalent,
|
| + verbose: verbose);
|
| +
|
| + checkSets(
|
| + compilerNormal.enqueuer.resolution.processedElements,
|
| + compilerDeserialized.enqueuer.resolution.processedElements,
|
| + "Processed element mismatch",
|
| + areElementsEquivalent,
|
| + verbose: verbose);
|
| +
|
| + checkClassHierarchyNodes(
|
| + compilerNormal.world.getClassHierarchyNode(
|
| + compilerNormal.coreClasses.objectClass),
|
| + compilerDeserialized.world.getClassHierarchyNode(
|
| + compilerDeserialized.coreClasses.objectClass),
|
| + verbose: verbose);
|
| +}
|
| +
|
| +void checkClassHierarchyNodes(
|
| + ClassHierarchyNode a, ClassHierarchyNode b,
|
| + {bool verbose: false}) {
|
| + if (verbose) {
|
| + print('Checking $a vs $b');
|
| + }
|
| + Expect.isTrue(
|
| + areElementsEquivalent(a.cls, b.cls),
|
| + "Element identity mismatch for ${a.cls} vs ${b.cls}.");
|
| + Expect.equals(
|
| + a.isDirectlyInstantiated,
|
| + b.isDirectlyInstantiated,
|
| + "Value mismatch for 'isDirectlyInstantiated' for ${a.cls} vs ${b.cls}.");
|
| + Expect.equals(
|
| + a.isIndirectlyInstantiated,
|
| + b.isIndirectlyInstantiated,
|
| + "Value mismatch for 'isIndirectlyInstantiated' "
|
| + "for ${a.cls} vs ${b.cls}.");
|
| + // TODO(johnniwinther): Enforce a canonical and stable order on direct
|
| + // subclasses.
|
| + for (ClassHierarchyNode child in a.directSubclasses) {
|
| + bool found = false;
|
| + for (ClassHierarchyNode other in b.directSubclasses) {
|
| + if (areElementsEquivalent(child.cls, other.cls)) {
|
| + checkClassHierarchyNodes(child, other,
|
| + verbose: verbose);
|
| + found = true;
|
| + break;
|
| + }
|
| + }
|
| + if (!found) {
|
| + Expect.isFalse(
|
| + child.isInstantiated, 'Missing subclass ${child.cls} of ${a.cls}');
|
| + }
|
| + }
|
| +}
|
| +
|
| +void checkSets(
|
| + Iterable set1,
|
| + Iterable set2,
|
| + String messagePrefix,
|
| + bool areEquivalent(a, b),
|
| + {bool failOnUnfound: true,
|
| + bool verbose: false}) {
|
| + List common = [];
|
| + List unfound = [];
|
| + Set remaining = computeSetDifference(
|
| + set1, set2, common, unfound, areEquivalent);
|
| + StringBuffer sb = new StringBuffer();
|
| + sb.write("$messagePrefix:");
|
| + if (verbose) {
|
| + sb.write("\n Common:\n ${common.join('\n ')}");
|
| + }
|
| + if (unfound.isNotEmpty || verbose) {
|
| + sb.write("\n Unfound:\n ${unfound.join('\n ')}");
|
| + }
|
| + if (remaining.isNotEmpty || verbose) {
|
| + sb.write("\n Extra: \n ${remaining.join('\n ')}");
|
| + }
|
| + String message = sb.toString();
|
| + if (unfound.isNotEmpty || remaining.isNotEmpty) {
|
| +
|
| + if (failOnUnfound || remaining.isNotEmpty) {
|
| + Expect.fail(message);
|
| + } else {
|
| + print(message);
|
| + }
|
| + } else if (verbose) {
|
| + print(message);
|
| + }
|
| +}
|
|
|