Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

proposal: add lint or collection of lints to detect when using interfaces in an impure way. #4963

Open
mmcdon20 opened this issue May 3, 2024 · 3 comments

Comments

@mmcdon20
Copy link

mmcdon20 commented May 3, 2024

Description

Warn when using interfaces in an impure way.

Details

Dart allows you to to use interfaces in an impure way (especially within the same library it is defined). This lint would detect and warn against any of the following in an interface:

  1. Non-abstract declarations
    a. Non-abstract interfaces
    b. Non-abstract properties
    c. Non-abstract methods
  2. Generative constructors (factory constructors are okay)
  3. An interface using extends or with
  4. Another class using extends on an interface

Kind

Style advice

Bad Examples

interface class Vehicle { // 1a. Non-abstract interface
  final String make; // 1b. Non-abstract property
  final String model; // 1b. Non-abstract property
  Vehicle(this.make, this.model); // 2. Generative constructor

  void moveForward() { // 1c. Non-abstract method
    print('$make $model is moving forward!');
  }
}

// 3. An interface using extends or with
abstract interface class Car extends Vehicle {
  Car(super.make, super.model);
}

// 4. Another class using extends on an interface
class HondaCivic extends Car {
  HondaCivic() : super('Honda', 'Civic');
}

Good Examples

abstract interface class Vehicle {
  abstract final String make;
  abstract final String model;
  void moveForward();
}

abstract interface class Car implements Vehicle {}

class HondaCivic implements Car {
  @override
  final String make = 'Honda';
  @override
  final String model = 'Civic';
  @override
  void moveForward() {
    print('$make $model is moving forward!');
  }
}

Discussion

See also dart-lang/language#3736 and dart-lang/sdk#55641.

@lrhn
Copy link
Member

lrhn commented May 5, 2024

it's not a lint I'd want in the recommended set. That is, it's a style lint that one can opt in to, but not an official style recommendation.

About the individual points of warning:

  • class fields in an interface

Should be "concrete instance field declaration". A declaration of

  abstract final int foo;

It's an instance variable declaration, but it doesn't introduce any implementation.

  • constructors in an interface

Should probably only be generative constructors. Having an interface with factory constructors creating instances of classes implementing the interface, is a common pattern.

  • method bodies in an interface

Can be combined with first item into:
"Non-abstract instance member declarations".

  • a class extending an interface (unless that class is also an interface)

Can only happen inside the same library.
I'd remove the exception. Other libraries cannot extend an interface declared class, which means that extending is not considered using it as an interface. This lint is about enforcing that the interface is only used as an interface.
So no exception.

  • an interface class that is not also abstract

Should have no effect if there is no generative constructor, and required if there is any abstract instance member (what must be abstract, so any instance member at all.)
But does prevent invoking a default constructor.
So sure.

  • creating an instance of an interface

Redundant with not allowing generative constructors and being abstract.

Might also want:

  • must not extend another class. (No extends or with clause.)

Otherwise the interface can inherit concrete instance members.

@mmcdon20

This comment was marked as resolved.

@mmcdon20
Copy link
Author

mmcdon20 commented May 5, 2024

I have updated the proposal to account for @lrhn's feedback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants