[cfe] Add mixin class flag to dill and binary.
Additionally, make class flags a uint because there are now more than 8 flags.
TEST=pkg/front_end/testcases/mixin_class/*
Change-Id: I4fe7babfa9911df0821cc73528e6b10b2ea3b92d
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/275402
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Commit-Queue: Kallen Tu <kallentu@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
diff --git a/pkg/front_end/lib/src/fasta/builder/class_builder.dart b/pkg/front_end/lib/src/fasta/builder/class_builder.dart
index 0e3fbba..49aadfb 100644
--- a/pkg/front_end/lib/src/fasta/builder/class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/class_builder.dart
@@ -73,6 +73,8 @@
bool get isMixin;
+ bool get isMixinClass;
+
bool get isMixinDeclaration;
bool get isMixinApplication;
diff --git a/pkg/front_end/lib/src/fasta/dill/dill_class_builder.dart b/pkg/front_end/lib/src/fasta/dill/dill_class_builder.dart
index 6cd51b4..d061e58 100644
--- a/pkg/front_end/lib/src/fasta/dill/dill_class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/dill/dill_class_builder.dart
@@ -58,6 +58,9 @@
bool get isMacro => cls.isMacro;
@override
+ bool get isMixinClass => cls.isMixinClass;
+
+ @override
bool get isMixinDeclaration => cls.isMixinDeclaration;
@override
diff --git a/pkg/front_end/lib/src/fasta/source/source_class_builder.dart b/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
index 3b0d8f9..9c0292e 100644
--- a/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
@@ -112,7 +112,7 @@
@override
final bool isAugmentation;
- // TODO(kallentu): Finish AST implementation for mixin classes.
+ @override
final bool isMixinClass;
@override
@@ -275,6 +275,7 @@
// compile-time error.
cls.isAbstract = isAbstract;
cls.isMacro = isMacro;
+ cls.isMixinClass = isMixinClass;
cls.isSealed = isSealed;
if (interfaceBuilders != null) {
for (int i = 0; i < interfaceBuilders!.length; ++i) {
diff --git a/pkg/front_end/testcases/mixin_class/mixin_class_declaration.dart.strong.expect b/pkg/front_end/testcases/mixin_class/mixin_class_declaration.dart.strong.expect
index 2a76063..2703a27 100644
--- a/pkg/front_end/testcases/mixin_class/mixin_class_declaration.dart.strong.expect
+++ b/pkg/front_end/testcases/mixin_class/mixin_class_declaration.dart.strong.expect
@@ -2,19 +2,19 @@
import self as self;
import "dart:core" as core;
-class A extends core::Object {
+mixin class A extends core::Object {
synthetic constructor •() → self::A
: super core::Object::•()
;
}
-abstract class B extends core::Object {
+abstract mixin class B extends core::Object {
synthetic constructor •() → self::B
: super core::Object::•()
;
}
abstract class M extends core::Object /*isMixinDeclaration*/ {
}
-class C = core::Object with self::M /*hasConstConstructor*/ {
+mixin class C = core::Object with self::M /*hasConstConstructor*/ {
const synthetic constructor •() → self::C
: super core::Object::•()
;
diff --git a/pkg/front_end/testcases/mixin_class/mixin_class_declaration.dart.strong.transformed.expect b/pkg/front_end/testcases/mixin_class/mixin_class_declaration.dart.strong.transformed.expect
index 3e3e810..47a4901 100644
--- a/pkg/front_end/testcases/mixin_class/mixin_class_declaration.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/mixin_class/mixin_class_declaration.dart.strong.transformed.expect
@@ -2,19 +2,19 @@
import self as self;
import "dart:core" as core;
-class A extends core::Object {
+mixin class A extends core::Object {
synthetic constructor •() → self::A
: super core::Object::•()
;
}
-abstract class B extends core::Object {
+abstract mixin class B extends core::Object {
synthetic constructor •() → self::B
: super core::Object::•()
;
}
abstract class M extends core::Object /*isMixinDeclaration*/ {
}
-class C extends core::Object implements self::M /*isEliminatedMixin,hasConstConstructor*/ {
+mixin class C extends core::Object implements self::M /*isEliminatedMixin,hasConstConstructor*/ {
const synthetic constructor •() → self::C
: super core::Object::•()
;
diff --git a/pkg/front_end/testcases/mixin_class/mixin_class_declaration.dart.weak.expect b/pkg/front_end/testcases/mixin_class/mixin_class_declaration.dart.weak.expect
index 2a76063..2703a27 100644
--- a/pkg/front_end/testcases/mixin_class/mixin_class_declaration.dart.weak.expect
+++ b/pkg/front_end/testcases/mixin_class/mixin_class_declaration.dart.weak.expect
@@ -2,19 +2,19 @@
import self as self;
import "dart:core" as core;
-class A extends core::Object {
+mixin class A extends core::Object {
synthetic constructor •() → self::A
: super core::Object::•()
;
}
-abstract class B extends core::Object {
+abstract mixin class B extends core::Object {
synthetic constructor •() → self::B
: super core::Object::•()
;
}
abstract class M extends core::Object /*isMixinDeclaration*/ {
}
-class C = core::Object with self::M /*hasConstConstructor*/ {
+mixin class C = core::Object with self::M /*hasConstConstructor*/ {
const synthetic constructor •() → self::C
: super core::Object::•()
;
diff --git a/pkg/front_end/testcases/mixin_class/mixin_class_declaration.dart.weak.modular.expect b/pkg/front_end/testcases/mixin_class/mixin_class_declaration.dart.weak.modular.expect
index 2a76063..2703a27 100644
--- a/pkg/front_end/testcases/mixin_class/mixin_class_declaration.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/mixin_class/mixin_class_declaration.dart.weak.modular.expect
@@ -2,19 +2,19 @@
import self as self;
import "dart:core" as core;
-class A extends core::Object {
+mixin class A extends core::Object {
synthetic constructor •() → self::A
: super core::Object::•()
;
}
-abstract class B extends core::Object {
+abstract mixin class B extends core::Object {
synthetic constructor •() → self::B
: super core::Object::•()
;
}
abstract class M extends core::Object /*isMixinDeclaration*/ {
}
-class C = core::Object with self::M /*hasConstConstructor*/ {
+mixin class C = core::Object with self::M /*hasConstConstructor*/ {
const synthetic constructor •() → self::C
: super core::Object::•()
;
diff --git a/pkg/front_end/testcases/mixin_class/mixin_class_declaration.dart.weak.outline.expect b/pkg/front_end/testcases/mixin_class/mixin_class_declaration.dart.weak.outline.expect
index 76f8cc4..637bcf8 100644
--- a/pkg/front_end/testcases/mixin_class/mixin_class_declaration.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/mixin_class/mixin_class_declaration.dart.weak.outline.expect
@@ -2,17 +2,17 @@
import self as self;
import "dart:core" as core;
-class A extends core::Object {
+mixin class A extends core::Object {
synthetic constructor •() → self::A
;
}
-abstract class B extends core::Object {
+abstract mixin class B extends core::Object {
synthetic constructor •() → self::B
;
}
abstract class M extends core::Object /*isMixinDeclaration*/ {
}
-class C = core::Object with self::M /*hasConstConstructor*/ {
+mixin class C = core::Object with self::M /*hasConstConstructor*/ {
const synthetic constructor •() → self::C
: super core::Object::•()
;
diff --git a/pkg/front_end/testcases/mixin_class/mixin_class_declaration.dart.weak.transformed.expect b/pkg/front_end/testcases/mixin_class/mixin_class_declaration.dart.weak.transformed.expect
index 3e3e810..47a4901 100644
--- a/pkg/front_end/testcases/mixin_class/mixin_class_declaration.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/mixin_class/mixin_class_declaration.dart.weak.transformed.expect
@@ -2,19 +2,19 @@
import self as self;
import "dart:core" as core;
-class A extends core::Object {
+mixin class A extends core::Object {
synthetic constructor •() → self::A
: super core::Object::•()
;
}
-abstract class B extends core::Object {
+abstract mixin class B extends core::Object {
synthetic constructor •() → self::B
: super core::Object::•()
;
}
abstract class M extends core::Object /*isMixinDeclaration*/ {
}
-class C extends core::Object implements self::M /*isEliminatedMixin,hasConstConstructor*/ {
+mixin class C extends core::Object implements self::M /*isEliminatedMixin,hasConstConstructor*/ {
const synthetic constructor •() → self::C
: super core::Object::•()
;
diff --git a/pkg/kernel/binary.md b/pkg/kernel/binary.md
index f95f4a0..fda11a5e 100644
--- a/pkg/kernel/binary.md
+++ b/pkg/kernel/binary.md
@@ -147,7 +147,7 @@
type ComponentFile {
UInt32 magic = 0x90ABCDEF;
- UInt32 formatVersion = 90;
+ UInt32 formatVersion = 91;
Byte[10] shortSdkHash;
List<String> problemsAsJson; // Described in problems.md.
Library[] libraries;
@@ -318,8 +318,9 @@
FileOffset startFileOffset; // Offset of the start of the class including any annotations.
FileOffset fileOffset; // Offset of the name of the class.
FileOffset fileEndOffset;
- Byte flags (isAbstract, isEnum, isAnonymousMixin, isEliminatedMixin,
- isMixinDeclaration, hasConstConstructor, isMacro, isSealed);
+ UInt flags (isAbstract, isEnum, isAnonymousMixin, isEliminatedMixin,
+ isMixinDeclaration, hasConstConstructor, isMacro, isSealed,
+ isMixinClass);
StringReference name;
List<Expression> annotations;
List<TypeParameter> typeParameters;
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart
index ea6aaf5..5080e6e 100644
--- a/pkg/kernel/lib/ast.dart
+++ b/pkg/kernel/lib/ast.dart
@@ -1026,6 +1026,7 @@
static const int FlagHasConstConstructor = 1 << 5;
static const int FlagMacro = 1 << 6;
static const int FlagSealed = 1 << 7;
+ static const int FlagMixinClass = 1 << 8;
int flags = 0;
@@ -1086,6 +1087,18 @@
value ? (flags | FlagEliminatedMixin) : (flags & ~FlagEliminatedMixin);
}
+ /// Whether this class is a mixin class.
+ ///
+ /// The `mixin` modifier was added to the class declaration which allows the
+ /// class to be used as a mixin. The class can be mixed in by other classes
+ /// outside of its library. Otherwise, classes are not able to be used as a
+ /// mixin outside of its library from version 3.0 and later.
+ bool get isMixinClass => flags & FlagMixinClass != 0;
+
+ void set isMixinClass(bool value) {
+ flags = value ? (flags | FlagMixinClass) : (flags & ~FlagMixinClass);
+ }
+
/// True if this class was a mixin declaration in Dart.
///
/// Mixins are declared in Dart with the `mixin` keyword. They are compiled
diff --git a/pkg/kernel/lib/binary/ast_from_binary.dart b/pkg/kernel/lib/binary/ast_from_binary.dart
index 4f89c55..d717999 100644
--- a/pkg/kernel/lib/binary/ast_from_binary.dart
+++ b/pkg/kernel/lib/binary/ast_from_binary.dart
@@ -1478,7 +1478,7 @@
int startFileOffset = readOffset();
int fileOffset = readOffset();
int fileEndOffset = readOffset();
- int flags = readByte();
+ int flags = readUInt30();
String name = readStringReference();
if (node == null) {
node = new Class(name: name, reference: reference, fileUri: fileUri)
diff --git a/pkg/kernel/lib/binary/ast_to_binary.dart b/pkg/kernel/lib/binary/ast_to_binary.dart
index 9b33d64..4524b7ab 100644
--- a/pkg/kernel/lib/binary/ast_to_binary.dart
+++ b/pkg/kernel/lib/binary/ast_to_binary.dart
@@ -1273,7 +1273,7 @@
writeOffset(node.fileOffset);
writeOffset(node.fileEndOffset);
- writeByte(node.flags);
+ writeUInt30(node.flags);
writeStringReference(node.name);
enterScope(memberScope: true);
diff --git a/pkg/kernel/lib/binary/tag.dart b/pkg/kernel/lib/binary/tag.dart
index d095dc4..2b60026 100644
--- a/pkg/kernel/lib/binary/tag.dart
+++ b/pkg/kernel/lib/binary/tag.dart
@@ -195,7 +195,7 @@
/// Internal version of kernel binary format.
/// Bump it when making incompatible changes in kernel binaries.
/// Keep in sync with runtime/vm/kernel_binary.h, pkg/kernel/binary.md.
- static const int BinaryFormatVersion = 90;
+ static const int BinaryFormatVersion = 91;
}
abstract class ConstantTag {
diff --git a/pkg/kernel/lib/text/ast_to_text.dart b/pkg/kernel/lib/text/ast_to_text.dart
index a70b837..ca6cd58 100644
--- a/pkg/kernel/lib/text/ast_to_text.dart
+++ b/pkg/kernel/lib/text/ast_to_text.dart
@@ -1307,6 +1307,7 @@
writeModifier(node.isAbstract, 'abstract');
writeModifier(node.isMacro, 'macro');
writeModifier(node.isSealed, 'sealed');
+ writeModifier(node.isMixinClass, 'mixin');
writeWord('class');
writeWord(getClassName(node));
writeTypeParameterList(node.typeParameters);
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.cc b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
index 040c11b..ceddc65 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.cc
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
@@ -1287,7 +1287,7 @@
if (++next_read_ == field) return;
FALL_THROUGH;
case kFlags:
- flags_ = helper_->ReadFlags(); // read flags.
+ flags_ = helper_->ReadUInt(); // read flags.
if (++next_read_ == field) return;
FALL_THROUGH;
case kNameIndex:
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.h b/runtime/vm/compiler/frontend/kernel_translation_helper.h
index 00295ac0..abb817d 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.h
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.h
@@ -759,6 +759,7 @@
kHasConstConstructor = 1 << 5,
kIsMacro = 1 << 6,
kisSealed = 1 << 7,
+ kIsMixinClass = 1 << 8,
};
explicit ClassHelper(KernelReaderHelper* helper)
@@ -793,7 +794,7 @@
intptr_t source_uri_index_ = 0;
intptr_t annotation_count_ = 0;
intptr_t procedure_count_ = 0;
- uint8_t flags_ = 0;
+ uint32_t flags_ = 0;
private:
KernelReaderHelper* helper_;
diff --git a/runtime/vm/kernel_binary.h b/runtime/vm/kernel_binary.h
index 2ee2ca8..1c0b234 100644
--- a/runtime/vm/kernel_binary.h
+++ b/runtime/vm/kernel_binary.h
@@ -18,7 +18,7 @@
// package:kernel/binary.md.
static const uint32_t kMagicProgramFile = 0x90ABCDEFu;
-static const uint32_t kSupportedKernelFormatVersion = 90;
+static const uint32_t kSupportedKernelFormatVersion = 91;
// Keep in sync with package:kernel/lib/binary/tag.dart
#define KERNEL_TAG_LIST(V) \