diff --git a/pkg/analysis_server/lib/src/cider/local_library_contributor.dart b/pkg/analysis_server/lib/src/cider/local_library_contributor.dart index 23244cb7f83..0fec7f804ab 100644 --- a/pkg/analysis_server/lib/src/cider/local_library_contributor.dart +++ b/pkg/analysis_server/lib/src/cider/local_library_contributor.dart @@ -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 { diff --git a/pkg/analysis_server/lib/src/computer/computer_call_hierarchy.dart b/pkg/analysis_server/lib/src/computer/computer_call_hierarchy.dart index 860feca8f73..fb64c4bbca5 100644 --- a/pkg/analysis_server/lib/src/computer/computer_call_hierarchy.dart +++ b/pkg/analysis_server/lib/src/computer/computer_call_hierarchy.dart @@ -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; } diff --git a/pkg/analysis_server/lib/src/lsp/handlers/custom/handler_summary.dart b/pkg/analysis_server/lib/src/lsp/handlers/custom/handler_summary.dart index f95f55efe9c..2ced1a337eb 100644 --- a/pkg/analysis_server/lib/src/lsp/handlers/custom/handler_summary.dart +++ b/pkg/analysis_server/lib/src/lsp/handlers/custom/handler_summary.dart @@ -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; diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_definition.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_definition.dart index 201ffb84737..aed57c1745f 100644 --- a/pkg/analysis_server/lib/src/lsp/handlers/handler_definition.dart +++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_definition.dart @@ -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; } diff --git a/pkg/analysis_server/lib/src/services/completion/dart/declaration_helper.dart b/pkg/analysis_server/lib/src/services/completion/dart/declaration_helper.dart index bb6e6f93c65..9c2c1173404 100644 --- a/pkg/analysis_server/lib/src/services/completion/dart/declaration_helper.dart +++ b/pkg/analysis_server/lib/src/services/completion/dart/declaration_helper.dart @@ -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; diff --git a/pkg/analysis_server/lib/src/services/completion/dart/feature_computer.dart b/pkg/analysis_server/lib/src/services/completion/dart/feature_computer.dart index f180b882f0c..ce5f198dfdd 100644 --- a/pkg/analysis_server/lib/src/services/completion/dart/feature_computer.dart +++ b/pkg/analysis_server/lib/src/services/completion/dart/feature_computer.dart @@ -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; diff --git a/pkg/analysis_server/lib/src/services/completion/dart/override_helper.dart b/pkg/analysis_server/lib/src/services/completion/dart/override_helper.dart index 7c29b0eafe0..4ddeffec801 100644 --- a/pkg/analysis_server/lib/src/services/completion/dart/override_helper.dart +++ b/pkg/analysis_server/lib/src/services/completion/dart/override_helper.dart @@ -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; diff --git a/pkg/analysis_server/lib/src/services/completion/dart/relevance_computer.dart b/pkg/analysis_server/lib/src/services/completion/dart/relevance_computer.dart index 6be5f956cb9..29634adc4aa 100644 --- a/pkg/analysis_server/lib/src/services/completion/dart/relevance_computer.dart +++ b/pkg/analysis_server/lib/src/services/completion/dart/relevance_computer.dart @@ -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) { diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_late.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_late.dart index 1bc2b1abd9a..483459c4a4e 100644 --- a/pkg/analysis_server/lib/src/services/correction/dart/add_late.dart +++ b/pkg/analysis_server/lib/src/services/correction/dart/add_late.dart @@ -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 && diff --git a/pkg/analysis_server/lib/src/services/correction/dart/make_field_not_final.dart b/pkg/analysis_server/lib/src/services/correction/dart/make_field_not_final.dart index 844fab9a4d0..d180d8d88f0 100644 --- a/pkg/analysis_server/lib/src/services/correction/dart/make_field_not_final.dart +++ b/pkg/analysis_server/lib/src/services/correction/dart/make_field_not_final.dart @@ -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; } diff --git a/pkg/analysis_server/lib/src/services/refactoring/legacy/convert_getter_to_method.dart b/pkg/analysis_server/lib/src/services/refactoring/legacy/convert_getter_to_method.dart index b8c0563df5c..96aef7df7e0 100644 --- a/pkg/analysis_server/lib/src/services/refactoring/legacy/convert_getter_to_method.dart +++ b/pkg/analysis_server/lib/src/services/refactoring/legacy/convert_getter_to_method.dart @@ -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.', ); diff --git a/pkg/analysis_server/lib/src/services/search/hierarchy.dart b/pkg/analysis_server/lib/src/services/search/hierarchy.dart index 733940671b4..42bb47a645e 100644 --- a/pkg/analysis_server/lib/src/services/search/hierarchy.dart +++ b/pkg/analysis_server/lib/src/services/search/hierarchy.dart @@ -276,7 +276,7 @@ List 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; } } diff --git a/pkg/analysis_server/lib/src/utilities/import_analyzer.dart b/pkg/analysis_server/lib/src/utilities/import_analyzer.dart index 67336474d78..92c9e3ff3a0 100644 --- a/pkg/analysis_server/lib/src/utilities/import_analyzer.dart +++ b/pkg/analysis_server/lib/src/utilities/import_analyzer.dart @@ -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 { 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); } } diff --git a/pkg/analyzer/CHANGELOG.md b/pkg/analyzer/CHANGELOG.md index 8e08468e921..1b1b8c432dc 100644 --- a/pkg/analyzer/CHANGELOG.md +++ b/pkg/analyzer/CHANGELOG.md @@ -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`. diff --git a/pkg/analyzer/api.txt b/pkg/analyzer/api.txt index 3d86dfa0972..cac3979e519 100644 --- a/pkg/analyzer/api.txt +++ b/pkg/analyzer/api.txt @@ -4061,6 +4061,10 @@ package:analyzer/dart/element/element.dart: enclosingElement (getter: Element) firstFragment (getter: PropertyAccessorFragment) fragments (getter: List) + 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()) diff --git a/pkg/analyzer/lib/dart/element/element.dart b/pkg/analyzer/lib/dart/element/element.dart index 0736e6bde58..486054c91e2 100644 --- a/pkg/analyzer/lib/dart/element/element.dart +++ b/pkg/analyzer/lib/dart/element/element.dart @@ -2931,6 +2931,29 @@ abstract class PropertyAccessorElement implements ExecutableElement { @override List 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 diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart index 20954ad7aef..9e4ce0149b7 100644 --- a/pkg/analyzer/lib/src/dart/analysis/driver.dart +++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart @@ -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. diff --git a/pkg/analyzer/lib/src/dart/analysis/search.dart b/pkg/analyzer/lib/src/dart/analysis/search.dart index 2f5f84f6932..253732eff33 100644 --- a/pkg/analyzer/lib/src/dart/analysis/search.dart +++ b/pkg/analyzer/lib/src/dart/analysis/search.dart @@ -1433,7 +1433,7 @@ class _FindLibraryDeclarations { void _addGetters(List 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 elements) { for (var i = 0; i < elements.length; i++) { var element = elements[i]; - if (!element.isSynthetic) { + if (element.isOriginDeclaration) { _addDeclaration(element, element.displayName); } } diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart index 6d47144b693..452a0b80e34 100644 --- a/pkg/analyzer/lib/src/dart/element/element.dart +++ b/pkg/analyzer/lib/src/dart/element/element.dart @@ -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 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, diff --git a/pkg/analyzer/lib/src/dart/element/element.g.dart b/pkg/analyzer/lib/src/dart/element/element.g.dart index 0ad8da5c64f..715d3c3804b 100644 --- a/pkg/analyzer/lib/src/dart/element/element.g.dart +++ b/pkg/analyzer/lib/src/dart/element/element.g.dart @@ -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); diff --git a/pkg/analyzer/lib/src/dart/element/inheritance_manager3.dart b/pkg/analyzer/lib/src/dart/element/inheritance_manager3.dart index bf9bf5970ae..6b7b0a30d0f 100644 --- a/pkg/analyzer/lib/src/dart/element/inheritance_manager3.dart +++ b/pkg/analyzer/lib/src/dart/element/inheritance_manager3.dart @@ -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; diff --git a/pkg/analyzer/lib/src/dart/element/member.dart b/pkg/analyzer/lib/src/dart/element/member.dart index bf3375216bf..92f0fb4314b 100644 --- a/pkg/analyzer/lib/src/dart/element/member.dart +++ b/pkg/analyzer/lib/src/dart/element/member.dart @@ -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; diff --git a/pkg/analyzer/lib/src/dart/resolver/annotation_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/annotation_resolver.dart index 840d08c35fa..c99a19c8ec0 100644 --- a/pkg/analyzer/lib/src/dart/resolver/annotation_resolver.dart +++ b/pkg/analyzer/lib/src/dart/resolver/annotation_resolver.dart @@ -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); diff --git a/pkg/analyzer/lib/src/error/best_practices_verifier.dart b/pkg/analyzer/lib/src/error/best_practices_verifier.dart index fb0fbaef720..175af72da17 100644 --- a/pkg/analyzer/lib/src/error/best_practices_verifier.dart +++ b/pkg/analyzer/lib/src/error/best_practices_verifier.dart @@ -1653,7 +1653,7 @@ class BestPracticesVerifier extends RecursiveAstVisitor { _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 { } static bool _hasNonVirtualAnnotation(ExecutableElement element) { - if (element is PropertyAccessorElement && element.isSynthetic) { + if (element is PropertyAccessorElement && element.isOriginVariable) { if (element.variable.metadata.hasNonVirtual) { return true; } diff --git a/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart b/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart index 37fb9cefffa..4c75ee4613a 100644 --- a/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart +++ b/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart @@ -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], diff --git a/pkg/analyzer/lib/src/error/unused_local_elements_verifier.dart b/pkg/analyzer/lib/src/error/unused_local_elements_verifier.dart index 6f344120df4..2169678fa46 100644 --- a/pkg/analyzer/lib/src/error/unused_local_elements_verifier.dart +++ b/pkg/analyzer/lib/src/error/unused_local_elements_verifier.dart @@ -282,7 +282,7 @@ class GatherUsedLocalElementsVisitor extends RecursiveAstVisitor { if (element is PropertyAccessorElement && isIdentifierRead && variable is TopLevelVariableElement) { - if (element.isSynthetic) { + if (element.isOriginVariable) { usedElements.addElement(variable); } else { usedElements.members.add(element); diff --git a/pkg/analyzer/lib/src/fine/manifest_item.dart b/pkg/analyzer/lib/src/fine/manifest_item.dart index 0ae5d903aa3..fd6e6bbf031 100644 --- a/pkg/analyzer/lib/src/fine/manifest_item.dart +++ b/pkg/analyzer/lib/src/fine/manifest_item.dart @@ -551,7 +551,7 @@ class FieldItem extends VariableItem { } } -class GetterItem extends ExecutableItem { +class GetterItem extends PropertyAccessorItem { GetterItem({ required super.id, required super.flags, @@ -566,7 +566,7 @@ class GetterItem extends ExecutableItem { }) { 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 { 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 { } } -class SetterItem extends ExecutableItem { +sealed class PropertyAccessorItem + extends ExecutableItem { + 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 { SetterItem({ required super.id, required super.flags, @@ -1388,7 +1410,7 @@ class SetterItem extends ExecutableItem { }) { 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 { 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 { extension _PropertyAccessExtension on PropertyAccessorElementImpl { MetadataImpl get thisOrVariableMetadata { - if (isSynthetic) { + if (isOriginVariable) { return variable.metadata; } else { return metadata; diff --git a/pkg/analyzer/lib/src/summary2/element_builder.dart b/pkg/analyzer/lib/src/summary2/element_builder.dart index 051db1bfc7c..9116a38c37f 100644 --- a/pkg/analyzer/lib/src/summary2/element_builder.dart +++ b/pkg/analyzer/lib/src/summary2/element_builder.dart @@ -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 { 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 { } 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 { 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 { 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; diff --git a/pkg/analyzer/lib/src/summary2/instance_member_inferrer.dart b/pkg/analyzer/lib/src/summary2/instance_member_inferrer.dart index 46ed5b7f4d2..abfb212d20d 100644 --- a/pkg/analyzer/lib/src/summary2/instance_member_inferrer.dart +++ b/pkg/analyzer/lib/src/summary2/instance_member_inferrer.dart @@ -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; diff --git a/pkg/analyzer/lib/src/summary2/library_builder.dart b/pkg/analyzer/lib/src/summary2/library_builder.dart index a298c788a37..59165b709ad 100644 --- a/pkg/analyzer/lib/src/summary2/library_builder.dart +++ b/pkg/analyzer/lib/src/summary2/library_builder.dart @@ -944,7 +944,7 @@ class _FieldPromotability } for (var getter in class_.getters) { - if (getter.isStatic || getter.isSynthetic) { + if (getter.isStatic || getter.isOriginVariable) { continue; } diff --git a/pkg/analyzer/test/id_tests/constant_test.dart b/pkg/analyzer/test/id_tests/constant_test.dart index df02883ad1d..7ffbb42e128 100644 --- a/pkg/analyzer/test/id_tests/constant_test.dart +++ b/pkg/analyzer/test/id_tests/constant_test.dart @@ -81,7 +81,7 @@ class ConstantsDataExtractor extends AstDataExtractor { 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(); diff --git a/pkg/analyzer/test/src/summary/element_text.dart b/pkg/analyzer/test/src/summary/element_text.dart index 6981294b130..9f1e247f456 100644 --- a/pkg/analyzer/test/src/summary/element_text.dart +++ b/pkg/analyzer/test/src/summary/element_text.dart @@ -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); }); diff --git a/pkg/analyzer_plugin/lib/utilities/completion/type_member_contributor.dart b/pkg/analyzer_plugin/lib/utilities/completion/type_member_contributor.dart index 3163bdde2f3..61961e59f4a 100644 --- a/pkg/analyzer_plugin/lib/utilities/completion/type_member_contributor.dart +++ b/pkg/analyzer_plugin/lib/utilities/completion/type_member_contributor.dart @@ -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); diff --git a/pkg/analyzer_utilities/lib/tool/api.dart b/pkg/analyzer_utilities/lib/tool/api.dart index 8e292d9c7f9..8f4be3c4524 100644 --- a/pkg/analyzer_utilities/lib/tool/api.dart +++ b/pkg/analyzer_utilities/lib/tool/api.dart @@ -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; diff --git a/pkg/linter/lib/src/ast.dart b/pkg/linter/lib/src/ast.dart index 3101a6264dc..c197c950d88 100644 --- a/pkg/linter/lib/src/ast.dart +++ b/pkg/linter/lib/src/ast.dart @@ -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; } diff --git a/pkg/linter/lib/src/rules/analyzer_public_api.dart b/pkg/linter/lib/src/rules/analyzer_public_api.dart index 52bf19189f1..36d6d61d67b 100644 --- a/pkg/linter/lib/src/rules/analyzer_public_api.dart +++ b/pkg/linter/lib/src/rules/analyzer_public_api.dart @@ -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; diff --git a/pkg/linter/lib/src/rules/unnecessary_lambdas.dart b/pkg/linter/lib/src/rules/unnecessary_lambdas.dart index 8b4c6809455..644f6e9d7b0 100644 --- a/pkg/linter/lib/src/rules/unnecessary_lambdas.dart +++ b/pkg/linter/lib/src/rules/unnecessary_lambdas.dart @@ -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, diff --git a/pkg/linter/lib/src/rules/unnecessary_statements.dart b/pkg/linter/lib/src/rules/unnecessary_statements.dart index 02f8e614024..94ace08c572 100644 --- a/pkg/linter/lib/src/rules/unnecessary_statements.dart +++ b/pkg/linter/lib/src/rules/unnecessary_statements.dart @@ -131,7 +131,7 @@ class _ReportNoClearEffectVisitor extends UnifyingAstVisitor { // 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 { // 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 { // 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; }