mirror of
https://github.com/dart-lang/sdk
synced 2024-09-15 23:39:48 +00:00
Build ClassAugmentationElementImpl, basic linking.
Change-Id: I18bd3d97ad9fe661d14e3d3d006219ffceedcfc4 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/312349 Reviewed-by: Brian Wilkerson <brianwilkerson@google.com> Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
This commit is contained in:
parent
9d876d12b2
commit
fc0e656868
|
@ -55,7 +55,8 @@ class RedirectingContributor extends DartCompletionContributor {
|
|||
var containingConstructor =
|
||||
parent.thisOrAncestorOfType<ConstructorDeclaration>();
|
||||
var constructorElement = containingConstructor?.declaredElement;
|
||||
var classElement = constructorElement?.enclosingElement2;
|
||||
var classElement =
|
||||
constructorElement?.enclosingElement2.augmentedDeclaration;
|
||||
var libraryElement = request.libraryElement;
|
||||
if (classElement == null) {
|
||||
return;
|
||||
|
|
|
@ -420,7 +420,12 @@ class SuggestionBuilder {
|
|||
// If the class name is already in the text, then we don't support
|
||||
// prepending a prefix.
|
||||
assert(!hasClassName || prefix == null);
|
||||
var enclosingClass = constructor.enclosingElement2;
|
||||
|
||||
var enclosingClass = constructor.enclosingElement2.augmentedDeclaration;
|
||||
if (enclosingClass == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
var className = enclosingClass.name;
|
||||
if (className.isEmpty) {
|
||||
return;
|
||||
|
@ -828,7 +833,8 @@ class SuggestionBuilder {
|
|||
var element = parameter.enclosingElement2;
|
||||
// If appendColon is false, default values should never be appended.
|
||||
if (element is ConstructorElement && appendColon) {
|
||||
if (Flutter.instance.isWidget(element.enclosingElement2)) {
|
||||
if (Flutter.instance
|
||||
.isWidget(element.enclosingElement2.augmentedDeclaration)) {
|
||||
var codeStyleOptions = request
|
||||
.analysisSession.analysisContext.analysisOptions.codeStyleOptions;
|
||||
// Don't bother with nullability. It won't affect default list values.
|
||||
|
|
|
@ -203,7 +203,8 @@ class Flutter {
|
|||
|
||||
/// Return the presentation for the given Flutter `Widget` creation [node].
|
||||
String? getWidgetPresentationText(InstanceCreationExpression node) {
|
||||
var element = node.constructorName.staticElement?.enclosingElement2;
|
||||
var element = node
|
||||
.constructorName.staticElement?.enclosingElement2.augmentedDeclaration;
|
||||
if (!isWidget(element)) {
|
||||
return null;
|
||||
}
|
||||
|
@ -524,7 +525,8 @@ class Flutter {
|
|||
/// Return `true` if the given [expr] is a constructor invocation for a
|
||||
/// class that has the Flutter class `Widget` as a superclass.
|
||||
bool isWidgetCreation(InstanceCreationExpression? expr) {
|
||||
var element = expr?.constructorName.staticElement?.enclosingElement2;
|
||||
var element = expr
|
||||
?.constructorName.staticElement?.enclosingElement2.augmentedDeclaration;
|
||||
return isWidget(element);
|
||||
}
|
||||
|
||||
|
|
|
@ -212,7 +212,7 @@ abstract class ClassAugmentationElement implements ClassOrAugmentationElement {
|
|||
///
|
||||
/// Clients may not extend, implement or mix-in this class.
|
||||
abstract class ClassElement
|
||||
implements ClassOrAugmentationElement, InterfaceElement {
|
||||
implements InterfaceElement, ClassOrAugmentationElement {
|
||||
/// The result of applying augmentations.
|
||||
AugmentedClassElement get augmented;
|
||||
|
||||
|
@ -343,6 +343,9 @@ abstract class ClassOrAugmentationElement
|
|||
/// [ClassAugmentationElement.augmentationTarget] is the back pointer that
|
||||
/// will point at this element.
|
||||
ClassAugmentationElement? get augmentation;
|
||||
|
||||
@override
|
||||
ClassElement? get augmentedDeclaration;
|
||||
}
|
||||
|
||||
/// An element representing a compilation unit.
|
||||
|
@ -353,6 +356,9 @@ abstract class CompilationUnitElement implements UriReferencedElement {
|
|||
/// compilation unit.
|
||||
List<PropertyAccessorElement> get accessors;
|
||||
|
||||
/// The class augmentations declared in this compilation unit.
|
||||
List<ClassAugmentationElement> get classAugmentations;
|
||||
|
||||
/// The classes declared in this compilation unit.
|
||||
List<ClassElement> get classes;
|
||||
|
||||
|
@ -439,7 +445,7 @@ abstract class ConstructorElement
|
|||
InterfaceElement get enclosingElement;
|
||||
|
||||
@override
|
||||
NamedInstanceElement get enclosingElement2;
|
||||
NamedInstanceOrAugmentationElement get enclosingElement2;
|
||||
|
||||
/// Whether the constructor is a const constructor.
|
||||
bool get isConst;
|
||||
|
@ -477,7 +483,7 @@ abstract class ConstructorElement
|
|||
InterfaceType get returnType;
|
||||
|
||||
@override
|
||||
NamedInstanceType get returnType2;
|
||||
DartType get returnType2;
|
||||
}
|
||||
|
||||
/// [ImportElementPrefix] that is used together with `deferred`.
|
||||
|
@ -1202,7 +1208,7 @@ abstract class EnumAugmentationElement implements EnumOrAugmentationElement {
|
|||
///
|
||||
/// Clients may not extend, implement or mix-in this class.
|
||||
abstract class EnumElement
|
||||
implements EnumOrAugmentationElement, InterfaceElement {
|
||||
implements InterfaceElement, EnumOrAugmentationElement {
|
||||
/// The result of applying augmentations.
|
||||
AugmentedEnumElement get augmented;
|
||||
}
|
||||
|
@ -1219,6 +1225,9 @@ abstract class EnumOrAugmentationElement
|
|||
/// [EnumAugmentationElement.augmentationTarget] is the back pointer that
|
||||
/// will point at this element.
|
||||
EnumAugmentationElement? get augmentation;
|
||||
|
||||
@override
|
||||
EnumElement? get augmentedDeclaration;
|
||||
}
|
||||
|
||||
/// An element representing an executable object, including functions, methods,
|
||||
|
@ -1502,7 +1511,7 @@ abstract class InlineClassAugmentationElement
|
|||
/// Clients may not extend, implement or mix-in this class.
|
||||
@experimental
|
||||
abstract class InlineClassElement
|
||||
implements InlineClassOrAugmentationElement, NamedInstanceElement {
|
||||
implements NamedInstanceElement, InlineClassOrAugmentationElement {
|
||||
/// The result of applying augmentations.
|
||||
@experimental
|
||||
AugmentedInlineClassElement get augmented;
|
||||
|
@ -1524,6 +1533,25 @@ abstract class InlineClassOrAugmentationElement
|
|||
/// [InlineClassAugmentationElement.augmentationTarget] is the back pointer
|
||||
/// that will point at this element.
|
||||
InlineClassAugmentationElement? get augmentation;
|
||||
|
||||
@override
|
||||
InlineClassElement? get augmentedDeclaration;
|
||||
}
|
||||
|
||||
/// [InstanceElement] augmentation.
|
||||
///
|
||||
/// Clients may not extend, implement or mix-in this class.
|
||||
@experimental
|
||||
abstract class InstanceAugmentationElement
|
||||
implements InstanceOrAugmentationElement {
|
||||
/// The element that is augmented by this augmentation; or `null` if
|
||||
/// there is no corresponding element to be augmented.
|
||||
///
|
||||
/// The chain of augmentations should normally end with a [InstanceElement],
|
||||
/// but might end with `null` immediately or after a few intermediate
|
||||
/// [InstanceAugmentationElement]s in case of invalid code when an
|
||||
/// augmentation is declared without the corresponding declaration.
|
||||
InstanceOrAugmentationElement? get augmentationTarget;
|
||||
}
|
||||
|
||||
/// An element that has `this`.
|
||||
|
@ -1550,6 +1578,11 @@ abstract class InstanceOrAugmentationElement
|
|||
/// The declared accessors (getters and setters).
|
||||
List<PropertyAccessorElement> get accessors;
|
||||
|
||||
/// The declaration in the main library, the start of the augmentation chain.
|
||||
///
|
||||
/// [InstanceElement] returns itself.
|
||||
InstanceElement? get augmentedDeclaration;
|
||||
|
||||
@Deprecated('Use enclosingElement2 instead')
|
||||
@override
|
||||
CompilationUnitElement get enclosingElement;
|
||||
|
@ -1568,7 +1601,7 @@ abstract class InstanceOrAugmentationElement
|
|||
///
|
||||
/// Clients may not extend, implement or mix-in this class.
|
||||
abstract class InterfaceElement
|
||||
implements InterfaceOrAugmentationElement, NamedInstanceElement {
|
||||
implements NamedInstanceElement, InterfaceOrAugmentationElement {
|
||||
/// All the supertypes defined for this element and its supertypes.
|
||||
///
|
||||
/// This includes superclasses, mixins, interfaces, and superclass constraints.
|
||||
|
@ -1800,6 +1833,9 @@ abstract class InterfaceElement
|
|||
@experimental
|
||||
abstract class InterfaceOrAugmentationElement
|
||||
implements NamedInstanceOrAugmentationElement {
|
||||
@override
|
||||
InterfaceElement? get augmentedDeclaration;
|
||||
|
||||
/// The interfaces that are implemented by this class.
|
||||
///
|
||||
/// <b>Note:</b> Because the element model represents the state of the code,
|
||||
|
@ -2126,7 +2162,7 @@ abstract class MixinAugmentationElement implements MixinOrAugmentationElement {
|
|||
///
|
||||
/// Clients may not extend, implement or mix-in this class.
|
||||
abstract class MixinElement
|
||||
implements MixinOrAugmentationElement, InterfaceElement {
|
||||
implements InterfaceElement, MixinOrAugmentationElement {
|
||||
/// The result of applying augmentations.
|
||||
AugmentedMixinElement get augmented;
|
||||
|
||||
|
@ -2166,6 +2202,9 @@ abstract class MixinOrAugmentationElement
|
|||
/// [MixinAugmentationElement.augmentationTarget] is the back pointer that
|
||||
/// will point at this element.
|
||||
MixinAugmentationElement? get augmentation;
|
||||
|
||||
@override
|
||||
MixinElement? get augmentedDeclaration;
|
||||
}
|
||||
|
||||
/// A pseudo-element that represents multiple elements defined within a single
|
||||
|
@ -2194,7 +2233,7 @@ abstract class MultiplyInheritedExecutableElement implements ExecutableElement {
|
|||
/// Clients may not extend, implement or mix-in this class.
|
||||
@experimental
|
||||
abstract class NamedInstanceElement
|
||||
implements NamedInstanceOrAugmentationElement, InstanceElement {
|
||||
implements InstanceElement, NamedInstanceOrAugmentationElement {
|
||||
/// Create the [DartType] for this element with the given [typeArguments]
|
||||
/// and [nullabilitySuffix].
|
||||
DartType instantiate({
|
||||
|
@ -2209,6 +2248,9 @@ abstract class NamedInstanceElement
|
|||
@experimental
|
||||
abstract class NamedInstanceOrAugmentationElement
|
||||
implements InstanceOrAugmentationElement {
|
||||
@override
|
||||
NamedInstanceElement? get augmentedDeclaration;
|
||||
|
||||
/// The declared constructors.
|
||||
///
|
||||
/// The list is empty for [MixinElement].
|
||||
|
|
|
@ -87,7 +87,7 @@ import 'package:analyzer/src/utilities/uri_cache.dart';
|
|||
/// TODO(scheglov) Clean up the list of implicitly analyzed files.
|
||||
class AnalysisDriver implements AnalysisDriverGeneric {
|
||||
/// The version of data format, should be incremented on every format change.
|
||||
static const int DATA_VERSION = 279;
|
||||
static const int DATA_VERSION = 280;
|
||||
|
||||
/// The number of exception contexts allowed to write. Once this field is
|
||||
/// zero, we stop writing any new exception contexts in this process.
|
||||
|
|
|
@ -2705,7 +2705,7 @@ final class ClassAugmentationDeclarationImpl
|
|||
final Token augmentKeyword;
|
||||
|
||||
@override
|
||||
ClassAugmentationElement? declaredElement;
|
||||
ClassAugmentationElementImpl? declaredElement;
|
||||
|
||||
ClassAugmentationDeclarationImpl({
|
||||
required super.comment,
|
||||
|
|
|
@ -248,12 +248,16 @@ class ConstantVerifier extends RecursiveAstVisitor<void> {
|
|||
// evaluation.
|
||||
var constructor = node.constructorName.staticElement;
|
||||
if (constructor != null) {
|
||||
var returnType = constructor.returnType2;
|
||||
if (returnType is! InterfaceType) {
|
||||
return;
|
||||
}
|
||||
ConstantVisitor constantVisitor =
|
||||
ConstantVisitor(_evaluationEngine, _currentLibrary, _errorReporter);
|
||||
_evaluationEngine.evaluateConstructorCall(
|
||||
_currentLibrary,
|
||||
node,
|
||||
constructor.returnType2.typeArguments,
|
||||
returnType.typeArguments,
|
||||
node.argumentList.arguments,
|
||||
constructor,
|
||||
constantVisitor,
|
||||
|
|
|
@ -195,7 +195,7 @@ class ConstantEvaluationEngine {
|
|||
var result = evaluateConstructorCall(
|
||||
library,
|
||||
constNode,
|
||||
element.returnType2.typeArguments,
|
||||
element.returnType2.ifTypeOrNull<InterfaceType>()?.typeArguments,
|
||||
constNode.arguments!.arguments,
|
||||
element,
|
||||
constantVisitor,
|
||||
|
@ -891,7 +891,7 @@ class ConstantVisitor extends UnifyingAstVisitor<Constant> {
|
|||
return evaluationEngine.evaluateConstructorCall(
|
||||
_library,
|
||||
node,
|
||||
constructor.returnType2.typeArguments,
|
||||
constructor.returnType2.ifTypeOrNull<InterfaceType>()?.typeArguments,
|
||||
node.argumentList.arguments,
|
||||
constructor,
|
||||
this,
|
||||
|
@ -2432,7 +2432,9 @@ class _InstanceCreationEvaluator {
|
|||
_argumentValues = argumentValues,
|
||||
_invocation = invocation;
|
||||
|
||||
NamedInstanceType get definingType => _constructor.returnType2;
|
||||
NamedInstanceType get definingType =>
|
||||
_constructor.returnType2.ifTypeOrNull<InterfaceType>() ??
|
||||
typeProvider.objectType;
|
||||
|
||||
DartObjectImpl? get firstArgument => _argumentValues[0];
|
||||
|
||||
|
@ -2572,7 +2574,7 @@ class _InstanceCreationEvaluator {
|
|||
continue;
|
||||
}
|
||||
// Match the value and the type.
|
||||
var fieldType = FieldMember.from(field, _constructor.returnType2).type;
|
||||
var fieldType = FieldMember.from(field, definingType).type;
|
||||
if (!typeSystem.runtimeTypeMatch(fieldValue, fieldType)) {
|
||||
_errorReporter.reportErrorForNode(
|
||||
CompileTimeErrorCode.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH,
|
||||
|
|
|
@ -122,9 +122,15 @@ class ClassAugmentationElementImpl extends InterfaceAugmentationElementImpl
|
|||
}
|
||||
|
||||
set augmentationTarget(ClassOrAugmentationElementMixin? value) {
|
||||
value?._augmentation = this;
|
||||
_augmentationTarget = value;
|
||||
}
|
||||
|
||||
@override
|
||||
ClassElementImpl? get augmentedDeclaration {
|
||||
return augmentationTarget?.augmentedDeclaration;
|
||||
}
|
||||
|
||||
@override
|
||||
ElementKind get kind => ElementKind.CLASS_AUGMENTATION;
|
||||
|
||||
|
@ -136,6 +142,7 @@ class ClassAugmentationElementImpl extends InterfaceAugmentationElementImpl
|
|||
|
||||
/// An [InterfaceElementImpl] which is a class.
|
||||
class ClassElementImpl extends ClassOrMixinElementImpl<ClassElementLinkedData>
|
||||
with ClassOrAugmentationElementMixin<ClassElementLinkedData>
|
||||
implements ClassElement {
|
||||
/// Initialize a newly created class element to have the given [name] at the
|
||||
/// given [offset] in the file that contains the declaration of this element.
|
||||
|
@ -198,16 +205,13 @@ class ClassElementImpl extends ClassOrMixinElementImpl<ClassElementLinkedData>
|
|||
}
|
||||
|
||||
@override
|
||||
ClassAugmentationElement? get augmentation {
|
||||
AugmentedClassElement get augmented {
|
||||
// TODO(scheglov) implement
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
AugmentedClassElement get augmented {
|
||||
// TODO(scheglov) implement
|
||||
throw UnimplementedError();
|
||||
}
|
||||
ClassElementImpl get augmentedDeclaration => this;
|
||||
|
||||
@override
|
||||
List<ConstructorElementImpl> get constructors {
|
||||
|
@ -656,10 +660,13 @@ mixin ClassOrAugmentationElementMixin<LinkedData extends ElementLinkedData>
|
|||
ClassAugmentationElementImpl? _augmentation;
|
||||
|
||||
@override
|
||||
ClassAugmentationElement? get augmentation {
|
||||
ClassAugmentationElementImpl? get augmentation {
|
||||
linkedData?.read(this);
|
||||
return _augmentation;
|
||||
}
|
||||
|
||||
@override
|
||||
ClassElementImpl? get augmentedDeclaration;
|
||||
}
|
||||
|
||||
abstract class ClassOrMixinElementImpl<LinkedData extends ElementLinkedData>
|
||||
|
@ -703,8 +710,8 @@ class CompilationUnitElementImpl extends UriReferencedElementImpl
|
|||
/// contained in this compilation unit.
|
||||
List<PropertyAccessorElementImpl> _accessors = const [];
|
||||
|
||||
/// A list containing all of the classes contained in this compilation unit.
|
||||
List<ClassElementImpl> _classes = const [];
|
||||
List<ClassAugmentationElementImpl> _classAugmentations = const [];
|
||||
|
||||
/// A list containing all of the enums contained in this compilation unit.
|
||||
List<EnumElementImpl> _enums = const [];
|
||||
|
@ -764,6 +771,18 @@ class CompilationUnitElementImpl extends UriReferencedElementImpl
|
|||
...topLevelVariables,
|
||||
];
|
||||
|
||||
@override
|
||||
List<ClassAugmentationElementImpl> get classAugmentations {
|
||||
return _classAugmentations;
|
||||
}
|
||||
|
||||
set classAugmentations(List<ClassAugmentationElementImpl> elements) {
|
||||
for (final element in elements) {
|
||||
element.enclosingElement = this;
|
||||
}
|
||||
_classAugmentations = elements;
|
||||
}
|
||||
|
||||
@override
|
||||
List<ClassElementImpl> get classes {
|
||||
return _classes;
|
||||
|
@ -1037,8 +1056,8 @@ class ConstructorElementImpl extends ExecutableElementImpl
|
|||
super.enclosingElement2 as InterfaceElementImpl;
|
||||
|
||||
@override
|
||||
NamedInstanceElement get enclosingElement2 =>
|
||||
super.enclosingElement2 as NamedInstanceElement;
|
||||
NamedInstanceOrAugmentationElement get enclosingElement2 =>
|
||||
super.enclosingElement2 as NamedInstanceOrAugmentationElement;
|
||||
|
||||
@override
|
||||
bool get isConst {
|
||||
|
@ -1100,13 +1119,20 @@ class ConstructorElementImpl extends ExecutableElementImpl
|
|||
}
|
||||
|
||||
@override
|
||||
NamedInstanceType get returnType2 =>
|
||||
ElementTypeProvider.current.getExecutableReturnType(this)
|
||||
as NamedInstanceType;
|
||||
DartType get returnType2 =>
|
||||
ElementTypeProvider.current.getExecutableReturnType(this);
|
||||
|
||||
@override
|
||||
DartType get returnTypeInternal {
|
||||
return _returnType ??= enclosingElement2.thisType;
|
||||
var result = _returnType;
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
|
||||
final augmentedDeclaration = enclosingElement2.augmentedDeclaration;
|
||||
result = augmentedDeclaration?.thisType;
|
||||
result ??= InvalidTypeImpl.instance;
|
||||
return _returnType = result;
|
||||
}
|
||||
|
||||
ConstructorElement? get superConstructor {
|
||||
|
@ -2597,6 +2623,9 @@ class EnumElementImpl extends InterfaceElementImpl<EnumElementLinkedData>
|
|||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
EnumElementImpl get augmentedDeclaration => this;
|
||||
|
||||
List<FieldElementImpl> get constants {
|
||||
return fields.where((field) => field.isEnumConstant).toList();
|
||||
}
|
||||
|
@ -2881,6 +2910,9 @@ class ExtensionElementImpl extends _ExistingElementImpl
|
|||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
ExtensionElementImpl get augmentedDeclaration => this;
|
||||
|
||||
@override
|
||||
List<Element> get children => [
|
||||
...super.children,
|
||||
|
@ -3371,6 +3403,9 @@ class InlineClassElementImpl extends NamedInstanceElementImpl
|
|||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
InlineClassElementImpl get augmentedDeclaration => this;
|
||||
|
||||
@override
|
||||
List<InlineClassType> get implemented {
|
||||
// TODO(scheglov) implement
|
||||
|
@ -3408,8 +3443,12 @@ mixin InlineClassOrAugmentationElementMixin
|
|||
on NamedInstanceOrAugmentationElementMixin
|
||||
implements InlineClassOrAugmentationElement {}
|
||||
|
||||
abstract class InstanceAugmentationElementImpl extends _ExistingElementImpl
|
||||
with TypeParameterizedElementMixin, InstanceOrAugmentationElementMixin {
|
||||
abstract class InstanceAugmentationElementImpl<
|
||||
LinkedData extends ElementLinkedData> extends _ExistingElementImpl
|
||||
with
|
||||
TypeParameterizedElementMixin,
|
||||
InstanceOrAugmentationElementMixin<LinkedData>
|
||||
implements InstanceAugmentationElement {
|
||||
InstanceAugmentationElementImpl(super.name, super.offset);
|
||||
}
|
||||
|
||||
|
@ -3418,7 +3457,7 @@ abstract class InstanceElementImpl<LinkedData extends ElementLinkedData>
|
|||
with
|
||||
TypeParameterizedElementMixin,
|
||||
InstanceOrAugmentationElementMixin<LinkedData>
|
||||
implements InstanceOrAugmentationElement {
|
||||
implements InstanceElement {
|
||||
InstanceElementImpl(super.name, super.nameOffset);
|
||||
}
|
||||
|
||||
|
@ -4970,6 +5009,9 @@ class MixinElementImpl extends ClassOrMixinElementImpl<MixinElementLinkedData>
|
|||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
MixinElementImpl get augmentedDeclaration => this;
|
||||
|
||||
@override
|
||||
List<InterfaceType> get mixins => const [];
|
||||
|
||||
|
@ -5437,7 +5479,7 @@ abstract class NamedInstanceAugmentationElementImpl
|
|||
abstract class NamedInstanceElementImpl<LinkedData extends ElementLinkedData>
|
||||
extends InstanceElementImpl<LinkedData>
|
||||
with NamedInstanceOrAugmentationElementMixin<LinkedData>
|
||||
implements NamedInstanceOrAugmentationElement {
|
||||
implements NamedInstanceElement {
|
||||
NamedInstanceElementImpl(super.name, super.nameOffset);
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ extension ElementAnnotationExtensions on ElementAnnotation {
|
|||
}
|
||||
}
|
||||
} else if (element is ConstructorElement) {
|
||||
instanceElement = element.enclosingElement2;
|
||||
instanceElement = element.enclosingElement2.augmentedDeclaration;
|
||||
}
|
||||
if (instanceElement == null) {
|
||||
return const <TargetKind>{};
|
||||
|
|
|
@ -49,7 +49,9 @@ class ConstructorMember extends ExecutableMember
|
|||
InterfaceElement get enclosingElement => declaration.enclosingElement;
|
||||
|
||||
@override
|
||||
NamedInstanceElement get enclosingElement2 => declaration.enclosingElement2;
|
||||
NamedInstanceOrAugmentationElement get enclosingElement2 {
|
||||
return declaration.enclosingElement2;
|
||||
}
|
||||
|
||||
@override
|
||||
bool get isConst => declaration.isConst;
|
||||
|
|
|
@ -31,6 +31,8 @@ class NullSafeApiVerifier {
|
|||
if (constructor == null) return;
|
||||
|
||||
final type = constructor.returnType2;
|
||||
if (type is! InterfaceType) return;
|
||||
|
||||
final isFutureValue = type.isDartAsyncFuture && constructor.name == 'value';
|
||||
|
||||
if (isFutureValue) {
|
||||
|
|
|
@ -116,8 +116,13 @@ class TypeArgumentsVerifier {
|
|||
return;
|
||||
}
|
||||
|
||||
var returnType = constructorElement.returnType2;
|
||||
if (returnType is! InterfaceType) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check that type arguments are regular-bounded.
|
||||
var typeArguments = constructorElement.returnType2.typeArguments;
|
||||
var typeArguments = returnType.typeArguments;
|
||||
var substitution = Substitution.fromPairs(typeParameters, typeArguments);
|
||||
for (var i = 0; i < typeArguments.length; i++) {
|
||||
var typeParameter = typeParameters[i];
|
||||
|
|
|
@ -102,7 +102,7 @@ class ClassAugmentationElementLinkedData
|
|||
);
|
||||
_readTypeParameters(reader, element.typeParameters);
|
||||
element.augmentationTarget =
|
||||
reader.readElement() as ClassOrAugmentationElementMixin?;
|
||||
reader.readElement() as ClassOrAugmentationElementMixin;
|
||||
element.mixins = reader._readInterfaceTypeList();
|
||||
element.interfaces = reader._readInterfaceTypeList();
|
||||
applyConstantOffsets?.perform();
|
||||
|
@ -620,6 +620,50 @@ class LibraryReader {
|
|||
);
|
||||
}
|
||||
|
||||
ClassAugmentationElementImpl _readClassAugmentationElement(
|
||||
CompilationUnitElementImpl unitElement,
|
||||
Reference unitReference,
|
||||
) {
|
||||
var resolutionOffset = _baseResolutionOffset + _reader.readUInt30();
|
||||
var name = _reader.readStringReference();
|
||||
var reference = unitReference.getChild('@classAugmentation').getChild(name);
|
||||
|
||||
var element = ClassAugmentationElementImpl(name, -1);
|
||||
|
||||
var linkedData = ClassAugmentationElementLinkedData(
|
||||
reference: reference,
|
||||
libraryReader: this,
|
||||
unitElement: unitElement,
|
||||
offset: resolutionOffset,
|
||||
);
|
||||
element.setLinkedData(reference, linkedData);
|
||||
ClassAugmentationElementFlags.read(_reader, element);
|
||||
|
||||
element.typeParameters = _readTypeParameters();
|
||||
|
||||
var fields = <FieldElementImpl>[];
|
||||
var accessors = <PropertyAccessorElementImpl>[];
|
||||
_readFields(unitElement, element, reference, accessors, fields);
|
||||
_readPropertyAccessors(
|
||||
unitElement, element, reference, accessors, fields, '@field');
|
||||
element.fields = fields.toFixedList();
|
||||
element.accessors = accessors.toFixedList();
|
||||
|
||||
element.constructors = _readConstructors(unitElement, element, reference);
|
||||
element.methods = _readMethods(unitElement, element, reference);
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
void _readClassAugmentations(
|
||||
CompilationUnitElementImpl unitElement,
|
||||
Reference unitReference,
|
||||
) {
|
||||
unitElement.classAugmentations = _reader.readTypedList(() {
|
||||
return _readClassAugmentationElement(unitElement, unitReference);
|
||||
});
|
||||
}
|
||||
|
||||
ClassElementImpl _readClassElement(
|
||||
CompilationUnitElementImpl unitElement,
|
||||
Reference unitReference,
|
||||
|
@ -693,7 +737,7 @@ class LibraryReader {
|
|||
|
||||
List<ConstructorElementImpl> _readConstructors(
|
||||
CompilationUnitElementImpl unitElement,
|
||||
InterfaceElementImpl classElement,
|
||||
NamedInstanceOrAugmentationElementMixin classElement,
|
||||
Reference classReference,
|
||||
) {
|
||||
var containerRef = classReference.getChild('@constructor');
|
||||
|
@ -1522,6 +1566,7 @@ class LibraryReader {
|
|||
unitElement.isSynthetic = _reader.readBool();
|
||||
|
||||
_readClasses(unitElement, unitReference);
|
||||
_readClassAugmentations(unitElement, unitReference);
|
||||
_readEnums(unitElement, unitReference);
|
||||
_readExtensions(unitElement, unitReference);
|
||||
_readFunctions(unitElement, unitReference);
|
||||
|
|
|
@ -137,6 +137,32 @@ class BundleWriter {
|
|||
_writeDirectiveUri(element.uri);
|
||||
}
|
||||
|
||||
void _writeClassAugmentationElement(ClassAugmentationElementImpl element) {
|
||||
_sink.writeUInt30(_resolutionSink.offset);
|
||||
|
||||
_sink._writeStringReference(element.name);
|
||||
ClassAugmentationElementFlags.write(_sink, element);
|
||||
|
||||
_resolutionSink._writeAnnotationList(element.metadata);
|
||||
|
||||
_writeTypeParameters(element.typeParameters, () {
|
||||
_resolutionSink.writeElement(element.augmentationTarget);
|
||||
_resolutionSink._writeTypeList(element.mixins);
|
||||
_resolutionSink._writeTypeList(element.interfaces);
|
||||
|
||||
_writeList(
|
||||
element.fields.where((e) => !e.isSynthetic).toList(),
|
||||
_writeFieldElement,
|
||||
);
|
||||
_writeList(
|
||||
element.accessors.where((e) => !e.isSynthetic).toList(),
|
||||
_writePropertyAccessorElement,
|
||||
);
|
||||
_writeList(element.constructors, _writeConstructorElement);
|
||||
_writeList(element.methods, _writeMethodElement);
|
||||
});
|
||||
}
|
||||
|
||||
void _writeClassElement(ClassElementImpl element) {
|
||||
_sink.writeUInt30(_resolutionSink.offset);
|
||||
|
||||
|
@ -533,6 +559,7 @@ class BundleWriter {
|
|||
_sink._writeOptionalStringReference(unitElement.uri);
|
||||
_sink.writeBool(unitElement.isSynthetic);
|
||||
_writeList(unitElement.classes, _writeClassElement);
|
||||
_writeList(unitElement.classAugmentations, _writeClassAugmentationElement);
|
||||
_writeList(unitElement.enums, _writeEnumElement);
|
||||
_writeList(unitElement.extensions, _writeExtensionElement);
|
||||
_writeList(unitElement.functions, _writeFunctionElement);
|
||||
|
|
|
@ -48,6 +48,7 @@ class ElementBuilder extends ThrowingAstVisitor<void> {
|
|||
_visitPropertyFirst<TopLevelVariableDeclaration>(unit.declarations);
|
||||
_unitElement.accessors = _enclosingContext.propertyAccessors;
|
||||
_unitElement.classes = _enclosingContext.classes;
|
||||
_unitElement.classAugmentations = _enclosingContext.classAugmentations;
|
||||
_unitElement.enums = _enclosingContext.enums;
|
||||
_unitElement.extensions = _enclosingContext.extensions;
|
||||
_unitElement.functions = _enclosingContext.functions;
|
||||
|
@ -83,9 +84,48 @@ class ElementBuilder extends ThrowingAstVisitor<void> {
|
|||
}
|
||||
|
||||
@override
|
||||
void visitClassAugmentationDeclaration(ClassAugmentationDeclaration node) {
|
||||
// TODO: implement visitClassAugmentationDeclaration
|
||||
// super.visitClassAugmentationDeclaration(node);
|
||||
void visitClassAugmentationDeclaration(
|
||||
covariant ClassAugmentationDeclarationImpl node,
|
||||
) {
|
||||
final nameToken = node.name;
|
||||
final name = nameToken.lexeme;
|
||||
|
||||
final element = ClassAugmentationElementImpl(name, nameToken.offset);
|
||||
element.metadata = _buildAnnotations(node.metadata);
|
||||
_setCodeRange(element, node);
|
||||
_setDocumentation(element, node);
|
||||
|
||||
node.declaredElement = element;
|
||||
_linker.elementNodes[element] = node;
|
||||
|
||||
final reference = _enclosingContext.addClassAugmentation(name, element);
|
||||
_libraryBuilder.declare(name, reference);
|
||||
|
||||
final holder = _EnclosingContext(reference, element);
|
||||
_withEnclosing(holder, () {
|
||||
final typeParameters = node.typeParameters;
|
||||
if (typeParameters != null) {
|
||||
typeParameters.accept(this);
|
||||
element.typeParameters = holder.typeParameters;
|
||||
}
|
||||
});
|
||||
|
||||
node.withClause?.accept(this);
|
||||
node.implementsClause?.accept(this);
|
||||
|
||||
_withEnclosing(holder, () {
|
||||
_visitPropertyFirst<FieldDeclaration>(node.members);
|
||||
});
|
||||
|
||||
element.accessors = holder.propertyAccessors;
|
||||
element.constructors = holder.constructors;
|
||||
element.fields = holder.fields;
|
||||
element.methods = holder.methods;
|
||||
|
||||
// TODO(scheglov) We cannot do this anymore.
|
||||
// Not for class augmentations, not for classes.
|
||||
// At the time when we build, we don't know all fields yet.
|
||||
// _resolveConstructorFieldFormals(element);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -1341,6 +1381,7 @@ class _EnclosingContext {
|
|||
final Reference reference;
|
||||
final ElementImpl element;
|
||||
final List<ClassElementImpl> _classes = [];
|
||||
final List<ClassAugmentationElementImpl> _classAugmentations = [];
|
||||
final List<ConstructorElementImpl> _constructors = [];
|
||||
final List<EnumElementImpl> _enums = [];
|
||||
final List<ExtensionElementImpl> _extensions = [];
|
||||
|
@ -1368,6 +1409,10 @@ class _EnclosingContext {
|
|||
this.hasDefaultFormalParameters = false,
|
||||
});
|
||||
|
||||
List<ClassAugmentationElementImpl> get classAugmentations {
|
||||
return _classAugmentations.toFixedList();
|
||||
}
|
||||
|
||||
List<ClassElementImpl> get classes {
|
||||
return _classes.toFixedList();
|
||||
}
|
||||
|
@ -1432,6 +1477,14 @@ class _EnclosingContext {
|
|||
return _bindReference('@class', name, element);
|
||||
}
|
||||
|
||||
Reference addClassAugmentation(
|
||||
String name,
|
||||
ClassAugmentationElementImpl element,
|
||||
) {
|
||||
_classAugmentations.add(element);
|
||||
return _bindReference('@classAugmentation', name, element);
|
||||
}
|
||||
|
||||
Reference addConstructor(ConstructorElementImpl element) {
|
||||
_constructors.add(element);
|
||||
|
||||
|
|
|
@ -6,6 +6,20 @@ import 'package:analyzer/src/dart/element/element.dart';
|
|||
import 'package:analyzer/src/summary2/data_reader.dart';
|
||||
import 'package:analyzer/src/summary2/data_writer.dart';
|
||||
|
||||
class ClassAugmentationElementFlags {
|
||||
static void read(
|
||||
SummaryDataReader reader,
|
||||
ClassAugmentationElementImpl element,
|
||||
) {
|
||||
reader.readUInt30();
|
||||
}
|
||||
|
||||
static void write(BufferedSink sink, ClassAugmentationElementImpl element) {
|
||||
var result = 0;
|
||||
sink.writeUInt30(result);
|
||||
}
|
||||
}
|
||||
|
||||
class ClassElementFlags {
|
||||
static const int _isAbstract = 1 << 0;
|
||||
static const int _isBase = 1 << 1;
|
||||
|
|
|
@ -101,6 +101,12 @@ class InformativeDataApplier {
|
|||
_applyToClassDeclaration,
|
||||
);
|
||||
|
||||
forCorrespondingPairs(
|
||||
unitElement.classAugmentations,
|
||||
unitInfo.classAugmentationDeclarations,
|
||||
_applyToClassAugmentationDeclaration,
|
||||
);
|
||||
|
||||
forCorrespondingPairs(
|
||||
unitElement.classes
|
||||
.where((element) => element.isMixinApplication)
|
||||
|
@ -205,6 +211,33 @@ class InformativeDataApplier {
|
|||
);
|
||||
}
|
||||
|
||||
void _applyToClassAugmentationDeclaration(
|
||||
ClassAugmentationElementImpl element,
|
||||
_InfoClassDeclaration info,
|
||||
) {
|
||||
element.setCodeRange(info.codeOffset, info.codeLength);
|
||||
element.nameOffset = info.nameOffset;
|
||||
element.documentationComment = info.documentationComment;
|
||||
_applyToTypeParameters(
|
||||
element.typeParameters_unresolved,
|
||||
info.typeParameters,
|
||||
);
|
||||
|
||||
_applyToConstructors(element.constructors, info.constructors);
|
||||
_applyToFields(element.fields, info.fields);
|
||||
_applyToAccessors(element.accessors, info.accessors);
|
||||
_applyToMethods(element.methods, info.methods);
|
||||
|
||||
var linkedData = element.linkedData as ClassAugmentationElementLinkedData;
|
||||
linkedData.applyConstantOffsets = ApplyConstantOffsets(
|
||||
info.constantOffsets,
|
||||
(applier) {
|
||||
applier.applyToMetadata(element);
|
||||
applier.applyToTypeParameters(element.typeParameters);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void _applyToClassDeclaration(
|
||||
ClassElement element,
|
||||
_InfoClassDeclaration info,
|
||||
|
@ -1130,6 +1163,22 @@ class _InformativeDataWriter {
|
|||
);
|
||||
});
|
||||
|
||||
sink.writeList2<ClassAugmentationDeclaration>(unit.declarations, (node) {
|
||||
sink.writeUInt30(node.offset);
|
||||
sink.writeUInt30(node.length);
|
||||
sink.writeUInt30(node.name.offset);
|
||||
_writeDocumentationComment(node);
|
||||
_writeTypeParameters(node.typeParameters);
|
||||
_writeConstructors(node.members);
|
||||
_writeFields(node.members);
|
||||
_writeGettersSetters(node.members);
|
||||
_writeMethods(node.members);
|
||||
_writeOffsets(
|
||||
metadata: node.metadata,
|
||||
typeParameters: node.typeParameters,
|
||||
);
|
||||
});
|
||||
|
||||
sink.writeList2<ClassTypeAlias>(unit.declarations, (node) {
|
||||
sink.writeUInt30(node.offset);
|
||||
sink.writeUInt30(node.length);
|
||||
|
@ -1620,6 +1669,7 @@ class _InfoUnit {
|
|||
final List<_InfoExport> exports;
|
||||
final List<_InfoPart> parts;
|
||||
final List<_InfoClassDeclaration> classDeclarations;
|
||||
final List<_InfoClassDeclaration> classAugmentationDeclarations;
|
||||
final List<_InfoClassTypeAlias> classTypeAliases;
|
||||
final List<_InfoClassDeclaration> enums;
|
||||
final List<_InfoClassDeclaration> extensions;
|
||||
|
@ -1650,6 +1700,9 @@ class _InfoUnit {
|
|||
classDeclarations: reader.readTypedList(
|
||||
() => _InfoClassDeclaration(reader),
|
||||
),
|
||||
classAugmentationDeclarations: reader.readTypedList(
|
||||
() => _InfoClassDeclaration(reader),
|
||||
),
|
||||
classTypeAliases: reader.readTypedList(
|
||||
() => _InfoClassTypeAlias(reader),
|
||||
),
|
||||
|
@ -1691,6 +1744,7 @@ class _InfoUnit {
|
|||
required this.exports,
|
||||
required this.parts,
|
||||
required this.classDeclarations,
|
||||
required this.classAugmentationDeclarations,
|
||||
required this.classTypeAliases,
|
||||
required this.enums,
|
||||
required this.extensions,
|
||||
|
|
|
@ -175,6 +175,7 @@ class LibraryBuilder {
|
|||
}
|
||||
elementBuilder.buildDeclarationElements(linkingUnit.node);
|
||||
}
|
||||
_mergeAugmentations();
|
||||
_declareDartCoreDynamicNever();
|
||||
}
|
||||
|
||||
|
@ -759,6 +760,21 @@ class LibraryBuilder {
|
|||
}
|
||||
}
|
||||
|
||||
void _mergeAugmentations() {
|
||||
final targets = <String, ClassOrAugmentationElementMixin>{};
|
||||
for (final unitElement in element.units) {
|
||||
for (final classElement in unitElement.classes) {
|
||||
targets[classElement.name] = classElement;
|
||||
}
|
||||
for (final augmentation in unitElement.classAugmentations) {
|
||||
final name = augmentation.name;
|
||||
// TODO(scheglov) create synthetic instead of null assert
|
||||
augmentation.augmentationTarget = targets[name]!;
|
||||
targets[augmentation.name] = augmentation;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void build(Linker linker, LibraryFileKind inputLibrary) {
|
||||
final elementFactory = linker.elementFactory;
|
||||
final rootReference = linker.rootReference;
|
||||
|
|
|
@ -39,6 +39,12 @@ class MetadataResolver extends ThrowingAstVisitor<void> {
|
|||
node.metadata.accept(this);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitClassAugmentationDeclaration(ClassAugmentationDeclaration node) {
|
||||
// TODO: implement visitClassAugmentationDeclaration
|
||||
// super.visitClassAugmentationDeclaration(node);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitClassDeclaration(ClassDeclaration node) {
|
||||
node.metadata.accept(this);
|
||||
|
|
|
@ -150,6 +150,15 @@ class _ElementWriter {
|
|||
);
|
||||
}
|
||||
|
||||
void _writeAugmentation(InterfaceOrAugmentationElementMixin e) {
|
||||
if (e case ClassOrAugmentationElementMixin e) {
|
||||
final augmentation = e.augmentation;
|
||||
if (augmentation != null) {
|
||||
_elementPrinter.writeNamedElement('augmentation', augmentation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void _writeAugmentationElement(LibraryAugmentationElementImpl e) {
|
||||
_writeLibraryOrAugmentationElement(e);
|
||||
}
|
||||
|
@ -168,6 +177,27 @@ class _ElementWriter {
|
|||
});
|
||||
}
|
||||
|
||||
void _writeAugmentationTarget(InterfaceOrAugmentationElementMixin e) {
|
||||
if (e case InstanceAugmentationElementImpl e) {
|
||||
_elementPrinter.writeNamedElement(
|
||||
'augmentationTarget',
|
||||
e.augmentationTarget,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void _writeAugmentedDeclaration(InterfaceOrAugmentationElementMixin e) {
|
||||
final augmentedDeclaration = e.augmentedDeclaration;
|
||||
if (identical(augmentedDeclaration, e)) {
|
||||
return;
|
||||
}
|
||||
|
||||
_elementPrinter.writeNamedElement(
|
||||
'augmentedDeclaration',
|
||||
augmentedDeclaration,
|
||||
);
|
||||
}
|
||||
|
||||
void _writeBodyModifiers(ExecutableElement e) {
|
||||
if (e.isAsynchronous) {
|
||||
expect(e.isSynchronous, isFalse);
|
||||
|
@ -186,79 +216,6 @@ class _ElementWriter {
|
|||
}
|
||||
}
|
||||
|
||||
void _writeClassElement(InterfaceElement e) {
|
||||
_sink.writeIndentedLine(() {
|
||||
if (e is ClassElement) {
|
||||
_sink.writeIf(e.isAbstract, 'abstract ');
|
||||
_sink.writeIf(e.isMacro, 'macro ');
|
||||
_sink.writeIf(e.isSealed, 'sealed ');
|
||||
_sink.writeIf(e.isBase, 'base ');
|
||||
_sink.writeIf(e.isInterface, 'interface ');
|
||||
_sink.writeIf(e.isFinal, 'final ');
|
||||
_sink.writeIf(e.isInline, 'inline ');
|
||||
_sink.writeIf(e.isMixinClass, 'mixin ');
|
||||
}
|
||||
_sink.writeIf(!e.isSimplyBounded, 'notSimplyBounded ');
|
||||
|
||||
if (e is EnumElement) {
|
||||
_sink.write('enum ');
|
||||
} else if (e is MixinElement) {
|
||||
_sink.writeIf(e.isBase, 'base ');
|
||||
_sink.write('mixin ');
|
||||
} else {
|
||||
_sink.write('class ');
|
||||
}
|
||||
if (e is ClassElement) {
|
||||
_sink.writeIf(e.isMixinApplication, 'alias ');
|
||||
}
|
||||
|
||||
_writeName(e);
|
||||
});
|
||||
|
||||
_sink.withIndent(() {
|
||||
_writeDocumentation(e);
|
||||
_writeMetadata(e);
|
||||
_writeSinceSdkVersion(e);
|
||||
_writeCodeRange(e);
|
||||
_writeTypeParameterElements(e.typeParameters);
|
||||
|
||||
final supertype = e.supertype;
|
||||
if (supertype != null &&
|
||||
(supertype.element.name != 'Object' || e.mixins.isNotEmpty)) {
|
||||
_writeType('supertype', supertype);
|
||||
}
|
||||
|
||||
if (e is MixinElement) {
|
||||
var superclassConstraints = e.superclassConstraints;
|
||||
if (superclassConstraints.isEmpty) {
|
||||
throw StateError('At least Object is expected.');
|
||||
}
|
||||
_elementPrinter.writeTypeList(
|
||||
'superclassConstraints',
|
||||
superclassConstraints,
|
||||
);
|
||||
}
|
||||
|
||||
_elementPrinter.writeTypeList('mixins', e.mixins);
|
||||
_elementPrinter.writeTypeList('interfaces', e.interfaces);
|
||||
|
||||
_writeElements('fields', e.fields, _writePropertyInducingElement);
|
||||
|
||||
var constructors = e.constructors;
|
||||
if (e is MixinElement) {
|
||||
expect(constructors, isEmpty);
|
||||
} else if (configuration.withConstructors) {
|
||||
expect(constructors, isNotEmpty);
|
||||
_writeElements('constructors', constructors, _writeConstructorElement);
|
||||
}
|
||||
|
||||
_writeElements('accessors', e.accessors, _writePropertyAccessorElement);
|
||||
_writeElements('methods', e.methods, _writeMethodElement);
|
||||
});
|
||||
|
||||
_assertNonSyntheticElementSelf(e);
|
||||
}
|
||||
|
||||
void _writeCodeRange(Element e) {
|
||||
if (configuration.withCodeRanges && !e.isSynthetic) {
|
||||
e as ElementImpl;
|
||||
|
@ -532,6 +489,92 @@ class _ElementWriter {
|
|||
}
|
||||
}
|
||||
|
||||
void _writeInterfaceOrAugmentationElement(
|
||||
InterfaceOrAugmentationElementMixin e,
|
||||
) {
|
||||
_sink.writeIndentedLine(() {
|
||||
if (e is InstanceAugmentationElementImpl) {
|
||||
_sink.write('augment ');
|
||||
}
|
||||
|
||||
if (e is ClassElementImpl) {
|
||||
_sink.writeIf(e.isAbstract, 'abstract ');
|
||||
_sink.writeIf(e.isMacro, 'macro ');
|
||||
_sink.writeIf(e.isSealed, 'sealed ');
|
||||
_sink.writeIf(e.isBase, 'base ');
|
||||
_sink.writeIf(e.isInterface, 'interface ');
|
||||
_sink.writeIf(e.isFinal, 'final ');
|
||||
_sink.writeIf(e.isInline, 'inline ');
|
||||
_sink.writeIf(e.isMixinClass, 'mixin ');
|
||||
}
|
||||
_sink.writeIf(!e.isSimplyBounded, 'notSimplyBounded ');
|
||||
|
||||
if (e is EnumElementImpl) {
|
||||
_sink.write('enum ');
|
||||
} else if (e is MixinElementImpl) {
|
||||
_sink.writeIf(e.isBase, 'base ');
|
||||
_sink.write('mixin ');
|
||||
} else {
|
||||
_sink.write('class ');
|
||||
}
|
||||
if (e is ClassElementImpl) {
|
||||
_sink.writeIf(e.isMixinApplication, 'alias ');
|
||||
}
|
||||
|
||||
_writeName(e);
|
||||
});
|
||||
|
||||
_sink.withIndent(() {
|
||||
_writeDocumentation(e);
|
||||
_writeMetadata(e);
|
||||
_writeSinceSdkVersion(e);
|
||||
_writeCodeRange(e);
|
||||
_writeTypeParameterElements(e.typeParameters);
|
||||
_writeAugmentationTarget(e);
|
||||
_writeAugmentedDeclaration(e);
|
||||
_writeAugmentation(e);
|
||||
|
||||
if (e is InterfaceElementImpl) {
|
||||
final supertype = e.supertype;
|
||||
if (supertype != null &&
|
||||
(supertype.element.name != 'Object' || e.mixins.isNotEmpty)) {
|
||||
_writeType('supertype', supertype);
|
||||
}
|
||||
}
|
||||
|
||||
if (e is MixinElementImpl) {
|
||||
var superclassConstraints = e.superclassConstraints;
|
||||
if (superclassConstraints.isEmpty) {
|
||||
throw StateError('At least Object is expected.');
|
||||
}
|
||||
_elementPrinter.writeTypeList(
|
||||
'superclassConstraints',
|
||||
superclassConstraints,
|
||||
);
|
||||
}
|
||||
|
||||
_elementPrinter.writeTypeList('mixins', e.mixins);
|
||||
_elementPrinter.writeTypeList('interfaces', e.interfaces);
|
||||
|
||||
_writeElements('fields', e.fields, _writePropertyInducingElement);
|
||||
|
||||
var constructors = e.constructors;
|
||||
if (e is MixinOrAugmentationElement) {
|
||||
expect(constructors, isEmpty);
|
||||
} else if (configuration.withConstructors) {
|
||||
if (e is NamedInstanceElement) {
|
||||
expect(constructors, isNotEmpty);
|
||||
}
|
||||
_writeElements('constructors', constructors, _writeConstructorElement);
|
||||
}
|
||||
|
||||
_writeElements('accessors', e.accessors, _writePropertyAccessorElement);
|
||||
_writeElements('methods', e.methods, _writeMethodElement);
|
||||
});
|
||||
|
||||
_assertNonSyntheticElementSelf(e);
|
||||
}
|
||||
|
||||
void _writeLibraryAugmentations(LibraryElementImpl e) {
|
||||
if (configuration.withLibraryAugmentations) {
|
||||
final augmentations = e.augmentations;
|
||||
|
@ -723,7 +766,7 @@ class _ElementWriter {
|
|||
|
||||
_sink.withIndent(() {
|
||||
_writeMetadata(e);
|
||||
if (uri is DirectiveUriWithUnit) {
|
||||
if (uri is DirectiveUriWithUnitImpl) {
|
||||
_writeUnitElement(uri.unit);
|
||||
}
|
||||
});
|
||||
|
@ -999,11 +1042,16 @@ class _ElementWriter {
|
|||
_writeElements('typeParameters', elements, _writeTypeParameterElement);
|
||||
}
|
||||
|
||||
void _writeUnitElement(CompilationUnitElement e) {
|
||||
_writeElements('classes', e.classes, _writeClassElement);
|
||||
_writeElements('enums', e.enums, _writeClassElement);
|
||||
void _writeUnitElement(CompilationUnitElementImpl e) {
|
||||
_writeElements('classes', e.classes, _writeInterfaceOrAugmentationElement);
|
||||
_writeElements(
|
||||
'classAugmentations',
|
||||
e.classAugmentations,
|
||||
_writeInterfaceOrAugmentationElement,
|
||||
);
|
||||
_writeElements('enums', e.enums, _writeInterfaceOrAugmentationElement);
|
||||
_writeElements('extensions', e.extensions, _writeExtensionElement);
|
||||
_writeElements('mixins', e.mixins, _writeClassElement);
|
||||
_writeElements('mixins', e.mixins, _writeInterfaceOrAugmentationElement);
|
||||
_writeElements('typeAliases', e.typeAliases, _writeTypeAliasElement);
|
||||
_writeElements(
|
||||
'topLevelVariables',
|
||||
|
@ -1038,10 +1086,3 @@ class _IdMap {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension on ClassElement {
|
||||
bool get isMacro {
|
||||
final self = this;
|
||||
return self is ClassElementImpl && self.isMacro;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,14 +24,61 @@ main() {
|
|||
});
|
||||
}
|
||||
|
||||
mixin ClassAugmentationElementsMixin on ElementsBaseTest {
|
||||
test_augmentationTarget() async {
|
||||
newFile('$testPackageLibPath/a.dart', r'''
|
||||
library augment 'test.dart';
|
||||
import augment 'b.dart';
|
||||
augment class A {}
|
||||
''');
|
||||
|
||||
newFile('$testPackageLibPath/b.dart', r'''
|
||||
library augment 'a.dart';
|
||||
augment class A {}
|
||||
''');
|
||||
|
||||
var library = await buildLibrary(r'''
|
||||
import augment 'a.dart';
|
||||
class A {}
|
||||
''');
|
||||
|
||||
checkElementText(library, r'''
|
||||
library
|
||||
augmentationImports
|
||||
package:test/a.dart
|
||||
augmentationImports
|
||||
package:test/b.dart
|
||||
definingUnit
|
||||
classAugmentations
|
||||
augment class A @40
|
||||
augmentationTarget: self::@augmentation::package:test/a.dart::@classAugmentation::A
|
||||
augmentedDeclaration: self::@class::A
|
||||
definingUnit
|
||||
classAugmentations
|
||||
augment class A @68
|
||||
augmentationTarget: self::@class::A
|
||||
augmentedDeclaration: self::@class::A
|
||||
augmentation: self::@augmentation::package:test/b.dart::@classAugmentation::A
|
||||
definingUnit
|
||||
classes
|
||||
class A @31
|
||||
augmentation: self::@augmentation::package:test/a.dart::@classAugmentation::A
|
||||
constructors
|
||||
synthetic @-1
|
||||
''');
|
||||
}
|
||||
}
|
||||
|
||||
@reflectiveTest
|
||||
class ElementsFromBytesTest extends ElementsTest {
|
||||
class ElementsFromBytesTest extends ElementsTest
|
||||
with ClassAugmentationElementsMixin {
|
||||
@override
|
||||
bool get keepLinkingLibraries => false;
|
||||
}
|
||||
|
||||
@reflectiveTest
|
||||
class ElementsKeepLinkingTest extends ElementsTest {
|
||||
class ElementsKeepLinkingTest extends ElementsTest
|
||||
with ClassAugmentationElementsMixin {
|
||||
@override
|
||||
bool get keepLinkingLibraries => true;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue