You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by su...@apache.org on 2020/08/09 04:53:30 UTC

[groovy] branch master updated: GROOVY-9677: provide a library of pre-canned macro methods

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

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


The following commit(s) were added to refs/heads/master by this push:
     new e4d768a  GROOVY-9677: provide a library of pre-canned macro methods
e4d768a is described below

commit e4d768ac139a41878008425fda119116dbd1416a
Author: Paul King <pa...@asert.com.au>
AuthorDate: Fri Aug 7 20:36:45 2020 +1000

    GROOVY-9677: provide a library of pre-canned macro methods
---
 gradle/upload.gradle                               |  1 +
 settings.gradle                                    |  1 +
 subprojects/groovy-macro-library/build.gradle      | 30 +++++++
 .../groovy/macrolib/MacroLibGroovyMethods.java     | 66 ++++++++++++++++
 .../org/apache/groovy/macrolib/MacroLibTest.groovy | 91 ++++++++++++++++++++++
 5 files changed, 189 insertions(+)

diff --git a/gradle/upload.gradle b/gradle/upload.gradle
index d8a4787..ceff62b 100644
--- a/gradle/upload.gradle
+++ b/gradle/upload.gradle
@@ -191,6 +191,7 @@ def optionalModules = [
         'groovy-dateutil',
         'groovy-contracts',
         'groovy-jaxb',
+        'groovy-macro-library',
         'groovy-testng'
 ]
 
diff --git a/settings.gradle b/settings.gradle
index 058ed1f..394acfc 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -46,6 +46,7 @@ def subprojects = ['groovy-ant',
         'groovy-json',
         'groovy-jsr223',
         'groovy-macro',
+        'groovy-macro-library',
         'groovy-nio',
         'groovy-servlet',
         'groovy-sql',
diff --git a/subprojects/groovy-macro-library/build.gradle b/subprojects/groovy-macro-library/build.gradle
new file mode 100644
index 0000000..b3e785e
--- /dev/null
+++ b/subprojects/groovy-macro-library/build.gradle
@@ -0,0 +1,30 @@
+/*
+ *  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.
+ */
+dependencies {
+    implementation rootProject
+    implementation project(':groovy-macro')
+    testImplementation rootProject.sourceSets.test.runtimeClasspath
+    testImplementation project(':groovy-test')
+}
+
+task moduleDescriptor(type: org.codehaus.groovy.gradle.WriteExtensionDescriptorTask) {
+    extensionClasses = 'org.apache.groovy.macrolib.MacroLibGroovyMethods'
+}
+
+compileJava.dependsOn moduleDescriptor
diff --git a/subprojects/groovy-macro-library/src/main/groovy/org/apache/groovy/macrolib/MacroLibGroovyMethods.java b/subprojects/groovy-macro-library/src/main/groovy/org/apache/groovy/macrolib/MacroLibGroovyMethods.java
new file mode 100644
index 0000000..ab64409
--- /dev/null
+++ b/subprojects/groovy-macro-library/src/main/groovy/org/apache/groovy/macrolib/MacroLibGroovyMethods.java
@@ -0,0 +1,66 @@
+/*
+ *  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.apache.groovy.macrolib;
+
+import org.codehaus.groovy.ast.expr.ConstantExpression;
+import org.codehaus.groovy.ast.expr.Expression;
+import org.codehaus.groovy.ast.expr.GStringExpression;
+import org.codehaus.groovy.macro.runtime.Macro;
+import org.codehaus.groovy.macro.runtime.MacroContext;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+
+import static org.codehaus.groovy.ast.tools.GeneralUtils.callX;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.constX;
+
+public class MacroLibGroovyMethods {
+
+    public static <T> T NV(Object self, Object... args) {
+        throw new IllegalStateException("MacroLibGroovyMethods.NV(Object...) should never be called at runtime. Are you sure you are using it correctly?");
+    }
+
+    @Macro
+    public static Expression NV(MacroContext ctx, final Expression... exps) {
+        return new GStringExpression("", makeLabels(exps), Arrays.asList(exps));
+    }
+
+    @Macro
+    public static Expression NVI(MacroContext ctx, final Expression... exps) {
+        List<Expression> expList = Arrays.stream(exps).map(exp -> callX(exp, "inspect"))
+                .collect(Collectors.toList());
+        return new GStringExpression("", makeLabels(exps), expList);
+    }
+
+    @Macro
+    public static Expression NVD(MacroContext ctx, final Expression... exps) {
+        List<Expression> expList = Arrays.stream(exps).map(exp -> callX(exp, "dump"))
+                .collect(Collectors.toList());
+        return new GStringExpression("", makeLabels(exps), expList);
+    }
+
+    private static List<ConstantExpression> makeLabels(Expression[] exps) {
+        return IntStream
+                .range(0, exps.length)
+                .mapToObj(i -> constX((i > 0 ? ", " : "") + exps[i].getText() + "="))
+                .collect(Collectors.toList());
+    }
+}
diff --git a/subprojects/groovy-macro-library/src/test/groovy/org/apache/groovy/macrolib/MacroLibTest.groovy b/subprojects/groovy-macro-library/src/test/groovy/org/apache/groovy/macrolib/MacroLibTest.groovy
new file mode 100644
index 0000000..5918463
--- /dev/null
+++ b/subprojects/groovy-macro-library/src/test/groovy/org/apache/groovy/macrolib/MacroLibTest.groovy
@@ -0,0 +1,91 @@
+/*
+ *  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.apache.groovy.macrolib
+
+import groovy.test.GroovyTestCase
+import groovy.transform.CompileStatic
+
+@CompileStatic
+class MacroLibTest extends GroovyTestCase {
+
+    def BASE = '''
+    def num = 42
+    def list = [1 ,2, 3]
+    def range = 0..5
+    def string = 'foo'
+    '''
+
+    void testNV() {
+        assertScript """
+        $BASE
+        assert NV(num, list, range, string).toString() == 'num=42, list=[1, 2, 3], range=[0, 1, 2, 3, 4, 5], string=foo'
+        """
+    }
+
+    void testNVInClosure() {
+        assertScript """
+        $BASE
+        def cl = {
+            NV(num, list, range, string).toString()
+        }
+
+        assert cl().toString() == 'num=42, list=[1, 2, 3], range=[0, 1, 2, 3, 4, 5], string=foo'
+        """
+    }
+
+    void testList() {
+        assertScript """
+        $BASE
+        assert [NV(num, list), NV(range, string)].toString() == '[num=42, list=[1, 2, 3], range=[0, 1, 2, 3, 4, 5], string=foo]'
+        """
+    }
+
+    void testNVInclude() {
+        assertScript """
+        $BASE
+        def numNV = NV(num)
+        assert NV(numNV, list, range, string).toString() == 'numNV=num=42, list=[1, 2, 3], range=[0, 1, 2, 3, 4, 5], string=foo'
+        """
+    }
+
+    void testNested() {
+        assertScript """
+        $BASE
+        def result = NV(NV(num), string)
+        def strip = 'org.codehaus.groovy.macro.runtime.MacroStub.INSTANCE.'
+        assert result - strip == 'macroMethod()=num=42, string=foo'
+        """
+    }
+
+    void testNVI() {
+        assertScript """
+        $BASE
+        assert NVI(num, list, range, string).toString() == /num=42, list=[1, 2, 3], range=0..5, string='foo'/
+        """
+    }
+
+    void testNVD() {
+        assertScript """
+        $BASE
+        def result = NVD(num, list, range, string)
+        def trimmed = result.replaceAll(/@[^>]+/, '@...')
+        assert trimmed == /num=<ja...@...>, list=<ja...@...>, range=<gr...@...>, string=<ja...@...>/
+        """
+    }
+}