You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by pa...@apache.org on 2026/06/01 05:22:34 UTC

(groovy) branch master updated: minor refactor: remove dup from capitalize scenarios

This is an automated email from the ASF dual-hosted git repository.

paulk-asert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git


The following commit(s) were added to refs/heads/master by this push:
     new 90e292c1ea minor refactor: remove dup from capitalize scenarios
90e292c1ea is described below

commit 90e292c1ead204d4110d0060ba1440e5f0dab4eb
Author: Paul King <pa...@asert.com.au>
AuthorDate: Mon Jun 1 15:22:25 2026 +1000

    minor refactor: remove dup from capitalize scenarios
---
 .../groovy/groovy/beans/ListenerListASTStubber.groovy |  4 ++--
 src/main/java/groovy/util/ObjectGraphBuilder.java     | 19 ++++++-------------
 .../org/apache/groovy/ast/tools/ClassNodeUtils.java   |  4 ++--
 .../java/groovy/sql/ResultSetMetaDataWrapper.java     |  5 +++--
 .../groovy/mock/interceptor/MockInterceptor.groovy    |  6 ++++--
 5 files changed, 17 insertions(+), 21 deletions(-)

diff --git a/src/main/groovy/groovy/beans/ListenerListASTStubber.groovy b/src/main/groovy/groovy/beans/ListenerListASTStubber.groovy
index 13698c0f06..c08f5d6d1d 100644
--- a/src/main/groovy/groovy/beans/ListenerListASTStubber.groovy
+++ b/src/main/groovy/groovy/beans/ListenerListASTStubber.groovy
@@ -80,7 +80,7 @@ class ListenerListASTStubber extends AbstractASTTransformation {
         ClassNode listener = types[0].type
 
         String name = annotation.getMember('name')?.value ?: listener.nameWithoutPackage
-        String capName = name[0].toUpperCase(Locale.ROOT) + name.substring(1)
+        String capName = name.capitalize()
         boolean synchronize = annotation.getMember('synchronize')?.value ?: false
         int modifiers = synchronize ? Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNCHRONIZED : Opcodes.ACC_PUBLIC
 
@@ -110,7 +110,7 @@ class ListenerListASTStubber extends AbstractASTTransformation {
         listener.methods.findAll { MethodNode m ->
             m.isPublic() && !m.isSynthetic() && !m.isStatic()
         }.each { MethodNode m ->
-            String fireName = "fire${m.name[0].toUpperCase(Locale.ROOT) + m.name.substring(1)}"
+            String fireName = "fire${m.name.capitalize()}"
             // Mirror the full transform's parameter copying (wrapper types,
             // plain refs) so stub signatures match what the full transform
             // will emit.
diff --git a/src/main/java/groovy/util/ObjectGraphBuilder.java b/src/main/java/groovy/util/ObjectGraphBuilder.java
index 7fce97a1e3..7904b45b00 100644
--- a/src/main/java/groovy/util/ObjectGraphBuilder.java
+++ b/src/main/java/groovy/util/ObjectGraphBuilder.java
@@ -33,10 +33,12 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.List;
-import java.util.Locale;
 import java.util.Map;
 import java.util.regex.Pattern;
 
+import static org.codehaus.groovy.runtime.StringGroovyMethods.capitalize;
+import static org.codehaus.groovy.runtime.StringGroovyMethods.uncapitalize;
+
 /**
  * A builder for creating object graphs.<br>
  * Each node defines the class to be created and the property on its parent (if
@@ -393,11 +395,7 @@ public class ObjectGraphBuilder extends FactoryBuilderSupport {
         /** {@inheritDoc} */
         @Override
         public String resolveClassname(String classname) {
-            if (classname.length() == 1) {
-                return classname.toUpperCase(Locale.ROOT);
-            }
-            return classname.substring(0, 1)
-                    .toUpperCase(Locale.ROOT) + classname.substring(1);
+            return capitalize(classname);
         }
     }
 
@@ -626,7 +624,7 @@ public class ObjectGraphBuilder extends FactoryBuilderSupport {
     }
 
     private static String makeClassName(String root, String name) {
-        return root + "." + name.substring(0, 1).toUpperCase(Locale.ROOT) + name.substring(1);
+        return root + "." + capitalize(name);
     }
 
     private static class ObjectFactory extends AbstractFactory {
@@ -775,12 +773,7 @@ public class ObjectGraphBuilder extends FactoryBuilderSupport {
                 bean = value;
             }
 
-            String nodename = klass.getSimpleName();
-            if(nodename.length() > 1) {
-                nodename = nodename.substring(0, 1).toLowerCase(Locale.ROOT) + nodename.substring(1);
-            } else {
-                nodename = nodename.toLowerCase(Locale.ROOT);
-            }
+            String nodename = uncapitalize(klass.getSimpleName());
             context.put(ObjectGraphBuilder.NODE_NAME, nodename);
             context.put(ObjectGraphBuilder.NODE_CLASS, klass);
             return bean;
diff --git a/src/main/java/org/apache/groovy/ast/tools/ClassNodeUtils.java b/src/main/java/org/apache/groovy/ast/tools/ClassNodeUtils.java
index 4e22b5b2d9..54f6dd6f29 100644
--- a/src/main/java/org/apache/groovy/ast/tools/ClassNodeUtils.java
+++ b/src/main/java/org/apache/groovy/ast/tools/ClassNodeUtils.java
@@ -40,7 +40,6 @@ import java.util.Collections;
 import java.util.HashSet;
 import java.util.LinkedHashMap;
 import java.util.List;
-import java.util.Locale;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Optional;
@@ -338,7 +337,8 @@ public class ClassNodeUtils {
     public static String getPropNameForAccessor(final String accessorName) {
         if (!isValidAccessorName(accessorName)) return accessorName;
         int prefixLength = accessorName.startsWith("is") ? 2 : 3;
-        return String.valueOf(accessorName.charAt(prefixLength)).toLowerCase(Locale.ROOT) + accessorName.substring(prefixLength + 1);
+        // use JavaBean decapitalization so acronyms match the runtime rule, e.g. getURL -> URL (not uRL)
+        return BeanUtils.decapitalize(accessorName.substring(prefixLength));
     }
 
     /**
diff --git a/subprojects/groovy-sql/src/main/java/groovy/sql/ResultSetMetaDataWrapper.java b/subprojects/groovy-sql/src/main/java/groovy/sql/ResultSetMetaDataWrapper.java
index 1c2a192e21..7bab61fd1e 100644
--- a/subprojects/groovy-sql/src/main/java/groovy/sql/ResultSetMetaDataWrapper.java
+++ b/subprojects/groovy-sql/src/main/java/groovy/sql/ResultSetMetaDataWrapper.java
@@ -24,7 +24,8 @@ import groovy.lang.ReadOnlyPropertyException;
 import org.codehaus.groovy.runtime.InvokerHelper;
 
 import java.sql.ResultSetMetaData;
-import java.util.Locale;
+
+import static org.apache.groovy.util.BeanUtils.capitalize;
 
 /**
  * This class defines a wrapper for accessing a specific column in <code>ResultSetMetaData</code>.
@@ -84,7 +85,7 @@ public class ResultSetMetaDataWrapper extends GroovyObjectSupport {
         if (prop == null || prop.isEmpty()) {
             throw new MissingPropertyException(prop, target.getClass());
         }
-        return "get" + prop.substring(0, 1).toUpperCase(Locale.ROOT) + prop.substring(1);
+        return "get" + capitalize(prop);
     }
 
     /**
diff --git a/subprojects/groovy-test/src/main/groovy/groovy/mock/interceptor/MockInterceptor.groovy b/subprojects/groovy-test/src/main/groovy/groovy/mock/interceptor/MockInterceptor.groovy
index 320f374f3b..0521f98b1e 100644
--- a/subprojects/groovy-test/src/main/groovy/groovy/mock/interceptor/MockInterceptor.groovy
+++ b/subprojects/groovy-test/src/main/groovy/groovy/mock/interceptor/MockInterceptor.groovy
@@ -18,6 +18,8 @@
  */
 package groovy.mock.interceptor
 
+import static org.apache.groovy.util.BeanUtils.capitalize
+
 /**
  * Intercepting calls to the collaborating object and notify the expectation object.
  */
@@ -53,7 +55,7 @@ class MockInterceptor implements PropertyAccessInterceptor {
      */
     def beforeGet(Object object, String property) {
         if (!expectation) throw new IllegalStateException("Property 'expectation' must be set before use.")
-        String name = "get${property[0].toUpperCase(Locale.ROOT)}${property[1..-1]}"
+        String name = "get${capitalize(property)}"
         def result = expectation.match(name)
         if (result == MockProxyMetaClass.FALL_THROUGH_MARKER) return result
         return result()
@@ -68,7 +70,7 @@ class MockInterceptor implements PropertyAccessInterceptor {
      */
     void beforeSet(Object object, String property, Object newValue) {
         if (!expectation) throw new IllegalStateException("Property 'expectation' must be set before use.")
-        String name = "set${property[0].toUpperCase(Locale.ROOT)}${property[1..-1]}"
+        String name = "set${capitalize(property)}"
         def result = expectation.match(name)
         if (result != MockProxyMetaClass.FALL_THROUGH_MARKER) {
             result(newValue)