mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 11:42:11 +00:00
Mark Kernel classes that were Dart mixin declarations
Add a flag to Kernel classes that indicates that they were Dart mixin declarations. Also, add an API to Kernel Class that allows a list of superclass constraints to be gotten from it. Change-Id: Ie78e7e56b5421dfb9d340e4330135b8d6f4e94f1 Reviewed-on: https://dart-review.googlesource.com/75261 Commit-Queue: Kevin Millikin <kmillikin@google.com> Reviewed-by: Peter von der Ahé <ahe@google.com> Reviewed-by: Dmitry Stefantsov <dmitryas@google.com>
This commit is contained in:
parent
c688d0c0c3
commit
2e43557274
|
@ -88,7 +88,8 @@ class KernelEnumBuilder extends SourceClassBuilder
|
|||
int startCharOffset,
|
||||
int charOffset)
|
||||
: super(metadata, 0, name, null, null, null, scope, constructors, parent,
|
||||
null, startCharOffset, charOffset, TreeNode.noOffset, cls);
|
||||
null, startCharOffset, charOffset, TreeNode.noOffset,
|
||||
cls: cls);
|
||||
|
||||
factory KernelEnumBuilder(
|
||||
MetadataCollector metadataCollector,
|
||||
|
|
|
@ -62,7 +62,11 @@ import '../import.dart' show Import;
|
|||
import '../loader.dart' show Loader;
|
||||
|
||||
import '../modifier.dart'
|
||||
show abstractMask, namedMixinApplicationMask, staticMask;
|
||||
show
|
||||
abstractMask,
|
||||
mixinDeclarationMask,
|
||||
namedMixinApplicationMask,
|
||||
staticMask;
|
||||
|
||||
import '../problems.dart' show unexpected, unhandled;
|
||||
|
||||
|
@ -216,6 +220,11 @@ class KernelLibraryBuilder
|
|||
// library scope.
|
||||
Scope constructorScope = new Scope(constructors, null, null, "constructors",
|
||||
isModifiable: false);
|
||||
bool isMixinDeclaration = false;
|
||||
if (modifiers & mixinDeclarationMask != 0) {
|
||||
isMixinDeclaration = true;
|
||||
modifiers = (modifiers & ~mixinDeclarationMask) | abstractMask;
|
||||
}
|
||||
ClassBuilder cls = new SourceClassBuilder(
|
||||
metadata,
|
||||
modifiers,
|
||||
|
@ -230,7 +239,8 @@ class KernelLibraryBuilder
|
|||
new List<ConstructorReferenceBuilder>.from(constructorReferences),
|
||||
startCharOffset,
|
||||
charOffset,
|
||||
charEndOffset);
|
||||
charEndOffset,
|
||||
isMixinDeclaration: isMixinDeclaration);
|
||||
loader.target.metadataCollector
|
||||
?.setDocumentationComment(cls.target, documentationComment);
|
||||
|
||||
|
@ -470,8 +480,7 @@ class KernelLibraryBuilder
|
|||
startCharOffset,
|
||||
charOffset,
|
||||
TreeNode.noOffset,
|
||||
null,
|
||||
mixin);
|
||||
mixedInType: mixin);
|
||||
if (isNamedMixinApplication) {
|
||||
loader.target.metadataCollector?.setDocumentationComment(
|
||||
application.target, documentationComment);
|
||||
|
|
|
@ -32,6 +32,10 @@ const int staticMask = finalMask << 1;
|
|||
|
||||
const int namedMixinApplicationMask = staticMask << 1;
|
||||
|
||||
/// Not a modifier, used for mixins declared explicitly by using the `mixin`
|
||||
/// keyword.
|
||||
const int mixinDeclarationMask = namedMixinApplicationMask << 1;
|
||||
|
||||
/// Not a real modifier, and by setting it to zero, it is automatically ignored
|
||||
/// by [Modifier.validate] below.
|
||||
const int varMask = 0;
|
||||
|
|
|
@ -59,6 +59,7 @@ import '../modifier.dart'
|
|||
constMask,
|
||||
covariantMask,
|
||||
externalMask,
|
||||
mixinDeclarationMask,
|
||||
staticMask;
|
||||
|
||||
import '../operator.dart'
|
||||
|
@ -535,7 +536,7 @@ class OutlineBuilder extends StackListener {
|
|||
library.addClass(
|
||||
documentationComment,
|
||||
metadata,
|
||||
abstractMask,
|
||||
mixinDeclarationMask,
|
||||
name,
|
||||
typeVariables,
|
||||
supertype,
|
||||
|
|
|
@ -80,6 +80,8 @@ class SourceClassBuilder extends KernelClassBuilder {
|
|||
|
||||
KernelTypeBuilder mixedInType;
|
||||
|
||||
bool isMixinDeclaration;
|
||||
|
||||
SourceClassBuilder(
|
||||
List<MetadataBuilder> metadata,
|
||||
int modifiers,
|
||||
|
@ -94,8 +96,9 @@ class SourceClassBuilder extends KernelClassBuilder {
|
|||
int startCharOffset,
|
||||
int charOffset,
|
||||
int charEndOffset,
|
||||
[ShadowClass cls,
|
||||
this.mixedInType])
|
||||
{Class cls,
|
||||
this.mixedInType,
|
||||
this.isMixinDeclaration = false})
|
||||
: actualCls = initializeClass(cls, typeVariables, name, parent,
|
||||
startCharOffset, charOffset, charEndOffset),
|
||||
super(metadata, modifiers, name, typeVariables, supertype, interfaces,
|
||||
|
@ -141,6 +144,7 @@ class SourceClassBuilder extends KernelClassBuilder {
|
|||
supertype?.buildSupertype(library, charOffset, fileUri);
|
||||
actualCls.mixedInType =
|
||||
mixedInType?.buildMixedInType(library, charOffset, fileUri);
|
||||
actualCls.isMixinDeclaration = isMixinDeclaration;
|
||||
// TODO(ahe): If `cls.supertype` is null, and this isn't Object, report a
|
||||
// compile-time error.
|
||||
cls.isAbstract = isAbstract;
|
||||
|
|
|
@ -291,7 +291,7 @@ type Class extends Node {
|
|||
FileOffset fileOffset; // Offset of the name of the class.
|
||||
FileOffset fileEndOffset;
|
||||
Byte flags (levelBit0, levelBit1, isAbstract, isEnum, isAnonymousMixin,
|
||||
isEliminatedMixin); // Where level is index into ClassLevel
|
||||
isEliminatedMixin, isMixinDeclaration); // Where level is index into ClassLevel
|
||||
StringReference name;
|
||||
List<Expression> annotations;
|
||||
List<TypeParameter> typeParameters;
|
||||
|
|
|
@ -728,6 +728,7 @@ class Class extends NamedNode implements FileUriNode {
|
|||
static const int FlagEnum = 1 << 3;
|
||||
static const int FlagAnonymousMixin = 1 << 4;
|
||||
static const int FlagEliminatedMixin = 1 << 5;
|
||||
static const int FlagMixinDeclaration = 1 << 6;
|
||||
|
||||
int flags = 0;
|
||||
|
||||
|
@ -774,6 +775,38 @@ class Class extends NamedNode implements FileUriNode {
|
|||
value ? (flags | FlagEliminatedMixin) : (flags & ~FlagEliminatedMixin);
|
||||
}
|
||||
|
||||
/// True if this class was a mixin declaration in Dart.
|
||||
///
|
||||
/// Mixins are declared in Dart with the `mixin` keyword. They are compiled
|
||||
/// to Kernel classes.
|
||||
bool get isMixinDeclaration => flags & FlagMixinDeclaration != 0;
|
||||
|
||||
void set isMixinDeclaration(bool value) {
|
||||
flags = value
|
||||
? (flags | FlagMixinDeclaration)
|
||||
: (flags & ~FlagMixinDeclaration);
|
||||
}
|
||||
|
||||
List<Supertype> superclassConstraints() {
|
||||
var constraints = <Supertype>[];
|
||||
|
||||
// Not a mixin declaration.
|
||||
if (!isMixinDeclaration) return constraints;
|
||||
|
||||
Class previous = this;
|
||||
Class current = supertype.classNode;
|
||||
|
||||
// Otherwise we have a left-linear binary tree (subtrees are supertype and
|
||||
// mixedInType) of constraints, where all the interior nodes are anonymous
|
||||
// mixin applications.
|
||||
while (current != null && current.isAnonymousMixin) {
|
||||
constraints.add(current.mixedInType);
|
||||
previous = current;
|
||||
current = current.supertype.classNode;
|
||||
}
|
||||
return constraints..add(previous.supertype);
|
||||
}
|
||||
|
||||
/// The URI of the source file this class was loaded from.
|
||||
Uri fileUri;
|
||||
|
||||
|
|
Loading…
Reference in a new issue