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.
Related
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.
I would like to write test for a controller class. The controller class takes a service object as constructor parameter. Added the #Inject annotation to the constructor of the service class.
class AssociateService #Inject()(configuration: Configuation){...}
The constructor parameter of the service class is a custom configuration object also created for the application. I added the #Inject to the constructor of the config class as well. Now I'm getting these types of error messages:
No implementation for "className" was bound.
Could not find a suitable constructor in java.lang.Integer. Classes must have either one (and only one) constructor annotated with #Inject or a zero-argument constructor that is not private.
The configuration class has several constructor parameters, those are "basic" types (Int, Boolean) and one parameter is a custom class type (className).
How should I do this binding or is it just enough to annotate something else?
And why it says that constructor error message?
As far as I know, there are two ways with tests and guice, with trade offs:
Don't using field injections, using only constructor injections and fields assignment in constructor for injected parameters. This approach enables very simple solution for testing, just don't use dependency injection in tests. But all your classes must have ability to be created with new operator in test cases...
Ps. You can define optional constructor and use field injections, of course, but it is not very clear solution.
Creating correct module with injectable interfaces binding to its implementations for every test or group of similar tests. Sometimes this approach takes a lot of unnecessary working hours.
You must design your software to maintain testability. Sometimes not every line of code in project need to be tested, sometimes not every code is testable, you must separate it from important parts of your software, that requires testing. If you design your software with single responsibility principe so writing tests is much easer...
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).
I was going through basics of UVM tutorials. Everywhere I read the transaction objects are always extended from uvm_sequence_item and not uvm_transaction since uvm_sequence_item has additional features like transaction id, etc. If that is the case, why is the uvm_transaction class even there in the UVM class hierarchy?
Who is using uvm_transaction other than uvm_sequence_item extending from it?
Is it because of legacy?
This is what the UVM Class Reference says about this:
"The uvm_transaction class is the root base class for UVM transactions. Inheriting all the methods of uvm_object, uvm_transaction adds a timing and recording interface.
This class provides timestamp properties, notification events, and transaction recording support.
Use of this class as a base for user-defined transactions is deprecated. Its subtype, uvm_sequence_item, shall be used as the base class for all user-defined transaction types."
If you refer uvm class hierarchy (Link:[https://www.google.co.in/search?biw=1366&bih=620&tbm=isch&sa=1&btnG=Search&q=uvm+class+hierarchy#imgrc=Laxc9UWNpnGTpM%3A][1] ) then you find out that uvm_transaction parent class while uvm_sequence is child class.
So, child class can access all the property of parent class.
But parent class can not access child class property.
uvm_sequence_item has its own functionality like get_sequencer_id,set_sequencer_id, get_root_sequence.
These methods used by sequencer internally in case of layer sequences.
You call sequence by start method, uvm_do family or config_db.
Each of these method call start_item(req) and finish_item(req).
task start_item(uvm_sequence_item item)
task finish_item(uvm_sequence_item item)
If you observes data type in first argument in both the function is uvm_sequence_item.
There are total eight uvm classes.
(1) uvm_driver.svh
(2) uvm_push_driver.svh
(3) uvm_sequencer.svh
(4) uvm_push_sequencer.svh
(5) uvm_sequencer_library.svh
(6) uvm_sequencer_analysis_fifo.svh
(7) uvm_sequence.svh
(8) uvm_sequencer_param_base.svh
These classes are parameterized with uvm_sequence_item not with uvm_transaction.
If you use uvm_transaction instead of uvm_sequence_item then ti will shout an error(set_sequence_id not found which is property of uvm_sequence_item not uvm_transaction ) from uvm_sequencer_param_base.svh.
So, communication of sequence,sequencer and driver is not completed.
In most of the cases which I observe if you have a code in which you are not going to use uvm_sequencer then you can use uvm_transaction it will not shout an error.
But if your code contains uvm_sequener and you use uvm_transaction then it will shout an error (Could not find member 'set_sequence_id').
Note that from uvm_transaction class, uvm_sequence_item as well as uvm_objects are inherited. So, the static behaviour and non-static behaviour (so to say) class hierarchy all starts from uvm_transaction.
Now, I can add whatever functionality I want to, to uvm_sequence_item so that every inheritor of uvm_sequence_item can get this. I can do this without modifying uvm_transction_item. Otherwise, any change in uvm_transaction would lead to unwanted functionality in the component class hierarchy (static behaviour) and can even lead to unintended side effects.
PS: one of the difference between other OOPs languages and SV is that multiple inheritance is not allowed in SV. For example, in case of C++, I can inherit from 2 classes in a new class. This is not allowed in SV. So, the only way one can get the properties of uvm_transaction as well as from uvm_sequence_item is by inheriting from uvm_sequence_item. This maybe the source of your confusion.
Just to be sure, has Dart removed explicitly defining an interface now in favor of implicitly defining it via abstract?
I see it mentioned in Dart and Interface Segregation Principle, however I'm also finding a lot of content still referencing the explicit definition, such as When to use interfaces in Dart?
Yes. The interface keyword was removed from Dart. Instead all classes have implicit interfaces. So if you want to define an interface you can use an abstract class instead.
See this blog post from 2012 about eliminating the interface keyword.