Skip to content

Commit 3fcede3

Browse files
Short-term hack to work around issue with duplicated interfaces.
See dartbug.com/31656 Change-Id: I017085953c5ac41d2cfd7368752918c6fcb51144 Reviewed-on: https://dart-review.googlesource.com/33884 Reviewed-by: Jens Johansen <[email protected]> Commit-Queue: Peter von der Ahé <[email protected]>
1 parent 513ac0f commit 3fcede3

File tree

8 files changed

+142
-33
lines changed

8 files changed

+142
-33
lines changed

pkg/analyzer/test/generated/compile_time_error_code_kernel_test.dart

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3087,6 +3087,18 @@ class CompileTimeErrorCodeTest_Kernel extends CompileTimeErrorCodeTest_Driver {
30873087
// Test passes, even though if fails in the superclass
30883088
await super.test_yieldInNonGenerator_async();
30893089
}
3090+
3091+
@override
3092+
@failingTest
3093+
test_implementsDisallowedClass_class_String_num() async {
3094+
await super.test_implementsDisallowedClass_class_String_num();
3095+
}
3096+
3097+
@override
3098+
@failingTest
3099+
test_implementsDisallowedClass_classTypeAlias_String_num() async {
3100+
await super.test_implementsDisallowedClass_classTypeAlias_String_num();
3101+
}
30903102
}
30913103

30923104
/// Tests marked with this annotation fail because of a Fasta problem.

pkg/front_end/lib/src/fasta/fasta_codes_generated.dart

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,38 @@ Message _withArgumentsAccessError(String name) {
9595
message: """Access error: '$name'.""", arguments: {'name': name});
9696
}
9797

98+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
99+
const Template<Message Function(String name, DartType _type, DartType _type2)>
100+
templateAmbiguousSupertypes = const Template<
101+
Message Function(String name, DartType _type, DartType _type2)>(
102+
messageTemplate:
103+
r"""'#name' can't implement both '#type' and '#type2'""",
104+
withArguments: _withArgumentsAmbiguousSupertypes);
105+
106+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
107+
const Code<Message Function(String name, DartType _type, DartType _type2)>
108+
codeAmbiguousSupertypes =
109+
const Code<Message Function(String name, DartType _type, DartType _type2)>(
110+
"AmbiguousSupertypes", templateAmbiguousSupertypes,
111+
severity: Severity.error);
112+
113+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
114+
Message _withArgumentsAmbiguousSupertypes(
115+
String name, DartType _type, DartType _type2) {
116+
NameSystem nameSystem = new NameSystem();
117+
StringBuffer buffer = new StringBuffer();
118+
new Printer(buffer, syntheticNames: nameSystem).writeNode(_type);
119+
String type = '$buffer';
120+
121+
buffer = new StringBuffer();
122+
new Printer(buffer, syntheticNames: nameSystem).writeNode(_type2);
123+
String type2 = '$buffer';
124+
125+
return new Message(codeAmbiguousSupertypes,
126+
message: """'$name' can't implement both '$type' and '$type2'""",
127+
arguments: {'name': name, 'type': _type, 'type2': _type2});
128+
}
129+
98130
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
99131
const Code<Null> codeAnnotationOnEnumConstant = messageAnnotationOnEnumConstant;
100132

pkg/front_end/lib/src/fasta/source/source_loader.dart

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,21 @@ import 'package:front_end/src/fasta/type_inference/interface_resolver.dart'
1212
show InterfaceResolver;
1313

1414
import 'package:kernel/ast.dart'
15-
show Arguments, Expression, Library, LibraryDependency, Program;
15+
show
16+
Arguments,
17+
Class,
18+
Expression,
19+
Library,
20+
LibraryDependency,
21+
Program,
22+
Supertype;
1623

1724
import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
1825

1926
import 'package:kernel/core_types.dart' show CoreTypes;
2027

28+
import 'package:kernel/type_environment.dart' show TypeEnvironment;
29+
2130
import '../../api_prototype/file_system.dart';
2231

2332
import '../../base/instrumentation.dart'
@@ -46,6 +55,7 @@ import '../fasta_codes.dart'
4655
Message,
4756
SummaryTemplate,
4857
Template,
58+
templateAmbiguousSupertypes,
4959
templateCyclicClassHierarchy,
5060
templateExtendingEnum,
5161
templateExtendingRestricted,
@@ -563,10 +573,37 @@ class SourceLoader<L> extends Loader<L> {
563573
}
564574

565575
void computeHierarchy() {
566-
hierarchy = new ClassHierarchy(computeFullProgram());
576+
List<List> ambiguousTypesRecords = [];
577+
hierarchy = new ClassHierarchy(computeFullProgram(),
578+
onAmbiguousSupertypes: (Class cls, Supertype a, Supertype b) {
579+
if (ambiguousTypesRecords != null) {
580+
ambiguousTypesRecords.add([cls, a, b]);
581+
}
582+
});
583+
for (List record in ambiguousTypesRecords) {
584+
handleAmbiguousSupertypes(record[0], record[1], record[2]);
585+
}
586+
ambiguousTypesRecords = null;
567587
ticker.logMs("Computed class hierarchy");
568588
}
569589

590+
void handleAmbiguousSupertypes(Class cls, Supertype a, Supertype b) {
591+
String name = cls.name;
592+
TypeEnvironment env = new TypeEnvironment(coreTypes, hierarchy,
593+
strongMode: target.strongMode);
594+
595+
if (cls.isSyntheticMixinImplementation) return;
596+
597+
if (env.isSubtypeOf(a.asInterfaceType, b.asInterfaceType)) return;
598+
addProblem(
599+
templateAmbiguousSupertypes.withArguments(
600+
name, a.asInterfaceType, b.asInterfaceType),
601+
cls.fileOffset,
602+
cls.fileUri);
603+
}
604+
605+
void ignoreAmbiguousSupertypes(Class cls, Supertype a, Supertype b) {}
606+
570607
void computeCoreTypes(Program program) {
571608
coreTypes = new CoreTypes(program);
572609
ticker.logMs("Computed core types");
@@ -646,8 +683,9 @@ class SourceLoader<L> extends Loader<L> {
646683
// target those forwarding stubs.
647684
// TODO(paulberry): could we make this unnecessary by not clearing class
648685
// inference info?
649-
typeInferenceEngine.classHierarchy =
650-
hierarchy = new ClassHierarchy(computeFullProgram());
686+
typeInferenceEngine.classHierarchy = hierarchy = new ClassHierarchy(
687+
computeFullProgram(),
688+
onAmbiguousSupertypes: ignoreAmbiguousSupertypes);
651689
ticker.logMs("Performed top level inference");
652690
}
653691

pkg/front_end/messages.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1796,6 +1796,7 @@ UndefinedMethod:
17961796
C c;
17971797
c.foo();
17981798
}
1799+
17991800
SourceOutlineSummary:
18001801
template: |
18011802
Built outlines for #count compilation units (#count2 bytes) in #string, that is,
@@ -1822,3 +1823,7 @@ CantInferTypeDueToCircularity:
18221823
template: "Can't infer the type of '#string': circularity found during type inference."
18231824
tip: "Specify the type explicitly."
18241825
severity: ERROR
1826+
1827+
AmbiguousSupertypes:
1828+
template: "'#name' can't implement both '#type' and '#type2'"
1829+
severity: ERROR

pkg/kernel/lib/class_hierarchy.dart

Lines changed: 48 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,25 @@ import 'type_algebra.dart';
1111

1212
import 'src/incremental_class_hierarchy.dart' show IncrementalClassHierarchy;
1313

14+
typedef HandleAmbiguousSupertypes = void Function(Class, Supertype, Supertype);
15+
1416
/// Interface for answering various subclassing queries.
1517
/// TODO(scheglov) Several methods are not used, or used only in tests.
1618
/// Check if these methods are not useful and should be removed .
1719
abstract class ClassHierarchy {
18-
factory ClassHierarchy(Program program) {
20+
factory ClassHierarchy(Program program,
21+
{HandleAmbiguousSupertypes onAmbiguousSupertypes}) {
1922
int numberOfClasses = 0;
2023
for (var library in program.libraries) {
2124
numberOfClasses += library.classes.length;
2225
}
23-
return new ClosedWorldClassHierarchy._internal(program, numberOfClasses)
26+
onAmbiguousSupertypes ??= (Class cls, Supertype a, Supertype b) {
27+
if (!cls.isSyntheticMixinImplementation) {
28+
throw "$cls can't implement both $a and $b";
29+
}
30+
};
31+
return new ClosedWorldClassHierarchy._internal(
32+
program, numberOfClasses, onAmbiguousSupertypes)
2433
.._initialize();
2534
}
2635

@@ -271,6 +280,8 @@ abstract class ClassHierarchy {
271280

272281
/// Implementation of [ClassHierarchy] for closed world.
273282
class ClosedWorldClassHierarchy implements ClassHierarchy {
283+
final HandleAmbiguousSupertypes _onAmbiguousSupertypes;
284+
274285
/// The [Program] that this class hierarchy represents.
275286
final Program _program;
276287

@@ -281,7 +292,8 @@ class ClosedWorldClassHierarchy implements ClassHierarchy {
281292

282293
final Map<Class, _ClassInfo> _infoFor = <Class, _ClassInfo>{};
283294

284-
ClosedWorldClassHierarchy._internal(this._program, int numberOfClasses)
295+
ClosedWorldClassHierarchy._internal(
296+
this._program, int numberOfClasses, this._onAmbiguousSupertypes)
285297
: classes = new List<Class>(numberOfClasses);
286298

287299
@override
@@ -446,11 +458,11 @@ class ClosedWorldClassHierarchy implements ClassHierarchy {
446458
var superType1 = identical(info1, next)
447459
? type1
448460
: Substitution.fromInterfaceType(type1).substituteType(
449-
info1.genericSuperTypes[next.classNode].asInterfaceType);
461+
info1.genericSuperTypes[next.classNode].first.asInterfaceType);
450462
var superType2 = identical(info2, next)
451463
? type2
452464
: Substitution.fromInterfaceType(type2).substituteType(
453-
info2.genericSuperTypes[next.classNode].asInterfaceType);
465+
info2.genericSuperTypes[next.classNode].first.asInterfaceType);
454466
if (superType1 == superType2) {
455467
candidate = superType1;
456468
++numCandidatesAtThisDepth;
@@ -466,7 +478,7 @@ class ClosedWorldClassHierarchy implements ClassHierarchy {
466478
_ClassInfo superInfo = _infoFor[superclass];
467479
if (!info.isSubtypeOf(superInfo)) return null;
468480
if (superclass.typeParameters.isEmpty) return superclass.asRawSupertype;
469-
return info.genericSuperTypes[superclass];
481+
return info.genericSuperTypes[superclass]?.first;
470482
}
471483

472484
@override
@@ -624,7 +636,8 @@ class ClosedWorldClassHierarchy implements ClassHierarchy {
624636
@override
625637
ClassHierarchy applyChanges(Iterable<Class> classes) {
626638
if (classes.isEmpty) return this;
627-
return new ClassHierarchy(_program);
639+
return new ClassHierarchy(_program,
640+
onAmbiguousSupertypes: _onAmbiguousSupertypes);
628641
}
629642

630643
void _initialize() {
@@ -900,20 +913,30 @@ class ClosedWorldClassHierarchy implements ClassHierarchy {
900913
superInfo.ownsGenericSuperTypeMap = false;
901914
} else {
902915
// Copy over the super type entries.
903-
subInfo.genericSuperTypes ??= <Class, Supertype>{};
904-
subInfo.genericSuperTypes.addAll(superInfo.genericSuperTypes);
916+
subInfo.genericSuperTypes ??= <Class, List<Supertype>>{};
917+
superInfo.genericSuperTypes
918+
?.forEach((Class key, List<Supertype> types) {
919+
for (Supertype type in types) {
920+
subInfo.recordGenericSuperType(key, type, _onAmbiguousSupertypes);
921+
}
922+
});
905923
}
906924
} else {
907925
// Copy over all transitive generic super types, and substitute the
908926
// free variables with those provided in [supertype].
909927
Class superclass = supertype.classNode;
910928
var substitution = Substitution.fromPairs(
911929
superclass.typeParameters, supertype.typeArguments);
912-
subInfo.genericSuperTypes ??= <Class, Supertype>{};
913-
superInfo.genericSuperTypes?.forEach((Class key, Supertype type) {
914-
subInfo.genericSuperTypes[key] = substitution.substituteSupertype(type);
930+
subInfo.genericSuperTypes ??= <Class, List<Supertype>>{};
931+
superInfo.genericSuperTypes?.forEach((Class key, List<Supertype> types) {
932+
for (Supertype type in types) {
933+
subInfo.recordGenericSuperType(key,
934+
substitution.substituteSupertype(type), _onAmbiguousSupertypes);
935+
}
915936
});
916-
subInfo.genericSuperTypes[superclass] = supertype;
937+
938+
subInfo.recordGenericSuperType(
939+
superclass, supertype, _onAmbiguousSupertypes);
917940
}
918941
}
919942

@@ -1151,7 +1174,7 @@ class _ClassInfo {
11511174
///
11521175
/// In this case, a single map object `{A: A<String>, Q: Q<int>}` may be
11531176
/// shared by the classes `B` and `C`.
1154-
Map<Class, Supertype> genericSuperTypes;
1177+
Map<Class, List<Supertype>> genericSuperTypes;
11551178

11561179
/// If true, this is the current "owner" of [genericSuperTypes], meaning
11571180
/// we may add additional entries to the map or transfer ownership to another
@@ -1178,6 +1201,17 @@ class _ClassInfo {
11781201
List<Member> interfaceSetters;
11791202

11801203
_ClassInfo(this.classNode);
1204+
1205+
void recordGenericSuperType(Class cls, Supertype type,
1206+
HandleAmbiguousSupertypes onAmbiguousSupertypes) {
1207+
List<Supertype> existing = genericSuperTypes[cls];
1208+
if (existing == null) {
1209+
genericSuperTypes[cls] = <Supertype>[type];
1210+
} else if (type != existing.first) {
1211+
existing.add(type);
1212+
onAmbiguousSupertypes(classNode, existing.first, type);
1213+
}
1214+
}
11811215
}
11821216

11831217
/// An immutable set of classes, internally represented as an interval list.

tests/language_2/language_2_dart2js.status

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1419,9 +1419,6 @@ redirecting_factory_default_values_test/02: MissingCompileTimeError
14191419
redirecting_factory_long_test: RuntimeError
14201420
redirecting_factory_reflection_test: RuntimeError
14211421
regress_20394_test/01: MissingCompileTimeError
1422-
regress_22976_test/01: RuntimeError
1423-
regress_22976_test/02: Pass # Incorrectly pass, we are ignoring an error due to #31118
1424-
regress_22976_test/none: Pass # Incorrectly pass, we are ignoring an error due to #31118
14251422
regress_24283_test: RuntimeError
14261423
regress_27617_test/1: Crash # Assertion failure: Unexpected constructor j:constructor(Foo._) in ConstructorDataImpl._getConstructorConstant
14271424
regress_28217_test/01: MissingCompileTimeError
@@ -2012,9 +2009,6 @@ redirecting_factory_default_values_test/02: MissingCompileTimeError
20122009
redirecting_factory_long_test: RuntimeError
20132010
redirecting_factory_reflection_test: RuntimeError
20142011
regress_20394_test/01: MissingCompileTimeError
2015-
regress_22976_test/01: Pass # Incorrectly pass, we are ignoring an error due to #31118
2016-
regress_22976_test/02: Pass # Incorrectly pass, we are ignoring an error due to #31118
2017-
regress_22976_test/none: Pass # Incorrectly pass, we are ignoring an error due to #31118
20182012
regress_24283_test: RuntimeError
20192013
regress_27617_test/1: Crash # Assertion failure: Unexpected constructor j:constructor(Foo._) in ConstructorDataImpl._getConstructorConstant
20202014
regress_28217_test/01: MissingCompileTimeError
@@ -2590,9 +2584,6 @@ regress_13462_0_test: CompileTimeError
25902584
regress_13462_1_test: CompileTimeError
25912585
regress_18535_test: CompileTimeError
25922586
regress_20394_test/01: MissingCompileTimeError
2593-
regress_22976_test/01: Pass # Incorrectly pass, we are ignoring an error due to #31118
2594-
regress_22976_test/02: Pass # Incorrectly pass, we are ignoring an error due to #31118
2595-
regress_22976_test/none: Pass # Incorrectly pass, we are ignoring an error due to #31118
25962587
regress_23408_test: Crash # Assertion failure: Missing scope info for j:method(_loadLibraryWrapper).
25972588
regress_24283_test: RuntimeError
25982589
regress_27617_test/1: Crash # Assertion failure: Unexpected constructor j:constructor(Foo._) in ConstructorDataImpl._getConstructorConstant
@@ -3346,9 +3337,6 @@ regress_13462_1_test: CompileTimeError
33463337
regress_18535_test: CompileTimeError
33473338
regress_20394_test/01: MissingCompileTimeError
33483339
regress_21795_test: RuntimeError
3349-
regress_22976_test/01: Pass # Incorrectly pass, we are ignoring an error due to #31118
3350-
regress_22976_test/02: Pass # Incorrectly pass, we are ignoring an error due to #31118
3351-
regress_22976_test/none: Pass # Incorrectly pass, we are ignoring an error due to #31118
33523340
regress_23408_test: Crash # NoSuchMethodError: The getter 'closureClassEntity' was called on null.
33533341
regress_24283_test: RuntimeError, OK # Requires 64 bit numbers.
33543342
regress_27617_test/1: Crash # Assertion failure: Unexpected constructor j:constructor(Foo._) in ConstructorDataImpl._getConstructorConstant

tests/language_2/language_2_dartdevc.status

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -546,7 +546,6 @@ redirecting_factory_default_values_test/02: MissingCompileTimeError
546546
redirecting_factory_default_values_test/03: MissingCompileTimeError
547547
redirecting_factory_infinite_steps_test/01: MissingCompileTimeError
548548
redirecting_factory_malbounded_test/01: MissingCompileTimeError
549-
regress_22976_test/01: CompileTimeError
550549
regress_23089_test: Crash
551550
regress_23408_test: CompileTimeError # Issue 31533
552551
regress_25550_test: CompileTimeError

tests/language_2/language_2_kernel.status

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ generic_no_such_method_dispatcher_test: RuntimeError # Issue 31424
1515
mock_writable_final_field_test: RuntimeError # Issue 31424
1616
no_such_method_subtype_test: RuntimeError # Issue 31424
1717

18+
[ $fasta ]
19+
regress_22976_test/*: CompileTimeError # Issue 31935
20+
1821
[ $compiler == dartk && $mode == debug && $runtime == vm && $strong ]
1922
bad_named_parameters_test/01: Crash # Issue(http://dartbug.com/31630)
2023
bad_named_parameters_test/02: Crash # Issue(http://dartbug.com/31630)
@@ -628,7 +631,6 @@ redirecting_factory_infinite_steps_test/01: MissingCompileTimeError
628631
redirecting_factory_long_test: RuntimeError # Fasta bug: Bad compilation of type arguments for redirecting factory.
629632
redirecting_factory_malbounded_test/01: MissingCompileTimeError
630633
regress_22443_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
631-
regress_22976_test/01: CompileTimeError # Issue 31402 (Variable declaration)
632634
regress_23089_test: Crash
633635
regress_23408_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
634636
regress_23408_test: RuntimeError
@@ -1496,7 +1498,6 @@ regress_13462_0_test: SkipByDesign
14961498
regress_13462_1_test: SkipByDesign
14971499
regress_18535_test: SkipByDesign
14981500
regress_22443_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
1499-
regress_22976_test/01: CompileTimeError # Issue 31402 (Variable declaration)
15001501
regress_23089_test: Crash
15011502
regress_23408_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
15021503
regress_23408_test: RuntimeError

0 commit comments

Comments
 (0)