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

Adjust MethodNameCasing to work with C# #397

Draft
wants to merge 8 commits into
base: main
Choose a base branch
from
54 changes: 7 additions & 47 deletions src/main/java/org/openrewrite/staticanalysis/MethodNameCasing.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,12 @@
import lombok.Value;
import org.jspecify.annotations.Nullable;
import org.openrewrite.*;
import org.openrewrite.internal.NameCaseConvention;
import org.openrewrite.internal.NamingService;
import org.openrewrite.internal.StringUtils;
import org.openrewrite.java.ChangeMethodName;
import org.openrewrite.java.JavaIsoVisitor;
import org.openrewrite.java.MethodMatcher;
import org.openrewrite.java.VariableNameUtils;
import org.openrewrite.java.marker.JavaSourceSet;
import org.openrewrite.java.tree.J;
import org.openrewrite.java.tree.JavaSourceFile;
import org.openrewrite.java.tree.JavaType;
Expand All @@ -39,9 +38,6 @@
@EqualsAndHashCode(callSuper = false)
public class MethodNameCasing extends ScanningRecipe<List<MethodNameCasing.MethodNameChange>> {

private static final Pattern STANDARD_METHOD_NAME = Pattern.compile("^[a-z][a-zA-Z0-9]*$");
private static final Pattern SNAKE_CASE = Pattern.compile("^[a-zA-Z0-9]+_\\w+$");

@Option(displayName = "Apply recipe to test source set",
description = "Changes only apply to main by default. `includeTestSources` will apply the recipe to `test` source files.",
required = false)
Expand All @@ -62,8 +58,8 @@ public String getDisplayName() {
@Override
public String getDescription() {
return "Fixes method names that do not follow standard naming conventions. " +
"For example, `String getFoo_bar()` would be adjusted to `String getFooBar()` " +
"and `int DoSomething()` would be adjusted to `int doSomething()`.";
"For example, `String getFoo_bar()` would be adjusted to `String getFooBar()` " +
"and `int DoSomething()` would be adjusted to `int doSomething()`.";
}

@Override
Expand All @@ -85,17 +81,11 @@ public List<MethodNameChange> getInitialValue(ExecutionContext ctx) {
public TreeVisitor<?, ExecutionContext> getScanner(List<MethodNameChange> changes) {
return new JavaIsoVisitor<ExecutionContext>() {
UUID scope;

@Override
public J preVisit(J tree, ExecutionContext ctx) {
if (tree instanceof JavaSourceFile) {
scope = tree.getId();
JavaSourceFile cu = (JavaSourceFile) tree;
Optional<JavaSourceSet> sourceSet = cu.getMarkers().findFirst(JavaSourceSet.class);
if (!sourceSet.isPresent()) {
stopAfterPreVisit();
} else if (!Boolean.TRUE.equals(includeTestSources) && !"main".equals(sourceSet.get().getName())) {
stopAfterPreVisit();
}
}
return super.preVisit(tree, ctx);
}
Expand All @@ -110,40 +100,10 @@ public J.MethodDeclaration visitMethodDeclaration(J.MethodDeclaration method, Ex
if (containsValidModifiers(method) &&
method.getMethodType() != null &&
enclosingClass.getType() != null &&
!method.isConstructor() &&
!simpleName.startsWith("_") &&
!STANDARD_METHOD_NAME.matcher(simpleName).matches()) {
StringBuilder standardized = new StringBuilder();
!method.isConstructor()) {
String normalized = VariableNameUtils.normalizeName(simpleName);

if (SNAKE_CASE.matcher(normalized).matches()) {
standardized.append(NameCaseConvention.format(NameCaseConvention.LOWER_CAMEL, normalized));
} else {
int nameLength = normalized.length();
for (int i = 0; i < nameLength; i++) {
char c = normalized.charAt(i);

if (i == 0) {
// the java specification requires identifiers to start with [a-zA-Z$_]
if (c != '$' && c != '_') {
standardized.append(Character.toLowerCase(c));
}
} else {
if (!Character.isLetterOrDigit(c)) {
while (i < nameLength && (!Character.isLetterOrDigit(c) || c > 'z')) {
c = normalized.charAt(i++);
}
if (i < nameLength) {
standardized.append(Character.toUpperCase(c));
}
} else {
standardized.append(c);
}
}
}
}

String toName = standardized.toString();
NamingService service = service(NamingService.class);
String toName = service.standardizeMethodName(normalized);
if (!StringUtils.isBlank(toName) && !StringUtils.isNumeric(toName) &&
!methodExists(method.getMethodType(), toName)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

standardizeMethodName is not guaranteed to give back a different method name; do we already have a test to check expecting no changes? Or should we add a comparison here between the old and new name?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Think it's best to introduce a check here, better safe then sorry

changes.add(new MethodNameChange(
Expand Down
Loading