Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

$R as MemberRef #496

Closed
wants to merge 4 commits into from
Closed

$R as MemberRef #496

wants to merge 4 commits into from

Conversation

sormuras
Copy link
Contributor

...or short for $T.$L 馃槈

This PR replaces/deprecates #443 - tests from there need to be merged into this PR.

$R for References

When generating code, you may point to already compiled elements like methods, fields
and especially the enum constant fields. Enter $R:

CodeBlock.builder().add("$R", Thread.State.NEW).build();

That produces the fully-qualified member name:

java.lang.Thread.State.NEW

A more complex example with ex- and implicit MemberRef creations for methods, fields, enum
constants:

Method convert = TimeUnit.class.getMethod("convert", long.class, TimeUnit.class);

MethodSpec.Builder method = MethodSpec.methodBuilder("minutesToSeconds")
  .addModifiers(Modifier.STATIC)
  .returns(long.class)
  .addParameter(long.class, "minutes")
  .addStatement("return $R.$R(minutes, $R)", TimeUnit.SECONDS, convert, TimeUnit.MINUTES);

TypeSpec util = TypeSpec.classBuilder("Util")
  .addMethod(method)
  .build();

JavaFile.builder("readme", util).build();

That generates the following .java file, complete with the necessary imports:

package readme;

import java.util.concurrent.TimeUnit;

class Util {
  static long minutesToSeconds(long minutes) {
    return TimeUnit.SECONDS.convert(minutes, TimeUnit.MINUTES);
  }
}

$R lets you reference static members:

  • enum constants, like e.g. TimeUnit.MINUTES above
  • static fields, like String.CASE_INSENSITIVE_ORDER
  • static methods, like Class.forName(String)

References to instance members are also supported. Here, it's up to you providing some object
as a call target. You can use any literal including "this", "super", TypeNames and
even MemberReferences like can be seen with TimeUnit.SECONDS in the example above.

The MemberRef API allows optional type arguments as parameters. Those can be used to specify
the generic return type of a method:

MemberRef emptyList = MemberRef.get(Collections.class.getMethod("emptyList"), String.class);
CodeBlock.builder().add("$R()", emptyList).build();

Which yields:

java.util.Collections.<java.lang.String>emptyList()

@sormuras
Copy link
Contributor Author

Will try it next yea$R. Again. (-:

@sormuras sormuras closed this Nov 15, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant