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 2020/09/20 23:36:06 UTC

[groovy] branch GROOVY_3_0_X updated: reuse asExpression and hasUnresolvedGenerics plus other minor edits

This is an automated email from the ASF dual-hosted git repository.

sunlan pushed a commit to branch GROOVY_3_0_X
in repository https://gitbox.apache.org/repos/asf/groovy.git


The following commit(s) were added to refs/heads/GROOVY_3_0_X by this push:
     new 896af63  reuse asExpression and hasUnresolvedGenerics plus other minor edits
896af63 is described below

commit 896af631077e66caea4bda311976f2aa91d9e7f5
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Mon Sep 14 13:33:38 2020 -0500

    reuse asExpression and hasUnresolvedGenerics plus other minor edits
    
    (cherry picked from commit 0b86329fc345c424638648ce62e2ec2d23c83d43)
---
 src/main/groovy/groovy/grape/GrapeIvy.groovy       |  2 +-
 .../ast/builder/AstSpecificationCompiler.groovy    | 19 +++---
 .../java/org/codehaus/groovy/ast/ClassNode.java    |  1 -
 .../codehaus/groovy/ast/expr/CastExpression.java   | 69 +++++++++++-----------
 .../codehaus/groovy/control/ResolveVisitor.java    |  8 +--
 .../transform/stc/StaticTypeCheckingSupport.java   | 20 +------
 .../groovy/parser/antlr4/util/AstDumper.groovy     | 22 +++----
 7 files changed, 60 insertions(+), 81 deletions(-)

diff --git a/src/main/groovy/groovy/grape/GrapeIvy.groovy b/src/main/groovy/groovy/grape/GrapeIvy.groovy
index 9dbc44f..4bb7950 100644
--- a/src/main/groovy/groovy/grape/GrapeIvy.groovy
+++ b/src/main/groovy/groovy/grape/GrapeIvy.groovy
@@ -142,7 +142,7 @@ class GrapeIvy implements GrapeEngine {
     }
 
     File getGrapeCacheDir() {
-        File cache = new File(grapeDir, 'grapes')
+        File cache = new File(getGrapeDir(), 'grapes')
         if (!cache.exists()) {
             cache.mkdirs()
         } else if (!cache.isDirectory()) {
diff --git a/src/main/groovy/org/codehaus/groovy/ast/builder/AstSpecificationCompiler.groovy b/src/main/groovy/org/codehaus/groovy/ast/builder/AstSpecificationCompiler.groovy
index fdc8a22..c4bf303 100644
--- a/src/main/groovy/org/codehaus/groovy/ast/builder/AstSpecificationCompiler.groovy
+++ b/src/main/groovy/org/codehaus/groovy/ast/builder/AstSpecificationCompiler.groovy
@@ -19,6 +19,8 @@
 package org.codehaus.groovy.ast.builder
 
 import groovy.transform.CompileStatic
+import groovy.transform.stc.ClosureParams
+import groovy.transform.stc.SimpleType
 import org.codehaus.groovy.ast.ASTNode
 import org.codehaus.groovy.ast.AnnotationNode
 import org.codehaus.groovy.ast.ClassHelper
@@ -97,11 +99,11 @@ import static org.codehaus.groovy.ast.tools.GeneralUtils.param
 /**
  * Handles parsing the properties from the closure into values that can be referenced.
  *
- * This object is very stateful and not threadsafe. It accumulates expressions in the 
- * 'expression' field as they are found and executed within the DSL. 
+ * This object is very stateful and not threadsafe. It accumulates expressions in the
+ * 'expression' field as they are found and executed within the DSL.
  *
  * Note: this class consists of many one-line method calls. A better implementation
- * might be to take a declarative approach and replace the one-liners with map entries. 
+ * might be to take a declarative approach and replace the one-liners with map entries.
  */
 @SuppressWarnings('BuilderMethodWithSideEffects')
 class AstSpecificationCompiler implements GroovyInterceptable {
@@ -160,17 +162,18 @@ class AstSpecificationCompiler implements GroovyInterceptable {
      *       name of object being constructed, used to create helpful error message.
      * @param argBlock
      *       the actual parameters being specified for the node
-     * @param constructorStatement
-     *       the type specific construction code that will be run
+     * @param ctorBlock
+     *       the type-specific construction code that will be run
      */
     @CompileStatic
-    private void captureAndCreateNode(String name, @DelegatesTo(AstSpecificationCompiler) Closure argBlock, Closure constructorStatement) {
+    private void captureAndCreateNode(String name, @DelegatesTo(AstSpecificationCompiler) Closure argBlock,
+            @ClosureParams(value=SimpleType, options="java.util.List<org.codehaus.groovy.ast.ASTNode>") Closure ctorBlock) {
         if (!argBlock) throw new IllegalArgumentException("nodes of type $name require arguments to be specified")
 
-        def oldProps = new ArrayList(expression)
+        def oldProps = new ArrayList<>(expression)
         expression.clear()
         new AstSpecificationCompiler(argBlock)
-        def result = constructorStatement(expression) // invoke custom constructor for node
+        def result = ctorBlock(expression) // invoke custom constructor for node
         expression.clear()
         expression.addAll(oldProps)
         ((List) expression).add(result)
diff --git a/src/main/java/org/codehaus/groovy/ast/ClassNode.java b/src/main/java/org/codehaus/groovy/ast/ClassNode.java
index 0f7e362..a70ac43 100644
--- a/src/main/java/org/codehaus/groovy/ast/ClassNode.java
+++ b/src/main/java/org/codehaus/groovy/ast/ClassNode.java
@@ -256,7 +256,6 @@ public class ClassNode extends AnnotatedNode implements Opcodes {
         clazz = c;
         lazyInitDone = false;
         isPrimaryNode = false;
-        Optional.ofNullable(getCompileUnit()).ifPresent(cu -> cu.addClass(this));
     }
 
     /**
diff --git a/src/main/java/org/codehaus/groovy/ast/expr/CastExpression.java b/src/main/java/org/codehaus/groovy/ast/expr/CastExpression.java
index c1e6c88..4932112 100644
--- a/src/main/java/org/codehaus/groovy/ast/expr/CastExpression.java
+++ b/src/main/java/org/codehaus/groovy/ast/expr/CastExpression.java
@@ -22,32 +22,37 @@ import org.codehaus.groovy.ast.ClassNode;
 import org.codehaus.groovy.ast.GroovyCodeVisitor;
 
 /**
- * Represents a type cast expression
+ * Represents a typecast expression.
  */
 public class CastExpression extends Expression {
-    
+
     private final Expression expression;
-    private boolean ignoreAutoboxing=false;
-    private boolean coerce = false;
-    private boolean strict = false;
+    private final boolean ignoreAutoboxing;
+
+    private boolean coerce;
+    private boolean strict;
 
-    public static CastExpression asExpression(ClassNode type, Expression expression) {
+    public static CastExpression asExpression(final ClassNode type, final Expression expression) {
         CastExpression answer = new CastExpression(type, expression);
         answer.setCoerce(true);
         return answer;
     }
 
-    public CastExpression(ClassNode type, Expression expression) {
-        this(type,expression,false);
+    public CastExpression(final ClassNode type, final Expression expression) {
+        this(type, expression, false);
     }
 
-    public CastExpression(ClassNode type, Expression expression, boolean ignoreAutoboxing) {
-        super.setType(type);
+    public CastExpression(final ClassNode type, final Expression expression, final boolean ignoreAutoboxing) {
+        this.setType(type);
         this.expression = expression;
         this.ignoreAutoboxing = ignoreAutoboxing;
     }
-    
-    public boolean isIgnoringAutoboxing(){
+
+    public Expression getExpression() {
+        return expression;
+    }
+
+    public boolean isIgnoringAutoboxing() {
         return ignoreAutoboxing;
     }
 
@@ -55,55 +60,53 @@ public class CastExpression extends Expression {
         return coerce;
     }
 
-    public void setCoerce(boolean coerce) {
+    public void setCoerce(final boolean coerce) {
         this.coerce = coerce;
     }
 
     /**
-     * If strict mode is true, then when the compiler generates a cast, it will disable
-     * Groovy casts and rely on a strict cast (CHECKCAST)
-     * @return true if strict mode is enable
+     * If strict mode is true, then when the compiler generates a cast, it will
+     * disable Groovy casts and rely on a strict cast (CHECKCAST).
      */
     public boolean isStrict() {
         return strict;
     }
 
     /**
-     * If strict mode is true, then when the compiler generates a cast, it will disable
-     * Groovy casts and rely on a strict cast (CHECKCAST)
-     * @param strict strict mode
+     * If strict mode is true, then when the compiler generates a cast, it will
+     * disable Groovy casts and rely on a strict cast (CHECKCAST).
      */
     public void setStrict(final boolean strict) {
         this.strict = strict;
     }
 
+    @Override
     public String toString() {
         return super.toString() +"[(" + getType().getName() + ") " + expression + "]";
     }
 
-    public void visit(GroovyCodeVisitor visitor) {
+    @Override
+    public void visit(final GroovyCodeVisitor visitor) {
         visitor.visitCastExpression(this);
     }
 
-    public Expression transformExpression(ExpressionTransformer transformer) {
-        CastExpression ret =  new CastExpression(getType(), transformer.transform(expression));
-        ret.setSourcePosition(this);
+    @Override
+    public Expression transformExpression(final ExpressionTransformer transformer) {
+        CastExpression ret = new CastExpression(getType(), transformer.transform(expression), isIgnoringAutoboxing());
         ret.setCoerce(this.isCoerce());
         ret.setStrict(this.isStrict());
+        ret.setSourcePosition(this);
         ret.copyNodeMetaData(this);
         return ret;
     }
-    
+
+    @Override
     public String getText() {
-        return "(" + getType() + ") " + expression.getText();
-    }
- 
-    public Expression getExpression() {
-        return expression;
-    }
-    
-    public void setType(ClassNode t) {
-        super.setType(t);
+        return "(" + getType().toString(false) + ") " + expression.getText(); // TODO: add alternate for "as"?
     }
 
+    @Override
+    public void setType(final ClassNode type) {
+        super.setType(type);
+    }
 }
diff --git a/src/main/java/org/codehaus/groovy/control/ResolveVisitor.java b/src/main/java/org/codehaus/groovy/control/ResolveVisitor.java
index 3ae6a4f..2c05616 100644
--- a/src/main/java/org/codehaus/groovy/control/ResolveVisitor.java
+++ b/src/main/java/org/codehaus/groovy/control/ResolveVisitor.java
@@ -1186,18 +1186,14 @@ public class ResolveVisitor extends ClassCodeExpressionTransformer {
                             me.addMapEntryExpression((MapEntryExpression) transform(expression));
                         }
                         me.setSourcePosition(list);
-                        CastExpression ce = new CastExpression(left.getType(), me);
-                        ce.setCoerce(true);
-                        return ce;
+                        return CastExpression.asExpression(left.getType(), me);
                     }
                 }
             } else if (be.getRightExpression() instanceof SpreadMapExpression) {
                 // we have C[*:map] -> should become (C) map
                 SpreadMapExpression mapExpression = (SpreadMapExpression) be.getRightExpression();
                 Expression right = transform(mapExpression.getExpression());
-                CastExpression ce = new CastExpression(left.getType(), right);
-                ce.setCoerce(true);
-                return ce;
+                return CastExpression.asExpression(left.getType(), right);
             }
 
             if (be.getRightExpression() instanceof MapEntryExpression) {
diff --git a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
index ec5c502..d531368 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
@@ -993,25 +993,7 @@ public abstract class StaticTypeCheckingSupport {
      * @return true if it is using any placeholder in generics types
      */
     public static boolean isUsingUncheckedGenerics(final ClassNode node) {
-        if (node.isArray()) return isUsingUncheckedGenerics(node.getComponentType());
-        GenericsType[] genericsTypes = node.getGenericsTypes();
-        if (genericsTypes != null) {
-            for (GenericsType genericsType : genericsTypes) {
-                if (genericsType.isPlaceholder()) return true;
-                if (genericsType.isWildcard()) {
-                    ClassNode lowerBound = genericsType.getLowerBound();
-                    ClassNode[] upperBounds = genericsType.getUpperBounds();
-                    if (lowerBound != null) {
-                        if (lowerBound.isGenericsPlaceHolder() || isUsingUncheckedGenerics(lowerBound)) return true;
-                    } else if (upperBounds != null) {
-                        if (upperBounds[0].isGenericsPlaceHolder() || isUsingUncheckedGenerics(upperBounds[0])) return true;
-                    }
-                } else {
-                    if (isUsingUncheckedGenerics(genericsType.getType())) return true;
-                }
-            }
-        }
-        return false;
+        return GenericsUtils.hasUnresolvedGenerics(node);
     }
 
     /**
diff --git a/subprojects/parser-antlr4/src/test/groovy/org/apache/groovy/parser/antlr4/util/AstDumper.groovy b/subprojects/parser-antlr4/src/test/groovy/org/apache/groovy/parser/antlr4/util/AstDumper.groovy
index 8d3b8d4..165f2f2 100644
--- a/subprojects/parser-antlr4/src/test/groovy/org/apache/groovy/parser/antlr4/util/AstDumper.groovy
+++ b/subprojects/parser-antlr4/src/test/groovy/org/apache/groovy/parser/antlr4/util/AstDumper.groovy
@@ -105,10 +105,10 @@ import java.lang.reflect.Modifier
  */
 @CompileStatic
 class AstDumper {
-    private ModuleNode ast;
+    private final ModuleNode ast
 
-    AstDumper(ModuleNode ast) {
-        this.ast = ast;
+    AstDumper(final ModuleNode ast) {
+        this.ast = ast
     }
 
     /**
@@ -117,23 +117,19 @@ class AstDumper {
      * @return the groovy source code
      */
     String gen() {
-        StringWriter out = new StringWriter();
+        try (StringWriter out = new StringWriter()) {
+            AstNodeToScriptVisitor visitor = new AstNodeToScriptVisitor(out, true, true)
 
-        try {
-            AstNodeToScriptVisitor visitor = new AstNodeToScriptVisitor(out, true, true);
-
-            new LinkedList<ClassNode>((List) this.ast?.classes ?: []).sort { c1, c2 -> c1.name <=> c2.name }?.each {
+            new LinkedList<ClassNode>(this.ast?.classes ?: Collections.<ClassNode>emptyList()).sort { c1, c2 -> c1.name <=> c2.name }?.each {
                 visitor.call(new SourceUnit((String) null, (ReaderSource) null, null, null, null) {
                     @Override
-                    public ModuleNode getAST() {
-                        return AstDumper.this.ast;
+                    ModuleNode getAST() {
+                        return AstDumper.this.ast
                     }
                 }, null, it)
             }
 
-            return out.toString().replaceAll(/([\w_$]+)@[0-9a-z]+/, '$1@<hashcode>');
-        } finally {
-            out.close();
+            return out.toString().replaceAll(/([\w_$]+)@[0-9a-z]+/, '$1@<hashcode>')
         }
     }
 }