Fine. Assert LibraryManifest serialization, for all libraries.

Change-Id: Ic8ee0c30a5d701e321f70f044e1a09f21dcfcb5d
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/419980
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Paul Berry <paulberry@google.com>
This commit is contained in:
Konstantin Shcheglov
2025-04-02 13:01:30 -07:00
committed by Commit Queue
parent 383cd496ce
commit 5ee30689bf
2 changed files with 29 additions and 72 deletions
@@ -2,6 +2,8 @@
// 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.
import 'dart:typed_data';
import 'package:analyzer/dart/element/element2.dart';
import 'package:analyzer/src/dart/analysis/file_state.dart';
import 'package:analyzer/src/dart/element/element.dart';
@@ -13,6 +15,7 @@ import 'package:analyzer/src/summary2/data_reader.dart';
import 'package:analyzer/src/summary2/data_writer.dart';
import 'package:analyzer/src/summary2/linked_element_factory.dart';
import 'package:analyzer/src/util/performance/operation_performance.dart';
import 'package:collection/collection.dart';
/// The manifest of a single library.
class LibraryManifest {
@@ -95,6 +98,7 @@ class LibraryManifestBuilder {
_buildManifests();
_addReExports();
assert(_assertSerialization());
return newManifests;
}
@@ -342,6 +346,31 @@ class LibraryManifestBuilder {
newItems[lookupName] = item;
}
/// Assert that every manifest can be serialized, and when deserialized
/// results in the same manifest.
bool _assertSerialization() {
Uint8List manifestAsBytes(LibraryManifest manifest) {
var byteSink = BufferedSink();
manifest.write(byteSink);
return byteSink.takeBytes();
}
newManifests.forEach((uri, manifest) {
var bytes = manifestAsBytes(manifest);
var readManifest = LibraryManifest.read(
SummaryDataReader(bytes),
);
var readBytes = manifestAsBytes(readManifest);
if (!const ListEquality<int>().equals(bytes, readBytes)) {
throw StateError('Library manifest bytes are different: $uri');
}
});
return true;
}
/// Fill `result` with new library manifests.
/// We reuse existing items when they fully match.
/// We build new items for mismatched elements.
@@ -3,7 +3,6 @@
// BSD-style license that can be found in the LICENSE file.
import 'dart:async';
import 'dart:typed_data';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/ast/ast.dart';
@@ -17,15 +16,11 @@ import 'package:analyzer/src/dart/analysis/driver_event.dart' as driver_events;
import 'package:analyzer/src/dart/analysis/file_state.dart';
import 'package:analyzer/src/dart/analysis/status.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/fine/library_manifest.dart';
import 'package:analyzer/src/fine/requirements.dart';
import 'package:analyzer/src/lint/linter.dart';
import 'package:analyzer/src/summary2/data_reader.dart';
import 'package:analyzer/src/summary2/data_writer.dart';
import 'package:analyzer/src/test_utilities/lint_registration_mixin.dart';
import 'package:analyzer/src/utilities/extensions/async.dart';
import 'package:analyzer_utilities/testing/tree_string_sink.dart';
import 'package:collection/collection.dart';
import 'package:linter/src/rules.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -11710,11 +11705,6 @@ int get b => 0;
collector.take();
}
_assertLibraryManifestSerialization(
driver: driver,
libraryUri: libraryUri,
);
modifyFile2(testFile, updatedCode);
driver.changeFile2(testFile);
@@ -11723,68 +11713,6 @@ int get b => 0;
setId('expectedUpdatedEvents');
await assertEventsText(collector, expectedUpdatedEvents);
}
static void _assertLibraryManifestSerialization({
required AnalysisDriver driver,
required Uri libraryUri,
}) {
var idProvider = IdProvider();
String manifestAsStr(LibraryManifest manifest) {
var buffer = StringBuffer();
LibraryManifestPrinter(
configuration: DriverEventsPrinterConfiguration()
..withElementManifests = true,
sink: TreeStringSink(sink: buffer, indent: ''),
idProvider: idProvider,
).write(manifest);
return buffer.toString().trim();
}
Uint8List manifestAsBytes(LibraryManifest manifest) {
var byteSink = BufferedSink();
manifest.write(byteSink);
return byteSink.takeBytes();
}
// Write the current manifest as string, and as bytes.
String currentStr;
Uint8List currentBytes;
{
var elementFactory = driver.libraryContext.elementFactory;
var libraryElement = elementFactory.libraryOfUri2(libraryUri);
// SAFETY: this function is invoked when manifests are enabled.
var manifest = libraryElement.manifest!;
currentStr = manifestAsStr(manifest);
currentBytes = manifestAsBytes(manifest);
}
// Read from bytes; write as string and again as bytes.
String readStr;
Uint8List readBytes;
{
var manifest = LibraryManifest.read(
SummaryDataReader(currentBytes),
);
readStr = manifestAsStr(manifest);
readBytes = manifestAsBytes(manifest);
}
// The strings must be identical.
if (readStr != currentStr) {
print('${'-' * 16} current');
print(currentStr);
print('${'-' * 16} read');
print(readStr);
print('-' * 32);
fail('Library manifest strings are different');
}
// The bytes must be identical.
if (!const ListEquality<int>().equals(currentBytes, readBytes)) {
fail('Library manifest bytes are different');
}
}
}
/// A lint that is always reported for all linted files.