Skip to content
This repository was archived by the owner on Feb 26, 2023. It is now read-only.
This repository was archived by the owner on Feb 26, 2023. It is now read-only.

Compilation fails for methods annotated with @ServiceAction that have the same name as one of their parameters #1070

@kutsal

Description

@kutsal

Given an @EIntentService like so:

@EIntentService
public class FooIntentService extends IntentService {
  @ServiceAction
  public void foo(Object foo) { /* ... */ }
}

Compilation fails annotation processing with the following error, which is misleading:
error: method foo(Object) is already defined in class IntentBuilder_

This is because the generated code in FooIntentService_.java has this bit (see comments in code block):

public FooIntentService_.IntentBuilder_ foo(Object foo) {
  intent_.setAction(ACTION_FOO);
  foo(foo); // <--- Recursive call!!!
  return this;
}

public FooIntentService_.IntentBuilder_ foo(Object foo) { // <--- Because of this
  intent_.putExtra(FOO_EXTRA, ((Serializable) foo);
  return this;
}

And when the parameter name is changed, the Extra is properly passed.

public FooIntentService_.IntentBuilder_ foo(Object bar) {
  intent_.setAction(ACTION_FOO);
  bar(bar); // <--- Happy now
  return this;
}

public FooIntentService_.IntentBuilder_ bar(Object bar) { // <--- Because, this.
  intent_.putExtra(BAR_EXTRA, ((Serializable) bar);
  return this;
}

Since the @EIntentService usage is defined as:

FooIntentService_.intent(getContext()).foo(new Whatever()).start();

I think having public accessors for the Extras generated from the parameters of the annotated methods is unnecessary. They only pollute the IntentBuilder_s namespace since they'll never be used directly.

I think a better way to do this would be, in this case, to make those Extras private, and use a different naming scheme while generating them so they won't collide with the annotated methods...

Or, maybe changing the usage to something like the following is better?

FooIntentService_.intent(getContext()) //
    .foo(/* NO PARAMETERS */).bar(new Whatever()) // .bar() is really the parameter to .foo()
    .start();

so those Extra methods handling the parameters would make sense.

Either of those, or @ServiceAction annotation's processor might warn users when it's placed on a method that has a parameter name the same as its name.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions