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’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support for lambda functions #6

Closed
wants to merge 10 commits into from
Closed

Conversation

HliasMpGH
Copy link
Contributor

*testing
*documentation

*add lambda with body feature
*add overloads of lambda creation
*add testing
*add javadoc documentation
@HliasMpGH
Copy link
Contributor Author

HliasMpGH commented Apr 18, 2024

This PR issues changes such as:

CodeBlock & MethodSpec:
-addLambda() overloads used for constructing different types of lambda functions.
-testing for different cases.

A plugin addition to the build, used for producing javadoc from source.
Some reformatting of variable declaration and javadoc.
A bug fix on TypeSpec where an overload of addPermits(), created an infinite recursion.

@@ -609,7 +609,7 @@ public Builder addSuperinterface(Type superinterface, boolean avoidNestedTypeNam
public Builder addPermits(Iterable<? extends TypeName> permits) {
checkArgument(permits != null, "permits == null");
for (TypeName permit : permits) {
addPermits(permits);
addPermits(permit);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I'd put this in a separate commit as it's not related to this commit

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Must have missed it while squashing my commits, sorry for the inconvenience. Thanks!

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you pushed latest? I'm still seeing this in the 1 commit.

@Randgalt
Copy link
Owner

Randgalt commented Apr 18, 2024

Thanks - I'll review as I have time. I'm not very familiar with the JavaPoet code base but I'll do my best. Maybe we can get some others to review from the community.

@@ -135,6 +135,16 @@
<build>
<pluginManagement>
<plugins>
<plugin>
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this needed? If just personal preference please put in a separate commit with its own comment.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will make sure that every change apart from the lambdas will be in a separate commit

* @param args the values that should be placed in the holders
* of the format.
*/
public Builder addLambda(List<ParameterSpec> parameters, String expressionFromat, Object... args) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spelling: expressionFromat should be expressionFormat (multiple places)

// the inputs of the lambda (left side)
String inputSide = String.join(
", ", parameters.stream()
.map(p -> p.toString())
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can be: .map(ParameterSpec::toString)

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whole thing can be:

Suggested change
.map(p -> p.toString())
String inputSide = parameters.stream()
.map(ParameterSpec::toString)
.collect(Collectors.joining(", "));

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, i see. Thank you for pointing it out!

// check that the input types are valid
for (ParameterSpec parameter : parameters) {
checkArgument(!parameter.type.equals(TypeName.VOID),
"lambda input parameters cannot be of void type!");
Copy link
Owner

@Randgalt Randgalt Apr 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: the rest of JavaPoet messages do not use !

* @param parameters the input parameters of the function.
* @param body the body of the function.
*/
public Builder addLambda(List<ParameterSpec> parameters, CodeBlock body) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be consistent with the rest of JavaPoet these should be Iterable<ParameterSpec>. You can convert to a stream via:

Stream<ParameterSpec> parameterSpecStream = StreamSupport.stream(parameters.spliterator(), false);

* @param args the values that should be placed in the holders
* of the format.
*/
public Builder addLambda(List<ParameterSpec> parameters, String expressionFromat, Object... args) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above, make Iterable to match rest of the library

@Randgalt
Copy link
Owner

I have a general comment about this. I think we should consider a more complete solution. Right now, this modifies CodeBlock and generates a lambda like this:

(double y) -> {return x + y;}

This is good but not ideal. If I were to write the above lambda, I'd write:

y -> x + y;

Instead of modifying CodeBlock with addLambda we probably need a LambdaSpec similar to MethodSpec that can analyze the parameters, return type, etc. and build a lambda more like what developers expect.

wdyt?

@HliasMpGH
Copy link
Contributor Author

HliasMpGH commented Apr 27, 2024

I have a general comment about this. I think we should consider a more complete solution. Right now, this modifies CodeBlock and generates a lambda like this:

(double y) -> {return x + y;}

This is good but not ideal. If I were to write the above lambda, I'd write:

y -> x + y;

Instead of modifying CodeBlock with addLambda we probably need a LambdaSpec similar to MethodSpec that can analyze the parameters, return type, etc. and build a lambda more like what developers expect.

wdyt?

You are right. My initial thought was to follow the LambdaSpec class idea, and that would be required if we want to allow code like

x -> x + 3;

The reason i avoided the idea was because it appeared to me that maybe it wouldnt fit with the rest of the Spec's of the project and was an an overkill to have a separate class for that, thats why i went through with the current implementation. That doesnt mean though that LambdaSpec cant be a thing, and since you propose it as well, i can make the changes needed to support it. My idea of the final code will be something like this:

ParameterSpec consumerLambda = ParameterSpec.builder(
	ParameterizedTypeName.get(
				ClassName.get(Consumer.class),
				TypeName.get(Integer.class)
			),"consumer"
		).build();

ParameterSpec p = ParameterSpec.builder(TypeName.INT, "x").build();

CodeBlock body = CodeBlock.builder().add("x + 5").build();

LambdaSpec lambda = LambdaSpec.builder(consumerLambda).addInput(p).addBody(body).build();

that will output something like this:

Consumer<Integer> consumer = x -> x + 5;

or

LambdaSpec lambda = LambdaSpec.builder().addInput(p).addBody(body).showTypes().build();

to produce:

(int x) -> x + 5;

for more general use (for example if we need to pass it as input to a method).

We would then have methods such as addLambda(LambdaSpec) in CodeBlock, that would be used for the final construction.

Does that make sense?

@Randgalt
Copy link
Owner

@HliasMpGH I don't think a LambdaSpec builder is necessary if we can get the output to be ideal with only a CodeBlock. wdyt?

@HliasMpGH
Copy link
Contributor Author

@HliasMpGH I don't think a LambdaSpec builder is necessary if we can get the output to be ideal with only a CodeBlock. wdyt?

So you are thinking of a LambdaSpec class that does not follow the builder pattern at all? If its convenient, can you provide me with an example of the idea you propose? Thanks

@Randgalt
Copy link
Owner

Sorry, no, I meant keep what you have but make it be able to build an ideal statement. I'm not sure if it's possible.

@HliasMpGH
Copy link
Contributor Author

Sorry, no, I meant keep what you have but make it be able to build an ideal statement. I'm not sure if it's possible.

Ohh i see. Okay, i will do my best to try and add that ability.

@HliasMpGH
Copy link
Contributor Author

HliasMpGH commented May 9, 2024

Closing to reduce the pollution made from this PR. The implemented result can be seen (more clearly) in #8

@HliasMpGH HliasMpGH closed this May 9, 2024
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.

2 participants