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

Improve the handling of ExtensionMethod arguments #3155

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
24 changes: 20 additions & 4 deletions src/eclipseAgent/lombok/eclipse/agent/PatchExtensionMethod.java
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2012-2021 The Project Lombok Authors.
* Copyright (C) 2012-2022 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
Expand Down Expand Up @@ -47,6 +47,7 @@
import org.eclipse.jdt.internal.compiler.ast.Annotation;
import org.eclipse.jdt.internal.compiler.ast.ClassLiteralAccess;
import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
import org.eclipse.jdt.internal.compiler.ast.ConditionalExpression;
import org.eclipse.jdt.internal.compiler.ast.Expression;
import org.eclipse.jdt.internal.compiler.ast.MessageSend;
import org.eclipse.jdt.internal.compiler.ast.NameReference;
Expand Down Expand Up @@ -298,7 +299,7 @@ public static TypeBinding resolveType(TypeBinding resolvedType, MessageSend meth
List<TypeBinding> argumentTypes = new ArrayList<TypeBinding>();
for (Expression argument : arguments) {
TypeBinding argumentType = argument.resolvedType;
if (argumentType == null && Reflection.isFunctionalExpression(argument)) {
if (argumentType == null && requiresPolyBinding(argument)) {
argumentType = Reflection.getPolyTypeBinding(argument);
}
if (argumentType == null) {
Expand Down Expand Up @@ -338,8 +339,8 @@ public static TypeBinding resolveType(TypeBinding resolvedType, MessageSend meth
} else {
param = parameters[i];
}
// Resolve types for lambdas
if (Reflection.isFunctionalExpression(arg)) {
// Resolve types for polys
if (requiresPolyBinding(arg)) {
arg.setExpectedType(param);
arg.resolveType(scope);
}
Expand Down Expand Up @@ -377,6 +378,10 @@ public static TypeBinding resolveType(TypeBinding resolvedType, MessageSend meth
MessageSend_postponedErrors.clear(methodCall);
return resolvedType;
}

private static boolean requiresPolyBinding(Expression argument) {
return Reflection.isFunctionalExpression(argument) || argument instanceof ConditionalExpression && Reflection.isPolyExpression(argument);
}

private static NameReference createNameRef(TypeBinding typeBinding, ASTNode source) {
long p = ((long) source.sourceStart << 32) | source.sourceEnd;
Expand Down Expand Up @@ -407,6 +412,7 @@ private static final class Reflection {
public static final Field argumentTypes = Permit.permissiveGetField(MessageSend.class, "argumentTypes");
public static final Field argumentsHaveErrors = Permit.permissiveGetField(MessageSend.class, "argumentsHaveErrors");
public static final Field inferenceContexts = Permit.permissiveGetField(MessageSend.class, "inferenceContexts");
private static final Method isPolyExpression = Permit.permissiveGetMethod(Expression.class, "isPolyExpression");
private static final Class<?> functionalExpression;
private static final Constructor<?> polyTypeBindingConstructor;

Expand All @@ -432,6 +438,16 @@ public static boolean isFunctionalExpression(Expression expression) {
return functionalExpression.isInstance(expression);
}

public static boolean isPolyExpression(Expression expression) {
if (isPolyExpression == null) return false;
try {
return (Boolean) isPolyExpression.invoke(expression);
} catch (Exception e) {
// Ignore
}
return false;
}

public static TypeBinding getPolyTypeBinding(Expression expression) {
if (polyTypeBindingConstructor == null) return null;
try {
Expand Down
Expand Up @@ -11,6 +11,7 @@ public void test() {
test = ExtensionMethodFunctional.Extensions.map(test, s -> ExtensionMethodFunctional.Extensions.reverse(s));
ExtensionMethodFunctional.Extensions.consume(test, s -> System.out.println("1: " + s), s -> System.out.println("2: " + s));
ExtensionMethodFunctional.Extensions.consume(test, System.out::println, System.out::println);
ExtensionMethodFunctional.Extensions.consume(test, test.length() > 0 ? System.out::println : null);
ExtensionMethodFunctional.Extensions.toList1(Stream.of("a", "b", "c").map(String::toUpperCase));
List<Integer> i2 = ExtensionMethodFunctional.Extensions.toList2(Stream.of("a", "b", "c").map(String::toUpperCase));
}
Expand Down
Expand Up @@ -36,6 +36,7 @@ public void test() {
test = ExtensionMethodFunctional.Extensions.map(test, (<no type> s) -> ExtensionMethodFunctional.Extensions.reverse(s));
ExtensionMethodFunctional.Extensions.consume(test, (<no type> s) -> System.out.println(("1: " + s)), (<no type> s) -> System.out.println(("2: " + s)));
ExtensionMethodFunctional.Extensions.consume(test, System.out::println, System.out::println);
ExtensionMethodFunctional.Extensions.consume(test, ((test.length() > 0) ? System.out::println : null));
ExtensionMethodFunctional.Extensions.toList1(Stream.of("a", "b", "c").map(String::toUpperCase));
List<Integer> i2 = ExtensionMethodFunctional.Extensions.toList2(Stream.of("a", "b", "c").map(String::toUpperCase));
}
Expand Down
2 changes: 2 additions & 0 deletions test/transform/resource/before/ExtensionMethodFunctional.java
Expand Up @@ -16,6 +16,8 @@ public void test() {
test.consume(s -> System.out.println("1: " + s), s -> System.out.println("2: " + s));
test.consume(System.out::println, System.out::println);

test.consume(test.length() > 0 ? System.out::println : null);

Stream.of("a", "b", "c").map(String::toUpperCase).toList1();
List<Integer> i2 = Stream.of("a", "b", "c").map(String::toUpperCase).toList2();
}
Expand Down