-
Notifications
You must be signed in to change notification settings - Fork 683
Add LocalVariableNameFactory. #3271
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
base: 4.0.x
Are you sure you want to change the base?
Conversation
10f4ee9
to
9d146dc
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good @christophstrobl . I made a few minor suggestions. PTAL.
src/main/java/org/springframework/data/repository/aot/generate/LocalVariableNameFactory.java
Show resolved
Hide resolved
src/main/java/org/springframework/data/repository/aot/generate/VariableNameFactory.java
Show resolved
Hide resolved
src/main/java/org/springframework/data/repository/aot/generate/VariableNameFactory.java
Outdated
Show resolved
Hide resolved
...java/org/springframework/data/repository/aot/generate/LocalVariableNameFactoryUnitTests.java
Show resolved
Hide resolved
return new LocalVariableNameFactory(variables); | ||
} | ||
|
||
LocalVariableNameFactory(Iterable<String> predefinedVariableNames) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A simplification of this could be:
LocalVariableNameFactory(Iterable<String> predefinedVariableNames) {
predefinedVariableNames.forEach((paramName) -> variables.put(paramName, 0L));
}
Wdyt?
Add a variable name factory that considers predefined names and resolves name clashes. Expose variable name clash resolution via the generation context of a single method.
9d146dc
to
4a48edc
Compare
} | ||
|
||
String targetName = suggestTargetName(intendedVariableName); | ||
variables.add(intendedVariableName, targetName); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to update the original intendedVariableName
?
This code is fine but concurrency aside, I still think something like the following that would replace line62-86 would simplify things:
@Override
public String generateName(String suggestedName) {
var counter = variables.compute(suggestedName,
(__, currentCount) -> currentCount == null ? 0 : currentCount.longValue() + 1);
return counter == 0 ? suggestedName : "%s_%s".formatted(suggestedName, counter));
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the updates @christophstrobl - LGTM
* @param variableName the intended variable name. | ||
* @return the suggested VariableName | ||
*/ | ||
public String suggestLocalVariableName(String variableName) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would suggest refining the way we approach the problem. We generally hold details in the context and can look these up. I would suggest that we keep a map around with parameter name mappings and use this method as getLocalVariableName(…)
or localVariable(String logicalName)
. One could then call the method with the same name twice. On the first call, we would ensure there is no clash, the second call would return the mapped name. Would also alleviate the need to track the variable name in the calling code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sorry I don't get that comment. Why would I want to call the same method twice?
you'll have to keep track of variable name in the calling code since you might have to apply it in different code blocks or have to pass it around between query creation and execution so you refer to right thing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you'll have to keep track of variable name in the calling code since you might have to apply it in different code blocks or have to pass it around between query creation and execution so you refer to right thing.
Calling code would then not be required to track the actual variable name but could refer to the context so the context provides the information.
*/ | ||
class MethodMetadata { | ||
|
||
private final Map<String, ParameterSpec> methodArguments = new LinkedHashMap<>(); | ||
private final ResolvableType actualReturnType; | ||
private final ResolvableType returnType; | ||
|
||
public MethodMetadata(RepositoryInformation repositoryInformation, Method method) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: I liked the visibility modifiers to indicate which methods are desired API and to differentiate between those ones, that are package-private for testing purposes.
Add a variable name factory that considers predefined names and resolves name clashes.
Expose variable name clash resolution via the generation context of a single method.