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 2017/06/13 05:36:14 UTC

[2/3] groovy git commit: Minor refactoring

Minor refactoring


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

Branch: refs/heads/GROOVY_2_6_X
Commit: b2bb7229490a9f2031c1d221dea3585193a0162c
Parents: 1c5dbda
Author: sunlan <su...@apache.org>
Authored: Sat Jun 10 11:56:36 2017 +0800
Committer: paulk <pa...@asert.com.au>
Committed: Tue Jun 13 15:35:34 2017 +1000

----------------------------------------------------------------------
 src/main/org/codehaus/groovy/ast/ASTNode.java   |  91 ++----------
 .../groovy/ast/NodeMetaDataHandler.java         | 137 +++++++++++++++++++
 .../apache/groovy/parser/antlr4/GroovyParser.g4 |  53 ++-----
 .../apache/groovy/parser/antlr4/AstBuilder.java |  48 +++----
 4 files changed, 175 insertions(+), 154 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/b2bb7229/src/main/org/codehaus/groovy/ast/ASTNode.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/ast/ASTNode.java b/src/main/org/codehaus/groovy/ast/ASTNode.java
index 058af78..a192e68 100644
--- a/src/main/org/codehaus/groovy/ast/ASTNode.java
+++ b/src/main/org/codehaus/groovy/ast/ASTNode.java
@@ -18,10 +18,8 @@
  */
 package org.codehaus.groovy.ast;
 
-import org.codehaus.groovy.GroovyBugError;
 import org.codehaus.groovy.util.ListHashMap;
 
-import java.util.Collections;
 import java.util.Map;
 
 /**
@@ -46,13 +44,13 @@ import java.util.Map;
  * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
  * @author <a href="mailto:blackdrag@gmx.org">Jochen "blackdrag" Theodorou</a>
  */
-public class ASTNode {
+public class ASTNode implements NodeMetaDataHandler {
 
     private int lineNumber = -1;
     private int columnNumber = -1;
     private int lastLineNumber = -1;
     private int lastColumnNumber = -1;
-    private ListHashMap metaDataMap = null;
+    private Map metaDataMap = null;
 
     public void visit(GroovyCodeVisitor visitor) {
         throw new RuntimeException("No visit() method implemented for class: " + getClass().getName());
@@ -108,93 +106,22 @@ public class ASTNode {
         this.lastColumnNumber = node.getLastColumnNumber();
         this.lineNumber = node.getLineNumber();
     }
-    
-    /**
-     * Gets the node meta data. 
-     * 
-     * @param key - the meta data key
-     * @return the node meta data value for this key
-     */
-    public <T> T getNodeMetaData(Object key) {
-        if (metaDataMap == null) {
-            return (T) null;
-        }
-        return (T) metaDataMap.get(key);
-    }
 
     /**
      * Copies all node meta data from the other node to this one
      * @param other - the other node
      */
     public void copyNodeMetaData(ASTNode other) {
-        if (other.metaDataMap == null) {
-            return;
-        }
-        if (metaDataMap == null) {
-            metaDataMap = new ListHashMap();
-        }
-        metaDataMap.putAll(other.metaDataMap);
-    }
-    
-    /**
-     * Sets the node meta data. 
-     * 
-     * @param key - the meta data key
-     * @param value - the meta data value
-     * @throws GroovyBugError if key is null or there is already meta 
-     *                        data under that key
-     */
-    public void setNodeMetaData(Object key, Object value) {
-        if (key==null) throw new GroovyBugError("Tried to set meta data with null key on "+this+".");
-        if (metaDataMap == null) {
-            metaDataMap = new ListHashMap();
-        }
-        Object old = metaDataMap.put(key,value);
-        if (old!=null) throw new GroovyBugError("Tried to overwrite existing meta data "+this+".");
+        copyNodeMetaData((NodeMetaDataHandler) other);
     }
 
-    /**
-     * Sets the node meta data but allows overwriting values.
-     *
-     * @param key   - the meta data key
-     * @param value - the meta data value
-     * @return the old node meta data value for this key
-     * @throws GroovyBugError if key is null
-     */
-    public Object putNodeMetaData(Object key, Object value) {
-        if (key == null) throw new GroovyBugError("Tried to set meta data with null key on " + this + ".");
-        if (metaDataMap == null) {
-            metaDataMap = new ListHashMap();
-        }
-        return metaDataMap.put(key, value);
-    }
-
-    /**
-     * Removes a node meta data entry.
-     * 
-     * @param key - the meta data key
-     * @throws GroovyBugError if the key is null
-     */
-    public void removeNodeMetaData(Object key) {
-        if (key==null) throw new GroovyBugError("Tried to remove meta data with null key "+this+".");
-        if (metaDataMap == null) {
-            return;
-        }
-        metaDataMap.remove(key);
-    }
-
-    /**
-     * Returns an unmodifiable view of the current node metadata.
-     * @return the node metadata. Always not null.
-     */
-    public Map<?,?> getNodeMetaData() {
-        if (metaDataMap==null) {
-            return Collections.emptyMap();
-        }
-        return Collections.unmodifiableMap(metaDataMap);
+    @Override
+    public ListHashMap getMetaDataMap() {
+        return (ListHashMap) metaDataMap;
     }
 
-    public ListHashMap getMetaDataMap() {
-        return metaDataMap;
+    @Override
+    public void setMetaDataMap(Map<?, ?> metaDataMap) {
+        this.metaDataMap = metaDataMap;
     }
 }

http://git-wip-us.apache.org/repos/asf/groovy/blob/b2bb7229/src/main/org/codehaus/groovy/ast/NodeMetaDataHandler.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/ast/NodeMetaDataHandler.java b/src/main/org/codehaus/groovy/ast/NodeMetaDataHandler.java
new file mode 100644
index 0000000..280cd6b
--- /dev/null
+++ b/src/main/org/codehaus/groovy/ast/NodeMetaDataHandler.java
@@ -0,0 +1,137 @@
+/*
+ *  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.ast;
+
+import org.codehaus.groovy.GroovyBugError;
+import org.codehaus.groovy.util.ListHashMap;
+
+import java.util.Collections;
+import java.util.Map;
+
+/**
+ * An interface to mark a node being able to handle metadata
+ */
+public interface NodeMetaDataHandler {
+    /**
+     * Gets the node meta data.
+     *
+     * @param key - the meta data key
+     * @return the node meta data value for this key
+     */
+    default <T> T getNodeMetaData(Object key) {
+        Map<?, ?> metaDataMap = this.getMetaDataMap();
+
+        if (metaDataMap == null) {
+            return (T) null;
+        }
+        return (T) metaDataMap.get(key);
+    }
+
+    /**
+     * Copies all node meta data from the other node to this one
+     *
+     * @param other - the other node
+     */
+    default void copyNodeMetaData(NodeMetaDataHandler other) {
+        Map otherMetaDataMap = other.getMetaDataMap();
+        if (otherMetaDataMap == null) {
+            return;
+        }
+        Map metaDataMap = this.getMetaDataMap();
+        if (metaDataMap == null) {
+            metaDataMap = new ListHashMap();
+            this.setMetaDataMap(metaDataMap);
+        }
+
+        metaDataMap.putAll(otherMetaDataMap);
+    }
+
+    /**
+     * Sets the node meta data.
+     *
+     * @param key   - the meta data key
+     * @param value - the meta data value
+     * @throws GroovyBugError if key is null or there is already meta
+     *                        data under that key
+     */
+    default void setNodeMetaData(Object key, Object value) {
+        if (key == null) throw new GroovyBugError("Tried to set meta data with null key on " + this + ".");
+
+        Map metaDataMap = this.getMetaDataMap();
+        if (metaDataMap == null) {
+            metaDataMap = new ListHashMap();
+            this.setMetaDataMap(metaDataMap);
+        }
+        Object old = metaDataMap.put(key, value);
+        if (old != null) throw new GroovyBugError("Tried to overwrite existing meta data " + this + ".");
+    }
+
+    /**
+     * Sets the node meta data but allows overwriting values.
+     *
+     * @param key   - the meta data key
+     * @param value - the meta data value
+     * @return the old node meta data value for this key
+     * @throws GroovyBugError if key is null
+     */
+    default Object putNodeMetaData(Object key, Object value) {
+        if (key == null) throw new GroovyBugError("Tried to set meta data with null key on " + this + ".");
+
+        Map metaDataMap = this.getMetaDataMap();
+        if (metaDataMap == null) {
+            metaDataMap = new ListHashMap();
+            this.setMetaDataMap(metaDataMap);
+        }
+        return metaDataMap.put(key, value);
+    }
+
+    /**
+     * Removes a node meta data entry.
+     *
+     * @param key - the meta data key
+     * @throws GroovyBugError if the key is null
+     */
+    default void removeNodeMetaData(Object key) {
+        if (key == null) throw new GroovyBugError("Tried to remove meta data with null key " + this + ".");
+
+        Map metaDataMap = this.getMetaDataMap();
+        if (metaDataMap == null) {
+            return;
+        }
+        metaDataMap.remove(key);
+    }
+
+    /**
+     * Returns an unmodifiable view of the current node metadata.
+     *
+     * @return the node metadata. Always not null.
+     */
+    default Map<?, ?> getNodeMetaData() {
+        Map metaDataMap = this.getMetaDataMap();
+
+        if (metaDataMap == null) {
+            return Collections.emptyMap();
+        }
+        return Collections.unmodifiableMap(metaDataMap);
+    }
+
+    Map<?, ?> getMetaDataMap();
+
+    void setMetaDataMap(Map<?, ?> metaDataMap);
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/b2bb7229/subprojects/parser-antlr4/src/main/antlr4/org/apache/groovy/parser/antlr4/GroovyParser.g4
----------------------------------------------------------------------
diff --git a/subprojects/parser-antlr4/src/main/antlr4/org/apache/groovy/parser/antlr4/GroovyParser.g4 b/subprojects/parser-antlr4/src/main/antlr4/org/apache/groovy/parser/antlr4/GroovyParser.g4
index 3e6bc07..1fb2c97 100644
--- a/subprojects/parser-antlr4/src/main/antlr4/org/apache/groovy/parser/antlr4/GroovyParser.g4
+++ b/subprojects/parser-antlr4/src/main/antlr4/org/apache/groovy/parser/antlr4/GroovyParser.g4
@@ -41,14 +41,13 @@ options {
 
 @header {
     import java.util.Map;
-    import org.codehaus.groovy.util.ListHashMap;
+    import org.codehaus.groovy.ast.NodeMetaDataHandler;
     import org.apache.groovy.parser.antlr4.SemanticPredicates;
-    import org.codehaus.groovy.GroovyBugError;
 }
 
 @members {
 
-    public static class GroovyParserRuleContext extends ParserRuleContext {
+    public static class GroovyParserRuleContext extends ParserRuleContext implements NodeMetaDataHandler {
         private Map metaDataMap = null;
 
         public GroovyParserRuleContext() {}
@@ -57,50 +56,14 @@ options {
             super(parent, invokingStateNumber);
         }
 
-        /**
-         * Gets the node meta data.
-         *
-         * @param key - the meta data key
-         * @return the node meta data value for this key
-         */
-        public <T> T getNodeMetaData(Object key) {
-            if (metaDataMap == null) {
-                return (T) null;
-            }
-            return (T) metaDataMap.get(key);
+        @Override
+        public Map<?, ?> getMetaDataMap() {
+            return this.metaDataMap;
         }
 
-        /**
-         * Sets the node meta data.
-         *
-         * @param key - the meta data key
-         * @param value - the meta data value
-         * @throws GroovyBugError if key is null or there is already meta
-         *                        data under that key
-         */
-        public void setNodeMetaData(Object key, Object value) {
-            if (key==null) throw new GroovyBugError("Tried to set meta data with null key on "+this+".");
-            if (metaDataMap == null) {
-                metaDataMap = new ListHashMap();
-            }
-            Object old = metaDataMap.put(key,value);
-            if (old!=null) throw new GroovyBugError("Tried to overwrite existing meta data "+this+".");
-        }
-
-        /**
-         * Sets the node meta data but allows overwriting values.
-         *
-         * @param key   - the meta data key
-         * @param value - the meta data value
-         * @return the old node meta data value for this key
-         * @throws GroovyBugError if key is null
-         */
-        public Object putNodeMetaData(Object key, Object value) {
-            if (key == null) throw new GroovyBugError("Tried to set meta data with null key on " + this + ".");
-            if (metaDataMap == null) {
-                metaDataMap = new ListHashMap();
-            }
-            return metaDataMap.put(key, value);
+        @Override
+        public void setMetaDataMap(Map<?, ?> metaDataMap) {
+            this.metaDataMap = metaDataMap;
         }
     }
 

http://git-wip-us.apache.org/repos/asf/groovy/blob/b2bb7229/subprojects/parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
----------------------------------------------------------------------
diff --git a/subprojects/parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java b/subprojects/parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
index add3e6d..c8d8eae 100644
--- a/subprojects/parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
+++ b/subprojects/parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
@@ -48,6 +48,7 @@ import org.codehaus.groovy.ast.ImportNode;
 import org.codehaus.groovy.ast.InnerClassNode;
 import org.codehaus.groovy.ast.MethodNode;
 import org.codehaus.groovy.ast.ModuleNode;
+import org.codehaus.groovy.ast.NodeMetaDataHandler;
 import org.codehaus.groovy.ast.PackageNode;
 import org.codehaus.groovy.ast.Parameter;
 import org.codehaus.groovy.ast.PropertyNode;
@@ -1749,7 +1750,7 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> implements Groov
                                     (PropertyExpression) baseExpr, arguments),
                             arguments);
 
-        } else if (baseExpr instanceof MethodCallExpression && !isTrue(baseExpr, IS_INSIDE_PARENTHESES)) { // e.g. m {} a, b  OR  m(...) a, b
+        } else if (baseExpr instanceof MethodCallExpression && !isInsideParentheses(baseExpr)) { // e.g. m {} a, b  OR  m(...) a, b
             if (asBoolean(arguments)) {
                 // The error should never be thrown.
                 throw new GroovyBugError("When baseExpr is a instance of MethodCallExpression, which should follow NO argumentList");
@@ -1757,7 +1758,7 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> implements Groov
 
             methodCallExpression = (MethodCallExpression) baseExpr;
         } else if (
-                !isTrue(baseExpr, IS_INSIDE_PARENTHESES)
+                !isInsideParentheses(baseExpr)
                         && (baseExpr instanceof VariableExpression /* e.g. m 1, 2 */
                         || baseExpr instanceof GStringExpression /* e.g. "$m" 1, 2 */
                         || (baseExpr instanceof ConstantExpression && isTrue(baseExpr, IS_STRING)) /* e.g. "m" 1, 2 */)
@@ -1852,8 +1853,6 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> implements Groov
     public Expression visitParExpression(ParExpressionContext ctx) {
         Expression expression = this.visitExpressionInPar(ctx.expressionInPar());
 
-        expression.putNodeMetaData(IS_INSIDE_PARENTHESES, true);
-
         Integer insideParenLevel = expression.getNodeMetaData(INSIDE_PARENTHESES_LEVEL);
         if (asBoolean((Object) insideParenLevel)) {
             insideParenLevel++;
@@ -1984,7 +1983,7 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> implements Groov
             Expression argumentsExpr = this.visitArguments(ctx.arguments());
             this.configureAST(argumentsExpr, ctx);
 
-            if (isTrue(baseExpr, IS_INSIDE_PARENTHESES)) { // e.g. (obj.x)(), (obj.@x)()
+            if (isInsideParentheses(baseExpr)) { // e.g. (obj.x)(), (obj.@x)()
                 MethodCallExpression methodCallExpression =
                         new MethodCallExpression(
                                 baseExpr,
@@ -2437,7 +2436,7 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> implements Groov
         ExpressionContext expressionCtx = ctx.expression();
         Expression expression = (Expression) this.visit(expressionCtx);
 
-        Boolean insidePar = isTrue(expression, IS_INSIDE_PARENTHESES);
+        Boolean insidePar = isInsideParentheses(expression);
 
         switch (ctx.op.getType()) {
             case ADD: {
@@ -2629,7 +2628,7 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> implements Groov
         Expression leftExpr = (Expression) this.visit(ctx.left);
 
         if (leftExpr instanceof VariableExpression
-                && isTrue(leftExpr, IS_INSIDE_PARENTHESES)) { // it is a special multiple assignment whose variable count is only one, e.g. (a) = [1]
+                && isInsideParentheses(leftExpr)) { // it is a special multiple assignment whose variable count is only one, e.g. (a) = [1]
 
             if ((Integer) leftExpr.getNodeMetaData(INSIDE_PARENTHESES_LEVEL) > 1) {
                 throw createParsingFailedException("Nested parenthesis is not allowed in multiple assignment, e.g. ((a)) = b", ctx);
@@ -2648,7 +2647,7 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> implements Groov
                 !(
                         (leftExpr instanceof VariableExpression
 //                                && !(THIS_STR.equals(leftExpr.getText()) || SUPER_STR.equals(leftExpr.getText()))     // commented, e.g. this = value // this will be transformed to $this
-                                && !isTrue(leftExpr, IS_INSIDE_PARENTHESES)) // e.g. p = 123
+                                && !isInsideParentheses(leftExpr)) // e.g. p = 123
 
                                 || leftExpr instanceof PropertyExpression // e.g. obj.p = 123
 
@@ -2929,7 +2928,7 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> implements Groov
             Expression expression = (Expression) this.visit(ctx.primary());
 
             // if the key is variable and not inside parentheses, convert it to a constant, e.g. [a:1, b:2]
-            if (expression instanceof VariableExpression && !isTrue(expression, IS_INSIDE_PARENTHESES)) {
+            if (expression instanceof VariableExpression && !isInsideParentheses(expression)) {
                 expression =
                         this.configureAST(
                                 new ConstantExpression(((VariableExpression) expression).getName()),
@@ -4019,6 +4018,16 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> implements Groov
         return moduleNode.getStatementBlock().isEmpty() && moduleNode.getMethods().isEmpty() && moduleNode.getClasses().isEmpty();
     }
 
+    private boolean isInsideParentheses(NodeMetaDataHandler nodeMetaDataHandler) {
+        Integer insideParenLevel = nodeMetaDataHandler.getNodeMetaData(INSIDE_PARENTHESES_LEVEL);
+
+        if (asBoolean((Object) insideParenLevel)) {
+            return insideParenLevel > 0;
+        }
+
+        return false;
+    }
+
     private void addEmptyReturnStatement() {
         moduleNode.addStatement(ReturnStatement.RETURN_NULL_OR_VOID);
     }
@@ -4182,29 +4191,15 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> implements Groov
         return astNode;
     }
 
-    private boolean isTrue(GroovyParserRuleContext ctx, String key) {
-        Object nmd = ctx.getNodeMetaData(key);
-
-        if (null == nmd) {
-            return false;
-        }
-
-        if (!(nmd instanceof Boolean)) {
-            throw new GroovyBugError(ctx + " ctx meta data[" + key + "] is not an instance of Boolean");
-        }
-
-        return (Boolean) nmd;
-    }
-
-    private boolean isTrue(ASTNode node, String key) {
-        Object nmd = node.getNodeMetaData(key);
+    private boolean isTrue(NodeMetaDataHandler nodeMetaDataHandler, String key) {
+        Object nmd = nodeMetaDataHandler.getNodeMetaData(key);
 
         if (null == nmd) {
             return false;
         }
 
         if (!(nmd instanceof Boolean)) {
-            throw new GroovyBugError(node + " node meta data[" + key + "] is not an instance of Boolean");
+            throw new GroovyBugError(nodeMetaDataHandler + " node meta data[" + key + "] is not an instance of Boolean");
         }
 
         return (Boolean) nmd;
@@ -4434,7 +4429,6 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> implements Groov
     private static final Set<String> PRIMITIVE_TYPE_SET = Collections.unmodifiableSet(new HashSet<>(Arrays.asList("boolean", "char", "byte", "short", "int", "long", "float", "double")));
     private static final Logger LOGGER = Logger.getLogger(AstBuilder.class.getName());
 
-    private static final String IS_INSIDE_PARENTHESES = "_IS_INSIDE_PARENTHESES";
     private static final String INSIDE_PARENTHESES_LEVEL = "_INSIDE_PARENTHESES_LEVEL";
 
     private static final String IS_INSIDE_INSTANCEOF_EXPR = "_IS_INSIDE_INSTANCEOF_EXPR";