Skip to content

Commit 1b3a032

Browse files
authored
Stabilize the global table insertion order in the new lookup code (dart-lang#2712)
* Stabilize the global table insertion order in the new lookup code. * Keep using all packages -- might be necessary in some cases and I've done all my testing that way so far. * Make byName more stable via hashCode. * No need to rename it
1 parent ba87dba commit 1b3a032

File tree

4 files changed

+45
-8
lines changed

4 files changed

+45
-8
lines changed

Diff for: lib/src/model/nameable.dart

+7-2
Original file line numberDiff line numberDiff line change
@@ -35,5 +35,10 @@ abstract class Nameable {
3535
String toString() => name;
3636
}
3737

38-
int byName(Nameable a, Nameable b) =>
39-
compareAsciiLowerCaseNatural(a.name, b.name);
38+
int byName(Nameable a, Nameable b) {
39+
var stringCompare = compareAsciiLowerCaseNatural(a.name, b.name);
40+
if (stringCompare == 0) {
41+
return a.hashCode.compareTo(b.hashCode);
42+
}
43+
return stringCompare;
44+
}

Diff for: lib/src/model/package.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,7 @@ class Package extends LibraryContainer
406406
Map<String, CommentReferable> get referenceChildren {
407407
if (_referenceChildren == null) {
408408
_referenceChildren = {};
409-
_referenceChildren.addEntries(allLibraries.generateEntries());
409+
_referenceChildren.addEntries(publicLibrariesSorted.generateEntries());
410410
// Do not override any preexisting data, and insert based on the
411411
// public library sort order.
412412
// TODO(jcollins-g): warn when results require package-global

Diff for: lib/src/model/package_graph.dart

+12-5
Original file line numberDiff line numberDiff line change
@@ -1030,19 +1030,26 @@ class PackageGraph with CommentReferable, Nameable {
10301030
Map<String, CommentReferable> get referenceChildren {
10311031
if (_referenceChildren == null) {
10321032
_referenceChildren = {};
1033+
// We have to use a stable order or otherwise references depending
1034+
// on ambiguous resolution (see below) will change where they
1035+
// resolve based on internal implementation details.
1036+
var sortedPackages = packages.toList()..sort(byName);
1037+
var sortedDocumentedPackages = documentedPackages.toList()..sort(byName);
10331038
// Packages are the top priority.
1034-
_referenceChildren.addEntries(packages.generateEntries());
1039+
_referenceChildren.addEntries(sortedPackages.generateEntries());
10351040

10361041
// Libraries are next.
10371042
// TODO(jcollins-g): Warn about directly referencing libraries out of
1038-
// scope?
1039-
_referenceChildren.addEntriesIfAbsent(documentedPackages
1043+
// scope? Doing this is always going to be ambiguous and potentially
1044+
// confusing.
1045+
_referenceChildren.addEntriesIfAbsent(sortedDocumentedPackages
10401046
.expand((p) => p.publicLibrariesSorted)
10411047
.generateEntries());
10421048

10431049
// TODO(jcollins-g): Warn about directly referencing top level items
1044-
// out of scope?
1045-
_referenceChildren.addEntriesIfAbsent(documentedPackages
1050+
// out of scope? Doing this will be even more ambiguous and
1051+
// potentially confusing than doing so with libraries.
1052+
_referenceChildren.addEntriesIfAbsent(sortedDocumentedPackages
10461053
.expand((p) => p.publicLibrariesSorted)
10471054
.expand((l) => [
10481055
...l.publicConstants,

Diff for: test/end2end/model_test.dart

+25
Original file line numberDiff line numberDiff line change
@@ -4970,6 +4970,16 @@ String topLevelFunction(int param1, bool param2, Cool coolBeans,
49704970
expect(byName(b, a), 1);
49714971
});
49724972
}
4973+
4974+
test('sort order is stable when necessary', () {
4975+
var a = StringNameHashCode('a', 12);
4976+
var b = StringNameHashCode('b', 12);
4977+
var aa = StringNameHashCode('a', 14);
4978+
expect(byName(a, aa), -1);
4979+
expect(byName(a, b), -1);
4980+
expect(byName(b, a), 1);
4981+
expect(byName(aa, b), -1);
4982+
});
49734983
});
49744984
}
49754985

@@ -4982,3 +4992,18 @@ class StringName extends Nameable {
49824992
@override
49834993
String toString() => name;
49844994
}
4995+
4996+
class StringNameHashCode extends Nameable {
4997+
@override
4998+
final String name;
4999+
@override
5000+
final int hashCode;
5001+
5002+
StringNameHashCode(this.name, this.hashCode);
5003+
5004+
@override
5005+
String toString() => name;
5006+
5007+
@override
5008+
bool operator ==(Object other) => super == other;
5009+
}

0 commit comments

Comments
 (0)