[CFE] Change sorting in textual outline

This CL basically change two things about the sorting:
* Entities are not sorted according to metadata. Metadata just follows
  along. Before "@a class B {}" would come before "class A {}" because
  "@" comes before "c". Now "class A {}" comes first because "A" < "B".
* Sorting happens on a token level, i.e. "F<int>" will now come before
  "F2<int>" because "F" < "F2" whereas before it was the other way
  around because "F2" < "F<" (because "2" < "<").

None of it really matters as long as sorting is done the same way when
comparing the outlines.
Doing it this way makes it faster and actually brings the runtime
(in benchmarks) less than the old (now deleted) textual outline.

Change-Id: Ib1d887ab0c14519316c8e9a3da38f0dd49b4104f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/159041
Commit-Queue: Jens Johansen <jensj@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
This commit is contained in:
Jens Johansen 2020-08-21 09:55:00 +00:00 committed by commit-bot@chromium.org
parent 0d322488ae
commit f190a4ae27
46 changed files with 153 additions and 173 deletions

View file

@ -110,8 +110,6 @@ abstract class _SortableChunk extends _TokenChunk {
_SortableChunk(int originalPosition, Token startToken, Token endToken)
: super(originalPosition, startToken, endToken);
String _cachedPrint;
@override
int compareTo(_Chunk o) {
if (o is! _SortableChunk) return super.compareTo(o);
@ -124,30 +122,16 @@ abstract class _SortableChunk extends _TokenChunk {
// say "C" < "C2" where a text-sort would say "C<" > "C2". This doesn't
// really matter as long as the sorting is consistent (i.e. the textual
// outline always sorts like this).
// Token thisToken = startToken;
// Token otherToken = other.startToken;
// int steps = 0;
// while (thisToken.lexeme == otherToken.lexeme) {
// if (steps++ > 10) break;
// thisToken = thisToken.next;
// otherToken = otherToken.next;
// }
// if (thisToken.lexeme == otherToken.lexeme) return super.compareTo(o);
// return thisToken.lexeme.compareTo(otherToken.lexeme);
// Hack to make sorting similar to v1.
if (_cachedPrint == null) {
StringBuffer sb = new StringBuffer();
printOn(sb, "");
_cachedPrint = sb.toString();
Token thisToken = startToken;
Token otherToken = other.startToken;
int steps = 0;
while (thisToken.lexeme == otherToken.lexeme) {
if (steps++ > 10) break;
thisToken = thisToken.next;
otherToken = otherToken.next;
}
if (other._cachedPrint == null) {
StringBuffer sb = new StringBuffer();
other.printOn(sb, "");
other._cachedPrint = sb.toString();
}
return _cachedPrint.compareTo(other._cachedPrint);
if (thisToken.lexeme == otherToken.lexeme) return super.compareTo(o);
return thisToken.lexeme.compareTo(otherToken.lexeme);
}
}

View file

@ -107,12 +107,12 @@ int f1, f2;
if (result !=
"""
@a
@A(2)
typedef void F1();
@A(3)
int f1, f2;
@a
@A(3)
int f1, f2;""") {
@A(2)
typedef void F1();""") {
throw "Unexpected result: $result";
}
@ -131,12 +131,12 @@ int f1, f2;
if (result !=
"""
@a
@A(2)
typedef void F1();
@A(3)
int f1, f2;
@a
@A(3)
int f1, f2;""") {
@A(2)
typedef void F1();""") {
throw "Unexpected result: $result";
}
@ -308,10 +308,10 @@ class Class1 {
if (result !=
"""
class Class1 {
Class1 get nonNullable1 => property1;
Class1? get nullable1 => property1;
Class2 get property1 => new Class1();
Class1 get nonNullable1 => property1;
Class2? get property => null;
Class2 get property1 => new Class1();
}""") {
throw "Unexpected result: $result";
}
@ -328,10 +328,10 @@ class D2 = Super with Mixin;
addMarkerForUnknownForTest: true);
if (result !=
"""
class C2<V> = Super<V> with Mixin<V>;
class C<V> extends Super<V> with Mixin<V> {}
class C2<V> = Super<V> with Mixin<V>;
class D extends Super with Mixin {}
class D2 = Super with Mixin;""") {

View file

@ -2,13 +2,15 @@
@A(1)
library test;
class A {
const A(int value);
}
@a
@A(2)
class C {}
@a
@A(2)
typedef void F1();
const Object a = const Object();
@a
@A(3)
int f1, f2;
@ -16,11 +18,8 @@ int f1, f2;
@A(3)
typedef F2 = void Function();
@a
@A(2)
typedef void F1();
@a
@A(4)
void main() {}
class A {
const A(int value);
}
const Object a = const Object();

View file

@ -2,11 +2,11 @@ import "package:ffi/ffi.dart";
import 'dart:ffi';
class Coordinate extends Struct {
Pointer<Coordinate> next;
@Double()
double x;
@Double()
double y;
Pointer<Coordinate> next;
factory Coordinate.allocate(double x, double y, Pointer<Coordinate> next) {}
}

View file

@ -24,9 +24,9 @@ typedef H3 = void Function(void Function<T, S>());
typedef H4 = void Function(void Function<T extends num, S extends num>());
typedef H5 = void Function(void Function<T extends S, S extends num>());
typedef H6 = void Function(void Function<T extends num, S extends T>());
void Function<T, S>() f3;
void Function<T>() f1;
void Function<T extends S, S extends num>() f5;
void Function<T extends num, S extends T>() f6;
void Function<T extends num, S extends num>() f4;
void Function<T extends num>() f2;
void Function<T, S>() f3;
void Function<T>() f1;

View file

@ -62,6 +62,7 @@ class C implements A<int>, B<int, String> {
this.field18);
int field12;
int field14;
var field1;
var field10;
var field11;
var field13 = 0;
@ -69,7 +70,6 @@ class C implements A<int>, B<int, String> {
var field16;
var field17;
var field18;
var field1;
var field2;
var field3 = 0;
var field4 = 0;
@ -102,6 +102,7 @@ class D<T> implements A<T>, B<T, T> {
this.field18);
T field12;
T field14;
var field1;
var field10;
var field11;
var field13 = null;
@ -109,7 +110,6 @@ class D<T> implements A<T>, B<T, T> {
var field16;
var field17;
var field18;
var field1;
var field2;
var field3 = 0;
var field4 = 0;

View file

@ -1,4 +1,4 @@
const a = null;
@a
enum E { E1, E2, E3 }
const a = null;
main() {}

View file

@ -18,28 +18,28 @@ class C<T> {
S Function<S extends T>() get getter12 => field12;
S Function<S extends T>(S) field14;
S Function<S extends T>(S) get getter14 => field14;
T Function(T Function()) field7;
T Function(T Function()) get getter7 => field7;
T Function(T Function(T)) field11;
T Function(T Function(T)) get getter11 => field11;
T Function(T) field4;
T Function(T) get getter4 => field4;
T Function() Function() field5;
T Function() Function() get getter5 => field5;
T Function() field2;
T Function() get getter2 => field2;
T Function(T) field4;
T Function(T) get getter4 => field4;
T Function(T Function()) field7;
T Function(T Function()) get getter7 => field7;
T Function(T Function(T)) field11;
T Function(T Function(T)) get getter11 => field11;
T Function(void Function(T)) field9;
T Function(void Function(T)) get getter9 => field9;
T field1;
T get getter1 => field1;
void Function(S Function<S extends T>()) field15;
void Function(S Function<S extends T>()) get getter15 => field15;
void Function(T) field3;
void Function(T) get getter3 => field3;
void Function(T Function()) field6;
void Function(T Function()) get getter6 => field6;
void Function(T Function(T)) field10;
void Function(T Function(T)) get getter10 => field10;
void Function(T) field3;
void Function(T) get getter3 => field3;
void Function(S Function<S extends T>()) field15;
void Function(S Function<S extends T>()) get getter15 => field15;
void Function(void Function(T)) field8;
void Function(void Function(T)) get getter8 => field8;
void Function<S extends T>(S) field13;

View file

@ -26,10 +26,10 @@ class SimpleCase<A, B> {
factory SimpleCase() = SimpleCaseImpl<A, B>;
}
class SimpleCaseImpl2<Ai2, Bi2> implements SimpleCaseImpl<Ai2, Bi2> {}
class SimpleCaseImpl<Ai, Bi> implements SimpleCase<Ai, Bi> {
factory SimpleCaseImpl() = SimpleCaseImpl2<Ai, Bi>;
}
class SimpleCaseImpl2<Ai2, Bi2> implements SimpleCaseImpl<Ai2, Bi2> {}
main() {}

View file

@ -1,7 +1,7 @@
class Foo {
Foo.named(p);
@forFactoryItself
factory Foo(@forParameter @anotherForParameter p) = Foo.named;
Foo.named(p);
}
const anotherForParameter = 3;

View file

@ -1,8 +1,8 @@
@A
class B {}
class A {
const A();
}
@A
class B {}
main() {}

View file

@ -13,8 +13,8 @@ class C<T1, T2, T3> extends B {}
class D<P, Q> extends C<int, Q, P> {
D(tt) : foo = tt;
Map<P, Q> foo4(w) {}
Map<P, Q> foo;
Map<P, Q> foo4(w) {}
foo2(y) {}
foo3<T1, T2>(z) {}
}

View file

@ -3,13 +3,15 @@
@A(1)
library test;
class A {
const A(int value);
}
@a
@A(2)
class C {}
@a
@A(2)
typedef void F1();
const Object a = const Object();
@a
@A(3)
int f1, f2;
@ -17,11 +19,8 @@ int f1, f2;
@A(3)
typedef F2 = void Function();
@a
@A(2)
typedef void F1();
@a
@A(4)
void main() {}
class A {
const A(int value);
}
const Object a = const Object();

View file

@ -3,11 +3,11 @@ import "package:ffi/ffi.dart";
import 'dart:ffi';
class Coordinate extends Struct {
Pointer<Coordinate> next;
@Double()
double x;
@Double()
double y;
Pointer<Coordinate> next;
factory Coordinate.allocate(double x, double y, Pointer<Coordinate> next) {}
}

View file

@ -1,5 +1,5 @@
// @dart = 2.6
const a = null;
@a
enum E { E1, E2, E3 }
const a = null;
main() {}

View file

@ -19,28 +19,28 @@ class C<T> {
S Function<S extends T>() get getter12 => field12;
S Function<S extends T>(S) field14;
S Function<S extends T>(S) get getter14 => field14;
T Function(T Function()) field7;
T Function(T Function()) get getter7 => field7;
T Function(T Function(T)) field11;
T Function(T Function(T)) get getter11 => field11;
T Function(T) field4;
T Function(T) get getter4 => field4;
T Function() Function() field5;
T Function() Function() get getter5 => field5;
T Function() field2;
T Function() get getter2 => field2;
T Function(T) field4;
T Function(T) get getter4 => field4;
T Function(T Function()) field7;
T Function(T Function()) get getter7 => field7;
T Function(T Function(T)) field11;
T Function(T Function(T)) get getter11 => field11;
T Function(void Function(T)) field9;
T Function(void Function(T)) get getter9 => field9;
T field1;
T get getter1 => field1;
void Function(S Function<S extends T>()) field15;
void Function(S Function<S extends T>()) get getter15 => field15;
void Function(T) field3;
void Function(T) get getter3 => field3;
void Function(T Function()) field6;
void Function(T Function()) get getter6 => field6;
void Function(T Function(T)) field10;
void Function(T Function(T)) get getter10 => field10;
void Function(T) field3;
void Function(T) get getter3 => field3;
void Function(S Function<S extends T>()) field15;
void Function(S Function<S extends T>()) get getter15 => field15;
void Function(void Function(T)) field8;
void Function(void Function(T)) get getter8 => field8;
void Function<S extends T>(S) field13;

View file

@ -27,10 +27,10 @@ class SimpleCase<A, B> {
factory SimpleCase() = SimpleCaseImpl<A, B>;
}
class SimpleCaseImpl2<Ai2, Bi2> implements SimpleCaseImpl<Ai2, Bi2> {}
class SimpleCaseImpl<Ai, Bi> implements SimpleCase<Ai, Bi> {
factory SimpleCaseImpl() = SimpleCaseImpl2<Ai, Bi>;
}
class SimpleCaseImpl2<Ai2, Bi2> implements SimpleCaseImpl<Ai2, Bi2> {}
main() {}

View file

@ -1,8 +1,8 @@
// @dart = 2.6
class Foo {
Foo.named(p);
@forFactoryItself
factory Foo(@forParameter @anotherForParameter p) = Foo.named;
Foo.named(p);
}
const anotherForParameter = 3;

View file

@ -1,9 +1,9 @@
// @dart = 2.6
@A
class B {}
class A {
const A();
}
@A
class B {}
main() {}

View file

@ -1,10 +1,9 @@
library test;
@Foo(const [])
typedef void F();
class Foo {
const Foo(List<String> l);
}
main() {}
@Foo(const [])
typedef void F();

View file

@ -2,11 +2,11 @@ library test;
import 'dart:async';
Future f;
Future<List<int>> g2() async {}
Future<List<int>> g3() async {}
Future<List<int>> t2 = f.then((_) => [3]);
Future<int> t1 = f.then((_) => new Future.value('hi'));
Future f;
class MyFuture<T> implements Future<T> {
MyFuture() {}

View file

@ -2,11 +2,11 @@ library test;
import 'dart:async';
Future f;
Future<List<int>> g2() async {}
Future<List<int>> g3() async {}
Future<List<int>> t2 = f.then((_) => [3]);
Future<int> t1 = f.then((_) => new MyFuture.value('hi'));
Future f;
class MyFuture<T> implements Future<T> {
MyFuture() {}

View file

@ -5,6 +5,6 @@ class Class<E> {
}
expect(expected, actual) {}
int returnNonNullable(int value) {}
int? returnNullable(int? value) {}
int returnNonNullable(int value) {}
main() {}

View file

@ -5,9 +5,9 @@ class Class {
const Class e = const Class(a);
const Class f = const Class(c);
const int b = a!;
const int? a = 42;
const int? c = null;
const int? d = c!;
const int b = a!;
expect(expected, actual) {}
main() {}

View file

@ -1,5 +1,5 @@
F bar() => foo;
F? baz() => foo;
F bar() => foo;
Function()? foobar(Function()? x) => null;
class A<T> {}
@ -10,6 +10,6 @@ class B extends A<Function()?> {
main() {}
typedef F = void Function();
void Function() hest() => foo;
void Function()? fisk() => foo;
void Function() hest() => foo;
void foo() {}

View file

@ -1,16 +1,16 @@
import 'dart:async';
FutureOr topLevelField1;
FutureOr<FutureOr> topLevelField3;
FutureOr<int?> topLevelField2;
FutureOr topLevelField1;
class Class1 {
FutureOr instanceField1;
FutureOr<FutureOr> instanceField3;
FutureOr<int?> instanceField2;
static FutureOr staticField1;
FutureOr instanceField1;
static FutureOr<FutureOr> staticField3;
static FutureOr<int?> staticField2;
static FutureOr staticField1;
static void staticMethod1(
[FutureOr parameter1,
FutureOr<int?> parameter2,
@ -33,9 +33,9 @@ class Class2 {
Class2.constructor1(
this.instanceField1, this.instanceField2, this.instanceField3);
Class2.constructor2();
FutureOr instanceField1;
FutureOr<FutureOr> instanceField3;
FutureOr<int?> instanceField2;
FutureOr instanceField1;
}
main() {}

View file

@ -24,6 +24,6 @@ final s9 = s7[0] = 0;
final t = StreamTransformer.fromHandlers(
handleData: (data, sink) => Future.microtask(() => sink.add(data)),
handleDone: (sink) => Future.microtask(() => sink.close()));
int Function()? s13;
int? s5;
int Function()? s13;
void main() {}

View file

@ -6,5 +6,5 @@ class A<T> {
}
main() {}
wrap2<R>(A<R> Function() f) {}
wrap<R>(R Function() f) {}
wrap2<R>(A<R> Function() f) {}

View file

@ -2,9 +2,9 @@ class Class {
Class call() => this;
Class get nonNullableClass => this;
NullableIndexClass get nonNullableNullableIndexClass => NullableIndexClass();
int? nullableField;
int nonNullableField = 0;
int operator [](int key) => key;
int? nullableField;
void operator []=(int key, int value) {}
}

View file

@ -1,8 +1,8 @@
class Class {
Class get getter1 => this;
Class([this.field]);
Class? field;
Class? get getter2 => field;
Class get getter1 => this;
}
main() {}

View file

@ -1,12 +1,12 @@
class Class1 {
Class1 get nonNullable1 => property1;
Class1 get property1 => new Class1();
Class1 nonNullable1Method() => nonNullable1;
Class1? get nullable1 => property1;
Class1? get property => null;
Class1? operator +(int value) => nullable1;
Class1? operator -() => nullable1;
Class1? operator [](Class1? key) => nullable1;
Class1 get nonNullable1 => property1;
Class1 get property1 => new Class1();
Class1 nonNullable1Method() => nonNullable1;
Class2 get nonNullable2 => property2;
Class2 get property2 => new Class2();
void operator []=(Class1? key, Class1? value) {}

View file

@ -7,8 +7,8 @@ class B1 {
}
class B2 extends B1 {
num bar = 3.14;
num? get baz => null;
num bar = 3.14;
void hest(num value) {}
}

View file

@ -1,6 +1,6 @@
class A<T> {
T get current => _current as T;
T? _current;
T get current => _current as T;
}
main() {}

View file

@ -5,6 +5,6 @@ class Class<E> {
}
expect(expected, actual) {}
int returnNonNullable(int value) {}
int? returnNullable(int? value) {}
int returnNonNullable(int value) {}
main() {}

View file

@ -2,12 +2,12 @@ import 'dart:async';
Enum caseReturn1(Enum e) {}
Enum caseReturn2(Enum e) {}
Future returnAsync1() async {}
Future<int?> returnAsync6() async {}
Future<int?> returnAsync7() async {}
FutureOr returnAsync2() async {}
Future returnAsync1() async {}
FutureOr<int> returnAsync3() async {}
FutureOr<int?> returnAsync4() async {}
FutureOr returnAsync2() async {}
Iterable yieldSync() sync* {}
Stream yieldAsync() async* {}
String returnExplicit() {}

View file

@ -1,3 +1,3 @@
Never foo() {}
Never? bar() => null;
Never foo() {}
main() {}

View file

@ -1,8 +1,8 @@
Never never() => throw "Never";
class A<X extends Object, Y extends Object?> {
X foo() => never();
X? bar() => null;
X foo() => never();
Y baz() => never();
}

View file

@ -3,18 +3,6 @@ library main;
import 'member_inheritance_from_opt_out_lib.dart';
abstract class Interface {
int field1 = 0;
int get field3;
int get getter1;
int get property1;
int method1();
int method3a(int a, int b);
int method3b(int a, [int b]);
int method3c([int a, int b]);
int method5a(int a, {int b: 0});
int method5b({int a: 0, int b: 0});
int method5c({required int a, required int b});
int property3 = 0;
int? field2;
int? get field4;
int? get getter2;
@ -27,6 +15,18 @@ abstract class Interface {
int? method6b({int? a, int? b});
int? method6c({required int? a, required int? b});
int? property4;
int field1 = 0;
int get field3;
int get getter1;
int get property1;
int method1();
int method3a(int a, int b);
int method3b(int a, [int b]);
int method3c([int a, int b]);
int method5a(int a, {int b: 0});
int method5b({int a: 0, int b: 0});
int method5c({required int a, required int b});
int property3 = 0;
void set field3(int value);
void set field4(int? value);
void set property1(int value);
@ -40,18 +40,6 @@ class Class1 extends LegacyClass {}
class Class2a extends LegacyClass implements Interface {}
class Class2b extends LegacyClass implements Interface {
int field1 = 0;
int get field3 => 0;
int get getter1 => 0;
int get property1 => 0;
int method1() => 0;
int method3a(int a, int b) => 0;
int method3b(int a, [int b = 42]) => 0;
int method3c([int a = 42, int b = 42]) => 0;
int method5a(int a, {int b: 0}) => 0;
int method5b({int a: 0, int b: 0}) => 0;
int method5c({required int a, required int b}) => 0;
int property3 = 0;
int? field2;
int? get field4 => 0;
int? get getter2 => 0;
@ -64,6 +52,18 @@ class Class2b extends LegacyClass implements Interface {
int? method6b({int? a, int? b}) => 0;
int? method6c({required int? a, required int? b}) => 0;
int? property4;
int field1 = 0;
int get field3 => 0;
int get getter1 => 0;
int get property1 => 0;
int method1() => 0;
int method3a(int a, int b) => 0;
int method3b(int a, [int b = 42]) => 0;
int method3c([int a = 42, int b = 42]) => 0;
int method5a(int a, {int b: 0}) => 0;
int method5b({int a: 0, int b: 0}) => 0;
int method5c({required int a, required int b}) => 0;
int property3 = 0;
void set field3(int value) {}
void set field4(int? value) {}
void set property1(int value) {}

View file

@ -1,24 +1,24 @@
import 'messages_with_types_opt_out.dart';
class SubInIn extends SuperIn {
String nonNullableSame() => "bar";
String? nullableSame() => "foo";
T nonNullableBad<T>(T t) => t;
String nonNullableSame() => "bar";
T? nullableBad<T>(T t) => null;
T nonNullableBad<T>(T t) => t;
}
class SubOutIn extends SuperOut {
String nonNullableSame() => "bar";
String? nullableSame() => "foo";
T nonNullableBad<T>(T t) => t;
String nonNullableSame() => "bar";
T? nullableBad<T>(T t) => null;
T nonNullableBad<T>(T t) => t;
}
class SuperIn {
String nonNullableSame() => "bar";
String? nullableSame() => "foo";
int nonNullableBad<T>(T t) => 2;
String nonNullableSame() => "bar";
int? nullableBad<T>(T t) => 1;
int nonNullableBad<T>(T t) => 2;
}
double nonNullableVar = 4.0;

View file

@ -11,14 +11,14 @@ class B<S> extends A<S> {
factory B.b() = C<C2>;
}
class C<U> extends B<U> {
C() : super.internal();
}
class C1 {}
class C2 {}
class C3 {}
class C<U> extends B<U> {
C() : super.internal();
}
main() {}

View file

@ -1,9 +1,9 @@
import "mixin_library.dart" show Mixin;
class C2<V> = Super<V> with Mixin<V>;
class C<V> extends Super<V> with Mixin<V> {}
class C2<V> = Super<V> with Mixin<V>;
class D extends Super with Mixin {}
class D2 = Super with Mixin;

View file

@ -1,6 +1,6 @@
const int y = 42;
@y
int x = 1;
@y
int x = 2;
const int y = 42;
main() {}

View file

@ -1,14 +1,13 @@
@valueClass
class A {}
@valueClass
class F = B with C;
class B {}
class C {}
class D = A with B;
class E = B with A;
@valueClass
class F = B with C;
const String valueClass = "valueClass";
main() {}

View file

@ -1,9 +1,9 @@
@valueClass
class Cat extends Animal {}
class Animal {
final int numLegs;
}
@valueClass
class Cat extends Animal {}
const String valueClass = "valueClass";
main() {}

View file

@ -1,9 +1,9 @@
@valueClass
class Cat extends Animal {}
class Animal {
int numLegs;
}
@valueClass
class Cat extends Animal {}
const String valueClass = "valueClass";
main() {}

View file

@ -1,11 +1,11 @@
class Animal {
final int numLegs;
}
@valueClass
class Cat implements Animal {
final int numLegs;
}
class Animal {
final int numLegs;
}
const String valueClass = "valueClass";
main() {}