Skip to content

Commit f443bc9

Browse files
johnniwinthercommit-bot@chromium.org
authored andcommitted
[cfe] Add tests for inheritance from opt-out libraries
Change-Id: If139945dfdd808da0c24ac550ecfa235b41d3c23 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/123737 Commit-Queue: Johnni Winther <johnniwinther@google.com> Reviewed-by: Paul Berry <paulberry@google.com>
1 parent 6ed0fca commit f443bc9

23 files changed

+555
-60
lines changed
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
/*cfe.library: nnbd=true*/
6+
7+
import 'opt_out.dart';
8+
9+
/*class: Class1:Class1,LegacyClass1,Object*/
10+
class Class1 extends LegacyClass1 {}
11+
12+
/*class: Class2:Class2<T*>,LegacyClass2<T>,Object*/
13+
class Class2<T> extends LegacyClass2<T> {}
14+
15+
/*class: Class3a:Class3a<T*>,GenericInterface<T*>,LegacyClass3<T>,Object*/
16+
class Class3a<T> extends LegacyClass3<T> {}
17+
18+
/*class: Class3b:Class3b<T*>,GenericInterface<T*>,LegacyClass3<T>,Object*/
19+
class
20+
// TODO(johnniwinther): Avoid this error.
21+
/*error: AmbiguousSupertypes*/
22+
Class3b<T> extends LegacyClass3<T> implements GenericInterface<T> {}
23+
24+
/*class: Class4a:Class4a,GenericInterface<num*>,LegacyClass4,Object*/
25+
class Class4a extends LegacyClass4 {}
26+
27+
/*class: Class4b:Class4b,GenericInterface<num!>,Object*/
28+
class Class4b implements GenericInterface<num> {}
29+
30+
/*class: Class4c:Class4c,GenericInterface<num?>,Object*/
31+
class Class4c implements GenericInterface<num?> {}
32+
33+
/*class: Class4d:Class4d,GenericInterface<num*>,LegacyClass4,Object*/
34+
class
35+
// TODO(johnniwinther): Avoid this error.
36+
/*error: AmbiguousSupertypes*/
37+
Class4d extends LegacyClass4 implements GenericInterface<num> {}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
// @dart=2.5
6+
7+
/*library: nnbd=false*/
8+
9+
/*class: GenericInterface:GenericInterface<T*>,Object*/
10+
abstract class GenericInterface<T> {}
11+
12+
/*class: LegacyClass1:LegacyClass1,Object*/
13+
class LegacyClass1 {}
14+
15+
/*class: LegacyClass2:LegacyClass2<T*>,Object*/
16+
class LegacyClass2<T> {}
17+
18+
/*class: LegacyClass3:GenericInterface<T*>,LegacyClass3<T*>,Object*/
19+
class LegacyClass3<T> implements GenericInterface<T> {}
20+
21+
/*class: LegacyClass4:GenericInterface<num*>,LegacyClass4,Object*/
22+
class LegacyClass4 implements GenericInterface<num> {}

pkg/front_end/lib/src/testing/id_testing_helper.dart

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,17 @@ export '../fasta/messages.dart' show FormattedMessage;
3535
/// Test configuration used for testing CFE in its default state.
3636
const TestConfig defaultCfeConfig = const TestConfig(cfeMarker, 'cfe');
3737

38-
/// Test configuration used for testing CFE with nnbd.
38+
/// Test configuration used for testing CFE with nnbd in addition to the
39+
/// default state.
3940
const TestConfig cfeNonNullableConfig = const TestConfig(
4041
cfeWithNnbdMarker, 'cfe with nnbd',
4142
experimentalFlags: const {ExperimentalFlag.nonNullable: true});
4243

44+
/// Test configuration used for testing CFE with nnbd as the default state.
45+
const TestConfig cfeNonNullableOnlyConfig = const TestConfig(
46+
cfeMarker, 'cfe with nnbd',
47+
experimentalFlags: const {ExperimentalFlag.nonNullable: true});
48+
4349
class TestConfig {
4450
final String marker;
4551
final String name;

pkg/front_end/lib/src/testing/id_testing_utils.dart

Lines changed: 87 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -233,26 +233,68 @@ MemberBuilder lookupExtensionMemberBuilder(
233233

234234
/// Returns a textual representation of the constant [node] to be used in
235235
/// testing.
236-
String constantToText(Constant node, {bool isNonNullableByDefault: false}) {
236+
String constantToText(Constant node,
237+
{TypeRepresentation typeRepresentation: TypeRepresentation.legacy}) {
237238
StringBuffer sb = new StringBuffer();
238-
new ConstantToTextVisitor(sb, isNonNullableByDefault).visit(node);
239+
new ConstantToTextVisitor(sb, typeRepresentation).visit(node);
239240
return sb.toString();
240241
}
241242

243+
enum TypeRepresentation {
244+
legacy,
245+
explicit,
246+
implicitUndetermined,
247+
nonNullableByDefault,
248+
}
249+
242250
/// Returns a textual representation of the type [node] to be used in
243251
/// testing.
244-
String typeToText(DartType node, {bool isNonNullableByDefault: false}) {
252+
String typeToText(DartType node,
253+
[TypeRepresentation typeRepresentation = TypeRepresentation.legacy]) {
254+
StringBuffer sb = new StringBuffer();
255+
new DartTypeToTextVisitor(sb, typeRepresentation).visit(node);
256+
return sb.toString();
257+
}
258+
259+
Set<Class> computeAllSuperclasses(Class node) {
260+
Set<Class> set = <Class>{};
261+
_getAllSuperclasses(node, set);
262+
return set;
263+
}
264+
265+
void _getAllSuperclasses(Class node, Set<Class> set) {
266+
if (set.add(node)) {
267+
if (node.supertype != null) {
268+
_getAllSuperclasses(node.supertype.classNode, set);
269+
}
270+
if (node.mixedInType != null) {
271+
_getAllSuperclasses(node.mixedInType.classNode, set);
272+
}
273+
for (Supertype interface in node.implementedTypes) {
274+
_getAllSuperclasses(interface.classNode, set);
275+
}
276+
}
277+
}
278+
279+
String supertypeToText(Supertype node,
280+
[TypeRepresentation typeRepresentation = TypeRepresentation.legacy]) {
245281
StringBuffer sb = new StringBuffer();
246-
new DartTypeToTextVisitor(sb, isNonNullableByDefault).visit(node);
282+
sb.write(node.classNode.name);
283+
if (node.typeArguments.isNotEmpty) {
284+
sb.write('<');
285+
new DartTypeToTextVisitor(sb, typeRepresentation)
286+
.visitList(node.typeArguments);
287+
sb.write('>');
288+
}
247289
return sb.toString();
248290
}
249291

250292
class ConstantToTextVisitor implements ConstantVisitor<void> {
251293
final StringBuffer sb;
252294
final DartTypeToTextVisitor typeToText;
253295

254-
ConstantToTextVisitor(this.sb, bool isNonNullableByDefault)
255-
: typeToText = new DartTypeToTextVisitor(sb, isNonNullableByDefault);
296+
ConstantToTextVisitor(this.sb, TypeRepresentation typeRepresentation)
297+
: typeToText = new DartTypeToTextVisitor(sb, typeRepresentation);
256298

257299
void visit(Constant node) => node.accept(this);
258300

@@ -375,9 +417,9 @@ class ConstantToTextVisitor implements ConstantVisitor<void> {
375417

376418
class DartTypeToTextVisitor implements DartTypeVisitor<void> {
377419
final StringBuffer sb;
378-
final bool isNonNullableByDefault;
420+
final TypeRepresentation typeRepresentation;
379421

380-
DartTypeToTextVisitor(this.sb, this.isNonNullableByDefault);
422+
DartTypeToTextVisitor(this.sb, this.typeRepresentation);
381423

382424
void visit(DartType node) => node.accept(this);
383425

@@ -421,8 +463,7 @@ class DartTypeToTextVisitor implements DartTypeVisitor<void> {
421463
sb.write('>');
422464
}
423465
if (!isNull(node)) {
424-
sb.write(nullabilityToText(node.nullability,
425-
isNonNullableByDefault: isNonNullableByDefault));
466+
sb.write(nullabilityToText(node.nullability, typeRepresentation));
426467
}
427468
}
428469

@@ -454,16 +495,14 @@ class DartTypeToTextVisitor implements DartTypeVisitor<void> {
454495
sb.write('}');
455496
}
456497
sb.write(')');
457-
sb.write(nullabilityToText(node.nullability,
458-
isNonNullableByDefault: isNonNullableByDefault));
498+
sb.write(nullabilityToText(node.nullability, typeRepresentation));
459499
sb.write('->');
460500
visit(node.returnType);
461501
}
462502

463503
void visitTypeParameterType(TypeParameterType node) {
464504
sb.write(node.parameter.name);
465-
sb.write(nullabilityToText(node.nullability,
466-
isNonNullableByDefault: isNonNullableByDefault));
505+
sb.write(nullabilityToText(node.nullability, typeRepresentation));
467506
if (node.promotedBound != null) {
468507
sb.write(' & ');
469508
visit(node.promotedBound);
@@ -477,8 +516,7 @@ class DartTypeToTextVisitor implements DartTypeVisitor<void> {
477516
visitList(node.typeArguments);
478517
sb.write('>');
479518
}
480-
sb.write(nullabilityToText(node.nullability,
481-
isNonNullableByDefault: isNonNullableByDefault));
519+
sb.write(nullabilityToText(node.nullability, typeRepresentation));
482520
}
483521
}
484522

@@ -546,8 +584,12 @@ String typeVariableBuilderToText(TypeVariableBuilder typeVariable) {
546584
}
547585

548586
/// Returns a textual representation of [errors] to be used in testing.
549-
String errorsToText(List<FormattedMessage> errors) {
550-
return errors.map((m) => m.message).join(',');
587+
String errorsToText(List<FormattedMessage> errors, {bool useCodes: false}) {
588+
if (useCodes) {
589+
return errors.map((m) => m.code).join(',');
590+
} else {
591+
return errors.map((m) => m.message).join(',');
592+
}
551593
}
552594

553595
/// Returns a textual representation of [descriptor] to be used in testing.
@@ -588,18 +630,39 @@ String extensionMethodDescriptorToText(ExtensionMemberDescriptor descriptor) {
588630
}
589631

590632
/// Returns a textual representation of [nullability] to be used in testing.
591-
String nullabilityToText(Nullability nullability,
592-
{bool isNonNullableByDefault}) {
593-
assert(isNonNullableByDefault != null);
633+
String nullabilityToText(
634+
Nullability nullability, TypeRepresentation typeRepresentation) {
594635
switch (nullability) {
595636
case Nullability.nonNullable:
596-
return isNonNullableByDefault ? '' : '!';
637+
switch (typeRepresentation) {
638+
case TypeRepresentation.explicit:
639+
case TypeRepresentation.legacy:
640+
case TypeRepresentation.implicitUndetermined:
641+
return '!';
642+
case TypeRepresentation.nonNullableByDefault:
643+
return '';
644+
}
645+
break;
597646
case Nullability.nullable:
598647
return '?';
599648
case Nullability.undetermined:
600-
return '%';
649+
switch (typeRepresentation) {
650+
case TypeRepresentation.implicitUndetermined:
651+
return '';
652+
default:
653+
return '%';
654+
}
655+
break;
601656
case Nullability.legacy:
602-
return isNonNullableByDefault ? '*' : '';
657+
switch (typeRepresentation) {
658+
case TypeRepresentation.legacy:
659+
return '';
660+
case TypeRepresentation.explicit:
661+
case TypeRepresentation.nonNullableByDefault:
662+
case TypeRepresentation.implicitUndetermined:
663+
return '*';
664+
}
665+
break;
603666
}
604667
throw new UnsupportedError('Unexpected nullability: $nullability.');
605668
}

pkg/front_end/test/flow_analysis/assigned_variables/assigned_variables_test.dart

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@ import 'package:_fe_analyzer_shared/src/testing/id.dart'
1010
import 'package:_fe_analyzer_shared/src/testing/id_testing.dart'
1111
show DataInterpreter, runTests;
1212
import 'package:_fe_analyzer_shared/src/testing/id_testing.dart';
13-
import 'package:front_end/src/api_prototype/experimental_flags.dart'
14-
show ExperimentalFlag;
1513
import 'package:front_end/src/fasta/builder/member_builder.dart';
1614
import 'package:front_end/src/fasta/source/source_loader.dart';
1715

@@ -28,10 +26,8 @@ main(List<String> args) async {
2826
supportedMarkers: sharedMarkers,
2927
createUriForFileName: createUriForFileName,
3028
onFailure: onFailure,
31-
runTest: runTestFor(const AssignedVariablesDataComputer(), [
32-
new TestConfig(cfeMarker, 'cfe with nnbd',
33-
experimentalFlags: const {ExperimentalFlag.nonNullable: true})
34-
]),
29+
runTest: runTestFor(
30+
const AssignedVariablesDataComputer(), [cfeNonNullableOnlyConfig]),
3531
skipList: [
3632
'for.dart',
3733
'for_element.dart',

pkg/front_end/test/flow_analysis/definite_assignment/definite_assignment_test.dart

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,6 @@ import 'package:_fe_analyzer_shared/src/testing/id.dart' show ActualData, Id;
77
import 'package:_fe_analyzer_shared/src/testing/id_testing.dart'
88
show DataInterpreter, runTests;
99
import 'package:_fe_analyzer_shared/src/testing/id_testing.dart';
10-
import 'package:front_end/src/api_prototype/experimental_flags.dart'
11-
show ExperimentalFlag;
12-
1310
import 'package:front_end/src/testing/id_testing_helper.dart';
1411
import 'package:front_end/src/fasta/type_inference/type_inference_engine.dart';
1512
import 'package:front_end/src/fasta/builder/member_builder.dart';
@@ -25,10 +22,8 @@ main(List<String> args) async {
2522
supportedMarkers: sharedMarkers,
2623
createUriForFileName: createUriForFileName,
2724
onFailure: onFailure,
28-
runTest: runTestFor(const DefiniteAssignmentDataComputer(), [
29-
new TestConfig(cfeMarker, 'cfe with nnbd',
30-
experimentalFlags: const {ExperimentalFlag.nonNullable: true})
31-
]),
25+
runTest: runTestFor(
26+
const DefiniteAssignmentDataComputer(), [cfeNonNullableOnlyConfig]),
3227
skipList: [
3328
// TODO(johnniwinther): Update break/continue handling to support these:
3429
'do.dart',

pkg/front_end/test/flow_analysis/nullability/nullability_test.dart

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,6 @@ import 'package:_fe_analyzer_shared/src/testing/id.dart' show ActualData, Id;
77
import 'package:_fe_analyzer_shared/src/testing/id_testing.dart'
88
show DataInterpreter, runTests;
99
import 'package:_fe_analyzer_shared/src/testing/id_testing.dart';
10-
import 'package:front_end/src/api_prototype/experimental_flags.dart'
11-
show ExperimentalFlag;
12-
1310
import 'package:front_end/src/testing/id_testing_helper.dart';
1411
import 'package:kernel/ast.dart' hide Variance;
1512

@@ -21,10 +18,8 @@ main(List<String> args) async {
2118
supportedMarkers: sharedMarkers,
2219
createUriForFileName: createUriForFileName,
2320
onFailure: onFailure,
24-
runTest: runTestFor(const NullabilityDataComputer(), [
25-
new TestConfig(cfeMarker, 'cfe with nnbd',
26-
experimentalFlags: const {ExperimentalFlag.nonNullable: true})
27-
]),
21+
runTest: runTestFor(
22+
const NullabilityDataComputer(), [cfeNonNullableOnlyConfig]),
2823
skipList: [
2924
// TODO(johnniwinther): Run all nullability tests.
3025
'null_aware_access.dart',

pkg/front_end/test/flow_analysis/reachability/reachability_test.dart

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,6 @@ import 'package:_fe_analyzer_shared/src/testing/id.dart' show ActualData, Id;
77
import 'package:_fe_analyzer_shared/src/testing/id_testing.dart'
88
show DataInterpreter, runTests;
99
import 'package:_fe_analyzer_shared/src/testing/id_testing.dart';
10-
import 'package:front_end/src/api_prototype/experimental_flags.dart'
11-
show ExperimentalFlag;
12-
1310
import 'package:front_end/src/testing/id_testing_helper.dart';
1411
import 'package:front_end/src/fasta/type_inference/type_inference_engine.dart';
1512
import 'package:front_end/src/fasta/builder/member_builder.dart';
@@ -24,10 +21,8 @@ main(List<String> args) async {
2421
supportedMarkers: sharedMarkers,
2522
createUriForFileName: createUriForFileName,
2623
onFailure: onFailure,
27-
runTest: runTestFor(const ReachabilityDataComputer(), [
28-
new TestConfig(cfeMarker, 'cfe with nnbd',
29-
experimentalFlags: const {ExperimentalFlag.nonNullable: true})
30-
]));
24+
runTest: runTestFor(
25+
const ReachabilityDataComputer(), [cfeNonNullableOnlyConfig]));
3126
}
3227

3328
class ReachabilityDataComputer

pkg/front_end/test/flow_analysis/type_promotion/type_promotion_test.dart

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,6 @@
33
// BSD-style license that can be found in the LICENSE file.
44

55
import 'dart:io' show Directory, Platform;
6-
import 'package:front_end/src/api_prototype/experimental_flags.dart'
7-
show ExperimentalFlag;
8-
96
import 'package:_fe_analyzer_shared/src/testing/id.dart' show ActualData, Id;
107
import 'package:_fe_analyzer_shared/src/testing/id_testing.dart'
118
show DataInterpreter, runTests;
@@ -23,10 +20,8 @@ main(List<String> args) async {
2320
supportedMarkers: sharedMarkers,
2421
createUriForFileName: createUriForFileName,
2522
onFailure: onFailure,
26-
runTest: runTestFor(const TypePromotionDataComputer(), [
27-
new TestConfig(cfeMarker, 'cfe with nnbd',
28-
experimentalFlags: const {ExperimentalFlag.nonNullable: true})
29-
]),
23+
runTest: runTestFor(
24+
const TypePromotionDataComputer(), [cfeNonNullableOnlyConfig]),
3025
skipList: [
3126
// TODO(johnniwinther): Run all type promotion tests.
3227
'assignment_promoted.dart',
@@ -79,7 +74,7 @@ class _TypePromotionDataInterpreter implements DataInterpreter<DartType> {
7974

8075
@override
8176
String getText(DartType actualData) =>
82-
typeToText(actualData, isNonNullableByDefault: true);
77+
typeToText(actualData, TypeRepresentation.nonNullableByDefault);
8378

8479
@override
8580
String isAsExpected(DartType actualData, String expectedData) {

0 commit comments

Comments
 (0)