| // Copyright (c) 2026, the Dart project authors. Please see the AUTHORS file |
| // 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/dart/element/element.dart'; |
| |
| /// Element categorization used by [MemberSortKey]. |
| enum MemberCategory { |
| constructor, |
| propertyAccessor, |
| topLevelFunctionOrMethod, |
| interface, |
| extension, |
| typeAlias, |
| } |
| |
| /// Sort key used to sort elements in the output. |
| final class MemberSortKey implements Comparable<MemberSortKey> { |
| final bool isInstanceMember; |
| final MemberCategory category; |
| final String name; |
| final bool isSetter; |
| |
| MemberSortKey({ |
| required this.isInstanceMember, |
| required this.category, |
| required this.name, |
| required this.isSetter, |
| }); |
| |
| @override |
| int compareTo(MemberSortKey other) { |
| if ((isInstanceMember ? 1 : 0).compareTo(other.isInstanceMember ? 1 : 0) |
| case final value when value != 0) { |
| return value; |
| } |
| if (category.index.compareTo(other.category.index) case final value |
| when value != 0) { |
| return value; |
| } |
| if (category == MemberCategory.constructor && |
| other.category == MemberCategory.constructor) { |
| if (name == 'new') { |
| return other.name == 'new' ? 0 : -1; |
| } else if (other.name == 'new') { |
| return 1; |
| } |
| } |
| if (name.compareTo(other.name) case final value when value != 0) { |
| return value; |
| } |
| return (isSetter ? 1 : 0).compareTo(other.isSetter ? 1 : 0); |
| } |
| |
| static MemberCategory computeCategory(Element element) => switch (element) { |
| ConstructorElement() => MemberCategory.constructor, |
| PropertyAccessorElement() => MemberCategory.propertyAccessor, |
| TopLevelFunctionElement() => MemberCategory.topLevelFunctionOrMethod, |
| MethodElement() => MemberCategory.topLevelFunctionOrMethod, |
| InterfaceElement() => MemberCategory.interface, |
| ExtensionElement() => MemberCategory.extension, |
| TypeAliasElement() => MemberCategory.typeAlias, |
| dynamic(:final runtimeType) => throw UnimplementedError( |
| 'Unexpected element: $runtimeType', |
| ), |
| }; |
| |
| static bool computeIsInstanceMember(Element element) => |
| element.enclosingElement is InstanceElement && |
| switch (element) { |
| ExecutableElement(:final isStatic) => !isStatic, |
| dynamic(:final runtimeType) => throw UnimplementedError( |
| 'Unexpected element: $runtimeType', |
| ), |
| }; |
| } |