This is an automated email from the ASF dual-hosted git repository.
sunlan pushed a commit to branch GROOVY_5_0_X
in repository https://gitbox.apache.org/repos/asf/groovy.git
The following commit(s) were added to refs/heads/GROOVY_5_0_X by this push:
new 27eaecec12 Minor tweaks
27eaecec12 is described below
commit 27eaecec12863a9b009fdebb0d037771d9a10537
Author: Daniel Sun <[email protected]>
AuthorDate: Sun Feb 15 12:01:01 2026 +0900
Minor tweaks
(cherry picked from commit 3ccc87f054b2000e12cd6236d16d57a0e1330df8)
---
.../java/org/codehaus/groovy/ast/ClassHelper.java | 44 +++++++++++++++-------
.../java/org/codehaus/groovy/ast/ClassNode.java | 7 +++-
.../org/codehaus/groovy/classgen/Verifier.java | 6 +--
.../groovy/classgen/asm/BytecodeHelper.java | 2 +-
.../codehaus/groovy/control/ResolveVisitor.java | 23 ++++++-----
.../groovy/control/StaticImportVisitor.java | 33 +++++++++-------
6 files changed, 70 insertions(+), 45 deletions(-)
diff --git a/src/main/java/org/codehaus/groovy/ast/ClassHelper.java
b/src/main/java/org/codehaus/groovy/ast/ClassHelper.java
index 653a11ec23..fafa25a7d4 100644
--- a/src/main/java/org/codehaus/groovy/ast/ClassHelper.java
+++ b/src/main/java/org/codehaus/groovy/ast/ClassHelper.java
@@ -66,6 +66,8 @@ import java.math.BigInteger;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
+import java.util.HashMap;
+import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -185,6 +187,26 @@ public class ClassHelper {
GROOVY_OBJECT_TYPE, GROOVY_INTERCEPTABLE_TYPE, Enum_Type,
Annotation_TYPE
};
+ // O(1) lookup maps for make(Class) and make(String), replacing O(n)
linear scans
+ private static final Map<Class<?>, ClassNode> classToTypeMap = new
IdentityHashMap<>();
+ private static final Map<String, ClassNode> nameToTypeMap = new
HashMap<>();
+ private static final Map<String, ClassNode> primitiveNameToTypeMap = new
HashMap<>();
+ private static final Set<ClassNode> cachedTypeSet =
Collections.newSetFromMap(new IdentityHashMap<>());
+ static {
+ for (int i = 0; i < classes.length; i++) {
+ classToTypeMap.put(classes[i], types[i]);
+ }
+ for (int i = 0; i < primitiveClassNames.length; i++) {
+ if (!primitiveClassNames[i].isEmpty()) {
+ primitiveNameToTypeMap.put(primitiveClassNames[i], types[i]);
+ }
+ }
+ for (int i = 0; i < classes.length; i++) {
+ nameToTypeMap.put(classes[i].getName(), types[i]);
+ }
+ cachedTypeSet.addAll(Arrays.asList(types));
+ }
+
private static final String DYNAMIC_TYPE_METADATA =
"_DYNAMIC_TYPE_METADATA_";
protected static final ClassNode[] EMPTY_TYPE_ARRAY =
ClassNode.EMPTY_ARRAY;
@@ -238,9 +260,8 @@ public class ClassHelper {
}
public static ClassNode make(Class c, boolean includeGenerics) {
- for (int i = 0; i < classes.length; i++) {
- if (c == classes[i]) return types[i];
- }
+ ClassNode cached = classToTypeMap.get(c);
+ if (cached != null) return cached;
if (c.isArray()) {
ClassNode cn = make(c.getComponentType(), includeGenerics);
return cn.makeArray();
@@ -295,14 +316,12 @@ public class ClassHelper {
public static ClassNode make(String name) {
if (name == null || name.isEmpty()) return dynamicType();
- for (int i = 0; i < primitiveClassNames.length; i++) {
- if (primitiveClassNames[i].equals(name)) return types[i];
- }
+ ClassNode cached = primitiveNameToTypeMap.get(name);
+ if (cached != null) return cached;
+
+ cached = nameToTypeMap.get(name);
+ if (cached != null) return cached;
- for (int i = 0; i < classes.length; i++) {
- String cname = classes[i].getName();
- if (name.equals(cname)) return types[i];
- }
return makeWithoutCaching(name);
}
@@ -424,10 +443,7 @@ public class ClassHelper {
}
public static boolean isCachedType(ClassNode type) {
- for (ClassNode cachedType : types) {
- if (cachedType == type) return true;
- }
- return false;
+ return cachedTypeSet.contains(type);
}
public static boolean isDynamicTyped(ClassNode type) {
diff --git a/src/main/java/org/codehaus/groovy/ast/ClassNode.java
b/src/main/java/org/codehaus/groovy/ast/ClassNode.java
index 96511c4b52..308de87ef9 100644
--- a/src/main/java/org/codehaus/groovy/ast/ClassNode.java
+++ b/src/main/java/org/codehaus/groovy/ast/ClassNode.java
@@ -127,8 +127,11 @@ public class ClassNode extends AnnotatedNode {
Map<Object, List<MethodNode>> map;
List<MethodNode> get(Object key) {
- return Optional.ofNullable(map)
- .map(m -> m.get(key)).orElseGet(Collections::emptyList);
+ if (map != null) {
+ List<MethodNode> result = map.get(key);
+ if (result != null) return result;
+ }
+ return Collections.emptyList();
}
void put(Object key, MethodNode value) {
diff --git a/src/main/java/org/codehaus/groovy/classgen/Verifier.java
b/src/main/java/org/codehaus/groovy/classgen/Verifier.java
index fe9758d0ab..a2b12b5905 100644
--- a/src/main/java/org/codehaus/groovy/classgen/Verifier.java
+++ b/src/main/java/org/codehaus/groovy/classgen/Verifier.java
@@ -431,7 +431,7 @@ public class Verifier implements GroovyClassVisitor,
Opcodes {
for (MethodNode mn : cn.getMethods()) {
if (mn.isSynthetic()) continue;
String mySig =
MethodNodeUtils.methodDescriptorWithoutReturnType(mn);
- if (descriptors.contains(mySig)) {
+ if (!descriptors.add(mySig)) {
if (mn.isScriptBody() ||
mySig.equals(scriptBodySignatureWithoutReturnType(cn))) {
throw new RuntimeParserException("The method " +
mn.getText() +
" is a duplicate of the one declared for this
script's body code", sourceOf(mn));
@@ -440,7 +440,6 @@ public class Verifier implements GroovyClassVisitor,
Opcodes {
" duplicates another method of the same
signature", sourceOf(mn));
}
}
- descriptors.add(mySig);
}
}
@@ -448,11 +447,10 @@ public class Verifier implements GroovyClassVisitor,
Opcodes {
Set<String> descriptors = new HashSet<>();
for (ConstructorNode cons : cn.getDeclaredConstructors()) {
String mySig =
MethodNodeUtils.methodDescriptorWithoutReturnType(cons);
- if (descriptors.contains(mySig)) {
+ if (!descriptors.add(mySig)) {
throw new RuntimeParserException("The constructor " +
cons.getText() +
" duplicates another constructor of the same signature",
sourceOf(cons));
}
- descriptors.add(mySig);
}
}
diff --git a/src/main/java/org/codehaus/groovy/classgen/asm/BytecodeHelper.java
b/src/main/java/org/codehaus/groovy/classgen/asm/BytecodeHelper.java
index b80433de02..8f292bca89 100644
--- a/src/main/java/org/codehaus/groovy/classgen/asm/BytecodeHelper.java
+++ b/src/main/java/org/codehaus/groovy/classgen/asm/BytecodeHelper.java
@@ -115,7 +115,7 @@ public class BytecodeHelper {
* @return the ASM internal name of the type
*/
public static String getClassInternalName(String name) {
- return name.replace('.', '/');
+ return name.indexOf('.') < 0 ? name : name.replace('.', '/');
}
/**
diff --git a/src/main/java/org/codehaus/groovy/control/ResolveVisitor.java
b/src/main/java/org/codehaus/groovy/control/ResolveVisitor.java
index 8e3a08716f..0eec6885bf 100644
--- a/src/main/java/org/codehaus/groovy/control/ResolveVisitor.java
+++ b/src/main/java/org/codehaus/groovy/control/ResolveVisitor.java
@@ -409,13 +409,15 @@ public class ResolveVisitor extends
ClassCodeExpressionTransformer {
String typeName = type.getName();
- GenericsType typeParameter = genericParameterNames.get(new
GenericsTypeName(typeName));
- if (typeParameter != null) {
-
type.setDeclaringClass(typeParameter.getType().getDeclaringClass());
- type.setGenericsTypes(new GenericsType[]{typeParameter});
- type.setRedirect(typeParameter.getType());
- type.setGenericsPlaceHolder(true);
- return true;
+ if (!genericParameterNames.isEmpty()) {
+ GenericsType typeParameter = genericParameterNames.get(new
GenericsTypeName(typeName));
+ if (typeParameter != null) {
+
type.setDeclaringClass(typeParameter.getType().getDeclaringClass());
+ type.setGenericsTypes(new GenericsType[]{typeParameter});
+ type.setRedirect(typeParameter.getType());
+ type.setGenericsPlaceHolder(true);
+ return true;
+ }
}
boolean resolved;
@@ -503,8 +505,9 @@ public class ResolveVisitor extends
ClassCodeExpressionTransformer {
private static String replaceLastPointWithDollar(final String name) {
int lastPointIndex = name.lastIndexOf('.');
-
- return name.substring(0, lastPointIndex) + "$" +
name.substring(lastPointIndex + 1);
+ char[] chars = name.toCharArray();
+ chars[lastPointIndex] = '$';
+ return new String(chars);
}
protected boolean resolveFromStaticInnerClasses(final ClassNode type) {
@@ -1491,7 +1494,7 @@ public class ResolveVisitor extends
ClassCodeExpressionTransformer {
currentClass.setUsingGenerics(true);
ClassNode type = genericsType.getType();
visitTypeAnnotations(type); // JSR 308 support
- GenericsType tp = genericParameterNames.get(new
GenericsTypeName(type.getName()));
+ GenericsType tp = genericParameterNames.isEmpty() ? null :
genericParameterNames.get(new GenericsTypeName(type.getName()));
if (tp != null) {
ClassNode[] bounds = tp.getUpperBounds();
if (bounds != null && (bounds.length > 1 ||
(bounds[0].isRedirectNode()
diff --git a/src/main/java/org/codehaus/groovy/control/StaticImportVisitor.java
b/src/main/java/org/codehaus/groovy/control/StaticImportVisitor.java
index dc4dd8e96f..259c59d70a 100644
--- a/src/main/java/org/codehaus/groovy/control/StaticImportVisitor.java
+++ b/src/main/java/org/codehaus/groovy/control/StaticImportVisitor.java
@@ -186,8 +186,8 @@ public class StaticImportVisitor extends
ClassCodeExpressionTransformer {
ModuleNode module = currentClass.getModule();
if (module != null && key instanceof ConstantExpression) {
Map<String, ImportNode> importNodes = module.getStaticImports();
- if (importNodes.containsKey(key.getText())) {
- ImportNode importNode = importNodes.get(key.getText());
+ ImportNode importNode = importNodes.get(key.getText());
+ if (importNode != null) {
if (importNode.getType().equals(constructorCallType)) {
String newKey = importNode.getFieldName();
return new MapEntryExpression(new
ConstantExpression(newKey), value.transformExpression(this));
@@ -411,9 +411,12 @@ public class StaticImportVisitor extends
ClassCodeExpressionTransformer {
// look for one of these:
// import static MyClass.prop [as otherProp]
// when resolving property or field reference
- if (staticImports.containsKey(name)) { ImportNode importNode =
staticImports.get(name);
- expression = findStaticPropertyOrField(importNode.getType(),
importNode.getFieldName());
- if (expression != null) return expression;
+ {
+ ImportNode importNode = staticImports.get(name);
+ if (importNode != null) {
+ expression = findStaticPropertyOrField(importNode.getType(),
importNode.getFieldName());
+ if (expression != null) return expression;
+ }
}
// look for one of these:
@@ -440,16 +443,18 @@ public class StaticImportVisitor extends
ClassCodeExpressionTransformer {
// import static MyClass.method [as alias]
// import static MyClass.property [as alias]
// when resolving implicit-this call name(args)
- if (staticImports.containsKey(name)) {
+ {
ImportNode importNode = staticImports.get(name);
- expression = findStaticMethod(importNode.getType(),
importNode.getFieldName(), args);
- if (expression != null) return expression;
- if (!inLeftExpression) { // GROOVY-11056, et al.
- expression = findStaticPropertyOrField(importNode.getType(),
importNode.getFieldName());
- if (expression != null) { // assume name refers to a callable
static field/property
- MethodCallExpression call = new
MethodCallExpression(expression, "call", args);
- call.setImplicitThis(false);
- return call;
+ if (importNode != null) {
+ expression = findStaticMethod(importNode.getType(),
importNode.getFieldName(), args);
+ if (expression != null) return expression;
+ if (!inLeftExpression) { // GROOVY-11056, et al.
+ expression =
findStaticPropertyOrField(importNode.getType(), importNode.getFieldName());
+ if (expression != null) { // assume name refers to a
callable static field/property
+ MethodCallExpression call = new
MethodCallExpression(expression, "call", args);
+ call.setImplicitThis(false);
+ return call;
+ }
}
}
}