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 e5af92d Merge `GString` and `GStringImpl` e5af92d is described below commit e5af92dc0ab52aef079ef586ba19c42ae470da1f Author: Daniel Sun <sun...@apache.org> AuthorDate: Thu Jul 23 08:20:34 2020 +0800 Merge `GString` and `GStringImpl` --- src/main/java/groovy/lang/GString.java | 70 ++++++++++++---------- .../groovy/classgen/AsmClassGenerator.java | 4 +- .../codehaus/groovy/control/CompilationUnit.java | 2 + .../org/codehaus/groovy/runtime/GStringImpl.java | 64 -------------------- src/test/groovy/lang/DummyGStringBase.java | 6 +- src/test/groovy/lang/GStringTest.java | 4 +- .../groovy/runtime/InvokeConstructorTest.java | 6 +- .../codehaus/groovy/runtime/InvokeMethodTest.java | 18 +++--- .../org/codehaus/groovy/runtime/InvokerTest.java | 21 ++++--- 9 files changed, 65 insertions(+), 130 deletions(-) diff --git a/src/main/java/groovy/lang/GString.java b/src/main/java/groovy/lang/GString.java index affd9b4..ed4b937 100644 --- a/src/main/java/groovy/lang/GString.java +++ b/src/main/java/groovy/lang/GString.java @@ -20,7 +20,6 @@ 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; import org.codehaus.groovy.runtime.StringGroovyMethods; @@ -28,6 +27,8 @@ import java.io.IOException; import java.io.Serializable; import java.io.UnsupportedEncodingException; import java.io.Writer; +import java.util.Arrays; +import java.util.List; import java.util.regex.Pattern; /** @@ -40,7 +41,7 @@ import java.util.regex.Pattern; * James Strachan: The lovely name of this class was suggested by Jules Gosnell * and was such a good idea, I couldn't resist :) */ -public abstract class GString extends GroovyObjectSupport implements Comparable, CharSequence, Writable, Buildable, Serializable { +public class GString extends GroovyObjectSupport implements Comparable, CharSequence, Writable, Buildable, Serializable { private static final long serialVersionUID = -2638020355892246323L; private static final String MKP = "mkp"; @@ -52,39 +53,37 @@ public abstract class GString extends GroovyObjectSupport implements Comparable, /** * A GString containing a single empty String and no values. */ - public static final GString EMPTY = new GString(EMPTY_OBJECT_ARRAY) { - private static final long serialVersionUID = -7676746462783374250L; - private static final String EMPTY_STRING = ""; - - @Override - public String[] getStrings() { - return new String[] { EMPTY_STRING }; - } - - @Override - public String toString() { - return EMPTY_STRING; - } - }; - + public static final GString EMPTY = new GString(EMPTY_OBJECT_ARRAY, EMPTY_STRING_ARRAY); + private final String[] strings; private final Object[] values; private final boolean immutable; - public GString(Object values) { + public GString(Object values, String[] strings) { this.values = (Object[]) values; + this.strings = strings; this.immutable = checkImmutable(this.values); } - public GString(Object[] values) { + /** + * Create a new GString with values and strings. + * <p> + * Each value is prefixed by a string, after the last value + * an additional String might be used. This means + * <code>strings.length == values.length || strings.length == values.length + 1</code>. + * <p> + * <b>NOTE:</b> The lengths are <b>not</b> checked. Using different lengths might result + * in unpredictable behaviour. + * + * @param values the value parts + * @param strings the string parts + */ + public GString(Object[] values, String[] strings) { this.values = values; + this.strings = strings; this.immutable = checkImmutable(this.values); } - // will be static in an instance - - public abstract String[] getStrings(); - /** * Overloaded to implement duck typing for Strings * so that any method that can't be evaluated on this @@ -100,14 +99,25 @@ public abstract class GString extends GroovyObjectSupport implements Comparable, } } - public Object[] getValues() { - return values.clone(); + public final List<Object> getValues() { + return Arrays.asList(values); + } + + /** + * Get the strings of this GString. + * <p> + * This methods returns the same array as used in the constructor. Changing + * the values will result in changes of the GString. It is not recommended + * to do so. + */ + public final List<String> getStrings() { + return Arrays.asList(strings); } public GString plus(GString that) { Object[] values = this.values; - return new GStringImpl(appendValues(values, that.values), appendStrings(getStrings(), that.getStrings(), values.length)); + return new GString(appendValues(values, that.values), appendStrings(this.strings, that.strings, values.length)); } private String[] appendStrings(String[] strings, String[] thatStrings, int valuesLength) { @@ -143,7 +153,7 @@ public abstract class GString extends GroovyObjectSupport implements Comparable, } public GString plus(String that) { - return plus(new GStringImpl(EMPTY_OBJECT_ARRAY, new String[]{that})); + return plus(new GString(EMPTY_OBJECT_ARRAY, new String[] { that })); } public int getValueCount() { @@ -176,7 +186,7 @@ public abstract class GString extends GroovyObjectSupport implements Comparable, } private int calcInitialCapacity() { - String[] strings = getStrings(); + String[] strings = this.strings; int initialCapacity = 0; for (String string : strings) { @@ -190,7 +200,7 @@ public abstract class GString extends GroovyObjectSupport implements Comparable, @Override public Writer writeTo(Writer out) throws IOException { - String[] s = getStrings(); + String[] s = this.strings; int numberOfValues = values.length; for (int i = 0, size = s.length; i < size; i++) { out.write(s[i]); @@ -223,7 +233,7 @@ public abstract class GString extends GroovyObjectSupport implements Comparable, @Override public void build(final GroovyObject builder) { - final String[] s = getStrings(); + final String[] s = this.strings; final int numberOfValues = values.length; for (int i = 0, size = s.length; i < size; i++) { diff --git a/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java b/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java index e8fd5ca..7247fb4 100644 --- a/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java +++ b/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java @@ -1873,7 +1873,7 @@ public class AsmClassGenerator extends ClassGenerator { public void visitGStringExpression(final GStringExpression expression) { MethodVisitor mv = controller.getMethodVisitor(); - mv.visitTypeInsn(NEW, "org/codehaus/groovy/runtime/GStringImpl"); + mv.visitTypeInsn(NEW, "groovy/lang/GString"); mv.visitInsn(DUP); int size = expression.getValues().size(); @@ -1903,7 +1903,7 @@ public class AsmClassGenerator extends ClassGenerator { } controller.getOperandStack().remove(size); - mv.visitMethodInsn(INVOKESPECIAL, "org/codehaus/groovy/runtime/GStringImpl", "<init>", "([Ljava/lang/Object;[Ljava/lang/String;)V", false); + mv.visitMethodInsn(INVOKESPECIAL, "groovy/lang/GString", "<init>", "([Ljava/lang/Object;[Ljava/lang/String;)V", false); controller.getOperandStack().push(ClassHelper.GSTRING_TYPE); } diff --git a/src/main/java/org/codehaus/groovy/control/CompilationUnit.java b/src/main/java/org/codehaus/groovy/control/CompilationUnit.java index fdfce7f..518c0e2 100644 --- a/src/main/java/org/codehaus/groovy/control/CompilationUnit.java +++ b/src/main/java/org/codehaus/groovy/control/CompilationUnit.java @@ -839,6 +839,8 @@ public class CompilationUnit extends ProcessingUnit { return lookupResult == null ? null : lookupResult.getClassNode(); } private ClassNode getCommonSuperClassNode(ClassNode c, ClassNode d) { + if (c == null || d == null) return ClassHelper.OBJECT_TYPE; + // adapted from ClassWriter code if (c.isDerivedFrom(d)) return d; if (d.isDerivedFrom(c)) return c; diff --git a/src/main/java/org/codehaus/groovy/runtime/GStringImpl.java b/src/main/java/org/codehaus/groovy/runtime/GStringImpl.java deleted file mode 100644 index f7ece63..0000000 --- a/src/main/java/org/codehaus/groovy/runtime/GStringImpl.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.codehaus.groovy.runtime; - -import groovy.lang.GString; - -/** - * Default implementation of a GString used by the compiler. A GString - * consist of a list of values and strings which can be combined to - * create a new String. - * - * @see groovy.lang.GString - */ -public class GStringImpl extends GString { - private static final long serialVersionUID = 3581289038662723858L; - private final String[] strings; - - /** - * Create a new GString with values and strings. - * <p> - * Each value is prefixed by a string, after the last value - * an additional String might be used. This means - * <code>strings.length == values.length || strings.length == values.length + 1</code>. - * <p> - * <b>NOTE:</b> The lengths are <b>not</b> checked. Using different lengths might result - * in unpredictable behaviour. - * - * @param values the value parts - * @param strings the string parts - */ - public GStringImpl(Object[] values, String[] strings) { - super(values); - this.strings = strings; - } - - /** - * Get the strings of this GString. - * <p> - * This methods returns the same array as used in the constructor. Changing - * the values will result in changes of the GString. It is not recommended - * to do so. - */ - @Override - public String[] getStrings() { - return strings.clone(); - } - -} diff --git a/src/test/groovy/lang/DummyGStringBase.java b/src/test/groovy/lang/DummyGStringBase.java index af3d9a2..d92a581 100644 --- a/src/test/groovy/lang/DummyGStringBase.java +++ b/src/test/groovy/lang/DummyGStringBase.java @@ -26,11 +26,7 @@ public class DummyGStringBase extends GString { } public DummyGStringBase(final Object[] values, String[] strings) { - super(values); + super(values, strings); this.strings = strings; } - - public String[] getStrings() { - return strings; - } } diff --git a/src/test/groovy/lang/GStringTest.java b/src/test/groovy/lang/GStringTest.java index 7ef901f..0e7655f 100644 --- a/src/test/groovy/lang/GStringTest.java +++ b/src/test/groovy/lang/GStringTest.java @@ -28,8 +28,8 @@ public class GStringTest extends GroovyTestCase { public void testIterateOverText() { DummyGString compString = new DummyGString(new Object[]{"James"}); - assertArrayEquals(new String[]{"Hello ", "!"}, compString.getStrings()); - assertArrayEquals(new Object[]{"James"}, compString.getValues()); + assertArrayEquals(new String[]{"Hello ", "!"}, compString.getStrings().toArray(new String[0])); + assertArrayEquals(new Object[]{"James"}, compString.getValues().toArray()); assertEquals("Hello James!", compString.toString()); } diff --git a/src/test/org/codehaus/groovy/runtime/InvokeConstructorTest.java b/src/test/org/codehaus/groovy/runtime/InvokeConstructorTest.java index fda5c3c..d7607a9 100644 --- a/src/test/org/codehaus/groovy/runtime/InvokeConstructorTest.java +++ b/src/test/org/codehaus/groovy/runtime/InvokeConstructorTest.java @@ -39,11 +39,7 @@ public class InvokeConstructorTest extends GroovyTestCase { } public void testConstructorWithGStringCoercion() throws Throwable { - GString gstring = new GString(new Object[]{Integer.valueOf(123)}) { - public String[] getStrings() { - return new String[]{""}; - } - }; + GString gstring = new GString(new Object[]{Integer.valueOf(123)}, new String[]{""}); Object expected = Long.valueOf(gstring.toString()); diff --git a/src/test/org/codehaus/groovy/runtime/InvokeMethodTest.java b/src/test/org/codehaus/groovy/runtime/InvokeMethodTest.java index 3b91f3a..14a0e21 100644 --- a/src/test/org/codehaus/groovy/runtime/InvokeMethodTest.java +++ b/src/test/org/codehaus/groovy/runtime/InvokeMethodTest.java @@ -28,7 +28,11 @@ import org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation; import java.math.BigDecimal; import java.text.SimpleDateFormat; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Date; +import java.util.List; /** * Tests method invocation @@ -217,21 +221,13 @@ public class InvokeMethodTest extends GroovyTestCase { } public void testCoerceGStringToString() throws Throwable { - GString param = new GString(new Object[]{"James"}) { - public String[] getStrings() { - return new String[]{"Hello "}; - } - }; + GString param = new GString(new Object[]{"James"}, new String[]{"Hello "}); Object value = invoke(this, "methodTakesString", new Object[]{param}); assertEquals("converted GString to string", param.toString(), value); } public void testCoerceGStringToStringOnGetBytes() throws Throwable { - GString param = new GString(new Object[]{CompilerConfiguration.DEFAULT_SOURCE_ENCODING}) { - public String[] getStrings() { - return new String[]{""}; - } - }; + GString param = new GString(new Object[]{CompilerConfiguration.DEFAULT_SOURCE_ENCODING}, new String[]{""}); Object value = invoke("test", "getBytes", new Object[]{param}); assertEquals("converted GString to string", "test".getBytes(CompilerConfiguration.DEFAULT_SOURCE_ENCODING).getClass(), value.getClass()); } diff --git a/src/test/org/codehaus/groovy/runtime/InvokerTest.java b/src/test/org/codehaus/groovy/runtime/InvokerTest.java index 828d42b..a50ab37 100644 --- a/src/test/org/codehaus/groovy/runtime/InvokerTest.java +++ b/src/test/org/codehaus/groovy/runtime/InvokerTest.java @@ -23,7 +23,14 @@ import groovy.lang.GroovyRuntimeException; import groovy.test.GroovyTestCase; import org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; /** @@ -71,17 +78,9 @@ public class InvokerTest extends GroovyTestCase { assertAsBoolean(false, Boolean.FALSE); assertAsBoolean(false, (String) null); assertAsBoolean(false, ""); - GString emptyGString = new GString(new Object[]{""}) { - public String[] getStrings() { - return new String[]{""}; - } - }; + GString emptyGString = new GString(new Object[]{""}, new String[]{""}); assertAsBoolean(false, emptyGString); - GString nonEmptyGString = new GString(new Object[]{"x"}) { - public String[] getStrings() { - return new String[]{"x"}; - } - }; + GString nonEmptyGString = new GString(new Object[]{"x"}, new String[]{"x"}); assertAsBoolean(true, nonEmptyGString); assertAsBoolean(true, Integer.valueOf(1234)); assertAsBoolean(false, Integer.valueOf(0));