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

Studying lambda parameters for a forEach method call #1379

Open
lasselindqvist opened this issue Nov 12, 2024 · 0 comments
Open

Studying lambda parameters for a forEach method call #1379

lasselindqvist opened this issue Nov 12, 2024 · 0 comments

Comments

@lasselindqvist
Copy link

lasselindqvist commented Nov 12, 2024

I am trying to write a rule such as:

	@ArchTest
	public static final ArchRule ruleSimple = methods().that()
			.areAnnotatedWith(RequestMapping.class)
			.should(new ArchCondition<JavaMethod>("call validator") {
				@Override
				public void check(JavaMethod item, ConditionEvents events) {
					if (!item.isAnnotatedWith(ValidationNotNeeded.class)) {
						List<JavaMethodCall> callsToValidator = item.getMethodCallsFromSelf().stream()
								.filter(call -> call.getTargetOwner().isAssignableFrom(Validator.class))
								.toList();
						if (callsToValidator.isEmpty()) {
							events.add(SimpleConditionEvent.violated(item,"No calls to Validator from " + item.getFullName()));
						}
					}
				}
			});

so as to enforce that in certain places all methods must call a method from Validator class.
This works fine and also works fine even if the calls are inside for loops. But case of forEach, the calls go to forEach method, not the methods that are called via the lambda passed onto it.

So

List<JavaMethodCall> calls = item.getMethodCallsFromSelf().stream()
.filter(jmc -> jmc.getName().equals("forEach"))
.toList();

find the forEach calls just fine. From these JavaMethodCall objects it is also possible to find the parameters passed on to forEach, but those are Consumers, not the lambdas themselves.

Is it even possible with ArchUnit to study what is passed as the Consumer?

As a bonus, this works differently with javac and Eclipse Compiler. When compiled with javac, the calls are found directly, but with Eclipse Compiler, the forEach calls are found.

Workaround:
Simple workaround is to just replace forEach calls with normal loops, but it is not ideal in all cases.

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

No branches or pull requests

1 participant