d7f200b97d
(Part of https://github.com/dart-lang/sdk/issues/63288) This change migrates the kernel package to use the new constructor declaration syntax, described in https://github.com/dart-lang/language/blob/main/accepted/future-releases/primary-constructors/feature-specification.md#abbreviations-of-in-body-constructor-declarations. This change was performed in an automated fashion, by (a) bumping the package's SDK constraint to `3.13.0-0`, (b) enabling the lints `unnecessary_type_name_in_constructor` and `unnecessary_const_in_enum_constructor`, (c) fixing the resulting lint failures using `dart fix`, and then (d) reformatting the affected files. To ease code review, I've reverted unrelated formatting changes. Change-Id: I8d32a0b26450a44dfa2ebd9fe2dff9df6a6a6964 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/508426 Reviewed-by: Konstantin Shcheglov <scheglov@google.com> Commit-Queue: Paul Berry <paulberry@google.com>
486 lines
14 KiB
Dart
486 lines
14 KiB
Dart
// Copyright (c) 2025, 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 'package:expect/expect.dart';
|
|
import 'package:kernel/ast.dart';
|
|
import 'package:kernel/src/equivalence.dart' show EquivalenceResult;
|
|
import 'package:kernel/src/tool/check_equivalence.dart';
|
|
|
|
Uri fileUri1 = Uri.parse('file://uri1');
|
|
Uri fileUri2 = Uri.parse('file://uri2');
|
|
Uri fileUri3 = Uri.parse('file://uri3');
|
|
Uri importUri1 = Uri.parse('import://uri1');
|
|
Uri importUri2 = Uri.parse('import://uri2');
|
|
Uri importUri3 = Uri.parse('import://uri3');
|
|
|
|
List<Test> tests = [
|
|
new Test((_) => new Component()),
|
|
new Test(
|
|
(_) =>
|
|
new Component()
|
|
..libraries.add(new Library(importUri1, fileUri: fileUri1)),
|
|
),
|
|
new Test(
|
|
(bool first) {
|
|
return new Component()
|
|
..libraries.add(
|
|
new Library(
|
|
first ? importUri1 : importUri2,
|
|
fileUri: first ? fileUri1 : fileUri2,
|
|
),
|
|
)
|
|
..libraries.add(
|
|
new Library(
|
|
first ? importUri2 : importUri1,
|
|
fileUri: first ? fileUri2 : fileUri1,
|
|
),
|
|
);
|
|
},
|
|
inequivalence: '''
|
|
Inequivalent nodes
|
|
1: library import://uri1
|
|
2: library import://uri2
|
|
.root
|
|
Component.libraries[0]
|
|
''',
|
|
unorderedLibraries: true,
|
|
),
|
|
new Test(
|
|
(bool first) {
|
|
Component c = new Component();
|
|
Library library1 = new Library(importUri1, fileUri: fileUri1);
|
|
Library library2 = new Library(importUri2, fileUri: fileUri2);
|
|
c.libraries.add(library1);
|
|
c.libraries.add(library2);
|
|
library1.dependencies
|
|
..add(new LibraryDependency.import(first ? library2 : library1))
|
|
..add(new LibraryDependency.import(first ? library1 : library2));
|
|
return c;
|
|
},
|
|
inequivalence: '''
|
|
Inequivalent references:
|
|
1: Reference to library import://uri2
|
|
2: Reference to library import://uri1
|
|
.root
|
|
Component.libraries[0]
|
|
Library(library import://uri1).dependencies[0]
|
|
LibraryDependency.importedLibraryReference
|
|
Inequivalent references:
|
|
1: Reference to library import://uri1
|
|
2: Reference to library import://uri2
|
|
.root
|
|
Component.libraries[0]
|
|
Library(library import://uri1).dependencies[1]
|
|
LibraryDependency.importedLibraryReference
|
|
''',
|
|
unorderedLibraryDependencies: true,
|
|
),
|
|
new Test(
|
|
(bool first) {
|
|
Component c = new Component();
|
|
Library l = new Library(importUri1, fileUri: fileUri1);
|
|
c.libraries.add(l);
|
|
Field f1 = new Field.immutable(new Name('field1'), fileUri: fileUri1);
|
|
l.addField(f1);
|
|
Field f2 = new Field.immutable(new Name('field2'), fileUri: fileUri1);
|
|
l.addField(f2);
|
|
l.additionalExports.add(first ? f1.getterReference : f2.getterReference);
|
|
l.additionalExports.add(first ? f2.getterReference : f1.getterReference);
|
|
return c;
|
|
},
|
|
inequivalence: '''
|
|
Inequivalent references:
|
|
1: Reference to field1
|
|
2: Reference to field2
|
|
.root
|
|
Component.libraries[0]
|
|
Library(library import://uri1).additionalExports[0]
|
|
''',
|
|
unorderedAdditionalExports: true,
|
|
),
|
|
new Test(
|
|
(bool first) {
|
|
Component c = new Component();
|
|
Library l = new Library(importUri1, fileUri: fileUri1);
|
|
c.libraries.add(l);
|
|
l.parts
|
|
..add(
|
|
new LibraryPart([], first ? '${fileUri2}' : '${fileUri3}')
|
|
..parent = l,
|
|
)
|
|
..add(
|
|
new LibraryPart([], first ? '${fileUri3}' : '${fileUri2}')
|
|
..parent = l,
|
|
);
|
|
return c;
|
|
},
|
|
inequivalence: '''
|
|
Values file://uri2/ and file://uri3/ are not equivalent
|
|
.root
|
|
Component.libraries[0]
|
|
Library(library import://uri1).parts[0]
|
|
LibraryPart.partUri
|
|
Values file://uri3/ and file://uri2/ are not equivalent
|
|
.root
|
|
Component.libraries[0]
|
|
Library(library import://uri1).parts[1]
|
|
LibraryPart.partUri
|
|
''',
|
|
unorderedParts: true,
|
|
),
|
|
new Test(
|
|
(bool first) {
|
|
Component c = new Component();
|
|
Library l = new Library(importUri1, fileUri: fileUri1);
|
|
c.libraries.add(l);
|
|
l
|
|
..addTypedef(
|
|
new Typedef(
|
|
first ? 'Typedef1' : 'Typedef2',
|
|
const DynamicType(),
|
|
fileUri: fileUri1,
|
|
),
|
|
)
|
|
..addTypedef(
|
|
new Typedef(
|
|
first ? 'Typedef2' : 'Typedef1',
|
|
const DynamicType(),
|
|
fileUri: fileUri1,
|
|
),
|
|
);
|
|
return c;
|
|
},
|
|
inequivalence: '''
|
|
Inequivalent nodes
|
|
1: Typedef(Typedef1)
|
|
2: Typedef(Typedef2)
|
|
.root
|
|
Component.libraries[0]
|
|
Library(library import://uri1).typedefs[0]
|
|
''',
|
|
unorderedTypedefs: true,
|
|
),
|
|
new Test(
|
|
(bool first) {
|
|
Component c = new Component();
|
|
Library l = new Library(importUri1, fileUri: fileUri1);
|
|
c.libraries.add(l);
|
|
l
|
|
..addClass(
|
|
new Class(name: first ? 'Class1' : 'Class2', fileUri: fileUri1),
|
|
)
|
|
..addClass(
|
|
new Class(name: first ? 'Class2' : 'Class1', fileUri: fileUri1),
|
|
);
|
|
return c;
|
|
},
|
|
inequivalence: '''
|
|
Inequivalent nodes
|
|
1: Class(Class1)
|
|
2: Class(Class2)
|
|
.root
|
|
Component.libraries[0]
|
|
Library(library import://uri1).classes[0]
|
|
''',
|
|
unorderedClasses: true,
|
|
),
|
|
new Test(
|
|
(bool first) {
|
|
Component c = new Component();
|
|
Library l = new Library(importUri1, fileUri: fileUri1);
|
|
c.libraries.add(l);
|
|
Field f1 = new Field.immutable(new Name('field1'), fileUri: fileUri1);
|
|
Field f2 = new Field.immutable(new Name('field2'), fileUri: fileUri1);
|
|
l.addField(first ? f1 : f2);
|
|
l.addField(first ? f2 : f1);
|
|
Class cls = new Class(name: first ? 'Class' : 'Class', fileUri: fileUri1);
|
|
l.addClass(cls);
|
|
Field f3 = new Field.immutable(new Name('field3'), fileUri: fileUri1);
|
|
Field f4 = new Field.immutable(new Name('field4'), fileUri: fileUri1);
|
|
cls.addField(first ? f3 : f4);
|
|
cls.addField(first ? f4 : f3);
|
|
return c;
|
|
},
|
|
inequivalence: '''
|
|
Inequivalent nodes
|
|
1: Class.field3
|
|
2: Class.field4
|
|
.root
|
|
Component.libraries[0]
|
|
Library(library import://uri1).classes[0]
|
|
Class(Class).fields[0]
|
|
Inequivalent nodes
|
|
1: field1
|
|
2: field2
|
|
.root
|
|
Component.libraries[0]
|
|
Library(library import://uri1).fields[0]
|
|
''',
|
|
unorderedFields: true,
|
|
),
|
|
new Test(
|
|
(bool first) {
|
|
Component c = new Component();
|
|
Library l = new Library(importUri1, fileUri: fileUri1);
|
|
c.libraries.add(l);
|
|
Procedure p1 = new Procedure(
|
|
new Name('procedure1'),
|
|
ProcedureKind.Method,
|
|
new FunctionNode(null),
|
|
fileUri: fileUri1,
|
|
);
|
|
Procedure p2 = new Procedure(
|
|
new Name('procedure2'),
|
|
ProcedureKind.Method,
|
|
new FunctionNode(null),
|
|
fileUri: fileUri1,
|
|
);
|
|
l.addProcedure(first ? p1 : p2);
|
|
l.addProcedure(first ? p2 : p1);
|
|
Class cls = new Class(name: first ? 'Class' : 'Class', fileUri: fileUri1);
|
|
l.addClass(cls);
|
|
Procedure p3 = new Procedure(
|
|
new Name('procedure3'),
|
|
ProcedureKind.Method,
|
|
new FunctionNode(null),
|
|
fileUri: fileUri1,
|
|
);
|
|
Procedure p4 = new Procedure(
|
|
new Name('procedure4'),
|
|
ProcedureKind.Method,
|
|
new FunctionNode(null),
|
|
fileUri: fileUri1,
|
|
);
|
|
cls.addProcedure(first ? p3 : p4);
|
|
cls.addProcedure(first ? p4 : p3);
|
|
return c;
|
|
},
|
|
inequivalence: '''
|
|
Inequivalent nodes
|
|
1: Class.procedure3
|
|
2: Class.procedure4
|
|
.root
|
|
Component.libraries[0]
|
|
Library(library import://uri1).classes[0]
|
|
Class(Class).procedures[0]
|
|
Inequivalent nodes
|
|
1: procedure1
|
|
2: procedure2
|
|
.root
|
|
Component.libraries[0]
|
|
Library(library import://uri1).procedures[0]
|
|
''',
|
|
unorderedProcedures: true,
|
|
),
|
|
new Test(
|
|
(bool first) {
|
|
Component c = new Component();
|
|
Library l = new Library(importUri1, fileUri: fileUri1);
|
|
c.libraries.add(l);
|
|
Class cls = new Class(name: first ? 'Class' : 'Class', fileUri: fileUri1);
|
|
l.addClass(cls);
|
|
Constructor c1 = new Constructor(
|
|
new FunctionNode(null),
|
|
name: new Name('constructor1'),
|
|
fileUri: fileUri1,
|
|
);
|
|
Constructor c2 = new Constructor(
|
|
new FunctionNode(null),
|
|
name: new Name('constructor2'),
|
|
fileUri: fileUri1,
|
|
);
|
|
cls.addConstructor(first ? c1 : c2);
|
|
cls.addConstructor(first ? c2 : c1);
|
|
return c;
|
|
},
|
|
inequivalence: '''
|
|
Inequivalent nodes
|
|
1: Class.constructor1
|
|
2: Class.constructor2
|
|
.root
|
|
Component.libraries[0]
|
|
Library(library import://uri1).classes[0]
|
|
Class(Class).constructors[0]
|
|
''',
|
|
unorderedConstructors: true,
|
|
),
|
|
new Test(
|
|
(bool first) {
|
|
Expression createAnnotation1() =>
|
|
first ? new IntLiteral(0) : new StringLiteral("foo");
|
|
Expression createAnnotation2() =>
|
|
first ? new StringLiteral("foo") : new IntLiteral(0);
|
|
|
|
Component c = new Component();
|
|
Library l = new Library(importUri1, fileUri: fileUri1);
|
|
c.libraries.add(l);
|
|
l
|
|
..addAnnotation(createAnnotation1())
|
|
..addAnnotation(createAnnotation2());
|
|
Class cls = new Class(name: first ? 'Class' : 'Class', fileUri: fileUri1);
|
|
l.addClass(cls);
|
|
cls
|
|
..addAnnotation(createAnnotation1())
|
|
..addAnnotation(createAnnotation2());
|
|
Procedure p = new Procedure(
|
|
new Name('procedure'),
|
|
ProcedureKind.Method,
|
|
new FunctionNode(null),
|
|
fileUri: fileUri1,
|
|
);
|
|
l.addProcedure(p);
|
|
p
|
|
..addAnnotation(createAnnotation1())
|
|
..addAnnotation(createAnnotation2());
|
|
return c;
|
|
},
|
|
inequivalence: '''
|
|
Inequivalent nodes
|
|
1: IntLiteral(0)
|
|
2: StringLiteral("foo")
|
|
.root
|
|
Component.libraries[0]
|
|
Library(library import://uri1).annotations[0]
|
|
Inequivalent nodes
|
|
1: IntLiteral(0)
|
|
2: StringLiteral("foo")
|
|
.root
|
|
Component.libraries[0]
|
|
Library(library import://uri1).classes[0]
|
|
Class(Class).annotations[0]
|
|
Inequivalent nodes
|
|
1: IntLiteral(0)
|
|
2: StringLiteral("foo")
|
|
.root
|
|
Component.libraries[0]
|
|
Library(library import://uri1).procedures[0]
|
|
Procedure(procedure).annotations[0]
|
|
''',
|
|
unorderedAnnotations: true,
|
|
),
|
|
];
|
|
|
|
class Test {
|
|
final Node a;
|
|
final Node b;
|
|
final String? inequivalence;
|
|
final bool? unorderedLibraries;
|
|
final bool? unorderedLibraryDependencies;
|
|
final bool? unorderedAdditionalExports;
|
|
final bool? unorderedParts;
|
|
final bool? unorderedTypedefs;
|
|
final bool? unorderedClasses;
|
|
final bool? unorderedFields;
|
|
final bool? unorderedProcedures;
|
|
final bool? unorderedConstructors;
|
|
final bool? unorderedAnnotations;
|
|
|
|
new(
|
|
Node Function(bool) create, {
|
|
this.inequivalence,
|
|
this.unorderedLibraries,
|
|
this.unorderedLibraryDependencies,
|
|
this.unorderedAdditionalExports,
|
|
this.unorderedParts,
|
|
this.unorderedTypedefs,
|
|
this.unorderedClasses,
|
|
this.unorderedFields,
|
|
this.unorderedProcedures,
|
|
this.unorderedConstructors,
|
|
this.unorderedAnnotations,
|
|
}) : a = create(true),
|
|
b = create(false);
|
|
|
|
bool get isEquivalent => inequivalence == null;
|
|
|
|
String get options {
|
|
List<String> list = [];
|
|
if (unorderedLibraries != null) {
|
|
list.add('unorderedLibraries=$unorderedLibraries');
|
|
}
|
|
if (unorderedLibraryDependencies != null) {
|
|
list.add('unorderedLibraryDependencies=$unorderedLibraryDependencies');
|
|
}
|
|
if (unorderedAdditionalExports != null) {
|
|
list.add('unorderedAdditionalExports=$unorderedAdditionalExports');
|
|
}
|
|
if (unorderedParts != null) {
|
|
list.add('unorderedParts=$unorderedParts');
|
|
}
|
|
if (unorderedTypedefs != null) {
|
|
list.add('unorderedTypedefs=$unorderedTypedefs');
|
|
}
|
|
if (unorderedClasses != null) {
|
|
list.add('unorderedClasses=$unorderedClasses');
|
|
}
|
|
if (unorderedFields != null) {
|
|
list.add('unorderedFields=$unorderedFields');
|
|
}
|
|
if (unorderedProcedures != null) {
|
|
list.add('unorderedProcedures=$unorderedProcedures');
|
|
}
|
|
if (unorderedConstructors != null) {
|
|
list.add('unorderedConstructors=$unorderedConstructors');
|
|
}
|
|
if (unorderedAnnotations != null) {
|
|
list.add('unorderedAnnotations=$unorderedAnnotations');
|
|
}
|
|
return list.join(',');
|
|
}
|
|
}
|
|
|
|
void main() {
|
|
for (Test test in tests) {
|
|
EquivalenceResult result = checkNodeEquivalence(test.a, test.b);
|
|
if (test.isEquivalent) {
|
|
Expect.equals(
|
|
result.isEquivalent,
|
|
test.isEquivalent,
|
|
'Unexpected result for\n${test.a}\n${test.b}:\n$result',
|
|
);
|
|
Expect.equals(
|
|
'',
|
|
test.options,
|
|
'Unexpected options for\n${test.a}\n${test.b}.',
|
|
);
|
|
} else if (result.isEquivalent) {
|
|
Expect.equals(
|
|
result.isEquivalent,
|
|
test.isEquivalent,
|
|
'Unexpected equivalence for\n${test.a}\n${test.b}:\n'
|
|
'Expected ${test.inequivalence}',
|
|
);
|
|
} else {
|
|
Expect.stringEquals(
|
|
result.toString(),
|
|
test.inequivalence!,
|
|
'Unexpected inequivalence result for\n${test.a}\n${test.b}:\n'
|
|
'Expected:\n---\n${test.inequivalence}\n---\n'
|
|
'Actual:\n---\n${result}\n---',
|
|
);
|
|
|
|
EquivalenceResult optionResult = checkNodeEquivalence(
|
|
test.a,
|
|
test.b,
|
|
unorderedLibraries: test.unorderedLibraries ?? false,
|
|
unorderedLibraryDependencies:
|
|
test.unorderedLibraryDependencies ?? false,
|
|
unorderedAdditionalExports: test.unorderedAdditionalExports ?? false,
|
|
unorderedParts: test.unorderedParts ?? false,
|
|
unorderedTypedefs: test.unorderedTypedefs ?? false,
|
|
unorderedClasses: test.unorderedClasses ?? false,
|
|
unorderedFields: test.unorderedFields ?? false,
|
|
unorderedProcedures: test.unorderedProcedures ?? false,
|
|
unorderedConstructors: test.unorderedConstructors ?? false,
|
|
unorderedAnnotations: test.unorderedAnnotations ?? false,
|
|
);
|
|
Expect.isTrue(
|
|
optionResult.isEquivalent,
|
|
'Unexpected result for\n${test.a}\n${test.b} with ${test.options}:\n'
|
|
'$optionResult',
|
|
);
|
|
}
|
|
}
|
|
}
|