8

I've created an Annotation

/**
 * Highlights this method is declared in XML
 */
public @interface FromXML {
}

I'm using this on methods that look like this:

@FromXML
public void onSomethingClick(View v){

}

The v variable is needed by the Android reflection system to call this method. However the input var v is unused, so my IDE warns me of this. I like this warning and want it on for the rest of my code.

enter image description here

To hide the warning I could do

@SuppressWarnings("unused")
@FromXML
public void onSomethingClick(View v){

}

or I could add a param tag

But I would rather that the IDE (eclipse) reads my @FromXML annotation and doesn't give me the warning.

I know you can't extend an Annotation, but thats basically what I want to do.

Is there a way I can add my annotation to be recognised as a 'suppress warnings' annotation.

or

Is there a way to code my annotation to 'act like' suppress warnings?

Community
  • 1
  • 1
Blundell
  • 75,855
  • 30
  • 208
  • 233
  • I'm not sure but i think that this article : http://technicalmumbojumbo.wordpress.com/2008/01/13/java-custom-annotations/ has a solution, something about the @Retention – eric.itzhak Nov 28 '12 at 12:10
  • 1
    Your custom annotation and the 'v' parameter has nothing to do with each other. Don't mess the thing by "making your custom annotation act like a suppresswarnings annotation'. From the language scope, the IDE is very right warning you about the unused parameter, because one or more incoming data is ignored. – gyorgyabraham Nov 28 '12 at 13:51
  • @gyabraham I'm making the annotation be used in places where I will only ever have one input var on the method. So I **do** want them to have to do with each other. (If it had 0 vars or more than 1 var that could potentially give an error). – Blundell Nov 28 '12 at 15:42
  • 1
    I understand your problem. Your method signatures must conform to the Android specifications, otherwise it will fail. (not actually using the parameter is another question). You must include a suppresswarnings annotation each time, you can't do any better, because Google is forcing this strange construct. – gyorgyabraham Nov 29 '12 at 14:06
  • @Blundell Android Lint already checks if `android:onClick` attribute in layout definition has proper method name which is present in the Activity which uses that layout. – MeTTeO Dec 04 '12 at 17:41
  • @MeTTeO yep it does now .. it still doesn't highlight in the Activity that that is why the method is there – Blundell Dec 04 '12 at 17:49

3 Answers3

11

You can always create a plugin for Eclipse, that would scan through the source and find these annotations in your case @FromXML and add an extra annotation in your case @SuppressWarnings.

You could create a Command for it and when that command is fired you would run this plugin.

Creating Eclipse Plugin

Hope this helps.

UPDATE - IT WAS A FLUKE CANNOT BE DONE USING THIS (TRIED IT):

Or Using AspectJ for removing the warnings Adding warnings in Eclipse using AspectJ

This tutorial uses AspectJ for adding warnings to eclipse if developer uses System.out.println() in the code. So the reverse can be done to remove the warning when annotation is present.

UPDATE 2: There is a way in Eclipse to create custom annotation processor or editting the bundeled annotation processor (that generates the unused variable warning). So will have to tweak that processor in a custom way.

Some great links:

Tutorials for Eclipse Annotation processor development

Java Development Tools - Annotation Processing Tools

Community
  • 1
  • 1
Narendra Pathai
  • 41,187
  • 18
  • 82
  • 120
  • I wouldn't want to the plugin to change my source code. I would want the plugin to notice my Annotation and not give the warning. An example of this would be nice. – Blundell Dec 05 '12 at 12:34
  • These are some links to tutorials for Eclipse Annotation processor developments which should help us. Trying to tweak the code of bundled annotation processor with eclipse. – Narendra Pathai Dec 05 '12 at 16:28
  • 2
    Gone through the bundled annotation processor with eclipse and seems like changing some classes will do the trick! You will need to check out the source of APT for eclipse using above link. Then change some classes that I think are needed to make requirement work, build the APT again and replace it for the old one. I am doing the same but takes time to get used to. Looks definitely possible! – Narendra Pathai Dec 05 '12 at 22:49
7

I think you could create an interface defining this method. That way, your class will override the method and there should not be any warning.

FromXML.java:

public @interface FromXML {
}

MyInterface.java:

public interface MyInterface {
    @FromXML
    public void onSomethingClick(View v);
}

MyClass.java

public MyClass implements MyInterface {

    @Override
    @FromXML
    public void onSomethingClick(View v){
    }
}

EDIT : Another solution could be to define your method as abstract. Indeed, as I understand your code, your methods are just declaration (Implementations are in a XML file). So, your problem is more a design problem than an IDE problem (your IDE is just right about the warning). The reality is that your method is abstract and is defined somewhere else.

Thus, defining your method as abstract will solve the problem but you'll have to make the class abstract:

public abstract class MyClassUsingOnSomethingClick {

/*
 * All the class implementation can be here as the normal class.
 */

    @FromXML
    public abstract void onSomethingClick(View v);

}

I know you'll say that this solution make it impossible to create object easily but you'll have two solutions then:

1 - Create your objects inline:

MyClassUsingOnSomethingClick a = new MyClassUsingOnSomethingClick() {
    @Override
    @FromXML
    public void onSomethingClick(View v) {}
};

2 - Create a factory method in your abstract MyClassUsingOnSomethingClick:

public static final MyClassUsingOnSomethingClick createEmptyMyClassUsingOnSomethingClick() {
    return new MyClassUsingOnSomethingClick() {
        @Override
        @FromXML
        public void onSomethingClick(View v) {}
    };
}

// and then, create with: :
MyClassUsingOnSomethingClick a = MyClassUsingOnSomethingClick.createEmptyMyClassUsingOnSomethingClick();

Even is I understand that you would prefer a faster solution, I believe that this solution is the cleanest because:

  1. It respects the Object Oriented Programming philosophy.
  2. It is not specific to an IDE.
  3. It avoids Annotation Processing Tool (which, in my opinion should be used very wisely)
ncenerar
  • 1,517
  • 12
  • 25
  • It's not the method that's unused, it's the variable `v`. – atamanroman Nov 30 '12 at 10:44
  • By the way, if this method should always be assigned this annotation, I think you can even write the annotation directly into the interface. – ncenerar Nov 30 '12 at 10:45
  • Yes but since there is no "parameter unused warning" for overridden method, it will do the trick. – ncenerar Nov 30 '12 at 10:46
  • Ok I see. Depends on the setting `Ignore in overriding and implementing methods` then. – atamanroman Nov 30 '12 at 10:50
  • @NicolasCenerario It's not a common interface, because the method name is different everytime amongst different use in different classes – Blundell Nov 30 '12 at 10:52
  • Yes and you need to create an interface for each `on....Click` method that you use. – ncenerar Nov 30 '12 at 10:55
  • @NicolasCenerario still has the same issue I want to use the `@FromXML` attribute instead of `@SuppressWarnings` / (`@Override` is a workaround) not alongside either of them. – Blundell Nov 30 '12 at 11:27
  • @NicolasCenerario IF I create inline object I no longer need to declare my onClick in XML and can just use `view.setOnClickListener` thanks anyway. I think I'm going to answer this question myself and explain what you can and can't do with annotations – Blundell Dec 05 '12 at 09:44
4

Ok I can't do this in any easy way or form.

Looking at the annotation package http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/annotation/package-summary.html

I can't extend an annotation: Why is not possible to extend annotations in Java?

I can't implement another annotation java.lang.Override

I can't mimic / mock / pretend to be @Override

If I add @Override to my @FromXML it is NOT inherited down the chain.

The only way would be to create an Eclipse plugin that recognises my annotation and stops the warning. Shame because I can't find an easy way to do this.

I also went down the route of creating an interface for my @FromXML entry points, this was very nice and communicated my Activity was of a type and therefore I didn't need the annotation anymore, perhaps this design change is the answer.

Community
  • 1
  • 1
Blundell
  • 75,855
  • 30
  • 208
  • 233