pedant 1.0.2 copy "pedant: ^1.0.2" to clipboard
pedant: ^1.0.2 copied to clipboard

A strict static analyzer and script for formatting Dart code.

Pedant #

A strict static analyzer and script for formatting Dart code.
Designed to solve problems in a project at the design and support stages.

Analyzer:

  • strict architectural rules;
  • strict stylistic rules;
  • not strict rules of approach.

Script:

  • automatic fix of detected linter errors;
  • sorting in alphabetical order of the fields of .arb files;
  • sorting in alphabetical order and converting declarations of imports, exports and parts;
  • sorting in alphabetical order of dependencies, dev_dependencies, dependency_overrides keys in pubspec.yaml;
  • Dart code formatting.

Get started #

Installing #

  1. Add two packages to the pubspec.yaml file in the dev_dependencies section:
dev_dependencies:
  custom_lint: ^latest_version
  pedant: ^latest_version
  1. Add the inclusion of a custom analyzer to the analysis_options.yaml file:
analyzer:
  plugins:
    - custom_lint

# For rules configuration add this inclusion
custom_lint:
  rules:
    - pedant:

It is advisable to restart the IDE after connecting the analyzer.

Config #

Current default configuration:

custom_lint:
  rules:
    - pedant:
      add_bloc_cubit_event_state_file: true
      add_bloc_cubit_state_postfix: true
      add_bloc_cubit_state_sealed: true
      add_bloc_event_postfix: true
      add_bloc_event_sealed: true
      add_bloc_postfix: true
      add_class_postfix_by_keyword_list: null
      add_class_postfix_by_path_list: null
      add_class_prefix_by_keyword_list: null
      add_class_prefix_by_path_list: null
      add_comma: true
      add_const_constructor: true
      add_const: true
      add_constructor: true
      add_controller_postfix: true
      add_cubit_postfix: true
      add_extension_postfix: true
      add_if_braces: true
      add_mixin_postfix: true
      add_override: true
      add_this: true
      add_type: true
      delete_bloc_cubit_dependent_bloc_cubit: true
      delete_bloc_cubit_dependent_flutter: true
      delete_bloc_cubit_public_property: true
      delete_class_postfix_list:
        - Impl
        - Implementation
        - Model
      delete_class_prefix_list: null
      delete_function_list:
        - print
        - debugPrint
        - debugPrintThrottled
      delete_new: true
      # delete_package_list: - Check note
      # delete_type_list: - Check note
      delete_widget_function_method: true
      edit_arrow_function: true
      edit_constructor_private_named_parameter: true
      edit_constructor_public_named_parameter: true
      edit_file_length_by_path_list: null
      edit_function_private_named_parameter: true
      edit_function_public_named_parameter: true
      edit_multiple_variable: true
      edit_private_in_function: true
      edit_relative_import: true
      edit_variable_name_by_type: true
      priority: 100

Note:
Default list of delete_package_list check here.
Default list of delete_type_list check here.

CLI #

The script is designed from the point of view of maximum coverage and bringing order to the project.
Run the script:

dart run pedant

Arguments:

 --no-fix - disable fix of analyzed linter problems;
 --no-sort-arb - disable alphabetical sorting of .arb files;
 --no-sort-convert-export-import-part - disable alphabetical sorting of declarations of imports, exports and parts of .dart files;
 --no-sort-pubspec-dependencies - disable alphabetical sorting dependencшуы in the pubspec.yaml file;
 --no-format - disable final formatting at the script completion stage;

Rules #

Add #

add_bloc_cubit_part

The Bloc/Cubit state and event class must be located either in the same file or in the same visibility area through part/part of.

// BAD:
import 'package:example/example_event.dart';
import 'package:example/example_state.dart';

class ExampleBloc extends Bloc<IExampleEvent, IExampleState> {
  ...
}

// GOOD:
class ExampleBloc extends Bloc<IExampleEvent, IExampleState> {
  ...
}

sealed class IExampleEvent {
  ...
}

sealed class IExampleState {
  ...
}

// GOOD:
part of 'example_event.dart';
part of 'example_state.dart';

class ExampleBloc extends Bloc<IExampleEvent, IExampleState> {
  ...
}

add_bloc_cubit_state_postfix

The Bloc/Cubit state class must have a State postfix.

// BAD:
sealed class IExampleSt {
  ...
}

// GOOD:
sealed class IExampleState {
  ...
}

add_bloc_cubit_state_sealed

The Bloc/Cubit state class must be declared with the 'sealed' keyword.

// BAD:
class ExampleState {
  ...
}

// GOOD:
sealed class IExampleState {
  ...
}

add_bloc_event_postfix

The Bloc event class must have the Event postfix.

// BAD:
sealed class IExampleEv {
  ...
}

// GOOD:
sealed class IExampleEvent {
  ...
}

add_bloc_event_sealed

The Bloc event class must be declared with the 'sealed' keyword.

// BAD:
class ExampleEvent {
  ...
}

// GOOD:
sealed class IExampleEvent {
  ...
}

add_bloc_postfix

The Bloc class must have a Bloc postfix.

// BAD:
class ExampleBlc extends Bloc<IExampleEvent, IExampleState> {
  ...
}

// GOOD:
class ExampleBloc extends Bloc<IExampleEvent, IExampleState> {
  ...
}

add_class_postfix_by_keyword_list

Classes that contain keywords from the list must have the appropriate postfix.
Example:

add_class_postfix_by_keyword_list:
  -
    keywordList:
      - base
    name: Base
// BAD:
base class Example {
  ...
}

// GOOD:
base class ExampleBase {
  ...
}

add_class_postfix_by_path_list

Classes that are located along the path from the list must have the appropriate postfix.

// BAD:
base class Example {
  ...
}

// GOOD:
base class ExampleBase {
  ...
}

add_class_prefix_by_keyword_list

Classes that contain keywords from the list must be prefixed accordingly.
Example:

add_class_prefix_by_keyword_list:
  -
    keywordList:
      - abstract
      - interface
      - sealed
    name: I
// BAD:
interface class Example {
  ...
}

// GOOD:
interface class IExample {
  ...
}

add_class_prefix_by_path_list

Classes that are located along the path from the list must have the appropriate prefix.

// BAD:
interface class Example {
  ...
}

// GOOD:
interface class IExample {
  ...
}

add_comma

There must be a comma at the end of the parameter list.

// BAD:
(a, b) {}

void exampleFunction({required String argument}) {
  print("Hello World!");
}

// GOOD:
(
  a, 
  b,
) {}

void exampleFunction({
  required String argument,
}) {
  print(
    "Hello World!",
  );
}

add_const_constructor

A class that has all final fields must have a const constructor.

// BAD:
class Example {
  Example({
    required this.title,
  });

  final String title;
}


// GOOD:
class Example {
  const Example({
    required this.title,
  });

  final String title;
}

add_const

Global variables, static fields, variables in functions, and objects that have the final keyword and can be constants must have the 'const' keyword.

// BAD:
final Example topLevel = Example(
  title: "Title",
);

class Example {
  static final String subTitle = "SubTitle";

  const Example({
    required this.title,
  });

  final String title;
}

void exampleFunction() {
  final Example function = Example(
    title: "Title",
  );
}

// GOOD:
const Example topLevel = Example(
  title: "Title",
);

class Example {
  static const String title = "SubTitle";

  const Example();
}

void exampleFunction() {
  const Example function = Example(
    title: "Title",
  );
}

add_constructor

All classes must have an explicit constructor.

// BAD:
class Example {}

// GOOD:
class Example {
  Example();
}

add_controller_postfix

The ChangeNotifier/ValueNotifier class must have a Controller postfix.

// BAD:
class ExampleNotifier extends ChangeNotifier {}

// GOOD:
class ExampleController extends ChangeNotifier {}

add_cubit_postfix

The Cubit class must have the Cubit postfix.

// BAD:
class ExampleCub extends Cubit<ExampleState> {
  ...
}

// GOOD:
class ExampleCubit extends Cubit<ExampleState> {
  ...
}

add_extension_postfix

The extension must have the Extension postfix.

// BAD:
extension ExampleX on Object {}

// GOOD:
extension ExampleExtension on Object {}

add_if_braces

The if expression must have parentheses.

// BAD:
if (list.isEmpty) return;

// GOOD:
if (list.isEmpty) {
  return;
}

add_mixin_postfix

A mixin must have a Mixin postfix.

// BAD:
mixin StringMix on Object {}

// GOOD:
mixin StringMixin on Object {}

add_override

Fields and methods of a class overridden from the base one must have the @override annotation.

// BAD:
class Example {
  String toString() => "";
}

// GOOD:
class Example {
  @override
  String toString() => "";
}

add_this

Within a class, access to internal fields and methods must begin with the this keyword.

// BAD:
class Example {
  ...

  final String title;

  @override
  String toString() => title;
}


// GOOD:
class Example {
  ...

  final String title;

  @override
  String toString() => this.title;
}

add_type

Variables and parameters of closures must have a type.

// BAD:
void exampleFunction(
  field,
) {
  final variable = "";
}

// GOOD:
void exampleFunction(
  dynamic field,
) {
  final String variable = "";
}

Delete #

delete_bloc_cubit_dependent_bloc_cubit

Need to remove the Bloc/Cubit dependency in the Bloc/Cubit class.

// BAD:
class ExampleBloc extends Bloc<IExampleEvent, IExampleState> {
  ExampleBloc({
    required AnotherBloc anotherbloc,
  })  : this._anotherbloc = anotherbloc,
        super(
          const ExampleLoadingState(),
        );

  final AnotherBloc _anotherbloc;
}

// GOOD:
class ExampleBloc extends Bloc<IExampleEvent, IExampleState> {
  ExampleBloc() : super(
    const ExampleLoadingState(),
  );
}

delete_bloc_cubit_dependent_flutter

Need to remove the Flutter resource dependency in the Bloc/Cubit class.

// BAD:
class ExampleBloc extends Bloc<IExampleEvent, IExampleState> {
  ExampleBloc({
    required TextEditingController textController,
  })  : this._textController = textController,
        super(
          const ExampleLoadingState(),
        );

  final TextEditingController _textController;
}

// GOOD:
class ExampleBloc extends Bloc<IExampleEvent, IExampleState> {
  ExampleBloc() : super(
    const ExampleLoadingState(),
  );
}

delete_bloc_cubit_public_property

Need to remove public properties in the Bloc/Cubit class.

// BAD:
class ExampleBloc extends Bloc<IExampleEvent, IExampleState> {
  ExampleBloc({
    required this.publicProperty,
  })  :  super(
          const ExampleLoadingState(),
        );

  final String publicProperty;
}

// GOOD:
class ExampleBloc extends Bloc<IExampleEvent, IExampleState> {
  ExampleBloc() : super(
    const ExampleLoadingState(),
  );
}

delete_class_postfix_list

Need to remove the class postfix included in the list.

// BAD:
class ExampleModel {
  const ExampleModel();
}

// GOOD:
class Example {
  const Example();
}

delete_class_prefix_list

Need to remove the class prefix included in the list.

// BAD:
class ModelExample {
  const ModelExample();
}

// GOOD:
class Example {
  const Example();
}

delete_function_list

Need to remove a function from the list.

// BAD:
void exampleFunction() {
  print(something);
}

// GOOD:
void exampleFunction() {}

delete_new

Need to remove the 'new' keyword when creating the instance.

// BAD:
final ExampleClass example = new ExampleClass();

// GOOD:
final ExampleClass example = ExampleClass();

delete_package_list

Need to remove the package that is on the list.

# BAD:
dependencies:
  bloc:
  get:
  get_it:
  fpdart:
  hive:

# GOOD:
dependencies:
  bloc:

delete_type_list

Need to remove a type from the list.

// BAD:
return Scaffold(
  body: Container(
    ... ,
  ),
);

// GOOD:
return Scaffold(
  body: Padding(
    padding: ... ,
    child: ColorBox(
      color: ... ,
    ),
  ),
);

delete_widget_function_method

Need to remove the function that returns Widget.

// BAD:
Widget _buildRow() => Row(
  ... ,
);

// GOOD:
List<String> _entityList() => [
  ... ,
];

Edit #

edit_arrow_function

Need to edit the arrow function.

// BAD:
int exampleFunction() {
  return 1 + 1;
}

// GOOD:
int exampleFunction() => 1 + 1;

edit_constructor_private_named_parameter

Need to edit all parameters of the private constructor into named ones.

// BAD:
class _ExampleClass {
  const _ExampleClass(
    this.property0,
    this.property1,
  );

  ...
}

// GOOD:
class _ExampleClass {
  const _ExampleClass({
    required this.property0,
    required this.property1,
  });

  ...
}

edit_constructor_public_named_parameter

Need to edit all parameters of the public constructor into named ones.

// BAD:
class ExampleClass {
  const ExampleClass(
    this.property0,
    this.property1,
  );

  ...
}

// GOOD:
class ExampleClass {
  const ExampleClass({
    required this.property0,
    required this.property1,
  });

  ...
}

edit_file_length_by_path_list

Need to edit the file located along the path to the allowable code length.

edit_function_private_named_parameter

Need to edit all parameters of a private function into named ones.

// BAD:
void _exampleFunction(
  String argument0,
  String argument1,
) {
  ...
}

// GOOD:
void _exampleFunction({
  required String argument0,
  required String argument1,
}) {
  ...
}

edit_function_public_named_parameter

Need to edit all parameters of a public function into named ones.

// BAD:
void exampleFunction(
  String argument0,
  String argument1,
) {
  ...
}

// GOOD:
void exampleFunction({
  required String argument0,
  required String argument1,
}) {
  ...
}

edit_multiple_variable

Need to edit the declaration of the list of variables into separate ones.

// BAD:
final String variable0, variable1, variable2 = "";

// GOOD:
final String variable0 = "";
final String variable1 = "";
final String variable2 = "";

edit_private_in_function

Need to edit a private variable to public in a function.

// BAD:
void exampleFunction() {
  final String _variable = "";
}

// GOOD:
void exampleFunction() {
  final String variable = "";
}

edit_relative_import

Need to edit relative import to absolute.

// BAD:
import '../src/example.dart';

// GOOD:
import 'package:example/src/example.dart';

edit_variable_name_by_type

You need to edit the variable name based on its type.

// BAD:
final ExampleClass a = ExampleClass();

// GOOD:
final ExampleClass example = ExampleClass();

Other #

Priority

The priority of displayed commands in the IDE.

5
likes
0
points
4
downloads

Publisher

unverified uploader

Weekly Downloads

A strict static analyzer and script for formatting Dart code.

Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

analyzer, analyzer_plugin, args, collection, custom_lint, custom_lint_builder, path, tint, yaml

More

Packages that depend on pedant