How do i restrict usage of my custom annotation? (dart) - dart

When i have a custom annotation like this:
class FieldAnnotation{
const FieldAnnotation();
}
How do i restrict the usage of that annotation to only be applied on fields. Specifically, how do i generate a warning or an error on static analysis?
#FieldAnnotation() // should show a warning or an error
class Test{
#FieldAnnotation() // should have no problems
final String id;
Test({required this.id});
}

I hoped, someone had already answered your question. I'm also searching for more detailed information about custom dart annotations.
But perhaps i have found the answer inside the meta package - in meta-meta.dart - to be precise.
As I understand, you can annotate your custom annotation class (annotation definition, not the annotated elements) with #Target(targets) where targets is a Set<TargetKind> where TargetKind is an enum.
Also interesting to see, that it is possible to write an extension on an enum what they did with TargetKind.

Related

Why is #override annotation optional?

I understand definition of an #override annotation.
But, why is the usage of the annotation optional?
From the documentation:
The intent of the #override notation is to catch situations where a superclass renames a member, and an independent subclass which used to override the member, could silently continue working using the superclass implementation.
You might want to name your method equal to the super class without explicitely overriding it. This is allowed as it does not break any constraints.
Basically you can name your methods whatever you want.
#Override only enforces, that one of your parents has to have a method with the same signature.
The annotation wasn't made part of the language because the language designers didn't want to enforce its use.
It has been added as an optional annotation for people who want the feature, but it's only recognized by the analyzer tool, it's not actually part of the language.
You can enable a linter rule to enforce it
http://dart-lang.github.io/linter/lints/annotate_overrides.html
by adding an .analysis_options file to your project besides the pubspec.yaml file with this content
linter:
rules:
- annotate_overrides
Because the name of the method is looked up in the inheritance chain: for example, let's look at this inheritance chain:
A
|
B
|
C
if we create an instance using class C and invoke a method test(), then the definition of test is first looked in the body of class C, then class B, then class A. Thus, the overriding effect is automatically implied.
The effect is similar to what observed in C++, and for a detailed read please check out this link:
https://isocpp.org/wiki/faq/strange-inheritance#hiding-rule
The reason of the existence of the annotation is clearly stated above by Abaddon666.

Dart Polymer 1.0 Behavior - method not found & getters required

I wanted to write a simple behavior in Dart to be used by a custom element.
#behavior
abstract class AlignmentBehavior implements PolymerBase {
#Property()
bool alignTop = false;
// more properties ...
ready() {
updateAlignment();
}
#reflectable
updateAlignment([_,__]) {
// reference to the element the Behavior is attached to.
// 1) Is that the correct way?
var ele = Polymer.dom(root);
// We need to inherit from PolymerBase to access set(...)
// 2) Is that the correct way?
set('alignTop', aTop);
// .. to more stuff
}
}
My first two questions are already written in the code. How do I access the element the behavior is attached to? What's the proper way of doing this? I currently use Polymer.dom(root) but I don't know if that even works since I have some runtime errors which I am going to explain later in this post. What is the official way of accessing the underlying element? Is it using the JsObject? Is it calling a Behavior function from the parent PolymerElement and pass this, or should you not access it at all?
Another question is whether I have to inherit from PolymerBase or not. The Behavior example at the Github wiki doesn't do so, but in order to access methods such as set to modify a #Property I have to inherit from it. What's the proper way of doing so?
My last two questions are about errors I get. One error asks me to implement getters and setters for my properties, such as adding a getter and setter for alignTop.
And last but not least, I cannot invoke updateAlignment() from my custom element. It says Class 'MainApp' has no instance method 'updateAlignment'.
1)
var ele = Polymer.dom(root);
If you want to access the DOM of the element, this fine.
Just root gives you the same AFAIK.
If you want to access the elements class instance, there is nothing to do. It's this but that is implicit in Dart anyway.
You can only access what is known in the mixin. To make "things" known to the mixin you can create an interface class.
abstract class MyComponentInterface {
void someFunction();
int someField;
String get someValue;
set someValue(String value);
...
}
Then implement the interface in the mixin and the element class and you have a shared contract.
abstract class AlignmentBehavior implements MyComponentInterface, PolymerBase {
The mixin can now access the members because the implementsMyComponentInterface` claims they will exist and
class MyComponent extends PolymerElement with AlignmentBehavior {
will force you to implement it to fulfill the contract of the mixin.
2) looks fine
3)
Another question is whether I have to inherit from PolymerBase or not.
Is basically the same as 1) Any Polymer element in Dart has to extend PolymerBase. To be able to access the members of PolymerBase from within the mixin it has to implement it as well. This doesn't result in any limitations because the classes that the mixin will be applied to, will fulfill that contract anyway.
If you don't need to access any members provided by PolymerBase there is no need to implement it.

Grails: #BindUsing on a class being ignored and #BindUsing vs ValueConverter

I need to do some custom data binding and I tried to use the #BindUsing annotation on a class (http://grails.org/doc/latest/api/org/grails/databinding/BindUsing.html), however, it's being ignored. I am under the assumption that since the annotation is used on the class that would mean that every time a data binding happens and that class is involved, the BindingHelper class would be used, but it's never actually called. Is there something that I'm missing or doing wrong?
Here's the class definition where UserBinding is a class that implements the BindingHelper interface:
#BindUsing(UserBinding)
class User extends SomeOtherClass
{
...
Also am I correct in understanding that basically creating a ValueConverter and using #BindUsing on a class accomplish the same thing?
BindUsing on a class is not used often and there seems to be a bug reported around that already. [From the link] The problem could be that there are multiple request parameters with the same name it might be using the helper only for the first one.
Using a property level #BindUsing annotation should be simpler to implement and is less likely to fail (even when there are multiple entries in the params map with the same name).

Dart using Json_object to produce strong typing

Using the ideas outlined in ding the article Using Dart with JSON Web Services at https://www.dartlang.org/articles/json-web-service/, I have been trying to implement the section on using JsonObject and interfaces to produce a strong typing of JSON data.
The article indicates that one should write something like.
abstract class Language {
String language;
List targets;
Map website;
}
class LanguageImpl extends JsonObject implements Language {
LanguageImpl();
factory LanguageImpl.fromJsonString(string) {
return new JsonObject.fromJsonString(string, new LanguageImpl());
}
}
However the compiler 'fail' at the definition of the class LanguageImpl with the message
Missing inherited members: 'Language.website', 'Language.targets' and
'Language.language'
Even more confusing the code will run without a problem....
In Darteditor you get Quick fix support for this.
Set the caret at LanguageImpl and press ctrl+1 or use the context menu > Quick fix.
You get the missing concrete implementations you inherit from the abstract base class generated automatically.
Dart is a dynamic language and therefor very flexible.
The tools support you and try to give meaningful warnings and hints about what could go wrong
but don't prevent you running a program even when it is not yet finished.
You can use the #proxy annotation on the class to silent the warnings.
This also needs the class to have a noSuchMethod() implementation.

Attributes in Dart

Are there any plans to introduce attributes
for classes, methods, parameters of methods,
something like C# or Java attributes ?
[Test]
class SomeClass
{
[Test]
someMethod()
}
or
#Test
class SomeClass
{
#Test
someMethod(#Test int param)
}
For many frameworks it would be very useful
In dart, they are called metadata / annotation. The syntax is quite close to java. Here's a example :
#Test testMethod() {}
In Dart Specification you can read :
Metadata consists of a series of annotations, each of which begin with the character #, followed a constant expression that starts with an identifier. It is a compile time error if the expression is not one of the following:
A reference to a compile-time constant variable.
A call to a constant constructor.
[....]
Metadata can appear before a library, class, typedef, type parameter, constructor, factory, function, field, parameter, or variable declaration and before an import or export directive.
There're already some annotations predifined in dart:core. Particulary #override, #deprecated and #proxy.
Dart already has annotations, similar to Java in some ways, they're just not used in very many places yet, and they're not accessible from reflection yet either.
See this article: http://news.dartlang.org/2012/06/proposal-to-add-metadata-to-dart.html
Here's a brief introduction to the two metadata annotations currently available in the Dart meta library:
Dart Metadata is your friend.
This doesn't preclude you from using your own, but these are the two that have tooling integration with the Dart Editor.

Resources