Skip to content

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

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

<groupId>org.springframework.data</groupId>
<artifactId>spring-data-commons</artifactId>
<version>4.0.0-SNAPSHOT</version>
<version>4.0.x-GH-3270-SNAPSHOT</version>

<name>Spring Data Core</name>
<description>Core Spring concepts underpinning every Spring Data module.</description>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,6 @@
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map.Entry;

import javax.lang.model.element.Modifier;

import org.jspecify.annotations.Nullable;

Expand All @@ -33,8 +30,6 @@
import org.springframework.data.repository.query.Parameter;
import org.springframework.data.repository.query.QueryMethod;
import org.springframework.data.repository.query.ReturnedType;
import org.springframework.javapoet.FieldSpec;
import org.springframework.javapoet.ParameterSpec;
import org.springframework.javapoet.TypeName;
import org.springframework.util.ObjectUtils;

Expand All @@ -53,7 +48,7 @@ public class AotQueryMethodGenerationContext {
private final RepositoryInformation repositoryInformation;
private final AotRepositoryFragmentMetadata targetTypeMetadata;
private final MethodMetadata targetMethodMetadata;
private final CodeBlocks codeBlocks;
private final VariableNameFactory variableNameFactory;

AotQueryMethodGenerationContext(RepositoryInformation repositoryInformation, Method method, QueryMethod queryMethod,
AotRepositoryFragmentMetadata targetTypeMetadata) {
Expand All @@ -64,11 +59,7 @@ public class AotQueryMethodGenerationContext {
this.repositoryInformation = repositoryInformation;
this.targetTypeMetadata = targetTypeMetadata;
this.targetMethodMetadata = new MethodMetadata(repositoryInformation, method);
this.codeBlocks = new CodeBlocks(targetTypeMetadata);
}

AotRepositoryFragmentMetadata getTargetTypeMetadata() {
return targetTypeMetadata;
this.variableNameFactory = LocalVariableNameFactory.forMethod(targetMethodMetadata);
}

MethodMetadata getTargetMethodMetadata() {
Expand All @@ -79,12 +70,18 @@ public RepositoryInformation getRepositoryInformation() {
return repositoryInformation;
}

public Method getMethod() {
return method;
/**
* Obtain the field name by type.
*
* @param type
* @return
*/
public @Nullable String fieldNameOf(Class<?> type) {
return targetTypeMetadata.fieldNameOf(type);
}

public CodeBlocks codeBlocks() {
return codeBlocks;
public Method getMethod() {
return method;
}

/**
Expand Down Expand Up @@ -112,10 +109,18 @@ public ReturnedType getReturnedType() {
return queryMethod.getResultProcessor().getReturnedType();
}

/**
* @return the actual returned domain type.
* @see org.springframework.data.repository.core.RepositoryMetadata#getReturnedDomainClass(Method)
*/
public ResolvableType getActualReturnType() {
return targetMethodMetadata.getActualReturnType();
}

/**
* @return the query method return type.
* @see org.springframework.data.repository.core.RepositoryMetadata#getReturnType(Method)
*/
public ResolvableType getReturnType() {
return targetMethodMetadata.getReturnType();
}
Expand All @@ -133,7 +138,7 @@ public TypeName getReturnTypeName() {
* index.
*
* @param parameterIndex the zero-based parameter index as used in the query to reference bindable parameters.
* @return the parameter name.
* @return the method parameter name.
*/
public String getRequiredBindableParameterName(int parameterIndex) {

Expand All @@ -151,9 +156,8 @@ public String getRequiredBindableParameterName(int parameterIndex) {
* {@code parameterIndex} or {@code null} if the parameter cannot be determined by its index.
*
* @param parameterIndex the zero-based parameter index as used in the query to reference bindable parameters.
* @return the parameter name.
* @return the method parameter name.
*/
// TODO: Simplify?!
public @Nullable String getBindableParameterName(int parameterIndex) {

int bindable = 0;
Expand All @@ -175,12 +179,12 @@ public String getRequiredBindableParameterName(int parameterIndex) {
}

/**
* Returns the required parameter name for the {@link Parameter#isBindable() bindable parameter} at the given
* {@code parameterName} or throws {@link IllegalArgumentException} if the parameter cannot be determined by its
* index.
* Returns the required parameter name for the {@link Parameter#isBindable() bindable parameter} at the given logical
* {@code parameterName} or throws {@link IllegalArgumentException} if the parameter cannot be determined by its name.
*
* @param parameterName the parameter name as used in the query to reference bindable parameters.
* @return the parameter name.
* @return the method parameter name.
* @see org.springframework.data.repository.query.Param
*/
public String getRequiredBindableParameterName(String parameterName) {

Expand All @@ -194,13 +198,13 @@ public String getRequiredBindableParameterName(String parameterName) {
}

/**
* Returns the required parameter name for the {@link Parameter#isBindable() bindable parameter} at the given
* {@code parameterName} or {@code null} if the parameter cannot be determined by its index.
* Returns the required parameter name for the {@link Parameter#isBindable() bindable parameter} at the given logical
* {@code parameterName} or {@code null} if the parameter cannot be determined by its name.
*
* @param parameterName the parameter name as used in the query to reference bindable parameters.
* @return the parameter name.
* @return the method parameter name.
* @see org.springframework.data.repository.query.Param
*/
// TODO: Simplify?!
public @Nullable String getBindableParameterName(String parameterName) {

int totalIndex = 0;
Expand All @@ -227,7 +231,7 @@ public List<String> getBindableParameterNames() {
List<String> result = new ArrayList<>();

for (Parameter parameter : queryMethod.getParameters().getBindableParameters()) {
parameter.getName().map(result::add);
result.add(getParameterName(parameter.getIndex()));
}

return result;
Expand All @@ -237,65 +241,53 @@ public List<String> getBindableParameterNames() {
* @return list of all parameter names (including non-bindable special parameters).
*/
public List<String> getAllParameterNames() {

List<String> result = new ArrayList<>();

for (Parameter parameter : queryMethod.getParameters()) {
parameter.getName().map(result::add);
}

return result;
}

public boolean hasField(String fieldName) {
return targetTypeMetadata.hasField(fieldName);
return targetMethodMetadata.getMethodArguments().keySet().stream().toList();
}

public void addField(String fieldName, TypeName type, Modifier... modifiers) {
targetTypeMetadata.addField(fieldName, type, modifiers);
}

public void addField(FieldSpec fieldSpec) {
targetTypeMetadata.addField(fieldSpec);
}

public @Nullable String fieldNameOf(Class<?> type) {
return targetTypeMetadata.fieldNameOf(type);
}

@Nullable
public String getParameterNameOf(Class<?> type) {
return targetMethodMetadata.getParameterNameOf(type);
/**
* Obtain a naming-clash free variant for the given logical variable name within the local method context. Returns the
* target variable name when called multiple times with the same {@code variableName}.
*
* @param variableName the logical variable name.
* @return the variable name used in the generated code.
*/
public String localVariable(String variableName) {
return targetMethodMetadata.getLocalVariables().computeIfAbsent(variableName, variableNameFactory::generateName);
}

/**
* Returns the parameter name for the method parameter at {@code position}.
*
* @param position zero-indexed parameter position.
* @return
* @see Method#getParameters()
*/
public @Nullable String getParameterName(int position) {

if (0 > position) {
return null;
}

List<Entry<String, ParameterSpec>> entries = new ArrayList<>(
targetMethodMetadata.getMethodArguments().entrySet());
if (position < entries.size()) {
return entries.get(position).getKey();
}
return null;
}

public void addParameter(ParameterSpec parameter) {
this.targetMethodMetadata.addParameter(parameter);
return targetMethodMetadata.getParameterName(position);
}

/**
* @return the parameter name for the {@link org.springframework.data.domain.Sort sort parameter} or {@code null} if
* the method does not declare a sort parameter.
*/
@Nullable
public String getSortParameterName() {
return getParameterName(queryMethod.getParameters().getSortIndex());
}

/**
* @return the parameter name for the {@link org.springframework.data.domain.Pageable pageable parameter} or
* {@code null} if the method does not declare a pageable parameter.
*/
@Nullable
public String getPageableParameterName() {
return getParameterName(queryMethod.getParameters().getPageableIndex());
}

/**
* @return the parameter name for the {@link org.springframework.data.domain.Limit limit parameter} or {@code null} if
* the method does not declare a limit parameter.
*/
@Nullable
public String getLimitParameterName() {
return getParameterName(queryMethod.getParameters().getLimitIndex());
Expand Down
Loading