Fine. Track constructor/method/top-level function APIs.
Fine-grained dependency tracking missed several element APIs and edge
cases. This change annotates and records usage of key properties on
`ConstructorElementImpl`, `MethodElementImpl`, and
`TopLevelFunctionElementImpl`, and extends the manifest/serialization to
capture relationships and inference state that affect API shape.
What’s included
- Add `@elementClass` and granular tracking on members:
- Mark identifiers and flags with `@trackedIncludedInId`.
- Mark getters like `firstFragment`, `fragments`, `lastFragment`,
`accept()`, `visitChildren()` as `@trackedDirectlyOpaque` and record
opaque API use.
- Mark derived properties as `@trackedIndirectly` and internal caches
as `@trackedInternal`.
- Expose `_fragments` lists so tracked access doesn’t bypass recording.
- Constructors:
- Track `isConst`, `isFactory`, `constantInitializers`.
- Persist and match `redirectedConstructor` and `superConstructor`
via new optional `ManifestElement` fields.
- Compute `isGenerative` as `!isFactory` to avoid fragment drift.
- Methods:
- Persist `isOperatorEqualWithParameterTypeFromObject`.
- Serialize `typeInferenceError` and surface it in manifests.
- Add binary I/O for `TopLevelInferenceError` (read/write/optional,
equality) and print it in result output.
- Extend `ManifestElement` with `encodeOptional()/readOptional()` and a
helper extension for matching/writing optionals.
- Update the result printer to show:
- Method flags and optional `typeInferenceError`.
- Constructor `redirectedConstructor` and `superConstructor`.
- Bump `AnalysisDriver.DATA_VERSION` to 547 to invalidate old caches.
- Minor fixes:
- Use `baseElement.firstFragmentLocation.libraryFragment!.source` when
wiring the diagnostic reporter in constant evaluation to align with
fragment locations.
Why
Clients of the fine-grained dependency system rely on accurate
identification and usage tracking of element APIs. Missing tracking for
fragments/visitors and absent manifest fields (constructor redirection/
super calls, method inference errors) could let incompatible API changes
slip past invalidation and requirement checks. Persisting these details
ensures correct cache keys, precise requirement verification, and more
actionable diagnostics.
Compatibility
- Data/summary format changes require a cache rebuild (version 547).
- No user-visible API changes.
Change-Id: Ifdc1a97e87dc6e2decabcf0d9a9c634825da6e85
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/448900
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index 49f6555..fa8513c 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -106,7 +106,7 @@
// TODO(scheglov): Clean up the list of implicitly analyzed files.
class AnalysisDriver {
/// The version of data format, should be incremented on every format change.
- static const int DATA_VERSION = 546;
+ static const int DATA_VERSION = 547;
/// The number of exception contexts allowed to write. Once this field is
/// zero, we stop writing any new exception contexts in this process.
diff --git a/pkg/analyzer/lib/src/dart/constant/evaluation.dart b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
index d04013d..ad8ef5f 100644
--- a/pkg/analyzer/lib/src/dart/constant/evaluation.dart
+++ b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
@@ -2811,7 +2811,7 @@
late final DiagnosticReporter _externalDiagnosticReporter =
DiagnosticReporter(
_externalDiagnosticListener,
- _constructor.firstFragment.libraryFragment.source,
+ _constructor.baseElement.firstFragmentLocation.libraryFragment!.source,
);
late final ConstantVisitor _initializerVisitor = ConstantVisitor(
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index cbc0fd8..ffd6610 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -605,13 +605,16 @@
ConstantInitializerImpl({required this.fragment, required this.expression});
}
+@elementClass
class ConstructorElementImpl extends ExecutableElementImpl
with InternalConstructorElement
implements ConstantEvaluationTarget {
@override
+ @trackedIncludedInId
final Reference reference;
@override
+ @trackedIncludedInId
final String? name;
@override
@@ -648,16 +651,19 @@
}
@override
+ @trackedIncludedInId
ConstructorElementImpl get baseElement => this;
/// The constant initializers for this element, from all fragments.
+ @trackedIncludedInId
List<ConstructorInitializer> get constantInitializers {
- return fragments
+ return _fragments
.expand((fragment) => fragment.constantInitializers)
.toList(growable: false);
}
@override
+ @trackedIndirectly
String get displayName {
var className = enclosingElement.name ?? '<null>';
var name = this.name ?? '<null>';
@@ -669,56 +675,67 @@
}
@override
+ @trackedIndirectly
InterfaceElementImpl get enclosingElement =>
_firstFragment.enclosingFragment.element;
@Deprecated('Use enclosingElement instead')
@override
+ @trackedIndirectly
InterfaceElementImpl get enclosingElement2 => enclosingElement;
@override
- ConstructorFragmentImpl get firstFragment => _firstFragment;
-
- @override
- List<ConstructorFragmentImpl> get fragments {
- return [
- for (
- ConstructorFragmentImpl? fragment = _firstFragment;
- fragment != null;
- fragment = fragment.nextFragment
- )
- fragment,
- ];
+ @trackedDirectlyOpaque
+ ConstructorFragmentImpl get firstFragment {
+ globalResultRequirements?.recordOpaqueApiUse(this, 'firstFragment');
+ return _firstFragment;
}
@override
+ @trackedDirectlyOpaque
+ List<ConstructorFragmentImpl> get fragments {
+ globalResultRequirements?.recordOpaqueApiUse(this, 'fragments');
+ return _fragments;
+ }
+
+ @override
+ @trackedIncludedInId
bool get isConst => _firstFragment.isConst;
@override
+ @trackedIndirectly
bool get isDefaultConstructor => _firstFragment.isDefaultConstructor;
@override
+ @trackedIncludedInId
bool get isFactory => _firstFragment.isFactory;
@override
- bool get isGenerative => _firstFragment.isGenerative;
+ @trackedIndirectly
+ bool get isGenerative => !isFactory;
@override
+ @trackedIncludedInId
ElementKind get kind => ElementKind.CONSTRUCTOR;
@override
+ @trackedDirectlyOpaque
ConstructorFragmentImpl get lastFragment {
+ globalResultRequirements?.recordOpaqueApiUse(this, 'lastFragment');
return super.lastFragment as ConstructorFragmentImpl;
}
@override
+ @trackedInternal
LibraryFragmentImpl get libraryFragment => _firstFragment.libraryFragment;
@Deprecated('Use name instead')
@override
+ @trackedIndirectly
String? get name3 => name;
@override
+ @trackedIncludedInId
Element get nonSynthetic {
if (isSynthetic) {
return enclosingElement;
@@ -728,6 +745,7 @@
}
@override
+ @trackedIncludedInId
InternalConstructorElement? get redirectedConstructor {
_ensureReadResolution();
return _redirectedConstructor;
@@ -739,11 +757,13 @@
@Deprecated('Use redirectedConstructor instead')
@override
+ @trackedIndirectly
InternalConstructorElement? get redirectedConstructor2 {
return redirectedConstructor;
}
@override
+ @trackedIncludedInId
InterfaceTypeImpl get returnType {
var result = _returnType;
if (result != null) {
@@ -754,6 +774,7 @@
}
@override
+ @trackedIncludedInId
InternalConstructorElement? get superConstructor {
_ensureReadResolution();
return _superConstructor;
@@ -765,26 +786,44 @@
@Deprecated('Use superConstructor instead')
@override
+ @trackedIndirectly
InternalConstructorElement? get superConstructor2 {
return superConstructor;
}
@override
+ List<ConstructorFragmentImpl> get _fragments {
+ return [
+ for (
+ ConstructorFragmentImpl? fragment = _firstFragment;
+ fragment != null;
+ fragment = fragment.nextFragment
+ )
+ fragment,
+ ];
+ }
+
+ @override
+ @trackedDirectlyOpaque
T? accept<T>(ElementVisitor2<T> visitor) {
+ globalResultRequirements?.recordOpaqueApiUse(this, 'accept');
return visitor.visitConstructorElement(this);
}
@Deprecated('Use accept instead')
@override
+ @trackedIndirectly
T? accept2<T>(ElementVisitor2<T> visitor) => accept(visitor);
@override
+ @trackedIndirectly
void appendTo(ElementDisplayStringBuilder builder) {
builder.writeConstructorElement(this);
}
/// Ensures that dependencies of this constructor, such as default values
/// of formal parameters, are evaluated.
+ @trackedInternal
void computeConstantDependencies() {
if (!isConstantEvaluated) {
computeConstants(
@@ -796,6 +835,7 @@
}
}
+ @trackedInternal
void linkFragments(List<ConstructorFragmentImpl> fragments) {
assert(identical(fragments[0], _firstFragment));
fragments.reduce((previous, current) {
@@ -805,7 +845,9 @@
}
@override
+ @trackedDirectlyOpaque
void visitChildren<T>(ElementVisitor2<T> visitor) {
+ globalResultRequirements?.recordOpaqueApiUse(this, 'visitChildren');
for (var child in children) {
child.accept(visitor);
}
@@ -2137,7 +2179,7 @@
@override
@trackedIncludedInId
bool get hasImplicitReturnType {
- for (var fragment in fragments) {
+ for (var fragment in _fragments) {
if (!fragment.hasImplicitReturnType) {
return false;
}
@@ -2153,7 +2195,7 @@
@override
@trackedIncludedInId
bool get isAbstract {
- for (var fragment in fragments) {
+ for (var fragment in _fragments) {
if (!fragment.isAbstract) {
return false;
}
@@ -2215,7 +2257,7 @@
@trackedIncludedInId
MetadataImpl get metadata {
var annotations = <ElementAnnotationImpl>[];
- for (var fragment in fragments) {
+ for (var fragment in _fragments) {
annotations.addAll(fragment.metadata.annotations);
}
return MetadataImpl(annotations);
@@ -2284,6 +2326,8 @@
@override
ExecutableFragmentImpl get _firstFragment;
+ List<ExecutableFragmentImpl> get _fragments;
+
@override
@trackedIndirectly
void appendTo(ElementDisplayStringBuilder builder) {
@@ -3948,15 +3992,10 @@
GetterFragmentImpl get firstFragment => _firstFragment;
@override
+ @trackedDirectlyOpaque
List<GetterFragmentImpl> get fragments {
- return [
- for (
- GetterFragmentImpl? fragment = _firstFragment;
- fragment != null;
- fragment = fragment.nextFragment
- )
- fragment,
- ];
+ globalResultRequirements?.recordOpaqueApiUse(this, 'fragments');
+ return _fragments;
}
@override
@@ -3985,6 +4024,18 @@
}
@override
+ List<GetterFragmentImpl> get _fragments {
+ return [
+ for (
+ GetterFragmentImpl? fragment = _firstFragment;
+ fragment != null;
+ fragment = fragment.nextFragment
+ )
+ fragment,
+ ];
+ }
+
+ @override
T? accept<T>(ElementVisitor2<T> visitor) {
return visitor.visitGetterElement(this);
}
@@ -7039,15 +7090,10 @@
LocalFunctionFragmentImpl get firstFragment => _firstFragment;
@override
+ @trackedDirectlyOpaque
List<LocalFunctionFragmentImpl> get fragments {
- return [
- for (
- LocalFunctionFragmentImpl? fragment = _firstFragment;
- fragment != null;
- fragment = fragment.nextFragment
- )
- fragment,
- ];
+ globalResultRequirements?.recordOpaqueApiUse(this, 'fragments');
+ return _fragments;
}
@override
@@ -7061,6 +7107,18 @@
String? get name3 => name;
@override
+ List<LocalFunctionFragmentImpl> get _fragments {
+ return [
+ for (
+ LocalFunctionFragmentImpl? fragment = _firstFragment;
+ fragment != null;
+ fragment = fragment.nextFragment
+ )
+ fragment,
+ ];
+ }
+
+ @override
T? accept<T>(ElementVisitor2<T> visitor) {
return visitor.visitLocalFunctionElement(this);
}
@@ -7648,12 +7706,15 @@
}
}
+@elementClass
class MethodElementImpl extends ExecutableElementImpl
with InternalMethodElement {
@override
+ @trackedIncludedInId
final Reference reference;
@override
+ @trackedIncludedInId
final String? name;
@override
@@ -7662,10 +7723,12 @@
/// Is `true` if this method is `operator==`, and there is no explicit
/// type specified for its formal parameter, in this method or in any
/// overridden methods other than the one declared in `Object`.
+ @trackedIncludedInId
bool isOperatorEqualWithParameterTypeFromObject = false;
/// The error reported during type inference for this variable, or `null` if
/// this variable is not a subject of type inference, or there was no error.
+ @trackedIncludedInId
TopLevelInferenceError? typeInferenceError;
MethodElementImpl({
@@ -7678,27 +7741,71 @@
}
@override
+ @trackedIncludedInId
MethodElementImpl get baseElement => this;
@override
+ @trackedIndirectly
String get displayName {
return lookupName ?? '<unnamed>';
}
@override
+ @trackedIncludedInId
InstanceElementImpl get enclosingElement {
return _firstFragment.enclosingFragment.element;
}
@Deprecated('Use enclosingElement instead')
@override
+ @trackedIndirectly
Element? get enclosingElement2 => enclosingElement;
@override
- MethodFragmentImpl get firstFragment => _firstFragment;
+ @trackedDirectlyOpaque
+ MethodFragmentImpl get firstFragment {
+ globalResultRequirements?.recordOpaqueApiUse(this, 'firstFragment');
+ return _firstFragment;
+ }
@override
+ @trackedDirectlyOpaque
List<MethodFragmentImpl> get fragments {
+ globalResultRequirements?.recordOpaqueApiUse(this, 'fragments');
+ return _fragments;
+ }
+
+ @override
+ @trackedIncludedInId
+ bool get isOperator => _firstFragment.isOperator;
+
+ @override
+ @trackedIncludedInId
+ ElementKind get kind => ElementKind.METHOD;
+
+ @override
+ @trackedDirectlyOpaque
+ MethodFragmentImpl get lastFragment {
+ globalResultRequirements?.recordOpaqueApiUse(this, 'lastFragment');
+ return super.lastFragment as MethodFragmentImpl;
+ }
+
+ @override
+ @trackedIndirectly
+ String? get lookupName {
+ if (name == '-' && formalParameters.isEmpty) {
+ return 'unary-';
+ }
+ return name;
+ }
+
+ @Deprecated('Use name instead')
+ @override
+ @trackedIndirectly
+ String? get name3 => name;
+
+ @override
+ List<MethodFragmentImpl> get _fragments {
return [
for (
MethodFragmentImpl? fragment = _firstFragment;
@@ -7710,42 +7817,24 @@
}
@override
- bool get isOperator => _firstFragment.isOperator;
-
- @override
- ElementKind get kind => ElementKind.METHOD;
-
- @override
- MethodFragmentImpl get lastFragment {
- return super.lastFragment as MethodFragmentImpl;
- }
-
- @override
- String? get lookupName {
- if (name == '-' && formalParameters.isEmpty) {
- return 'unary-';
- }
- return name;
- }
-
- @Deprecated('Use name instead')
- @override
- String? get name3 => name;
-
- @override
+ @trackedDirectlyOpaque
T? accept<T>(ElementVisitor2<T> visitor) {
+ globalResultRequirements?.recordOpaqueApiUse(this, 'accept');
return visitor.visitMethodElement(this);
}
@Deprecated('Use accept instead')
@override
+ @trackedIndirectly
T? accept2<T>(ElementVisitor2<T> visitor) => accept(visitor);
@override
+ @trackedIndirectly
void appendTo(ElementDisplayStringBuilder builder) {
builder.writeMethodElement(this);
}
+ @trackedInternal
void linkFragments(List<MethodFragmentImpl> fragments) {
assert(identical(fragments[0], _firstFragment));
fragments.reduce((previous, current) {
@@ -9130,15 +9219,10 @@
SetterFragmentImpl get firstFragment => _firstFragment;
@override
+ @trackedDirectlyOpaque
List<SetterFragmentImpl> get fragments {
- return [
- for (
- SetterFragmentImpl? fragment = _firstFragment;
- fragment != null;
- fragment = fragment.nextFragment
- )
- fragment,
- ];
+ globalResultRequirements?.recordOpaqueApiUse(this, 'fragments');
+ return _fragments;
}
@override
@@ -9179,6 +9263,18 @@
}
@override
+ List<SetterFragmentImpl> get _fragments {
+ return [
+ for (
+ SetterFragmentImpl? fragment = _firstFragment;
+ fragment != null;
+ fragment = fragment.nextFragment
+ )
+ fragment,
+ ];
+ }
+
+ @override
T? accept<T>(ElementVisitor2<T> visitor) {
return visitor.visitSetterElement(this);
}
@@ -9435,9 +9531,11 @@
);
}
+@elementClass
class TopLevelFunctionElementImpl extends ExecutableElementImpl
implements TopLevelFunctionElement {
@override
+ @trackedIncludedInId
final Reference reference;
@override
@@ -9449,20 +9547,71 @@
}
@override
+ @trackedIncludedInId
TopLevelFunctionElementImpl get baseElement => this;
@override
+ @trackedIncludedInId
LibraryElementImpl get enclosingElement => library;
@Deprecated('Use enclosingElement instead')
@override
+ @trackedIndirectly
LibraryElementImpl get enclosingElement2 => enclosingElement;
@override
- TopLevelFunctionFragmentImpl get firstFragment => _firstFragment;
+ @trackedDirectlyOpaque
+ TopLevelFunctionFragmentImpl get firstFragment {
+ globalResultRequirements?.recordOpaqueApiUse(this, 'firstFragment');
+ return _firstFragment;
+ }
@override
+ @trackedDirectlyOpaque
List<TopLevelFunctionFragmentImpl> get fragments {
+ globalResultRequirements?.recordOpaqueApiUse(this, 'fragments');
+ return _fragments;
+ }
+
+ @override
+ @trackedIncludedInId
+ bool get isDartCoreIdentical {
+ return name == 'identical' && library.isDartCore;
+ }
+
+ @override
+ @trackedIndirectly
+ bool get isEntryPoint {
+ return displayName == TopLevelFunctionElement.MAIN_FUNCTION_NAME;
+ }
+
+ @override
+ @trackedIncludedInId
+ ElementKind get kind => ElementKind.FUNCTION;
+
+ @override
+ @trackedDirectlyOpaque
+ TopLevelFunctionFragmentImpl get lastFragment {
+ globalResultRequirements?.recordOpaqueApiUse(this, 'lastFragment');
+ return super.lastFragment as TopLevelFunctionFragmentImpl;
+ }
+
+ @Deprecated('Use library instead')
+ @override
+ @trackedIncludedInId
+ LibraryElementImpl get library2 => library;
+
+ @override
+ @trackedIncludedInId
+ String? get name => _firstFragment.name;
+
+ @Deprecated('Use name instead')
+ @override
+ @trackedIndirectly
+ String? get name3 => name;
+
+ @override
+ List<TopLevelFunctionFragmentImpl> get _fragments {
return [
for (
TopLevelFunctionFragmentImpl? fragment = _firstFragment;
@@ -9474,48 +9623,24 @@
}
@override
- bool get isDartCoreIdentical {
- return name == 'identical' && library.isDartCore;
- }
-
- @override
- bool get isEntryPoint {
- return displayName == TopLevelFunctionElement.MAIN_FUNCTION_NAME;
- }
-
- @override
- ElementKind get kind => ElementKind.FUNCTION;
-
- @override
- TopLevelFunctionFragmentImpl get lastFragment {
- return super.lastFragment as TopLevelFunctionFragmentImpl;
- }
-
- @Deprecated('Use library instead')
- @override
- LibraryElementImpl get library2 => library;
-
- @override
- String? get name => _firstFragment.name;
-
- @Deprecated('Use name instead')
- @override
- String? get name3 => name;
-
- @override
+ @trackedDirectlyOpaque
T? accept<T>(ElementVisitor2<T> visitor) {
+ globalResultRequirements?.recordOpaqueApiUse(this, 'accept');
return visitor.visitTopLevelFunctionElement(this);
}
@Deprecated('Use accept instead')
@override
+ @trackedIndirectly
T? accept2<T>(ElementVisitor2<T> visitor) => accept(visitor);
@override
+ @trackedIndirectly
void appendTo(ElementDisplayStringBuilder builder) {
builder.writeTopLevelFunctionElement(this);
}
+ @trackedInternal
void linkFragments(List<TopLevelFunctionFragmentImpl> fragments) {
assert(identical(fragments[0], _firstFragment));
fragments.reduce((previous, current) {
diff --git a/pkg/analyzer/lib/src/error/inference_error.dart b/pkg/analyzer/lib/src/error/inference_error.dart
index d8a0af1..6fa6a1e 100644
--- a/pkg/analyzer/lib/src/error/inference_error.dart
+++ b/pkg/analyzer/lib/src/error/inference_error.dart
@@ -2,6 +2,10 @@
// 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.
+import 'package:analyzer/src/binary/binary_reader.dart';
+import 'package:analyzer/src/binary/binary_writer.dart';
+import 'package:collection/collection.dart';
+
/// The top-level type inference error.
class TopLevelInferenceError {
/// The kind of the error.
@@ -11,6 +15,29 @@
final List<String> arguments;
TopLevelInferenceError({required this.kind, required this.arguments});
+
+ factory TopLevelInferenceError.read(SummaryDataReader reader) {
+ return TopLevelInferenceError(
+ kind: reader.readEnum(TopLevelInferenceErrorKind.values),
+ arguments: reader.readStringUtf8List(),
+ );
+ }
+
+ @override
+ bool operator ==(Object other) {
+ return other is TopLevelInferenceError &&
+ other.kind == kind &&
+ const ListEquality<String>().equals(other.arguments, arguments);
+ }
+
+ void write(BufferedSink sink) {
+ sink.writeEnum(kind);
+ sink.writeStringUtf8Iterable(arguments);
+ }
+
+ static TopLevelInferenceError? readOptional(SummaryDataReader reader) {
+ return reader.readOptionalObject(() => TopLevelInferenceError.read(reader));
+ }
}
/// Enum used to indicate the kind of the error during top-level inference.
@@ -19,3 +46,9 @@
dependencyCycle,
overrideNoCombinedSuperSignature,
}
+
+extension TopLevelInferenceErrorExtension on TopLevelInferenceError? {
+ void writeOptional(BufferedSink sink) {
+ sink.writeOptionalObject(this, (it) => it.write(sink));
+ }
+}
diff --git a/pkg/analyzer/lib/src/fine/manifest_context.dart b/pkg/analyzer/lib/src/fine/manifest_context.dart
index b488192..6dd37f8 100644
--- a/pkg/analyzer/lib/src/fine/manifest_context.dart
+++ b/pkg/analyzer/lib/src/fine/manifest_context.dart
@@ -199,9 +199,20 @@
);
}
+ static ManifestElement? encodeOptional(
+ EncodeContext context,
+ Element? element,
+ ) {
+ return element != null ? encode(context, element) : null;
+ }
+
static List<ManifestElement> readList(SummaryDataReader reader) {
return reader.readTypedList(() => ManifestElement.read(reader));
}
+
+ static ManifestElement? readOptional(SummaryDataReader reader) {
+ return reader.readOptionalObject(() => ManifestElement.read(reader));
+ }
}
/// Note, "instance" means inside [InstanceElement], not as "not static".
@@ -435,3 +446,18 @@
'[memberName: $memberName]');
}
}
+
+extension ManifestElementExtension on ManifestElement? {
+ bool match(MatchContext context, Element? element) {
+ if (this case var self?) {
+ return element != null && self.match(context, element);
+ }
+ return element == null;
+ }
+
+ void writeOptional(BufferedSink sink) {
+ sink.writeOptionalObject(this, (it) {
+ it.write(sink);
+ });
+ }
+}
diff --git a/pkg/analyzer/lib/src/fine/manifest_item.dart b/pkg/analyzer/lib/src/fine/manifest_item.dart
index 9719a58..a4e7f0d 100644
--- a/pkg/analyzer/lib/src/fine/manifest_item.dart
+++ b/pkg/analyzer/lib/src/fine/manifest_item.dart
@@ -6,6 +6,7 @@
import 'package:analyzer/src/binary/binary_reader.dart';
import 'package:analyzer/src/binary/binary_writer.dart';
import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/error/inference_error.dart';
import 'package:analyzer/src/fine/lookup_name.dart';
import 'package:analyzer/src/fine/manifest_ast.dart';
import 'package:analyzer/src/fine/manifest_context.dart';
@@ -144,6 +145,8 @@
final bool isConst;
final bool isFactory;
final List<ManifestNode> constantInitializers;
+ final ManifestElement? redirectedConstructor;
+ final ManifestElement? superConstructor;
ConstructorItem({
required super.id,
@@ -161,6 +164,8 @@
required this.isConst,
required this.isFactory,
required this.constantInitializers,
+ required this.redirectedConstructor,
+ required this.superConstructor,
});
factory ConstructorItem.fromElement({
@@ -188,6 +193,14 @@
constantInitializers: element.constantInitializers
.map((initializer) => ManifestNode.encode(context, initializer))
.toFixedList(),
+ redirectedConstructor: ManifestElement.encodeOptional(
+ context,
+ element.redirectedConstructor,
+ ),
+ superConstructor: ManifestElement.encodeOptional(
+ context,
+ element.superConstructor,
+ ),
);
});
}
@@ -209,6 +222,8 @@
isConst: reader.readBool(),
isFactory: reader.readBool(),
constantInitializers: ManifestNode.readList(reader),
+ redirectedConstructor: ManifestElement.readOptional(reader),
+ superConstructor: ManifestElement.readOptional(reader),
);
}
@@ -218,7 +233,9 @@
return super.match(context, element) &&
isConst == element.isConst &&
isFactory == element.isFactory &&
- constantInitializers.match(context, element.constantInitializers);
+ constantInitializers.match(context, element.constantInitializers) &&
+ redirectedConstructor.match(context, element.redirectedConstructor) &&
+ superConstructor.match(context, element.superConstructor);
});
}
@@ -228,6 +245,8 @@
sink.writeBool(isConst);
sink.writeBool(isFactory);
constantInitializers.writeList(sink);
+ redirectedConstructor.writeOptional(sink);
+ superConstructor.writeOptional(sink);
}
static Map<LookupName, ConstructorItem> readMap(SummaryDataReader reader) {
@@ -1187,6 +1206,9 @@
}
class MethodItem extends ExecutableItem<MethodElementImpl> {
+ final bool isOperatorEqualWithParameterTypeFromObject;
+ final TopLevelInferenceError? typeInferenceError;
+
MethodItem({
required super.id,
required super.isSynthetic,
@@ -1200,6 +1222,8 @@
required super.isSimplyBounded,
required super.isStatic,
required super.functionType,
+ required this.isOperatorEqualWithParameterTypeFromObject,
+ required this.typeInferenceError,
});
factory MethodItem.fromElement({
@@ -1221,6 +1245,9 @@
isSimplyBounded: element.isSimplyBounded,
isStatic: element.isStatic,
functionType: element.type.encode(context),
+ isOperatorEqualWithParameterTypeFromObject:
+ element.isOperatorEqualWithParameterTypeFromObject,
+ typeInferenceError: element.typeInferenceError,
);
}
@@ -1238,9 +1265,26 @@
isSimplyBounded: reader.readBool(),
isStatic: reader.readBool(),
functionType: ManifestFunctionType.read(reader),
+ isOperatorEqualWithParameterTypeFromObject: reader.readBool(),
+ typeInferenceError: TopLevelInferenceError.readOptional(reader),
);
}
+ @override
+ bool match(MatchContext context, MethodElementImpl element) {
+ return super.match(context, element) &&
+ isOperatorEqualWithParameterTypeFromObject ==
+ element.isOperatorEqualWithParameterTypeFromObject &&
+ typeInferenceError == element.typeInferenceError;
+ }
+
+ @override
+ void write(BufferedSink sink) {
+ super.write(sink);
+ sink.writeBool(isOperatorEqualWithParameterTypeFromObject);
+ typeInferenceError.writeOptional(sink);
+ }
+
static Map<LookupName, MethodItem> readMap(SummaryDataReader reader) {
return reader.readMap(
readKey: () => LookupName.read(reader),
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
index 206b22b..1e21a76 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
@@ -15173,7 +15173,7 @@
declaredClasses
B: #M3
declaredConstructors
- foo: #M4
+ foo: #M7
interface: #M5
requirements
libraries
@@ -44471,142 +44471,6 @@
);
}
- test_manifest_class_constructor_isConst_falseToTrue() async {
- await _runLibraryManifestScenario(
- initialCode: r'''
-class A {
- A.foo();
-}
-''',
- expectedInitialEvents: r'''
-[operation] linkLibraryCycle SDK
-[operation] linkLibraryCycle
- package:test/test.dart
- declaredClasses
- A: #M0
- declaredConstructors
- foo: #M1
- interface: #M2
-''',
- updatedCode: r'''
-class A {
- const A.foo();
-}
-''',
- expectedUpdatedEvents: r'''
-[operation] linkLibraryCycle
- package:test/test.dart
- declaredClasses
- A: #M0
- declaredConstructors
- foo: #M3
- interface: #M2
-''',
- );
- }
-
- test_manifest_class_constructor_isConst_trueToFalse() async {
- await _runLibraryManifestScenario(
- initialCode: r'''
-class A {
- const A.foo();
-}
-''',
- expectedInitialEvents: r'''
-[operation] linkLibraryCycle SDK
-[operation] linkLibraryCycle
- package:test/test.dart
- declaredClasses
- A: #M0
- declaredConstructors
- foo: #M1
- interface: #M2
-''',
- updatedCode: r'''
-class A {
- A.foo() {}
-}
-''',
- expectedUpdatedEvents: r'''
-[operation] linkLibraryCycle
- package:test/test.dart
- declaredClasses
- A: #M0
- declaredConstructors
- foo: #M3
- interface: #M2
-''',
- );
- }
-
- test_manifest_class_constructor_isFactory_falseToTrue() async {
- await _runLibraryManifestScenario(
- initialCode: r'''
-class A {
- A.foo();
-}
-''',
- expectedInitialEvents: r'''
-[operation] linkLibraryCycle SDK
-[operation] linkLibraryCycle
- package:test/test.dart
- declaredClasses
- A: #M0
- declaredConstructors
- foo: #M1
- interface: #M2
-''',
- updatedCode: r'''
-class A {
- factory A.foo();
-}
-''',
- expectedUpdatedEvents: r'''
-[operation] linkLibraryCycle
- package:test/test.dart
- declaredClasses
- A: #M0
- declaredConstructors
- foo: #M3
- interface: #M2
-''',
- );
- }
-
- test_manifest_class_constructor_isFactory_trueToFalse() async {
- await _runLibraryManifestScenario(
- initialCode: r'''
-class A {
- factory A.foo();
-}
-''',
- expectedInitialEvents: r'''
-[operation] linkLibraryCycle SDK
-[operation] linkLibraryCycle
- package:test/test.dart
- declaredClasses
- A: #M0
- declaredConstructors
- foo: #M1
- interface: #M2
-''',
- updatedCode: r'''
-class A {
- A.foo();
-}
-''',
- expectedUpdatedEvents: r'''
-[operation] linkLibraryCycle
- package:test/test.dart
- declaredClasses
- A: #M0
- declaredConstructors
- foo: #M3
- interface: #M2
-''',
- );
- }
-
test_manifest_class_constructor_isSynthetic() async {
configuration.includeDefaultConstructors();
await _runLibraryManifestScenario(
@@ -44717,19 +44581,23 @@
flags: hasEnclosingTypeParameterReference isSimplyBounded
functionType: FunctionType
returnType: A @ package:test/test.dart
- foo2: #M2
+ superConstructor: (dart:core, interfaceConstructor, Object, new) #M2
+ foo2: #M3
flags: hasEnclosingTypeParameterReference isConst isSimplyBounded
functionType: FunctionType
returnType: A @ package:test/test.dart
- foo3: #M3
+ superConstructor: (dart:core, interfaceConstructor, Object, new) #M2
+ foo3: #M4
flags: hasEnclosingTypeParameterReference isSimplyBounded
functionType: FunctionType
returnType: A @ package:test/test.dart
- foo4: #M4
+ superConstructor: (dart:core, interfaceConstructor, Object, new) #M2
+ foo4: #M5
flags: hasEnclosingTypeParameterReference isConst isSimplyBounded
functionType: FunctionType
returnType: A @ package:test/test.dart
- interface: #M5
+ superConstructor: (dart:core, interfaceConstructor, Object, new) #M2
+ interface: #M6
''',
updatedCode: r'''
class A {
@@ -44750,19 +44618,23 @@
flags: hasEnclosingTypeParameterReference isSimplyBounded
functionType: FunctionType
returnType: A @ package:test/test.dart
- foo2: #M2
+ superConstructor: (dart:core, interfaceConstructor, Object, new) #M2
+ foo2: #M3
flags: hasEnclosingTypeParameterReference isConst isSimplyBounded
functionType: FunctionType
returnType: A @ package:test/test.dart
- foo3: #M6
+ superConstructor: (dart:core, interfaceConstructor, Object, new) #M2
+ foo3: #M7
flags: hasEnclosingTypeParameterReference isConst isSimplyBounded
functionType: FunctionType
returnType: A @ package:test/test.dart
- foo4: #M7
+ superConstructor: (dart:core, interfaceConstructor, Object, new) #M2
+ foo4: #M8
flags: hasEnclosingTypeParameterReference isSimplyBounded
functionType: FunctionType
returnType: A @ package:test/test.dart
- interface: #M5
+ superConstructor: (dart:core, interfaceConstructor, Object, new) #M2
+ interface: #M6
''',
);
}
@@ -44790,19 +44662,23 @@
flags: hasEnclosingTypeParameterReference isSimplyBounded
functionType: FunctionType
returnType: A @ package:test/test.dart
- foo2: #M2
+ superConstructor: (dart:core, interfaceConstructor, Object, new) #M2
+ foo2: #M3
flags: hasEnclosingTypeParameterReference isExternal isSimplyBounded
functionType: FunctionType
returnType: A @ package:test/test.dart
- foo3: #M3
+ superConstructor: (dart:core, interfaceConstructor, Object, new) #M2
+ foo3: #M4
flags: hasEnclosingTypeParameterReference isSimplyBounded
functionType: FunctionType
returnType: A @ package:test/test.dart
- foo4: #M4
+ superConstructor: (dart:core, interfaceConstructor, Object, new) #M2
+ foo4: #M5
flags: hasEnclosingTypeParameterReference isExternal isSimplyBounded
functionType: FunctionType
returnType: A @ package:test/test.dart
- interface: #M5
+ superConstructor: (dart:core, interfaceConstructor, Object, new) #M2
+ interface: #M6
''',
updatedCode: r'''
class A {
@@ -44823,19 +44699,23 @@
flags: hasEnclosingTypeParameterReference isSimplyBounded
functionType: FunctionType
returnType: A @ package:test/test.dart
- foo2: #M2
+ superConstructor: (dart:core, interfaceConstructor, Object, new) #M2
+ foo2: #M3
flags: hasEnclosingTypeParameterReference isExternal isSimplyBounded
functionType: FunctionType
returnType: A @ package:test/test.dart
- foo3: #M6
+ superConstructor: (dart:core, interfaceConstructor, Object, new) #M2
+ foo3: #M7
flags: hasEnclosingTypeParameterReference isExternal isSimplyBounded
functionType: FunctionType
returnType: A @ package:test/test.dart
- foo4: #M7
+ superConstructor: (dart:core, interfaceConstructor, Object, new) #M2
+ foo4: #M8
flags: hasEnclosingTypeParameterReference isSimplyBounded
functionType: FunctionType
returnType: A @ package:test/test.dart
- interface: #M5
+ superConstructor: (dart:core, interfaceConstructor, Object, new) #M2
+ interface: #M6
''',
);
}
@@ -44863,19 +44743,21 @@
flags: hasEnclosingTypeParameterReference isSimplyBounded
functionType: FunctionType
returnType: A @ package:test/test.dart
- foo2: #M2
+ superConstructor: (dart:core, interfaceConstructor, Object, new) #M2
+ foo2: #M3
flags: hasEnclosingTypeParameterReference isFactory isSimplyBounded
functionType: FunctionType
returnType: A @ package:test/test.dart
- foo3: #M3
+ foo3: #M4
flags: hasEnclosingTypeParameterReference isSimplyBounded
functionType: FunctionType
returnType: A @ package:test/test.dart
- foo4: #M4
+ superConstructor: (dart:core, interfaceConstructor, Object, new) #M2
+ foo4: #M5
flags: hasEnclosingTypeParameterReference isFactory isSimplyBounded
functionType: FunctionType
returnType: A @ package:test/test.dart
- interface: #M5
+ interface: #M6
''',
updatedCode: r'''
class A {
@@ -44896,19 +44778,21 @@
flags: hasEnclosingTypeParameterReference isSimplyBounded
functionType: FunctionType
returnType: A @ package:test/test.dart
- foo2: #M2
+ superConstructor: (dart:core, interfaceConstructor, Object, new) #M2
+ foo2: #M3
flags: hasEnclosingTypeParameterReference isFactory isSimplyBounded
functionType: FunctionType
returnType: A @ package:test/test.dart
- foo3: #M6
+ foo3: #M7
flags: hasEnclosingTypeParameterReference isFactory isSimplyBounded
functionType: FunctionType
returnType: A @ package:test/test.dart
- foo4: #M7
+ foo4: #M8
flags: hasEnclosingTypeParameterReference isSimplyBounded
functionType: FunctionType
returnType: A @ package:test/test.dart
- interface: #M5
+ superConstructor: (dart:core, interfaceConstructor, Object, new) #M2
+ interface: #M6
''',
);
}
@@ -44985,6 +44869,168 @@
);
}
+ test_manifest_class_constructor_redirectingConstructor() async {
+ await _runLibraryManifestScenario(
+ initialCode: r'''
+class A {
+ A.foo1(int _);
+ A.foo2(int _);
+ A.foo3(int _) : this.foo1(0);
+ A.foo4(int _) : this.foo2(0);
+}
+''',
+ expectedInitialEvents: r'''
+[operation] linkLibraryCycle SDK
+[operation] linkLibraryCycle
+ package:test/test.dart
+ declaredClasses
+ A: #M0
+ declaredConstructors
+ foo1: #M1
+ foo2: #M2
+ foo3: #M3
+ foo4: #M4
+ interface: #M5
+''',
+ updatedCode: r'''
+class A {
+ A.foo1(int _);
+ A.foo2(double _);
+ A.foo3(int _) : this.foo1(0);
+ A.foo4(int _) : this.foo2(0);
+}
+''',
+ expectedUpdatedEvents: r'''
+[operation] linkLibraryCycle
+ package:test/test.dart
+ declaredClasses
+ A: #M0
+ declaredConstructors
+ foo1: #M1
+ foo2: #M6
+ foo3: #M3
+ foo4: #M7
+ interface: #M5
+''',
+ );
+ }
+
+ test_manifest_class_constructor_redirectingConstructor_factory() async {
+ await _runLibraryManifestScenario(
+ initialCode: r'''
+class A {
+ factory A.foo1(int _) = B.bar1;
+ factory A.foo2(int _) = B.bar2;
+}
+
+class B implements A {
+ B.bar1(int _);
+ B.bar2(int _);
+}
+''',
+ expectedInitialEvents: r'''
+[operation] linkLibraryCycle SDK
+[operation] linkLibraryCycle
+ package:test/test.dart
+ declaredClasses
+ A: #M0
+ declaredConstructors
+ foo1: #M1
+ foo2: #M2
+ interface: #M3
+ B: #M4
+ declaredConstructors
+ bar1: #M5
+ bar2: #M6
+ interface: #M7
+''',
+ updatedCode: r'''
+class A {
+ factory A.foo1(int _) = B.bar1;
+ factory A.foo2(int _) = B.bar2;
+}
+
+class B implements A {
+ B.bar1(int _);
+ B.bar2(double _);
+}
+''',
+ expectedUpdatedEvents: r'''
+[operation] linkLibraryCycle
+ package:test/test.dart
+ declaredClasses
+ A: #M0
+ declaredConstructors
+ foo1: #M1
+ foo2: #M8
+ interface: #M3
+ B: #M4
+ declaredConstructors
+ bar1: #M5
+ bar2: #M9
+ interface: #M7
+''',
+ );
+ }
+
+ test_manifest_class_constructor_superConstructor() async {
+ await _runLibraryManifestScenario(
+ initialCode: r'''
+class A {
+ A.foo1(int _);
+ A.foo2(int _);
+}
+
+class B extends A {
+ B.bar1(int _) : super.foo1();
+ B.bar2(int _) : super.foo2();
+}
+''',
+ expectedInitialEvents: r'''
+[operation] linkLibraryCycle SDK
+[operation] linkLibraryCycle
+ package:test/test.dart
+ declaredClasses
+ A: #M0
+ declaredConstructors
+ foo1: #M1
+ foo2: #M2
+ interface: #M3
+ B: #M4
+ declaredConstructors
+ bar1: #M5
+ bar2: #M6
+ interface: #M7
+''',
+ updatedCode: r'''
+class A {
+ A.foo1(int _);
+ A.foo2(double _);
+}
+
+class B extends A {
+ B.bar1(int _) : super.foo1();
+ B.bar2(int _) : super.foo2();
+}
+''',
+ expectedUpdatedEvents: r'''
+[operation] linkLibraryCycle
+ package:test/test.dart
+ declaredClasses
+ A: #M0
+ declaredConstructors
+ foo1: #M1
+ foo2: #M8
+ interface: #M3
+ B: #M4
+ declaredConstructors
+ bar1: #M5
+ bar2: #M9
+ interface: #M7
+''',
+ );
+ }
+
test_manifest_class_extendsAdd_direct() async {
await _runLibraryManifestScenario(
initialCode: r'''
@@ -51352,6 +51398,122 @@
);
}
+ test_manifest_class_method_modifier_isOperatorEqualWithParameterTypeFromObject() async {
+ configuration
+ ..withElementManifests = true
+ ..ignoredManifestInstanceMemberNames.remove('==');
+
+ await _runLibraryManifestScenario(
+ initialCode: r'''
+abstract class A {
+ bool operator ==(other);
+}
+abstract class B {
+ bool operator ==(Object? other);
+}
+''',
+ expectedInitialEvents: r'''
+[operation] linkLibraryCycle SDK
+[operation] linkLibraryCycle
+ package:test/test.dart
+ declaredClasses
+ A: #M0
+ flags: isAbstract
+ supertype: Object @ dart:core
+ declaredMethods
+ ==: #M1
+ flags: isAbstract isOperatorEqualWithParameterTypeFromObject isSimplyBounded
+ functionType: FunctionType
+ positional
+ required Object @ dart:core
+ returnType: bool @ dart:core
+ interface: #M2
+ map
+ ==: #M1
+ implemented
+ ==: #M3
+ superImplemented
+ [0]
+ ==: #M3
+ inherited
+ ==: #M3
+ B: #M4
+ flags: isAbstract
+ supertype: Object @ dart:core
+ declaredMethods
+ ==: #M5
+ flags: isAbstract isSimplyBounded
+ functionType: FunctionType
+ positional
+ required Object? @ dart:core
+ returnType: bool @ dart:core
+ interface: #M6
+ map
+ ==: #M5
+ implemented
+ ==: #M3
+ superImplemented
+ [0]
+ ==: #M3
+ inherited
+ ==: #M3
+''',
+ updatedCode: r'''
+abstract class A {
+ bool operator ==(Object? other);
+}
+abstract class B {
+ bool operator ==(other);
+}
+''',
+ expectedUpdatedEvents: r'''
+[operation] linkLibraryCycle
+ package:test/test.dart
+ declaredClasses
+ A: #M0
+ flags: isAbstract
+ supertype: Object @ dart:core
+ declaredMethods
+ ==: #M7
+ flags: isAbstract isSimplyBounded
+ functionType: FunctionType
+ positional
+ required Object? @ dart:core
+ returnType: bool @ dart:core
+ interface: #M8
+ map
+ ==: #M7
+ implemented
+ ==: #M3
+ superImplemented
+ [0]
+ ==: #M3
+ inherited
+ ==: #M3
+ B: #M4
+ flags: isAbstract
+ supertype: Object @ dart:core
+ declaredMethods
+ ==: #M9
+ flags: isAbstract isOperatorEqualWithParameterTypeFromObject isSimplyBounded
+ functionType: FunctionType
+ positional
+ required Object @ dart:core
+ returnType: bool @ dart:core
+ interface: #M10
+ map
+ ==: #M9
+ implemented
+ ==: #M3
+ superImplemented
+ [0]
+ ==: #M3
+ inherited
+ ==: #M3
+''',
+ );
+ }
+
test_manifest_class_method_modifier_isStatic() async {
configuration.withElementManifests = true;
await _runLibraryManifestScenario(
@@ -51437,6 +51599,134 @@
);
}
+ test_manifest_class_method_modifier_typeInferenceError() async {
+ configuration.withElementManifests = true;
+
+ await _runLibraryManifestScenario(
+ initialCode: r'''
+abstract class A {
+ void foo(double x);
+}
+abstract class B {
+ void foo(int x);
+}
+class C implements A, B {
+ void foo(x) {}
+}
+''',
+ expectedInitialEvents: r'''
+[operation] linkLibraryCycle SDK
+[operation] linkLibraryCycle
+ package:test/test.dart
+ declaredClasses
+ A: #M0
+ flags: isAbstract
+ supertype: Object @ dart:core
+ declaredMethods
+ foo: #M1
+ flags: isAbstract isSimplyBounded
+ functionType: FunctionType
+ positional
+ required double @ dart:core
+ returnType: void
+ interface: #M2
+ map
+ foo: #M1
+ B: #M3
+ flags: isAbstract
+ supertype: Object @ dart:core
+ declaredMethods
+ foo: #M4
+ flags: isAbstract isSimplyBounded
+ functionType: FunctionType
+ positional
+ required int @ dart:core
+ returnType: void
+ interface: #M5
+ map
+ foo: #M4
+ C: #M6
+ supertype: Object @ dart:core
+ interfaces
+ A @ package:test/test.dart
+ B @ package:test/test.dart
+ declaredMethods
+ foo: #M7
+ flags: isSimplyBounded
+ functionType: FunctionType
+ positional
+ required dynamic
+ returnType: void
+ inferenceError: overrideNoCombinedSuperSignature(A.foo (void Function(double)), B.foo (void Function(int)))
+ interface: #M8
+ map
+ foo: #M7
+ implemented
+ foo: #M7
+''',
+ updatedCode: r'''
+abstract class A {
+ void foo(String x);
+}
+abstract class B {
+ void foo(int x);
+}
+class C implements A, B {
+ void foo(x) {}
+}
+''',
+ expectedUpdatedEvents: r'''
+[operation] linkLibraryCycle
+ package:test/test.dart
+ declaredClasses
+ A: #M0
+ flags: isAbstract
+ supertype: Object @ dart:core
+ declaredMethods
+ foo: #M9
+ flags: isAbstract isSimplyBounded
+ functionType: FunctionType
+ positional
+ required String @ dart:core
+ returnType: void
+ interface: #M10
+ map
+ foo: #M9
+ B: #M3
+ flags: isAbstract
+ supertype: Object @ dart:core
+ declaredMethods
+ foo: #M4
+ flags: isAbstract isSimplyBounded
+ functionType: FunctionType
+ positional
+ required int @ dart:core
+ returnType: void
+ interface: #M5
+ map
+ foo: #M4
+ C: #M6
+ supertype: Object @ dart:core
+ interfaces
+ A @ package:test/test.dart
+ B @ package:test/test.dart
+ declaredMethods
+ foo: #M11
+ flags: isSimplyBounded
+ functionType: FunctionType
+ positional
+ required dynamic
+ returnType: void
+ inferenceError: overrideNoCombinedSuperSignature(A.foo (void Function(String)), B.foo (void Function(int)))
+ interface: #M12
+ map
+ foo: #M11
+ implemented
+ foo: #M11
+''',
+ );
+ }
+
test_manifest_class_method_private_instance() async {
await _runLibraryManifestScenario(
initialCode: r'''
diff --git a/pkg/analyzer/test/src/dart/analysis/result_printer.dart b/pkg/analyzer/test/src/dart/analysis/result_printer.dart
index 61b310f..1024a73 100644
--- a/pkg/analyzer/test/src/dart/analysis/result_printer.dart
+++ b/pkg/analyzer/test/src/dart/analysis/result_printer.dart
@@ -13,6 +13,7 @@
import 'package:analyzer/src/dart/analysis/library_graph.dart';
import 'package:analyzer/src/dart/analysis/results.dart';
import 'package:analyzer/src/dart/analysis/status.dart';
+import 'package:analyzer/src/error/inference_error.dart';
import 'package:analyzer/src/fine/library_manifest.dart';
import 'package:analyzer/src/fine/lookup_name.dart';
import 'package:analyzer/src/fine/manifest_ast.dart';
@@ -1306,9 +1307,17 @@
sink.writelnWithIndent('$name: $idStr');
if (configuration.withElementManifests) {
sink.withIndent(() {
- sink.writeFlags({..._executableItemFlags(item)});
+ sink.writeFlags({
+ ..._executableItemFlags(item),
+ 'isOperatorEqualWithParameterTypeFromObject':
+ item.isOperatorEqualWithParameterTypeFromObject,
+ });
_writeMetadata(item);
_writeNamedType('functionType', item.functionType);
+ _writeTopLevelInferenceError(
+ 'inferenceError',
+ item.typeInferenceError,
+ );
});
}
}
@@ -1341,6 +1350,14 @@
});
_writeMetadata(item);
_writeNamedType('functionType', item.functionType);
+ _writelnNamedElement(
+ 'redirectedConstructor',
+ item.redirectedConstructor,
+ );
+ _writelnNamedElement(
+ 'superConstructor',
+ item.superConstructor,
+ );
});
});
}
@@ -1476,6 +1493,13 @@
sink.writeln('(${parts.join(', ')}) $idStr');
}
+ void _writelnNamedElement(String name, ManifestElement? element) {
+ if (element != null) {
+ sink.writeWithIndent('$name: ');
+ _writelnElement(element);
+ }
+ }
+
void _writeMetadata(ManifestItem item) {
if (configuration.withElementManifests) {
sink.writeElements(
@@ -1590,6 +1614,16 @@
}
}
+ void _writeTopLevelInferenceError(
+ String name,
+ TopLevelInferenceError? error,
+ ) {
+ if (error != null) {
+ var arguments = error.arguments.join(', ');
+ sink.writelnWithIndent('$name: ${error.kind.name}($arguments)');
+ }
+ }
+
void _writeTopLevelVariableItem(TopLevelVariableItem item) {
if (configuration.withElementManifests) {
sink.withIndent(() {