Skip to content

Commit

Permalink
Handle serialization with --dump-info
Browse files Browse the repository at this point in the history
Change-Id: I626eb8c7dca0b4e92f2aca79429f6e7336215840
Reviewed-on: https://dart-review.googlesource.com/c/84846
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Sigmund Cherem <sigmund@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
  • Loading branch information
johnniwinther authored and commit-bot@chromium.org committed Nov 21, 2018
1 parent e62951f commit 0fded45
Show file tree
Hide file tree
Showing 11 changed files with 116 additions and 51 deletions.
8 changes: 5 additions & 3 deletions pkg/compiler/lib/compiler_new.dart
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,11 @@ enum OutputType {
/// A source map for a JavaScript output.
sourceMap,

/// Additional information requested by the user, such dump info or a deferred
/// map.
info,
/// Dump info output.
dumpInfo,

/// Deferred map output.
deferredMap,

/// Implementation specific output used for debugging the compiler.
debug,
Expand Down
19 changes: 4 additions & 15 deletions pkg/compiler/lib/src/dump_info.dart
Original file line number Diff line number Diff line change
Expand Up @@ -113,14 +113,6 @@ class ElementInfoCollector {
_globalInferenceResults.resultOfParameter(e);

FieldInfo visitField(FieldEntity field, {ClassEntity containingClass}) {
var isInInstantiatedClass = false;
if (containingClass != null) {
isInInstantiatedClass =
closedWorld.classHierarchy.isInstantiated(containingClass);
}
if (!isInInstantiatedClass && !_hasBeenResolved(field)) {
return null;
}
AbstractValue inferredType = _resultOfMember(field).type;
// If a field has an empty inferred type it is never used.
if (inferredType == null ||
Expand Down Expand Up @@ -160,12 +152,6 @@ class ElementInfoCollector {
return info;
}

bool _hasBeenResolved(MemberEntity entity) {
return compiler.globalInference.typesInferrerInternal.inferrer.types
.memberTypeInformations
.containsKey(entity);
}

ClassInfo visitClass(ClassEntity clazz) {
// Omit class if it is not needed.
ClassInfo classInfo = new ClassInfo(
Expand Down Expand Up @@ -556,9 +542,12 @@ class DumpInfoTask extends CompilerTask implements InfoReporter {
compiler.outputProvider.createOutputSink(
compiler.options.outputUri.pathSegments.last,
'info.json',
OutputType.info)
OutputType.dumpInfo)
..add(jsonBuffer.toString())
..close();
// TODO(johnniwinther): Reenable this when package:dart2js_info have
// stable ids.
//BasicInfo.resetIds();
});
}

Expand Down
2 changes: 1 addition & 1 deletion pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1718,7 +1718,7 @@ class Emitter extends js_emitter.EmitterBase {
mapping.addAll(_closedWorld.outputUnitData
.computeDeferredMap(compiler.options, _elementEnvironment));
compiler.outputProvider.createOutputSink(
compiler.options.deferredMapUri.path, '', OutputType.info)
compiler.options.deferredMapUri.path, '', OutputType.deferredMap)
..add(const JsonEncoder.withIndent(" ").convert(mapping))
..close();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,7 @@ class ModelEmitter {
omittedUnits:
omittedFragments.map((fragemnt) => fragemnt.outputUnit).toSet()));
compiler.outputProvider.createOutputSink(
compiler.options.deferredMapUri.path, '', OutputType.info)
compiler.options.deferredMapUri.path, '', OutputType.deferredMap)
..add(const JsonEncoder.withIndent(" ").convert(mapping))
..close();
}
Expand Down
16 changes: 15 additions & 1 deletion pkg/compiler/lib/src/js_model/element_map_impl.dart
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ class JsKernelToElementMap
static const String typedefDataTag = 'typedef-data';
static const String memberDataTag = 'member-data';
static const String typeVariableDataTag = 'type-variable-data';
static const String nestedClosuresTag = 'nested-closures';

final CompilerOptions options;
final DiagnosticReporter reporter;
Expand Down Expand Up @@ -333,7 +334,10 @@ class JsKernelToElementMap
JClassEnv env = new JClassEnv.readFromDataSource(source);
JClassData data = new JClassData.readFromDataSource(source);
classMap[env.cls] = classes.registerByIndex(index, cls, data, env);
libraries.getEnv(cls.library).registerClass(cls.name, env);
if (cls is! JRecord && cls is! JClosureClass) {
// Synthesized classes are not part of the library environment.
libraries.getEnv(cls.library).registerClass(cls.name, env);
}
assert(index == cls.classIndex);
});
source.end(classDataTag);
Expand Down Expand Up @@ -376,6 +380,12 @@ class JsKernelToElementMap
assert(index == typeVariable.typeVariableIndex);
});
source.end(typeVariableDataTag);

source.begin(nestedClosuresTag);
_nestedClosureMap.addAll(
source.readMemberMap(() => source.readMembers<IndexedFunction>()));
source.end(nestedClosuresTag);

source.end(tag);
}

Expand Down Expand Up @@ -457,6 +467,10 @@ class JsKernelToElementMap
});
sink.end(typeVariableDataTag);

sink.begin(nestedClosuresTag);
sink.writeMemberMap(_nestedClosureMap, sink.writeMembers);
sink.end(nestedClosuresTag);

sink.end(tag);
}

Expand Down
3 changes: 2 additions & 1 deletion pkg/compiler/lib/src/old_to_new_api.dart
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ class LegacyCompilerOutput implements CompilerOutput {
OutputSink createOutputSink(String name, String extension, OutputType type) {
if (_outputProvider != null) {
switch (type) {
case OutputType.info:
case OutputType.dumpInfo:
case OutputType.deferredMap:
if (extension == '') {
// Needed to make Pub generate the same output name.
extension = 'deferred_map';
Expand Down
3 changes: 2 additions & 1 deletion pkg/compiler/lib/src/source_file_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,8 @@ class RandomAccessFileOutputProvider implements CompilerOutput {
case OutputType.jsPart:
uri = out.resolve('$name.$extension');
break;
case OutputType.info:
case OutputType.dumpInfo:
case OutputType.deferredMap:
if (name == '') {
name = out.pathSegments.last;
}
Expand Down
3 changes: 2 additions & 1 deletion tests/compiler/dart2js/deferred/load_mapping_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ void main() {
CompilerImpl compiler = result.compiler;
JClosedWorld closedWorld = compiler.backendClosedWorldForTesting;
// Ensure a mapping file is output.
Expect.isNotNull(collector.getOutput("deferred_map.json", OutputType.info));
Expect.isNotNull(
collector.getOutput("deferred_map.json", OutputType.deferredMap));

Map mapping = closedWorld.outputUnitData
.computeDeferredMap(compiler.options, closedWorld.elementEnvironment);
Expand Down
78 changes: 53 additions & 25 deletions tests/compiler/dart2js/helpers/text_helpers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,40 +6,68 @@
/// of the [windowSize] lines before and after are printed and the mismatch line
/// number is returned. If identical, nothing is printed and `null` is returned.
int checkEqualContentAndShowDiff(String text1, String text2,
{int windowSize: 20}) {
{int windowSize: 20,
bool Function(int, List<String>, List<String>) filter}) {
List<String> lines1 = text1.split('\n');
List<String> lines2 = text2.split('\n');
for (int i = 0; i < lines1.length && i < lines2.length; i++) {
if (i >= lines1.length || i >= lines2.length || lines1[i] != lines2[i]) {
for (int j = i - windowSize; j < i + windowSize; j++) {
if (j < 0) continue;
String line1 = 0 <= j && j < lines1.length ? lines1[j] : null;
String line2 = 0 <= j && j < lines2.length ? lines2[j] : null;
if (line1 == line2) {
print(' $j $line1');
} else {
String text = line1 == null ? '<eof>' : line1;
String newText = line2 == null ? '<eof>' : line2;
print('- $j ${text}');
print('+ $j ${newText}');
if (text.length > 80 && newText.length > 80) {
assert(text != newText);
StringBuffer diff = new StringBuffer();
diff.write(' $j ');
for (int k = 0; k < text.length && k < newText.length; k++) {
int char1 = k < text.length ? text.codeUnitAt(k) : null;
int char2 = k < newText.length ? newText.codeUnitAt(k) : null;
if (char1 != char2) {
diff.write('^');
} else {
diff.write(' ');
if (filter != null && filter(i, lines1, lines2)) {
String line1 = 0 <= i && i < lines1.length ? lines1[i] : null;
String line2 = 0 <= i && i < lines2.length ? lines2[i] : null;
String text = line1 == null ? '<eof>' : line1;
String newText = line2 == null ? '<eof>' : line2;
print('(skipped) - $i ${text}');
print('(skipped) + $i ${newText}');
} else {
List<String> pendingLines = <String>[];

void flushPendingLines() {
if (pendingLines.isNotEmpty) {
print(pendingLines.join('\n'));
pendingLines.clear();
}
}

for (int j = i - windowSize; j < i + windowSize; j++) {
if (j < 0) continue;
String line1 = 0 <= j && j < lines1.length ? lines1[j] : null;
String line2 = 0 <= j && j < lines2.length ? lines2[j] : null;
if (line1 == line2) {
flushPendingLines();
if (line1 != null) {
print(' $j $line1');
}
} else {
String text = line1 == null ? '<eof>' : line1;
String newText = line2 == null ? '<eof>' : line2;

if (text.length > 80 && newText.length > 80) {
flushPendingLines();
print('- $j ${text}');
print('+ $j ${newText}');
assert(text != newText);
StringBuffer diff = new StringBuffer();
diff.write(' $j ');
for (int k = 0; k < text.length && k < newText.length; k++) {
int char1 = k < text.length ? text.codeUnitAt(k) : null;
int char2 = k < newText.length ? newText.codeUnitAt(k) : null;
if (char1 != char2) {
diff.write('^');
} else {
diff.write(' ');
}
}
print(diff);
} else {
print('- $j ${text}');
pendingLines.add('+ $j ${newText}');
}
print(diff);
}
}
flushPendingLines();
return i;
}
return i;
}
}
return null;
Expand Down
3 changes: 3 additions & 0 deletions tests/compiler/dart2js/serialization/serialization_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import 'dart:io';
import 'package:async_helper/async_helper.dart';
import 'package:compiler/src/commandline_options.dart';
import 'package:compiler/src/serialization/strategies.dart';
import 'package:expect/expect.dart';
import 'serialization_test_helper.dart';
Expand Down Expand Up @@ -49,6 +50,8 @@ Future checkTests(Directory dataDir,
if (shouldContinue) continued = true;
testCount++;
List<String> testOptions = options.toList();
testOptions.add(Flags.dumpInfo);
testOptions.add('--out=out.js');
if (onTest != null) {
onTest(entity.uri);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@ import 'package:kernel/ast.dart' as ir;
import '../helpers/memory_compiler.dart';
import '../helpers/text_helpers.dart';

/// Entries in dump info that naturally differ between compilations.
const List<String> dumpInfoExceptions = [
'"compilationMoment":',
'"compilationDuration":',
'"toJsonDuration":'
];

runTest(
{Uri entryPoint,
Map<String, String> memorySourceFiles: const <String, String>{},
Expand Down Expand Up @@ -62,10 +69,29 @@ runTest(
Map<String, String> newFileMap = newOutput[outputType];
Expect.setEquals(fileMap.keys, newFileMap.keys,
"File mismatch for output type $outputType.");

fileMap.forEach((String fileName, String code) {
String newCode = newFileMap[fileName];
int failureLine = checkEqualContentAndShowDiff(code, newCode);
bool Function(int, List<String>, List<String>) filter;
if (outputType == OutputType.dumpInfo) {
return;
// TODO(johnniwinther): Reenable this when package:dart2js_info have
// stable ids.
//filter = (int index, List<String> lines1, List<String> lines2) {
// if (index <= lines1.length && index <= lines2.length) {
// String line1 = lines1[index];
// String line2 = lines2[index];
// for (String exception in dumpInfoExceptions) {
// if (line1.trim().startsWith(exception) &&
// line2.trim().startsWith(exception)) {
// return true;
// }
// }
// }
// return false;
//};
}
int failureLine =
checkEqualContentAndShowDiff(code, newCode, filter: filter);
Expect.isNull(
failureLine,
"Output mismatch at line $failureLine in "
Expand Down

0 comments on commit 0fded45

Please sign in to comment.