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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions