You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by su...@apache.org on 2018/02/18 10:28:34 UTC

[1/2] groovy git commit: Implement `inverse` for maps

Repository: groovy
Updated Branches:
  refs/heads/master 6ab675920 -> ee6060bee


Implement `inverse` for maps


Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/9699e994
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/9699e994
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/9699e994

Branch: refs/heads/master
Commit: 9699e99483b8f53e4a77762225343a86ee3c4783
Parents: 6ab6759
Author: danielsun1106 <re...@hotmail.com>
Authored: Sun Feb 18 18:02:30 2018 +0800
Committer: danielsun1106 <re...@hotmail.com>
Committed: Sun Feb 18 18:02:30 2018 +0800

----------------------------------------------------------------------
 src/main/java/org/apache/groovy/util/Maps.java  | 39 ++++++++++++++++++++
 .../java/org/apache/groovy/util/MapsTest.java   | 34 +++++++++++++++++
 2 files changed, 73 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/9699e994/src/main/java/org/apache/groovy/util/Maps.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/groovy/util/Maps.java b/src/main/java/org/apache/groovy/util/Maps.java
index 94ec26e..b560a4f 100644
--- a/src/main/java/org/apache/groovy/util/Maps.java
+++ b/src/main/java/org/apache/groovy/util/Maps.java
@@ -5778,4 +5778,43 @@ public abstract class Maps {
         return Collections.unmodifiableMap(map);
     }
 
+    /**
+     * Returns the inverse view of this map, and duplicated key is not allowed
+     *
+     * @param map the map to inverse
+     * @param <K> key type
+     * @param <V> value type
+     * @return the inverse view of this map
+     */
+    public static <K, V> Map<V, K> inverse(Map<K, V> map) {
+        return inverse(map, false);
+    }
+
+    /**
+     * Returns the inverse view of this map
+     *
+     * @param map the map to inverse
+     * @param force whether to put anyway even if duplicated key exists
+     * @param <K> key type
+     * @param <V> value type
+     * @return the inverse view of this map
+     */
+    public static <K, V> Map<V, K> inverse(Map<K, V> map, boolean force) {
+        // Because we can not rely on 3rd party library(excluding antlr, asm), we have to implement our own utils such as the `inverse` method...
+        // Actually `BiMap` of Guava and `BidiMap` of commons-collections are both suitable for this scenario.
+
+        Map<V, K> resultMap = new LinkedHashMap<>();
+
+        for (Map.Entry<K, V> entry : map.entrySet()) {
+            V value = entry.getValue();
+
+            if (!force && resultMap.containsKey(value)) {
+                throw new IllegalArgumentException("duplicated key found: " + value);
+            }
+
+            resultMap.put(value, entry.getKey());
+        }
+
+        return Collections.<V, K>unmodifiableMap(resultMap);
+    }
 }

http://git-wip-us.apache.org/repos/asf/groovy/blob/9699e994/src/test/java/org/apache/groovy/util/MapsTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/groovy/util/MapsTest.java b/src/test/java/org/apache/groovy/util/MapsTest.java
new file mode 100644
index 0000000..4a1bd10
--- /dev/null
+++ b/src/test/java/org/apache/groovy/util/MapsTest.java
@@ -0,0 +1,34 @@
+package org.apache.groovy.util;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.Map;
+
+import static org.apache.groovy.util.Maps.of;
+import static org.junit.Assert.*;
+
+public class MapsTest {
+
+    @Test
+    public void inverse() {
+        Map<String, Integer> map = Maps.of("a", 1, "b", 2, "c", 3);
+        Map<Integer, String> inversedMap = Maps.inverse(map);
+
+        Assert.assertEquals(map.size(), inversedMap.size());
+        for (Map.Entry<Integer, String> entry : inversedMap.entrySet()) {
+            Assert.assertEquals(map.get(entry.getValue()), entry.getKey());
+        }
+
+        try {
+            Maps.inverse(Maps.of("a", 1, "b", 2, "c", 2));
+        } catch (IllegalArgumentException e) {
+            Assert.assertTrue(e.getMessage().contains("duplicated key found: 2"));
+        }
+
+        Map<Integer, String> inversedMap2 = Maps.inverse(Maps.of("a", 1, "b", 2, "c", 2), true);
+        Assert.assertEquals(2, inversedMap2.size());
+        Assert.assertEquals("a", inversedMap2.get(1));
+        Assert.assertEquals("c", inversedMap2.get(2));
+    }
+}
\ No newline at end of file


[2/2] groovy git commit: Minor refactoring: remove duplicated code of `ClassHelper`

Posted by su...@apache.org.
Minor refactoring: remove duplicated code of `ClassHelper`


Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/ee6060be
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/ee6060be
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/ee6060be

Branch: refs/heads/master
Commit: ee6060bee045631cca608a48fb36c3483aaafec3
Parents: 9699e99
Author: danielsun1106 <re...@hotmail.com>
Authored: Sun Feb 18 18:28:28 2018 +0800
Committer: danielsun1106 <re...@hotmail.com>
Committed: Sun Feb 18 18:28:28 2018 +0800

----------------------------------------------------------------------
 .../org/codehaus/groovy/ast/ClassHelper.java    | 67 +++++++++-----------
 1 file changed, 29 insertions(+), 38 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/ee6060be/src/main/java/org/codehaus/groovy/ast/ClassHelper.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/ClassHelper.java b/src/main/java/org/codehaus/groovy/ast/ClassHelper.java
index d8ce0d7..8362d8d 100644
--- a/src/main/java/org/codehaus/groovy/ast/ClassHelper.java
+++ b/src/main/java/org/codehaus/groovy/ast/ClassHelper.java
@@ -28,6 +28,7 @@ import groovy.lang.MetaClass;
 import groovy.lang.Range;
 import groovy.lang.Reference;
 import groovy.lang.Script;
+import org.apache.groovy.util.Maps;
 import org.codehaus.groovy.classgen.asm.util.TypeDescriptionUtil;
 import org.codehaus.groovy.runtime.GeneratedClosure;
 import org.codehaus.groovy.runtime.GeneratedLambda;
@@ -248,6 +249,18 @@ public class ClassHelper {
         return makeWithoutCaching(name);
     }
 
+    private static final Map<ClassNode, ClassNode> PRIMARY_TYPE_TO_WRAPPER_TYPE_MAP = Maps.of(
+            boolean_TYPE, Boolean_TYPE,
+            byte_TYPE, Byte_TYPE,
+            char_TYPE, Character_TYPE,
+            short_TYPE, Short_TYPE,
+            int_TYPE, Integer_TYPE,
+            long_TYPE, Long_TYPE,
+            float_TYPE, Float_TYPE,
+            double_TYPE, Double_TYPE,
+            VOID_TYPE, void_WRAPPER_TYPE
+    );
+
     /**
      * Creates a ClassNode containing the wrapper of a ClassNode
      * of primitive type. Any ClassNode representing a primitive
@@ -268,51 +281,29 @@ public class ClassHelper {
     public static ClassNode getWrapper(ClassNode cn) {
         cn = cn.redirect();
         if (!isPrimitiveType(cn)) return cn;
-        if (cn == boolean_TYPE) {
-            return Boolean_TYPE;
-        } else if (cn == byte_TYPE) {
-            return Byte_TYPE;
-        } else if (cn == char_TYPE) {
-            return Character_TYPE;
-        } else if (cn == short_TYPE) {
-            return Short_TYPE;
-        } else if (cn == int_TYPE) {
-            return Integer_TYPE;
-        } else if (cn == long_TYPE) {
-            return Long_TYPE;
-        } else if (cn == float_TYPE) {
-            return Float_TYPE;
-        } else if (cn == double_TYPE) {
-            return Double_TYPE;
-        } else if (cn == VOID_TYPE) {
-            return void_WRAPPER_TYPE;
-        } else {
-            return cn;
+
+        ClassNode result = PRIMARY_TYPE_TO_WRAPPER_TYPE_MAP.get(cn);
+
+        if (null != result) {
+            return result;
         }
+
+        return cn;
     }
 
+    private static final Map<ClassNode, ClassNode> WRAPPER_TYPE_TO_PRIMARY_TYPE_MAP = Maps.inverse(PRIMARY_TYPE_TO_WRAPPER_TYPE_MAP);
+
     public static ClassNode getUnwrapper(ClassNode cn) {
         cn = cn.redirect();
         if (isPrimitiveType(cn)) return cn;
-        if (cn == Boolean_TYPE) {
-            return boolean_TYPE;
-        } else if (cn == Byte_TYPE) {
-            return byte_TYPE;
-        } else if (cn == Character_TYPE) {
-            return char_TYPE;
-        } else if (cn == Short_TYPE) {
-            return short_TYPE;
-        } else if (cn == Integer_TYPE) {
-            return int_TYPE;
-        } else if (cn == Long_TYPE) {
-            return long_TYPE;
-        } else if (cn == Float_TYPE) {
-            return float_TYPE;
-        } else if (cn == Double_TYPE) {
-            return double_TYPE;
-        } else {
-            return cn;
+
+        ClassNode result = WRAPPER_TYPE_TO_PRIMARY_TYPE_MAP.get(cn);
+
+        if (null != result) {
+            return result;
         }
+
+        return cn;
     }