fragmentargs icon indicating copy to clipboard operation
fragmentargs copied to clipboard

Hiding bugs when renaming Args

Open gabrieloshiro opened this issue 6 years ago • 0 comments

Hallo Hannes,

I really like the idea behind fragmentargs I think it solves a lot of problems when instantiating fragments.

But one thing concerns me, when I refactor an arg, renaming it, the order of the builder might change and generated code can potentially hide some errors. Here is an example of what I am trying to say:

@FragmentWithArgs
public class MainFragment extends Fragment {
    @Arg int a;
    @Arg int b;
    @Arg int c;
...
}

and the calling code is:

MainFragment fragment = MainFragmentBuilder.newMainFragment(1, 2, 3);

So now I decide to rename my variable a to z

@FragmentWithArgs
public class MainFragment extends Fragment {
    @Arg int z;
    @Arg int b;
    @Arg int c;
...
}

And my calling code still compiles, but now it is wrong semantically because instead of a, b, c, it is now receiving b, c, z

MainFragment fragment = MainFragmentBuilder.newMainFragment(1, 2, 3); // Compiles with no problem

If you always use the builder pattern you can solve this problem. Let's go through the same issue but now using a builder.

@FragmentWithArgs
public class MainFragment extends Fragment {
    @Arg(required = false) int a;
    @Arg(required = false) int b;
    @Arg(required = false) int c;
...
}

and we change the calling code like this:

MainFragment fragment = new MainFragmentBuilder().a(1).b(2).c(3).build();

All good, life is pretty. But now I want to rename a to z. The moment I perform the following changes

@FragmentWithArgs
public class MainFragment extends Fragment {
    @Arg(required = false) int a;
    @Arg(required = false) int b;
    @Arg(required = false) int c;
...
}

I get the following error message:

Error:(17, 62) error: cannot find symbol method a(int)

Which is exactly what we want. We want to break the code in compilation time to tell the developer "whatever you did somewhere else, you broke the code here". This is, by the way, the exact same behaviour of library Dart.

So my questions here are:

  • Why mix the way we pass arguments via constructor and via builder?
  • Why not simply use the builder for everything? If @Args are not required, then the builder does not need to have to validate them when build is called.
  • Have you considered this and would you be open for a PR that transforms all generated code into a builder?

gabrieloshiro avatar Sep 15 '17 20:09 gabrieloshiro