This is an automated email from the ASF dual-hosted git repository. sunlan pushed a commit to branch GROOVY-9637 in repository https://gitbox.apache.org/repos/asf/groovy.git
The following commit(s) were added to refs/heads/GROOVY-9637 by this push: new 6187f3e Check immutable with `ImmutablePropertyUtils` 6187f3e is described below commit 6187f3e4355db563a3d39d4698ec1b2b064b3406 Author: Daniel Sun <sun...@apache.org> AuthorDate: Mon Jul 13 07:25:16 2020 +0800 Check immutable with `ImmutablePropertyUtils` --- src/main/java/groovy/lang/GString.java | 9 ++++--- .../groovy/ast/tools/ImmutablePropertyUtils.java | 12 +++++++-- src/test/groovy/GStringTest.groovy | 31 +++++++++++++++++++++- 3 files changed, 45 insertions(+), 7 deletions(-) diff --git a/src/main/java/groovy/lang/GString.java b/src/main/java/groovy/lang/GString.java index ec1c06a..401e652 100644 --- a/src/main/java/groovy/lang/GString.java +++ b/src/main/java/groovy/lang/GString.java @@ -18,6 +18,7 @@ */ package groovy.lang; +import org.apache.groovy.ast.tools.ImmutablePropertyUtils; import org.apache.groovy.io.StringBuilderWriter; import org.codehaus.groovy.runtime.GStringImpl; import org.codehaus.groovy.runtime.InvokerHelper; @@ -93,12 +94,12 @@ public abstract class GString extends GroovyObjectSupport implements Comparable, public GString(Object values) { this.values = (Object[]) values; - this.immutable = checkValuesImmutable(); + this.immutable = checkImmutable(this.values); } public GString(Object[] values) { this.values = values; - this.immutable = checkValuesImmutable(); + this.immutable = checkImmutable(this.values); } // will be static in an instance @@ -310,10 +311,10 @@ public abstract class GString extends GroovyObjectSupport implements Comparable, return toString().getBytes(charset); } - private boolean checkValuesImmutable() { + private static boolean checkImmutable(Object[] values) { for (Object value : values) { if (null == value) continue; - if (!(IMMUTABLE_TYPE_LIST.contains(value.getClass()) + if (!(ImmutablePropertyUtils.isBuiltinImmutable(value.getClass().getName()) || (value instanceof GString && ((GString) value).immutable))) { return false; } diff --git a/src/main/java/org/apache/groovy/ast/tools/ImmutablePropertyUtils.java b/src/main/java/org/apache/groovy/ast/tools/ImmutablePropertyUtils.java index 7ee64a6..f2c73fd 100644 --- a/src/main/java/org/apache/groovy/ast/tools/ImmutablePropertyUtils.java +++ b/src/main/java/org/apache/groovy/ast/tools/ImmutablePropertyUtils.java @@ -69,7 +69,15 @@ public class ImmutablePropertyUtils { This list can by extended by providing "known immutable" classes via Immutable.knownImmutableClasses */ - private static Set<String> builtinImmutables = new HashSet<String>(Arrays.asList( + private static final Set<String> BUILTIN_IMMUTABLES = new HashSet<String>(Arrays.asList( + "boolean", + "byte", + "char", + "double", + "float", + "int", + "long", + "short", "java.lang.Class", "java.lang.Boolean", "java.lang.Byte", @@ -195,7 +203,7 @@ public class ImmutablePropertyUtils { } public static boolean isBuiltinImmutable(String typeName) { - return builtinImmutables.contains(typeName); + return BUILTIN_IMMUTABLES.contains(typeName); } private static boolean hasImmutableAnnotation(Class clazz) { diff --git a/src/test/groovy/GStringTest.groovy b/src/test/groovy/GStringTest.groovy index 00c75eb..f7ad73e 100644 --- a/src/test/groovy/GStringTest.groovy +++ b/src/test/groovy/GStringTest.groovy @@ -585,7 +585,7 @@ class GStringTest extends GroovyTestCase { assert Eval.me('''def foo='bar'; /${foo}\u002abaz/''') == 'bar*baz' } - void testNestedGString() { + void testImmutableNestedGString() { def gstr = "a${"${123}"}b" assert 'a123b' == gstr assert gstr.toString() === gstr.toString() @@ -598,4 +598,33 @@ class GStringTest extends GroovyTestCase { cachedStringLiteralField.setAccessible(true) assert 'a123b' == cachedStringLiteralField.get(gstr) } + + void testImmutableGString() { + def gstr = "a${'1'}" + assert gstr.toString() === gstr.toString() + + def gstr2 = "a${true}" + assert gstr2.toString() === gstr2.toString() + + def gstr3 = "a${(byte) 1}" + assert gstr3.toString() === gstr3.toString() + + def gstr4 = "a${(char) 65}" + assert gstr4.toString() === gstr4.toString() + + def gstr5 = "a${1D}" + assert gstr5.toString() === gstr5.toString() + + def gstr6 = "a${1F}" + assert gstr6.toString() === gstr6.toString() + + def gstr7 = "a${1}" + assert gstr7.toString() === gstr7.toString() + + def gstr8 = "a${1L}" + assert gstr8.toString() === gstr8.toString() + + def gstr9 = "a${(short) 1}" + assert gstr9.toString() === gstr9.toString() + } }