mirror of
https://github.com/dart-lang/sdk
synced 2024-10-04 16:54:55 +00:00
[CFE/kernel] Test of relink bug with ExtensionTypeDeclaration
Tests for fix done in https://dart-review.googlesource.com/c/sdk/+/350801. Change-Id: I01a6512dc5de3e91f698828d99097a083d392972 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/352061 Reviewed-by: Chloe Stefantsova <cstefantsova@google.com> Commit-Queue: Jens Johansen <jensj@google.com>
This commit is contained in:
parent
cd23ab4e59
commit
35b923f884
|
@ -4,8 +4,10 @@
|
|||
|
||||
import 'package:kernel/ast.dart';
|
||||
|
||||
Set<Library> findAllReferencedLibraries(List<Library> from) {
|
||||
_LibraryCollector collector = new _LibraryCollector();
|
||||
Set<Library> findAllReferencedLibraries(List<Library> from,
|
||||
{bool collectViaReferencesToo = false}) {
|
||||
_LibraryCollector collector =
|
||||
new _LibraryCollector(collectViaReferencesToo: collectViaReferencesToo);
|
||||
for (Library library in from) {
|
||||
collector.visitLibrary(library);
|
||||
}
|
||||
|
@ -21,13 +23,23 @@ bool duplicateLibrariesReachable(List<Library> from) {
|
|||
}
|
||||
|
||||
class _LibraryCollector extends RecursiveVisitor {
|
||||
final bool collectViaReferencesToo;
|
||||
Set<Library> allSeenLibraries = {};
|
||||
|
||||
_LibraryCollector({required this.collectViaReferencesToo});
|
||||
|
||||
@override
|
||||
void defaultNode(Node node) {
|
||||
if (node is NamedNode) {
|
||||
// Named nodes can be linked to.
|
||||
seen(node);
|
||||
if (collectViaReferencesToo) {
|
||||
TreeNode? refNode = node.reference.node;
|
||||
if (refNode != null && !identical(refNode, node)) {
|
||||
// This is generally pretty bad.
|
||||
seen(refNode);
|
||||
}
|
||||
}
|
||||
} else if (node is Name) {
|
||||
if (node.library != null) {
|
||||
seen(node.library!);
|
||||
|
|
87
pkg/kernel/test/binary/relink_platform_test.dart
Normal file
87
pkg/kernel/test/binary/relink_platform_test.dart
Normal file
|
@ -0,0 +1,87 @@
|
|||
// Copyright (c) 2024, 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.
|
||||
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:kernel/binary/ast_from_binary.dart';
|
||||
import 'package:kernel/kernel.dart';
|
||||
import 'package:kernel/src/tool/find_referenced_libraries.dart';
|
||||
|
||||
import '../relink_test.dart';
|
||||
import 'find_sdk_dills.dart';
|
||||
|
||||
void main() {
|
||||
List<File> dills = findSdkDills();
|
||||
print("Found ${dills.length} dills!");
|
||||
|
||||
for (File dill in dills) {
|
||||
readAndRelink(dill);
|
||||
}
|
||||
}
|
||||
|
||||
void readAndRelink(File dill) {
|
||||
print("Reading $dill");
|
||||
List<int> bytes = dill.readAsBytesSync();
|
||||
|
||||
try {
|
||||
// Loading a component it should be self-contained.
|
||||
Component component1 = new Component();
|
||||
new BinaryBuilder(bytes,
|
||||
alwaysCreateNewNamedNodes: true, disableLazyReading: true)
|
||||
.readComponent(component1);
|
||||
checkReachable(component1);
|
||||
|
||||
// Loading a component it should be self-contained.
|
||||
Component component2 = new Component(nameRoot: component1.root);
|
||||
new BinaryBuilder(bytes,
|
||||
alwaysCreateNewNamedNodes: true, disableLazyReading: true)
|
||||
.readComponent(component2);
|
||||
checkReachable(component2);
|
||||
|
||||
// Now that we read "component 2" on top of "component 1" the 1-version is
|
||||
// no longer self-contained.
|
||||
try {
|
||||
checkReachable(component1);
|
||||
throw "Expected this one to fail.";
|
||||
} catch (e) {
|
||||
// Expected.
|
||||
}
|
||||
|
||||
// Relinking it it should be back to being self contained though.
|
||||
component1.relink();
|
||||
checkReachable(component1);
|
||||
|
||||
// Now that component 1 is relinked component 2 is no longer self contained.
|
||||
try {
|
||||
checkReachable(component2);
|
||||
throw "Expected this one to fail.";
|
||||
} catch (e) {
|
||||
// Expected.
|
||||
}
|
||||
|
||||
// But relinking makes it self-contained again.
|
||||
component2.relink();
|
||||
checkReachable(component2);
|
||||
} catch (e, st) {
|
||||
print("Error for $dill:");
|
||||
print(e);
|
||||
print(st);
|
||||
print("");
|
||||
print("--------------------");
|
||||
print("");
|
||||
exitCode = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void checkReachable(Component component) {
|
||||
expectReachable(
|
||||
findAllReferencedLibraries(component.libraries), component.libraries);
|
||||
expectReachable(
|
||||
findAllReferencedLibraries(component.libraries,
|
||||
collectViaReferencesToo: true),
|
||||
component.libraries);
|
||||
if (duplicateLibrariesReachable(component.libraries)) {
|
||||
throw "Didn't expect duplicates libraries!";
|
||||
}
|
||||
}
|
|
@ -80,6 +80,10 @@ void main() {
|
|||
// After the relink only the libs from component1Prime are reachable!
|
||||
expectReachable(findAllReferencedLibraries(component1Prime.libraries),
|
||||
component1Prime.libraries);
|
||||
expectReachable(
|
||||
findAllReferencedLibraries(component1Prime.libraries,
|
||||
collectViaReferencesToo: true),
|
||||
component1Prime.libraries);
|
||||
if (duplicateLibrariesReachable(component1Prime.libraries)) {
|
||||
throw "Didn't expect duplicates libraries!";
|
||||
}
|
||||
|
@ -103,6 +107,10 @@ void main() {
|
|||
// After the relink only the libs from component1Prime are reachable!
|
||||
expectReachable(findAllReferencedLibraries(component2Prime.libraries),
|
||||
component2Prime.libraries);
|
||||
expectReachable(
|
||||
findAllReferencedLibraries(component2Prime.libraries,
|
||||
collectViaReferencesToo: true),
|
||||
component2Prime.libraries);
|
||||
if (duplicateLibrariesReachable(component2Prime.libraries)) {
|
||||
throw "Didn't expect duplicates libraries!";
|
||||
}
|
||||
|
@ -160,6 +168,21 @@ Component createComponent(int literal) {
|
|||
fileUri: libUri);
|
||||
lib.addProcedure(libProcedure);
|
||||
|
||||
ExtensionTypeDeclaration extensionTypeDeclaration =
|
||||
new ExtensionTypeDeclaration(name: "Foo", fileUri: libUri);
|
||||
extensionTypeDeclaration.declaredRepresentationType = DynamicType();
|
||||
extensionTypeDeclaration.representationName = "extensionTypeMethod";
|
||||
final Block extensionTypeProcedureBody =
|
||||
new Block([new ReturnStatement(new IntLiteral(literal))]);
|
||||
final Procedure extensionTypeProcedure = new Procedure(
|
||||
new Name("extensionTypeMethod"),
|
||||
ProcedureKind.Method,
|
||||
new FunctionNode(extensionTypeProcedureBody,
|
||||
returnType: new DynamicType()),
|
||||
fileUri: libUri);
|
||||
extensionTypeDeclaration.addProcedure(extensionTypeProcedure);
|
||||
lib.addExtensionTypeDeclaration(extensionTypeDeclaration);
|
||||
|
||||
final Uri mainUri = Uri.parse('org-dartlang:///main.dart');
|
||||
final Library main = new Library(mainUri, fileUri: mainUri);
|
||||
final Block mainProcedureBody = new Block([
|
||||
|
|
Loading…
Reference in a new issue