Mixins have no static members
Change-Id: I93b43ad2d58ab2804ed7deafeadb6346eade9eab
Reviewed-on: https://dart-review.googlesource.com/c/91481
Reviewed-by: Jens Johansen <jensj@google.com>
Commit-Queue: Peter von der Ahé <ahe@google.com>
diff --git a/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart b/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
index c0575b3..d69df1a 100644
--- a/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
@@ -280,7 +280,7 @@
mixin = named.mixedInType.declaration;
}
if (mixin is KernelClassBuilder) {
- scope = mixin.scope;
+ scope = mixin.scope.computeMixinScope();
}
}
diff --git a/pkg/front_end/lib/src/fasta/scope.dart b/pkg/front_end/lib/src/fasta/scope.dart
index b7c8584..c74cc99 100644
--- a/pkg/front_end/lib/src/fasta/scope.dart
+++ b/pkg/front_end/lib/src/fasta/scope.dart
@@ -284,6 +284,36 @@
});
return nestingLevel;
}
+
+ Scope computeMixinScope() {
+ List<String> names = this.local.keys.toList();
+ Map<String, Declaration> local = <String, Declaration>{};
+ bool needsCopy = false;
+ for (int i = 0; i < names.length; i++) {
+ String name = names[i];
+ Declaration declaration = this.local[name];
+ if (declaration.isStatic) {
+ needsCopy = true;
+ } else {
+ local[name] = declaration;
+ }
+ }
+ names = this.setters.keys.toList();
+ Map<String, Declaration> setters = <String, Declaration>{};
+ for (int i = 0; i < names.length; i++) {
+ String name = names[i];
+ Declaration declaration = this.setters[name];
+ if (declaration.isStatic) {
+ needsCopy = true;
+ } else {
+ setters[name] = declaration;
+ }
+ }
+ return needsCopy
+ ? new Scope(local, setters, parent, classNameOrDebugName,
+ isModifiable: isModifiable)
+ : this;
+ }
}
class ScopeBuilder {
diff --git a/pkg/front_end/testcases/mixin_with_static_member.dart b/pkg/front_end/testcases/mixin_with_static_member.dart
new file mode 100644
index 0000000..27ce9da
--- /dev/null
+++ b/pkg/front_end/testcases/mixin_with_static_member.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2019, 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 file.
+
+class A extends B with M {}
+
+class B {
+ final Object m = null;
+}
+
+class M {
+ static Object m() => null;
+}
+
+main() {
+ new A();
+}
diff --git a/pkg/front_end/testcases/mixin_with_static_member.dart.hierarchy.expect b/pkg/front_end/testcases/mixin_with_static_member.dart.hierarchy.expect
new file mode 100644
index 0000000..6eaae17
--- /dev/null
+++ b/pkg/front_end/testcases/mixin_with_static_member.dart.hierarchy.expect
@@ -0,0 +1,120 @@
+Object:
+ superclasses:
+ interfaces:
+ classMembers:
+ Object._haveSameRuntimeType
+ Object.toString
+ Object.runtimeType
+ Object._toString
+ Object._simpleInstanceOf
+ Object._hashCodeRnd
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._objectHashCode
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+B:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ B.m
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+M:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ M.m
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+B with M:
+ superclasses:
+ Object
+ -> B
+ interfaces: M
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ B.m
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+ interfaceMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ B.m
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ interfaceSetters:
+
+A:
+ superclasses:
+ Object
+ -> B
+ -> _A&B&M
+ interfaces: M
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ B.m
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+ interfaceMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ B.m
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ interfaceSetters:
diff --git a/pkg/front_end/testcases/mixin_with_static_member.dart.legacy.expect b/pkg/front_end/testcases/mixin_with_static_member.dart.legacy.expect
new file mode 100644
index 0000000..8c1ae5e
--- /dev/null
+++ b/pkg/front_end/testcases/mixin_with_static_member.dart.legacy.expect
@@ -0,0 +1,30 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+abstract class _A&B&M = self::B with self::M {
+ synthetic constructor •() → self::_A&B&M
+ : super self::B::•()
+ ;
+}
+class A extends self::_A&B&M {
+ synthetic constructor •() → self::A
+ : super self::_A&B&M::•()
+ ;
+}
+class B extends core::Object {
+ final field core::Object m = null;
+ synthetic constructor •() → self::B
+ : super core::Object::•()
+ ;
+}
+class M extends core::Object {
+ synthetic constructor •() → self::M
+ : super core::Object::•()
+ ;
+ static method m() → core::Object
+ return null;
+}
+static method main() → dynamic {
+ new self::A::•();
+}
diff --git a/pkg/front_end/testcases/mixin_with_static_member.dart.legacy.transformed.expect b/pkg/front_end/testcases/mixin_with_static_member.dart.legacy.transformed.expect
new file mode 100644
index 0000000..e243b45
--- /dev/null
+++ b/pkg/front_end/testcases/mixin_with_static_member.dart.legacy.transformed.expect
@@ -0,0 +1,32 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+abstract class _A&B&M extends self::B implements self::M {
+ synthetic constructor •() → self::_A&B&M
+ : super self::B::•()
+ ;
+ static method m() → core::Object
+ return null;
+}
+class A extends self::_A&B&M {
+ synthetic constructor •() → self::A
+ : super self::_A&B&M::•()
+ ;
+}
+class B extends core::Object {
+ final field core::Object m = null;
+ synthetic constructor •() → self::B
+ : super core::Object::•()
+ ;
+}
+class M extends core::Object {
+ synthetic constructor •() → self::M
+ : super core::Object::•()
+ ;
+ static method m() → core::Object
+ return null;
+}
+static method main() → dynamic {
+ new self::A::•();
+}
diff --git a/pkg/front_end/testcases/mixin_with_static_member.dart.outline.expect b/pkg/front_end/testcases/mixin_with_static_member.dart.outline.expect
new file mode 100644
index 0000000..2de8dc52
--- /dev/null
+++ b/pkg/front_end/testcases/mixin_with_static_member.dart.outline.expect
@@ -0,0 +1,26 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+abstract class _A&B&M = self::B with self::M {
+ synthetic constructor •() → self::_A&B&M
+ : super self::B::•()
+ ;
+}
+class A extends self::_A&B&M {
+ synthetic constructor •() → self::A
+ ;
+}
+class B extends core::Object {
+ final field core::Object m;
+ synthetic constructor •() → self::B
+ ;
+}
+class M extends core::Object {
+ synthetic constructor •() → self::M
+ ;
+ static method m() → core::Object
+ ;
+}
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/mixin_with_static_member.dart.strong.expect b/pkg/front_end/testcases/mixin_with_static_member.dart.strong.expect
new file mode 100644
index 0000000..8c1ae5e
--- /dev/null
+++ b/pkg/front_end/testcases/mixin_with_static_member.dart.strong.expect
@@ -0,0 +1,30 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+abstract class _A&B&M = self::B with self::M {
+ synthetic constructor •() → self::_A&B&M
+ : super self::B::•()
+ ;
+}
+class A extends self::_A&B&M {
+ synthetic constructor •() → self::A
+ : super self::_A&B&M::•()
+ ;
+}
+class B extends core::Object {
+ final field core::Object m = null;
+ synthetic constructor •() → self::B
+ : super core::Object::•()
+ ;
+}
+class M extends core::Object {
+ synthetic constructor •() → self::M
+ : super core::Object::•()
+ ;
+ static method m() → core::Object
+ return null;
+}
+static method main() → dynamic {
+ new self::A::•();
+}
diff --git a/pkg/front_end/testcases/mixin_with_static_member.dart.strong.transformed.expect b/pkg/front_end/testcases/mixin_with_static_member.dart.strong.transformed.expect
new file mode 100644
index 0000000..e243b45
--- /dev/null
+++ b/pkg/front_end/testcases/mixin_with_static_member.dart.strong.transformed.expect
@@ -0,0 +1,32 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+abstract class _A&B&M extends self::B implements self::M {
+ synthetic constructor •() → self::_A&B&M
+ : super self::B::•()
+ ;
+ static method m() → core::Object
+ return null;
+}
+class A extends self::_A&B&M {
+ synthetic constructor •() → self::A
+ : super self::_A&B&M::•()
+ ;
+}
+class B extends core::Object {
+ final field core::Object m = null;
+ synthetic constructor •() → self::B
+ : super core::Object::•()
+ ;
+}
+class M extends core::Object {
+ synthetic constructor •() → self::M
+ : super core::Object::•()
+ ;
+ static method m() → core::Object
+ return null;
+}
+static method main() → dynamic {
+ new self::A::•();
+}
diff --git a/pkg/front_end/testcases/text_serialization.status b/pkg/front_end/testcases/text_serialization.status
index 424fbf9..8ac7058 100644
--- a/pkg/front_end/testcases/text_serialization.status
+++ b/pkg/front_end/testcases/text_serialization.status
@@ -681,6 +681,7 @@
mixin_constructors_with_default_values: TextSerializationFailure # Was: Pass
mixin_inherited_setter_for_mixed_in_field: TextSerializationFailure # Was: Pass
mixin_super_repeated: TextSerializationFailure # Was: Pass
+mixin_with_static_member: TextSerializationFailure
mixin: TextSerializationFailure # Was: Pass
named_function_scope: TextSerializationFailure # Was: Pass
named_parameters: TextSerializationFailure # Was: Pass