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 2017/04/07 13:30:44 UTC

[01/50] [abbrv] groovy git commit: fixed documentation of default Grape root directory (closes #506)

Repository: groovy
Updated Branches:
  refs/heads/parrot 3b1a72049 -> 921fa3d90


fixed documentation of default Grape root directory (closes #506)


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

Branch: refs/heads/parrot
Commit: 5d3f7477e99d0dd132fb624f307b1d3ca914a587
Parents: 8a95665
Author: Keegan Witt <ke...@gmail.com>
Authored: Wed Mar 1 12:24:00 2017 -0500
Committer: Keegan Witt <ke...@gmail.com>
Committed: Wed Mar 1 16:28:10 2017 -0500

----------------------------------------------------------------------
 src/spec/doc/grape.adoc | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/5d3f7477/src/spec/doc/grape.adoc
----------------------------------------------------------------------
diff --git a/src/spec/doc/grape.adoc b/src/spec/doc/grape.adoc
index 952aecc..f072cb8 100644
--- a/src/spec/doc/grape.adoc
+++ b/src/spec/doc/grape.adoc
@@ -167,7 +167,7 @@ version).
 * `classifier` - The optional classifier to use (for example, _jdk15_)
 
 The downloaded modules will be stored according to Ivy\u2019s standard
-mechanism with a cache root of `~/.groovy/grape`
+mechanism with a cache root of `~/.groovy/grapes`
 
 [[Grape-Usage]]
 == Usage
@@ -354,10 +354,10 @@ dependencies expressed in an ivy like format.
 
 If you need to change the directory grape uses for downloading libraries
 you can specify the grape.root system property to change the default
-(which is ~/.groovy/grape)
+(which is ~/.groovy/grapes)
 
 -------------------------------------------------
-groovy -Dgrape.root=/repo/grape yourscript.groovy
+groovy -Dgrape.root=/repo/grapes yourscript.groovy
 -------------------------------------------------
 
 [[Grape-CustomizeIvysettings]]


[48/50] [abbrv] groovy git commit: Fix non-deterministic selection of interface method in `@CompileStatic`

Posted by su...@apache.org.
Fix non-deterministic selection of interface method in `@CompileStatic`

This commit makes sure that the list of methods we choose from when multiple methods
are found in interfaces is always in the same order. Without this, it results in non
reproducible builds, where the bytecode would once choose to call the method from
one interface, and another time from the other interface. While the bytecode is valid,
it kills tools like Gradle which rely on the ABI to detect changes.


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

Branch: refs/heads/parrot
Commit: d52d28a461bcbe2ddb236c95eea6af8ec7041e2c
Parents: b2d95c2
Author: Cedric Champeau <cc...@apache.org>
Authored: Thu Apr 6 18:51:30 2017 +0200
Committer: Cedric Champeau <cc...@apache.org>
Committed: Thu Apr 6 18:59:07 2017 +0200

----------------------------------------------------------------------
 src/main/org/codehaus/groovy/ast/ClassNode.java |  3 +-
 .../codehaus/groovy/ast/tools/GeneralUtils.java |  4 +-
 .../stc/StaticTypeCheckingSupport.java          |  2 +-
 .../classgen/asm/sc/bugs/Groovy8142Bug.groovy   | 51 ++++++++++++++++++++
 4 files changed, 55 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/d52d28a4/src/main/org/codehaus/groovy/ast/ClassNode.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/ast/ClassNode.java b/src/main/org/codehaus/groovy/ast/ClassNode.java
index 9b885fd..f8858b2 100644
--- a/src/main/org/codehaus/groovy/ast/ClassNode.java
+++ b/src/main/org/codehaus/groovy/ast/ClassNode.java
@@ -36,7 +36,6 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.EnumMap;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.Iterator;
 import java.util.LinkedHashSet;
 import java.util.LinkedList;
@@ -418,7 +417,7 @@ public class ClassNode extends AnnotatedNode implements Opcodes {
     }
 
     public Set<ClassNode> getAllInterfaces () {
-        Set<ClassNode> res = new HashSet<ClassNode>();
+        Set<ClassNode> res = new LinkedHashSet<ClassNode>();
         getAllInterfaces(res);
         return res;
     }

http://git-wip-us.apache.org/repos/asf/groovy/blob/d52d28a4/src/main/org/codehaus/groovy/ast/tools/GeneralUtils.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/ast/tools/GeneralUtils.java b/src/main/org/codehaus/groovy/ast/tools/GeneralUtils.java
index bcdf627..413292a 100644
--- a/src/main/org/codehaus/groovy/ast/tools/GeneralUtils.java
+++ b/src/main/org/codehaus/groovy/ast/tools/GeneralUtils.java
@@ -67,7 +67,7 @@ import org.codehaus.groovy.transform.AbstractASTTransformation;
 import java.lang.reflect.Modifier;
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.HashSet;
+import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -414,7 +414,7 @@ public class GeneralUtils {
     }
 
     public static Set<ClassNode> getInterfacesAndSuperInterfaces(ClassNode type) {
-        Set<ClassNode> res = new HashSet<ClassNode>();
+        Set<ClassNode> res = new LinkedHashSet<ClassNode>();
         if (type.isInterface()) {
             res.add(type);
             return res;

http://git-wip-us.apache.org/repos/asf/groovy/blob/d52d28a4/src/main/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java b/src/main/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
index 622084b..bcc86a8 100644
--- a/src/main/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
+++ b/src/main/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
@@ -1110,7 +1110,7 @@ public abstract class StaticTypeCheckingSupport {
     private static Collection<MethodNode> removeCovariantsAndInterfaceEquivalents(Collection<MethodNode> collection) {
         if (collection.size() <= 1) return collection;
         List<MethodNode> toBeRemoved = new LinkedList<MethodNode>();
-        List<MethodNode> list = new LinkedList<MethodNode>(new HashSet<MethodNode>(collection));
+        List<MethodNode> list = new LinkedList<MethodNode>(new LinkedHashSet<MethodNode>(collection));
         for (int i = 0; i < list.size() - 1; i++) {
             MethodNode one = list.get(i);
             if (toBeRemoved.contains(one)) continue;

http://git-wip-us.apache.org/repos/asf/groovy/blob/d52d28a4/src/test/org/codehaus/groovy/classgen/asm/sc/bugs/Groovy8142Bug.groovy
----------------------------------------------------------------------
diff --git a/src/test/org/codehaus/groovy/classgen/asm/sc/bugs/Groovy8142Bug.groovy b/src/test/org/codehaus/groovy/classgen/asm/sc/bugs/Groovy8142Bug.groovy
new file mode 100644
index 0000000..9a95a0e
--- /dev/null
+++ b/src/test/org/codehaus/groovy/classgen/asm/sc/bugs/Groovy8142Bug.groovy
@@ -0,0 +1,51 @@
+/*
+ *  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.classgen.asm.sc.bugs
+
+import groovy.transform.stc.StaticTypeCheckingTestCase
+import org.codehaus.groovy.classgen.asm.sc.StaticCompilationTestSupport
+
+class Groovy8142Bug extends StaticTypeCheckingTestCase implements StaticCompilationTestSupport {
+    void testShouldNotProduceDeterministicBytecode() {
+        100.times {
+            assertScript '''
+            interface Project {
+                File file()
+            }
+            interface FileOperations {
+                File file()
+            }
+            interface ProjectInternal extends Project, FileOperations {
+            }
+            
+            class Check {
+                void test(ProjectInternal p) {
+                    def f = p.file()
+                }
+            }
+            
+            def c = new Check()
+        '''
+
+            assert astTrees['Check'][1].contains('INVOKEINTERFACE FileOperations.file ()Ljava/io/File;') : "Incorrect bytecode found in iteration $it"
+        }
+    }
+}


[42/50] [abbrv] groovy git commit: BaseScript: correct example in javadoc

Posted by su...@apache.org.
BaseScript: correct example in javadoc


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

Branch: refs/heads/parrot
Commit: a5202223dfec2b9d1eddb693acfdec7d0053672f
Parents: 062b0b1
Author: Shil Sinha <sh...@apache.org>
Authored: Wed Mar 29 00:14:15 2017 -0400
Committer: Shil Sinha <sh...@apache.org>
Committed: Wed Mar 29 00:14:15 2017 -0400

----------------------------------------------------------------------
 src/main/groovy/transform/BaseScript.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/a5202223/src/main/groovy/transform/BaseScript.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/transform/BaseScript.java b/src/main/groovy/transform/BaseScript.java
index 6bea56e..227333a 100644
--- a/src/main/groovy/transform/BaseScript.java
+++ b/src/main/groovy/transform/BaseScript.java
@@ -36,7 +36,7 @@ import java.lang.annotation.Target;
  * {@link org.codehaus.groovy.control.CompilerConfiguration} of {@link groovy.lang.GroovyShell}
  * Example usage:
  * <pre>
- * class CustomScript extends Script {
+ * abstract class CustomScript extends Script {
  *     int getTheMeaningOfLife() { 42 }
  * }
  *


[23/50] [abbrv] groovy git commit: DefaultGroovyMethods: add more javadoc examples for the each, eachWithIndex and every methods

Posted by su...@apache.org.
DefaultGroovyMethods: add more javadoc examples for the each, eachWithIndex and every methods


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

Branch: refs/heads/parrot
Commit: 97d8c9ebd1608f2f93b8914971913ffe801809ba
Parents: d05cdcc
Author: pascalschumacher <pa...@gmx.net>
Authored: Sat Mar 18 11:38:45 2017 +0100
Committer: pascalschumacher <pa...@gmx.net>
Committed: Sat Mar 18 11:38:45 2017 +0100

----------------------------------------------------------------------
 .../groovy/runtime/DefaultGroovyMethods.java    | 27 ++++++++++++++++++++
 1 file changed, 27 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/97d8c9eb/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java b/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
index 219226f..68a9efd 100644
--- a/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
+++ b/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
@@ -1976,6 +1976,12 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
 
     /**
      * Iterates through an array passing each array entry to the given closure.
+     * <pre class="groovyTestCase">
+     * String[] letters = ['a', 'b', 'c']
+     * String result = ''
+     * letters.each{ result += it }
+     * assert result == 'abc'
+     * </pre>
      *
      * @param self    the array over which we iterate
      * @param closure the closure applied on each array entry
@@ -1994,6 +2000,11 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * passing each item to the given closure.  Custom types may utilize this
      * method by simply providing an "iterator()" method.  The items returned
      * from the resulting iterator will be passed to the closure.
+     * <pre class="groovyTestCase">
+     * String result = ''
+     * ['a', 'b', 'c'].each{ result += it }
+     * assert result == 'abc'
+     * </pre>
      *
      * @param self    the object over which we iterate
      * @param closure the closure applied on each element found
@@ -2009,6 +2020,12 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * Iterates through an array,
      * passing each array element and the element's index (a counter starting at
      * zero) to the given closure.
+     * <pre class="groovyTestCase">
+     * String[] letters = ['a', 'b', 'c']
+     * String result = ''
+     * letters.eachWithIndex{ letter, index -> result += "$index:$letter" }
+     * assert result == '0:a1:b2:c'
+     * </pre>
      *
      * @param self    an array
      * @param closure a Closure to operate on each array entry
@@ -2030,6 +2047,11 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * Iterates through an aggregate type or data structure,
      * passing each item and the item's index (a counter starting at
      * zero) to the given closure.
+     * <pre class="groovyTestCase">
+     * String result = ''
+     * ['a', 'b', 'c'].eachWithIndex{ letter, index -> result += "$index:$letter" }
+     * assert result == '0:a1:b2:c'
+     * </pre>
      *
      * @param self    an Object
      * @param closure a Closure to operate on each item
@@ -2413,6 +2435,11 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * Iterates over every element of a collection, and checks whether all
      * elements are <code>true</code> according to the Groovy Truth.
      * Equivalent to <code>self.every({element -> element})</code>
+     * <pre class="groovyTestCase">
+     * assert [true, true].every()
+     * assert [1, 1].every()
+     * assert ![1, 0].every()
+     * </pre>
      *
      * @param self the object over which we iterate
      * @return true if every item in the collection matches the closure


[34/50] [abbrv] groovy git commit: GROOVY-8128: Breaking change in 2.4.9 with Sql query with GString

Posted by su...@apache.org.
GROOVY-8128: Breaking change in 2.4.9 with Sql query with GString


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

Branch: refs/heads/parrot
Commit: a299cbaffa6ba23f3b484b01b3457448ed8d3634
Parents: d1ecc17
Author: paulk <pa...@asert.com.au>
Authored: Mon Mar 27 23:19:24 2017 +1000
Committer: paulk <pa...@asert.com.au>
Committed: Mon Mar 27 23:19:24 2017 +1000

----------------------------------------------------------------------
 .../src/main/java/groovy/sql/Sql.java           | 25 ++++++++++++++------
 1 file changed, 18 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/a299cbaf/subprojects/groovy-sql/src/main/java/groovy/sql/Sql.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-sql/src/main/java/groovy/sql/Sql.java b/subprojects/groovy-sql/src/main/java/groovy/sql/Sql.java
index a896109..26d52df 100644
--- a/subprojects/groovy-sql/src/main/java/groovy/sql/Sql.java
+++ b/subprojects/groovy-sql/src/main/java/groovy/sql/Sql.java
@@ -4108,19 +4108,30 @@ public class Sql {
      */
     protected void setParameters(List<Object> params, PreparedStatement statement) throws SQLException {
         int i = 1;
-        ParameterMetaData metaData = statement.getParameterMetaData();
-        if (metaData.getParameterCount() == 0 && params.size() == 1 && params.get(0) instanceof Map) {
-            Map paramsMap = (Map) params.get(0);
-            if (paramsMap.isEmpty()) return;
-        }
-        if (metaData.getParameterCount() != params.size()) {
-            throw new IllegalArgumentException("Found " + metaData.getParameterCount() + " parameter placeholders but supplied with " + params.size() + " parameters");
+        ParameterMetaData metaData = getParameterMetaDataSafe(statement);
+        if (metaData != null) {
+            if (metaData.getParameterCount() == 0 && params.size() == 1 && params.get(0) instanceof Map) {
+                Map paramsMap = (Map) params.get(0);
+                if (paramsMap.isEmpty()) return;
+            }
+            if (metaData.getParameterCount() != params.size()) {
+                throw new IllegalArgumentException("Found " + metaData.getParameterCount() + " parameter placeholders but supplied with " + params.size() + " parameters");
+            }
         }
         for (Object value : params) {
             setObject(statement, i++, value);
         }
     }
 
+    private ParameterMetaData getParameterMetaDataSafe(PreparedStatement statement) throws SQLException {
+        try {
+            return statement.getParameterMetaData();
+        } catch(SQLException se) {
+            LOG.fine("Unable to retrieve parameter metadata - reduced checking will occur: " + se.getMessage());
+            return null;
+        }
+    }
+
     /**
      * Strategy method allowing derived classes to handle types differently
      * such as for CLOBs etc.


[20/50] [abbrv] groovy git commit: GROOVY-8046: ClassFormatError void field/variable/parameter (closes #513)

Posted by su...@apache.org.
GROOVY-8046: ClassFormatError void field/variable/parameter (closes #513)


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

Branch: refs/heads/parrot
Commit: 439e297529c1c63bd145f0fe9d8a6d2621da520a
Parents: 48f99a1
Author: paulk <pa...@asert.com.au>
Authored: Wed Mar 15 09:48:05 2017 +1000
Committer: paulk <pa...@asert.com.au>
Committed: Wed Mar 15 12:22:53 2017 +1000

----------------------------------------------------------------------
 .../classgen/ClassCompletionVerifier.java       | 23 +++++++--
 src/test/groovy/bugs/Groovy8046Bug.groovy       | 52 ++++++++++++++++++++
 2 files changed, 70 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/439e2975/src/main/org/codehaus/groovy/classgen/ClassCompletionVerifier.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/classgen/ClassCompletionVerifier.java b/src/main/org/codehaus/groovy/classgen/ClassCompletionVerifier.java
index c2da690..3cea76a 100644
--- a/src/main/org/codehaus/groovy/classgen/ClassCompletionVerifier.java
+++ b/src/main/org/codehaus/groovy/classgen/ClassCompletionVerifier.java
@@ -43,6 +43,7 @@ import org.codehaus.groovy.syntax.Types;
 import org.codehaus.groovy.transform.trait.Traits;
 
 import static java.lang.reflect.Modifier.*;
+import static org.codehaus.groovy.ast.ClassHelper.VOID_TYPE;
 import static org.objectweb.asm.Opcodes.*;
 /**
  * Checks that a class satisfies various conditions including:
@@ -260,6 +261,10 @@ public class ClassCompletionVerifier extends ClassCodeVisitorSupport {
         return "field '" + node.getName() + "'";
     }
 
+    private static String getDescription(Parameter node) {
+        return "parameter '" + node.getName() + "'";
+    }
+
     private void checkAbstractDeclaration(MethodNode methodNode) {
         if (!methodNode.isAbstract()) return;
         if (isAbstract(currentClass.getModifiers())) return;
@@ -272,11 +277,8 @@ public class ClassCompletionVerifier extends ClassCodeVisitorSupport {
         ClassNode superCN = cn.getSuperClass();
         if (superCN == null) return;
         if (!isFinal(superCN.getModifiers())) return;
-        StringBuilder msg = new StringBuilder();
-        msg.append("You are not allowed to overwrite the final ");
-        msg.append(getDescription(superCN));
-        msg.append(".");
-        addError(msg.toString(), cn);
+        String msg = "You are not allowed to overwrite the final " + getDescription(superCN) + ".";
+        addError(msg, cn);
     }
 
     private void checkImplementsAndExtends(ClassNode node) {
@@ -407,6 +409,11 @@ public class ClassCompletionVerifier extends ClassCodeVisitorSupport {
         checkMethodModifiers(node);
         checkGenericsUsage(node, node.getParameters());
         checkGenericsUsage(node, node.getReturnType());
+        for (Parameter param : node.getParameters()) {
+            if (param.getType().equals(VOID_TYPE)) {
+                addError("The " + getDescription(param) + " in " +  getDescription(node) + " has invalid type void", param);
+            }
+        }
         super.visitMethod(node);
     }
 
@@ -485,6 +492,9 @@ public class ClassCompletionVerifier extends ClassCodeVisitorSupport {
         }
         checkInterfaceFieldModifiers(node);
         checkGenericsUsage(node, node.getType());
+        if (node.getType().equals(VOID_TYPE)) {
+            addError("The " + getDescription(node) + " has invalid type void", node);
+        }
         super.visitField(node);
     }
 
@@ -635,6 +645,9 @@ public class ClassCompletionVerifier extends ClassCodeVisitorSupport {
         checkInvalidDeclarationModifier(expression, ACC_SYNCHRONIZED, "synchronized");
         checkInvalidDeclarationModifier(expression, ACC_TRANSIENT, "transient");
         checkInvalidDeclarationModifier(expression, ACC_VOLATILE, "volatile");
+        if (expression.getVariableExpression().getOriginType().equals(VOID_TYPE)) {
+            addError("The variable '" + expression.getVariableExpression().getName() + "' has invalid type void", expression);
+        }
     }
 
     private void checkInvalidDeclarationModifier(DeclarationExpression expression, int modifier, String modName) {

http://git-wip-us.apache.org/repos/asf/groovy/blob/439e2975/src/test/groovy/bugs/Groovy8046Bug.groovy
----------------------------------------------------------------------
diff --git a/src/test/groovy/bugs/Groovy8046Bug.groovy b/src/test/groovy/bugs/Groovy8046Bug.groovy
new file mode 100644
index 0000000..c8bf633
--- /dev/null
+++ b/src/test/groovy/bugs/Groovy8046Bug.groovy
@@ -0,0 +1,52 @@
+/*
+ *  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 groovy.bugs
+
+import gls.CompilableTestSupport
+
+class Groovy8046Bug extends CompilableTestSupport {
+    void testFieldShouldNotHavePrimitiveVoidType() {
+        def message = shouldNotCompile """
+            class MyClass {
+                void field
+            }
+        """
+        assert message.contains("The field 'field' has invalid type void")
+    }
+
+    void testParameterShouldNotHavePrimitiveVoidType() {
+        def message = shouldNotCompile """
+            class MyClass {
+                int foo(void param) {}
+            }
+        """
+        assert message.contains("The parameter 'param' in method 'int foo(void)' has invalid type void")
+    }
+
+    void testLocalVariableShouldNotHavePrimitiveVoidType() {
+        def message = shouldNotCompile """
+            class MyClass {
+                def foo() {
+                    void bar = null
+                }
+            }
+        """
+        assert message.contains("The variable 'bar' has invalid type void")
+    }
+}


[22/50] [abbrv] groovy git commit: DefaultGroovyMethods#any: add examples to javadoc

Posted by su...@apache.org.
DefaultGroovyMethods#any: add examples to javadoc


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

Branch: refs/heads/parrot
Commit: d05cdcc67266f3c8aa1be1c5dc8cd02fbd6e01e7
Parents: e8863f4
Author: pascalschumacher <pa...@gmx.net>
Authored: Sat Mar 18 10:39:44 2017 +0100
Committer: pascalschumacher <pa...@gmx.net>
Committed: Sat Mar 18 10:39:44 2017 +0100

----------------------------------------------------------------------
 .../groovy/runtime/DefaultGroovyMethods.java       | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/d05cdcc6/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java b/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
index 96c99d9..219226f 100644
--- a/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
+++ b/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
@@ -2432,6 +2432,10 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
     /**
      * Iterates over the contents of an object or collection, and checks whether a
      * predicate is valid for at least one element.
+     * <pre class="groovyTestCase">
+     * assert [1, 2, 3].any { it == 2 }
+     * assert ![1, 2, 3].any { it > 3 }
+     * </pre>
      *
      * @param self    the object over which we iterate
      * @param closure the closure predicate used for matching
@@ -2449,6 +2453,10 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
     /**
      * Iterates over the contents of an iterator, and checks whether a
      * predicate is valid for at least one element.
+     * <pre class="groovyTestCase">
+     * assert [1, 2, 3].iterator().any { it == 2 }
+     * assert ![1, 2, 3].iterator().any { it > 3 }
+     * </pre>
      *
      * @param self    the iterator over which we iterate
      * @param closure the closure predicate used for matching
@@ -2466,6 +2474,10 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
     /**
      * Iterates over the contents of an iterable, and checks whether a
      * predicate is valid for at least one element.
+     * <pre class="groovyTestCase">
+     * assert [1, 2, 3].any { it == 2 }
+     * assert ![1, 2, 3].any { it > 3 }
+     * </pre>
      *
      * @param self    the iterable over which we iterate
      * @param closure the closure predicate used for matching
@@ -2510,6 +2522,11 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * Iterates over the elements of a collection, and checks whether at least
      * one element is true according to the Groovy Truth.
      * Equivalent to self.any({element -> element})
+     * <pre class="groovyTestCase">
+     * assert [false, true].any()
+     * assert [0, 1].any()
+     * assert ![0, 0].any()
+     * </pre>
      *
      * @param self the object over which we iterate
      * @return true if any item in the collection matches the closure predicate


[49/50] [abbrv] groovy git commit: Fix non-reproducible output of the compiler for closure shared variables

Posted by su...@apache.org.
Fix non-reproducible output of the compiler for closure shared variables

This commit fixes the variable scope collector, to make sure that the collected variables
are always collected _in the same order_. Without this, the compiler may generate different
bytecode for the same sources. The problem is that if the bytecode is used as a cache key,
like in Gradle, the same sources producing different bytecode becomes an issue.


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

Branch: refs/heads/parrot
Commit: fb1f14a39d3ee4fd7dc30907096b0603ce126e21
Parents: d52d28a
Author: Cedric Champeau <cc...@apache.org>
Authored: Fri Apr 7 11:14:01 2017 +0200
Committer: Cedric Champeau <cc...@apache.org>
Committed: Fri Apr 7 11:16:24 2017 +0200

----------------------------------------------------------------------
 .../org/codehaus/groovy/ast/VariableScope.java  | 17 ++--
 .../classgen/asm/sc/bugs/Groovy8142Bug.groovy   | 51 -----------
 .../asm/sc/bugs/ReproducibleBytecodeBugs.groovy | 92 ++++++++++++++++++++
 3 files changed, 99 insertions(+), 61 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/fb1f14a3/src/main/org/codehaus/groovy/ast/VariableScope.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/ast/VariableScope.java b/src/main/org/codehaus/groovy/ast/VariableScope.java
index 077c7f1..521b301 100644
--- a/src/main/org/codehaus/groovy/ast/VariableScope.java
+++ b/src/main/org/codehaus/groovy/ast/VariableScope.java
@@ -19,8 +19,8 @@
 package org.codehaus.groovy.ast;
 
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.Iterator;
+import java.util.LinkedHashMap;
 import java.util.Map;
 
 /**
@@ -99,18 +99,15 @@ public class VariableScope  {
         VariableScope copy = new VariableScope();
         copy.clazzScope = clazzScope;
         if (!declaredVariables.isEmpty()) {
-          copy.declaredVariables = new HashMap<String, Variable>();
-          copy.declaredVariables.putAll(declaredVariables);
+          copy.declaredVariables = new LinkedHashMap<String, Variable>(declaredVariables);
         }
         copy.inStaticContext = inStaticContext;
         copy.parent = parent;
         if (!referencedClassVariables.isEmpty()) {
-            copy.referencedClassVariables = new HashMap<String, Variable>();
-            copy.referencedClassVariables.putAll(referencedClassVariables);
+            copy.referencedClassVariables = new LinkedHashMap<String, Variable>(referencedClassVariables);
         }
         if (!referencedLocalVariables.isEmpty()) {
-            copy.referencedLocalVariables = new HashMap<String, Variable>();
-            copy.referencedLocalVariables.putAll(referencedLocalVariables);
+            copy.referencedLocalVariables = new LinkedHashMap<String, Variable>(referencedLocalVariables);
         }
         copy.resolvesDynamic = resolvesDynamic;
         return copy;
@@ -118,7 +115,7 @@ public class VariableScope  {
 
     public void putDeclaredVariable(Variable var) {
         if (declaredVariables == Collections.EMPTY_MAP)
-          declaredVariables = new HashMap<String, Variable>();
+          declaredVariables = new LinkedHashMap<String, Variable>();
         declaredVariables.put(var.getName(), var);
     }
 
@@ -136,13 +133,13 @@ public class VariableScope  {
 
     public void putReferencedLocalVariable(Variable var) {
         if (referencedLocalVariables == Collections.EMPTY_MAP)
-          referencedLocalVariables = new HashMap<String, Variable>();
+          referencedLocalVariables = new LinkedHashMap<String, Variable>();
         referencedLocalVariables.put(var.getName(), var);
     }
 
     public void putReferencedClassVariable(Variable var) {
         if (referencedClassVariables == Collections.EMPTY_MAP)
-          referencedClassVariables = new HashMap<String, Variable>();
+          referencedClassVariables = new LinkedHashMap<String, Variable>();
         referencedClassVariables.put(var.getName(), var);
     }
 

http://git-wip-us.apache.org/repos/asf/groovy/blob/fb1f14a3/src/test/org/codehaus/groovy/classgen/asm/sc/bugs/Groovy8142Bug.groovy
----------------------------------------------------------------------
diff --git a/src/test/org/codehaus/groovy/classgen/asm/sc/bugs/Groovy8142Bug.groovy b/src/test/org/codehaus/groovy/classgen/asm/sc/bugs/Groovy8142Bug.groovy
deleted file mode 100644
index 9a95a0e..0000000
--- a/src/test/org/codehaus/groovy/classgen/asm/sc/bugs/Groovy8142Bug.groovy
+++ /dev/null
@@ -1,51 +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.classgen.asm.sc.bugs
-
-import groovy.transform.stc.StaticTypeCheckingTestCase
-import org.codehaus.groovy.classgen.asm.sc.StaticCompilationTestSupport
-
-class Groovy8142Bug extends StaticTypeCheckingTestCase implements StaticCompilationTestSupport {
-    void testShouldNotProduceDeterministicBytecode() {
-        100.times {
-            assertScript '''
-            interface Project {
-                File file()
-            }
-            interface FileOperations {
-                File file()
-            }
-            interface ProjectInternal extends Project, FileOperations {
-            }
-            
-            class Check {
-                void test(ProjectInternal p) {
-                    def f = p.file()
-                }
-            }
-            
-            def c = new Check()
-        '''
-
-            assert astTrees['Check'][1].contains('INVOKEINTERFACE FileOperations.file ()Ljava/io/File;') : "Incorrect bytecode found in iteration $it"
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/groovy/blob/fb1f14a3/src/test/org/codehaus/groovy/classgen/asm/sc/bugs/ReproducibleBytecodeBugs.groovy
----------------------------------------------------------------------
diff --git a/src/test/org/codehaus/groovy/classgen/asm/sc/bugs/ReproducibleBytecodeBugs.groovy b/src/test/org/codehaus/groovy/classgen/asm/sc/bugs/ReproducibleBytecodeBugs.groovy
new file mode 100644
index 0000000..d7e8f8a
--- /dev/null
+++ b/src/test/org/codehaus/groovy/classgen/asm/sc/bugs/ReproducibleBytecodeBugs.groovy
@@ -0,0 +1,92 @@
+/*
+ *  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.classgen.asm.sc.bugs
+
+import groovy.transform.stc.StaticTypeCheckingTestCase
+import org.codehaus.groovy.classgen.asm.sc.StaticCompilationTestSupport
+
+class ReproducibleBytecodeBugs extends StaticTypeCheckingTestCase implements StaticCompilationTestSupport {
+    // GROOVY-8142
+    void testShouldNotProduceDeterministicBytecode() {
+        100.times {
+            assertScript '''
+            interface Project {
+                File file()
+            }
+            interface FileOperations {
+                File file()
+            }
+            interface ProjectInternal extends Project, FileOperations {
+            }
+            
+            class Check {
+                void test(ProjectInternal p) {
+                    def f = p.file()
+                }
+            }
+            
+            def c = new Check()
+        '''
+
+            assert astTrees['Check'][1].contains('INVOKEINTERFACE FileOperations.file ()Ljava/io/File;') : "Incorrect bytecode found in iteration $it"
+        }
+    }
+
+    // GROOVY-8148
+    void testShouldAlwaysAddClosureSharedVariablesInSameOrder() {
+        100.times {
+            assertScript '''
+            class Check {
+                void test() {
+                    def xx = true
+                    def moot = "bar"
+                    def kr = [:]
+                    def zorg = []
+                    def cl = {
+                        def (x,y,z,t) = [xx, moot, kr , zorg]
+                    }
+                }
+            }
+            
+            def c = new Check()
+        '''
+
+            def bytecode = astTrees['Check$_test_closure1'][1]
+            assertOrdered it, bytecode,
+                    'PUTFIELD Check$_test_closure1.xx',
+                    'PUTFIELD Check$_test_closure1.moot',
+                    'PUTFIELD Check$_test_closure1.kr',
+                    'PUTFIELD Check$_test_closure1.zorg'
+
+        }
+    }
+
+
+    private static void assertOrdered(int iteration, String bytecode, String... elements) {
+        int start = 0
+        elements.eachWithIndex { it, i ->
+            start = bytecode.indexOf(it, start)
+            if (start == -1) {
+                throw new AssertionError("Iteration $iteration - Element [$it] not found in order (expected to find it at index $i)")
+            }
+        }
+    }
+}


[12/50] [abbrv] groovy git commit: GROOVY-7248: MissingPropertyException: No such property in finally block (closes #501)

Posted by su...@apache.org.
GROOVY-7248: MissingPropertyException: No such property in finally block (closes #501)


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

Branch: refs/heads/parrot
Commit: d51694473e921c7360061f6a4bfe876ea6a401cf
Parents: b32ce96
Author: John Wagenleitner <jw...@apache.org>
Authored: Sun Mar 5 10:39:38 2017 -0800
Committer: John Wagenleitner <jw...@apache.org>
Committed: Thu Mar 9 05:18:29 2017 -0800

----------------------------------------------------------------------
 .../classgen/asm/OptimizingStatementWriter.java | 18 +++++-
 src/test/groovy/bugs/Groovy7248Bug.groovy       | 67 ++++++++++++++++++++
 2 files changed, 83 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/d5169447/src/main/org/codehaus/groovy/classgen/asm/OptimizingStatementWriter.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/classgen/asm/OptimizingStatementWriter.java b/src/main/org/codehaus/groovy/classgen/asm/OptimizingStatementWriter.java
index 134600d..8696637 100644
--- a/src/main/org/codehaus/groovy/classgen/asm/OptimizingStatementWriter.java
+++ b/src/main/org/codehaus/groovy/classgen/asm/OptimizingStatementWriter.java
@@ -55,6 +55,7 @@ public class OptimizingStatementWriter extends StatementWriter {
         private boolean optimize=false;
         protected MethodNode target;
         protected ClassNode type;
+        protected VariableExpression declaredVariableExpression;
         protected boolean[] involvedTypes = new boolean[typeMapKeyNames.length];
         public void chainInvolvedTypes(OptimizeFlagsCollector opt) {
             for (int i=0; i<typeMapKeyNames.length; i++) {
@@ -304,6 +305,10 @@ public class OptimizingStatementWriter extends StatementWriter {
         } else {
             StatementMeta meta = (StatementMeta) statement.getNodeMetaData(StatementMeta.class);
             if (isNewPathFork(meta) && writeDeclarationExtraction(statement)) {
+                if (meta.declaredVariableExpression != null) {
+                    // declaration was replaced by assignment so we need to define the variable
+                    controller.getCompileStack().defineVariable(meta.declaredVariableExpression, false);
+                }
                 FastPathData fastPathData = writeGuards(meta, statement);
 
                 boolean oldFastPathBlock = fastPathBlocked;
@@ -342,6 +347,10 @@ public class OptimizingStatementWriter extends StatementWriter {
             // the only case we need to handle is then (2).
 
             if (isNewPathFork(meta) && writeDeclarationExtraction(statement)) {
+                if (meta.declaredVariableExpression != null) {
+                    // declaration was replaced by assignment so we need to define the variable
+                    controller.getCompileStack().defineVariable(meta.declaredVariableExpression, false);
+                }
                 FastPathData fastPathData = writeGuards(meta, statement);
 
                 boolean oldFastPathBlock = fastPathBlocked;
@@ -375,8 +384,13 @@ public class OptimizingStatementWriter extends StatementWriter {
         ex = declaration.getLeftExpression();
         if (ex instanceof TupleExpression) return false;
 
-        // do declaration
-        controller.getCompileStack().defineVariable(declaration.getVariableExpression(), false);
+        // stash declared variable in case we do subsequent visits after we
+        // change to assignment only
+        StatementMeta meta = statement.getNodeMetaData(StatementMeta.class);
+        if (meta != null) {
+            meta.declaredVariableExpression = declaration.getVariableExpression();
+        }
+
         // change statement to do assignment only
         BinaryExpression assignment = new BinaryExpression(
                 declaration.getLeftExpression(),

http://git-wip-us.apache.org/repos/asf/groovy/blob/d5169447/src/test/groovy/bugs/Groovy7248Bug.groovy
----------------------------------------------------------------------
diff --git a/src/test/groovy/bugs/Groovy7248Bug.groovy b/src/test/groovy/bugs/Groovy7248Bug.groovy
new file mode 100644
index 0000000..b8057fb
--- /dev/null
+++ b/src/test/groovy/bugs/Groovy7248Bug.groovy
@@ -0,0 +1,67 @@
+/*
+ *  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 groovy.bugs
+
+/**
+ * StatementWriter.writeTryCatchFinally visits the finally block
+ * twice, once for the normal path and once again for the "catch all"
+ * path. When the OptimizingStatementWriter is used DeclarationExpressions
+ * are rewritten to BinaryExpressions to allow splitting between fast and
+ * slow paths.  Because the expression is modified variable declarations
+ * are lost if the statement is visited more than once.
+ *
+ * This is not a problem for scripts because the property call that is
+ * generated will succeed because of the script context.  So to reproduce
+ * the issue it must be contained in a class.
+ */
+class Groovy7248Bug extends GroovyTestCase {
+
+    void testFinallyDeclaredVariableExpression() {
+        assertScript '''
+            class Test {
+                long run() {
+                    long dur = 0
+                    long start = 0
+                    try {
+                        start++
+                    } finally {
+                        long end = 2
+                        long time = end - start
+                        dur = time
+                    }
+                    dur
+                }
+            }
+            assert new Test().run() == 1
+        '''
+    }
+
+    void testReturnStatementDeclaration() {
+        assertScript '''
+            class Foo {
+                int test() {
+                    int x = 2
+                    int y = x - 1
+                }
+            }
+            assert new Foo().test() == 1
+        '''
+    }
+
+}


[50/50] [abbrv] groovy git commit: Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/groovy into parrot

Posted by su...@apache.org.
Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/groovy into parrot

# Conflicts:
#	.travis.yml
#	build.gradle
#	gradle/wrapper/gradle-wrapper.jar
#	gradle/wrapper/gradle-wrapper.properties
#	src/main/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
#	src/test/groovy/EqualsTest.groovy
#	subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/runtime/MacroBuilder.java
#	subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroInvocationTrap.java
#	subprojects/groovy-macro/src/test/groovy/org/codehaus/groovy/macro/MacroTest.groovy


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

Branch: refs/heads/parrot
Commit: 921fa3d90e2557bcf5a21d2be4886b0a7f0a2c35
Parents: 3b1a720 fb1f14a
Author: sunlan <su...@apache.org>
Authored: Fri Apr 7 21:30:13 2017 +0800
Committer: sunlan <su...@apache.org>
Committed: Fri Apr 7 21:30:30 2017 +0800

----------------------------------------------------------------------
 build.gradle                                    |  10 +-
 gradle.properties                               |   4 +-
 gradle/assemble.gradle                          |  52 ++-
 gradle/wrapper/gradle-wrapper.jar               | Bin 54208 -> 54227 bytes
 gradle/wrapper/gradle-wrapper.properties        |   5 +-
 security/groovy.policy                          |   2 +
 settings.gradle                                 |   4 +
 .../beans/ListenerListASTTransformation.groovy  |   3 +-
 src/main/groovy/lang/MetaClassImpl.java         |   5 -
 src/main/groovy/transform/BaseScript.java       |   2 +-
 src/main/groovy/transform/MapConstructor.java   |   4 +-
 src/main/groovy/transform/TupleConstructor.java |   4 +-
 .../transform/builder/DefaultStrategy.java      |   8 +-
 src/main/groovy/util/NodeList.java              |   3 +-
 src/main/org/codehaus/groovy/ast/ClassNode.java |   3 +-
 .../groovy/ast/TransformingCodeVisitor.java     | 340 ++++++++++++++++++
 .../org/codehaus/groovy/ast/VariableScope.java  |  17 +-
 .../codehaus/groovy/ast/tools/GeneralUtils.java |   4 +-
 .../classgen/ClassCompletionVerifier.java       |  44 ++-
 .../groovy/classgen/asm/CompileStack.java       |  17 +-
 .../classgen/asm/OptimizingStatementWriter.java |  18 +-
 .../codehaus/groovy/control/ErrorCollector.java |   6 +-
 .../org/codehaus/groovy/control/SourceUnit.java |   4 +
 .../codehaus/groovy/reflection/ClassInfo.java   |  55 ++-
 .../groovy/runtime/DefaultGroovyMethods.java    |  64 +++-
 .../metaclass/MetaClassRegistryImpl.java        |  12 +-
 .../codehaus/groovy/syntax/SyntaxException.java |   5 +
 .../transform/ImmutableASTTransformation.java   |  11 +-
 .../transform/MemoizedASTTransformation.java    |   7 +-
 .../stc/StaticTypeCheckingSupport.java          |   2 +-
 .../stc/StaticTypeCheckingVisitor.java          |  12 +-
 .../trait/SuperCallTraitTransformer.java        |  83 +++--
 .../transform/trait/TraitASTTransformation.java | 104 ++++--
 .../groovy/transform/trait/TraitComposer.java   |  96 +++--
 .../trait/TraitReceiverTransformer.java         |  97 +++--
 .../util/ManagedConcurrentLinkedQueue.java      | 180 ++++++++++
 .../codehaus/groovy/util/ManagedLinkedList.java |   2 +
 src/spec/doc/core-semantics.adoc                |   4 +-
 src/spec/doc/grape.adoc                         |   6 +-
 src/spec/doc/working-with-collections.adoc      |  20 +-
 src/spec/test/ClosuresSpecTest.groovy           |   2 +-
 .../test/gdk/WorkingWithCollectionsTest.groovy  |  20 +-
 src/test/groovy/bugs/Groovy6792Bug.groovy       |  49 +++
 src/test/groovy/bugs/Groovy7248Bug.groovy       |  67 ++++
 src/test/groovy/bugs/Groovy7797Bug.groovy       |  38 ++
 src/test/groovy/bugs/Groovy7909Bug.groovy       |  76 ++++
 src/test/groovy/bugs/Groovy8046Bug.groovy       |  52 +++
 src/test/groovy/bugs/Groovy8048Bug.groovy       |  46 +++
 src/test/groovy/bugs/Groovy8085Bug.groovy       |  91 +++++
 src/test/groovy/bugs/Groovy8110Bug.groovy       |  45 +++
 src/test/groovy/bugs/Groovy8140Bug.groovy       |  48 +++
 src/test/groovy/util/logging/Log4j2Test.groovy  |  36 +-
 .../asm/sc/bugs/ReproducibleBytecodeBugs.groovy |  92 +++++
 .../MemoizedASTTransformationTest.groovy        |  12 +
 .../ManagedConcurrentLinkedQueueTest.groovy     |  88 +++++
 .../groovy/inspect/swingui/AstBrowser.groovy    |  79 ++--
 .../swingui/AstNodeToScriptAdapter.groovy       |  51 ++-
 .../swingui/AstNodeToScriptAdapterTest.groovy   |  92 +++++
 subprojects/groovy-macro/build.gradle           |   2 +-
 .../macro/methods/MacroGroovyMethods.java       | 207 +++++++++++
 .../codehaus/groovy/macro/runtime/Macro.java    |  37 ++
 .../groovy/macro/runtime/MacroBuilder.java      |  22 +-
 .../groovy/macro/runtime/MacroContext.java      |  71 ++++
 .../macro/runtime/MacroGroovyMethods.java       |  53 ---
 .../groovy/macro/runtime/MacroStub.java         |  33 ++
 .../transform/MacroCallTransformingVisitor.java | 156 ++++++++
 .../groovy/macro/transform/MacroClass.java      |   8 +
 .../transform/MacroClassTransformation.java     | 138 +++++++
 .../macro/transform/MacroInvocationTrap.java    | 274 --------------
 .../macro/transform/MacroMethodsCache.java      | 144 ++++++++
 .../macro/transform/MacroTransformation.java    |  34 +-
 .../macro/transform/TransformingMacroTrap.java  | 343 ------------------
 ....codehaus.groovy.transform.ASTTransformation |   1 +
 .../groovy/macro/ExampleMacroMethods.java       |  52 +++
 .../org/codehaus/groovy/macro/MacroTest.groovy  |  24 ++
 .../groovy/macro/MacroTransformationTest.groovy |  70 ++++
 .../groovy/macro/matcher/ASTMatcherTest.groovy  | 357 ++++++++++++++++++-
 .../org.codehaus.groovy.runtime.ExtensionModule |  17 +
 .../src/main/java/groovy/sql/Sql.java           |  27 +-
 .../groovy/groovy/sql/SqlCompleteTest.groovy    |  17 +
 .../main/java/groovy/xml/dom/DOMCategory.java   |   5 +-
 .../groovy-xml/src/spec/doc/xml-userguide.adoc  |   2 +-
 subprojects/stress/README.adoc                  |  40 +++
 subprojects/stress/build.gradle                 |  28 ++
 .../org/apache/groovy/stress/util/GCUtils.java  |  39 ++
 .../apache/groovy/stress/util/ThreadUtils.java  |  43 +++
 .../reflection/ClassInfoDeadlockStressTest.java | 138 +++++++
 .../reflection/ClassInfoLeakStressTest.java     | 101 ++++++
 .../ManagedConcurrentLinkedQueueStressTest.java | 164 +++++++++
 .../util/ManagedConcurrentMapStressTest.java    | 136 +++++++
 .../ManagedConcurrentValueMapStressTest.java    | 135 +++++++
 91 files changed, 4204 insertions(+), 1017 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/921fa3d9/build.gradle
----------------------------------------------------------------------
diff --cc build.gradle
index 2dee7bc,0bcddc9..469048f
--- a/build.gradle
+++ b/build.gradle
@@@ -174,8 -169,7 +174,8 @@@ ext 
      slf4jVersion = '1.7.21'
      xmlunitVersion = '1.6'
      xstreamVersion = '1.4.9'
-     spockVersion = '1.0-groovy-2.4'
+     spockVersion = '1.1-groovy-2.4-SNAPSHOT' // supports 3.0
 +    antlr4Version = '4.6.0.3'
      isReleaseVersion = !groovyVersion.toLowerCase().endsWith("snapshot")
  }
  

http://git-wip-us.apache.org/repos/asf/groovy/blob/921fa3d9/gradle/assemble.gradle
----------------------------------------------------------------------
diff --cc gradle/assemble.gradle
index acb4540,72ef7f5..ab8c69c
--- a/gradle/assemble.gradle
+++ b/gradle/assemble.gradle
@@@ -191,10 -191,9 +191,10 @@@ allprojects 
                          }
  
                          zipfileset(src: configurations.runtime.files.find { file -> file.name.startsWith('asm-util') },
-                                 includes: 'org/objectweb/asm/util/Printer.class,org/objectweb/asm/util/Textifier.class,org/objectweb/asm/util/Trace*')
+                                 includes: 'org/objectweb/asm/util/Printer.class,org/objectweb/asm/util/Textifier.class,org/objectweb/asm/util/ASMifier.class,org/objectweb/asm/util/Trace*')
                      }
 -                    rule pattern: 'antlr.**', result: 'groovyjarjarantlr.@1'
 +                    rule pattern: 'antlr.**', result: 'groovyjarjarantlr.@1' // antlr2
 +                    rule pattern: 'org.antlr.**', result: 'groovyjarjarantlr4.@1' // antlr4
                      rule pattern: 'org.objectweb.**', result: 'groovyjarjarasm.@1'
                      rule pattern: 'org.apache.commons.cli.**', result: 'groovyjarjarcommonscli.@1'
                  }

http://git-wip-us.apache.org/repos/asf/groovy/blob/921fa3d9/src/main/groovy/lang/MetaClassImpl.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/groovy/blob/921fa3d9/src/main/org/codehaus/groovy/classgen/ClassCompletionVerifier.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/groovy/blob/921fa3d9/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/groovy/blob/921fa3d9/src/main/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/groovy/blob/921fa3d9/src/main/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
----------------------------------------------------------------------


[11/50] [abbrv] groovy git commit: make field package private (closes #432)

Posted by su...@apache.org.
make field package private (closes #432)


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

Branch: refs/heads/parrot
Commit: b32ce96c6597c90538dce41556c6400c95792e11
Parents: 3d752e3
Author: zhangbo <zh...@nanchao.org>
Authored: Sun Oct 16 17:21:52 2016 +0800
Committer: paulk <pa...@asert.com.au>
Committed: Wed Mar 8 18:11:15 2017 +1000

----------------------------------------------------------------------
 .../codehaus/groovy/transform/trait/SuperCallTraitTransformer.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/b32ce96c/src/main/org/codehaus/groovy/transform/trait/SuperCallTraitTransformer.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/transform/trait/SuperCallTraitTransformer.java b/src/main/org/codehaus/groovy/transform/trait/SuperCallTraitTransformer.java
index 2972c72..5d2d772 100644
--- a/src/main/org/codehaus/groovy/transform/trait/SuperCallTraitTransformer.java
+++ b/src/main/org/codehaus/groovy/transform/trait/SuperCallTraitTransformer.java
@@ -49,7 +49,7 @@ import static org.objectweb.asm.Opcodes.ACC_SYNTHETIC;
  * @since 2.3.0
  */
 class SuperCallTraitTransformer extends ClassCodeExpressionTransformer {
-    public static final String UNRESOLVED_HELPER_CLASS = "UNRESOLVED_HELPER_CLASS";
+    static final String UNRESOLVED_HELPER_CLASS = "UNRESOLVED_HELPER_CLASS";
     private final SourceUnit unit;
 
     SuperCallTraitTransformer(final SourceUnit unit) {


[28/50] [abbrv] groovy git commit: change to version 3.0.0-SNAPSHOT and use latest Spock snapshot which supports that version number

Posted by su...@apache.org.
change to version 3.0.0-SNAPSHOT and use latest Spock snapshot which supports that version number


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

Branch: refs/heads/parrot
Commit: 5d93686d8e4b54091b075cfa91858ac65a3d9b06
Parents: c155e9d
Author: paulk <pa...@asert.com.au>
Authored: Fri Mar 24 13:39:36 2017 +1000
Committer: paulk <pa...@asert.com.au>
Committed: Fri Mar 24 13:39:36 2017 +1000

----------------------------------------------------------------------
 build.gradle      | 2 +-
 gradle.properties | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/5d93686d/build.gradle
----------------------------------------------------------------------
diff --git a/build.gradle b/build.gradle
index b2a5047..0bcddc9 100644
--- a/build.gradle
+++ b/build.gradle
@@ -169,7 +169,7 @@ ext {
     slf4jVersion = '1.7.21'
     xmlunitVersion = '1.6'
     xstreamVersion = '1.4.9'
-    spockVersion = '1.0-groovy-2.4'
+    spockVersion = '1.1-groovy-2.4-SNAPSHOT' // supports 3.0
     isReleaseVersion = !groovyVersion.toLowerCase().endsWith("snapshot")
 }
 

http://git-wip-us.apache.org/repos/asf/groovy/blob/5d93686d/gradle.properties
----------------------------------------------------------------------
diff --git a/gradle.properties b/gradle.properties
index 4d21a12..db8f993 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -13,9 +13,9 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-groovyVersion = 2.9.98-SNAPSHOT
+groovyVersion = 3.0.0-SNAPSHOT
 # bundle version format: major('.'minor('.'micro('.'qualifier)?)?)? (first 3 only digits)
-groovyBundleVersion = 2.9.98.SNAPSHOT
+groovyBundleVersion = 3.0.0.SNAPSHOT
 
 groovyJUnit_ms = 256m
 groovyJUnit_mx = 512m


[14/50] [abbrv] groovy git commit: GROOVY-8118: Builder's DefaultStrategy has small doc error

Posted by su...@apache.org.
GROOVY-8118: Builder's DefaultStrategy has small doc error


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

Branch: refs/heads/parrot
Commit: b842d1bbd43e3b4d3f901084876ce4845b37319d
Parents: 4f4aa73
Author: paulk <pa...@asert.com.au>
Authored: Mon Mar 13 08:55:19 2017 +1000
Committer: paulk <pa...@asert.com.au>
Committed: Mon Mar 13 08:55:19 2017 +1000

----------------------------------------------------------------------
 src/main/groovy/transform/builder/DefaultStrategy.java | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/b842d1bb/src/main/groovy/transform/builder/DefaultStrategy.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/transform/builder/DefaultStrategy.java b/src/main/groovy/transform/builder/DefaultStrategy.java
index c863410..3c4b048 100644
--- a/src/main/groovy/transform/builder/DefaultStrategy.java
+++ b/src/main/groovy/transform/builder/DefaultStrategy.java
@@ -76,7 +76,7 @@ import static org.objectweb.asm.Opcodes.ACC_STATIC;
  *     String lastName
  *     int age
  * }
- * def person = Person.builder().firstName("Robert").lastName("Lewandowski").age(21)
+ * def person = Person.builder().firstName("Robert").lastName("Lewandowski").age(21).build()
  * assert person.firstName == "Robert"
  * assert person.lastName == "Lewandowski"
  * assert person.age == 21
@@ -90,11 +90,11 @@ import static org.objectweb.asm.Opcodes.ACC_STATIC;
  *     String lastName
  *     int age
  * }
- * def p2 = Person.builder().setFirstName("Robert").setLastName("Lewandowski").setAge(21)
+ * def p2 = Person.builder().setFirstName("Robert").setLastName("Lewandowski").setAge(21).build()
  * </pre>
  * or using a prefix of 'with' would result in usage like this:
  * <pre>
- * def p3 = Person.builder().withFirstName("Robert").withLastName("Lewandowski").withAge(21)
+ * def p3 = Person.builder().withFirstName("Robert").withLastName("Lewandowski").withAge(21).build()
  * </pre>
  *
  * You can also use the {@code @Builder} annotation in combination with this strategy on one or more constructor or
@@ -160,8 +160,6 @@ import static org.objectweb.asm.Opcodes.ACC_STATIC;
  *
  * The 'forClass' annotation attribute for the {@code @Builder} transform isn't applicable for this strategy.
  * The 'useSetters' annotation attribute for the {@code @Builder} transform is ignored by this strategy which always uses setters.
- *
- * @author Paul King
  */
 public class DefaultStrategy extends BuilderASTTransformation.AbstractBuilderStrategy {
     private static final Expression DEFAULT_INITIAL_VALUE = null;


[47/50] [abbrv] groovy git commit: GROOVY-8140: Invoke method not returning MOP super method if isCallToSuper (closes #520)

Posted by su...@apache.org.
GROOVY-8140: Invoke method not returning MOP super method if isCallToSuper (closes #520)


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

Branch: refs/heads/parrot
Commit: b2d95c2bcacb9c5473ea7f008ed3f5392717a6f0
Parents: 752341d
Author: John Wagenleitner <jw...@apache.org>
Authored: Sun Apr 2 08:34:47 2017 -0700
Committer: John Wagenleitner <jw...@apache.org>
Committed: Tue Apr 4 19:14:57 2017 -0700

----------------------------------------------------------------------
 src/main/groovy/lang/MetaClassImpl.java   |  5 ---
 src/test/groovy/bugs/Groovy8140Bug.groovy | 48 ++++++++++++++++++++++++++
 2 files changed, 48 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/b2d95c2b/src/main/groovy/lang/MetaClassImpl.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/lang/MetaClassImpl.java b/src/main/groovy/lang/MetaClassImpl.java
index 93c013b..a059a4f 100644
--- a/src/main/groovy/lang/MetaClassImpl.java
+++ b/src/main/groovy/lang/MetaClassImpl.java
@@ -493,11 +493,6 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
             boolean useThis;
 
             @Override
-            public boolean skipClass(Class clazz) {
-                return !useThis && clazz == theClass;
-            }
-
-            @Override
             public void methodNameAction(Class clazz, MetaMethodIndex.Entry e) {
                 if (useThis) {
                     if (e.methods == null)

http://git-wip-us.apache.org/repos/asf/groovy/blob/b2d95c2b/src/test/groovy/bugs/Groovy8140Bug.groovy
----------------------------------------------------------------------
diff --git a/src/test/groovy/bugs/Groovy8140Bug.groovy b/src/test/groovy/bugs/Groovy8140Bug.groovy
new file mode 100644
index 0000000..4de5c88
--- /dev/null
+++ b/src/test/groovy/bugs/Groovy8140Bug.groovy
@@ -0,0 +1,48 @@
+/*
+ *  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 groovy.bugs
+
+
+class Groovy8140Bug extends GroovyTestCase {
+
+    void testGetMethodCallToSuperReturnsMOPSuperMethod() {
+        assertScript '''
+            import org.codehaus.groovy.runtime.InvokerHelper
+
+            class A {
+                @Override
+                public String toString() {
+                    return "base"
+                }
+            }
+
+            class B extends A {
+                @Override
+                public String toString() {
+                    return "x" + super.toString()
+                }
+            }
+
+            MetaClass mc = InvokerHelper.getMetaClass(B.class)
+            def method = mc.getMethodWithCaching(B.class, "toString", null, true)
+            assert method.getName() ==~ /super[$]\\d+[$]toString/
+        '''
+    }
+
+}


[13/50] [abbrv] groovy git commit: GROOVY-8110: @ListenerList generated fireWhatever() method stops working (closes #510)

Posted by su...@apache.org.
GROOVY-8110: @ListenerList generated fireWhatever() method stops working (closes #510)


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

Branch: refs/heads/parrot
Commit: 4f4aa73e52a01dd05c8d3bac45f6765f2c7d174d
Parents: d516944
Author: paulk <pa...@asert.com.au>
Authored: Thu Mar 9 17:59:15 2017 +1000
Committer: paulk <pa...@asert.com.au>
Committed: Fri Mar 10 07:11:08 2017 +1000

----------------------------------------------------------------------
 .../beans/ListenerListASTTransformation.groovy  |  3 +-
 src/test/groovy/bugs/Groovy8110Bug.groovy       | 45 ++++++++++++++++++++
 2 files changed, 47 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/4f4aa73e/src/main/groovy/beans/ListenerListASTTransformation.groovy
----------------------------------------------------------------------
diff --git a/src/main/groovy/beans/ListenerListASTTransformation.groovy b/src/main/groovy/beans/ListenerListASTTransformation.groovy
index 1c191e7..4591346 100644
--- a/src/main/groovy/beans/ListenerListASTTransformation.groovy
+++ b/src/main/groovy/beans/ListenerListASTTransformation.groovy
@@ -18,6 +18,7 @@
  */
 package groovy.beans
 
+import org.codehaus.groovy.ast.tools.GenericsUtils
 import org.codehaus.groovy.control.CompilePhase
 import org.codehaus.groovy.control.SourceUnit
 import org.codehaus.groovy.control.messages.SyntaxErrorMessage
@@ -352,7 +353,7 @@ class ListenerListASTTransformation implements ASTTransformation, Opcodes {
 
         def params = method.parameters.collect {
             def paramType = ClassHelper.getWrapper(it.type)
-            def cn = ClassHelper.makeWithoutCaching(paramType.name)
+            def cn = GenericsUtils.makeClassSafe(paramType.typeClass)
             cn.setRedirect(paramType)
             new Parameter(cn, it.name)
         }

http://git-wip-us.apache.org/repos/asf/groovy/blob/4f4aa73e/src/test/groovy/bugs/Groovy8110Bug.groovy
----------------------------------------------------------------------
diff --git a/src/test/groovy/bugs/Groovy8110Bug.groovy b/src/test/groovy/bugs/Groovy8110Bug.groovy
new file mode 100644
index 0000000..355d462
--- /dev/null
+++ b/src/test/groovy/bugs/Groovy8110Bug.groovy
@@ -0,0 +1,45 @@
+/*
+ *  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 groovy.bugs
+
+class Groovy8110Bug extends GroovyTestCase {
+    void testListenerListWithArrayParam() {
+        assertScript '''
+            import groovy.beans.ListenerList
+
+            interface MessageListener {
+                void messageReceived(byte[] msg)
+            }
+
+            class MessageProducer {
+                String log = ''
+                @ListenerList List<MessageListener> listeners
+
+                void produce(String msg) {
+                    fireMessageReceived(msg.getBytes())
+                }
+            }
+
+            producer = new MessageProducer()
+            producer.addMessageListener({ producer.log += it.toString() } as MessageListener)
+            producer.produce('Groovy')
+            assert producer.log == '[71, 114, 111, 111, 118, 121]'
+        '''
+    }
+}


[29/50] [abbrv] groovy git commit: More useful error message in NodeList.replaceNode method (closes #516)

Posted by su...@apache.org.
More useful error message in NodeList.replaceNode method (closes #516)


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

Branch: refs/heads/parrot
Commit: 97a1a48258d23968ad173db7969916d3cdd7ef6a
Parents: 4432ca2
Author: Konstantin Yegupov <ky...@gmail.com>
Authored: Wed Mar 22 18:52:44 2017 +0000
Committer: John Wagenleitner <jw...@apache.org>
Committed: Sun Mar 26 11:22:15 2017 -0700

----------------------------------------------------------------------
 src/main/groovy/util/NodeList.java | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/97a1a482/src/main/groovy/util/NodeList.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/util/NodeList.java b/src/main/groovy/util/NodeList.java
index 1442a53..e54009c 100644
--- a/src/main/groovy/util/NodeList.java
+++ b/src/main/groovy/util/NodeList.java
@@ -187,7 +187,8 @@ public class NodeList extends ArrayList {
 
     public Node replaceNode(Closure c) {
         if (size() <= 0 || size() > 1) {
-            throw new GroovyRuntimeException("replaceNode() can only be used to replace a single node.");
+            throw new GroovyRuntimeException(
+                    "replaceNode() can only be used to replace a single node, but was applied to " + size() + " nodes");
         }
         return ((Node)get(0)).replaceNode(c);
     }


[27/50] [abbrv] groovy git commit: DefaultGroovyMethods: add javadoc examples for #find and #findResult

Posted by su...@apache.org.
DefaultGroovyMethods: add javadoc examples for #find and #findResult


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

Branch: refs/heads/parrot
Commit: 4432ca286d4f1c537acd9407f2f143cf362e714d
Parents: c155e9d
Author: pascalschumacher <pa...@gmx.net>
Authored: Wed Mar 22 21:44:28 2017 +0100
Committer: pascalschumacher <pa...@gmx.net>
Committed: Wed Mar 22 21:46:54 2017 +0100

----------------------------------------------------------------------
 .../groovy/runtime/DefaultGroovyMethods.java    | 20 +++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/4432ca28/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java b/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
index 68a9efd..a8b6868 100644
--- a/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
+++ b/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
@@ -3984,7 +3984,13 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
-     * Finds the first value matching the closure condition
+     * Finds the first value matching the closure condition.
+     *
+     * <pre class="groovyTestCase">
+     * def numbers = [1, 2, 3]
+     * def result = numbers.find { it > 1}
+     * assert result == 2
+     * </pre>
      *
      * @param self    an Object with an iterator returning its values
      * @param closure a closure condition
@@ -4023,6 +4029,12 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
     /**
      * Treats the object as iterable, iterating through the values it represents and returns the first non-null result obtained from calling the closure, otherwise returns the defaultResult.
      *
+     * <pre class="groovyTestCase">
+     * int[] numbers = [1, 2, 3]
+     * assert numbers.findResult(5) { if(it > 1) return it } == 2
+     * assert numbers.findResult(5) { if(it > 4) return it } == 5
+     * </pre>
+     *
      * @param self    an Object with an iterator returning its values
      * @param defaultResult an Object that should be returned if all closure results are null
      * @param closure a closure that returns a non-null value when processing should stop
@@ -4038,6 +4050,12 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
     /**
      * Treats the object as iterable, iterating through the values it represents and returns the first non-null result obtained from calling the closure, otherwise returns null.
      *
+     * <pre class="groovyTestCase">
+     * int[] numbers = [1, 2, 3]
+     * assert numbers.findResult { if(it > 1) return it } == 2
+     * assert numbers.findResult { if(it > 4) return it } == null
+     * </pre>
+     *
      * @param self    an Object with an iterator returning its values
      * @param closure a closure that returns a non-null value when processing should stop
      * @return the first non-null result of the closure


[18/50] [abbrv] groovy git commit: GROOVY-6792: ClassFormatError if a method has dots within its name (fix impact for tests)

Posted by su...@apache.org.
GROOVY-6792: ClassFormatError if a method has dots within its name (fix impact for tests)


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

Branch: refs/heads/parrot
Commit: 46a47936b9d595984c1d79e552e3ac3d686043cc
Parents: 800205d
Author: paulk <pa...@asert.com.au>
Authored: Tue Mar 14 22:32:24 2017 +1000
Committer: paulk <pa...@asert.com.au>
Committed: Tue Mar 14 22:32:24 2017 +1000

----------------------------------------------------------------------
 security/groovy.policy | 2 ++
 1 file changed, 2 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/46a47936/security/groovy.policy
----------------------------------------------------------------------
diff --git a/security/groovy.policy b/security/groovy.policy
index 9dc92a7..848de08 100644
--- a/security/groovy.policy
+++ b/security/groovy.policy
@@ -192,6 +192,7 @@ grant signedBy "Groovy" {
 
 grant codeBase "file:${user.dir}/src/test/groovy/bugs/BadScriptNameBug.groovy" {
     permission java.lang.RuntimePermission "createClassLoader";
+    permission java.util.PropertyPermission "groovy.compiler.strictNames", "read";
 };
 
 grant codeBase "file:${user.dir}/src/test/groovy/ClosureMethodTest.groovy" {
@@ -213,6 +214,7 @@ grant codeBase "file:${user.dir}/src/test/groovy/bugs/ConstructorBug.groovy" {
 
     // Required because GroovyCodeSource calls to File#getCanonicalPath (at least on the Windows FileSystem)
     permission java.util.PropertyPermission "user.dir", "read";
+    permission java.util.PropertyPermission "groovy.compiler.strictNames", "read";
 
     permission java.io.FilePermission "src${/}test${/}groovy${/}bugs${/}TestBase.groovy", "read";
     permission java.io.FilePermission "src${/}test${/}groovy${/}bugs${/}TestDerived.groovy", "read";


[31/50] [abbrv] groovy git commit: Adds documentation around 'remove' method Integer/Object ambiguity (closes #514)

Posted by su...@apache.org.
Adds documentation around 'remove' method Integer/Object ambiguity (closes #514)


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

Branch: refs/heads/parrot
Commit: 091a8b7be05208902d09492756e9b4953e7ec2fc
Parents: 293e179
Author: Jason Schindler <ja...@types.codes>
Authored: Sun Mar 19 14:50:40 2017 -0500
Committer: John Wagenleitner <jw...@apache.org>
Committed: Sun Mar 26 13:13:36 2017 -0700

----------------------------------------------------------------------
 src/spec/doc/working-with-collections.adoc      | 20 ++++++++++++++++----
 .../test/gdk/WorkingWithCollectionsTest.groovy  | 20 +++++++++++++++++++-
 2 files changed, 35 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/091a8b7b/src/spec/doc/working-with-collections.adoc
----------------------------------------------------------------------
diff --git a/src/spec/doc/working-with-collections.adoc b/src/spec/doc/working-with-collections.adoc
index 2e94c14..ace44ed 100644
--- a/src/spec/doc/working-with-collections.adoc
+++ b/src/spec/doc/working-with-collections.adoc
@@ -138,22 +138,34 @@ The {gdk} also contains methods allowing you to easily remove elements from a li
 include::{projectdir}/src/spec/test/gdk/WorkingWithCollectionsTest.groovy[tags=list_gdk3,indent=0]
 ----------------------------------------------------------------------------
 
-It is also possible to remove an element by referring to its index, in which case the list is mutated:
+It is also possible to remove an element by passing its index to the `remove` method, in which case the list is mutated:
 
 [source,groovy]
 ----------------------------------------------------------------------------
-include::{projectdir}/src/spec/test/gdk/WorkingWithCollectionsTest.groovy[tags=list_gdk4,indent=0]
+include::{projectdir}/src/spec/test/gdk/WorkingWithCollectionsTest.groovy[tags=list_gdk_remove_index,indent=0]
 ----------------------------------------------------------------------------
 
 In case you only want to remove the first element having the same value in a list, instead of removing all
-elements, you call call the `remove` method:
+elements, you call call the `remove` method passing the value:
 
 [source,groovy]
 ----------------------------------------------------------------------------
 include::{projectdir}/src/spec/test/gdk/WorkingWithCollectionsTest.groovy[tags=list_gdk5,indent=0]
 ----------------------------------------------------------------------------
 
-And removing all the elements in a list can be done by calling the `clear` method:
+As you can see, there are two `remove` methods available.  One that takes an integer and removes an element
+by its index, and another that will remove the first element that matches the passed value.  So what should we 
+do when we have a list of integers?  In this case, you may wish to use `removeAt` to remove an element by its
+index, and `removeElement` to remove the first element that matches a value.
+
+[source,groovy]
+----------------------------------------------------------------------------
+include::{projectdir}/src/spec/test/gdk/WorkingWithCollectionsTest.groovy[tags=list_gdk4,indent=0]
+----------------------------------------------------------------------------
+
+Of course, `removeAt` and `removeElement` will work with lists of any type.
+
+Additionally, removing all the elements in a list can be done by calling the `clear` method:
 
 [source,groovy]
 ----------------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/groovy/blob/091a8b7b/src/spec/test/gdk/WorkingWithCollectionsTest.groovy
----------------------------------------------------------------------
diff --git a/src/spec/test/gdk/WorkingWithCollectionsTest.groovy b/src/spec/test/gdk/WorkingWithCollectionsTest.groovy
index 46e5d51..a117ab1 100644
--- a/src/spec/test/gdk/WorkingWithCollectionsTest.groovy
+++ b/src/spec/test/gdk/WorkingWithCollectionsTest.groovy
@@ -238,10 +238,28 @@ class WorkingWithCollectionsTest extends GroovyTestCase {
         '''
 
         assertScript '''
+            // tag::list_gdk_remove_index[]
+            def list = ['a','b','c','d','e','f','b','b','a']
+            assert list.remove(2) == 'c'        // remove the third element, and return it
+            assert list == ['a','b','d','e','f','b','b','a']
+            // end::list_gdk_remove_index[]
+        '''
+        
+        assertScript '''
             // tag::list_gdk4[]
             def list = [1,2,3,4,5,6,2,2,1]
-            assert list.remove(2) == 3          // remove the third element, and return it
+
+            assert list.remove(2) == 3          // this removes the element at index 2, and returns it
             assert list == [1,2,4,5,6,2,2,1]
+
+            assert list.removeElement(2)        // remove first 2 and return true
+            assert list == [1,4,5,6,2,2,1]
+
+            assert ! list.removeElement(8)      // return false because 8 is not in the list
+            assert list == [1,4,5,6,2,2,1]
+
+            assert list.removeAt(1) == 4        // remove element at index 1, and return it
+            assert list == [1,5,6,2,2,1]
             // end::list_gdk4[]
         '''
 


[03/50] [abbrv] groovy git commit: refactor to remove duplicate code

Posted by su...@apache.org.
refactor to remove duplicate code


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

Branch: refs/heads/parrot
Commit: ed981a7212c855c0be50686fed3558e08dd8fa27
Parents: 1ed615a
Author: zhangbo <zh...@nanchao.org>
Authored: Wed Nov 2 13:39:06 2016 +0800
Committer: paulk <pa...@asert.com.au>
Committed: Thu Mar 2 18:59:48 2017 +1000

----------------------------------------------------------------------
 .../trait/TraitReceiverTransformer.java         | 97 +++++++++++++-------
 1 file changed, 64 insertions(+), 33 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/ed981a72/src/main/org/codehaus/groovy/transform/trait/TraitReceiverTransformer.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/transform/trait/TraitReceiverTransformer.java b/src/main/org/codehaus/groovy/transform/trait/TraitReceiverTransformer.java
index 42729b0..e89c3f7 100644
--- a/src/main/org/codehaus/groovy/transform/trait/TraitReceiverTransformer.java
+++ b/src/main/org/codehaus/groovy/transform/trait/TraitReceiverTransformer.java
@@ -54,7 +54,8 @@ import java.util.List;
 /**
  * This expression transformer is used internally by the {@link org.codehaus.groovy.transform.trait.TraitASTTransformation
  * trait} AST transformation to change the receiver of a message on "this" into a static method call on the trait helper
- * class. <p></p> In a nutshell, code like this one in a trait:<p></p> <code>void foo() { this.bar() }</code> is
+ * class. <p></p>
+ * In a nutshell, code like the following method definition in a trait:<p></p> <code>void foo() { this.bar() }</code> is
  * transformed into: <code>void foo() { TraitHelper$bar(this) }</code>
  *
  * @author Cedric Champeau
@@ -65,15 +66,18 @@ class TraitReceiverTransformer extends ClassCodeExpressionTransformer {
     private final VariableExpression weaved;
     private final SourceUnit unit;
     private final ClassNode traitClass;
+    private final ClassNode traitHelperClass;
     private final ClassNode fieldHelper;
     private final Collection<String> knownFields;
 
     private boolean inClosure;
 
-    public TraitReceiverTransformer(VariableExpression thisObject, SourceUnit unit, final ClassNode traitClass, ClassNode fieldHelper, Collection<String> knownFields) {
+    public TraitReceiverTransformer(VariableExpression thisObject, SourceUnit unit, final ClassNode traitClass,
+                                    final ClassNode traitHelperClass, ClassNode fieldHelper, Collection<String> knownFields) {
         this.weaved = thisObject;
         this.unit = unit;
         this.traitClass = traitClass;
+        this.traitHelperClass = traitHelperClass;
         this.fieldHelper = fieldHelper;
         this.knownFields = knownFields;
     }
@@ -136,15 +140,7 @@ class TraitReceiverTransformer extends ClassCodeExpressionTransformer {
             } else if (accessedVariable instanceof PropertyNode) {
                 String propName = accessedVariable.getName();
                 if (knownFields.contains(propName)) {
-                    String method = Traits.helperGetterName(new FieldNode(propName, 0, ClassHelper.OBJECT_TYPE, weavedType, null));
-                    MethodCallExpression mce = new MethodCallExpression(
-                            createFieldHelperReceiver(),
-                            method,
-                            ArgumentListExpression.EMPTY_ARGUMENTS
-                    );
-                    mce.setSourcePosition(exp);
-                    mce.setImplicitThis(false);
-                    return mce;
+                    return createFieldHelperCall(exp, weavedType, propName);
                 } else {
                     return new PropertyExpression(
                             new VariableExpression(weaved),
@@ -171,15 +167,7 @@ class TraitReceiverTransformer extends ClassCodeExpressionTransformer {
             if (pexp.isImplicitThis() || "this".equals(object.getText())) {
                 String propName = pexp.getPropertyAsString();
                 if (knownFields.contains(propName)) {
-                    String method = Traits.helperGetterName(new FieldNode(propName, 0, ClassHelper.OBJECT_TYPE, weavedType, null));
-                    MethodCallExpression mce = new MethodCallExpression(
-                            createFieldHelperReceiver(),
-                            method,
-                            ArgumentListExpression.EMPTY_ARGUMENTS
-                    );
-                    mce.setSourcePosition(exp);
-                    mce.setImplicitThis(false);
-                    return mce;
+                    return createFieldHelperCall(exp, weavedType, propName);
                 }
             }
         } else if (exp instanceof ClosureExpression) {
@@ -209,6 +197,18 @@ class TraitReceiverTransformer extends ClassCodeExpressionTransformer {
         return super.transform(exp);
     }
 
+    private Expression createFieldHelperCall(Expression exp, ClassNode weavedType, String propName) {
+        String method = Traits.helperGetterName(new FieldNode(propName, 0, ClassHelper.OBJECT_TYPE, weavedType, null));
+        MethodCallExpression mce = new MethodCallExpression(
+                createFieldHelperReceiver(),
+                method,
+                ArgumentListExpression.EMPTY_ARGUMENTS
+        );
+        mce.setSourcePosition(exp);
+        mce.setImplicitThis(false);
+        return mce;
+    }
+
     private Expression transformFieldExpression(final FieldExpression exp) {
         FieldNode field = exp.getField();
         MethodCallExpression mce = new MethodCallExpression(
@@ -294,7 +294,8 @@ class TraitReceiverTransformer extends ClassCodeExpressionTransformer {
         );
     }
 
-    private BinaryExpression createAssignmentToField(final Expression rightExpression, final Token operation, final String fieldName) {
+    private BinaryExpression createAssignmentToField(final Expression rightExpression,
+                                                     final Token operation, final String fieldName) {
         return new BinaryExpression(
                 new PropertyExpression(
                         new VariableExpression(weaved),
@@ -357,23 +358,24 @@ class TraitReceiverTransformer extends ClassCodeExpressionTransformer {
             List<MethodNode> methods = traitClass.getMethods(methodName);
             for (MethodNode methodNode : methods) {
                 if (methodName.equals(methodNode.getName()) && methodNode.isPrivate()) {
-                    return transformPrivateMethodCall(call, arguments, methodName);
+                    if (inClosure) {
+                        return transformPrivateMethodCallOnThisInClosure(call, arguments, methodName);
+                    }
+                    return transformPrivateMethodCallOnThis(call, arguments, methodName);
                 }
             }
         }
+
         if (inClosure) {
-            MethodCallExpression transformed = new MethodCallExpression(
-                    (Expression) call.getReceiver(),
-                    call.getMethod(),
-                    transform(call.getArguments())
-            );
-            transformed.setSourcePosition(call);
-            transformed.setSafe(call.isSafe());
-            transformed.setSpreadSafe(call.isSpreadSafe());
-            transformed.setImplicitThis(call.isImplicitThis());
-            return transformed;
+            return transformMethodCallOnThisInClosure(call);
         }
 
+        return transformMethodCallOnThisFallBack(call, method, arguments);
+
+    }
+
+    private Expression transformMethodCallOnThisFallBack(final MethodCallExpression call,
+                                                         final Expression method, final Expression arguments) {
         MethodCallExpression transformed = new MethodCallExpression(
                 weaved,
                 method,
@@ -386,7 +388,21 @@ class TraitReceiverTransformer extends ClassCodeExpressionTransformer {
         return transformed;
     }
 
-    private Expression transformPrivateMethodCall(final MethodCallExpression call, final Expression arguments, final String methodName) {
+    private Expression transformMethodCallOnThisInClosure(final MethodCallExpression call) {
+        MethodCallExpression transformed = new MethodCallExpression(
+                (Expression) call.getReceiver(),
+                call.getMethod(),
+                transform(call.getArguments())
+        );
+        transformed.setSourcePosition(call);
+        transformed.setSafe(call.isSafe());
+        transformed.setSpreadSafe(call.isSpreadSafe());
+        transformed.setImplicitThis(call.isImplicitThis());
+        return transformed;
+    }
+
+    private Expression transformPrivateMethodCallOnThis(final MethodCallExpression call,
+                                                        final Expression arguments, final String methodName) {
         ArgumentListExpression newArgs = createArgumentList(arguments);
         MethodCallExpression transformed = new MethodCallExpression(
                 new VariableExpression("this"),
@@ -400,6 +416,21 @@ class TraitReceiverTransformer extends ClassCodeExpressionTransformer {
         return transformed;
     }
 
+    private Expression transformPrivateMethodCallOnThisInClosure(final MethodCallExpression call,
+                                                                 final Expression arguments, final String methodName) {
+        ArgumentListExpression newArgs = createArgumentList(arguments);
+        MethodCallExpression transformed = new MethodCallExpression(
+                new ClassExpression(traitHelperClass),
+                methodName,
+                newArgs
+        );
+        transformed.setSourcePosition(call);
+        transformed.setSafe(call.isSafe());
+        transformed.setSpreadSafe(call.isSpreadSafe());
+        transformed.setImplicitThis(true);
+        return transformed;
+    }
+
     private Expression createFieldHelperReceiver() {
         return ClassHelper.CLASS_Type.equals(weaved.getOriginType()) ? weaved : new CastExpression(fieldHelper, weaved);
     }


[33/50] [abbrv] groovy git commit: Merge remote-tracking branch 'origin/master'

Posted by su...@apache.org.
Merge remote-tracking branch 'origin/master'


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

Branch: refs/heads/parrot
Commit: d1ecc176dc0cddd1cd3807846f6f4c9a39504344
Parents: 5d93686 5e4c92f
Author: paulk <pa...@asert.com.au>
Authored: Mon Mar 27 16:34:21 2017 +1000
Committer: paulk <pa...@asert.com.au>
Committed: Mon Mar 27 16:34:21 2017 +1000

----------------------------------------------------------------------
 src/main/groovy/util/NodeList.java              |  3 ++-
 .../groovy/runtime/DefaultGroovyMethods.java    | 20 +++++++++++++++++++-
 src/spec/doc/working-with-collections.adoc      | 20 ++++++++++++++++----
 .../test/gdk/WorkingWithCollectionsTest.groovy  | 20 +++++++++++++++++++-
 .../main/java/groovy/xml/dom/DOMCategory.java   |  5 ++++-
 5 files changed, 60 insertions(+), 8 deletions(-)
----------------------------------------------------------------------



[44/50] [abbrv] groovy git commit: merge global transforms from subprojects

Posted by su...@apache.org.
merge global transforms from subprojects


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

Branch: refs/heads/parrot
Commit: 42b9a42323b8a8cb74bf76b17427a49a2de92d78
Parents: 1877bed
Author: paulk <pa...@asert.com.au>
Authored: Wed Mar 29 22:46:20 2017 +1000
Committer: paulk <pa...@asert.com.au>
Committed: Wed Mar 29 22:47:09 2017 +1000

----------------------------------------------------------------------
 gradle/assemble.gradle | 34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/42b9a423/gradle/assemble.gradle
----------------------------------------------------------------------
diff --git a/gradle/assemble.gradle b/gradle/assemble.gradle
index 57a0bbb..72ef7f5 100644
--- a/gradle/assemble.gradle
+++ b/gradle/assemble.gradle
@@ -315,6 +315,36 @@ def mergeModuleDescriptors() {
     descriptor
 }
 
+def mergeGlobalTransforms() {
+    new File("$buildDir/tmp/").mkdirs()
+
+    def descriptor = new File("$buildDir/tmp/org.codehaus.groovy.transform.ASTTransformation")
+    descriptor.withWriter('UTF-8') {
+        it << '# This is a generated file, do not edit\n'
+    }
+
+    def files = []
+    files << new File("${rootProject.buildDir}/resources/main/META-INF/services/org.codehaus.groovy.transform.ASTTransformation")
+    modules().collect {
+        new File("${it.buildDir}/resources/main/META-INF/services/org.codehaus.groovy.transform.ASTTransformation")
+    }.findAll { it.exists() }.each {
+        files << it
+    }
+    files.each {
+        def skipping = true
+        it.readLines().each { line ->
+            if (skipping) {
+                skipping = line.startsWith('#')
+            }
+            if (!skipping) {
+                descriptor << line + '\n'
+            }
+        }
+    }
+
+    descriptor
+}
+
 task replaceJarWithJarJar(dependsOn: allprojects.jarjar ) {
     description = "Overwrites normal JAR files with their JARJAR version"
     doLast {
@@ -370,6 +400,10 @@ task jarAll(type: Jar, dependsOn: replaceJarWithJarJar) {
             into "$owner.ext.metaInfDir/services"
         }
         copy {
+            from(mergeGlobalTransforms())
+            into "$owner.ext.metaInfDir/services"
+        }
+        copy {
             into "$owner.ext.metaInfDir"
         }
         logger.info 'Packaging with jarjar'


[30/50] [abbrv] groovy git commit: More useful error message in DOMCategory.replaceNode method

Posted by su...@apache.org.
More useful error message in DOMCategory.replaceNode method

Related to change in PR #516


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

Branch: refs/heads/parrot
Commit: 293e1790fec7a446de763c42e1dd1243c0218d11
Parents: 97a1a48
Author: John Wagenleitner <jw...@apache.org>
Authored: Sun Mar 26 11:40:24 2017 -0700
Committer: John Wagenleitner <jw...@apache.org>
Committed: Sun Mar 26 11:40:24 2017 -0700

----------------------------------------------------------------------
 .../groovy-xml/src/main/java/groovy/xml/dom/DOMCategory.java    | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/293e1790/subprojects/groovy-xml/src/main/java/groovy/xml/dom/DOMCategory.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-xml/src/main/java/groovy/xml/dom/DOMCategory.java b/subprojects/groovy-xml/src/main/java/groovy/xml/dom/DOMCategory.java
index d2f0d6d..71fb4d3 100644
--- a/subprojects/groovy-xml/src/main/java/groovy/xml/dom/DOMCategory.java
+++ b/subprojects/groovy-xml/src/main/java/groovy/xml/dom/DOMCategory.java
@@ -355,7 +355,10 @@ public class DOMCategory {
 
     public static Node replaceNode(NodesHolder self, Closure c) {
         if (self.getLength() <= 0 || self.getLength() > 1) {
-            throw new GroovyRuntimeException("replaceNode() can only be used to replace a single element.");
+            throw new GroovyRuntimeException(
+                    "replaceNode() can only be used to replace a single element, " +
+                    "but was applied to " + self.getLength() + " elements."
+            );
         }
         return replaceNode(self.item(0), c);
     }


[19/50] [abbrv] groovy git commit: bump version to 3.0.0 for master

Posted by su...@apache.org.
bump version to 3.0.0 for master


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

Branch: refs/heads/parrot
Commit: 48f99a1b6131dcba59a609ff56737c53dac9ae1c
Parents: 46a4793
Author: paulk <pa...@asert.com.au>
Authored: Wed Mar 15 10:16:19 2017 +1000
Committer: paulk <pa...@asert.com.au>
Committed: Wed Mar 15 10:16:19 2017 +1000

----------------------------------------------------------------------
 gradle.properties | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/48f99a1b/gradle.properties
----------------------------------------------------------------------
diff --git a/gradle.properties b/gradle.properties
index c745a6f..db8f993 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -13,9 +13,9 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-groovyVersion = 2.5.0-SNAPSHOT
+groovyVersion = 3.0.0-SNAPSHOT
 # bundle version format: major('.'minor('.'micro('.'qualifier)?)?)? (first 3 only digits)
-groovyBundleVersion = 2.5.0.SNAPSHOT
+groovyBundleVersion = 3.0.0.SNAPSHOT
 
 groovyJUnit_ms = 256m
 groovyJUnit_mx = 512m


[10/50] [abbrv] groovy git commit: add license header to test groovy file

Posted by su...@apache.org.
add license header to test groovy file


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

Branch: refs/heads/parrot
Commit: 3d752e352d9a32ba14ce07030e4a306654e37dde
Parents: 64d4f84
Author: zhangbo <zh...@nanchao.org>
Authored: Sat Oct 8 09:52:27 2016 +0800
Committer: paulk <pa...@asert.com.au>
Committed: Wed Mar 8 17:50:01 2017 +1000

----------------------------------------------------------------------
 src/test/groovy/bugs/Groovy7909Bug.groovy | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/3d752e35/src/test/groovy/bugs/Groovy7909Bug.groovy
----------------------------------------------------------------------
diff --git a/src/test/groovy/bugs/Groovy7909Bug.groovy b/src/test/groovy/bugs/Groovy7909Bug.groovy
index b1e1f97..5eb6454 100644
--- a/src/test/groovy/bugs/Groovy7909Bug.groovy
+++ b/src/test/groovy/bugs/Groovy7909Bug.groovy
@@ -1,3 +1,21 @@
+/*
+ *  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 groovy.bugs
 
 import gls.CompilableTestSupport


[08/50] [abbrv] groovy git commit: GROOVY-6792: ClassFormatError if a method has dots within its name (closes #505)

Posted by su...@apache.org.
GROOVY-6792: ClassFormatError if a method has dots within its name (closes #505)


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

Branch: refs/heads/parrot
Commit: 4382195f20ad597e22b744e16de28ee3a79af543
Parents: 988c386
Author: paulk <pa...@asert.com.au>
Authored: Tue Feb 28 13:05:22 2017 +1000
Committer: paulk <pa...@asert.com.au>
Committed: Wed Mar 8 15:49:29 2017 +1000

----------------------------------------------------------------------
 .../classgen/ClassCompletionVerifier.java       | 18 ++++++++-
 src/test/groovy/bugs/Groovy6792Bug.groovy       | 41 ++++++++++++++++++++
 2 files changed, 58 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/4382195f/src/main/org/codehaus/groovy/classgen/ClassCompletionVerifier.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/classgen/ClassCompletionVerifier.java b/src/main/org/codehaus/groovy/classgen/ClassCompletionVerifier.java
index a8f4948..aba375a 100644
--- a/src/main/org/codehaus/groovy/classgen/ClassCompletionVerifier.java
+++ b/src/main/org/codehaus/groovy/classgen/ClassCompletionVerifier.java
@@ -54,7 +54,7 @@ import static org.objectweb.asm.Opcodes.*;
  * </ul>
  */
 public class ClassCompletionVerifier extends ClassCodeVisitorSupport {
-
+    private static final String[] INVALID_NAME_CHARS = {".", ":", "/", ";", "[", "<", ">"};
     private ClassNode currentClass;
     private final SourceUnit source;
     private boolean inConstructor = false;
@@ -78,6 +78,7 @@ public class ClassCompletionVerifier extends ClassCodeVisitorSupport {
             checkAbstractMethodVisibility(node);
             checkClassForOverwritingFinal(node);
             checkMethodsForIncorrectModifiers(node);
+            checkMethodsForIncorrectName(node);
             checkMethodsForWeakerAccess(node);
             checkMethodsForOverridingFinal(node);
             checkNoAbstractMethodsNonabstractClass(node);
@@ -289,6 +290,21 @@ public class ClassCompletionVerifier extends ClassCodeVisitorSupport {
         }
     }
 
+    private void checkMethodsForIncorrectName(ClassNode cn) {
+        List<MethodNode> methods = cn.getAllDeclaredMethods();
+        for (MethodNode mNode : methods) {
+            String name = mNode.getName();
+            if (name.equals("<init>") || name.equals("<clinit>")) continue;
+            // Groovy allows more characters than Character.isValidJavaIdentifier() would allow
+            // if we find a good way to encode special chars we could remove (some of) these checks
+            for (String ch : INVALID_NAME_CHARS) {
+                if (name.contains(ch)) {
+                    addError("You are not allowed to have '" + ch + "' in a method name", mNode);
+                }
+            }
+        }
+    }
+
     private void checkMethodsForIncorrectModifiers(ClassNode cn) {
         if (!cn.isInterface()) return;
         for (MethodNode method : cn.getMethods()) {

http://git-wip-us.apache.org/repos/asf/groovy/blob/4382195f/src/test/groovy/bugs/Groovy6792Bug.groovy
----------------------------------------------------------------------
diff --git a/src/test/groovy/bugs/Groovy6792Bug.groovy b/src/test/groovy/bugs/Groovy6792Bug.groovy
new file mode 100644
index 0000000..9223174
--- /dev/null
+++ b/src/test/groovy/bugs/Groovy6792Bug.groovy
@@ -0,0 +1,41 @@
+/*
+ *  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 groovy.bugs
+
+import gls.CompilableTestSupport
+
+class Groovy6792Bug extends CompilableTestSupport {
+    void testMethodWithSpecialCharsInName() {
+        assertScript """
+            class Foo {
+                static ",{}()|!?foo@#\\\$%^&*-=]\\\\bar'\\""(){ Foo.name }
+            }
+            assert Foo.",{}()|!?foo@#\\\$%^&*-=]\\\\bar'\\""() == 'Foo'
+        """
+    }
+
+    void testMethodWithInvalidName() {
+        def message = shouldNotCompile """
+            class Foo {
+                def "bar.baz"(){}
+            }
+        """
+        assert message.contains("You are not allowed to have '.' in a method name")
+    }
+}


[02/50] [abbrv] groovy git commit: fix groovy7797 - assign correct receiver in closure

Posted by su...@apache.org.
fix groovy7797 - assign correct receiver in closure


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

Branch: refs/heads/parrot
Commit: 1ed615a2a770d7539c8a62d198a7d432ba5050f1
Parents: 5d3f747
Author: zhangbo <zh...@nanchao.org>
Authored: Wed Nov 2 13:33:32 2016 +0800
Committer: paulk <pa...@asert.com.au>
Committed: Thu Mar 2 18:59:12 2017 +1000

----------------------------------------------------------------------
 src/test/groovy/bugs/Groovy7797Bug.groovy | 38 ++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/1ed615a2/src/test/groovy/bugs/Groovy7797Bug.groovy
----------------------------------------------------------------------
diff --git a/src/test/groovy/bugs/Groovy7797Bug.groovy b/src/test/groovy/bugs/Groovy7797Bug.groovy
new file mode 100644
index 0000000..892b6eb
--- /dev/null
+++ b/src/test/groovy/bugs/Groovy7797Bug.groovy
@@ -0,0 +1,38 @@
+/*
+ *  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 groovy.bugs
+
+class Groovy7797Bug extends GroovyTestCase {
+    void test() {
+        new GroovyShell().evaluate('''
+trait MyTrait {
+    void greeter() {
+        { ->doGreeting("hi") }.call()
+        //doGreeting("hi")
+    }
+
+    private void doGreeting(String message) { println message }
+}
+
+class MyClass implements MyTrait {}
+new MyClass().greeter()
+''')
+    }
+}
+


[37/50] [abbrv] groovy git commit: extract MacroCallTransformingVisitor

Posted by su...@apache.org.
extract MacroCallTransformingVisitor


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

Branch: refs/heads/parrot
Commit: ada0e2cd5442ff4bdd8e14839a49987abb60e7a3
Parents: b4e68bd
Author: Sergei Egorov <se...@zeroturnaround.com>
Authored: Mon Mar 13 15:59:14 2017 +0200
Committer: paulk <pa...@asert.com.au>
Committed: Tue Mar 28 16:02:23 2017 +1000

----------------------------------------------------------------------
 .../transform/MacroCallTransformingVisitor.java | 100 +++++++++++++++++++
 .../macro/transform/MacroTransformation.java    |  86 +---------------
 2 files changed, 101 insertions(+), 85 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/ada0e2cd/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroCallTransformingVisitor.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroCallTransformingVisitor.java b/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroCallTransformingVisitor.java
new file mode 100644
index 0000000..6af1afe
--- /dev/null
+++ b/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroCallTransformingVisitor.java
@@ -0,0 +1,100 @@
+package org.codehaus.groovy.macro.transform;
+
+import org.codehaus.groovy.ast.*;
+import org.codehaus.groovy.ast.expr.*;
+import org.codehaus.groovy.classgen.asm.InvocationWriter;
+import org.codehaus.groovy.control.CompilationUnit;
+import org.codehaus.groovy.control.SourceUnit;
+import org.codehaus.groovy.macro.runtime.MacroContext;
+import org.codehaus.groovy.macro.runtime.MacroStub;
+import org.codehaus.groovy.runtime.InvokerHelper;
+import org.codehaus.groovy.transform.stc.ExtensionMethodNode;
+import org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport;
+
+import java.util.ArrayList;
+import java.util.List;
+
+class MacroCallTransformingVisitor extends ClassCodeVisitorSupport {
+
+    private static final ClassNode MACRO_CONTEXT_CLASS_NODE = ClassHelper.make(MacroContext.class);
+
+    private static final ClassNode MACRO_STUB_CLASS_NODE = ClassHelper.make(MacroStub.class);
+
+    private static final PropertyExpression MACRO_STUB_INSTANCE = new PropertyExpression(new ClassExpression(MACRO_STUB_CLASS_NODE), "INSTANCE");
+
+    private static final String MACRO_STUB_METHOD_NAME = "macroMethod";
+
+    private final SourceUnit sourceUnit;
+    private final CompilationUnit unit;
+    private final ClassLoader classLoader;
+
+    public MacroCallTransformingVisitor(SourceUnit sourceUnit, CompilationUnit unit) {
+        this.sourceUnit = sourceUnit;
+        this.unit = unit;
+        this.classLoader = unit.getTransformLoader();
+    }
+
+    @Override
+    protected SourceUnit getSourceUnit() {
+        return sourceUnit;
+    }
+
+    @Override
+    public void visitMethodCallExpression(MethodCallExpression call) {
+        super.visitMethodCallExpression(call);
+
+        List<MethodNode> methods = MacroMethodsCache.get(classLoader).get(call.getMethodAsString());
+
+        if (methods == null) {
+            // Not a macro call
+            return;
+        }
+
+        List<Expression> callArguments = InvocationWriter.makeArgumentList(call.getArguments()).getExpressions();
+
+        ClassNode[] argumentsList = new ClassNode[callArguments.size()];
+
+        for (int i = 0; i < callArguments.size(); i++) {
+            argumentsList[i] = ClassHelper.make(callArguments.get(i).getClass());
+        }
+
+        methods = StaticTypeCheckingSupport.chooseBestMethod(MACRO_CONTEXT_CLASS_NODE, methods, argumentsList);
+
+        for (MethodNode macroMethodNode : methods) {
+            if (!(macroMethodNode instanceof ExtensionMethodNode)) {
+                // TODO is it even possible?
+                continue;
+            }
+
+            MethodNode macroExtensionMethodNode = ((ExtensionMethodNode) macroMethodNode).getExtensionMethodNode();
+
+            final Class clazz;
+            try {
+                clazz = classLoader.loadClass(macroExtensionMethodNode.getDeclaringClass().getName());
+            } catch (ClassNotFoundException e) {
+                //TODO different reaction?
+                continue;
+            }
+
+            MacroContext macroContext = new MacroContext(unit, sourceUnit, call);
+
+            List<Object> macroArguments = new ArrayList<>();
+            macroArguments.add(macroContext);
+            macroArguments.addAll(callArguments);
+
+            Expression result = (Expression) InvokerHelper.invokeStaticMethod(clazz, macroMethodNode.getName(), macroArguments.toArray());
+
+            call.setObjectExpression(MACRO_STUB_INSTANCE);
+            call.setMethod(new ConstantExpression(MACRO_STUB_METHOD_NAME));
+
+            // TODO check that we reset everything here
+            call.setSpreadSafe(false);
+            call.setSafe(false);
+            call.setImplicitThis(false);
+            call.setArguments(result);
+            call.setGenericsTypes(new GenericsType[0]);
+
+            break;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/ada0e2cd/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroTransformation.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroTransformation.java b/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroTransformation.java
index 84e8d60..983ba18 100644
--- a/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroTransformation.java
+++ b/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroTransformation.java
@@ -20,20 +20,10 @@ package org.codehaus.groovy.macro.transform;
 
 import groovy.transform.CompilationUnitAware;
 import org.codehaus.groovy.ast.*;
-import org.codehaus.groovy.ast.expr.*;
-import org.codehaus.groovy.classgen.asm.InvocationWriter;
 import org.codehaus.groovy.control.CompilationUnit;
 import org.codehaus.groovy.control.CompilePhase;
 import org.codehaus.groovy.control.SourceUnit;
-import org.codehaus.groovy.macro.runtime.MacroContext;
-import org.codehaus.groovy.macro.runtime.MacroStub;
-import org.codehaus.groovy.runtime.InvokerHelper;
 import org.codehaus.groovy.transform.GroovyASTTransformation;
-import org.codehaus.groovy.transform.stc.ExtensionMethodNode;
-import org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport;
-
-import java.util.ArrayList;
-import java.util.List;
 
 /**
  * @author Sergei Egorov <bs...@gmail.com>
@@ -42,14 +32,6 @@ import java.util.List;
 @GroovyASTTransformation(phase = CompilePhase.CONVERSION)
 public class MacroTransformation extends MethodCallTransformation implements CompilationUnitAware {
 
-    private static final ClassNode MACRO_CONTEXT_CLASS_NODE = ClassHelper.make(MacroContext.class);
-
-    private static final ClassNode MACRO_STUB_CLASS_NODE = ClassHelper.make(MacroStub.class);
-
-    private static final PropertyExpression MACRO_STUB_INSTANCE = new PropertyExpression(new ClassExpression(MACRO_STUB_CLASS_NODE), "INSTANCE");
-
-    private static final String MACRO_STUB_METHOD_NAME = "macroMethod";
-
     protected CompilationUnit unit;
 
     @Override
@@ -59,72 +41,6 @@ public class MacroTransformation extends MethodCallTransformation implements Com
 
     @Override
     protected GroovyCodeVisitor getTransformer(ASTNode[] nodes, final SourceUnit sourceUnit) {
-        // Macro methods should on a classpath of the compiler because we invoke them during the compilation
-        final ClassLoader classLoader = this.getClass().getClassLoader();
-        return new ClassCodeVisitorSupport() {
-
-            @Override
-            protected SourceUnit getSourceUnit() {
-                return sourceUnit;
-            }
-
-            @Override
-            public void visitMethodCallExpression(MethodCallExpression call) {
-                super.visitMethodCallExpression(call);
-
-                List<MethodNode> methods = MacroMethodsCache.get(classLoader).get(call.getMethodAsString());
-
-                if (methods == null) {
-                    // Not a macro call
-                    return;
-                }
-
-                List<Expression> callArguments = InvocationWriter.makeArgumentList(call.getArguments()).getExpressions();
-
-                ClassNode[] argumentsList = new ClassNode[callArguments.size()];
-
-                for (int i = 0; i < callArguments.size(); i++) {
-                    argumentsList[i] = ClassHelper.make(callArguments.get(i).getClass());
-                }
-
-                methods = StaticTypeCheckingSupport.chooseBestMethod(MACRO_CONTEXT_CLASS_NODE, methods, argumentsList);
-
-                for (MethodNode macroMethodNode : methods) {
-                    if (!(macroMethodNode instanceof ExtensionMethodNode)) {
-                        // TODO is it even possible?
-                        continue;
-                    }
-
-                    MethodNode macroExtensionMethodNode = ((ExtensionMethodNode) macroMethodNode).getExtensionMethodNode();
-
-                    final Class clazz;
-                    try {
-                        clazz = classLoader.loadClass(macroExtensionMethodNode.getDeclaringClass().getName());
-                    } catch (ClassNotFoundException e) {
-                        //TODO different reaction?
-                        continue;
-                    }
-
-                    MacroContext macroContext = new MacroContext(unit, sourceUnit, call);
-
-                    List<Object> macroArguments = new ArrayList<>();
-                    macroArguments.add(macroContext);
-                    macroArguments.addAll(callArguments);
-
-                    Expression result = (Expression) InvokerHelper.invokeStaticMethod(clazz, macroMethodNode.getName(), macroArguments.toArray());
-
-                    call.setObjectExpression(MACRO_STUB_INSTANCE);
-                    call.setMethod(new ConstantExpression(MACRO_STUB_METHOD_NAME));
-
-                    // TODO check that we reset everything here
-                    call.setSpreadSafe(false);
-                    call.setSafe(false);
-                    call.setImplicitThis(false);
-                    call.setArguments(result);
-
-                    break;
-                }
-            }
-        };
+        return new MacroCallTransformingVisitor(sourceUnit, unit);
     }
 }


[21/50] [abbrv] groovy git commit: temporary version change until Spock supports 3+

Posted by su...@apache.org.
temporary version change until Spock supports 3+


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

Branch: refs/heads/parrot
Commit: e8863f4a203e2343457eeae414b36f32d6870f3a
Parents: 439e297
Author: paulk <pa...@asert.com.au>
Authored: Thu Mar 16 20:16:51 2017 +1000
Committer: paulk <pa...@asert.com.au>
Committed: Thu Mar 16 20:19:47 2017 +1000

----------------------------------------------------------------------
 gradle.properties | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/e8863f4a/gradle.properties
----------------------------------------------------------------------
diff --git a/gradle.properties b/gradle.properties
index db8f993..4d21a12 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -13,9 +13,9 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-groovyVersion = 3.0.0-SNAPSHOT
+groovyVersion = 2.9.98-SNAPSHOT
 # bundle version format: major('.'minor('.'micro('.'qualifier)?)?)? (first 3 only digits)
-groovyBundleVersion = 3.0.0.SNAPSHOT
+groovyBundleVersion = 2.9.98.SNAPSHOT
 
 groovyJUnit_ms = 256m
 groovyJUnit_mx = 512m


[17/50] [abbrv] groovy git commit: GROOVY-8119: Groovy Language Specification documentation has bad internal links to "type checking section"

Posted by su...@apache.org.
GROOVY-8119: Groovy Language Specification documentation has bad internal links to "type checking section"


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

Branch: refs/heads/parrot
Commit: 800205d432335024e72a5d11db3994d20ba044be
Parents: 64a7dda
Author: paulk <pa...@asert.com.au>
Authored: Tue Mar 14 21:05:52 2017 +1000
Committer: paulk <pa...@asert.com.au>
Committed: Tue Mar 14 21:05:52 2017 +1000

----------------------------------------------------------------------
 src/spec/doc/core-semantics.adoc | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/800205d4/src/spec/doc/core-semantics.adoc
----------------------------------------------------------------------
diff --git a/src/spec/doc/core-semantics.adoc b/src/spec/doc/core-semantics.adoc
index cdbeace..68c9629 100644
--- a/src/spec/doc/core-semantics.adoc
+++ b/src/spec/doc/core-semantics.adoc
@@ -863,7 +863,7 @@ include::{projectdir}/src/spec/test/typing/OptionalTypingTest.groovy[tags=option
 <2> we can still call the `toUpperCase` method, because the type of `aString` is resolved at runtime
 
 So it doesn't matter that you use an explicit type here. It is in particular interesting when you combine this feature
-with <<typechecking,static type checking>>, because the type checker performs type inference.
+with <<static-type-checking,static type checking>>, because the type checker performs type inference.
 
 Likewise, Groovy doesn't make it mandatory to declare the types of a parameter in a method:
 
@@ -1989,7 +1989,7 @@ discussed in a link:core-domain-specific-languages.html#section-delegatesto[spec
 
 ==== Dynamic vs static
 
-In the <<typechecking,type checking section>>, we have seen that Groovy provides optional type checking thanks to the
+In the <<static-type-checking,type checking section>>, we have seen that Groovy provides optional type checking thanks to the
 `@TypeChecked` annotation. The type checker runs at compile time and performs a static analysis of dynamic code. The
 program will behave exactly the same whether type checking has been enabled or not. This means that the `@TypeChecked`
 annotation is neutral with regards to the semantics of a program. Even though it may be necessary to add type information


[25/50] [abbrv] groovy git commit: tweak build to report snapshot dependencies found during non-snapshot release

Posted by su...@apache.org.
tweak build to report snapshot dependencies found during non-snapshot release


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

Branch: refs/heads/parrot
Commit: a4ba2032601884c2dd0ad0af84da16ac17b752ad
Parents: 2211af5
Author: paulk <pa...@asert.com.au>
Authored: Tue Mar 21 21:06:51 2017 +1000
Committer: paulk <pa...@asert.com.au>
Committed: Tue Mar 21 21:06:51 2017 +1000

----------------------------------------------------------------------
 gradle/assemble.gradle | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/a4ba2032/gradle/assemble.gradle
----------------------------------------------------------------------
diff --git a/gradle/assemble.gradle b/gradle/assemble.gradle
index f83e2e6..57a0bbb 100644
--- a/gradle/assemble.gradle
+++ b/gradle/assemble.gradle
@@ -586,6 +586,22 @@ task installGroovy(type: Sync, dependsOn: [checkCompatibility, distBin]) {
     into installDir
 }
 
+task checkNoSnapshotVersions {
+    doLast {
+        if (project.isReleaseVersion) {
+            // TODO use modules() and exclusions as per distSpec
+            allprojects {
+                project.configurations.runtime.resolvedConfiguration.resolvedArtifacts.each {
+                    if (it.moduleVersion.id.version.endsWith("-SNAPSHOT")) {
+                        throw new GradleException("Found snapshot dependency for non-snapshot Groovy: " + it.moduleVersion)
+                    }
+                }
+            }
+        }
+    }
+}
+distBin.dependsOn checkNoSnapshotVersions
+
 import org.gradle.api.file.DuplicatesStrategy
 
 task dist(type: Zip, dependsOn: [checkCompatibility, distBin, distSrc, distDoc, syncDoc]) {


[04/50] [abbrv] groovy git commit: refactor a huge monster method which is over 100 lines (closes #455)

Posted by su...@apache.org.
refactor a huge monster method which is over 100 lines (closes #455)


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

Branch: refs/heads/parrot
Commit: ec3179a45582fc57077ca1ffe87e0ed60545681e
Parents: ed981a7
Author: zhangbo <zh...@nanchao.org>
Authored: Wed Nov 2 13:46:33 2016 +0800
Committer: paulk <pa...@asert.com.au>
Committed: Thu Mar 2 19:02:57 2017 +1000

----------------------------------------------------------------------
 .../transform/trait/TraitASTTransformation.java     | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/ec3179a4/src/main/org/codehaus/groovy/transform/trait/TraitASTTransformation.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/transform/trait/TraitASTTransformation.java b/src/main/org/codehaus/groovy/transform/trait/TraitASTTransformation.java
index 5ff3bb7..99d1c0d 100644
--- a/src/main/org/codehaus/groovy/transform/trait/TraitASTTransformation.java
+++ b/src/main/org/codehaus/groovy/transform/trait/TraitASTTransformation.java
@@ -192,7 +192,7 @@ public class TraitASTTransformation extends AbstractASTTransformation implements
                             methodNode.getLineNumber(), methodNode.getColumnNumber()));
                     return;
                 }
-                helper.addMethod(processMethod(cNode, methodNode, fieldHelper, fieldNames));
+                helper.addMethod(processMethod(cNode, helper, methodNode, fieldHelper, fieldNames));
                 if (methodNode.isPrivate() || methodNode.isStatic()) {
                     nonPublicAPIMethods.add(methodNode);
                 }
@@ -386,9 +386,9 @@ public class TraitASTTransformation extends AbstractASTTransformation implements
         return true;
     }
 
-
     private void processField(final FieldNode field, final MethodNode initializer, final MethodNode staticInitializer,
-                              final ClassNode fieldHelper, final ClassNode helper, final ClassNode trait, final Set<String> knownFields) {
+                              final ClassNode fieldHelper, final ClassNode helper, final ClassNode trait,
+                              final Set<String> knownFields) {
         if (field.isProtected()) {
             unit.addError(new SyntaxException("Cannot have protected field in a trait (" + trait.getName() + "#" + field.getName() + ")",
                     field.getLineNumber(), field.getColumnNumber()));
@@ -412,7 +412,7 @@ public class TraitASTTransformation extends AbstractASTTransformation implements
             } else {
                 VariableExpression thisObject = new VariableExpression(selectedMethod.getParameters()[0]);
                 ExpressionStatement initCode = new ExpressionStatement(initialExpression);
-                processBody(thisObject, selectedMethod, initCode, trait, fieldHelper, knownFields);
+                processBody(thisObject, initCode, trait, helper, fieldHelper, knownFields);
                 BlockStatement code = (BlockStatement) selectedMethod.getCode();
                 MethodCallExpression mce;
                 if (field.isStatic()) {
@@ -476,7 +476,7 @@ public class TraitASTTransformation extends AbstractASTTransformation implements
         fieldHelper.addField(dummyField);
     }
 
-    private MethodNode processMethod(ClassNode traitClass, MethodNode methodNode, ClassNode fieldHelper, Collection<String> knownFields) {
+    private MethodNode processMethod(ClassNode traitClass, ClassNode traitHelperClass, MethodNode methodNode, ClassNode fieldHelper, Collection<String> knownFields) {
         Parameter[] initialParams = methodNode.getParameters();
         Parameter[] newParams = new Parameter[initialParams.length + 1];
         newParams[0] = createSelfParameter(traitClass, methodNode.isStatic());
@@ -488,7 +488,7 @@ public class TraitASTTransformation extends AbstractASTTransformation implements
                 methodNode.getReturnType(),
                 newParams,
                 methodNode.getExceptions(),
-                processBody(new VariableExpression(newParams[0]), methodNode, methodNode.getCode(), traitClass, fieldHelper, knownFields)
+                processBody(new VariableExpression(newParams[0]), methodNode.getCode(), traitClass, traitHelperClass, fieldHelper, knownFields)
         );
         mNode.setSourcePosition(methodNode);
         mNode.addAnnotations(filterAnnotations(methodNode.getAnnotations()));
@@ -538,13 +538,13 @@ public class TraitASTTransformation extends AbstractASTTransformation implements
         return type;
     }
 
-    private Statement processBody(VariableExpression thisObject, MethodNode methodNode, Statement code, ClassNode trait, ClassNode fieldHelper, Collection<String> knownFields) {
+    private Statement processBody(VariableExpression thisObject, Statement code, ClassNode trait, ClassNode traitHelper, ClassNode fieldHelper, Collection<String> knownFields) {
         if (code == null) return null;
         NAryOperationRewriter operationRewriter = new NAryOperationRewriter(unit, knownFields);
         code.visit(operationRewriter);
         SuperCallTraitTransformer superTrn = new SuperCallTraitTransformer(unit);
         code.visit(superTrn);
-        TraitReceiverTransformer trn = new TraitReceiverTransformer(thisObject, unit, trait, fieldHelper, knownFields);
+        TraitReceiverTransformer trn = new TraitReceiverTransformer(thisObject, unit, trait, traitHelper, fieldHelper, knownFields);
         code.visit(trn);
         return code;
     }


[07/50] [abbrv] groovy git commit: GROOVY-8109: Unsupported operator with @CompileStatic causes BUG! () during compilation - add test (closes #509)

Posted by su...@apache.org.
GROOVY-8109: Unsupported operator with @CompileStatic causes BUG! () during compilation - add test (closes #509)


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

Branch: refs/heads/parrot
Commit: 988c3865ed8e725c6cdfeb82d4c1c983a3135042
Parents: 8303729
Author: paulk <pa...@asert.com.au>
Authored: Wed Mar 8 15:46:57 2017 +1000
Committer: paulk <pa...@asert.com.au>
Committed: Wed Mar 8 15:46:57 2017 +1000

----------------------------------------------------------------------
 src/test/groovy/EqualsTest.groovy | 31 ++++++++++++++++++++++++++-----
 1 file changed, 26 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/988c3865/src/test/groovy/EqualsTest.groovy
----------------------------------------------------------------------
diff --git a/src/test/groovy/EqualsTest.groovy b/src/test/groovy/EqualsTest.groovy
index 8011ea9..1e3c612 100644
--- a/src/test/groovy/EqualsTest.groovy
+++ b/src/test/groovy/EqualsTest.groovy
@@ -18,6 +18,8 @@
  */
 package groovy
 
+import org.codehaus.groovy.control.MultipleCompilationErrorsException
+
 class EqualsTest extends GroovyShellTestCase {
 
     void testParentChildrenEquals() {
@@ -37,15 +39,34 @@ class EqualsTest extends GroovyShellTestCase {
         assert x != n
     }
 
-    void testIdentical() {
-        shouldFail {
+    // until Parrot is merged
+    void testNotIdentical() {
+        def msg = shouldFail(MultipleCompilationErrorsException) {
             shell.evaluate """
-                    def x = []
-                    def y = []
-
+                def x = []
+                def y = []
+                def doIt() {
                     assert y !== x
+                }
+                doIt()
             """
         }
+        assert msg.contains("!==") && msg.contains("not supported")
     }
 
+    // until Parrot is merged
+    void testIdenticalCompileStatic() {
+        def msg = shouldFail(MultipleCompilationErrorsException) {
+            shell.evaluate """
+                def x = []
+                def y = []
+                @groovy.transform.CompileStatic
+                def doIt() {
+                    assert y === x
+                }
+                doIt()
+            """
+        }
+        assert msg.contains("===") && msg.contains("not supported")
+    }
 }


[16/50] [abbrv] groovy git commit: GROOVY-8120: Bump commons cli version to 1.4

Posted by su...@apache.org.
GROOVY-8120: Bump commons cli version to 1.4


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

Branch: refs/heads/parrot
Commit: 64a7ddad55c2004655f7f5db32a6c6ad9cfbeeb7
Parents: 73db9a7
Author: paulk <pa...@asert.com.au>
Authored: Tue Mar 14 20:56:01 2017 +1000
Committer: paulk <pa...@asert.com.au>
Committed: Tue Mar 14 20:56:01 2017 +1000

----------------------------------------------------------------------
 build.gradle | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/64a7ddad/build.gradle
----------------------------------------------------------------------
diff --git a/build.gradle b/build.gradle
index 8bf2dd7..b2a5047 100644
--- a/build.gradle
+++ b/build.gradle
@@ -149,7 +149,7 @@ ext {
     antlrVersion = '2.7.7'
     bridgerVersion = '1.1.Final'
     coberturaVersion = '1.9.4.1'
-    commonsCliVersion = '1.3.1'
+    commonsCliVersion = '1.4'
     commonsHttpClientVersion = '3.1'
     eclipseOsgiVersion = '3.9.1-v20140110-1610'
     gparsVersion = '1.2.1'


[45/50] [abbrv] groovy git commit: remove "subprojects/groovy-macro/src/main/resources/META-INF/services/org.codehaus.groovy.runtime.ExtensionModule" (it is auto-generated by Gradle) and fix the assumption in test

Posted by su...@apache.org.
remove "subprojects/groovy-macro/src/main/resources/META-INF/services/org.codehaus.groovy.runtime.ExtensionModule" (it is auto-generated by Gradle) and fix the assumption in test


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

Branch: refs/heads/parrot
Commit: 68acdae20654c3beb5e3dfe1a439b4fb824f16b2
Parents: 42b9a42
Author: Sergei Egorov <se...@zeroturnaround.com>
Authored: Wed Mar 29 17:01:39 2017 +0200
Committer: Sergei Egorov <se...@zeroturnaround.com>
Committed: Wed Mar 29 17:01:39 2017 +0200

----------------------------------------------------------------------
 .../org.codehaus.groovy.runtime.ExtensionModule    | 17 -----------------
 .../org/codehaus/groovy/macro/MacroTest.groovy     |  5 ++++-
 2 files changed, 4 insertions(+), 18 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/68acdae2/subprojects/groovy-macro/src/main/resources/META-INF/services/org.codehaus.groovy.runtime.ExtensionModule
----------------------------------------------------------------------
diff --git a/subprojects/groovy-macro/src/main/resources/META-INF/services/org.codehaus.groovy.runtime.ExtensionModule b/subprojects/groovy-macro/src/main/resources/META-INF/services/org.codehaus.groovy.runtime.ExtensionModule
deleted file mode 100644
index 2d10063..0000000
--- a/subprojects/groovy-macro/src/main/resources/META-INF/services/org.codehaus.groovy.runtime.ExtensionModule
+++ /dev/null
@@ -1,17 +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.
-moduleName=macro-module
-moduleVersion=1.0
-extensionClasses=org.codehaus.groovy.macro.methods.MacroGroovyMethods

http://git-wip-us.apache.org/repos/asf/groovy/blob/68acdae2/subprojects/groovy-macro/src/test/groovy/org/codehaus/groovy/macro/MacroTest.groovy
----------------------------------------------------------------------
diff --git a/subprojects/groovy-macro/src/test/groovy/org/codehaus/groovy/macro/MacroTest.groovy b/subprojects/groovy-macro/src/test/groovy/org/codehaus/groovy/macro/MacroTest.groovy
index 4ccb46b..a091335 100644
--- a/subprojects/groovy-macro/src/test/groovy/org/codehaus/groovy/macro/MacroTest.groovy
+++ b/subprojects/groovy-macro/src/test/groovy/org/codehaus/groovy/macro/MacroTest.groovy
@@ -19,6 +19,7 @@
 package org.codehaus.groovy.macro
 
 import groovy.transform.CompileStatic;
+import org.codehaus.groovy.runtime.metaclass.MethodSelectionException;
 
 /**
  *
@@ -226,7 +227,9 @@ class MacroTest extends GroovyTestCase {
     }
 
     void testNotAMacroCall() {
-        shouldFail(MissingMethodException) {
+        // FIXME should fail with "MissingMethodException" because none of MacroGroovy extension methods
+        // are defined with "no-args" version
+        shouldFail(MethodSelectionException) {
             assertScript 'macro()'
         }
     }


[35/50] [abbrv] groovy git commit: introduce macro methods and re-implement macro as a macro method

Posted by su...@apache.org.
http://git-wip-us.apache.org/repos/asf/groovy/blob/b4e68bd5/subprojects/groovy-macro/src/test/groovy/org/codehaus/groovy/macro/MacroTransformationTest.groovy
----------------------------------------------------------------------
diff --git a/subprojects/groovy-macro/src/test/groovy/org/codehaus/groovy/macro/MacroTransformationTest.groovy b/subprojects/groovy-macro/src/test/groovy/org/codehaus/groovy/macro/MacroTransformationTest.groovy
new file mode 100644
index 0000000..a7975b0
--- /dev/null
+++ b/subprojects/groovy-macro/src/test/groovy/org/codehaus/groovy/macro/MacroTransformationTest.groovy
@@ -0,0 +1,70 @@
+/*
+ *  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.macro
+
+import groovy.transform.CompileStatic
+
+@CompileStatic
+class MacroTransformationTest extends GroovyTestCase {
+
+    void testSimple() {
+        assertScript """
+        def nullObject = null
+        
+        assert null == safe(nullObject.hashcode())
+"""
+    }
+
+    void testMacroInClosure() {
+        assertScript """
+        def cl = {
+            return safe(it.hashcode())
+        }
+
+        assert null == cl(null)
+"""
+    }
+
+    void testCascade() {
+        assertScript """
+        def nullObject = null
+        assert null == safe(safe(nullObject.hashcode()).toString())
+"""
+    }
+
+    void testMethodName() {
+        assertScript """
+        assert "toString" == methodName(123.toString())
+
+        assert "getInteger" == methodName(Integer.getInteger())
+
+        assert "call" == methodName({}())
+
+        assert "after" == methodName((new Date()).&after)
+"""
+    }
+
+    void testPropertyName() {
+        assertScript """
+        assert "bytes" == propertyName("".bytes)
+
+        assert "class" == propertyName(123.class)
+"""
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/b4e68bd5/subprojects/groovy-macro/src/test/groovy/org/codehaus/groovy/macro/matcher/ASTMatcherTest.groovy
----------------------------------------------------------------------
diff --git a/subprojects/groovy-macro/src/test/groovy/org/codehaus/groovy/macro/matcher/ASTMatcherTest.groovy b/subprojects/groovy-macro/src/test/groovy/org/codehaus/groovy/macro/matcher/ASTMatcherTest.groovy
index d57459d..2680e3e 100644
--- a/subprojects/groovy-macro/src/test/groovy/org/codehaus/groovy/macro/matcher/ASTMatcherTest.groovy
+++ b/subprojects/groovy-macro/src/test/groovy/org/codehaus/groovy/macro/matcher/ASTMatcherTest.groovy
@@ -18,37 +18,39 @@
  */
 package org.codehaus.groovy.macro.matcher
 
-import org.codehaus.groovy.ast.ClassNode
-import org.codehaus.groovy.ast.expr.ArrayExpression
-import org.codehaus.groovy.ast.expr.BinaryExpression
-import org.codehaus.groovy.ast.expr.BitwiseNegationExpression
-import org.codehaus.groovy.ast.expr.CastExpression
-import org.codehaus.groovy.ast.expr.ClassExpression
-import org.codehaus.groovy.ast.expr.GStringExpression
-import org.codehaus.groovy.ast.expr.MethodPointerExpression
-import org.codehaus.groovy.ast.expr.StaticMethodCallExpression
-import org.codehaus.groovy.ast.expr.UnaryMinusExpression
-import org.codehaus.groovy.ast.expr.UnaryPlusExpression
-import org.codehaus.groovy.ast.stmt.ForStatement
-import org.codehaus.groovy.ast.stmt.IfStatement
-import org.codehaus.groovy.ast.stmt.WhileStatement
-import org.codehaus.groovy.control.CompilePhase
-import org.codehaus.groovy.macro.transform.MacroClass
-import org.codehaus.groovy.syntax.Types
-
 class ASTMatcherTest extends GroovyTestCase {
     void testMatchesSimpleVar() {
+        assertScript '''
+        import org.codehaus.groovy.ast.*
+        import org.codehaus.groovy.ast.builder.AstAssert
+        import org.codehaus.groovy.macro.matcher.ASTMatcher
+        import org.codehaus.groovy.macro.transform.MacroClass
+
         def ast = macro { a }
         assert ASTMatcher.matches(ast, ast)
+        '''
     }
     void testMatchesSimpleVarNeg() {
+        assertScript '''
+        import org.codehaus.groovy.ast.*
+        import org.codehaus.groovy.ast.builder.AstAssert
+        import org.codehaus.groovy.macro.matcher.ASTMatcher
+        import org.codehaus.groovy.macro.transform.MacroClass
+
         def ast = macro { a }
         def ast2 = macro { b }
         assert !ASTMatcher.matches(ast, ast2)
         assert !ASTMatcher.matches(ast2, ast)
+        '''
     }
 
     void testBinaryExpression() {
+        assertScript '''
+        import org.codehaus.groovy.ast.*
+        import org.codehaus.groovy.ast.builder.AstAssert
+        import org.codehaus.groovy.macro.matcher.ASTMatcher
+        import org.codehaus.groovy.macro.transform.MacroClass
+
         def ast1 = macro { a+b }
         def ast2 = macro { a+b }
         def ast3 = macro { b+a }
@@ -58,9 +60,16 @@ class ASTMatcherTest extends GroovyTestCase {
         assert ASTMatcher.matches(ast2, ast1)
         assert !ASTMatcher.matches(ast1, ast3)
         assert !ASTMatcher.matches(ast1, ast4)
+        '''
     }
 
     void testMethodCallExpression() {
+        assertScript '''
+        import org.codehaus.groovy.ast.*
+        import org.codehaus.groovy.ast.builder.AstAssert
+        import org.codehaus.groovy.macro.matcher.ASTMatcher
+        import org.codehaus.groovy.macro.transform.MacroClass
+
         def ast1 = macro { foo() }
         def ast2 = macro { foo() }
         def ast3 = macro { this.foo() }
@@ -75,9 +84,16 @@ class ASTMatcherTest extends GroovyTestCase {
         assert !ASTMatcher.matches(ast1, ast4)
         assert !ASTMatcher.matches(ast1, ast5)
         assert ASTMatcher.matches(ast6, ast7)
+        '''
     }
 
     void testPropertyExpression() {
+        assertScript '''
+        import org.codehaus.groovy.ast.*
+        import org.codehaus.groovy.ast.builder.AstAssert
+        import org.codehaus.groovy.macro.matcher.ASTMatcher
+        import org.codehaus.groovy.macro.transform.MacroClass
+
         def ast1 = macro { this.p }
         def ast2 = macro { this.p }
         def ast3 = macro { that.p }
@@ -91,9 +107,16 @@ class ASTMatcherTest extends GroovyTestCase {
         assert !ASTMatcher.matches(ast1, ast4)
         assert !ASTMatcher.matches(ast1, ast5)
         assert !ASTMatcher.matches(ast1, ast6)
+        '''
     }
 
     void testAttributeExpression() {
+        assertScript '''
+        import org.codehaus.groovy.ast.*
+        import org.codehaus.groovy.ast.builder.AstAssert
+        import org.codehaus.groovy.macro.matcher.ASTMatcher
+        import org.codehaus.groovy.macro.transform.MacroClass
+
         def ast1 = macro { this.@p }
         def ast2 = macro { this.@p }
         def ast3 = macro { that.@p }
@@ -107,9 +130,18 @@ class ASTMatcherTest extends GroovyTestCase {
         assert !ASTMatcher.matches(ast1, ast4)
         assert !ASTMatcher.matches(ast1, ast5)
         assert !ASTMatcher.matches(ast1, ast6)
+        '''
     }
 
     void testClassExpression() {
+        assertScript '''
+        import org.codehaus.groovy.ast.*
+        import org.codehaus.groovy.ast.expr.*
+        import org.codehaus.groovy.control.CompilePhase
+        import org.codehaus.groovy.ast.builder.AstAssert
+        import org.codehaus.groovy.macro.matcher.ASTMatcher
+        import org.codehaus.groovy.macro.transform.MacroClass
+
         def ast1 = macro(CompilePhase.SEMANTIC_ANALYSIS) { String }
         def ast2 = macro(CompilePhase.SEMANTIC_ANALYSIS) { String }
         def ast3 = macro(CompilePhase.SEMANTIC_ANALYSIS) { Boolean }
@@ -120,9 +152,16 @@ class ASTMatcherTest extends GroovyTestCase {
         assert ASTMatcher.matches(ast1, ast2)
         assert ASTMatcher.matches(ast2, ast1)
         assert !ASTMatcher.matches(ast1, ast3)
+        '''
     }
 
     void testTernaryExpression() {
+        assertScript '''
+        import org.codehaus.groovy.ast.*
+        import org.codehaus.groovy.ast.builder.AstAssert
+        import org.codehaus.groovy.macro.matcher.ASTMatcher
+        import org.codehaus.groovy.macro.transform.MacroClass
+
         def ast1 = macro { a?b:c }
         def ast2 = macro { a?b:c }
         def ast3 = macro { b?b:c }
@@ -137,9 +176,16 @@ class ASTMatcherTest extends GroovyTestCase {
         assert !ASTMatcher.matches(ast1, ast4)
         assert !ASTMatcher.matches(ast1, ast5)
         assert ASTMatcher.matches(ast6, ast7)
+        '''
     }
 
     void testElvis() {
+        assertScript '''
+        import org.codehaus.groovy.ast.*
+        import org.codehaus.groovy.ast.builder.AstAssert
+        import org.codehaus.groovy.macro.matcher.ASTMatcher
+        import org.codehaus.groovy.macro.transform.MacroClass
+
         def ast1 = macro { a?:c }
         def ast2 = macro { a?:c }
         def ast3 = macro { b?:c }
@@ -153,9 +199,16 @@ class ASTMatcherTest extends GroovyTestCase {
         assert !ASTMatcher.matches(ast1, ast4)
         assert !ASTMatcher.matches(ast1, ast5)
         assert ASTMatcher.matches(ast5, ast6)
+        '''
     }
 
     void testPrefixExpression() {
+        assertScript '''
+        import org.codehaus.groovy.ast.*
+        import org.codehaus.groovy.ast.builder.AstAssert
+        import org.codehaus.groovy.macro.matcher.ASTMatcher
+        import org.codehaus.groovy.macro.transform.MacroClass
+
         def ast1 = macro { ++a }
         def ast2 = macro { ++a }
         def ast3 = macro { ++b }
@@ -165,9 +218,16 @@ class ASTMatcherTest extends GroovyTestCase {
         assert ASTMatcher.matches(ast2, ast1)
         assert !ASTMatcher.matches(ast1, ast3)
         assert !ASTMatcher.matches(ast1, ast4)
+        '''
     }
 
     void testPostfixExpression() {
+        assertScript '''
+        import org.codehaus.groovy.ast.*
+        import org.codehaus.groovy.ast.builder.AstAssert
+        import org.codehaus.groovy.macro.matcher.ASTMatcher
+        import org.codehaus.groovy.macro.transform.MacroClass
+
         def ast1 = macro { a++ }
         def ast2 = macro { a++ }
         def ast3 = macro { b++ }
@@ -177,9 +237,16 @@ class ASTMatcherTest extends GroovyTestCase {
         assert ASTMatcher.matches(ast2, ast1)
         assert !ASTMatcher.matches(ast1, ast3)
         assert !ASTMatcher.matches(ast1, ast4)
+        '''
     }
 
     void testConstructorCall() {
+        assertScript '''
+        import org.codehaus.groovy.ast.*
+        import org.codehaus.groovy.ast.builder.AstAssert
+        import org.codehaus.groovy.macro.matcher.ASTMatcher
+        import org.codehaus.groovy.macro.transform.MacroClass
+
         def ast1 = macro { new Foo() }
         def ast2 = macro { new Foo() }
         def ast3 = macro { new Bar() }
@@ -189,9 +256,16 @@ class ASTMatcherTest extends GroovyTestCase {
         assert ASTMatcher.matches(ast2, ast1)
         assert !ASTMatcher.matches(ast1, ast3)
         assert !ASTMatcher.matches(ast1, ast4)
+        '''
     }
 
     void testDeclaration() {
+        assertScript '''
+        import org.codehaus.groovy.ast.*
+        import org.codehaus.groovy.ast.builder.AstAssert
+        import org.codehaus.groovy.macro.matcher.ASTMatcher
+        import org.codehaus.groovy.macro.transform.MacroClass
+
         def ast1 = macro { def x = 1 }
         def ast2 = macro { def x = 1 }
         def ast3 = macro { int x = 1 }
@@ -203,9 +277,16 @@ class ASTMatcherTest extends GroovyTestCase {
         assert !ASTMatcher.matches(ast1, ast3)
         assert !ASTMatcher.matches(ast1, ast4)
         assert !ASTMatcher.matches(ast1, ast5)
+        '''
     }
 
     void testBooleanExpression() {
+        assertScript '''
+        import org.codehaus.groovy.ast.*
+        import org.codehaus.groovy.ast.builder.AstAssert
+        import org.codehaus.groovy.macro.matcher.ASTMatcher
+        import org.codehaus.groovy.macro.transform.MacroClass
+
         def ast1 = macro { a==1 }
         def ast2 = macro { a==1 }
         def ast3 = macro { 1==a }
@@ -217,9 +298,16 @@ class ASTMatcherTest extends GroovyTestCase {
         assert !ASTMatcher.matches(ast1, ast3)
         assert !ASTMatcher.matches(ast1, ast4)
         assert !ASTMatcher.matches(ast1, ast5)
+        '''
     }
 
     void testClosureExpression() {
+        assertScript '''
+        import org.codehaus.groovy.ast.*
+        import org.codehaus.groovy.ast.builder.AstAssert
+        import org.codehaus.groovy.macro.matcher.ASTMatcher
+        import org.codehaus.groovy.macro.transform.MacroClass
+
         def ast1 = macro { {-> a } }
         def ast2 = macro { {-> a } }
         def ast3 = macro { {-> b } }
@@ -235,9 +323,16 @@ class ASTMatcherTest extends GroovyTestCase {
         assert ASTMatcher.matches(ast4, ast5)
         assert !ASTMatcher.matches(ast5, ast6)
         assert !ASTMatcher.matches(ast5, ast7)
+        '''
     }
 
     void testNotExpression() {
+        assertScript '''
+        import org.codehaus.groovy.ast.*
+        import org.codehaus.groovy.ast.builder.AstAssert
+        import org.codehaus.groovy.macro.matcher.ASTMatcher
+        import org.codehaus.groovy.macro.transform.MacroClass
+
         def ast1 = macro { !a }
         def ast2 = macro { !a }
         def ast3 = macro { a }
@@ -249,9 +344,16 @@ class ASTMatcherTest extends GroovyTestCase {
         assert !ASTMatcher.matches(ast1, ast3)
         assert !ASTMatcher.matches(ast1, ast4)
         assert !ASTMatcher.matches(ast1, ast5)
+        '''
     }
 
     void testMapExpression() {
+        assertScript '''
+        import org.codehaus.groovy.ast.*
+        import org.codehaus.groovy.ast.builder.AstAssert
+        import org.codehaus.groovy.macro.matcher.ASTMatcher
+        import org.codehaus.groovy.macro.transform.MacroClass
+
         def ast1 = macro { [:] }
         def ast2 = macro { [:] }
         def ast3 = macro { [a:''] }
@@ -271,9 +373,16 @@ class ASTMatcherTest extends GroovyTestCase {
         assert !ASTMatcher.matches(ast6, ast7)
         assert !ASTMatcher.matches(ast3, ast8)
         assert !ASTMatcher.matches(ast6, ast8)
+        '''
     }
 
     void testRangeExpression() {
+        assertScript '''
+        import org.codehaus.groovy.ast.*
+        import org.codehaus.groovy.ast.builder.AstAssert
+        import org.codehaus.groovy.macro.matcher.ASTMatcher
+        import org.codehaus.groovy.macro.transform.MacroClass
+
         def ast1 = macro { (0..10) }
         def ast2 = macro { (0..10) }
         def ast3 = macro { (1..10) }
@@ -287,9 +396,16 @@ class ASTMatcherTest extends GroovyTestCase {
         assert !ASTMatcher.matches(ast1, ast4)
         assert !ASTMatcher.matches(ast1, ast5)
         assert !ASTMatcher.matches(ast1, ast6)
+        '''
     }
 
     void testListExpression() {
+        assertScript '''
+        import org.codehaus.groovy.ast.*
+        import org.codehaus.groovy.ast.builder.AstAssert
+        import org.codehaus.groovy.macro.matcher.ASTMatcher
+        import org.codehaus.groovy.macro.transform.MacroClass
+
         def ast1 = macro { [] }
         def ast2 = macro { [] }
         def ast3 = macro { [a] }
@@ -308,9 +424,16 @@ class ASTMatcherTest extends GroovyTestCase {
         assert !ASTMatcher.matches(ast5, ast4)
         assert !ASTMatcher.matches(ast5, ast6)
         assert !ASTMatcher.matches(ast1, ast6)
+        '''
     }
 
     void testSpreadExpression() {
+        assertScript '''
+        import org.codehaus.groovy.ast.*
+        import org.codehaus.groovy.ast.builder.AstAssert
+        import org.codehaus.groovy.macro.matcher.ASTMatcher
+        import org.codehaus.groovy.macro.transform.MacroClass
+
         def ast1 = macro { [*a] }
         def ast2 = macro { [*a] }
         def ast3 = macro { [*b] }
@@ -320,9 +443,17 @@ class ASTMatcherTest extends GroovyTestCase {
         assert ASTMatcher.matches(ast2, ast1)
         assert !ASTMatcher.matches(ast1, ast3)
         assert !ASTMatcher.matches(ast1, ast4)
+        '''
     }
 
     void testArrayExpression() {
+        assertScript '''
+        import org.codehaus.groovy.ast.*
+        import org.codehaus.groovy.ast.expr.*
+        import org.codehaus.groovy.ast.builder.AstAssert
+        import org.codehaus.groovy.macro.matcher.ASTMatcher
+        import org.codehaus.groovy.macro.transform.MacroClass
+
         def ast1 = macro { new Integer[0] }
         def ast2 = macro { new Integer[0] }
         def ast3 = macro { new Integer[1] }
@@ -335,9 +466,17 @@ class ASTMatcherTest extends GroovyTestCase {
         assert !ASTMatcher.matches(ast1, ast3)
         assert !ASTMatcher.matches(ast1, ast4)
         assert !ASTMatcher.matches(ast1, ast5)
+        '''
     }
 
     void testMethodPointerExpression() {
+        assertScript '''
+        import org.codehaus.groovy.ast.*
+        import org.codehaus.groovy.ast.expr.*
+        import org.codehaus.groovy.ast.builder.AstAssert
+        import org.codehaus.groovy.macro.matcher.ASTMatcher
+        import org.codehaus.groovy.macro.transform.MacroClass
+
         def ast1 = macro { this.&foo }
         def ast2 = macro { this.&foo }
         def ast3 = macro { that.&foo }
@@ -348,9 +487,17 @@ class ASTMatcherTest extends GroovyTestCase {
         assert ASTMatcher.matches(ast2, ast1)
         assert !ASTMatcher.matches(ast1, ast3)
         assert !ASTMatcher.matches(ast1, ast4)
+        '''
     }
 
     void testUnaryMinus() {
+        assertScript '''
+        import org.codehaus.groovy.ast.*
+        import org.codehaus.groovy.ast.expr.*
+        import org.codehaus.groovy.ast.builder.AstAssert
+        import org.codehaus.groovy.macro.matcher.ASTMatcher
+        import org.codehaus.groovy.macro.transform.MacroClass
+
         def ast1 = macro { -a }
         def ast2 = macro { -a }
         def ast3 = macro { -0 }
@@ -361,9 +508,17 @@ class ASTMatcherTest extends GroovyTestCase {
         assert ASTMatcher.matches(ast2, ast1)
         assert !ASTMatcher.matches(ast1, ast3)
         assert !ASTMatcher.matches(ast1, ast4)
+        '''
     }
 
     void testUnaryPlus() {
+        assertScript '''
+        import org.codehaus.groovy.ast.*
+        import org.codehaus.groovy.ast.expr.*
+        import org.codehaus.groovy.ast.builder.AstAssert
+        import org.codehaus.groovy.macro.matcher.ASTMatcher
+        import org.codehaus.groovy.macro.transform.MacroClass
+
         def ast1 = macro { +a }
         def ast2 = macro { +a }
         def ast3 = macro { +0 }
@@ -374,9 +529,17 @@ class ASTMatcherTest extends GroovyTestCase {
         assert ASTMatcher.matches(ast2, ast1)
         assert !ASTMatcher.matches(ast1, ast3)
         assert !ASTMatcher.matches(ast1, ast4)
+        '''
     }
 
     void testBitwiseNegate() {
+        assertScript '''
+        import org.codehaus.groovy.ast.*
+        import org.codehaus.groovy.ast.expr.*
+        import org.codehaus.groovy.ast.builder.AstAssert
+        import org.codehaus.groovy.macro.matcher.ASTMatcher
+        import org.codehaus.groovy.macro.transform.MacroClass
+
         def ast1 = macro { ~a }
         def ast2 = macro { ~a }
         def ast3 = macro { ~0 }
@@ -387,9 +550,17 @@ class ASTMatcherTest extends GroovyTestCase {
         assert ASTMatcher.matches(ast2, ast1)
         assert !ASTMatcher.matches(ast1, ast3)
         assert !ASTMatcher.matches(ast1, ast4)
+        '''
     }
 
     void testCastExpression() {
+        assertScript '''
+        import org.codehaus.groovy.ast.*
+        import org.codehaus.groovy.ast.expr.*
+        import org.codehaus.groovy.ast.builder.AstAssert
+        import org.codehaus.groovy.macro.matcher.ASTMatcher
+        import org.codehaus.groovy.macro.transform.MacroClass
+
         def ast1 = macro { (String) foo }
         def ast2 = macro { (String) foo }
         def ast3 = macro { (Integer) foo }
@@ -400,9 +571,17 @@ class ASTMatcherTest extends GroovyTestCase {
         assert ASTMatcher.matches(ast2, ast1)
         assert !ASTMatcher.matches(ast1, ast3)
         assert !ASTMatcher.matches(ast1, ast4)
+        '''
     }
 
     void testGStringExpression() {
+        assertScript '''
+        import org.codehaus.groovy.ast.*
+        import org.codehaus.groovy.ast.expr.*
+        import org.codehaus.groovy.ast.builder.AstAssert
+        import org.codehaus.groovy.macro.matcher.ASTMatcher
+        import org.codehaus.groovy.macro.transform.MacroClass
+
         def ast1 = macro { "123$a" }
         def ast2 = macro { "123$a" }
         def ast3 = macro { "$a" }
@@ -413,9 +592,16 @@ class ASTMatcherTest extends GroovyTestCase {
         assert ASTMatcher.matches(ast2, ast1)
         assert !ASTMatcher.matches(ast1, ast3)
         assert !ASTMatcher.matches(ast1, ast4)
+        '''
     }
 
     void testClassComparison() {
+        assertScript '''
+        import org.codehaus.groovy.ast.*
+        import org.codehaus.groovy.ast.builder.AstAssert
+        import org.codehaus.groovy.macro.matcher.ASTMatcher
+        import org.codehaus.groovy.macro.transform.MacroClass
+
         def ast1 = new MacroClass() {
             class A {}
         }
@@ -438,9 +624,16 @@ class ASTMatcherTest extends GroovyTestCase {
         assert !ASTMatcher.matches(ast1, ast3)
         assert !ASTMatcher.matches(ast1, ast4)
         assert !ASTMatcher.matches(ast1, ast5)
+        '''
     }
 
     void testPropertyComparison() {
+        assertScript '''
+        import org.codehaus.groovy.ast.*
+        import org.codehaus.groovy.ast.builder.AstAssert
+        import org.codehaus.groovy.macro.matcher.ASTMatcher
+        import org.codehaus.groovy.macro.transform.MacroClass
+
         def ast1 = new MacroClass() {
             class A { String str }
         }
@@ -480,8 +673,15 @@ class ASTMatcherTest extends GroovyTestCase {
         assert !ASTMatcher.matches(ast1, ast8)
         assert ASTMatcher.matches(ast8, ast8)
         assert !ASTMatcher.matches(ast8, ast9)
+        '''
     }
     void testFieldComparison() {
+        assertScript '''
+        import org.codehaus.groovy.ast.*
+        import org.codehaus.groovy.ast.builder.AstAssert
+        import org.codehaus.groovy.macro.matcher.ASTMatcher
+        import org.codehaus.groovy.macro.transform.MacroClass
+
         def ast1 = new MacroClass() {
             class A { public String str }
         }
@@ -525,9 +725,17 @@ class ASTMatcherTest extends GroovyTestCase {
         assert ASTMatcher.matches(ast8, ast8)
         assert !ASTMatcher.matches(ast8, ast9)
         assert !ASTMatcher.matches(ast1, ast10)
+        '''
     }
 
     void testIf() {
+        assertScript '''
+        import org.codehaus.groovy.ast.*
+        import org.codehaus.groovy.ast.stmt.*
+        import org.codehaus.groovy.ast.builder.AstAssert
+        import org.codehaus.groovy.macro.matcher.ASTMatcher
+        import org.codehaus.groovy.macro.transform.MacroClass
+
         def ast1 = macro { if (a) b }
         def ast2 = macro { if (a) b }
         def ast3 = macro { if (a) c }
@@ -546,9 +754,17 @@ class ASTMatcherTest extends GroovyTestCase {
         assert !ASTMatcher.matches(ast1, ast6)
         assert ASTMatcher.matches(ast6, ast7)
         assert !ASTMatcher.matches(ast7, ast8)
+        '''
     }
 
     void testForLoop() {
+        assertScript '''
+        import org.codehaus.groovy.ast.*
+        import org.codehaus.groovy.ast.stmt.*
+        import org.codehaus.groovy.ast.builder.AstAssert
+        import org.codehaus.groovy.macro.matcher.ASTMatcher
+        import org.codehaus.groovy.macro.transform.MacroClass
+
         def ast1 = macro { for (;;) {} }
         def ast2 = macro { for (;;) {} }
         def ast3 = macro { for (int i=0;i<10;i++) {} }
@@ -563,9 +779,17 @@ class ASTMatcherTest extends GroovyTestCase {
         assert !ASTMatcher.matches(ast3, ast4)
         assert !ASTMatcher.matches(ast3, ast5)
         assert !ASTMatcher.matches(ast3, ast6)
+        '''
     }
 
     void testWhileLoop() {
+        assertScript '''
+        import org.codehaus.groovy.ast.*
+        import org.codehaus.groovy.ast.stmt.*
+        import org.codehaus.groovy.ast.builder.AstAssert
+        import org.codehaus.groovy.macro.matcher.ASTMatcher
+        import org.codehaus.groovy.macro.transform.MacroClass
+
         def ast1 = macro { while (true) {} }
         def ast2 = macro { while (true) {} }
         def ast3 = macro { while (false) {} }
@@ -577,18 +801,32 @@ class ASTMatcherTest extends GroovyTestCase {
         assert ASTMatcher.matches(ast2, ast1)
         assert !ASTMatcher.matches(ast1, ast3)
         assert !ASTMatcher.matches(ast1, ast4)
+        '''
     }
 
     void testWildcardMatchVariable() {
+        assertScript '''
+        import org.codehaus.groovy.ast.*
+        import org.codehaus.groovy.ast.builder.AstAssert
+        import org.codehaus.groovy.macro.matcher.ASTMatcher
+        import org.codehaus.groovy.macro.transform.MacroClass
+
         def ast1 = macro { a }
         def ast2 = macro { _ }
         def ast3 = macro { b }
         assert ASTMatcher.matches(ast1, ast2)
         assert !ASTMatcher.matches(ast2, ast1)
         assert !ASTMatcher.matches(ast2, ast3)
+        '''
     }
 
     void testWildcardMatchVariableInBinaryExpression() {
+        assertScript '''
+        import org.codehaus.groovy.ast.*
+        import org.codehaus.groovy.ast.builder.AstAssert
+        import org.codehaus.groovy.macro.matcher.ASTMatcher
+        import org.codehaus.groovy.macro.transform.MacroClass
+
         def ast1 = macro { a+b }
         def ast2 = macro { _+_ }
         def ast3 = macro { _+c }
@@ -601,27 +839,48 @@ class ASTMatcherTest extends GroovyTestCase {
         assert !ASTMatcher.matches(ast1, ast4)
         assert ASTMatcher.matches(ast1, ast5)
         assert ASTMatcher.matches(ast1, ast6)
+        '''
     }
 
     void testWildcardForSubExpression() {
+        assertScript '''
+        import org.codehaus.groovy.ast.*
+        import org.codehaus.groovy.ast.builder.AstAssert
+        import org.codehaus.groovy.macro.matcher.ASTMatcher
+        import org.codehaus.groovy.macro.transform.MacroClass
+
         def ast1 = macro { a+foo(b) }
         def ast2 = macro { _+foo(b) }
         def ast3 = macro { a+_ }
         assert ASTMatcher.matches(ast1, ast2)
         assert !ASTMatcher.matches(ast2, ast1)
         assert ASTMatcher.matches(ast1, ast3)
+        '''
     }
 
     void testWildcardInMethodName() {
+        assertScript '''
+        import org.codehaus.groovy.ast.*
+        import org.codehaus.groovy.ast.builder.AstAssert
+        import org.codehaus.groovy.macro.matcher.ASTMatcher
+        import org.codehaus.groovy.macro.transform.MacroClass
+
         def ast1 = macro { a+foo(b) }
         def ast2 = macro { a+_(b) }
         def ast3 = macro { a+_(c) }
         assert ASTMatcher.matches(ast1, ast2)
         assert !ASTMatcher.matches(ast2, ast1)
         assert !ASTMatcher.matches(ast1, ast3)
+        '''
     }
 
     void testConstrainedMatcher() {
+        assertScript '''
+        import org.codehaus.groovy.ast.*
+        import org.codehaus.groovy.ast.builder.AstAssert
+        import org.codehaus.groovy.macro.matcher.ASTMatcher
+        import org.codehaus.groovy.macro.transform.MacroClass
+
         def ast = macro { a+foo(b) }
         def pattern = macro {
             a+b
@@ -630,9 +889,16 @@ class ASTMatcherTest extends GroovyTestCase {
             placeholder a,b
         }
         assert ASTMatcher.matches(ast, pattern)
+        '''
     }
 
     void testPlaceholdersMustMatch() {
+        assertScript '''
+        import org.codehaus.groovy.ast.*
+        import org.codehaus.groovy.ast.builder.AstAssert
+        import org.codehaus.groovy.macro.matcher.ASTMatcher
+        import org.codehaus.groovy.macro.transform.MacroClass
+
         def ast1 = macro { foo(a)+foo(a) }
         def ast2 = macro { foo(a)+foo(b) }
         def pattern = macro {
@@ -643,9 +909,16 @@ class ASTMatcherTest extends GroovyTestCase {
         }
         assert ASTMatcher.matches(ast1, pattern)
         assert !ASTMatcher.matches(ast2, pattern)
+        '''
     }
 
     void testPlaceholdersMustMatch2() {
+        assertScript '''
+        import org.codehaus.groovy.ast.*
+        import org.codehaus.groovy.ast.builder.AstAssert
+        import org.codehaus.groovy.macro.matcher.ASTMatcher
+        import org.codehaus.groovy.macro.transform.MacroClass
+
         use(ASTMatcher) {
             def ast1 = macro { foo(a) + foo(a) }
             def ast2 = macro { foo(a) + foo(foo(a)) }
@@ -657,9 +930,17 @@ class ASTMatcherTest extends GroovyTestCase {
             assert !ast1.matches(pattern)
             assert ast2.matches(pattern)
         }
+        '''
     }
 
     void testMacroCombination() {
+        assertScript '''
+        import org.codehaus.groovy.ast.*
+        import org.codehaus.groovy.ast.expr.*
+        import org.codehaus.groovy.ast.builder.AstAssert
+        import org.codehaus.groovy.macro.matcher.ASTMatcher
+        import org.codehaus.groovy.macro.transform.MacroClass
+
         use(ASTMatcher) {
             def lhs = macro { a }
             def rhs = macro { b }
@@ -670,9 +951,16 @@ class ASTMatcherTest extends GroovyTestCase {
             def pattern = macro { a + b }
             assert ast.matches(pattern)
         }
+        '''
     }
 
     void testRelaxedBinaryExpression() {
+        assertScript '''
+        import org.codehaus.groovy.ast.*
+        import org.codehaus.groovy.ast.builder.AstAssert
+        import org.codehaus.groovy.macro.matcher.ASTMatcher
+        import org.codehaus.groovy.macro.transform.MacroClass
+        
         use(ASTMatcher) {
             def ast1 = macro { a + b }
             def ast2 = macro { a - b }
@@ -688,9 +976,17 @@ class ASTMatcherTest extends GroovyTestCase {
             assert ast3.matches(pattern)
             assert !ast4.matches(pattern)
         }
+        '''
     }
 
     void testRelaxedBinaryExpressionWithConstrainedToken() {
+        assertScript '''
+        import org.codehaus.groovy.ast.*
+        import org.codehaus.groovy.ast.builder.AstAssert
+        import org.codehaus.groovy.macro.matcher.ASTMatcher
+        import org.codehaus.groovy.macro.transform.MacroClass
+        import org.codehaus.groovy.syntax.Types
+
         use(ASTMatcher) {
             def ast1 = macro { a + b }
             def ast2 = macro { a - b }
@@ -708,9 +1004,17 @@ class ASTMatcherTest extends GroovyTestCase {
             assert !ast3.matches(pattern)
             assert !ast4.matches(pattern)
         }
+        '''
     }
 
     void testInlineMacroCombinationWithConstraints() {
+        assertScript '''
+        import org.codehaus.groovy.ast.*
+        import org.codehaus.groovy.ast.expr.*
+        import org.codehaus.groovy.ast.builder.AstAssert
+        import org.codehaus.groovy.macro.matcher.ASTMatcher
+        import org.codehaus.groovy.macro.transform.MacroClass
+
         use(ASTMatcher) {
             def ast1 = macro { a + b }
             def ast2 = macro { b + b }
@@ -727,9 +1031,17 @@ class ASTMatcherTest extends GroovyTestCase {
             assert !ast3.matches(pattern)
             assert ast4.matches(pattern)
         }
+        '''
     }
 
     void testInlineMacroCombinationWithSimplifiedConstraints() {
+        assertScript '''
+        import org.codehaus.groovy.ast.*
+        import org.codehaus.groovy.ast.expr.*
+        import org.codehaus.groovy.ast.builder.AstAssert
+        import org.codehaus.groovy.macro.matcher.ASTMatcher
+        import org.codehaus.groovy.macro.transform.MacroClass
+
         use(ASTMatcher) {
             def ast1 = macro { a + b }
             def ast2 = macro { b + b }
@@ -747,9 +1059,16 @@ class ASTMatcherTest extends GroovyTestCase {
             assert !ast3.matches(pattern)
             assert ast4.matches(pattern)
         }
+        '''
     }
 
     void testRelationshipMatching() {
+        assertScript '''
+        import org.codehaus.groovy.ast.*
+        import org.codehaus.groovy.ast.builder.AstAssert
+        import org.codehaus.groovy.macro.matcher.ASTMatcher
+        import org.codehaus.groovy.macro.transform.MacroClass
+
         use (ASTMatcher) {
             def ast1 = macro { (a + b) + (a + b ) }
             def ast2 = macro { (a + b) - (a + b ) }
@@ -768,7 +1087,7 @@ class ASTMatcherTest extends GroovyTestCase {
             assert ast3.matches(pattern)
             assert !ast4.matches(pattern)
             assert !ast5.matches(pattern)
-
         }
+        '''
     }
 }

http://git-wip-us.apache.org/repos/asf/groovy/blob/b4e68bd5/subprojects/groovy-macro/src/test/resources/META-INF/services/org.codehaus.groovy.runtime.ExtensionModule
----------------------------------------------------------------------
diff --git a/subprojects/groovy-macro/src/test/resources/META-INF/services/org.codehaus.groovy.runtime.ExtensionModule b/subprojects/groovy-macro/src/test/resources/META-INF/services/org.codehaus.groovy.runtime.ExtensionModule
new file mode 100644
index 0000000..45c87ed
--- /dev/null
+++ b/subprojects/groovy-macro/src/test/resources/META-INF/services/org.codehaus.groovy.runtime.ExtensionModule
@@ -0,0 +1,17 @@
+# 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.
+moduleName=macro-module
+moduleVersion=1.0
+extensionClasses=org.codehaus.groovy.macro.ExampleMacroMethods


[38/50] [abbrv] groovy git commit: CR fixes, split code into smaller parts, add @Incubating and @since to different classes

Posted by su...@apache.org.
CR fixes, split code into smaller parts, add @Incubating and @since to different classes


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

Branch: refs/heads/parrot
Commit: 30949043538a813e78c8e334f07bfe8e79e953cb
Parents: ada0e2c
Author: Sergei Egorov <se...@zeroturnaround.com>
Authored: Sat Mar 25 16:44:48 2017 +0200
Committer: paulk <pa...@asert.com.au>
Committed: Tue Mar 28 16:02:26 2017 +1000

----------------------------------------------------------------------
 .../codehaus/groovy/macro/runtime/Macro.java    |   1 +
 .../groovy/macro/runtime/MacroBuilder.java      |   6 +
 .../groovy/macro/runtime/MacroContext.java      |  15 ++
 .../groovy/macro/runtime/MacroStub.java         |   1 +
 .../transform/MacroCallTransformingVisitor.java | 126 +++++++++++-----
 .../groovy/macro/transform/MacroClass.java      |   8 ++
 .../transform/MacroClassTransformation.java     | 142 +++++++++++--------
 .../macro/transform/MacroMethodsCache.java      |   1 +
 .../macro/transform/MacroTransformation.java    |   1 +
 9 files changed, 205 insertions(+), 96 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/30949043/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/runtime/Macro.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/runtime/Macro.java b/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/runtime/Macro.java
index b6a8938..a0fa4fc 100644
--- a/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/runtime/Macro.java
+++ b/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/runtime/Macro.java
@@ -27,6 +27,7 @@ import java.lang.annotation.Target;
 
 /**
  * @author Sergei Egorov <bs...@gmail.com>
+ * @since 2.5.0
  */
 
 @Retention(RetentionPolicy.RUNTIME)

http://git-wip-us.apache.org/repos/asf/groovy/blob/30949043/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/runtime/MacroBuilder.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/runtime/MacroBuilder.java b/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/runtime/MacroBuilder.java
index ef857e9..73cb0e2 100644
--- a/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/runtime/MacroBuilder.java
+++ b/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/runtime/MacroBuilder.java
@@ -19,6 +19,7 @@
 package org.codehaus.groovy.macro.runtime;
 
 import groovy.lang.Closure;
+import org.apache.groovy.lang.annotation.Incubating;
 import org.codehaus.groovy.ast.ASTNode;
 import org.codehaus.groovy.ast.ClassCodeExpressionTransformer;
 import org.codehaus.groovy.ast.ClassNode;
@@ -38,8 +39,13 @@ import java.util.concurrent.atomic.AtomicInteger;
 import static org.codehaus.groovy.macro.methods.MacroGroovyMethods.DOLLAR_VALUE;
 
 /**
+ * Runtime support for <pre>{@code macro {} }</pre> method.
+ *
  * @author Sergei Egorov <bs...@gmail.com>
+ * @since 2.5.0
  */
+
+@Incubating
 public enum MacroBuilder {
     INSTANCE;
 

http://git-wip-us.apache.org/repos/asf/groovy/blob/30949043/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/runtime/MacroContext.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/runtime/MacroContext.java b/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/runtime/MacroContext.java
index e181a2a..07df293 100644
--- a/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/runtime/MacroContext.java
+++ b/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/runtime/MacroContext.java
@@ -24,7 +24,10 @@ import org.codehaus.groovy.control.CompilationUnit;
 import org.codehaus.groovy.control.SourceUnit;
 
 /**
+ * Macro method context. Every macro method must be an extension method of it.
+ *
  * @author Sergei Egorov <bs...@gmail.com>
+ * @since 2.5.0
  */
 
 @Incubating
@@ -42,14 +45,26 @@ public class MacroContext {
         this.call = call;
     }
 
+    /**
+     *
+     * @return original method call expression
+     */
     public MethodCallExpression getCall() {
         return call;
     }
 
+    /**
+     *
+     * @return current source unit
+     */
     public SourceUnit getSourceUnit() {
         return sourceUnit;
     }
 
+    /**
+     *
+     * @return current compilation unit
+     */
     public CompilationUnit getCompilationUnit() {
         return compilationUnit;
     }

http://git-wip-us.apache.org/repos/asf/groovy/blob/30949043/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/runtime/MacroStub.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/runtime/MacroStub.java b/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/runtime/MacroStub.java
index b0590b5..cf4b2f7 100644
--- a/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/runtime/MacroStub.java
+++ b/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/runtime/MacroStub.java
@@ -22,6 +22,7 @@ package org.codehaus.groovy.macro.runtime;
  * Stub for macro calls.
  *
  * @author Sergei Egorov <bs...@gmail.com>
+ * @since 2.5.0
  */
 public enum MacroStub {
     INSTANCE;

http://git-wip-us.apache.org/repos/asf/groovy/blob/30949043/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroCallTransformingVisitor.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroCallTransformingVisitor.java b/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroCallTransformingVisitor.java
index 6af1afe..1afbeb7 100644
--- a/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroCallTransformingVisitor.java
+++ b/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroCallTransformingVisitor.java
@@ -1,3 +1,21 @@
+/*
+ *  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.macro.transform;
 
 import org.codehaus.groovy.ast.*;
@@ -11,9 +29,19 @@ import org.codehaus.groovy.runtime.InvokerHelper;
 import org.codehaus.groovy.transform.stc.ExtensionMethodNode;
 import org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport;
 
-import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 
+/**
+ * Visitor to find and transform macro method calls. For the performance reasons it's not a transformer,
+ * but transforming visitor - it mutates {@link MethodCallExpression} if it's a macro method call by replacing
+ * original call (i.e. {@code myMacroMethod("foo", "bar")} with something like:
+ * {@code MacroStub.INSTANCE.macroMethod(123)}
+ * (where {@code myMacroMethod} returns constant expression {@code 123})
+ *
+ * @author Sergei Egorov <bs...@gmail.com>
+ * @since 2.5.0
+ */
 class MacroCallTransformingVisitor extends ClassCodeVisitorSupport {
 
     private static final ClassNode MACRO_CONTEXT_CLASS_NODE = ClassHelper.make(MacroContext.class);
@@ -43,58 +71,82 @@ class MacroCallTransformingVisitor extends ClassCodeVisitorSupport {
     public void visitMethodCallExpression(MethodCallExpression call) {
         super.visitMethodCallExpression(call);
 
-        List<MethodNode> methods = MacroMethodsCache.get(classLoader).get(call.getMethodAsString());
-
-        if (methods == null) {
-            // Not a macro call
-            return;
-        }
-
         List<Expression> callArguments = InvocationWriter.makeArgumentList(call.getArguments()).getExpressions();
 
-        ClassNode[] argumentsList = new ClassNode[callArguments.size()];
+        List<MethodNode> macroMethods = findMacroMethods(call.getMethodAsString(), callArguments);
 
-        for (int i = 0; i < callArguments.size(); i++) {
-            argumentsList[i] = ClassHelper.make(callArguments.get(i).getClass());
+        if (macroMethods.isEmpty()) {
+            // Early return to avoid macro context and arguments creation
+            return;
         }
 
-        methods = StaticTypeCheckingSupport.chooseBestMethod(MACRO_CONTEXT_CLASS_NODE, methods, argumentsList);
+        MacroContext macroContext = new MacroContext(unit, sourceUnit, call);
 
-        for (MethodNode macroMethodNode : methods) {
+        Object[] macroArguments = new Object[callArguments.size() + 1];
+        macroArguments[0] = macroContext;
+        System.arraycopy(callArguments.toArray(), 0, macroArguments, 1, callArguments.size());
+
+        for (MethodNode macroMethodNode : macroMethods) {
             if (!(macroMethodNode instanceof ExtensionMethodNode)) {
-                // TODO is it even possible?
-                continue;
+                throw new IllegalStateException(macroMethodNode + " is not an instance of ExtensionMethodNode");
             }
 
-            MethodNode macroExtensionMethodNode = ((ExtensionMethodNode) macroMethodNode).getExtensionMethodNode();
-
-            final Class clazz;
-            try {
-                clazz = classLoader.loadClass(macroExtensionMethodNode.getDeclaringClass().getName());
-            } catch (ClassNotFoundException e) {
-                //TODO different reaction?
-                continue;
+            if (tryMacroMethod(call, (ExtensionMethodNode) macroMethodNode, macroArguments)) {
+                break;
             }
+        }
+    }
 
-            MacroContext macroContext = new MacroContext(unit, sourceUnit, call);
+    /**
+     * Finds all extension methods of {@link MacroContext} for given methodName
+     * with @{@link org.codehaus.groovy.macro.runtime.Macro} annotation.
+     */
+    private List<MethodNode> findMacroMethods(String methodName, List<Expression> callArguments) {
+        List<MethodNode> methods = MacroMethodsCache.get(classLoader).get(methodName);
 
-            List<Object> macroArguments = new ArrayList<>();
-            macroArguments.add(macroContext);
-            macroArguments.addAll(callArguments);
+        if (methods == null) {
+            // Not a macro call
+            return Collections.emptyList();
+        }
 
-            Expression result = (Expression) InvokerHelper.invokeStaticMethod(clazz, macroMethodNode.getName(), macroArguments.toArray());
+        ClassNode[] argumentsList = new ClassNode[callArguments.size()];
 
-            call.setObjectExpression(MACRO_STUB_INSTANCE);
-            call.setMethod(new ConstantExpression(MACRO_STUB_METHOD_NAME));
+        for (int i = 0; i < callArguments.size(); i++) {
+            argumentsList[i] = ClassHelper.make(callArguments.get(i).getClass());
+        }
 
-            // TODO check that we reset everything here
-            call.setSpreadSafe(false);
-            call.setSafe(false);
-            call.setImplicitThis(false);
-            call.setArguments(result);
-            call.setGenericsTypes(new GenericsType[0]);
+        return StaticTypeCheckingSupport.chooseBestMethod(MACRO_CONTEXT_CLASS_NODE, methods, argumentsList);
+    }
 
-            break;
+    /**
+     * Attempts to call given macroMethod
+     * @param call MethodCallExpression before the transformation
+     * @param macroMethod a macro method candidate
+     * @param macroArguments arguments to pass to
+     * @return true if call succeeded and current call was transformed
+     */
+    private boolean tryMacroMethod(MethodCallExpression call, ExtensionMethodNode macroMethod, Object[] macroArguments) {
+        Expression result = (Expression) InvokerHelper.invokeStaticMethod(
+            macroMethod.getExtensionMethodNode().getDeclaringClass().getTypeClass(),
+            macroMethod.getName(),
+            macroArguments
+        );
+
+        if (result == null) {
+            // Allow macro methods to return null as an indicator that they didn't match a method call
+            return false;
         }
+
+        call.setObjectExpression(MACRO_STUB_INSTANCE);
+        call.setMethod(new ConstantExpression(MACRO_STUB_METHOD_NAME));
+
+        // TODO check that we reset everything here
+        call.setSpreadSafe(false);
+        call.setSafe(false);
+        call.setImplicitThis(false);
+        call.setArguments(result);
+        call.setGenericsTypes(new GenericsType[0]);
+
+        return true;
     }
 }

http://git-wip-us.apache.org/repos/asf/groovy/blob/30949043/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroClass.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroClass.java b/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroClass.java
index 0b01efa..d9d3f7c 100644
--- a/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroClass.java
+++ b/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroClass.java
@@ -18,5 +18,13 @@
  */
 package org.codehaus.groovy.macro.transform;
 
+import org.apache.groovy.lang.annotation.Incubating;
+
+/**
+ *
+ * since 2.5.0
+ */
+
+@Incubating
 public abstract class MacroClass {
 }

http://git-wip-us.apache.org/repos/asf/groovy/blob/30949043/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroClassTransformation.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroClassTransformation.java b/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroClassTransformation.java
index 292d59d..4ecd42e 100644
--- a/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroClassTransformation.java
+++ b/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroClassTransformation.java
@@ -34,6 +34,12 @@ import java.util.List;
 
 import static org.codehaus.groovy.ast.tools.GeneralUtils.*;
 
+/**
+ * Transforms {@link MacroClass} calls into it's ClassNode
+ *
+ * @since 2.5.0
+ */
+
 @GroovyASTTransformation(phase = CompilePhase.CONVERSION)
 public class MacroClassTransformation extends MethodCallTransformation {
 
@@ -42,73 +48,91 @@ public class MacroClassTransformation extends MethodCallTransformation {
 
     @Override
     protected GroovyCodeVisitor getTransformer(final ASTNode[] nodes, final SourceUnit sourceUnit) {
-        ClassCodeExpressionTransformer transformer = new ClassCodeExpressionTransformer() {
-            @Override
-            protected SourceUnit getSourceUnit() {
-                return sourceUnit;
-            }
+        ClassCodeExpressionTransformer transformer = new MacroClassTransformer(sourceUnit);
 
-            @Override
-            public Expression transform(final Expression exp) {
-                if (exp instanceof ConstructorCallExpression) {
-                    MethodCallExpression call = exp.getNodeMetaData(MacroTransformation.class);
-                    if (call != null) {
-                        return call;
-                    }
+        return new MacroClassTransformingCodeVisitor(transformer, sourceUnit);
+    }
+
+    private static class MacroClassTransformer extends ClassCodeExpressionTransformer {
+
+        private final SourceUnit sourceUnit;
+
+        public MacroClassTransformer(SourceUnit sourceUnit) {
+            this.sourceUnit = sourceUnit;
+        }
+
+        @Override
+        protected SourceUnit getSourceUnit() {
+            return sourceUnit;
+        }
+
+        @Override
+        public Expression transform(final Expression exp) {
+            if (exp instanceof ConstructorCallExpression) {
+                MethodCallExpression call = exp.getNodeMetaData(MacroTransformation.class);
+                if (call != null) {
+                    return call;
                 }
-                return super.transform(exp);
             }
-        };
-
-        return new TransformingCodeVisitor(transformer) {
-
-            @Override
-            public void visitConstructorCallExpression(final ConstructorCallExpression call) {
-                ClassNode type = call.getType();
-                if (type instanceof InnerClassNode) {
-                    if (((InnerClassNode) type).isAnonymous() &&
-                            MACROCLASS_TYPE.getNameWithoutPackage().equals(type.getSuperClass().getNameWithoutPackage())) {
-                        try {
-                            String source = convertInnerClassToSource(type);
-
-                            MethodCallExpression macroCall = callX(
-                                    propX(classX(ClassHelper.makeWithoutCaching(MacroBuilder.class, false)), "INSTANCE"),
-                                    MACRO_METHOD,
-                                    args(
-                                            constX(source),
-                                            MacroGroovyMethods.buildSubstitutionMap(sourceUnit, type),
-                                            classX(ClassHelper.make(ClassNode.class))
-                                    )
-                            );
-
-                            macroCall.setSpreadSafe(false);
-                            macroCall.setSafe(false);
-                            macroCall.setImplicitThis(false);
-                            call.putNodeMetaData(MacroTransformation.class, macroCall);
-                            List<ClassNode> classes = sourceUnit.getAST().getClasses();
-                            for (Iterator<ClassNode> iterator = classes.iterator(); iterator.hasNext(); ) {
-                                final ClassNode aClass = iterator.next();
-                                if (aClass == type || type == aClass.getOuterClass()) {
-                                    iterator.remove();
-                                }
+            return super.transform(exp);
+        }
+    }
+
+    private static class MacroClassTransformingCodeVisitor extends TransformingCodeVisitor {
+
+        private final SourceUnit sourceUnit;
+
+        public MacroClassTransformingCodeVisitor(ClassCodeExpressionTransformer transformer, SourceUnit sourceUnit) {
+            super(transformer);
+            this.sourceUnit = sourceUnit;
+        }
+
+        @Override
+        public void visitConstructorCallExpression(final ConstructorCallExpression call) {
+            ClassNode type = call.getType();
+            if (type instanceof InnerClassNode) {
+                if (((InnerClassNode) type).isAnonymous() &&
+                        MACROCLASS_TYPE.getNameWithoutPackage().equals(type.getSuperClass().getNameWithoutPackage())) {
+                    try {
+                        String source = convertInnerClassToSource(type);
+
+                        MethodCallExpression macroCall = callX(
+                                propX(classX(ClassHelper.makeWithoutCaching(MacroBuilder.class, false)), "INSTANCE"),
+                                MACRO_METHOD,
+                                args(
+                                        constX(source),
+                                        MacroGroovyMethods.buildSubstitutionMap(sourceUnit, type),
+                                        classX(ClassHelper.make(ClassNode.class))
+                                )
+                        );
+
+                        macroCall.setSpreadSafe(false);
+                        macroCall.setSafe(false);
+                        macroCall.setImplicitThis(false);
+                        call.putNodeMetaData(MacroTransformation.class, macroCall);
+                        List<ClassNode> classes = sourceUnit.getAST().getClasses();
+                        for (Iterator<ClassNode> iterator = classes.iterator(); iterator.hasNext(); ) {
+                            final ClassNode aClass = iterator.next();
+                            if (aClass == type || type == aClass.getOuterClass()) {
+                                iterator.remove();
                             }
-                        } catch (Exception e) {
-                            // FIXME
-                            e.printStackTrace();
                         }
-                        return;
+                    } catch (Exception e) {
+                        // FIXME
+                        e.printStackTrace();
                     }
+                    return;
                 }
-                super.visitConstructorCallExpression(call);
-
             }
+            super.visitConstructorCallExpression(call);
 
-            private String convertInnerClassToSource(final ClassNode type) throws Exception {
-                String source = GeneralUtils.convertASTToSource(sourceUnit.getSource(), type);
-                // we need to remove the leading "{" and trailing "}"
-                source = source.substring(source.indexOf('{') + 1, source.lastIndexOf('}') - 1);
-                return source;
-            }
-        };
+        }
+
+        private String convertInnerClassToSource(final ClassNode type) throws Exception {
+            String source = GeneralUtils.convertASTToSource(sourceUnit.getSource(), type);
+            // we need to remove the leading "{" and trailing "}"
+            source = source.substring(source.indexOf('{') + 1, source.lastIndexOf('}') - 1);
+            return source;
+        }
     }
 }

http://git-wip-us.apache.org/repos/asf/groovy/blob/30949043/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroMethodsCache.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroMethodsCache.java b/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroMethodsCache.java
index d3e8ed4..90ca15b 100644
--- a/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroMethodsCache.java
+++ b/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroMethodsCache.java
@@ -34,6 +34,7 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
 /**
  * TODO share some code with {@link org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.ExtensionMethodCache}
  * @author Sergei Egorov <bs...@gmail.com>
+ * @since 2.5.0
  */
 class MacroMethodsCache {
 

http://git-wip-us.apache.org/repos/asf/groovy/blob/30949043/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroTransformation.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroTransformation.java b/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroTransformation.java
index 983ba18..3ea441a 100644
--- a/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroTransformation.java
+++ b/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroTransformation.java
@@ -27,6 +27,7 @@ import org.codehaus.groovy.transform.GroovyASTTransformation;
 
 /**
  * @author Sergei Egorov <bs...@gmail.com>
+ * @since 2.5.0
  */
 
 @GroovyASTTransformation(phase = CompilePhase.CONVERSION)


[43/50] [abbrv] groovy git commit: fix a leftover after "macro methods" re-implementation of MacroGroovy.

Posted by su...@apache.org.
fix a leftover after "macro methods" re-implementation of MacroGroovy.

in subprojects/groovy-macro we had "org.codehaus.groovy.macro.runtime.MacroGroovyMethods" but it should be "org.codehaus.groovy.macro.methods.MacroGroovyMethods".


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

Branch: refs/heads/parrot
Commit: 1877bed142fae002cb1e8abfbac7cb68a0eed1df
Parents: a520222
Author: Sergei Egorov <se...@zeroturnaround.com>
Authored: Wed Mar 29 12:18:11 2017 +0200
Committer: Sergei Egorov <se...@zeroturnaround.com>
Committed: Wed Mar 29 12:18:11 2017 +0200

----------------------------------------------------------------------
 subprojects/groovy-macro/build.gradle | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/1877bed1/subprojects/groovy-macro/build.gradle
----------------------------------------------------------------------
diff --git a/subprojects/groovy-macro/build.gradle b/subprojects/groovy-macro/build.gradle
index d9949ca..5d3cd11 100644
--- a/subprojects/groovy-macro/build.gradle
+++ b/subprojects/groovy-macro/build.gradle
@@ -23,7 +23,7 @@ dependencies {
 }
 
 task moduleDescriptor(type: org.codehaus.groovy.gradle.WriteExtensionDescriptorTask) {
-    extensionClasses = 'org.codehaus.groovy.macro.runtime.MacroGroovyMethods,org.codehaus.groovy.macro.matcher.ASTMatcher'
+    extensionClasses = 'org.codehaus.groovy.macro.methods.MacroGroovyMethods,org.codehaus.groovy.macro.matcher.ASTMatcher'
 }
 
 compileJava.dependsOn moduleDescriptor


[24/50] [abbrv] groovy git commit: GROOVY-8043: NPE compiling Memoized method with AIC (closes #511)

Posted by su...@apache.org.
GROOVY-8043: NPE compiling Memoized method with AIC (closes #511)


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

Branch: refs/heads/parrot
Commit: 2211af50cd83dc7444c3db0b3df135cf9657f1bf
Parents: 97d8c9e
Author: paulk <pa...@asert.com.au>
Authored: Fri Mar 10 17:27:55 2017 +1000
Committer: paulk <pa...@asert.com.au>
Committed: Mon Mar 20 16:48:46 2017 +1000

----------------------------------------------------------------------
 .../groovy/transform/MemoizedASTTransformation.java     |  7 ++++++-
 .../transform/MemoizedASTTransformationTest.groovy      | 12 ++++++++++++
 2 files changed, 18 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/2211af50/src/main/org/codehaus/groovy/transform/MemoizedASTTransformation.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/transform/MemoizedASTTransformation.java b/src/main/org/codehaus/groovy/transform/MemoizedASTTransformation.java
index 8067cba..2769a33 100644
--- a/src/main/org/codehaus/groovy/transform/MemoizedASTTransformation.java
+++ b/src/main/org/codehaus/groovy/transform/MemoizedASTTransformation.java
@@ -25,6 +25,7 @@ import org.codehaus.groovy.ast.AnnotationNode;
 import org.codehaus.groovy.ast.ClassHelper;
 import org.codehaus.groovy.ast.ClassNode;
 import org.codehaus.groovy.ast.FieldNode;
+import org.codehaus.groovy.ast.InnerClassNode;
 import org.codehaus.groovy.ast.MethodNode;
 import org.codehaus.groovy.ast.Parameter;
 import org.codehaus.groovy.ast.expr.ClosureExpression;
@@ -109,7 +110,11 @@ public class MemoizedASTTransformation extends AbstractASTTransformation {
             newCode.addStatement(returnS(closureCallExpression));
             methodNode.setCode(newCode);
             VariableScopeVisitor visitor = new VariableScopeVisitor(source);
-            visitor.visitClass(ownerClassNode);
+            if (ownerClassNode instanceof InnerClassNode) {
+                visitor.visitClass(((InnerClassNode) ownerClassNode).getOuterMostClass());
+            } else {
+                visitor.visitClass(ownerClassNode);
+            }
         }
     }
 

http://git-wip-us.apache.org/repos/asf/groovy/blob/2211af50/src/test/org/codehaus/groovy/transform/MemoizedASTTransformationTest.groovy
----------------------------------------------------------------------
diff --git a/src/test/org/codehaus/groovy/transform/MemoizedASTTransformationTest.groovy b/src/test/org/codehaus/groovy/transform/MemoizedASTTransformationTest.groovy
index e75138d..77e3f61 100644
--- a/src/test/org/codehaus/groovy/transform/MemoizedASTTransformationTest.groovy
+++ b/src/test/org/codehaus/groovy/transform/MemoizedASTTransformationTest.groovy
@@ -193,6 +193,18 @@ class MemoizedASTTransformationTest extends GroovyTestCase {
         assertEquals(MemoizedTestClass.privateStaticMethodWithParams(20, 5), 15)
         assertEquals(MemoizedTestClass.privateStaticMethodWithParamsCounter, 3)
     }
+
+    void testMemoizedAIC_Groovy8043() {
+        assertScript '''
+            class A {}
+            assert new A() {
+                @groovy.transform.Memoized()
+                String a() {
+                    return "a"
+                }
+            }.a() == 'a'
+        '''
+    }
 }
 
 class MemoizedTestClass2 {


[39/50] [abbrv] groovy git commit: add license header and remove some dead code (closes #472)

Posted by su...@apache.org.
add license header and remove some dead code (closes #472)


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

Branch: refs/heads/parrot
Commit: e0655ebefd5bf067b2ae7e6f1072e3a4b92e47cf
Parents: 3094904
Author: Sergei Egorov <se...@zeroturnaround.com>
Authored: Mon Mar 27 13:20:53 2017 +0300
Committer: paulk <pa...@asert.com.au>
Committed: Tue Mar 28 16:04:02 2017 +1000

----------------------------------------------------------------------
 .../groovy/macro/methods/MacroGroovyMethods.java  | 11 ++---------
 .../macro/transform/MacroClassTransformation.java |  2 +-
 .../groovy/macro/ExampleMacroMethods.java         | 18 ++++++++++++++++++
 .../org/codehaus/groovy/macro/MacroTest.groovy    |  6 ++++++
 4 files changed, 27 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/e0655ebe/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/methods/MacroGroovyMethods.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/methods/MacroGroovyMethods.java b/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/methods/MacroGroovyMethods.java
index d9f00e6..ae2a568 100644
--- a/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/methods/MacroGroovyMethods.java
+++ b/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/methods/MacroGroovyMethods.java
@@ -106,13 +106,6 @@ public class MacroGroovyMethods {
 
         Boolean asIs = (Boolean) asIsConstantExpression.getValue();
 
-        TupleExpression macroArguments = getMacroArguments(macroContext.getSourceUnit(), macroContext.getCall());
-
-        if (macroArguments == null) {
-            // FIXME
-            return macroContext.getCall();
-        }
-
         return callX(
                 propX(classX(ClassHelper.makeWithoutCaching(MacroBuilder.class, false)), "INSTANCE"),
                 "macro",
@@ -120,13 +113,13 @@ public class MacroGroovyMethods {
                         phaseExpression != null ? phaseExpression : constX(null),
                         asIsConstantExpression,
                         constX(source),
-                        buildSubstitutionMap(macroContext.getSourceUnit(), closureExpression),
+                        buildSubstitutions(macroContext.getSourceUnit(), closureExpression),
                         classX(ClassHelper.makeWithoutCaching(MacroBuilder.getMacroValue(closureBlock, asIs).getClass(), false))
                 )
         );
     }
 
-    public static ListExpression buildSubstitutionMap(final SourceUnit source, final ASTNode expr) {
+    public static ListExpression buildSubstitutions(final SourceUnit source, final ASTNode expr) {
         final ListExpression listExpression = new ListExpression();
 
         ClassCodeVisitorSupport visitor = new ClassCodeVisitorSupport() {

http://git-wip-us.apache.org/repos/asf/groovy/blob/e0655ebe/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroClassTransformation.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroClassTransformation.java b/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroClassTransformation.java
index 4ecd42e..6777933 100644
--- a/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroClassTransformation.java
+++ b/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroClassTransformation.java
@@ -101,7 +101,7 @@ public class MacroClassTransformation extends MethodCallTransformation {
                                 MACRO_METHOD,
                                 args(
                                         constX(source),
-                                        MacroGroovyMethods.buildSubstitutionMap(sourceUnit, type),
+                                        MacroGroovyMethods.buildSubstitutions(sourceUnit, type),
                                         classX(ClassHelper.make(ClassNode.class))
                                 )
                         );

http://git-wip-us.apache.org/repos/asf/groovy/blob/e0655ebe/subprojects/groovy-macro/src/test/groovy/org/codehaus/groovy/macro/ExampleMacroMethods.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-macro/src/test/groovy/org/codehaus/groovy/macro/ExampleMacroMethods.java b/subprojects/groovy-macro/src/test/groovy/org/codehaus/groovy/macro/ExampleMacroMethods.java
index 3b32ab8..3fc8574 100644
--- a/subprojects/groovy-macro/src/test/groovy/org/codehaus/groovy/macro/ExampleMacroMethods.java
+++ b/subprojects/groovy-macro/src/test/groovy/org/codehaus/groovy/macro/ExampleMacroMethods.java
@@ -1,3 +1,21 @@
+/*
+ *  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.macro;
 
 import org.codehaus.groovy.ast.expr.*;

http://git-wip-us.apache.org/repos/asf/groovy/blob/e0655ebe/subprojects/groovy-macro/src/test/groovy/org/codehaus/groovy/macro/MacroTest.groovy
----------------------------------------------------------------------
diff --git a/subprojects/groovy-macro/src/test/groovy/org/codehaus/groovy/macro/MacroTest.groovy b/subprojects/groovy-macro/src/test/groovy/org/codehaus/groovy/macro/MacroTest.groovy
index 69139b2..4ccb46b 100644
--- a/subprojects/groovy-macro/src/test/groovy/org/codehaus/groovy/macro/MacroTest.groovy
+++ b/subprojects/groovy-macro/src/test/groovy/org/codehaus/groovy/macro/MacroTest.groovy
@@ -224,4 +224,10 @@ class MacroTest extends GroovyTestCase {
         assert ast1.getField("str") != null
 '''
     }
+
+    void testNotAMacroCall() {
+        shouldFail(MissingMethodException) {
+            assertScript 'macro()'
+        }
+    }
 }


[06/50] [abbrv] groovy git commit: GROOVY-8107: Binary incompatibility problems between compiled code in Groovy 2.4.7 vs 2.4.9 (closes PR#508)

Posted by su...@apache.org.
GROOVY-8107: Binary incompatibility problems between compiled code in Groovy 2.4.7 vs 2.4.9 (closes PR#508)


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

Branch: refs/heads/parrot
Commit: 83037298daa86a4fcc7613f98fcebae6102ce90d
Parents: d55329c
Author: paulk <pa...@asert.com.au>
Authored: Mon Mar 6 07:52:26 2017 +1000
Committer: paulk <pa...@asert.com.au>
Committed: Wed Mar 8 15:03:37 2017 +1000

----------------------------------------------------------------------
 .../transform/trait/TraitASTTransformation.java | 87 ++++++++++++--------
 .../groovy/transform/trait/TraitComposer.java   | 81 +++++++++---------
 2 files changed, 94 insertions(+), 74 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/83037298/src/main/org/codehaus/groovy/transform/trait/TraitASTTransformation.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/transform/trait/TraitASTTransformation.java b/src/main/org/codehaus/groovy/transform/trait/TraitASTTransformation.java
index 99d1c0d..da71e9e 100644
--- a/src/main/org/codehaus/groovy/transform/trait/TraitASTTransformation.java
+++ b/src/main/org/codehaus/groovy/transform/trait/TraitASTTransformation.java
@@ -409,45 +409,42 @@ public class TraitASTTransformation extends AbstractASTTransformation implements
                         returnS(initialExpression)
                 );
                 helper.addMethod(fieldInitializer);
+            }
+            VariableExpression thisObject = new VariableExpression(selectedMethod.getParameters()[0]);
+            ExpressionStatement initCode = new ExpressionStatement(initialExpression);
+            processBody(thisObject, initCode, trait, helper, fieldHelper, knownFields);
+            BlockStatement code = (BlockStatement) selectedMethod.getCode();
+            MethodCallExpression mce;
+            if (field.isStatic()) {
+                mce = new MethodCallExpression(
+                        new ClassExpression(INVOKERHELPER_CLASSNODE),
+                        "invokeStaticMethod",
+                        new ArgumentListExpression(
+                                thisObject,
+                                new ConstantExpression(Traits.helperSetterName(field)),
+                                initCode.getExpression()
+                        )
+                );
             } else {
-                VariableExpression thisObject = new VariableExpression(selectedMethod.getParameters()[0]);
-                ExpressionStatement initCode = new ExpressionStatement(initialExpression);
-                processBody(thisObject, initCode, trait, helper, fieldHelper, knownFields);
-                BlockStatement code = (BlockStatement) selectedMethod.getCode();
-                MethodCallExpression mce;
-                if (field.isStatic()) {
-                    mce = new MethodCallExpression(
-                            new ClassExpression(INVOKERHELPER_CLASSNODE),
-                            "invokeStaticMethod",
-                            new ArgumentListExpression(
-                                    thisObject,
-                                    new ConstantExpression(Traits.helperSetterName(field)),
-                                    initCode.getExpression()
-                            )
-                    );
-                } else {
-                    mce = new MethodCallExpression(
-                            new CastExpression(createReceiverType(field.isStatic(), fieldHelper), thisObject),
-                            Traits.helperSetterName(field),
-                            new CastExpression(field.getOriginType(),initCode.getExpression())
-                    );
-                }
-                mce.setImplicitThis(false);
-                mce.setSourcePosition(initialExpression);
-                code.addStatement(new ExpressionStatement(mce));
+                mce = new MethodCallExpression(
+                        new CastExpression(createReceiverType(field.isStatic(), fieldHelper), thisObject),
+                        Traits.helperSetterName(field),
+                        new CastExpression(field.getOriginType(),initCode.getExpression())
+                );
             }
+            mce.setImplicitThis(false);
+            mce.setSourcePosition(initialExpression);
+            code.addStatement(new ExpressionStatement(mce));
         }
-        // define setter/getter helper methods
-        if (!Modifier.isFinal(field.getModifiers())) {
-            fieldHelper.addMethod(
-                    Traits.helperSetterName(field),
-                    ACC_PUBLIC | ACC_ABSTRACT,
-                    field.getOriginType(),
-                    new Parameter[]{new Parameter(field.getOriginType(), "val")},
-                    ClassNode.EMPTY_ARRAY,
-                    null
-            );
-        }
+        // define setter/getter helper methods (setter added even for final fields for legacy compatibility)
+        fieldHelper.addMethod(
+                Traits.helperSetterName(field),
+                ACC_PUBLIC | ACC_ABSTRACT,
+                field.getOriginType(),
+                new Parameter[]{new Parameter(field.getOriginType(), "val")},
+                ClassNode.EMPTY_ARRAY,
+                null
+        );
         fieldHelper.addMethod(
                 Traits.helperGetterName(field),
                 ACC_PUBLIC | ACC_ABSTRACT,
@@ -474,6 +471,24 @@ public class TraitASTTransformation extends AbstractASTTransformation implements
         GeneralUtils.copyAnnotatedNodeAnnotations(field, copied, notCopied);
         dummyField.addAnnotations(copied);
         fieldHelper.addField(dummyField);
+
+        // retain legacy field (will be given lower precedence than above)
+        dummyFieldName = (field.isStatic() ? Traits.STATIC_FIELD_PREFIX : Traits.FIELD_PREFIX) +
+                (field.isPublic()? Traits.PUBLIC_FIELD_PREFIX : Traits.PRIVATE_FIELD_PREFIX)+
+                Traits.remappedFieldName(field.getOwner(), field.getName());
+        dummyField = new FieldNode(
+                dummyFieldName,
+                ACC_STATIC | ACC_PUBLIC | ACC_FINAL | ACC_SYNTHETIC,
+                field.getOriginType(),
+                fieldHelper,
+                null
+        );
+        // copy annotations from field to legacy dummy field
+        copied = new LinkedList<AnnotationNode>();
+        notCopied = new LinkedList<AnnotationNode>();
+        GeneralUtils.copyAnnotatedNodeAnnotations(field, copied, notCopied);
+        dummyField.addAnnotations(copied);
+        fieldHelper.addField(dummyField);
     }
 
     private MethodNode processMethod(ClassNode traitClass, ClassNode traitHelperClass, MethodNode methodNode, ClassNode fieldHelper, Collection<String> knownFields) {

http://git-wip-us.apache.org/repos/asf/groovy/blob/83037298/src/main/org/codehaus/groovy/transform/trait/TraitComposer.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/transform/trait/TraitComposer.java b/src/main/org/codehaus/groovy/transform/trait/TraitComposer.java
index 704162d..1025e61 100644
--- a/src/main/org/codehaus/groovy/transform/trait/TraitComposer.java
+++ b/src/main/org/codehaus/groovy/transform/trait/TraitComposer.java
@@ -217,34 +217,38 @@ public abstract class TraitComposer {
                     int fieldMods = 0;
                     int isStatic = 0;
                     boolean publicField = true;
-                    FieldNode helperField = fieldHelperClassNode.getField(Traits.FIELD_PREFIX + Traits.PUBLIC_FIELD_PREFIX + fieldName);
-                    if (helperField==null) {
-                        publicField = false;
-                        helperField = fieldHelperClassNode.getField(Traits.FIELD_PREFIX + Traits.PRIVATE_FIELD_PREFIX + fieldName);
+                    FieldNode helperField = null;
+                    fieldMods = 0;
+                    isStatic = 0;
+
+                    // look first for field with encoded modifier information
+                    for (Integer mod : Traits.FIELD_PREFIXES) {
+                        helperField = fieldHelperClassNode.getField(String.format("$0x%04x", mod) + fieldName);
+                        if (helperField != null) {
+                            if ((mod & Opcodes.ACC_STATIC) != 0) isStatic = Opcodes.ACC_STATIC;
+                            fieldMods = fieldMods | mod;
+                            break;
+                        }
                     }
-                    if (helperField==null) {
-                        publicField = true;
-                        // try to find a static one
-                        helperField = fieldHelperClassNode.getField(Traits.STATIC_FIELD_PREFIX+Traits.PUBLIC_FIELD_PREFIX+fieldName);
+
+                    if (helperField == null) {
+                        // look for possible legacy fields (trait compiled pre 2.4.8)
+                        helperField = fieldHelperClassNode.getField(Traits.FIELD_PREFIX + Traits.PUBLIC_FIELD_PREFIX + fieldName);
                         if (helperField==null) {
                             publicField = false;
-                            helperField = fieldHelperClassNode.getField(Traits.STATIC_FIELD_PREFIX+Traits.PRIVATE_FIELD_PREFIX +fieldName);
+                            helperField = fieldHelperClassNode.getField(Traits.FIELD_PREFIX + Traits.PRIVATE_FIELD_PREFIX + fieldName);
                         }
-                        fieldMods = fieldMods | Opcodes.ACC_STATIC;
-                        isStatic = Opcodes.ACC_STATIC;
-                    }
-                    if (helperField == null) {
-                        fieldMods = 0;
-                        isStatic = 0;
-                        for (Integer mod : Traits.FIELD_PREFIXES) {
-                            helperField = fieldHelperClassNode.getField(String.format("$0x%04x", mod) + fieldName);
-                            if (helperField != null) {
-                                if ((mod & Opcodes.ACC_STATIC) != 0) isStatic = Opcodes.ACC_STATIC;
-                                fieldMods = fieldMods | mod;
-                                break;
+                        if (helperField==null) {
+                            publicField = true;
+                            // try to find a static one
+                            helperField = fieldHelperClassNode.getField(Traits.STATIC_FIELD_PREFIX+Traits.PUBLIC_FIELD_PREFIX+fieldName);
+                            if (helperField==null) {
+                                publicField = false;
+                                helperField = fieldHelperClassNode.getField(Traits.STATIC_FIELD_PREFIX+Traits.PRIVATE_FIELD_PREFIX +fieldName);
                             }
+                            fieldMods = fieldMods | Opcodes.ACC_STATIC;
+                            isStatic = Opcodes.ACC_STATIC;
                         }
-                    } else {
                         fieldMods = fieldMods | (publicField?Opcodes.ACC_PUBLIC:Opcodes.ACC_PRIVATE);
                     }
                     if (getter) {
@@ -279,29 +283,30 @@ public abstract class TraitComposer {
                     }
 
                     Expression fieldExpr = varX(cNode.getField(fieldName));
+                    boolean finalSetter = !getter && (fieldMods & Opcodes.ACC_FINAL) != 0;
                     Statement body =
                             getter ? returnS(fieldExpr) :
-                                    stmt(
+                                    (finalSetter ? null : stmt(
                                             new BinaryExpression(
                                                     fieldExpr,
                                                     Token.newSymbol(Types.EQUAL, 0, 0),
                                                     varX(newParams[0])
                                             )
-                                    );
-                    if (getter || (fieldMods & Opcodes.ACC_FINAL) == 0) {
-                        MethodNode impl = new MethodNode(
-                                methodNode.getName(),
-                                Opcodes.ACC_PUBLIC | isStatic,
-                                returnType,
-                                newParams,
-                                ClassNode.EMPTY_ARRAY,
-                                body
-                        );
-                        AnnotationNode an = new AnnotationNode(COMPILESTATIC_CLASSNODE);
-                        impl.addAnnotation(an);
-                        cNode.addTransform(StaticCompileTransformation.class, an);
-                        cNode.addMethod(impl);
-                    }
+                                    ));
+                    // add getter/setter even though setter not strictly needed for final fields
+                    // but add empty body for setter for legacy compatibility
+                    MethodNode impl = new MethodNode(
+                            methodNode.getName(),
+                            Opcodes.ACC_PUBLIC | isStatic,
+                            returnType,
+                            newParams,
+                            ClassNode.EMPTY_ARRAY,
+                            body
+                    );
+                    AnnotationNode an = new AnnotationNode(COMPILESTATIC_CLASSNODE);
+                    impl.addAnnotation(an);
+                    cNode.addTransform(StaticCompileTransformation.class, an);
+                    cNode.addMethod(impl);
                 }
             }
         }


[41/50] [abbrv] groovy git commit: fix typo in isOdd

Posted by su...@apache.org.
fix typo in isOdd


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

Branch: refs/heads/parrot
Commit: 062b0b1d1068891c2bea157d10f7ce6d8355dec3
Parents: b58da0f
Author: paulk <pa...@asert.com.au>
Authored: Wed Mar 29 11:56:55 2017 +1000
Committer: paulk <pa...@asert.com.au>
Committed: Wed Mar 29 11:57:49 2017 +1000

----------------------------------------------------------------------
 src/spec/test/ClosuresSpecTest.groovy | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/062b0b1d/src/spec/test/ClosuresSpecTest.groovy
----------------------------------------------------------------------
diff --git a/src/spec/test/ClosuresSpecTest.groovy b/src/spec/test/ClosuresSpecTest.groovy
index 3e82e1a..5276b67 100644
--- a/src/spec/test/ClosuresSpecTest.groovy
+++ b/src/spec/test/ClosuresSpecTest.groovy
@@ -82,7 +82,7 @@ class ClosuresSpecTest extends GroovyTestCase {
         // end::closure_call_1_explicit[]
 
         // tag::closure_call_2[]
-        def isOdd = { int i-> i%2 == 1 }                            // <1>
+        def isOdd = { int i -> i%2 != 0 }                           // <1>
         assert isOdd(3) == true                                     // <2>
         assert isOdd.call(2) == false                               // <3>
 


[05/50] [abbrv] groovy git commit: GROOVY-8109: Unsupported operator with @CompileStatic causes BUG! () during compilation (closes PR#509)

Posted by su...@apache.org.
GROOVY-8109: Unsupported operator with @CompileStatic causes BUG! () during compilation (closes PR#509)


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

Branch: refs/heads/parrot
Commit: d55329c119a14dadce00a8edd8a139fbc279bce4
Parents: ec3179a
Author: paulk <pa...@asert.com.au>
Authored: Wed Mar 8 07:08:07 2017 +1000
Committer: paulk <pa...@asert.com.au>
Committed: Wed Mar 8 15:01:21 2017 +1000

----------------------------------------------------------------------
 .../groovy/transform/stc/StaticTypeCheckingVisitor.java       | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/d55329c1/src/main/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java b/src/main/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
index 0f49976..8a08e58 100644
--- a/src/main/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -110,7 +110,9 @@ import static org.codehaus.groovy.ast.tools.WideningCategories.lowestUpperBound;
 import static org.codehaus.groovy.syntax.Types.ASSIGN;
 import static org.codehaus.groovy.syntax.Types.ASSIGNMENT_OPERATOR;
 import static org.codehaus.groovy.syntax.Types.COMPARE_EQUAL;
+import static org.codehaus.groovy.syntax.Types.COMPARE_IDENTICAL;
 import static org.codehaus.groovy.syntax.Types.COMPARE_NOT_EQUAL;
+import static org.codehaus.groovy.syntax.Types.COMPARE_NOT_IDENTICAL;
 import static org.codehaus.groovy.syntax.Types.COMPARE_TO;
 import static org.codehaus.groovy.syntax.Types.DIVIDE;
 import static org.codehaus.groovy.syntax.Types.DIVIDE_EQUAL;
@@ -558,12 +560,15 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
 
     @Override
     public void visitBinaryExpression(BinaryExpression expression) {
+        int op = expression.getOperation().getType();
+        if (op == COMPARE_IDENTICAL || op == COMPARE_NOT_IDENTICAL) {
+            return; // we'll report those as errors later
+        }
         BinaryExpression enclosingBinaryExpression = typeCheckingContext.getEnclosingBinaryExpression();
         typeCheckingContext.pushEnclosingBinaryExpression(expression);
         try {
             final Expression leftExpression = expression.getLeftExpression();
             final Expression rightExpression = expression.getRightExpression();
-            int op = expression.getOperation().getType();
             leftExpression.visit(this);
             SetterInfo setterInfo = removeSetterInfo(leftExpression);
             if (setterInfo != null) {


[36/50] [abbrv] groovy git commit: introduce macro methods and re-implement macro as a macro method

Posted by su...@apache.org.
introduce macro methods and re-implement macro as a macro method


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

Branch: refs/heads/parrot
Commit: b4e68bd554acbe8a9fc30a81a2291306d1e78968
Parents: a299cba
Author: Sergei Egorov <se...@zeroturnaround.com>
Authored: Thu Dec 29 20:42:50 2016 +0200
Committer: paulk <pa...@asert.com.au>
Committed: Tue Mar 28 16:02:21 2017 +1000

----------------------------------------------------------------------
 .../groovy/ast/TransformingCodeVisitor.java     | 340 ++++++++++++++++++
 .../codehaus/groovy/control/ErrorCollector.java |   6 +-
 .../org/codehaus/groovy/control/SourceUnit.java |   4 +
 .../codehaus/groovy/syntax/SyntaxException.java |   5 +
 .../macro/methods/MacroGroovyMethods.java       | 214 +++++++++++
 .../codehaus/groovy/macro/runtime/Macro.java    |  36 ++
 .../groovy/macro/runtime/MacroBuilder.java      |  18 +-
 .../groovy/macro/runtime/MacroContext.java      |  56 +++
 .../macro/runtime/MacroGroovyMethods.java       |  53 ---
 .../groovy/macro/runtime/MacroStub.java         |  32 ++
 .../transform/MacroClassTransformation.java     | 114 ++++++
 .../macro/transform/MacroInvocationTrap.java    | 274 --------------
 .../macro/transform/MacroMethodsCache.java      | 143 ++++++++
 .../macro/transform/MacroTransformation.java    |  97 ++++-
 .../macro/transform/TransformingMacroTrap.java  | 343 ------------------
 .../org.codehaus.groovy.runtime.ExtensionModule |  17 +
 ....codehaus.groovy.transform.ASTTransformation |   1 +
 .../groovy/macro/ExampleMacroMethods.java       |  34 ++
 .../org/codehaus/groovy/macro/MacroTest.groovy  |  15 +
 .../groovy/macro/MacroTransformationTest.groovy |  70 ++++
 .../groovy/macro/matcher/ASTMatcherTest.groovy  | 357 ++++++++++++++++++-
 .../org.codehaus.groovy.runtime.ExtensionModule |  17 +
 22 files changed, 1534 insertions(+), 712 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/b4e68bd5/src/main/org/codehaus/groovy/ast/TransformingCodeVisitor.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/ast/TransformingCodeVisitor.java b/src/main/org/codehaus/groovy/ast/TransformingCodeVisitor.java
new file mode 100644
index 0000000..53f02fd
--- /dev/null
+++ b/src/main/org/codehaus/groovy/ast/TransformingCodeVisitor.java
@@ -0,0 +1,340 @@
+/*
+ *  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.ast.expr.*;
+import org.codehaus.groovy.ast.stmt.AssertStatement;
+import org.codehaus.groovy.ast.stmt.BlockStatement;
+import org.codehaus.groovy.ast.stmt.BreakStatement;
+import org.codehaus.groovy.ast.stmt.CaseStatement;
+import org.codehaus.groovy.ast.stmt.CatchStatement;
+import org.codehaus.groovy.ast.stmt.ContinueStatement;
+import org.codehaus.groovy.ast.stmt.DoWhileStatement;
+import org.codehaus.groovy.ast.stmt.ExpressionStatement;
+import org.codehaus.groovy.ast.stmt.ForStatement;
+import org.codehaus.groovy.ast.stmt.IfStatement;
+import org.codehaus.groovy.ast.stmt.ReturnStatement;
+import org.codehaus.groovy.ast.stmt.SwitchStatement;
+import org.codehaus.groovy.ast.stmt.SynchronizedStatement;
+import org.codehaus.groovy.ast.stmt.ThrowStatement;
+import org.codehaus.groovy.ast.stmt.TryCatchStatement;
+import org.codehaus.groovy.ast.stmt.WhileStatement;
+import org.codehaus.groovy.classgen.BytecodeExpression;
+
+public class TransformingCodeVisitor extends CodeVisitorSupport {
+    private final ClassCodeExpressionTransformer trn;
+
+    public TransformingCodeVisitor(final ClassCodeExpressionTransformer trn) {
+        this.trn = trn;
+    }
+
+    @Override
+    public void visitBlockStatement(final BlockStatement block) {
+        super.visitBlockStatement(block);
+        trn.visitBlockStatement(block);
+    }
+
+    @Override
+    public void visitForLoop(final ForStatement forLoop) {
+        super.visitForLoop(forLoop);
+        trn.visitForLoop(forLoop);
+    }
+
+    @Override
+    public void visitWhileLoop(final WhileStatement loop) {
+        super.visitWhileLoop(loop);
+        trn.visitWhileLoop(loop);
+    }
+
+    @Override
+    public void visitDoWhileLoop(final DoWhileStatement loop) {
+        super.visitDoWhileLoop(loop);
+        trn.visitDoWhileLoop(loop);
+    }
+
+    @Override
+    public void visitIfElse(final IfStatement ifElse) {
+        super.visitIfElse(ifElse);
+        trn.visitIfElse(ifElse);
+    }
+
+    @Override
+    public void visitExpressionStatement(final ExpressionStatement statement) {
+        super.visitExpressionStatement(statement);
+        trn.visitExpressionStatement(statement);
+    }
+
+    @Override
+    public void visitReturnStatement(final ReturnStatement statement) {
+        super.visitReturnStatement(statement);
+        trn.visitReturnStatement(statement);
+    }
+
+    @Override
+    public void visitAssertStatement(final AssertStatement statement) {
+        super.visitAssertStatement(statement);
+        trn.visitAssertStatement(statement);
+    }
+
+    @Override
+    public void visitTryCatchFinally(final TryCatchStatement statement) {
+        super.visitTryCatchFinally(statement);
+        trn.visitTryCatchFinally(statement);
+    }
+
+    @Override
+    public void visitSwitch(final SwitchStatement statement) {
+        super.visitSwitch(statement);
+        trn.visitSwitch(statement);
+    }
+
+    @Override
+    public void visitCaseStatement(final CaseStatement statement) {
+        super.visitCaseStatement(statement);
+        trn.visitCaseStatement(statement);
+    }
+
+    @Override
+    public void visitBreakStatement(final BreakStatement statement) {
+        super.visitBreakStatement(statement);
+        trn.visitBreakStatement(statement);
+    }
+
+    @Override
+    public void visitContinueStatement(final ContinueStatement statement) {
+        super.visitContinueStatement(statement);
+        trn.visitContinueStatement(statement);
+    }
+
+    @Override
+    public void visitSynchronizedStatement(final SynchronizedStatement statement) {
+        super.visitSynchronizedStatement(statement);
+        trn.visitSynchronizedStatement(statement);
+    }
+
+    @Override
+    public void visitThrowStatement(final ThrowStatement statement) {
+        super.visitThrowStatement(statement);
+        trn.visitThrowStatement(statement);
+    }
+
+    @Override
+    public void visitStaticMethodCallExpression(final StaticMethodCallExpression call) {
+        super.visitStaticMethodCallExpression(call);
+        trn.visitStaticMethodCallExpression(call);
+    }
+
+    @Override
+    public void visitBinaryExpression(final BinaryExpression expression) {
+        super.visitBinaryExpression(expression);
+        trn.visitBinaryExpression(expression);
+    }
+
+    @Override
+    public void visitTernaryExpression(final TernaryExpression expression) {
+        super.visitTernaryExpression(expression);
+        trn.visitTernaryExpression(expression);
+    }
+
+    @Override
+    public void visitShortTernaryExpression(final ElvisOperatorExpression expression) {
+        super.visitShortTernaryExpression(expression);
+        trn.visitShortTernaryExpression(expression);
+    }
+
+    @Override
+    public void visitPostfixExpression(final PostfixExpression expression) {
+        super.visitPostfixExpression(expression);
+        trn.visitPostfixExpression(expression);
+    }
+
+    @Override
+    public void visitPrefixExpression(final PrefixExpression expression) {
+        super.visitPrefixExpression(expression);
+        trn.visitPrefixExpression(expression);
+    }
+
+    @Override
+    public void visitBooleanExpression(final BooleanExpression expression) {
+        super.visitBooleanExpression(expression);
+        trn.visitBooleanExpression(expression);
+    }
+
+    @Override
+    public void visitNotExpression(final NotExpression expression) {
+        super.visitNotExpression(expression);
+        trn.visitNotExpression(expression);
+    }
+
+    @Override
+    public void visitClosureExpression(final ClosureExpression expression) {
+        super.visitClosureExpression(expression);
+        trn.visitClosureExpression(expression);
+    }
+
+    @Override
+    public void visitTupleExpression(final TupleExpression expression) {
+        super.visitTupleExpression(expression);
+        trn.visitTupleExpression(expression);
+    }
+
+    @Override
+    public void visitListExpression(final ListExpression expression) {
+        super.visitListExpression(expression);
+        trn.visitListExpression(expression);
+    }
+
+    @Override
+    public void visitArrayExpression(final ArrayExpression expression) {
+        super.visitArrayExpression(expression);
+        trn.visitArrayExpression(expression);
+    }
+
+    @Override
+    public void visitMapExpression(final MapExpression expression) {
+        super.visitMapExpression(expression);
+        trn.visitMapExpression(expression);
+    }
+
+    @Override
+    public void visitMapEntryExpression(final MapEntryExpression expression) {
+        super.visitMapEntryExpression(expression);
+        trn.visitMapEntryExpression(expression);
+    }
+
+    @Override
+    public void visitRangeExpression(final RangeExpression expression) {
+        super.visitRangeExpression(expression);
+        trn.visitRangeExpression(expression);
+    }
+
+    @Override
+    public void visitSpreadExpression(final SpreadExpression expression) {
+        super.visitSpreadExpression(expression);
+        trn.visitSpreadExpression(expression);
+    }
+
+    @Override
+    public void visitSpreadMapExpression(final SpreadMapExpression expression) {
+        super.visitSpreadMapExpression(expression);
+        trn.visitSpreadMapExpression(expression);
+    }
+
+    @Override
+    public void visitMethodPointerExpression(final MethodPointerExpression expression) {
+        super.visitMethodPointerExpression(expression);
+        trn.visitMethodPointerExpression(expression);
+    }
+
+    @Override
+    public void visitUnaryMinusExpression(final UnaryMinusExpression expression) {
+        super.visitUnaryMinusExpression(expression);
+        trn.visitUnaryMinusExpression(expression);
+    }
+
+    @Override
+    public void visitUnaryPlusExpression(final UnaryPlusExpression expression) {
+        super.visitUnaryPlusExpression(expression);
+        trn.visitUnaryPlusExpression(expression);
+    }
+
+    @Override
+    public void visitBitwiseNegationExpression(final BitwiseNegationExpression expression) {
+        super.visitBitwiseNegationExpression(expression);
+        trn.visitBitwiseNegationExpression(expression);
+    }
+
+    @Override
+    public void visitCastExpression(final CastExpression expression) {
+        super.visitCastExpression(expression);
+        trn.visitCastExpression(expression);
+    }
+
+    @Override
+    public void visitConstantExpression(final ConstantExpression expression) {
+        super.visitConstantExpression(expression);
+        trn.visitConstantExpression(expression);
+    }
+
+    @Override
+    public void visitClassExpression(final ClassExpression expression) {
+        super.visitClassExpression(expression);
+        trn.visitClassExpression(expression);
+    }
+
+    @Override
+    public void visitVariableExpression(final VariableExpression expression) {
+        super.visitVariableExpression(expression);
+        trn.visitVariableExpression(expression);
+    }
+
+    @Override
+    public void visitDeclarationExpression(final DeclarationExpression expression) {
+        super.visitDeclarationExpression(expression);
+        trn.visitDeclarationExpression(expression);
+    }
+
+    @Override
+    public void visitPropertyExpression(final PropertyExpression expression) {
+        super.visitPropertyExpression(expression);
+        trn.visitPropertyExpression(expression);
+    }
+
+    @Override
+    public void visitAttributeExpression(final AttributeExpression expression) {
+        super.visitAttributeExpression(expression);
+        trn.visitAttributeExpression(expression);
+    }
+
+    @Override
+    public void visitFieldExpression(final FieldExpression expression) {
+        super.visitFieldExpression(expression);
+        trn.visitFieldExpression(expression);
+    }
+
+    @Override
+    public void visitGStringExpression(final GStringExpression expression) {
+        super.visitGStringExpression(expression);
+        trn.visitGStringExpression(expression);
+    }
+
+    @Override
+    public void visitCatchStatement(final CatchStatement statement) {
+        super.visitCatchStatement(statement);
+        trn.visitCatchStatement(statement);
+    }
+
+    @Override
+    public void visitArgumentlistExpression(final ArgumentListExpression ale) {
+        super.visitArgumentlistExpression(ale);
+        trn.visitArgumentlistExpression(ale);
+    }
+
+    @Override
+    public void visitClosureListExpression(final ClosureListExpression cle) {
+        super.visitClosureListExpression(cle);
+        trn.visitClosureListExpression(cle);
+    }
+
+    @Override
+    public void visitBytecodeExpression(final BytecodeExpression cle) {
+        super.visitBytecodeExpression(cle);
+        trn.visitBytecodeExpression(cle);
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/b4e68bd5/src/main/org/codehaus/groovy/control/ErrorCollector.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/control/ErrorCollector.java b/src/main/org/codehaus/groovy/control/ErrorCollector.java
index 4777d34..3376644 100644
--- a/src/main/org/codehaus/groovy/control/ErrorCollector.java
+++ b/src/main/org/codehaus/groovy/control/ErrorCollector.java
@@ -80,8 +80,10 @@ public class ErrorCollector {
             }            
         }
     }
-    
-    
+
+    public void addErrorAndContinue(SyntaxException error, SourceUnit source) throws CompilationFailedException {
+        addErrorAndContinue(Message.create(error, source));
+    }
     
     /**
      * Adds an error to the message set, but does not cause a failure. The message is not required to have a source

http://git-wip-us.apache.org/repos/asf/groovy/blob/b4e68bd5/src/main/org/codehaus/groovy/control/SourceUnit.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/control/SourceUnit.java b/src/main/org/codehaus/groovy/control/SourceUnit.java
index 66950f4..b2c8a32 100644
--- a/src/main/org/codehaus/groovy/control/SourceUnit.java
+++ b/src/main/org/codehaus/groovy/control/SourceUnit.java
@@ -349,5 +349,9 @@ public class SourceUnit extends ProcessingUnit {
         getErrorCollector().addError(se, this);
     }
 
+    public void addErrorAndContinue(SyntaxException se) throws CompilationFailedException {
+        getErrorCollector().addErrorAndContinue(se, this);
+    }
+
     public ReaderSource getSource() { return source; }
 }

http://git-wip-us.apache.org/repos/asf/groovy/blob/b4e68bd5/src/main/org/codehaus/groovy/syntax/SyntaxException.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/syntax/SyntaxException.java b/src/main/org/codehaus/groovy/syntax/SyntaxException.java
index 0348e8c..eb5b69f 100644
--- a/src/main/org/codehaus/groovy/syntax/SyntaxException.java
+++ b/src/main/org/codehaus/groovy/syntax/SyntaxException.java
@@ -19,6 +19,7 @@
 package org.codehaus.groovy.syntax;
 
 import org.codehaus.groovy.GroovyException;
+import org.codehaus.groovy.ast.ASTNode;
 
 /** Base exception indicating a syntax error.
  *
@@ -36,6 +37,10 @@ public class SyntaxException extends GroovyException {
 
     private String sourceLocator;
 
+    public SyntaxException(String message, ASTNode node) {
+        this(message, node.getLineNumber(), node.getColumnNumber(), node.getLastLineNumber(), node.getLastColumnNumber());
+    }
+
     public SyntaxException(String message, int startLine, int startColumn) {
         this(message, startLine, startColumn, startLine, startColumn+1);
     }

http://git-wip-us.apache.org/repos/asf/groovy/blob/b4e68bd5/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/methods/MacroGroovyMethods.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/methods/MacroGroovyMethods.java b/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/methods/MacroGroovyMethods.java
new file mode 100644
index 0000000..d9f00e6
--- /dev/null
+++ b/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/methods/MacroGroovyMethods.java
@@ -0,0 +1,214 @@
+/*
+ *  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.macro.methods;
+
+import groovy.lang.Closure;
+import groovy.lang.DelegatesTo;
+import org.codehaus.groovy.ast.ASTNode;
+import org.codehaus.groovy.ast.ClassCodeVisitorSupport;
+import org.codehaus.groovy.ast.ClassHelper;
+import org.codehaus.groovy.ast.ClassNode;
+import org.codehaus.groovy.ast.InnerClassNode;
+import org.codehaus.groovy.ast.expr.ClosureExpression;
+import org.codehaus.groovy.ast.expr.ConstantExpression;
+import org.codehaus.groovy.ast.expr.Expression;
+import org.codehaus.groovy.ast.expr.ListExpression;
+import org.codehaus.groovy.ast.expr.MethodCallExpression;
+import org.codehaus.groovy.ast.expr.PropertyExpression;
+import org.codehaus.groovy.ast.expr.TupleExpression;
+import org.codehaus.groovy.ast.stmt.BlockStatement;
+import org.codehaus.groovy.ast.stmt.Statement;
+import org.codehaus.groovy.ast.tools.ClosureUtils;
+import org.codehaus.groovy.control.CompilePhase;
+import org.codehaus.groovy.control.SourceUnit;
+import org.codehaus.groovy.macro.runtime.Macro;
+import org.codehaus.groovy.macro.runtime.MacroBuilder;
+import org.codehaus.groovy.macro.runtime.MacroContext;
+import org.codehaus.groovy.syntax.SyntaxException;
+
+import java.util.Iterator;
+
+import static org.codehaus.groovy.ast.tools.GeneralUtils.*;
+
+public class MacroGroovyMethods {
+
+    public static final String DOLLAR_VALUE = "$v";
+
+    public static class MacroValuePlaceholder {
+        public static Object $v(Closure cl) {
+            // replaced with AST transformations
+            return null;
+        }
+    }
+
+    public static <T> T macro(Object self, @DelegatesTo(MacroValuePlaceholder.class) Closure cl) {
+        throw new IllegalStateException("MacroGroovyMethods.macro(Closure) should never be called at runtime. Are you sure you are using it correctly?");
+    }
+
+    @Macro
+    public static Expression macro(MacroContext macroContext, ClosureExpression closureExpression) {
+        return macro(macroContext, new ConstantExpression(false, true), closureExpression);
+    }
+
+    public static <T> T macro(Object self, boolean asIs, @DelegatesTo(MacroValuePlaceholder.class) Closure cl) {
+        throw new IllegalStateException("MacroGroovyMethods.macro(boolean, Closure) should never be called at runtime. Are you sure you are using it correctly?");
+    }
+
+    @Macro
+    public static Expression macro(MacroContext macroContext, ConstantExpression asIsConstantExpression, ClosureExpression closureExpression) {
+        return macro(macroContext, null, asIsConstantExpression, closureExpression);
+    }
+
+    public static <T> T macro(Object self, CompilePhase compilePhase, @DelegatesTo(MacroValuePlaceholder.class) Closure cl) {
+        throw new IllegalStateException("MacroGroovyMethods.macro(CompilePhase, Closure) should never be called at runtime. Are you sure you are using it correctly?");
+    }
+
+    @Macro
+    public static Expression macro(MacroContext macroContext, PropertyExpression phaseExpression, ClosureExpression closureExpression) {
+        return macro(macroContext, phaseExpression, new ConstantExpression(false, true), closureExpression);
+    }
+
+    public static <T> T macro(Object self, CompilePhase compilePhase, boolean asIs, @DelegatesTo(MacroValuePlaceholder.class) Closure cl) {
+        throw new IllegalStateException("MacroGroovyMethods.macro(CompilePhase, boolean, Closure) should never be called at runtime. Are you sure you are using it correctly?");
+    }
+
+    @Macro
+    public static Expression macro(MacroContext macroContext, PropertyExpression phaseExpression, ConstantExpression asIsConstantExpression, ClosureExpression closureExpression) {
+        if (closureExpression.getParameters() != null && closureExpression.getParameters().length > 0) {
+            macroContext.getSourceUnit().addError(new SyntaxException("Macro closure arguments are not allowed" + '\n', closureExpression));
+            return macroContext.getCall();
+        }
+
+        final String source;
+        try {
+            source = ClosureUtils.convertClosureToSource(macroContext.getSourceUnit().getSource(), closureExpression);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+
+        BlockStatement closureBlock = (BlockStatement) closureExpression.getCode();
+
+        Boolean asIs = (Boolean) asIsConstantExpression.getValue();
+
+        TupleExpression macroArguments = getMacroArguments(macroContext.getSourceUnit(), macroContext.getCall());
+
+        if (macroArguments == null) {
+            // FIXME
+            return macroContext.getCall();
+        }
+
+        return callX(
+                propX(classX(ClassHelper.makeWithoutCaching(MacroBuilder.class, false)), "INSTANCE"),
+                "macro",
+                args(
+                        phaseExpression != null ? phaseExpression : constX(null),
+                        asIsConstantExpression,
+                        constX(source),
+                        buildSubstitutionMap(macroContext.getSourceUnit(), closureExpression),
+                        classX(ClassHelper.makeWithoutCaching(MacroBuilder.getMacroValue(closureBlock, asIs).getClass(), false))
+                )
+        );
+    }
+
+    public static ListExpression buildSubstitutionMap(final SourceUnit source, final ASTNode expr) {
+        final ListExpression listExpression = new ListExpression();
+
+        ClassCodeVisitorSupport visitor = new ClassCodeVisitorSupport() {
+            @Override
+            protected SourceUnit getSourceUnit() {
+                return null;
+            }
+
+            @Override
+            public void visitClass(final ClassNode node) {
+                super.visitClass(node);
+                Iterator<InnerClassNode> it = node.getInnerClasses();
+                while (it.hasNext()) {
+                    InnerClassNode next = it.next();
+                    visitClass(next);
+                }
+            }
+
+            @Override
+            public void visitMethodCallExpression(MethodCallExpression call) {
+                super.visitMethodCallExpression(call);
+
+                if (DOLLAR_VALUE.equals(call.getMethodAsString())) {
+                    ClosureExpression substitutionClosureExpression = getClosureArgument(source, call);
+
+                    if (substitutionClosureExpression == null) {
+                        return;
+                    }
+
+                    Statement code = substitutionClosureExpression.getCode();
+                    if (code instanceof BlockStatement) {
+                        ((BlockStatement) code).setVariableScope(null);
+                    }
+
+                    listExpression.addExpression(substitutionClosureExpression);
+                }
+            }
+        };
+        if (expr instanceof ClassNode) {
+            visitor.visitClass((ClassNode) expr);
+        } else {
+            expr.visit(visitor);
+        }
+        return listExpression;
+    }
+
+    protected static TupleExpression getMacroArguments(SourceUnit source, MethodCallExpression call) {
+        Expression macroCallArguments = call.getArguments();
+        if (macroCallArguments == null) {
+            source.addError(new SyntaxException("Call should have arguments" + '\n', call));
+            return null;
+        }
+
+        if (!(macroCallArguments instanceof TupleExpression)) {
+            source.addError(new SyntaxException("Call should have TupleExpression as arguments" + '\n', macroCallArguments));
+            return null;
+        }
+
+        TupleExpression tupleArguments = (TupleExpression) macroCallArguments;
+
+        if (tupleArguments.getExpressions() == null) {
+            source.addError(new SyntaxException("Call arguments should have expressions" + '\n', tupleArguments));
+            return null;
+        }
+
+        return tupleArguments;
+    }
+
+    protected static ClosureExpression getClosureArgument(SourceUnit source, MethodCallExpression call) {
+        TupleExpression tupleArguments = getMacroArguments(source, call);
+
+        if (tupleArguments == null || tupleArguments.getExpressions().size() < 1) {
+            source.addError(new SyntaxException("Call arguments should have at least one argument" + '\n', tupleArguments));
+            return null;
+        }
+
+        Expression result = tupleArguments.getExpression(tupleArguments.getExpressions().size() - 1);
+        if (!(result instanceof ClosureExpression)) {
+            source.addError(new SyntaxException("Last call argument should be a closure" + '\n', result));
+            return null;
+        }
+
+        return (ClosureExpression) result;
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/b4e68bd5/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/runtime/Macro.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/runtime/Macro.java b/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/runtime/Macro.java
new file mode 100644
index 0000000..b6a8938
--- /dev/null
+++ b/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/runtime/Macro.java
@@ -0,0 +1,36 @@
+/*
+ *  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.macro.runtime;
+
+import org.apache.groovy.lang.annotation.Incubating;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * @author Sergei Egorov <bs...@gmail.com>
+ */
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD})
+@Incubating
+public @interface Macro {
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/b4e68bd5/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/runtime/MacroBuilder.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/runtime/MacroBuilder.java b/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/runtime/MacroBuilder.java
index d7cc5ce..ef857e9 100644
--- a/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/runtime/MacroBuilder.java
+++ b/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/runtime/MacroBuilder.java
@@ -30,15 +30,14 @@ import org.codehaus.groovy.ast.stmt.ExpressionStatement;
 import org.codehaus.groovy.ast.stmt.Statement;
 import org.codehaus.groovy.control.CompilePhase;
 import org.codehaus.groovy.control.SourceUnit;
-import org.codehaus.groovy.macro.transform.MacroInvocationTrap;
-import org.codehaus.groovy.macro.transform.MacroTransformation;
 
 import java.util.Iterator;
 import java.util.List;
 import java.util.concurrent.atomic.AtomicInteger;
 
+import static org.codehaus.groovy.macro.methods.MacroGroovyMethods.DOLLAR_VALUE;
+
 /**
- *
  * @author Sergei Egorov <bs...@gmail.com>
  */
 public enum MacroBuilder {
@@ -49,7 +48,7 @@ public enum MacroBuilder {
     }
 
     public <T> T macro(boolean asIs, String source, final List<Closure<Expression>> context, Class<T> resultClass) {
-        return macro(CompilePhase.CONVERSION, asIs, source, context, resultClass);
+        return macro(null, asIs, source, context, resultClass);
     }
 
     public <T> T macro(CompilePhase compilePhase, String source, final List<Closure<Expression>> context, Class<T> resultClass) {
@@ -61,12 +60,16 @@ public enum MacroBuilder {
     @SuppressWarnings("unchecked")
     public <T> T macro(CompilePhase compilePhase, boolean asIs, String source, final List<Closure<Expression>> context, Class<T> resultClass) {
         boolean isClosure = source.startsWith("{");
-        final String label = isClosure ?"__synthesized__label__" + COUNTER.incrementAndGet() + "__:":"";
+        final String label = isClosure ? "__synthesized__label__" + COUNTER.incrementAndGet() + "__:" : "";
         final String labelledSource = label + source;
 
+        if (compilePhase == null) {
+            compilePhase = CompilePhase.CONVERSION;
+        }
+
         List<ASTNode> nodes = (new AstBuilder()).buildFromString(compilePhase, true, labelledSource);
 
-        for(ASTNode node : nodes) {
+        for (ASTNode node : nodes) {
             if (node instanceof BlockStatement) {
 
                 List<Statement> statements = ((BlockStatement) node).getStatements();
@@ -75,7 +78,6 @@ public enum MacroBuilder {
 
                     performSubstitutions(context, closureBlock);
 
-
                     return (T) getMacroValue(closureBlock, asIs);
                 }
             }
@@ -97,7 +99,7 @@ public enum MacroBuilder {
 
                 MethodCallExpression call = (MethodCallExpression) expression;
 
-                if (!MacroInvocationTrap.isBuildInvocation(call, MacroTransformation.DOLLAR_VALUE)) {
+                if (!DOLLAR_VALUE.equals(call.getMethodAsString())) {
                     return super.transform(expression);
                 }
 

http://git-wip-us.apache.org/repos/asf/groovy/blob/b4e68bd5/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/runtime/MacroContext.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/runtime/MacroContext.java b/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/runtime/MacroContext.java
new file mode 100644
index 0000000..e181a2a
--- /dev/null
+++ b/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/runtime/MacroContext.java
@@ -0,0 +1,56 @@
+/*
+ *  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.macro.runtime;
+
+import org.apache.groovy.lang.annotation.Incubating;
+import org.codehaus.groovy.ast.expr.MethodCallExpression;
+import org.codehaus.groovy.control.CompilationUnit;
+import org.codehaus.groovy.control.SourceUnit;
+
+/**
+ * @author Sergei Egorov <bs...@gmail.com>
+ */
+
+@Incubating
+public class MacroContext {
+
+    private final MethodCallExpression call;
+
+    private final SourceUnit sourceUnit;
+
+    private final CompilationUnit compilationUnit;
+
+    public MacroContext(CompilationUnit compilationUnit, SourceUnit sourceUnit, MethodCallExpression call) {
+        this.compilationUnit = compilationUnit;
+        this.sourceUnit = sourceUnit;
+        this.call = call;
+    }
+
+    public MethodCallExpression getCall() {
+        return call;
+    }
+
+    public SourceUnit getSourceUnit() {
+        return sourceUnit;
+    }
+
+    public CompilationUnit getCompilationUnit() {
+        return compilationUnit;
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/b4e68bd5/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/runtime/MacroGroovyMethods.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/runtime/MacroGroovyMethods.java b/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/runtime/MacroGroovyMethods.java
deleted file mode 100644
index 7e39589..0000000
--- a/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/runtime/MacroGroovyMethods.java
+++ /dev/null
@@ -1,53 +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.macro.runtime;
-
-import groovy.lang.Closure;
-import groovy.lang.DelegatesTo;
-import org.codehaus.groovy.control.CompilePhase;
-
-/**
- *
- * @author Sergei Egorov <bs...@gmail.com>
- */
-public class MacroGroovyMethods {
-
-    public static class MacroValuePlaceholder {
-        public static Object $v(Closure cl) {
-            // replaced with AST transformations
-            return null;
-        }
-    }
-
-    public static <T> T macro(Object self, @DelegatesTo(MacroValuePlaceholder.class) Closure cl) {
-        return null;
-    }
-
-    public static <T> T macro(Object self, boolean asIs, @DelegatesTo(MacroValuePlaceholder.class) Closure cl) {
-        return null;
-    }
-
-    public static <T> T macro(Object self, CompilePhase compilePhase, @DelegatesTo(MacroValuePlaceholder.class) Closure cl) {
-        return null;
-    }
-
-    public static <T> T macro(Object self, CompilePhase compilePhase, boolean asIs, @DelegatesTo(MacroValuePlaceholder.class) Closure cl) {
-        return null;
-    }
-}

http://git-wip-us.apache.org/repos/asf/groovy/blob/b4e68bd5/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/runtime/MacroStub.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/runtime/MacroStub.java b/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/runtime/MacroStub.java
new file mode 100644
index 0000000..b0590b5
--- /dev/null
+++ b/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/runtime/MacroStub.java
@@ -0,0 +1,32 @@
+/*
+ *  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.macro.runtime;
+
+/**
+ * Stub for macro calls.
+ *
+ * @author Sergei Egorov <bs...@gmail.com>
+ */
+public enum MacroStub {
+    INSTANCE;
+
+    public <T> T macroMethod(T obj) {
+        return obj;
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/b4e68bd5/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroClassTransformation.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroClassTransformation.java b/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroClassTransformation.java
new file mode 100644
index 0000000..292d59d
--- /dev/null
+++ b/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroClassTransformation.java
@@ -0,0 +1,114 @@
+/*
+ *  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.macro.transform;
+
+import org.codehaus.groovy.ast.*;
+import org.codehaus.groovy.ast.expr.ConstructorCallExpression;
+import org.codehaus.groovy.ast.expr.Expression;
+import org.codehaus.groovy.ast.expr.MethodCallExpression;
+import org.codehaus.groovy.ast.tools.GeneralUtils;
+import org.codehaus.groovy.control.CompilePhase;
+import org.codehaus.groovy.control.SourceUnit;
+import org.codehaus.groovy.macro.methods.MacroGroovyMethods;
+import org.codehaus.groovy.macro.runtime.MacroBuilder;
+import org.codehaus.groovy.transform.GroovyASTTransformation;
+
+import java.util.Iterator;
+import java.util.List;
+
+import static org.codehaus.groovy.ast.tools.GeneralUtils.*;
+
+@GroovyASTTransformation(phase = CompilePhase.CONVERSION)
+public class MacroClassTransformation extends MethodCallTransformation {
+
+    private static final String MACRO_METHOD = "macro";
+    private static final ClassNode MACROCLASS_TYPE = ClassHelper.make(MacroClass.class);
+
+    @Override
+    protected GroovyCodeVisitor getTransformer(final ASTNode[] nodes, final SourceUnit sourceUnit) {
+        ClassCodeExpressionTransformer transformer = new ClassCodeExpressionTransformer() {
+            @Override
+            protected SourceUnit getSourceUnit() {
+                return sourceUnit;
+            }
+
+            @Override
+            public Expression transform(final Expression exp) {
+                if (exp instanceof ConstructorCallExpression) {
+                    MethodCallExpression call = exp.getNodeMetaData(MacroTransformation.class);
+                    if (call != null) {
+                        return call;
+                    }
+                }
+                return super.transform(exp);
+            }
+        };
+
+        return new TransformingCodeVisitor(transformer) {
+
+            @Override
+            public void visitConstructorCallExpression(final ConstructorCallExpression call) {
+                ClassNode type = call.getType();
+                if (type instanceof InnerClassNode) {
+                    if (((InnerClassNode) type).isAnonymous() &&
+                            MACROCLASS_TYPE.getNameWithoutPackage().equals(type.getSuperClass().getNameWithoutPackage())) {
+                        try {
+                            String source = convertInnerClassToSource(type);
+
+                            MethodCallExpression macroCall = callX(
+                                    propX(classX(ClassHelper.makeWithoutCaching(MacroBuilder.class, false)), "INSTANCE"),
+                                    MACRO_METHOD,
+                                    args(
+                                            constX(source),
+                                            MacroGroovyMethods.buildSubstitutionMap(sourceUnit, type),
+                                            classX(ClassHelper.make(ClassNode.class))
+                                    )
+                            );
+
+                            macroCall.setSpreadSafe(false);
+                            macroCall.setSafe(false);
+                            macroCall.setImplicitThis(false);
+                            call.putNodeMetaData(MacroTransformation.class, macroCall);
+                            List<ClassNode> classes = sourceUnit.getAST().getClasses();
+                            for (Iterator<ClassNode> iterator = classes.iterator(); iterator.hasNext(); ) {
+                                final ClassNode aClass = iterator.next();
+                                if (aClass == type || type == aClass.getOuterClass()) {
+                                    iterator.remove();
+                                }
+                            }
+                        } catch (Exception e) {
+                            // FIXME
+                            e.printStackTrace();
+                        }
+                        return;
+                    }
+                }
+                super.visitConstructorCallExpression(call);
+
+            }
+
+            private String convertInnerClassToSource(final ClassNode type) throws Exception {
+                String source = GeneralUtils.convertASTToSource(sourceUnit.getSource(), type);
+                // we need to remove the leading "{" and trailing "}"
+                source = source.substring(source.indexOf('{') + 1, source.lastIndexOf('}') - 1);
+                return source;
+            }
+        };
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/b4e68bd5/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroInvocationTrap.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroInvocationTrap.java b/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroInvocationTrap.java
deleted file mode 100644
index 73c14db..0000000
--- a/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroInvocationTrap.java
+++ /dev/null
@@ -1,274 +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.macro.transform;
-
-import org.codehaus.groovy.ast.ASTNode;
-import org.codehaus.groovy.ast.ClassCodeVisitorSupport;
-import org.codehaus.groovy.ast.ClassHelper;
-import org.codehaus.groovy.ast.ClassNode;
-import org.codehaus.groovy.ast.InnerClassNode;
-import org.codehaus.groovy.ast.MethodInvocationTrap;
-import org.codehaus.groovy.ast.expr.ArgumentListExpression;
-import org.codehaus.groovy.ast.expr.ClassExpression;
-import org.codehaus.groovy.ast.expr.ClosureExpression;
-import org.codehaus.groovy.ast.expr.ConstantExpression;
-import org.codehaus.groovy.ast.expr.ConstructorCallExpression;
-import org.codehaus.groovy.ast.expr.Expression;
-import org.codehaus.groovy.ast.expr.ListExpression;
-import org.codehaus.groovy.ast.expr.MethodCallExpression;
-import org.codehaus.groovy.ast.expr.PropertyExpression;
-import org.codehaus.groovy.ast.expr.TupleExpression;
-import org.codehaus.groovy.ast.stmt.BlockStatement;
-import org.codehaus.groovy.ast.stmt.Statement;
-import org.codehaus.groovy.ast.tools.GeneralUtils;
-import org.codehaus.groovy.control.SourceUnit;
-import org.codehaus.groovy.control.io.ReaderSource;
-import org.codehaus.groovy.macro.runtime.MacroBuilder;
-
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-
-import static org.codehaus.groovy.ast.expr.VariableExpression.THIS_EXPRESSION;
-
-/**
- * @author Sergei Egorov <bs...@gmail.com>
- */
-public class MacroInvocationTrap extends MethodInvocationTrap {
-
-    private final static ClassNode MACROCLASS_TYPE = ClassHelper.make(MacroClass.class);
-    private final ReaderSource readerSource;
-    private final SourceUnit sourceUnit;
-
-    public MacroInvocationTrap(ReaderSource source, SourceUnit sourceUnit) {
-        super(source, sourceUnit);
-        this.readerSource = source;
-        this.sourceUnit = sourceUnit;
-    }
-
-    @Override
-    public void visitConstructorCallExpression(final ConstructorCallExpression call) {
-        ClassNode type = call.getType();
-        if (type instanceof InnerClassNode) {
-            if (((InnerClassNode) type).isAnonymous() &&
-                    MACROCLASS_TYPE.getNameWithoutPackage().equals(type.getSuperClass().getNameWithoutPackage())) {
-                //System.out.println("call = " + call.getText());
-                try {
-                    String source = convertInnerClassToSource(type);
-                    List<Expression> macroArgumentsExpressions = new LinkedList<Expression>();
-                    macroArgumentsExpressions.add(new ConstantExpression(source));
-                    macroArgumentsExpressions.add(buildSubstitutionMap(type));
-                    macroArgumentsExpressions.add(new ClassExpression(ClassHelper.make(ClassNode.class)));
-
-                    MethodCallExpression macroCall = new MethodCallExpression(
-                            new PropertyExpression(new ClassExpression(ClassHelper.makeWithoutCaching(MacroBuilder.class, false)), "INSTANCE"),
-                            MacroTransformation.MACRO_METHOD,
-                            new ArgumentListExpression(macroArgumentsExpressions)
-                    );
-
-                    macroCall.setSpreadSafe(false);
-                    macroCall.setSafe(false);
-                    macroCall.setImplicitThis(false);
-                    call.putNodeMetaData(MacroTransformation.class, macroCall);
-                    List<ClassNode> classes = sourceUnit.getAST().getClasses();
-                    for (Iterator<ClassNode> iterator = classes.iterator(); iterator.hasNext(); ) {
-                        final ClassNode aClass = iterator.next();
-                        if (aClass==type || type==aClass.getOuterClass()) {
-                            iterator.remove();
-                        }
-                    }
-                } catch (Exception e) {
-                    e.printStackTrace();
-                }
-                return;
-            }
-        }
-        super.visitConstructorCallExpression(call);
-
-    }
-
-    private String convertInnerClassToSource(final ClassNode type) throws Exception {
-        String source = GeneralUtils.convertASTToSource(readerSource, type);
-        // we need to remove the leading "{" and trailing "}"
-        source = source.substring(source.indexOf('{')+1, source.lastIndexOf('}')-1);
-        return source;
-    }
-
-    @Override
-    protected boolean handleTargetMethodCallExpression(MethodCallExpression macroCall) {
-        final ClosureExpression closureExpression = getClosureArgument(macroCall);
-
-        if (closureExpression == null) {
-            return true;
-        }
-
-        if (closureExpression.getParameters() != null && closureExpression.getParameters().length > 0) {
-            addError("Macro closure arguments are not allowed", closureExpression);
-            return true;
-        }
-
-        String source = convertClosureToSource(closureExpression);
-
-        BlockStatement closureBlock = (BlockStatement) closureExpression.getCode();
-
-        Boolean asIs = false;
-
-        TupleExpression macroArguments = getMacroArguments(macroCall);
-
-        if (macroArguments == null) {
-            return true;
-        }
-
-        List<Expression> macroArgumentsExpressions = macroArguments.getExpressions();
-
-        if (macroArgumentsExpressions.size() == 2 || macroArgumentsExpressions.size() == 3) {
-            Expression asIsArgumentExpression = macroArgumentsExpressions.get(macroArgumentsExpressions.size() - 2);
-            if ((asIsArgumentExpression instanceof ConstantExpression)) {
-                ConstantExpression asIsConstantExpression = (ConstantExpression) asIsArgumentExpression;
-
-                if (!(asIsConstantExpression.getValue() instanceof Boolean)) {
-                    addError("AsIs argument value should be boolean", asIsConstantExpression);
-                    return true;
-                }
-
-                asIs = (Boolean) asIsConstantExpression.getValue();
-            }
-        }
-
-        macroArgumentsExpressions.remove(macroArgumentsExpressions.size() - 1);
-
-        macroArgumentsExpressions.add(new ConstantExpression(source));
-        macroArgumentsExpressions.add(buildSubstitutionMap(closureExpression));
-        macroArgumentsExpressions.add(new ClassExpression(ClassHelper.makeWithoutCaching(MacroBuilder.getMacroValue(closureBlock, asIs).getClass(), false)));
-
-        macroCall.setObjectExpression(new PropertyExpression(new ClassExpression(ClassHelper.makeWithoutCaching(MacroBuilder.class, false)), "INSTANCE"));
-        macroCall.setSpreadSafe(false);
-        macroCall.setSafe(false);
-        macroCall.setImplicitThis(false);
-
-        return true;
-    }
-
-    private ListExpression buildSubstitutionMap(final ASTNode expr) {
-        final ListExpression listExpression = new ListExpression();
-
-        ClassCodeVisitorSupport visitor = new ClassCodeVisitorSupport() {
-            @Override
-            protected SourceUnit getSourceUnit() {
-                return null;
-            }
-
-            @Override
-            public void visitClass(final ClassNode node) {
-                super.visitClass(node);
-                Iterator<InnerClassNode> it = node.getInnerClasses();
-                while (it.hasNext()) {
-                    InnerClassNode next = it.next();
-                    visitClass(next);
-                }
-            }
-
-            @Override
-            public void visitMethodCallExpression(MethodCallExpression call) {
-                super.visitMethodCallExpression(call);
-
-                if (isBuildInvocation(call, MacroTransformation.DOLLAR_VALUE)) {
-                    ClosureExpression substitutionClosureExpression = getClosureArgument(call);
-
-                    if (substitutionClosureExpression == null) {
-                        return;
-                    }
-
-                    Statement code = substitutionClosureExpression.getCode();
-                    if (code instanceof BlockStatement) {
-                        ((BlockStatement) code).setVariableScope(null);
-                    }
-
-                    listExpression.addExpression(substitutionClosureExpression);
-                }
-            }
-        };
-        if (expr instanceof ClassNode) {
-            visitor.visitClass((ClassNode) expr);
-        } else {
-            expr.visit(visitor);
-        }
-        return listExpression;
-    }
-
-    @Override
-    protected boolean isBuildInvocation(MethodCallExpression call) {
-        return isBuildInvocation(call, MacroTransformation.MACRO_METHOD);
-    }
-
-    public static boolean isBuildInvocation(MethodCallExpression call, String methodName) {
-        if (call == null) throw new IllegalArgumentException("Null: call");
-        if (methodName == null) throw new IllegalArgumentException("Null: methodName");
-
-        if (!(call.getMethod() instanceof ConstantExpression)) {
-            return false;
-        }
-
-        if (!(methodName.equals(call.getMethodAsString()))) {
-            return false;
-        }
-
-        // is method object correct type?
-        return call.getObjectExpression() == THIS_EXPRESSION;
-    }
-
-    protected TupleExpression getMacroArguments(MethodCallExpression call) {
-        Expression macroCallArguments = call.getArguments();
-        if (macroCallArguments == null) {
-            addError("Call should have arguments", call);
-            return null;
-        }
-
-        if (!(macroCallArguments instanceof TupleExpression)) {
-            addError("Call should have TupleExpression as arguments", macroCallArguments);
-            return null;
-        }
-
-        TupleExpression tupleArguments = (TupleExpression) macroCallArguments;
-
-        if (tupleArguments.getExpressions() == null) {
-            addError("Call arguments should have expressions", tupleArguments);
-            return null;
-        }
-
-        return tupleArguments;
-    }
-
-    protected ClosureExpression getClosureArgument(MethodCallExpression call) {
-        TupleExpression tupleArguments = getMacroArguments(call);
-
-        if (tupleArguments.getExpressions().size() < 1) {
-            addError("Call arguments should have at least one argument", tupleArguments);
-            return null;
-        }
-
-        Expression result = tupleArguments.getExpression(tupleArguments.getExpressions().size() - 1);
-        if (!(result instanceof ClosureExpression)) {
-            addError("Last call argument should be a closure", result);
-            return null;
-        }
-
-        return (ClosureExpression) result;
-    }
-}

http://git-wip-us.apache.org/repos/asf/groovy/blob/b4e68bd5/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroMethodsCache.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroMethodsCache.java b/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroMethodsCache.java
new file mode 100644
index 0000000..d3e8ed4
--- /dev/null
+++ b/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroMethodsCache.java
@@ -0,0 +1,143 @@
+/*
+ *  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.macro.transform;
+
+import org.codehaus.groovy.ast.ClassHelper;
+import org.codehaus.groovy.ast.ClassNode;
+import org.codehaus.groovy.ast.MethodNode;
+import org.codehaus.groovy.ast.Parameter;
+import org.codehaus.groovy.macro.runtime.Macro;
+import org.codehaus.groovy.runtime.m12n.ExtensionModule;
+import org.codehaus.groovy.runtime.m12n.ExtensionModuleScanner;
+import org.codehaus.groovy.runtime.m12n.MetaInfExtensionModule;
+import org.codehaus.groovy.transform.stc.ExtensionMethodNode;
+
+import java.util.*;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+/**
+ * TODO share some code with {@link org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.ExtensionMethodCache}
+ * @author Sergei Egorov <bs...@gmail.com>
+ */
+class MacroMethodsCache {
+
+    private static final ClassNode MACRO_ANNOTATION_CLASS_NODE = ClassHelper.make(Macro.class);
+
+    private static volatile Map<ClassLoader, Map<String, List<MethodNode>>> CACHE = new WeakHashMap<>();
+
+    private static final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
+
+    public static Map<String, List<MethodNode>> get(ClassLoader classLoader) {
+        try {
+            lock.readLock().lock();
+            if (!CACHE.containsKey(classLoader)) {
+                lock.readLock().unlock();
+                lock.writeLock().lock();
+
+                try {
+                    if (!CACHE.containsKey(classLoader)) {
+                        WeakHashMap<ClassLoader, Map<String, List<MethodNode>>> newCache = new WeakHashMap<>(CACHE);
+
+                        Map<String, List<MethodNode>> methods = getMacroMethodsFromClassLoader(classLoader);
+                        newCache.put(classLoader, methods);
+
+                        CACHE = Collections.unmodifiableMap(newCache);
+                    }
+                } finally {
+                    lock.readLock().lock();
+                    lock.writeLock().unlock();
+                }
+            }
+
+            return CACHE.get(classLoader);
+        } finally {
+            lock.readLock().unlock();
+        }
+    }
+
+    protected static Map<String, List<MethodNode>> getMacroMethodsFromClassLoader(ClassLoader classLoader) {
+        final Map<String, List<MethodNode>> result = new HashMap<String, List<MethodNode>>();
+        ExtensionModuleScanner.ExtensionModuleListener listener = new ExtensionModuleScanner.ExtensionModuleListener() {
+            @Override
+            public void onModule(ExtensionModule module) {
+                if (!(module instanceof MetaInfExtensionModule)) {
+                    return;
+                }
+
+                MetaInfExtensionModule extensionModule = (MetaInfExtensionModule) module;
+
+                scanExtClasses(result, extensionModule.getInstanceMethodsExtensionClasses(), false);
+                scanExtClasses(result, extensionModule.getStaticMethodsExtensionClasses(), true);
+            }
+        };
+
+        ExtensionModuleScanner macroModuleScanner = new ExtensionModuleScanner(listener, classLoader);
+
+        macroModuleScanner.scanClasspathModules();
+
+        for (Map.Entry<String, List<MethodNode>> entry : result.entrySet()) {
+            result.put(entry.getKey(), Collections.unmodifiableList(entry.getValue()));
+        }
+
+        return Collections.unmodifiableMap(result);
+    }
+
+    private static void scanExtClasses(Map<String, List<MethodNode>> accumulator, List<Class> classes, boolean isStatic) {
+        for (Class dgmLikeClass : classes) {
+            ClassNode cn = ClassHelper.makeWithoutCaching(dgmLikeClass, true);
+            for (MethodNode metaMethod : cn.getMethods()) {
+                Parameter[] types = metaMethod.getParameters();
+                if (!(metaMethod.isStatic() && metaMethod.isPublic())) {
+                    continue;
+                }
+
+                if (types.length == 0) {
+                    continue;
+                }
+
+                if (metaMethod.getAnnotations(MACRO_ANNOTATION_CLASS_NODE).isEmpty()) {
+                    continue;
+                }
+
+                Parameter[] parameters = new Parameter[types.length - 1];
+                System.arraycopy(types, 1, parameters, 0, parameters.length);
+                ExtensionMethodNode node = new ExtensionMethodNode(
+                        metaMethod,
+                        metaMethod.getName(),
+                        metaMethod.getModifiers(),
+                        metaMethod.getReturnType(),
+                        parameters,
+                        ClassNode.EMPTY_ARRAY, null,
+                        isStatic);
+                node.setGenericsTypes(metaMethod.getGenericsTypes());
+                ClassNode declaringClass = types[0].getType();
+                node.setDeclaringClass(declaringClass);
+
+                List<MethodNode> macroMethods = accumulator.get(metaMethod.getName());
+
+                if (macroMethods == null) {
+                    macroMethods = new ArrayList<>();
+                    accumulator.put(metaMethod.getName(), macroMethods);
+                }
+
+                macroMethods.add(node);
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/b4e68bd5/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroTransformation.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroTransformation.java b/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroTransformation.java
index 06de16f..84e8d60 100644
--- a/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroTransformation.java
+++ b/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroTransformation.java
@@ -18,42 +18,113 @@
  */
 package org.codehaus.groovy.macro.transform;
 
+import groovy.transform.CompilationUnitAware;
 import org.codehaus.groovy.ast.*;
 import org.codehaus.groovy.ast.expr.*;
+import org.codehaus.groovy.classgen.asm.InvocationWriter;
+import org.codehaus.groovy.control.CompilationUnit;
 import org.codehaus.groovy.control.CompilePhase;
 import org.codehaus.groovy.control.SourceUnit;
+import org.codehaus.groovy.macro.runtime.MacroContext;
+import org.codehaus.groovy.macro.runtime.MacroStub;
+import org.codehaus.groovy.runtime.InvokerHelper;
 import org.codehaus.groovy.transform.GroovyASTTransformation;
+import org.codehaus.groovy.transform.stc.ExtensionMethodNode;
+import org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport;
+
+import java.util.ArrayList;
+import java.util.List;
 
 /**
- *
  * @author Sergei Egorov <bs...@gmail.com>
  */
 
 @GroovyASTTransformation(phase = CompilePhase.CONVERSION)
-public class MacroTransformation extends MethodCallTransformation {
+public class MacroTransformation extends MethodCallTransformation implements CompilationUnitAware {
+
+    private static final ClassNode MACRO_CONTEXT_CLASS_NODE = ClassHelper.make(MacroContext.class);
+
+    private static final ClassNode MACRO_STUB_CLASS_NODE = ClassHelper.make(MacroStub.class);
+
+    private static final PropertyExpression MACRO_STUB_INSTANCE = new PropertyExpression(new ClassExpression(MACRO_STUB_CLASS_NODE), "INSTANCE");
+
+    private static final String MACRO_STUB_METHOD_NAME = "macroMethod";
+
+    protected CompilationUnit unit;
 
-    public static final String DOLLAR_VALUE = "$v";
-    public static final String MACRO_METHOD = "macro";
+    @Override
+    public void setCompilationUnit(CompilationUnit unit) {
+        this.unit = unit;
+    }
 
     @Override
-    protected GroovyCodeVisitor getTransformer(final ASTNode[] nodes, final SourceUnit sourceUnit) {
-        final ClassCodeExpressionTransformer trn = new ClassCodeExpressionTransformer() {
+    protected GroovyCodeVisitor getTransformer(ASTNode[] nodes, final SourceUnit sourceUnit) {
+        // Macro methods should on a classpath of the compiler because we invoke them during the compilation
+        final ClassLoader classLoader = this.getClass().getClassLoader();
+        return new ClassCodeVisitorSupport() {
+
             @Override
             protected SourceUnit getSourceUnit() {
                 return sourceUnit;
             }
 
             @Override
-            public Expression transform(final Expression exp) {
-                if (exp instanceof ConstructorCallExpression) {
-                    MethodCallExpression call = exp.getNodeMetaData(MacroTransformation.class);
-                    if (call!=null) {
-                        return call;
+            public void visitMethodCallExpression(MethodCallExpression call) {
+                super.visitMethodCallExpression(call);
+
+                List<MethodNode> methods = MacroMethodsCache.get(classLoader).get(call.getMethodAsString());
+
+                if (methods == null) {
+                    // Not a macro call
+                    return;
+                }
+
+                List<Expression> callArguments = InvocationWriter.makeArgumentList(call.getArguments()).getExpressions();
+
+                ClassNode[] argumentsList = new ClassNode[callArguments.size()];
+
+                for (int i = 0; i < callArguments.size(); i++) {
+                    argumentsList[i] = ClassHelper.make(callArguments.get(i).getClass());
+                }
+
+                methods = StaticTypeCheckingSupport.chooseBestMethod(MACRO_CONTEXT_CLASS_NODE, methods, argumentsList);
+
+                for (MethodNode macroMethodNode : methods) {
+                    if (!(macroMethodNode instanceof ExtensionMethodNode)) {
+                        // TODO is it even possible?
+                        continue;
+                    }
+
+                    MethodNode macroExtensionMethodNode = ((ExtensionMethodNode) macroMethodNode).getExtensionMethodNode();
+
+                    final Class clazz;
+                    try {
+                        clazz = classLoader.loadClass(macroExtensionMethodNode.getDeclaringClass().getName());
+                    } catch (ClassNotFoundException e) {
+                        //TODO different reaction?
+                        continue;
                     }
+
+                    MacroContext macroContext = new MacroContext(unit, sourceUnit, call);
+
+                    List<Object> macroArguments = new ArrayList<>();
+                    macroArguments.add(macroContext);
+                    macroArguments.addAll(callArguments);
+
+                    Expression result = (Expression) InvokerHelper.invokeStaticMethod(clazz, macroMethodNode.getName(), macroArguments.toArray());
+
+                    call.setObjectExpression(MACRO_STUB_INSTANCE);
+                    call.setMethod(new ConstantExpression(MACRO_STUB_METHOD_NAME));
+
+                    // TODO check that we reset everything here
+                    call.setSpreadSafe(false);
+                    call.setSafe(false);
+                    call.setImplicitThis(false);
+                    call.setArguments(result);
+
+                    break;
                 }
-                return super.transform(exp);
             }
         };
-        return new TransformingMacroTrap(sourceUnit, trn);
     }
 }

http://git-wip-us.apache.org/repos/asf/groovy/blob/b4e68bd5/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/TransformingMacroTrap.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/TransformingMacroTrap.java b/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/TransformingMacroTrap.java
deleted file mode 100644
index f16e47a..0000000
--- a/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/TransformingMacroTrap.java
+++ /dev/null
@@ -1,343 +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.macro.transform;
-
-import org.codehaus.groovy.ast.ClassCodeExpressionTransformer;
-import org.codehaus.groovy.ast.expr.*;
-import org.codehaus.groovy.ast.stmt.AssertStatement;
-import org.codehaus.groovy.ast.stmt.BlockStatement;
-import org.codehaus.groovy.ast.stmt.BreakStatement;
-import org.codehaus.groovy.ast.stmt.CaseStatement;
-import org.codehaus.groovy.ast.stmt.CatchStatement;
-import org.codehaus.groovy.ast.stmt.ContinueStatement;
-import org.codehaus.groovy.ast.stmt.DoWhileStatement;
-import org.codehaus.groovy.ast.stmt.ExpressionStatement;
-import org.codehaus.groovy.ast.stmt.ForStatement;
-import org.codehaus.groovy.ast.stmt.IfStatement;
-import org.codehaus.groovy.ast.stmt.ReturnStatement;
-import org.codehaus.groovy.ast.stmt.SwitchStatement;
-import org.codehaus.groovy.ast.stmt.SynchronizedStatement;
-import org.codehaus.groovy.ast.stmt.ThrowStatement;
-import org.codehaus.groovy.ast.stmt.TryCatchStatement;
-import org.codehaus.groovy.ast.stmt.WhileStatement;
-import org.codehaus.groovy.classgen.BytecodeExpression;
-import org.codehaus.groovy.control.SourceUnit;
-
-class TransformingMacroTrap extends MacroInvocationTrap {
-    private final ClassCodeExpressionTransformer trn;
-
-    public TransformingMacroTrap(final SourceUnit sourceUnit, final ClassCodeExpressionTransformer trn) {
-        super(sourceUnit.getSource(), sourceUnit);
-        this.trn = trn;
-    }
-
-    @Override
-    public void visitBlockStatement(final BlockStatement block) {
-        super.visitBlockStatement(block);
-        trn.visitBlockStatement(block);
-    }
-
-    @Override
-    public void visitForLoop(final ForStatement forLoop) {
-        super.visitForLoop(forLoop);
-        trn.visitForLoop(forLoop);
-    }
-
-    @Override
-    public void visitWhileLoop(final WhileStatement loop) {
-        super.visitWhileLoop(loop);
-        trn.visitWhileLoop(loop);
-    }
-
-    @Override
-    public void visitDoWhileLoop(final DoWhileStatement loop) {
-        super.visitDoWhileLoop(loop);
-        trn.visitDoWhileLoop(loop);
-    }
-
-    @Override
-    public void visitIfElse(final IfStatement ifElse) {
-        super.visitIfElse(ifElse);
-        trn.visitIfElse(ifElse);
-    }
-
-    @Override
-    public void visitExpressionStatement(final ExpressionStatement statement) {
-        super.visitExpressionStatement(statement);
-        trn.visitExpressionStatement(statement);
-    }
-
-    @Override
-    public void visitReturnStatement(final ReturnStatement statement) {
-        super.visitReturnStatement(statement);
-        trn.visitReturnStatement(statement);
-    }
-
-    @Override
-    public void visitAssertStatement(final AssertStatement statement) {
-        super.visitAssertStatement(statement);
-        trn.visitAssertStatement(statement);
-    }
-
-    @Override
-    public void visitTryCatchFinally(final TryCatchStatement statement) {
-        super.visitTryCatchFinally(statement);
-        trn.visitTryCatchFinally(statement);
-    }
-
-    @Override
-    public void visitSwitch(final SwitchStatement statement) {
-        super.visitSwitch(statement);
-        trn.visitSwitch(statement);
-    }
-
-    @Override
-    public void visitCaseStatement(final CaseStatement statement) {
-        super.visitCaseStatement(statement);
-        trn.visitCaseStatement(statement);
-    }
-
-    @Override
-    public void visitBreakStatement(final BreakStatement statement) {
-        super.visitBreakStatement(statement);
-        trn.visitBreakStatement(statement);
-    }
-
-    @Override
-    public void visitContinueStatement(final ContinueStatement statement) {
-        super.visitContinueStatement(statement);
-        trn.visitContinueStatement(statement);
-    }
-
-    @Override
-    public void visitSynchronizedStatement(final SynchronizedStatement statement) {
-        super.visitSynchronizedStatement(statement);
-        trn.visitSynchronizedStatement(statement);
-    }
-
-    @Override
-    public void visitThrowStatement(final ThrowStatement statement) {
-        super.visitThrowStatement(statement);
-        trn.visitThrowStatement(statement);
-    }
-
-    @Override
-    public void visitStaticMethodCallExpression(final StaticMethodCallExpression call) {
-        super.visitStaticMethodCallExpression(call);
-        trn.visitStaticMethodCallExpression(call);
-    }
-
-    @Override
-    public void visitBinaryExpression(final BinaryExpression expression) {
-        super.visitBinaryExpression(expression);
-        trn.visitBinaryExpression(expression);
-    }
-
-    @Override
-    public void visitTernaryExpression(final TernaryExpression expression) {
-        super.visitTernaryExpression(expression);
-        trn.visitTernaryExpression(expression);
-    }
-
-    @Override
-    public void visitShortTernaryExpression(final ElvisOperatorExpression expression) {
-        super.visitShortTernaryExpression(expression);
-        trn.visitShortTernaryExpression(expression);
-    }
-
-    @Override
-    public void visitPostfixExpression(final PostfixExpression expression) {
-        super.visitPostfixExpression(expression);
-        trn.visitPostfixExpression(expression);
-    }
-
-    @Override
-    public void visitPrefixExpression(final PrefixExpression expression) {
-        super.visitPrefixExpression(expression);
-        trn.visitPrefixExpression(expression);
-    }
-
-    @Override
-    public void visitBooleanExpression(final BooleanExpression expression) {
-        super.visitBooleanExpression(expression);
-        trn.visitBooleanExpression(expression);
-    }
-
-    @Override
-    public void visitNotExpression(final NotExpression expression) {
-        super.visitNotExpression(expression);
-        trn.visitNotExpression(expression);
-    }
-
-    @Override
-    public void visitClosureExpression(final ClosureExpression expression) {
-        super.visitClosureExpression(expression);
-        trn.visitClosureExpression(expression);
-    }
-
-    @Override
-    public void visitTupleExpression(final TupleExpression expression) {
-        super.visitTupleExpression(expression);
-        trn.visitTupleExpression(expression);
-    }
-
-    @Override
-    public void visitListExpression(final ListExpression expression) {
-        super.visitListExpression(expression);
-        trn.visitListExpression(expression);
-    }
-
-    @Override
-    public void visitArrayExpression(final ArrayExpression expression) {
-        super.visitArrayExpression(expression);
-        trn.visitArrayExpression(expression);
-    }
-
-    @Override
-    public void visitMapExpression(final MapExpression expression) {
-        super.visitMapExpression(expression);
-        trn.visitMapExpression(expression);
-    }
-
-    @Override
-    public void visitMapEntryExpression(final MapEntryExpression expression) {
-        super.visitMapEntryExpression(expression);
-        trn.visitMapEntryExpression(expression);
-    }
-
-    @Override
-    public void visitRangeExpression(final RangeExpression expression) {
-        super.visitRangeExpression(expression);
-        trn.visitRangeExpression(expression);
-    }
-
-    @Override
-    public void visitSpreadExpression(final SpreadExpression expression) {
-        super.visitSpreadExpression(expression);
-        trn.visitSpreadExpression(expression);
-    }
-
-    @Override
-    public void visitSpreadMapExpression(final SpreadMapExpression expression) {
-        super.visitSpreadMapExpression(expression);
-        trn.visitSpreadMapExpression(expression);
-    }
-
-    @Override
-    public void visitMethodPointerExpression(final MethodPointerExpression expression) {
-        super.visitMethodPointerExpression(expression);
-        trn.visitMethodPointerExpression(expression);
-    }
-
-    @Override
-    public void visitUnaryMinusExpression(final UnaryMinusExpression expression) {
-        super.visitUnaryMinusExpression(expression);
-        trn.visitUnaryMinusExpression(expression);
-    }
-
-    @Override
-    public void visitUnaryPlusExpression(final UnaryPlusExpression expression) {
-        super.visitUnaryPlusExpression(expression);
-        trn.visitUnaryPlusExpression(expression);
-    }
-
-    @Override
-    public void visitBitwiseNegationExpression(final BitwiseNegationExpression expression) {
-        super.visitBitwiseNegationExpression(expression);
-        trn.visitBitwiseNegationExpression(expression);
-    }
-
-    @Override
-    public void visitCastExpression(final CastExpression expression) {
-        super.visitCastExpression(expression);
-        trn.visitCastExpression(expression);
-    }
-
-    @Override
-    public void visitConstantExpression(final ConstantExpression expression) {
-        super.visitConstantExpression(expression);
-        trn.visitConstantExpression(expression);
-    }
-
-    @Override
-    public void visitClassExpression(final ClassExpression expression) {
-        super.visitClassExpression(expression);
-        trn.visitClassExpression(expression);
-    }
-
-    @Override
-    public void visitVariableExpression(final VariableExpression expression) {
-        super.visitVariableExpression(expression);
-        trn.visitVariableExpression(expression);
-    }
-
-    @Override
-    public void visitDeclarationExpression(final DeclarationExpression expression) {
-        super.visitDeclarationExpression(expression);
-        trn.visitDeclarationExpression(expression);
-    }
-
-    @Override
-    public void visitPropertyExpression(final PropertyExpression expression) {
-        super.visitPropertyExpression(expression);
-        trn.visitPropertyExpression(expression);
-    }
-
-    @Override
-    public void visitAttributeExpression(final AttributeExpression expression) {
-        super.visitAttributeExpression(expression);
-        trn.visitAttributeExpression(expression);
-    }
-
-    @Override
-    public void visitFieldExpression(final FieldExpression expression) {
-        super.visitFieldExpression(expression);
-        trn.visitFieldExpression(expression);
-    }
-
-    @Override
-    public void visitGStringExpression(final GStringExpression expression) {
-        super.visitGStringExpression(expression);
-        trn.visitGStringExpression(expression);
-    }
-
-    @Override
-    public void visitCatchStatement(final CatchStatement statement) {
-        super.visitCatchStatement(statement);
-        trn.visitCatchStatement(statement);
-    }
-
-    @Override
-    public void visitArgumentlistExpression(final ArgumentListExpression ale) {
-        super.visitArgumentlistExpression(ale);
-        trn.visitArgumentlistExpression(ale);
-    }
-
-    @Override
-    public void visitClosureListExpression(final ClosureListExpression cle) {
-        super.visitClosureListExpression(cle);
-        trn.visitClosureListExpression(cle);
-    }
-
-    @Override
-    public void visitBytecodeExpression(final BytecodeExpression cle) {
-        super.visitBytecodeExpression(cle);
-        trn.visitBytecodeExpression(cle);
-    }
-}

http://git-wip-us.apache.org/repos/asf/groovy/blob/b4e68bd5/subprojects/groovy-macro/src/main/resources/META-INF/services/org.codehaus.groovy.runtime.ExtensionModule
----------------------------------------------------------------------
diff --git a/subprojects/groovy-macro/src/main/resources/META-INF/services/org.codehaus.groovy.runtime.ExtensionModule b/subprojects/groovy-macro/src/main/resources/META-INF/services/org.codehaus.groovy.runtime.ExtensionModule
new file mode 100644
index 0000000..2d10063
--- /dev/null
+++ b/subprojects/groovy-macro/src/main/resources/META-INF/services/org.codehaus.groovy.runtime.ExtensionModule
@@ -0,0 +1,17 @@
+# 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.
+moduleName=macro-module
+moduleVersion=1.0
+extensionClasses=org.codehaus.groovy.macro.methods.MacroGroovyMethods

http://git-wip-us.apache.org/repos/asf/groovy/blob/b4e68bd5/subprojects/groovy-macro/src/main/resources/META-INF/services/org.codehaus.groovy.transform.ASTTransformation
----------------------------------------------------------------------
diff --git a/subprojects/groovy-macro/src/main/resources/META-INF/services/org.codehaus.groovy.transform.ASTTransformation b/subprojects/groovy-macro/src/main/resources/META-INF/services/org.codehaus.groovy.transform.ASTTransformation
index c2ef479..e080e18 100644
--- a/subprojects/groovy-macro/src/main/resources/META-INF/services/org.codehaus.groovy.transform.ASTTransformation
+++ b/subprojects/groovy-macro/src/main/resources/META-INF/services/org.codehaus.groovy.transform.ASTTransformation
@@ -15,3 +15,4 @@
 
 #global transformation for macro support
 org.codehaus.groovy.macro.transform.MacroTransformation
+org.codehaus.groovy.macro.transform.MacroClassTransformation

http://git-wip-us.apache.org/repos/asf/groovy/blob/b4e68bd5/subprojects/groovy-macro/src/test/groovy/org/codehaus/groovy/macro/ExampleMacroMethods.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-macro/src/test/groovy/org/codehaus/groovy/macro/ExampleMacroMethods.java b/subprojects/groovy-macro/src/test/groovy/org/codehaus/groovy/macro/ExampleMacroMethods.java
new file mode 100644
index 0000000..3b32ab8
--- /dev/null
+++ b/subprojects/groovy-macro/src/test/groovy/org/codehaus/groovy/macro/ExampleMacroMethods.java
@@ -0,0 +1,34 @@
+package org.codehaus.groovy.macro;
+
+import org.codehaus.groovy.ast.expr.*;
+import org.codehaus.groovy.macro.runtime.Macro;
+import org.codehaus.groovy.macro.runtime.MacroContext;
+
+import static org.codehaus.groovy.ast.tools.GeneralUtils.*;
+
+public class ExampleMacroMethods {
+
+    @Macro
+    public static Expression safe(MacroContext macroContext, MethodCallExpression callExpression) {
+        return ternaryX(
+                notNullX(callExpression.getObjectExpression()),
+                callExpression,
+                constX(null)
+        );
+    }
+
+    @Macro
+    public static ConstantExpression methodName(MacroContext macroContext, MethodCallExpression callExpression) {
+        return constX(callExpression.getMethodAsString());
+    }
+
+    @Macro
+    public static ConstantExpression methodName(MacroContext macroContext, MethodPointerExpression methodPointerExpression) {
+        return constX(methodPointerExpression.getMethodName().getText());
+    }
+
+    @Macro
+    public static ConstantExpression propertyName(MacroContext macroContext, PropertyExpression propertyExpression) {
+        return constX(propertyExpression.getPropertyAsString());
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/b4e68bd5/subprojects/groovy-macro/src/test/groovy/org/codehaus/groovy/macro/MacroTest.groovy
----------------------------------------------------------------------
diff --git a/subprojects/groovy-macro/src/test/groovy/org/codehaus/groovy/macro/MacroTest.groovy b/subprojects/groovy-macro/src/test/groovy/org/codehaus/groovy/macro/MacroTest.groovy
index 1febbfa..69139b2 100644
--- a/subprojects/groovy-macro/src/test/groovy/org/codehaus/groovy/macro/MacroTest.groovy
+++ b/subprojects/groovy-macro/src/test/groovy/org/codehaus/groovy/macro/MacroTest.groovy
@@ -209,4 +209,19 @@ class MacroTest extends GroovyTestCase {
         AstAssert.assertSyntaxTree([expected], [result])
 '''
     }
+
+    void testMacroClass() {
+        assertScript '''
+        import org.codehaus.groovy.ast.ClassNode
+        import org.codehaus.groovy.macro.transform.MacroClass
+
+        def ast1 = new MacroClass() {
+            class A { String str }
+        }
+
+        assert ast1.getClass() == ClassNode
+        assert ast1.name == "A"
+        assert ast1.getField("str") != null
+'''
+    }
 }


[09/50] [abbrv] groovy git commit: groovy 7909 bug

Posted by su...@apache.org.
groovy 7909 bug


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

Branch: refs/heads/parrot
Commit: 64d4f844ce60374749d5f5adb3d4075d7165acc4
Parents: 4382195
Author: zhangbo <zh...@nanchao.org>
Authored: Mon Sep 26 10:29:16 2016 +0800
Committer: paulk <pa...@asert.com.au>
Committed: Wed Mar 8 17:49:59 2017 +1000

----------------------------------------------------------------------
 .../trait/SuperCallTraitTransformer.java        | 83 ++++++++++++++------
 .../transform/trait/TraitASTTransformation.java | 23 +++++-
 src/test/groovy/bugs/Groovy7909Bug.groovy       | 58 ++++++++++++++
 3 files changed, 137 insertions(+), 27 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/64d4f844/src/main/org/codehaus/groovy/transform/trait/SuperCallTraitTransformer.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/transform/trait/SuperCallTraitTransformer.java b/src/main/org/codehaus/groovy/transform/trait/SuperCallTraitTransformer.java
index f3d35d8..2972c72 100644
--- a/src/main/org/codehaus/groovy/transform/trait/SuperCallTraitTransformer.java
+++ b/src/main/org/codehaus/groovy/transform/trait/SuperCallTraitTransformer.java
@@ -21,7 +21,9 @@ package org.codehaus.groovy.transform.trait;
 import groovy.lang.MetaProperty;
 import java.util.List;
 import org.codehaus.groovy.ast.ClassCodeExpressionTransformer;
+import org.codehaus.groovy.ast.ClassHelper;
 import org.codehaus.groovy.ast.ClassNode;
+import org.codehaus.groovy.ast.InnerClassNode;
 import org.codehaus.groovy.ast.MethodNode;
 import org.codehaus.groovy.ast.Parameter;
 import org.codehaus.groovy.ast.expr.ArgumentListExpression;
@@ -35,6 +37,11 @@ import org.codehaus.groovy.ast.expr.VariableExpression;
 import org.codehaus.groovy.control.SourceUnit;
 import org.codehaus.groovy.syntax.Types;
 
+import static org.objectweb.asm.Opcodes.ACC_ABSTRACT;
+import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
+import static org.objectweb.asm.Opcodes.ACC_STATIC;
+import static org.objectweb.asm.Opcodes.ACC_SYNTHETIC;
+
 /**
  * This transformer is used to transform calls to <code>SomeTrait.super.foo()</code> into the appropriate trait call.
  *
@@ -42,6 +49,7 @@ import org.codehaus.groovy.syntax.Types;
  * @since 2.3.0
  */
 class SuperCallTraitTransformer extends ClassCodeExpressionTransformer {
+    public static final String UNRESOLVED_HELPER_CLASS = "UNRESOLVED_HELPER_CLASS";
     private final SourceUnit unit;
 
     SuperCallTraitTransformer(final SourceUnit unit) {
@@ -111,36 +119,63 @@ class SuperCallTraitTransformer extends ClassCodeExpressionTransformer {
             Expression objectExpression = exp.getObjectExpression();
             ClassNode traitReceiver = ((PropertyExpression) objectExpression).getObjectExpression().getType();
 
-            TraitHelpersTuple helpers = Traits.findHelpers(traitReceiver);
-            // (SomeTrait.super).foo() --> SomeTrait$Helper.foo(this)
-            ClassExpression receiver = new ClassExpression(
-                    helpers.getHelper()
-            );
-            ArgumentListExpression newArgs = new ArgumentListExpression();
-            Expression arguments = exp.getArguments();
-            newArgs.addExpression(new VariableExpression("this"));
-            if (arguments instanceof TupleExpression) {
-                List<Expression> expressions = ((TupleExpression) arguments).getExpressions();
-                for (Expression expression : expressions) {
-                    newArgs.addExpression(transform(expression));
+            if (traitReceiver != null) {
+                // (SomeTrait.super).foo() --> SomeTrait$Helper.foo(this)
+                ClassExpression receiver = new ClassExpression(
+                        getHelper(traitReceiver)
+                );
+                ArgumentListExpression newArgs = new ArgumentListExpression();
+                Expression arguments = exp.getArguments();
+                newArgs.addExpression(new VariableExpression("this"));
+                if (arguments instanceof TupleExpression) {
+                    List<Expression> expressions = ((TupleExpression) arguments).getExpressions();
+                    for (Expression expression : expressions) {
+                        newArgs.addExpression(transform(expression));
+                    }
+                } else {
+                    newArgs.addExpression(transform(arguments));
                 }
-            } else {
-                newArgs.addExpression(transform(arguments));
+                MethodCallExpression result = new MethodCallExpression(
+                        receiver,
+                        transform(exp.getMethod()),
+                        newArgs
+                );
+                result.setImplicitThis(false);
+                result.setSpreadSafe(exp.isSpreadSafe());
+                result.setSafe(exp.isSafe());
+                result.setSourcePosition(exp);
+                return result;
             }
-            MethodCallExpression result = new MethodCallExpression(
-                    receiver,
-                    transform(exp.getMethod()),
-                    newArgs
-            );
-            result.setImplicitThis(false);
-            result.setSpreadSafe(exp.isSpreadSafe());
-            result.setSafe(exp.isSafe());
-            result.setSourcePosition(exp);
-            return result;
         }
         return super.transform(exp);
     }
 
+    private ClassNode getHelper(final ClassNode traitReceiver) {
+        if (helperClassNotCreatedYet(traitReceiver)) {
+            // GROOVY-7909 A Helper class in same compilation unit may have not been created when referenced
+            // Here create a symbol as a "placeholder" and it will be resolved later.
+            ClassNode ret = new InnerClassNode(
+                    traitReceiver,
+                    Traits.helperClassName(traitReceiver),
+                    ACC_PUBLIC | ACC_STATIC | ACC_ABSTRACT | ACC_SYNTHETIC,
+                    ClassHelper.OBJECT_TYPE,
+                    ClassNode.EMPTY_ARRAY,
+                    null
+            ).getPlainNodeReference();
+
+            ret.setRedirect(null);
+            traitReceiver.redirect().setNodeMetaData(UNRESOLVED_HELPER_CLASS, ret);
+            return ret;
+        } else {
+            TraitHelpersTuple helpers = Traits.findHelpers(traitReceiver);
+            return helpers.getHelper();
+        }
+    }
+
+    private boolean helperClassNotCreatedYet(final ClassNode traitReceiver) {
+        return !traitReceiver.redirect().getInnerClasses().hasNext()
+                && this.unit.getAST().getClasses().contains(traitReceiver.redirect());
+    }
     private boolean isTraitSuperPropertyExpression(Expression exp) {
         if (exp instanceof PropertyExpression) {
             PropertyExpression pexp = (PropertyExpression) exp;

http://git-wip-us.apache.org/repos/asf/groovy/blob/64d4f844/src/main/org/codehaus/groovy/transform/trait/TraitASTTransformation.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/transform/trait/TraitASTTransformation.java b/src/main/org/codehaus/groovy/transform/trait/TraitASTTransformation.java
index da71e9e..053ac42 100644
--- a/src/main/org/codehaus/groovy/transform/trait/TraitASTTransformation.java
+++ b/src/main/org/codehaus/groovy/transform/trait/TraitASTTransformation.java
@@ -70,6 +70,8 @@ import java.util.Set;
 
 import static org.codehaus.groovy.ast.tools.GeneralUtils.returnS;
 
+import static org.codehaus.groovy.transform.trait.SuperCallTraitTransformer.UNRESOLVED_HELPER_CLASS;
+
 /**
  * Handles generation of code for the @Trait annotation. A class annotated with @Trait will generate, instead: <ul>
  * <li>an <i>interface</i> with the same name</li> <li>an utility inner class that will be used by the compiler to
@@ -103,7 +105,21 @@ public class TraitASTTransformation extends AbstractASTTransformation implements
             checkExtendsClause(cNode);
             generateMethodsWithDefaultArgs(cNode);
             replaceExtendsByImplements(cNode);
-            createHelperClass(cNode);
+            ClassNode helperClassNode = createHelperClass(cNode);
+            resolveHelperClassIfNecessary(helperClassNode);
+        }
+    }
+
+    private void resolveHelperClassIfNecessary(final ClassNode helperClassNode) {
+        if (helperClassNode == null) {
+            return;
+        }
+        for (ClassNode cNode : unit.getAST().getClasses()) {
+            ClassNode unresolvedHelperNode = cNode.getNodeMetaData(UNRESOLVED_HELPER_CLASS);
+            if (unresolvedHelperNode != null
+                    && unresolvedHelperNode.getName().equals(helperClassNode.getName())) {
+                unresolvedHelperNode.setRedirect(helperClassNode);
+            }
         }
     }
 
@@ -143,7 +159,7 @@ public class TraitASTTransformation extends AbstractASTTransformation implements
         }
     }
 
-    private void createHelperClass(final ClassNode cNode) {
+    private ClassNode createHelperClass(final ClassNode cNode) {
         ClassNode helper = new InnerClassNode(
                 cNode,
                 Traits.helperClassName(cNode),
@@ -190,7 +206,7 @@ public class TraitASTTransformation extends AbstractASTTransformation implements
                 if (!methodNode.isSynthetic() && (methodNode.isProtected() || methodNode.getModifiers()==0)) {
                     unit.addError(new SyntaxException("Cannot have protected/package private method in a trait (" + cNode.getName() + "#" + methodNode.getTypeDescriptor() + ")",
                             methodNode.getLineNumber(), methodNode.getColumnNumber()));
-                    return;
+                    return null;
                 }
                 helper.addMethod(processMethod(cNode, helper, methodNode, fieldHelper, fieldNames));
                 if (methodNode.isPrivate() || methodNode.isStatic()) {
@@ -233,6 +249,7 @@ public class TraitASTTransformation extends AbstractASTTransformation implements
         if (fieldHelper!=null) {
             resolveScope(fieldHelper);
         }
+        return helper;
     }
 
     private static MethodNode createInitMethod(final boolean isStatic, final ClassNode cNode, final ClassNode helper) {

http://git-wip-us.apache.org/repos/asf/groovy/blob/64d4f844/src/test/groovy/bugs/Groovy7909Bug.groovy
----------------------------------------------------------------------
diff --git a/src/test/groovy/bugs/Groovy7909Bug.groovy b/src/test/groovy/bugs/Groovy7909Bug.groovy
new file mode 100644
index 0000000..b1e1f97
--- /dev/null
+++ b/src/test/groovy/bugs/Groovy7909Bug.groovy
@@ -0,0 +1,58 @@
+package groovy.bugs
+
+import gls.CompilableTestSupport
+
+class Groovy7909Bug extends CompilableTestSupport {
+    void testDynamicCompile(){
+        shouldCompile '''
+trait Three implements One, Two {
+    def postMake() {
+        One.super.postMake()
+        Two.super.postMake()
+        println "Three"
+    }
+}
+trait One {
+    def postMake() { println "One"}
+}
+trait Two {
+    def postMake() { println "Two"}
+}
+class Four implements Three {
+    def make() {
+        Three.super.postMake()
+        println "All done?"
+    }
+}
+Four f = new Four()
+f.make()
+    '''
+    }
+    void testStaticCompile(){
+        shouldCompile '''
+@groovy.transform.CompileStatic
+trait Three implements One, Two {
+    def postMake() {
+        One.super.postMake()
+        Two.super.postMake()
+        println "Three"
+    }
+}
+trait One {
+    def postMake() { println "One"}
+}
+trait Two {
+    def postMake() { println "Two"}
+}
+class Four implements Three {
+    def make() {
+        Three.super.postMake()
+        println "All done?"
+    }
+}
+Four f = new Four()
+f.make()
+    '''
+    }
+}
+


[15/50] [abbrv] groovy git commit: GROOVY-6792: ClassFormatError if a method has dots within its name (enable only with system property for now)

Posted by su...@apache.org.
GROOVY-6792: ClassFormatError if a method has dots within its name (enable only with system property for now)


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

Branch: refs/heads/parrot
Commit: 73db9a7a75586e5cb17348c4d6108768798c2c7a
Parents: b842d1b
Author: paulk <pa...@asert.com.au>
Authored: Tue Mar 14 20:54:41 2017 +1000
Committer: paulk <pa...@asert.com.au>
Committed: Tue Mar 14 20:54:41 2017 +1000

----------------------------------------------------------------------
 .../codehaus/groovy/classgen/ClassCompletionVerifier.java    | 3 +++
 src/test/groovy/bugs/Groovy6792Bug.groovy                    | 8 ++++++++
 2 files changed, 11 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/73db9a7a/src/main/org/codehaus/groovy/classgen/ClassCompletionVerifier.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/classgen/ClassCompletionVerifier.java b/src/main/org/codehaus/groovy/classgen/ClassCompletionVerifier.java
index aba375a..c2da690 100644
--- a/src/main/org/codehaus/groovy/classgen/ClassCompletionVerifier.java
+++ b/src/main/org/codehaus/groovy/classgen/ClassCompletionVerifier.java
@@ -55,6 +55,8 @@ import static org.objectweb.asm.Opcodes.*;
  */
 public class ClassCompletionVerifier extends ClassCodeVisitorSupport {
     private static final String[] INVALID_NAME_CHARS = {".", ":", "/", ";", "[", "<", ">"};
+    // the groovy.compiler.strictNames system property is experimental and may change default value or be removed in a future version of Groovy
+    private final boolean strictNames = Boolean.parseBoolean(System.getProperty("groovy.compiler.strictNames", "false"));
     private ClassNode currentClass;
     private final SourceUnit source;
     private boolean inConstructor = false;
@@ -291,6 +293,7 @@ public class ClassCompletionVerifier extends ClassCodeVisitorSupport {
     }
 
     private void checkMethodsForIncorrectName(ClassNode cn) {
+        if (!strictNames) return;
         List<MethodNode> methods = cn.getAllDeclaredMethods();
         for (MethodNode mNode : methods) {
             String name = mNode.getName();

http://git-wip-us.apache.org/repos/asf/groovy/blob/73db9a7a/src/test/groovy/bugs/Groovy6792Bug.groovy
----------------------------------------------------------------------
diff --git a/src/test/groovy/bugs/Groovy6792Bug.groovy b/src/test/groovy/bugs/Groovy6792Bug.groovy
index 9223174..53bfd4e 100644
--- a/src/test/groovy/bugs/Groovy6792Bug.groovy
+++ b/src/test/groovy/bugs/Groovy6792Bug.groovy
@@ -31,6 +31,8 @@ class Groovy6792Bug extends CompilableTestSupport {
     }
 
     void testMethodWithInvalidName() {
+        // currently groovy.compiler.strictNames is experimental
+        System.setProperty('groovy.compiler.strictNames', 'true')
         def message = shouldNotCompile """
             class Foo {
                 def "bar.baz"(){}
@@ -38,4 +40,10 @@ class Groovy6792Bug extends CompilableTestSupport {
         """
         assert message.contains("You are not allowed to have '.' in a method name")
     }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown()
+        System.setProperty('groovy.compiler.strictNames', 'false')
+    }
 }


[46/50] [abbrv] groovy git commit: Update of a documentation issue (closes #519)

Posted by su...@apache.org.
Update of a documentation issue (closes #519)


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

Branch: refs/heads/parrot
Commit: 752341d7dcaf996ec1a0e941df754045eb555e59
Parents: 68acdae
Author: Geoffrey Alexandre <py...@gmail.com>
Authored: Sat Apr 1 11:50:20 2017 +0100
Committer: John Wagenleitner <jw...@apache.org>
Committed: Sat Apr 1 10:29:12 2017 -0700

----------------------------------------------------------------------
 subprojects/groovy-xml/src/spec/doc/xml-userguide.adoc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/752341d7/subprojects/groovy-xml/src/spec/doc/xml-userguide.adoc
----------------------------------------------------------------------
diff --git a/subprojects/groovy-xml/src/spec/doc/xml-userguide.adoc b/subprojects/groovy-xml/src/spec/doc/xml-userguide.adoc
index 4c78022..ec98d16 100644
--- a/subprojects/groovy-xml/src/spec/doc/xml-userguide.adoc
+++ b/subprojects/groovy-xml/src/spec/doc/xml-userguide.adoc
@@ -112,7 +112,7 @@ Having a XML like the following:
 include::{rootProjectDir}/subprojects/groovy-xml/src/spec/test/UserGuideDOMCategory.groovy[tags=testXML,indent=0]
 ----
 
-You can parse it using 'groovy.xml.DOMBuilder` and
+You can parse it using `groovy.xml.DOMBuilder` and
 `groovy.xml.dom.DOMCategory`.
 
 [source,groovy]


[32/50] [abbrv] groovy git commit: Fix typo

Posted by su...@apache.org.
Fix typo


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

Branch: refs/heads/parrot
Commit: 5e4c92ff7965f4922ca173919599317a2e01d2aa
Parents: 091a8b7
Author: John Wagenleitner <jw...@apache.org>
Authored: Sun Mar 26 13:23:51 2017 -0700
Committer: John Wagenleitner <jw...@apache.org>
Committed: Sun Mar 26 13:23:51 2017 -0700

----------------------------------------------------------------------
 src/spec/doc/working-with-collections.adoc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/5e4c92ff/src/spec/doc/working-with-collections.adoc
----------------------------------------------------------------------
diff --git a/src/spec/doc/working-with-collections.adoc b/src/spec/doc/working-with-collections.adoc
index ace44ed..0153983 100644
--- a/src/spec/doc/working-with-collections.adoc
+++ b/src/spec/doc/working-with-collections.adoc
@@ -146,7 +146,7 @@ include::{projectdir}/src/spec/test/gdk/WorkingWithCollectionsTest.groovy[tags=l
 ----------------------------------------------------------------------------
 
 In case you only want to remove the first element having the same value in a list, instead of removing all
-elements, you call call the `remove` method passing the value:
+elements, you can call the `remove` method passing the value:
 
 [source,groovy]
 ----------------------------------------------------------------------------


[26/50] [abbrv] groovy git commit: Simplify MacroGroovy substitutions' implementation (closes #443)

Posted by su...@apache.org.
Simplify MacroGroovy substitutions' implementation (closes #443)

Assume the order of substitutions, so we can use a list instead of a map to pass the context. Fixes some related issues to Antlr4 migration.


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

Branch: refs/heads/parrot
Commit: c155e9d8eb00c9984cb96481e248e94d9ba1beaf
Parents: a4ba203
Author: Sergei Egorov <se...@zeroturnaround.com>
Authored: Sat Oct 8 20:19:12 2016 +0300
Committer: paulk <pa...@asert.com.au>
Committed: Tue Mar 21 22:13:18 2017 +1000

----------------------------------------------------------------------
 .../groovy/macro/runtime/MacroBuilder.java      | 23 ++---
 .../macro/runtime/MacroSubstitutionKey.java     | 99 --------------------
 .../macro/transform/MacroInvocationTrap.java    | 23 ++---
 .../org/codehaus/groovy/macro/MacroTest.groovy  | 23 +++++
 4 files changed, 39 insertions(+), 129 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/c155e9d8/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/runtime/MacroBuilder.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/runtime/MacroBuilder.java b/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/runtime/MacroBuilder.java
index ab4c4f3..d7cc5ce 100644
--- a/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/runtime/MacroBuilder.java
+++ b/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/runtime/MacroBuilder.java
@@ -33,8 +33,8 @@ import org.codehaus.groovy.control.SourceUnit;
 import org.codehaus.groovy.macro.transform.MacroInvocationTrap;
 import org.codehaus.groovy.macro.transform.MacroTransformation;
 
+import java.util.Iterator;
 import java.util.List;
-import java.util.Map;
 import java.util.concurrent.atomic.AtomicInteger;
 
 /**
@@ -44,27 +44,25 @@ import java.util.concurrent.atomic.AtomicInteger;
 public enum MacroBuilder {
     INSTANCE;
 
-    public <T> T macro(String source, final Map<MacroSubstitutionKey, Closure<Expression>> context, Class<T> resultClass) {
+    public <T> T macro(String source, final List<Closure<Expression>> context, Class<T> resultClass) {
         return macro(false, source, context, resultClass);
     }
 
-    public <T> T macro(boolean asIs, String source, final Map<MacroSubstitutionKey, Closure<Expression>> context, Class<T> resultClass) {
+    public <T> T macro(boolean asIs, String source, final List<Closure<Expression>> context, Class<T> resultClass) {
         return macro(CompilePhase.CONVERSION, asIs, source, context, resultClass);
     }
 
-    public <T> T macro(CompilePhase compilePhase, String source, final Map<MacroSubstitutionKey, Closure<Expression>> context, Class<T> resultClass) {
+    public <T> T macro(CompilePhase compilePhase, String source, final List<Closure<Expression>> context, Class<T> resultClass) {
         return macro(compilePhase, false, source, context, resultClass);
     }
 
     private final static AtomicInteger COUNTER = new AtomicInteger();
 
     @SuppressWarnings("unchecked")
-    public <T> T macro(CompilePhase compilePhase, boolean asIs, String source, final Map<MacroSubstitutionKey, Closure<Expression>> context, Class<T> resultClass) {
+    public <T> T macro(CompilePhase compilePhase, boolean asIs, String source, final List<Closure<Expression>> context, Class<T> resultClass) {
         boolean isClosure = source.startsWith("{");
         final String label = isClosure ?"__synthesized__label__" + COUNTER.incrementAndGet() + "__:":"";
         final String labelledSource = label + source;
-        final int linesOffset = 1;
-        final int columnsOffset = label.length() + (isClosure?1:0); // +1 because of {
 
         List<ASTNode> nodes = (new AstBuilder()).buildFromString(compilePhase, true, labelledSource);
 
@@ -75,21 +73,22 @@ public enum MacroBuilder {
                 if (!statements.isEmpty()) {
                     BlockStatement closureBlock = (BlockStatement) statements.get(0);
 
-                    performSubstitutions(linesOffset, columnsOffset, context, closureBlock);
+                    performSubstitutions(context, closureBlock);
 
 
                     return (T) getMacroValue(closureBlock, asIs);
                 }
             }
             if (node instanceof ClassNode) {
-                performSubstitutions(linesOffset, columnsOffset, context, node);
+                performSubstitutions(context, node);
                 return (T) node;
             }
         }
         return null;
     }
 
-    private static void performSubstitutions(final int linesOffset, final int columnsOffset, final Map<MacroSubstitutionKey, Closure<Expression>> context, final ASTNode astNode) {
+    private static void performSubstitutions(final List<Closure<Expression>> context, final ASTNode astNode) {
+        final Iterator<Closure<Expression>> iterator = context.iterator();
         ClassCodeExpressionTransformer trn = new ClassCodeExpressionTransformer() {
             public Expression transform(Expression expression) {
                 if (!(expression instanceof MethodCallExpression)) {
@@ -102,9 +101,7 @@ public enum MacroBuilder {
                     return super.transform(expression);
                 }
 
-                MacroSubstitutionKey key = new MacroSubstitutionKey(call, linesOffset, columnsOffset);
-
-                return context.get(key).call();
+                return iterator.next().call();
             }
 
             @Override

http://git-wip-us.apache.org/repos/asf/groovy/blob/c155e9d8/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/runtime/MacroSubstitutionKey.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/runtime/MacroSubstitutionKey.java b/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/runtime/MacroSubstitutionKey.java
deleted file mode 100644
index 5b382e5..0000000
--- a/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/runtime/MacroSubstitutionKey.java
+++ /dev/null
@@ -1,99 +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.macro.runtime;
-
-import org.codehaus.groovy.ast.ClassHelper;
-import org.codehaus.groovy.ast.expr.ArgumentListExpression;
-import org.codehaus.groovy.ast.expr.ConstantExpression;
-import org.codehaus.groovy.ast.expr.ConstructorCallExpression;
-import org.codehaus.groovy.ast.expr.Expression;
-
-/**
- *
- * @author Sergei Egorov <bs...@gmail.com>
- */
-public class MacroSubstitutionKey {
-
-    private final int startLine;
-    private final int startColumn;
-    private final int endLine;
-    private final int endColumn;
-
-    public MacroSubstitutionKey(int startLine, int startColumn, int endLine, int endColumn) {
-        this.startLine = startLine;
-        this.startColumn = startColumn;
-        this.endLine = endLine;
-        this.endColumn = endColumn;
-    }
-
-    public MacroSubstitutionKey(Expression expression, int linesOffset, int columnsOffset) {
-        this(
-                expression.getLineNumber() - linesOffset,
-                expression.getColumnNumber() - (expression.getLineNumber() == linesOffset ? columnsOffset : 0),
-                expression.getLastLineNumber() - linesOffset,
-                expression.getLastColumnNumber() - (expression.getLastLineNumber() == linesOffset ? columnsOffset : 0)
-        );
-    }
-
-    public ConstructorCallExpression toConstructorCallExpression() {
-        return new ConstructorCallExpression(
-                ClassHelper.make(this.getClass()),
-                new ArgumentListExpression(new Expression[] {
-                        new ConstantExpression(startLine),
-                        new ConstantExpression(startColumn),
-                        new ConstantExpression(endLine),
-                        new ConstantExpression(endColumn)
-                })
-        );
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-
-        MacroSubstitutionKey that = (MacroSubstitutionKey) o;
-
-        if (endColumn != that.endColumn) return false;
-        if (endLine != that.endLine) return false;
-        if (startColumn != that.startColumn) return false;
-        if (startLine != that.startLine) return false;
-
-        return true;
-    }
-
-    @Override
-    public int hashCode() {
-        int result = startLine;
-        result = 31 * result + startColumn;
-        result = 31 * result + endLine;
-        result = 31 * result + endColumn;
-        return result;
-    }
-
-    @Override
-    public String toString() {
-        return "SubstitutionKey{" +
-                "startLine=" + startLine +
-                ", startColumn=" + startColumn +
-                ", endLine=" + endLine +
-                ", endColumn=" + endColumn +
-                '}';
-    }
-}

http://git-wip-us.apache.org/repos/asf/groovy/blob/c155e9d8/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroInvocationTrap.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroInvocationTrap.java b/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroInvocationTrap.java
index a8cac37..73c14db 100644
--- a/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroInvocationTrap.java
+++ b/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroInvocationTrap.java
@@ -30,7 +30,7 @@ import org.codehaus.groovy.ast.expr.ClosureExpression;
 import org.codehaus.groovy.ast.expr.ConstantExpression;
 import org.codehaus.groovy.ast.expr.ConstructorCallExpression;
 import org.codehaus.groovy.ast.expr.Expression;
-import org.codehaus.groovy.ast.expr.MapExpression;
+import org.codehaus.groovy.ast.expr.ListExpression;
 import org.codehaus.groovy.ast.expr.MethodCallExpression;
 import org.codehaus.groovy.ast.expr.PropertyExpression;
 import org.codehaus.groovy.ast.expr.TupleExpression;
@@ -40,13 +40,10 @@ import org.codehaus.groovy.ast.tools.GeneralUtils;
 import org.codehaus.groovy.control.SourceUnit;
 import org.codehaus.groovy.control.io.ReaderSource;
 import org.codehaus.groovy.macro.runtime.MacroBuilder;
-import org.codehaus.groovy.macro.runtime.MacroSubstitutionKey;
 
-import java.util.HashMap;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
-import java.util.Map;
 
 import static org.codehaus.groovy.ast.expr.VariableExpression.THIS_EXPRESSION;
 
@@ -126,8 +123,6 @@ public class MacroInvocationTrap extends MethodInvocationTrap {
             return true;
         }
 
-        final MapExpression mapExpression = buildSubstitutionMap(closureExpression);
-
         String source = convertClosureToSource(closureExpression);
 
         BlockStatement closureBlock = (BlockStatement) closureExpression.getCode();
@@ -159,7 +154,7 @@ public class MacroInvocationTrap extends MethodInvocationTrap {
         macroArgumentsExpressions.remove(macroArgumentsExpressions.size() - 1);
 
         macroArgumentsExpressions.add(new ConstantExpression(source));
-        macroArgumentsExpressions.add(mapExpression);
+        macroArgumentsExpressions.add(buildSubstitutionMap(closureExpression));
         macroArgumentsExpressions.add(new ClassExpression(ClassHelper.makeWithoutCaching(MacroBuilder.getMacroValue(closureBlock, asIs).getClass(), false)));
 
         macroCall.setObjectExpression(new PropertyExpression(new ClassExpression(ClassHelper.makeWithoutCaching(MacroBuilder.class, false)), "INSTANCE"));
@@ -170,9 +165,8 @@ public class MacroInvocationTrap extends MethodInvocationTrap {
         return true;
     }
 
-    private MapExpression buildSubstitutionMap(final ASTNode expr) {
-        final Map<MacroSubstitutionKey, ClosureExpression> map = new HashMap<MacroSubstitutionKey, ClosureExpression>();
-        final MapExpression mapExpression = new MapExpression();
+    private ListExpression buildSubstitutionMap(final ASTNode expr) {
+        final ListExpression listExpression = new ListExpression();
 
         ClassCodeVisitorSupport visitor = new ClassCodeVisitorSupport() {
             @Override
@@ -206,9 +200,7 @@ public class MacroInvocationTrap extends MethodInvocationTrap {
                         ((BlockStatement) code).setVariableScope(null);
                     }
 
-                    MacroSubstitutionKey key = new MacroSubstitutionKey(call, expr.getLineNumber(), expr.getColumnNumber());
-
-                    map.put(key, substitutionClosureExpression);
+                    listExpression.addExpression(substitutionClosureExpression);
                 }
             }
         };
@@ -217,10 +209,7 @@ public class MacroInvocationTrap extends MethodInvocationTrap {
         } else {
             expr.visit(visitor);
         }
-        for (Map.Entry<MacroSubstitutionKey, ClosureExpression> entry : map.entrySet()) {
-            mapExpression.addMapEntryExpression(entry.getKey().toConstructorCallExpression(), entry.getValue());
-        }
-        return mapExpression;
+        return listExpression;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/groovy/blob/c155e9d8/subprojects/groovy-macro/src/test/groovy/org/codehaus/groovy/macro/MacroTest.groovy
----------------------------------------------------------------------
diff --git a/subprojects/groovy-macro/src/test/groovy/org/codehaus/groovy/macro/MacroTest.groovy b/subprojects/groovy-macro/src/test/groovy/org/codehaus/groovy/macro/MacroTest.groovy
index 3b740c9..1febbfa 100644
--- a/subprojects/groovy-macro/src/test/groovy/org/codehaus/groovy/macro/MacroTest.groovy
+++ b/subprojects/groovy-macro/src/test/groovy/org/codehaus/groovy/macro/MacroTest.groovy
@@ -186,4 +186,27 @@ class MacroTest extends GroovyTestCase {
         AstAssert.assertSyntaxTree([expected], [getReturnStatement()]);
 '''
     }
+
+    void testMultipleSubstitutions() {
+        assertScript '''
+        import org.codehaus.groovy.ast.expr.*;
+        import org.codehaus.groovy.ast.stmt.*;
+        import org.codehaus.groovy.ast.ClassHelper;
+        import org.codehaus.groovy.ast.builder.AstAssert;
+
+        import static org.codehaus.groovy.ast.tools.GeneralUtils.*;
+
+        def var1 = new VariableExpression("a")
+        def var2 = new VariableExpression("b")
+        def var3 = new VariableExpression("c")
+
+        ReturnStatement result = macro {
+            return new NonExistingClass($v{var1}, $v{var2}) + $v{var3}
+        }
+
+        def expected = returnS(plusX(ctorX(ClassHelper.make("NonExistingClass"), args(var1, var2)), var3))
+
+        AstAssert.assertSyntaxTree([expected], [result])
+'''
+    }
 }


[40/50] [abbrv] groovy git commit: remove InvocationWriter's usage from groovy-macro module

Posted by su...@apache.org.
remove InvocationWriter's usage from groovy-macro module


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

Branch: refs/heads/parrot
Commit: b58da0fa95335e6c996474a9eb10edfaeaf3d73d
Parents: e0655eb
Author: Sergei Egorov <se...@zeroturnaround.com>
Authored: Tue Mar 28 16:39:09 2017 +0300
Committer: Sergei Egorov <se...@zeroturnaround.com>
Committed: Tue Mar 28 16:39:09 2017 +0300

----------------------------------------------------------------------
 .../groovy/macro/transform/MacroCallTransformingVisitor.java | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/b58da0fa/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroCallTransformingVisitor.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroCallTransformingVisitor.java b/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroCallTransformingVisitor.java
index 1afbeb7..733d666 100644
--- a/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroCallTransformingVisitor.java
+++ b/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroCallTransformingVisitor.java
@@ -20,7 +20,6 @@ package org.codehaus.groovy.macro.transform;
 
 import org.codehaus.groovy.ast.*;
 import org.codehaus.groovy.ast.expr.*;
-import org.codehaus.groovy.classgen.asm.InvocationWriter;
 import org.codehaus.groovy.control.CompilationUnit;
 import org.codehaus.groovy.control.SourceUnit;
 import org.codehaus.groovy.macro.runtime.MacroContext;
@@ -71,7 +70,12 @@ class MacroCallTransformingVisitor extends ClassCodeVisitorSupport {
     public void visitMethodCallExpression(MethodCallExpression call) {
         super.visitMethodCallExpression(call);
 
-        List<Expression> callArguments = InvocationWriter.makeArgumentList(call.getArguments()).getExpressions();
+        final List<Expression> callArguments;
+        if (call.getArguments() instanceof TupleExpression) {
+            callArguments = ((TupleExpression) call.getArguments()).getExpressions();
+        } else {
+            callArguments = Collections.singletonList(call.getArguments());
+        }
 
         List<MethodNode> macroMethods = findMacroMethods(call.getMethodAsString(), callArguments);