da4e3f4bbe
The incremental compiler now passes the correct nnbd settings and extension methods settings. Change-Id: I89e6bad8af330c3c81f141c260b2325aca4a5bb1 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/182630 Commit-Queue: Jens Johansen <jensj@google.com> Reviewed-by: Johnni Winther <johnniwinther@google.com>
444 lines
9.2 KiB
Dart
444 lines
9.2 KiB
Dart
// Copyright (c) 2020, 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.md file.
|
|
|
|
// @dart = 2.9
|
|
|
|
import "dart:convert";
|
|
|
|
import 'package:_fe_analyzer_shared/src/scanner/abstract_scanner.dart'
|
|
show ScannerConfiguration;
|
|
|
|
import "package:front_end/src/fasta/util/textual_outline.dart"
|
|
show textualOutline;
|
|
|
|
const ScannerConfiguration scannerConfiguration =
|
|
const ScannerConfiguration(enableExtensionMethods: true);
|
|
|
|
main() {
|
|
// Doesn't sort if not asked to perform modelling.
|
|
String result = textualOutline(utf8.encode("""
|
|
b() { print("hello"); }
|
|
a() { print("hello"); }
|
|
"""), scannerConfiguration, throwOnUnexpected: true, performModelling: false);
|
|
if (result !=
|
|
"""
|
|
b() {}
|
|
|
|
a() {}""") {
|
|
throw "Unexpected result: $result";
|
|
}
|
|
|
|
// Sort if asked to perform modelling.
|
|
result = textualOutline(utf8.encode("""
|
|
b() { print("hello"); }
|
|
a() { print("hello"); }
|
|
"""), scannerConfiguration,
|
|
throwOnUnexpected: true,
|
|
performModelling: true,
|
|
addMarkerForUnknownForTest: true);
|
|
if (result !=
|
|
"""
|
|
a() {}
|
|
|
|
b() {}""") {
|
|
throw "Unexpected result: $result";
|
|
}
|
|
|
|
// Content between braces or not doesn't make any difference.
|
|
// Procedure without content.
|
|
result = textualOutline(utf8.encode("""
|
|
a() {}
|
|
"""), scannerConfiguration,
|
|
throwOnUnexpected: true,
|
|
performModelling: true,
|
|
addMarkerForUnknownForTest: true);
|
|
if (result !=
|
|
"""
|
|
a() {}""") {
|
|
throw "Unexpected result: $result";
|
|
}
|
|
|
|
// Procedure with content.
|
|
result = textualOutline(utf8.encode("""
|
|
a() {
|
|
// Whatever
|
|
}
|
|
"""), scannerConfiguration,
|
|
throwOnUnexpected: true,
|
|
performModelling: true,
|
|
addMarkerForUnknownForTest: true);
|
|
if (result !=
|
|
"""
|
|
a() {}""") {
|
|
throw "Unexpected result: $result";
|
|
}
|
|
|
|
// Class without content.
|
|
result = textualOutline(utf8.encode("""
|
|
class B {}
|
|
class A {}
|
|
"""), scannerConfiguration,
|
|
throwOnUnexpected: true,
|
|
performModelling: true,
|
|
addMarkerForUnknownForTest: true);
|
|
if (result !=
|
|
"""
|
|
class A {}
|
|
|
|
class B {}""") {
|
|
throw "Unexpected result: $result";
|
|
}
|
|
|
|
// Class without real content.
|
|
result = textualOutline(utf8.encode("""
|
|
class A {
|
|
// Whatever
|
|
}
|
|
"""), scannerConfiguration,
|
|
throwOnUnexpected: true,
|
|
performModelling: true,
|
|
addMarkerForUnknownForTest: true);
|
|
if (result !=
|
|
"""
|
|
class A {}""") {
|
|
throw "Unexpected result: $result";
|
|
}
|
|
|
|
// Has space between entries.
|
|
result = textualOutline(utf8.encode("""
|
|
@a
|
|
@A(2)
|
|
typedef void F1();
|
|
|
|
@a
|
|
@A(3)
|
|
int f1, f2;
|
|
"""), scannerConfiguration,
|
|
throwOnUnexpected: true,
|
|
performModelling: true,
|
|
addMarkerForUnknownForTest: true);
|
|
if (result !=
|
|
"""
|
|
@a
|
|
@A(3)
|
|
int f1, f2;
|
|
|
|
@a
|
|
@A(2)
|
|
typedef void F1();""") {
|
|
throw "Unexpected result: $result";
|
|
}
|
|
|
|
// Has space between entries.
|
|
result = textualOutline(utf8.encode("""
|
|
@a
|
|
@A(2)
|
|
typedef void F1();
|
|
@a
|
|
@A(3)
|
|
int f1, f2;
|
|
"""), scannerConfiguration,
|
|
throwOnUnexpected: true,
|
|
performModelling: true,
|
|
addMarkerForUnknownForTest: true);
|
|
if (result !=
|
|
"""
|
|
@a
|
|
@A(3)
|
|
int f1, f2;
|
|
|
|
@a
|
|
@A(2)
|
|
typedef void F1();""") {
|
|
throw "Unexpected result: $result";
|
|
}
|
|
|
|
// Knows about and can sort named mixin applications.
|
|
result = textualOutline(utf8.encode("""
|
|
class C<T> = Object with A<Function(T)>;
|
|
class B<T> = Object with A<Function(T)>;
|
|
class A<T> {}
|
|
"""), scannerConfiguration,
|
|
throwOnUnexpected: true,
|
|
performModelling: true,
|
|
addMarkerForUnknownForTest: true);
|
|
if (result !=
|
|
"""
|
|
class A<T> {}
|
|
|
|
class B<T> = Object with A<Function(T)>;
|
|
|
|
class C<T> = Object with A<Function(T)>;""") {
|
|
throw "Unexpected result: $result";
|
|
}
|
|
|
|
// Knows about and can sort imports, but doesn't mix them with the other
|
|
// content.
|
|
result = textualOutline(utf8.encode("""
|
|
import "foo.dart" show B,
|
|
A,
|
|
C;
|
|
import "bar.dart";
|
|
|
|
main() {}
|
|
|
|
import "baz.dart";
|
|
"""), scannerConfiguration,
|
|
throwOnUnexpected: true,
|
|
performModelling: true,
|
|
addMarkerForUnknownForTest: true,
|
|
returnNullOnError: false);
|
|
if (result !=
|
|
"""
|
|
import "bar.dart";
|
|
import "foo.dart" show A, B, C;
|
|
|
|
main() {}
|
|
|
|
import "baz.dart";""") {
|
|
throw "Unexpected result: $result";
|
|
}
|
|
|
|
// Knows about and can sort exports, but doesn't mix them with the other
|
|
// content.
|
|
result = textualOutline(utf8.encode("""
|
|
export "foo.dart" show B,
|
|
A,
|
|
C;
|
|
export "bar.dart";
|
|
|
|
main() {}
|
|
|
|
export "baz.dart";
|
|
"""), scannerConfiguration,
|
|
throwOnUnexpected: true,
|
|
performModelling: true,
|
|
addMarkerForUnknownForTest: true,
|
|
returnNullOnError: false);
|
|
if (result !=
|
|
"""
|
|
export "bar.dart";
|
|
export "foo.dart" show A, B, C;
|
|
|
|
main() {}
|
|
|
|
export "baz.dart";""") {
|
|
throw "Unexpected result: $result";
|
|
}
|
|
|
|
// Knows about and can sort imports and exports,
|
|
// but doesn't mix them with the other content.
|
|
result = textualOutline(utf8.encode("""
|
|
export "foo.dart" show B,
|
|
A,
|
|
C;
|
|
import "foo.dart" show B,
|
|
A,
|
|
C;
|
|
export "bar.dart";
|
|
import "bar.dart";
|
|
|
|
main() {}
|
|
|
|
export "baz.dart";
|
|
import "baz.dart";
|
|
"""), scannerConfiguration,
|
|
throwOnUnexpected: true,
|
|
performModelling: true,
|
|
addMarkerForUnknownForTest: true,
|
|
returnNullOnError: false);
|
|
if (result !=
|
|
"""
|
|
export "bar.dart";
|
|
export "foo.dart" show A, B, C;
|
|
import "bar.dart";
|
|
import "foo.dart" show A, B, C;
|
|
|
|
main() {}
|
|
|
|
export "baz.dart";
|
|
import "baz.dart";""") {
|
|
throw "Unexpected result: $result";
|
|
}
|
|
|
|
// Knows about library, part and part of but they cannot be sorted.
|
|
result = textualOutline(utf8.encode("""
|
|
part "foo.dart";
|
|
part of "foo.dart";
|
|
library foo;
|
|
|
|
bar() {
|
|
// whatever
|
|
}
|
|
"""), scannerConfiguration,
|
|
throwOnUnexpected: true,
|
|
performModelling: true,
|
|
addMarkerForUnknownForTest: true,
|
|
returnNullOnError: false);
|
|
if (result !=
|
|
"""
|
|
part "foo.dart";
|
|
|
|
part of "foo.dart";
|
|
|
|
library foo;
|
|
|
|
bar() {}""") {
|
|
throw "Unexpected result: $result";
|
|
}
|
|
|
|
// Ending metadata (not associated with anything) is still present.
|
|
result = textualOutline(utf8.encode("""
|
|
@Object2()
|
|
foo() {
|
|
// hello
|
|
}
|
|
|
|
@Object1()
|
|
"""), scannerConfiguration,
|
|
throwOnUnexpected: true,
|
|
performModelling: true,
|
|
addMarkerForUnknownForTest: true,
|
|
returnNullOnError: false);
|
|
if (result !=
|
|
"""
|
|
@Object2()
|
|
foo() {}
|
|
|
|
@Object1()""") {
|
|
throw "Unexpected result: $result";
|
|
}
|
|
|
|
// Sorting of question mark types.
|
|
result = textualOutline(utf8.encode("""
|
|
class Class1 {
|
|
Class1? get nullable1 => property1;
|
|
Class2? get property => null;
|
|
Class1 get nonNullable1 => property1;
|
|
Class2 get property1 => new Class1();
|
|
}
|
|
"""), scannerConfiguration,
|
|
throwOnUnexpected: true,
|
|
performModelling: true,
|
|
addMarkerForUnknownForTest: true);
|
|
if (result !=
|
|
"""
|
|
class Class1 {
|
|
Class1? get nullable1 => property1;
|
|
Class1 get nonNullable1 => property1;
|
|
Class2? get property => null;
|
|
Class2 get property1 => new Class1();
|
|
}""") {
|
|
throw "Unexpected result: $result";
|
|
}
|
|
|
|
// Sorting of various classes with numbers and less than.
|
|
result = textualOutline(utf8.encode("""
|
|
class C2<V> = Super<V> with Mixin<V>;
|
|
class C<V> extends Super<V> with Mixin<V> {}
|
|
class D extends Super with Mixin {}
|
|
class D2 = Super with Mixin;
|
|
"""), scannerConfiguration,
|
|
throwOnUnexpected: true,
|
|
performModelling: true,
|
|
addMarkerForUnknownForTest: true);
|
|
if (result !=
|
|
"""
|
|
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;""") {
|
|
throw "Unexpected result: $result";
|
|
}
|
|
|
|
// Metadata on imports / exports.
|
|
result = textualOutline(utf8.encode("""
|
|
@Object1
|
|
export "a3.dart";
|
|
@Object2
|
|
import "a2.dart";
|
|
@Object3
|
|
export "a1.dart";
|
|
@Object4
|
|
import "a0.dart";
|
|
"""), scannerConfiguration,
|
|
throwOnUnexpected: true,
|
|
performModelling: true,
|
|
addMarkerForUnknownForTest: true);
|
|
if (result !=
|
|
"""
|
|
@Object3
|
|
export "a1.dart";
|
|
|
|
@Object1
|
|
export "a3.dart";
|
|
|
|
@Object4
|
|
import "a0.dart";
|
|
|
|
@Object2
|
|
import "a2.dart";""") {
|
|
throw "Unexpected result: $result";
|
|
}
|
|
|
|
// Doesn't crash on illegal import/export.
|
|
// Note that for now a bad import becomes unknown as it has
|
|
// 'advanced recovery' via "handleRecoverImport" whereas exports enforce the
|
|
// structure more.
|
|
result = textualOutline(utf8.encode("""
|
|
// bad line.
|
|
import "a0.dart" show
|
|
// ok line
|
|
import "a1.dart" show foo;
|
|
// bad line.
|
|
export "a2.dart" show
|
|
// ok line
|
|
export "a3.dart" show foo;
|
|
"""), scannerConfiguration,
|
|
throwOnUnexpected: true,
|
|
performModelling: true,
|
|
addMarkerForUnknownForTest: true,
|
|
returnNullOnError: false);
|
|
if (result !=
|
|
"""
|
|
---- unknown chunk starts ----
|
|
import "a0.dart" show ;
|
|
---- unknown chunk ends ----
|
|
|
|
export "a2.dart" show ;
|
|
export "a3.dart" show foo;
|
|
import "a1.dart" show foo;""") {
|
|
throw "Unexpected result: $result";
|
|
}
|
|
|
|
// Enums.
|
|
result = textualOutline(utf8.encode("""
|
|
library test;
|
|
|
|
enum E { v1 }
|
|
final x = E.v1;
|
|
|
|
main() {
|
|
x;
|
|
}
|
|
"""), scannerConfiguration,
|
|
throwOnUnexpected: true,
|
|
performModelling: true,
|
|
addMarkerForUnknownForTest: true);
|
|
if (result !=
|
|
"""
|
|
library test;
|
|
|
|
enum E { v1 }
|
|
|
|
final x = E.v1;
|
|
|
|
main() {}""") {
|
|
throw "Unexpected result: $result";
|
|
}
|
|
}
|