Update: As a clarification by "get rid" of the annotation I mean suppressing the warnings the analyzer throws without changing anything in the analyzer itself
I'm extending a class with an annotation and I want to override the parent class annotation, more particularly, get it rid of it. Is it possible to do so?
For example:
#immutable
class A {}
/// get rid of #immutable annotation
class MutableA extends A {}
Annotations have no semantics in the Dart language itself, they mean what the tools recognizing them decide that they mean.
Annotations are never inherited. If you check using dart:mirrors, annotations only exist where they are written in the source code. Annotations are on declarations, not values.
So, if a tool recognizing #immutable, and it decides that the property of being "immutable" is "inherited" by subclasses, then that's that tool's decision.
The immutable annotation is documented as applying to "all subtypes".
From the language perspective, there is no #immutable on MutableA, it's all in the head of the tool, so there is not annotation to get rid of. The meaning of the annotation on A is that all subclasses of A must be immutable.
The message that you get from the analyzer is a hint. You can suppress hints in various way, for example by adding an "ignore" comment before the line causing the hint.
In this case, you can add
// ignore: must_be_immutable
on the line before the class declaration of the subclass which is not immutable. That should suppress the hint.
Related
When using Dagger 2, very often I'm applying the following pattern:
Create interface, let's call it LoginService
Create the only one implementation - LoginServiceImpl with the constructor injection:
class LoginServiceImpl implements LoginService {
#Inject LoginServiceImpl() {}
}
Bind the implementation to the interface:
#Binds
abstract LoginService bindStatisticsService(LoginServiceImpl impl);
Always depend on the interface - LoginService in this case.
Is there a possibility to avoid the #Binds annotated method? Is there a simpler (with the less amount of boilerplate code) way to tell Dagger - this class is the only one implementation of the interface, always bind it for example in some annotation on the interface itself?
I've read the documentation and unfortunately haven't found anything like that, but maybe someone knows some trick which can solve my problem.
I don't think that's possible, even hypothetically.
Dagger can't really tell that there's only one implementation, and the only way it could would be to search for every class on the (compilation) classpath to try to find all sorts of possible implementation. That would be slow at best, but Java allows classloading from custom classloaders, so you aren't ever really guaranteed to get a full list of available classes. Even if you were to claim that Dagger should just match against the first appropriate assignable type it sees (because you know that there's only one), Dagger may not have a way to identify where to find that implementation type.
Ultimately it's going to be difficult to improve on a single-line #Binds statement that identifies the fully-qualified class of the binding key (your.package.name.LoginService) and target (your.package.name.LoginServiceImpl).
IDE recognised StoreWatcher Flutter Widget as immutable. Where is that #immutable annotation? It is not in the store_watcher.dart source code.
The annotation is from the meta package
The docs say
Used to annotate a class C. Indicates that C and all subtypes of C
must be immutable.
A class is immutable if all of the instance fields of the class,
whether defined directly or inherited, are final.
Tools, such as the analyzer, can provide feedback if
the annotation is associated with anything other than a class, or a
class that has this annotation or extends, implements or mixes in a
class that has this annotation is not immutable.
Not all annotation cause the expected feedback yet.
Some might need to enable linter rules.
For some it might only planned yet to be supported eventually by the analyzer or the linter.
I have a method that takes type parameters with an implicit view bounds on them. Can I use the #implicitNotFound annotation to give nicer compiler errors when the method is called with invalid data types?
The documentation for the method is useless and even the source code doesn't help, and all the examples of use online are at the trait or class level.
No, you cannot directly do that. As you’ve noticed, #implicitNotFound annotates traits or classes. You could, however, make a special implicit type just for that method and annotate it if you really wanted to have a custom message.
Why is the "abstract" keyword for class definition optional in Scala, and how do I force the Scala compiler to tell me when my class is abstract?
Here an example that I wrote in Eclipse:
class Toto[T] {
def get(index: Int): T
}
object Toto {
def create[T]: Toto[T] = new Toto[T]
}
This seems to be a perfectly valid class definition in Scala, although it does NOT define the required get method, and is NOT prefixed with abstract. If you don't need the abstract keyword, then why does it exist? And if you want to be told that your class is actually abstract, how do you get the compiler to tell you?
This is not valid scala code, abstract is required, and instanciation forbidden. From the spec (5.2, p63):
The abstract modifier is used in class
definitions. It is redundant for
traits, and mandatory for all other
classes which have incomplete members.
Ab- stract classes cannot be
instantiated (§6.10) with a
constructor invocation unless
followed by mixins and/or a refinement
which override all incomplete members
of the class. Only abstract classes
and traits can have abstract term
members.
The code produces an error in the REPL : error: class Toto needs to be abstract, since method get is not defined
I get the proper behavior with the same message in Eclipse too. You should check whether you get the same error with and without eclipse. Whichever is true, I guess if you have exactly the code you posted without an error (does it run?), a bug repport will be warranted.
To answer my own question: In Eclipse, you can only tell if a class is correct if all other classes compile without errors! In other word, you can't trust anything Eclipse says about a class unless there are no errors in other classes.
So if you have errors in several classes, then there is no way of knowing which ones are the real errors, and neither if a class without errors is correct.
You just have to repeatedly loop on the errors, fixing any one that makes sense, and hoping the others errors that don't make sense are eventually going to just disappear.
In Eclipse, after I added one abstract method in my abstract class, is there a way to ask Eclipse add an empty implementation in all subclasses of that abstract class?
You can select the "type Foo must implement inherited abstract bar()" in the problems view, select Quick Fix from the context menu and apply the fix to all affected classes. However, they will only get the empty method stub so I'm not aware of a way to add the same implementation body to all subtypes.