DeCo. Add PropertyAccessorElement.isOriginDeclaration, isOriginInterface, isOriginVariable. Same element text writer.

Change-Id: I4a80530e7fe8e971bb5ee3f1138d4e2756b3ff19
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/465742
Reviewed-by: Paul Berry <paulberry@google.com>
Reviewed-by: Samuel Rawlins <srawlins@google.com>
This commit is contained in:
Konstantin Shcheglov
2025-12-02 20:59:00 -08:00
committed by Commit Queue
parent 5a9ea6d9ed
commit 342a0a7422
38 changed files with 276 additions and 81 deletions
@@ -110,7 +110,7 @@ class LibraryElementSuggestionBuilder
(opType.includeAnnotationSuggestions && variable.isConst)) {
var parent = element.enclosingElement;
if (parent is InterfaceElement || parent is ExtensionElement) {
if (element.isSynthetic) {
if (element.isOriginVariable) {
if (variable is FieldElement) {
builder.suggestField(variable, inheritanceDistance: 0.0);
}
@@ -148,7 +148,7 @@ class LibraryElementSuggestionBuilder
(opType.includeAnnotationSuggestions && variable.isConst)) {
var parent = element.enclosingElement;
if (parent is InterfaceElement || parent is ExtensionElement) {
if (!element.isSynthetic) {
if (!element.isOriginVariable) {
builder.suggestSetter(element, inheritanceDistance: 0.0);
}
} else {
@@ -385,7 +385,7 @@ class DartCallHierarchyComputer {
// Don't consider synthetic getter/setter for a field to be executable
// since they don't contain any executable code.
if (element is PropertyAccessorElement && element.isSynthetic) {
if (element is PropertyAccessorElement && element.isOriginVariable) {
return null;
}
@@ -341,7 +341,7 @@ class SummaryWriter {
}
void summarizeGetter(GetterElement element) {
if (element.isSynthetic) return;
if (element.isOriginVariable) return;
var name = element.name;
if (name == null) return;
@@ -448,7 +448,7 @@ class SummaryWriter {
}
void summarizeSetter(SetterElement element) {
if (element.isSynthetic) return;
if (element.isOriginVariable) return;
var name = element.name;
if (name == null) return;
@@ -227,7 +227,7 @@ class DefinitionHandler
// For synthetic getters created for fields, we need to access the associated
// variable to get the codeOffset/codeLength.
if (codeFragment is PropertyAccessorFragment &&
codeFragment.element.isSynthetic) {
codeFragment.element.isOriginVariable) {
codeFragment = codeFragment.element.nonSynthetic.firstFragment;
}
@@ -850,7 +850,7 @@ class DeclarationHelper {
if (excludedGetters.contains(getter.name)) {
continue;
}
if (!getter.isSynthetic) {
if (getter.isOriginDeclaration) {
if (getter.isVisibleIn(libraryElement)) {
_suggestProperty(
accessor: getter,
@@ -877,7 +877,7 @@ class DeclarationHelper {
// Avoid visiting a field twice. All fields induce a getter, but only
// non-final fields induce a setter, so we don't add a suggestion for
// a synthetic setter.
if (setter.isSynthetic || !setter.isVisibleIn(libraryElement)) {
if (setter.isOriginVariable || !setter.isVisibleIn(libraryElement)) {
continue;
}
_suggestProperty(accessor: setter);
@@ -927,7 +927,7 @@ class DeclarationHelper {
// Do not add synthetic setters, as these may prevent adding getters,
// they are both tracked with the same name in the
// [VisibilityTracker].
if (element.isSynthetic) {
if (element.isOriginVariable) {
break;
}
_suggestTopLevelProperty(element, importData);
@@ -1386,7 +1386,7 @@ class DeclarationHelper {
var referencingInterface = _referencingInterfaceFor(element);
for (var accessor in element.getters) {
if ((!accessor.isSynthetic || accessor.isEnumValues) &&
if ((accessor.isOriginDeclaration || accessor.isEnumValues) &&
(!mustBeStatic || accessor.isStatic)) {
_suggestProperty(
accessor: accessor,
@@ -1397,7 +1397,8 @@ class DeclarationHelper {
}
for (var accessor in element.setters) {
if (!accessor.isSynthetic && (!mustBeStatic || accessor.isStatic)) {
if (accessor.isOriginDeclaration &&
(!mustBeStatic || accessor.isStatic)) {
_suggestProperty(
accessor: accessor,
referencingInterface: referencingInterface,
@@ -1519,7 +1520,7 @@ class DeclarationHelper {
}) {
for (var getter in getters) {
if (getter.isStatic &&
!getter.isSynthetic &&
getter.isOriginDeclaration &&
getter.isVisibleIn(request.libraryElement) &&
(!onlyInvocations ||
getter.returnType is FunctionType ||
@@ -1529,7 +1530,7 @@ class DeclarationHelper {
}
for (var setter in setters) {
if (setter.isStatic &&
!setter.isSynthetic &&
setter.isOriginDeclaration &&
setter.isVisibleIn(request.libraryElement)) {
_suggestProperty(accessor: setter);
}
@@ -1607,12 +1608,12 @@ class DeclarationHelper {
}
if (!mustBeType) {
for (var element in library.getters) {
if (!element.isSynthetic) {
if (element.isOriginDeclaration) {
_suggestTopLevelProperty(element, null);
}
}
for (var element in library.setters) {
if (!element.isSynthetic) {
if (element.isOriginDeclaration) {
if (element.correspondingGetter == null) {
_suggestTopLevelProperty(element, null);
}
@@ -1648,10 +1649,10 @@ class DeclarationHelper {
var firstMember = list.first;
if (mustBeAssignable) {
if (firstMember case SetterElementImpl(
:var isSynthetic,
:var isOriginVariable,
:var correspondingGetter,
)) {
if (isSynthetic && correspondingGetter != null) {
if (isOriginVariable && correspondingGetter != null) {
return correspondingGetter;
} else {
return firstMember;
@@ -1660,10 +1661,10 @@ class DeclarationHelper {
for (var i = 1; i < list.length; i++) {
var member = list[i];
if (member case SetterElementImpl(
:var isSynthetic,
:var isOriginVariable,
:var correspondingGetter,
)) {
if (isSynthetic && correspondingGetter != null) {
if (isOriginVariable && correspondingGetter != null) {
return correspondingGetter;
} else {
return member;
@@ -1747,7 +1748,7 @@ class DeclarationHelper {
double matcherScore, {
ImportData? importData,
}) {
if (element.isSynthetic) {
if (element.isOriginVariable) {
if (element is GetterElement) {
var variable = element.variable;
if (variable is TopLevelVariableElement) {
@@ -2232,7 +2233,7 @@ class DeclarationHelper {
keyword = Keyword.VAR;
}
}
if (accessor.isSynthetic) {
if (accessor.isOriginVariable) {
// Avoid visiting a field twice. All fields induce a getter, but only
// non-final fields induce a setter, so we don't add a suggestion for a
// synthetic setter.
@@ -2341,7 +2342,7 @@ class DeclarationHelper {
if (element.isOriginGetterSetter) {
var getter = element.getter;
if (getter != null) {
if (getter.isSynthetic) {
if (getter.isOriginVariable) {
var variable = getter.variable;
if (variable is FieldElement) {
var suggestion = FieldSuggestion(
@@ -2792,7 +2793,7 @@ extension on GetterElement {
bool get isEnumValues =>
name == 'values' &&
isStatic &&
isSynthetic &&
isOriginVariable &&
enclosingElement is EnumElement;
}
@@ -2813,7 +2814,7 @@ extension on Element {
extension on PropertyAccessorElement {
/// Whether this accessor is an accessor for a constant variable.
bool get isConst {
if (isSynthetic) {
if (isOriginVariable) {
return variable.isConst;
}
return false;
@@ -382,7 +382,7 @@ class FeatureComputer {
return 1.0;
} else if (element is TopLevelVariableElement && element.isConst) {
return 1.0;
} else if (element is PropertyAccessorElement && element.isSynthetic) {
} else if (element is PropertyAccessorElement && element.isOriginVariable) {
var variable = element.variable;
if (variable.isStatic && variable.isConst) {
return 1.0;
@@ -64,7 +64,7 @@ class OverrideHelper {
/// Checks if the [element] has the `@nonVirtual` annotation.
bool _hasNonVirtualAnnotation(ExecutableElement element) {
if (element is GetterElement && element.isSynthetic) {
if (element is GetterElement && element.isOriginVariable) {
var variable = element.variable;
if (variable.metadata.hasNonVirtual) {
return true;
@@ -641,7 +641,7 @@ class RelevanceComputer {
double inheritanceDistance,
bool isNotImportedLibrary,
) {
if (accessor.isSynthetic) {
if (accessor.isOriginVariable) {
if (accessor is GetterElement) {
var variable = accessor.variable;
if (variable is FieldElement) {
@@ -698,7 +698,7 @@ class RelevanceComputer {
PropertyAccessorElement accessor,
bool isNotImportedLibrary,
) {
if (accessor.isSynthetic) {
if (accessor.isOriginVariable) {
if (accessor is GetterElement) {
var variable = accessor.variable;
if (variable is TopLevelVariableElement) {
@@ -65,7 +65,7 @@ class AddLate extends ResolvedCorrectionProducer {
} else if (node is SimpleIdentifier) {
var getter = node.writeOrReadElement;
if (getter is GetterElement &&
getter.isSynthetic &&
getter.isOriginVariable &&
getter.enclosingElement is InterfaceElement) {
var variableElement = getter.variable;
if (variableElement.isOriginDeclaration &&
@@ -38,7 +38,7 @@ class MakeFieldNotFinal extends ResolvedCorrectionProducer {
var getter = node.writeOrReadElement;
// The accessor must be a getter, and it must be synthetic.
if (!(getter is GetterElement && getter.isSynthetic)) {
if (!(getter is GetterElement && getter.isOriginVariable)) {
return;
}
@@ -63,7 +63,7 @@ class ConvertGetterToMethodRefactoringImpl extends RefactoringImpl
await Future.forEach(elements, (Element member) async {
if (member is FieldElement) {
var getter = member.getter;
if (getter != null && !getter.isSynthetic) {
if (getter != null && getter.isOriginDeclaration) {
await _updateElementDeclaration(getter);
return _updateElementReferences(getter);
}
@@ -87,7 +87,7 @@ class ConvertGetterToMethodRefactoringImpl extends RefactoringImpl
);
}
if (element.isSynthetic) {
if (!element.isOriginDeclaration) {
return RefactoringStatus.fatal(
'Only explicit getters can be converted to methods.',
);
@@ -276,7 +276,7 @@ List<Element> getMembers(InterfaceElement clazz) {
/// its variable, otherwise returns [element].
Element getSyntheticAccessorVariable(Element element) {
if (element is PropertyAccessorElement) {
if (element.isSynthetic) {
if (element.isOriginVariable) {
return element.variable;
}
}
@@ -124,7 +124,7 @@ class _ElementRecorder {
LibraryImport? import,
) {
if (referencedElement is PropertyAccessorElement) {
if (referencedElement.isSynthetic) {
if (referencedElement.isOriginVariable) {
referencedElement = referencedElement.variable;
}
}
@@ -221,12 +221,12 @@ class _ReferenceFinder extends RecursiveAstVisitor<void> {
if (extensionElement != null) {
recorder.recordDeclaration(node.offset, extensionElement);
for (var getter in extensionElement.getters) {
if (!getter.isStatic && !getter.isSynthetic) {
if (!getter.isStatic && getter.isOriginDeclaration) {
recorder.recordDeclaration(node.offset, getter);
}
}
for (var setter in extensionElement.setters) {
if (!setter.isStatic && !setter.isSynthetic) {
if (!setter.isStatic && setter.isOriginDeclaration) {
recorder.recordDeclaration(node.offset, setter);
}
}
+2
View File
@@ -27,6 +27,8 @@
Use `isOriginDeclaration`, `isOriginGetterSetter`.
* Deprecate `FieldElement.isSynthetic`.
Use `isOriginDeclaration`, `isOriginGetterSetter`, `isOriginDeclaringFormalParameter`, `isOriginEnumValues` instead.
* Deprecate `PropertyAccessorElement.isSynthetic`.
Use `isOriginDeclaration`, `isOriginInterface`, `isOriginVariable` instead.
## 9.0.0
* Remove deprecated field `Diagnostic.data`.
+4
View File
@@ -4061,6 +4061,10 @@ package:analyzer/dart/element/element.dart:
enclosingElement (getter: Element)
firstFragment (getter: PropertyAccessorFragment)
fragments (getter: List<PropertyAccessorFragment>)
isOriginDeclaration (getter: bool)
isOriginInterface (getter: bool)
isOriginVariable (getter: bool)
isSynthetic (getter: bool, deprecated)
variable (getter: PropertyInducingElement)
PropertyAccessorFragment (class extends Object implements ExecutableFragment):
new (constructor: PropertyAccessorFragment Function())
@@ -2931,6 +2931,29 @@ abstract class PropertyAccessorElement implements ExecutableElement {
@override
List<PropertyAccessorFragment> get fragments;
/// Whether the property accessor is from an explicit [MethodDeclaration] or
/// [FunctionDeclaration].
///
/// When this is `true`, [isOriginVariable] and [isOriginInterface] are `false`.
bool get isOriginDeclaration;
/// Whether the property accessor is created while building interface.
///
/// When this is `true`, [isOriginDeclaration] and [isOriginVariable]
/// are `false`.
bool get isOriginInterface;
/// Whether the property accessor is from a [FieldElement] or
/// [TopLevelVariableElement].
///
/// When this is `true`, [isOriginDeclaration] and [isOriginInterface] are
/// `false`.
bool get isOriginVariable;
@Deprecated('Use isOriginX instead')
@override
bool get isSynthetic;
/// The field or top-level variable associated with this getter.
///
/// If this getter was explicitly defined (is not synthetic) then the variable
@@ -108,7 +108,7 @@ testFineAfterLibraryAnalyzerHook;
// 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 = 591;
static const int DATA_VERSION = 592;
/// The number of exception contexts allowed to write. Once this field is
/// zero, we stop writing any new exception contexts in this process.
@@ -1433,7 +1433,7 @@ class _FindLibraryDeclarations {
void _addGetters(List<GetterElement> elements) {
for (var i = 0; i < elements.length; i++) {
var element = elements[i];
if (!element.isSynthetic) {
if (element.isOriginDeclaration) {
_addDeclaration(element, element.displayName);
}
}
@@ -1449,7 +1449,7 @@ class _FindLibraryDeclarations {
void _addSetters(List<SetterElement> elements) {
for (var i = 0; i < elements.length; i++) {
var element = elements[i];
if (!element.isSynthetic) {
if (element.isOriginDeclaration) {
_addDeclaration(element, element.displayName);
}
}
+49 -10
View File
@@ -2865,13 +2865,13 @@ class FieldElementImpl extends PropertyInducingElementImpl
@override
@trackedIncludedInId
bool get isOriginDeclaringFormalParameter {
return firstFragment.isOriginDeclaringFormalParameter;
return _firstFragment.isOriginDeclaringFormalParameter;
}
@override
@trackedIncludedInId
bool get isOriginEnumValues {
return firstFragment.isOriginEnumValues;
return _firstFragment.isOriginEnumValues;
}
@override
@@ -4022,7 +4022,7 @@ class GetterElementImpl extends PropertyAccessorElementImpl
@override
@trackedIndirectly
Element get nonSynthetic {
if (isSynthetic) {
if (isOriginVariable) {
return variable.nonSynthetic;
} else {
return this;
@@ -4032,7 +4032,7 @@ class GetterElementImpl extends PropertyAccessorElementImpl
@override
@trackedIndirectly
Version? get sinceSdkVersion {
if (isSynthetic) {
if (isOriginVariable) {
return variable.sinceSdkVersion;
}
return super.sinceSdkVersion;
@@ -8151,9 +8151,15 @@ enum Modifier {
/// constructors.
ORIGIN_IMPLICIT_DEFAULT,
/// Whether the property accessor is created while building interface.
ORIGIN_INTERFACE,
/// Whether the constructor was created for a mixin application.
ORIGIN_MIXIN_APPLICATION,
/// Whether the property accessor is from a field or top-level variable.
ORIGIN_VARIABLE,
/// Whether the constructor is primary.
PRIMARY,
@@ -8735,6 +8741,28 @@ abstract class PropertyAccessorElementImpl extends ExecutableElementImpl
@override
List<PropertyAccessorFragmentImpl> get fragments;
@override
@trackedIncludedInId
bool get isOriginDeclaration {
return _firstFragment.isOriginDeclaration;
}
@override
@trackedIncludedInId
bool get isOriginInterface {
return _firstFragment.isOriginInterface;
}
@override
@trackedIncludedInId
bool get isOriginVariable {
return _firstFragment.isOriginVariable;
}
@Deprecated('Use isOriginX instead')
@override
bool get isSynthetic;
@override
@trackedDirectlyOpaque
PropertyAccessorFragmentImpl get lastFragment {
@@ -8767,9 +8795,14 @@ abstract class PropertyAccessorElementImpl extends ExecutableElementImpl
set variable(PropertyInducingElementImpl? value) {
_variable3 = value;
}
@override
PropertyAccessorFragmentImpl get _firstFragment;
}
@GenerateFragmentImpl(modifiers: _PropertyAccessorFragmentImplModifiers.values)
sealed class PropertyAccessorFragmentImpl extends ExecutableFragmentImpl
with _PropertyAccessorFragmentImplMixin
implements PropertyAccessorFragment {
@override
final String? name;
@@ -8867,13 +8900,13 @@ abstract class PropertyInducingElementImpl extends VariableElementImpl
@override
@trackedIncludedInId
bool get isOriginDeclaration {
return firstFragment.isOriginDeclaration;
return _firstFragment.isOriginDeclaration;
}
@override
@trackedIncludedInId
bool get isOriginGetterSetter {
return firstFragment.isOriginGetterSetter;
return _firstFragment.isOriginGetterSetter;
}
@override
@@ -8930,13 +8963,13 @@ abstract class PropertyInducingElementImpl extends VariableElementImpl
_type = value;
if (getter case var getter?) {
if (getter.isSynthetic) {
if (getter.isOriginVariable) {
getter.returnType = type;
}
}
if (setter case var setter?) {
if (setter.isSynthetic) {
if (setter.isOriginVariable) {
setter.returnType = VoidTypeImpl.instance;
setter.valueFormalParameter.type = type;
}
@@ -9090,7 +9123,7 @@ class SetterElementImpl extends PropertyAccessorElementImpl
@override
@trackedIndirectly
Element get nonSynthetic {
if (isSynthetic) {
if (isOriginVariable) {
return variable.nonSynthetic;
} else {
return this;
@@ -9100,7 +9133,7 @@ class SetterElementImpl extends PropertyAccessorElementImpl
@override
@trackedIndirectly
Version? get sinceSdkVersion {
if (isSynthetic) {
if (isOriginVariable) {
return variable.sinceSdkVersion;
}
return super.sinceSdkVersion;
@@ -10533,6 +10566,12 @@ enum _MixinFragmentImplModifiers { isBase }
enum _NonParameterVariableFragmentImplModifiers { hasInitializer }
enum _PropertyAccessorFragmentImplModifiers {
isOriginDeclaration,
isOriginInterface,
isOriginVariable,
}
enum _PropertyInducingFragmentImplModifiers {
isOriginDeclaration,
isOriginGetterSetter,
@@ -341,6 +341,36 @@ mixin _NonParameterVariableFragmentImplMixin {
void setModifier(Modifier modifier, bool value);
}
mixin _PropertyAccessorFragmentImplMixin {
bool get isOriginDeclaration {
return hasModifier(Modifier.ORIGIN_DECLARATION);
}
set isOriginDeclaration(bool value) {
setModifier(Modifier.ORIGIN_DECLARATION, value);
}
bool get isOriginInterface {
return hasModifier(Modifier.ORIGIN_INTERFACE);
}
set isOriginInterface(bool value) {
setModifier(Modifier.ORIGIN_INTERFACE, value);
}
bool get isOriginVariable {
return hasModifier(Modifier.ORIGIN_VARIABLE);
}
set isOriginVariable(bool value) {
setModifier(Modifier.ORIGIN_VARIABLE, value);
}
bool hasModifier(Modifier modifier);
void setModifier(Modifier modifier, bool value);
}
mixin _PropertyInducingFragmentImplMixin {
bool get isOriginDeclaration {
return hasModifier(Modifier.ORIGIN_DECLARATION);
@@ -1030,6 +1030,7 @@ class InheritanceManager3 {
var resultFragment = SetterFragmentImpl(name: executable.name);
resultFragment.enclosingFragment = class_.firstFragment;
resultFragment.isSynthetic = true;
resultFragment.isOriginInterface = true;
resultFragment.formalParameters = transformedParameters
.map((e) => e.firstFragment)
.toList();
@@ -1150,6 +1151,7 @@ class InheritanceManager3 {
var fragment = SetterFragmentImpl(name: fragmentName);
resultFragment = fragment;
resultFragment.isOriginInterface = true;
var element = SetterElementImpl(elementReference, fragment);
element.returnType = resultType.returnType;
@@ -921,6 +921,15 @@ abstract class SubstitutedPropertyAccessorElementImpl
@override
PropertyAccessorFragmentImpl get firstFragment;
@override
bool get isOriginDeclaration => baseElement.isOriginDeclaration;
@override
bool get isOriginInterface => baseElement.isOriginInterface;
@override
bool get isOriginVariable => baseElement.isOriginVariable;
@override
Version? get sinceSdkVersion => baseElement.sinceSdkVersion;
@@ -390,7 +390,7 @@ class AnnotationResolver {
) {
// The accessor should be synthetic, the variable should be constant, and
// there should be no arguments.
if (!accessorElement.isSynthetic ||
if (accessorElement.isOriginDeclaration ||
!accessorElement.variable.isConst ||
annotation.arguments != null) {
_diagnosticReporter.atNode(annotation, diag.invalidAnnotation);
@@ -1653,7 +1653,7 @@ class BestPracticesVerifier extends RecursiveAstVisitor<void> {
_getSubExpressionsMarkedDoNotStore(body.expression, addTo: expressions);
}
}
if (element is PropertyAccessorElement && element.isSynthetic) {
if (element is PropertyAccessorElement && element.isOriginVariable) {
element = element.variable;
}
@@ -1674,7 +1674,7 @@ class BestPracticesVerifier extends RecursiveAstVisitor<void> {
}
static bool _hasNonVirtualAnnotation(ExecutableElement element) {
if (element is PropertyAccessorElement && element.isSynthetic) {
if (element is PropertyAccessorElement && element.isOriginVariable) {
if (element.variable.metadata.hasNonVirtual) {
return true;
}
@@ -545,7 +545,7 @@ class MemberDuplicateDefinitionVerifier {
element: PropertyAccessorElementImpl staticMember2,
):
DiagnosticCode errorCode;
if (staticMember2.isSynthetic) {
if (staticMember2.isOriginVariable) {
errorCode = diag.conflictingConstructorAndStaticField;
} else if (staticMember2 is GetterElementImpl) {
errorCode = diag.conflictingConstructorAndStaticGetter;
@@ -566,7 +566,7 @@ class MemberDuplicateDefinitionVerifier {
case _ScopeEntryGetterSetterPair():
_diagnosticReporter.atElement2(
constructor.asElement2,
state.getter.isSynthetic
state.getter.isOriginVariable
? diag.conflictingConstructorAndStaticField
: diag.conflictingConstructorAndStaticGetter,
arguments: [name],
@@ -282,7 +282,7 @@ class GatherUsedLocalElementsVisitor extends RecursiveAstVisitor<void> {
if (element is PropertyAccessorElement &&
isIdentifierRead &&
variable is TopLevelVariableElement) {
if (element.isSynthetic) {
if (element.isOriginVariable) {
usedElements.addElement(variable);
} else {
usedElements.members.add(element);
+86 -7
View File
@@ -551,7 +551,7 @@ class FieldItem extends VariableItem<FieldElementImpl> {
}
}
class GetterItem extends ExecutableItem<GetterElementImpl> {
class GetterItem extends PropertyAccessorItem<GetterElementImpl> {
GetterItem({
required super.id,
required super.flags,
@@ -566,7 +566,7 @@ class GetterItem extends ExecutableItem<GetterElementImpl> {
}) {
return GetterItem(
id: id,
flags: _ExecutableItemFlags.encode(element),
flags: _PropertyAccessorItemFlags.encode(element),
metadata: ManifestMetadata.encode(
context,
element.thisOrVariableMetadata,
@@ -578,7 +578,7 @@ class GetterItem extends ExecutableItem<GetterElementImpl> {
factory GetterItem.read(BinaryReader reader) {
return GetterItem(
id: ManifestItemId.read(reader),
flags: _ExecutableItemFlags.read(reader),
flags: _PropertyAccessorItemFlags.read(reader),
metadata: ManifestMetadata.read(reader),
functionType: ManifestFunctionType.read(reader),
);
@@ -1373,7 +1373,29 @@ class MixinItem extends InterfaceItem<MixinElementImpl> {
}
}
class SetterItem extends ExecutableItem<SetterElementImpl> {
sealed class PropertyAccessorItem<E extends PropertyAccessorElementImpl>
extends ExecutableItem<E> {
PropertyAccessorItem({
required super.id,
required _PropertyAccessorItemFlags super.flags,
required super.metadata,
required super.functionType,
});
@override
_PropertyAccessorItemFlags get flags =>
super.flags as _PropertyAccessorItemFlags;
@override
bool match(MatchContext context, E element) {
return super.match(context, element) &&
flags.isOriginDeclaration == element.isOriginDeclaration &&
flags.isOriginInterface == element.isOriginInterface &&
flags.isOriginVariable == element.isOriginVariable;
}
}
class SetterItem extends PropertyAccessorItem<SetterElementImpl> {
SetterItem({
required super.id,
required super.flags,
@@ -1388,7 +1410,7 @@ class SetterItem extends ExecutableItem<SetterElementImpl> {
}) {
return SetterItem(
id: id,
flags: _ExecutableItemFlags.encode(element),
flags: _PropertyAccessorItemFlags.encode(element),
metadata: ManifestMetadata.encode(
context,
element.thisOrVariableMetadata,
@@ -1400,7 +1422,7 @@ class SetterItem extends ExecutableItem<SetterElementImpl> {
factory SetterItem.read(BinaryReader reader) {
return SetterItem(
id: ManifestItemId.read(reader),
flags: _ExecutableItemFlags.read(reader),
flags: _PropertyAccessorItemFlags.read(reader),
metadata: ManifestMetadata.read(reader),
functionType: ManifestFunctionType.read(reader),
);
@@ -1655,6 +1677,12 @@ enum _MethodItemFlag { isOperatorEqualWithParameterTypeFromObject }
enum _MixinItemFlag { isBase }
enum _PropertyAccessorItemFlag {
isOriginDeclaration,
isOriginInterface,
isOriginVariable,
}
enum _TopLevelVariableItemFlag {
isExternal,
isOriginDeclaration,
@@ -2211,6 +2239,57 @@ extension type _MixinItemFlags._(int _bits) implements _InterfaceItemFlags {
}
}
extension type _PropertyAccessorItemFlags._(int _bits)
implements _ExecutableItemFlags {
static final int _base = _ExecutableItemFlags._next;
factory _PropertyAccessorItemFlags.encode(
PropertyAccessorElementImpl element,
) {
var bits = _ExecutableItemFlags.encode(element)._bits;
if (element.isOriginDeclaration) {
bits |= _maskFor(_PropertyAccessorItemFlag.isOriginDeclaration);
}
if (element.isOriginInterface) {
bits |= _maskFor(_PropertyAccessorItemFlag.isOriginInterface);
}
if (element.isOriginVariable) {
bits |= _maskFor(_PropertyAccessorItemFlag.isOriginVariable);
}
return _PropertyAccessorItemFlags._(bits);
}
factory _PropertyAccessorItemFlags.read(BinaryReader reader) {
return _PropertyAccessorItemFlags._(reader.readUint30());
}
bool get isOriginDeclaration {
return _has(_PropertyAccessorItemFlag.isOriginDeclaration);
}
bool get isOriginInterface {
return _has(_PropertyAccessorItemFlag.isOriginInterface);
}
bool get isOriginVariable {
return _has(_PropertyAccessorItemFlag.isOriginVariable);
}
void write(BinaryWriter writer) {
writer.writeUint30(_bits);
}
bool _has(_PropertyAccessorItemFlag flag) {
return (_bits & _maskFor(flag)) != 0;
}
static int _maskFor(_PropertyAccessorItemFlag flag) {
var bit = _base + flag.index;
assert(bit < 30);
return 1 << bit;
}
}
extension type _TopLevelVariableItemFlags._(int _bits)
implements _VariableItemFlags {
static final int _base = _VariableItemFlags._next;
@@ -2477,7 +2556,7 @@ extension _LookupNameToSetterItemMapExtension on Map<LookupName, SetterItem> {
extension _PropertyAccessExtension on PropertyAccessorElementImpl {
MetadataImpl get thisOrVariableMetadata {
if (isSynthetic) {
if (isOriginVariable) {
return variable.metadata;
} else {
return metadata;
@@ -384,6 +384,7 @@ class ElementBuilder {
{
var getterFragment = GetterFragmentImpl(name: fieldFragment.name)
..isOriginVariable = true
..isSynthetic = true
..isAbstract = fieldFragment.isAbstract
..isStatic = fieldFragment.isStatic;
@@ -401,6 +402,7 @@ class ElementBuilder {
if (fieldFragment.hasSetter) {
var setterFragment = SetterFragmentImpl(name: fieldFragment.name)
..isOriginVariable = true
..isSynthetic = true
..isAbstract = fieldFragment.isAbstract
..isStatic = fieldFragment.isStatic;
@@ -782,6 +784,7 @@ class ElementBuilder {
{
var getterFragment = GetterFragmentImpl(name: variableFragment.name)
..isOriginVariable = true
..isSynthetic = true
..isStatic = true;
libraryFragment.addGetter(getterFragment);
@@ -799,6 +802,7 @@ class ElementBuilder {
if (variableFragment.hasSetter) {
var setterFragment = SetterFragmentImpl(name: variableFragment.name)
..isOriginVariable = true
..isSynthetic = true
..isStatic = true;
libraryFragment.addSetter(setterFragment);
@@ -1503,6 +1507,7 @@ class FragmentBuilder extends ThrowingAstVisitor<void> {
if (node.isGetter) {
var getterFragment = GetterFragmentImpl(name: name2);
getterFragment.isAugmentation = node.augmentKeyword != null;
getterFragment.isOriginDeclaration = true;
getterFragment.isStatic = true;
getterFragment.enclosingFragment = _unitElement;
@@ -1512,6 +1517,7 @@ class FragmentBuilder extends ThrowingAstVisitor<void> {
} else if (node.isSetter) {
var setterFragment = SetterFragmentImpl(name: name2);
setterFragment.isAugmentation = node.augmentKeyword != null;
setterFragment.isOriginDeclaration = true;
setterFragment.isStatic = true;
setterFragment.enclosingFragment = _unitElement;
@@ -1702,6 +1708,7 @@ class FragmentBuilder extends ThrowingAstVisitor<void> {
var fragment = GetterFragmentImpl(name: _getFragmentName(nameToken));
fragment.isAbstract = node.isAbstract;
fragment.isAugmentation = node.augmentKeyword != null;
fragment.isOriginDeclaration = true;
fragment.isStatic = node.isStatic;
_addChildFragment(fragment);
executableFragment = fragment;
@@ -1709,6 +1716,7 @@ class FragmentBuilder extends ThrowingAstVisitor<void> {
var fragment = SetterFragmentImpl(name: _getFragmentName(nameToken));
fragment.isAbstract = node.isAbstract;
fragment.isAugmentation = node.augmentKeyword != null;
fragment.isOriginDeclaration = true;
fragment.isStatic = node.isStatic;
_addChildFragment(fragment);
executableFragment = fragment;
@@ -102,13 +102,13 @@ class InstanceMemberInferrer {
String elementName;
if (getter != null) {
if (getter.isSynthetic || getter.isStatic) {
if (getter.isOriginVariable || getter.isStatic) {
return;
}
elementLibraryUri = getter.library.uri;
elementName = getter.displayName;
} else if (setter != null) {
if (setter.isSynthetic || setter.isStatic) {
if (setter.isOriginVariable || setter.isStatic) {
return;
}
elementLibraryUri = setter.library.uri;
@@ -944,7 +944,7 @@ class _FieldPromotability
}
for (var getter in class_.getters) {
if (getter.isStatic || getter.isSynthetic) {
if (getter.isStatic || getter.isOriginVariable) {
continue;
}
@@ -81,7 +81,7 @@ class ConstantsDataExtractor extends AstDataExtractor<String> {
String? computeNodeValue(Id id, AstNode node) {
if (node is Identifier) {
var element = node.element;
if (element is PropertyAccessorElement && element.isSynthetic) {
if (element is PropertyAccessorElement && element.isOriginVariable) {
var variable = element.variable;
if (variable.isOriginDeclaration && variable.isConst) {
var value = variable.computeConstantValue();
@@ -294,7 +294,7 @@ class _Element2Writer extends _AbstractElementWriter {
'getters',
e,
e.getters.where((getter) {
if (!configuration.withSyntheticGetters && getter.isSynthetic) {
if (!configuration.withSyntheticGetters && getter.isOriginVariable) {
return false;
}
return true;
@@ -942,12 +942,12 @@ class _Element2Writer extends _AbstractElementWriter {
// }
_sink.writeIndentedLine(() {
// ignore: deprecated_member_use_from_same_package
_sink.writeIf(e.isSynthetic, 'synthetic ');
_sink.writeIf(e.isStatic, 'static ');
_sink.writeIf(e.isAbstract, 'abstract ');
_sink.writeIf(e.isExternal, 'external ');
_sink.writeIf(e.isExtensionTypeMember, 'isExtensionTypeMember ');
_writeElementName(e);
});
@@ -998,7 +998,6 @@ class _Element2Writer extends _AbstractElementWriter {
_writeObjectId(f);
_sink.writeIf(f.isAugmentation, 'augment ');
_sink.writeIf(f.isSynthetic, 'synthetic ');
_writeFragmentName(f);
// _writeBodyModifiers(e);
});
@@ -1539,12 +1538,12 @@ class _Element2Writer extends _AbstractElementWriter {
// }
_sink.writeIndentedLine(() {
// ignore: deprecated_member_use_from_same_package
_sink.writeIf(e.isSynthetic, 'synthetic ');
_sink.writeIf(e.isStatic, 'static ');
_sink.writeIf(e.isAbstract, 'abstract ');
_sink.writeIf(e.isExternal, 'external ');
_sink.writeIf(e.isExtensionTypeMember, 'isExtensionTypeMember ');
_writeElementName(e);
});
@@ -1595,7 +1594,6 @@ class _Element2Writer extends _AbstractElementWriter {
_writeObjectId(f);
_sink.writeIf(f.isAugmentation, 'augment ');
_sink.writeIf(f.isSynthetic, 'synthetic ');
_writeFragmentName(f);
// _writeBodyModifiers(f);
});
@@ -338,7 +338,7 @@ class _SuggestionBuilder {
...targetType.setters,
]) {
if (!propertyAccessor.isStatic) {
if (propertyAccessor.isSynthetic) {
if (propertyAccessor.isOriginVariable) {
// Avoid visiting a field twice
if (propertyAccessor is GetterElement) {
_addSuggestion(propertyAccessor.variable);
+1 -1
View File
@@ -663,7 +663,7 @@ extension on Element {
bool isInPublicApiOf(String packageName) {
if (this case PropertyAccessorElement(
isSynthetic: true,
isOriginVariable: true,
:var variable,
) when variable.isInPublicApiOf(packageName)) {
return true;
+2 -2
View File
@@ -242,7 +242,7 @@ bool _checkForSimpleGetter(MethodDeclaration getter, Expression? expression) {
// the same
if (staticElement.enclosingElement == enclosingElement) {
var variable = staticElement.variable;
return staticElement.isSynthetic && variable.isPrivate;
return staticElement.isOriginVariable && variable.isPrivate;
}
}
}
@@ -261,7 +261,7 @@ bool _checkForSimpleSetter(MethodDeclaration setter, Expression expression) {
var rightHandSide = expression.rightHandSide;
if (leftHandSide is SimpleIdentifier && rightHandSide is SimpleIdentifier) {
var leftElement = expression.writeElement;
if (leftElement is! SetterElement || !leftElement.isSynthetic) {
if (leftElement is! SetterElement || leftElement.isOriginDeclaration) {
return false;
}
@@ -435,7 +435,7 @@ extension on String {
extension on Element {
bool get isInAnalyzerPublicApi {
if (this case PropertyAccessorElement(
isSynthetic: true,
isOriginVariable: true,
:var variable,
) when variable.isInAnalyzerPublicApi) {
return true;
@@ -248,8 +248,8 @@ extension on Expression? {
extension on Element? {
/// Returns whether this is a `final` variable or property and not `late`.
bool get isFinal => switch (this) {
PropertyAccessorElement(:var isSynthetic, :var variable) =>
isSynthetic && variable.isFinal && !variable.isLate,
PropertyAccessorElement(:var isOriginVariable, :var variable) =>
isOriginVariable && variable.isFinal && !variable.isLate,
VariableElement(:var isLate, :var isFinal) => isFinal && !isLate,
// TODO(pq): [element model] this preserves existing v1 semantics but looks fishy
_ => true,
@@ -131,7 +131,7 @@ class _ReportNoClearEffectVisitor extends UnifyingAstVisitor<void> {
// Allow getters; getters with side effects were the main cause of false
// positives.
var element = node.identifier.element;
if (element is GetterElement && !element.isSynthetic) {
if (element is GetterElement && element.isOriginDeclaration) {
return;
}
@@ -152,7 +152,7 @@ class _ReportNoClearEffectVisitor extends UnifyingAstVisitor<void> {
// Allow getters; previously getters with side effects were the main cause
// of false positives.
var element = node.propertyName.element;
if (element is GetterElement && !element.isSynthetic) {
if (element is GetterElement && element.isOriginDeclaration) {
return;
}
@@ -169,7 +169,7 @@ class _ReportNoClearEffectVisitor extends UnifyingAstVisitor<void> {
// Allow getter (in this case with an implicit `this.`); previously, getters
// with side effects were the main cause of false positives.
var element = node.element;
if (element is GetterElement && !element.isSynthetic) {
if (element is GetterElement && element.isOriginDeclaration) {
return;
}