Dart Multiple Annotations & source_gen - flutter

I'm trying to create a package for Flutter that provides source generation using source_gen. I would like to be able to annotate a class and fields to identify what needs to be generated. (An example of this would be the libraries Dagger2 or ROOM, for java.)
Given an abstract class:
#ServiceCalls("http://www.whocares.com")
abstract class ServiceCalls
#Get
int getCount();
#Post
void postCount(int count);
}
The following concrete implementation would be generated:
class ServiceCallsImp extends ServiceCalls {
Future<int> getCount() {
// details for implementing a get service call
}
Future<void> postCount(int count) {
// details for implementing a post call
}
}
So, the big questions I'm trying to answer are:
1) Is an abstract class the way to go, or is a part the correct approach?
2) How do I setup builders for a 'recursive' annotation processing? (Annotated fields in an annotated class)
NOTE: I don't really care about service calls, its just an example.

Related

why do we use abstract classes in clean architecture?

we have abstract classes in clean architecture where we just define functions and then write the whole code in an implementation class that implements those functions.
why not use only the second function?
abstraction
abstract class PriceTrackerDataSource {
Stream<dynamic> getActiveSymbols();
}
implementation
class PriceTrackerDataSourceImpl implements PriceTrackerDataSource {
#override
Stream<dynamic> getActiveSymbols() async* {
if (_ws != null) {
await _ws!.sink.close();
}
_connect();
yield* _ws!.stream;
}
Abstract classes are used to make each layers more independent (data, domain, presentation). And also to define main methods for the own classes
Abstract classes help us to define a template / common definition for our multiple derived classes also reducing code duplication.
Making the class abstract ensures that it cannot be used on its own, but the details must be defined in the derived class implementation.
For more explanation you can have a look at Dart Docs.

How to set a custom property for conditional import in Dart?

Dart allows to use the standard library names for conditional import/export, like this:
export 'src/hw_none.dart' // Stub implementation
if (dart.library.io) 'src/hw_io.dart' // dart:io implementation
if (dart.library.html) 'src/hw_html.dart'; // dart:html implementation
Is it possible to define a custom property/condition? For example, pass it when compiling.
I have a project that I would like to split into two variants: Flutter variant and pure Dart variant. The choice of the variant depends at compile time, and the necessary implements of abstract classes defines at compile time.
Custom properties where an experimental feature in Dart 1. With Dart 2 there is no longer any support for user defined custom conditions in compile time.
Here is the discussion referencing your question.
All you can do is, switch between implementations on run time:
abstract class SomeFactory {
String get message;
factory SomeFactory() {
if(Platform.environment['SOME_VAR'] != null)
return new _SomeImplementation();
return new _SomeOtherImplementation();
}
}
class _SomeImplementation implements SomeFactory {
#override
String get message => 'SomeImplementation';
}
class _SomeOtherImplementation implements SomeFactory {
#override
String get message => "OtherImplementation";
}
Check this blog entry for more details.

How to override main abstract methods from mixins

As you see in example,
I have Core class for distribute the shared variables/methods etc. into the mixins.
Abstract class for defining necessary methods, providing summary about api.
Main class for importing everything like a provider.
There isn't any runtime error of course.
Problem with this approach, mixin methods does not recognize #override annotation.
I want to create granular, clean structure for my packages. What is the best approach for this situation or what is the mistake I'm doing?
abstract class AbstractCore {
void foo();
void bar();
}
class Core {
var shared;
}
mixin Feature1 on Core {
#override // not recognized by syntax of course
void foo() {
// something with [shared]
}
}
mixin Feature2 on Core {
#override // not recognized
void bar() {
// yet another thing with [shared]
}
}
class Main with Core, Feature1, Feature2 implements AbstractCore {}
You can accept like:
Core: ApiBase(For sharing Client object, constants, keeping dispose method...)
Feature1: let's say Authentication related Api calls
Feature2: let's say Content related Api calls
Main: Api provider.
Annotations don't have any impact on what the code do. They are just used for readability and tooling.
In your care, it is the analyzer that is complaining about #override, because you're not overriding anything.
Simply remove the #override decorator — it wasn't needed to begin with.

Is it possible to find all classes annotated with #MyAnnotation using a GWT GeneratorContext?

While creating classes using Generators, it's possible to discover all subclasses of a type. You can find this technique for example in the GWT Showcase source (see full code):
JClassType cwType = null;
try {
cwType = context.getTypeOracle().getType(ContentWidget.class.getName());
} catch (NotFoundException e) {
logger.log(TreeLogger.ERROR, "Cannot find ContentWidget class", e);
throw new UnableToCompleteException();
}
JClassType[] types = cwType.getSubtypes();
I would like to do something similar, but instead of extending a class (or implementing an interface)
public class SomeWidget extends ContentWidget { ... }
, could I also do this by annotating Widgets?
#MyAnnotation(...)
public class SomeWidget extends Widget { ... }
And then finding all Widgets that are annotated with #MyAnnotation? I couldn't find a method like JAnnotationType.getAnnotatedTypes(), but maybe I'm just blind?
Note: I was able to make it work with the Google Reflections library, using reflections.getTypesAnnotatedWith(SomeAnnotation.class), but I'd prefer using the GeneratorContext instead, especially because this works a lot better when reloading the app in DevMode.
Yes - easiest way is to iterate through all types, and check them for the annotation. You might have other rules too (is public, is non-abstract) that should also be done at that time.
for (JClassType type : oracle.getTypes()) {
MyAnnotation annotation = type.getAnnotation(MyAnnotation.class);
if (annotation != null && ...) {
// handle this type
}
}
The TypeOracle instance can be obtained from the GeneratorContext using context.getTypeOracle().
Note that this will only give you access to types on the source path. That is, only types currently available based on the modules being inherited and <source> tags in use.

Does Google Dart support mixins?

I've skimmed through the language documentation and it seems that the Google Dart does not support mixins (no method bodies in interfaces, no multiple inheritance, no Ruby-like modules). Am I right about this, or is there another way to have mixin-like functionality in Dart?
I'm happy to report that the answer is now Yes!
A mixin is really just the delta between a subclass and a superclass. You can then "mix in" that delta to another class.
For example, consider this abstract class:
abstract class Persistence {
void save(String filename) {
print('saving the object as ${toJson()}');
}
void load(String filename) {
print('loading from $filename');
}
Object toJson();
}
You can then mix this into other classes, thus avoiding the pollution of the inheritance tree.
abstract class Warrior extends Object with Persistence {
fight(Warrior other) {
// ...
}
}
class Ninja extends Warrior {
Map toJson() {
return {'throwing_stars': true};
}
}
class Zombie extends Warrior {
Map toJson() {
return {'eats_brains': true};
}
}
Restrictions on mixin definitions include:
Must not declare a constructor
Superclass is Object
Contains no calls to super
Some additional reading:
http://www.dartlang.org/articles/mixins/
http://blog.sethladd.com/2013/03/first-look-at-dart-mixins.html
Edit:
The Dart team have now released their proposal for Mixins, the original issue for Mixins was here.
It's not implemented yet, but in the meantime I've released an extensible Mixins library for Dart which includes a port of the popular Underscore.js functional utility library: https://github.com/mythz/DartMixins