You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by cc...@apache.org on 2015/10/07 21:26:40 UTC

[20/37] incubator-groovy git commit: First load of unit tests for ASTMatcher

First load of unit tests for ASTMatcher


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

Branch: refs/heads/master
Commit: f736c6ad3beef8051c7c563ca5d9256cb7fbfc6b
Parents: cae1462
Author: Cedric Champeau <ce...@gmail.com>
Authored: Thu Oct 16 17:29:37 2014 +0200
Committer: Sergei Egorov <bs...@gmail.com>
Committed: Mon Sep 28 14:33:10 2015 +0300

----------------------------------------------------------------------
 .../groovy/macro/matcher/ASTMatcher.groovy      |  80 +++++++--
 .../groovy/macro/matcher/ASTMatcherTest.groovy  | 174 +++++++++++++++++++
 2 files changed, 240 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-groovy/blob/f736c6ad/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/matcher/ASTMatcher.groovy
----------------------------------------------------------------------
diff --git a/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/matcher/ASTMatcher.groovy b/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/matcher/ASTMatcher.groovy
index bce42da..cec1632 100644
--- a/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/matcher/ASTMatcher.groovy
+++ b/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/matcher/ASTMatcher.groovy
@@ -16,11 +16,13 @@
 package org.codehaus.groovy.macro.matcher
 
 import groovy.transform.CompileStatic
+import groovy.transform.TypeCheckingMode
 import org.codehaus.groovy.ast.*
 import org.codehaus.groovy.ast.expr.*
 import org.codehaus.groovy.ast.stmt.*
 import org.codehaus.groovy.classgen.BytecodeExpression
 import org.codehaus.groovy.control.SourceUnit
+import org.codehaus.groovy.transform.stc.StaticTypesMarker
 
 @CompileStatic
 class ASTMatcher extends ClassCodeVisitorSupport {
@@ -288,6 +290,7 @@ class ASTMatcher extends ClassCodeVisitorSupport {
     }
 
     @Override
+    @CompileStatic(TypeCheckingMode.SKIP)
     public void visitDeclarationExpression(final DeclarationExpression expression) {
         doWithNode(DeclarationExpression, current) {
             super.visitDeclarationExpression(expression)
@@ -416,7 +419,8 @@ class ASTMatcher extends ClassCodeVisitorSupport {
             }
             match = match && (call.methodAsString==mce.methodAsString) &&
                     (call.safe==mce.safe) &&
-                    (call.spreadSafe == mce.spreadSafe)
+                    (call.spreadSafe == mce.spreadSafe) &&
+                    (call.implicitThis == mce.implicitThis)
         }
     }
 
@@ -427,8 +431,11 @@ class ASTMatcher extends ClassCodeVisitorSupport {
 
     @Override
     public void visitConstructorCallExpression(final ConstructorCallExpression call) {
-        doWithNode(call.arguments.class, ((ConstructorCallExpression)call).arguments) {
+        def cur = (ConstructorCallExpression) current
+        doWithNode(call.arguments.class, cur.arguments) {
             call.arguments.visit(this)
+            match = match &&
+                    (call.type == cur.type)
         }
     }
 
@@ -469,18 +476,29 @@ class ASTMatcher extends ClassCodeVisitorSupport {
     }
 
     @Override
-    public void visitShortTernaryExpression(final ElvisOperatorExpression expression) {
-        super.visitShortTernaryExpression(expression);
-    }
-
-    @Override
     public void visitPostfixExpression(final PostfixExpression expression) {
-        super.visitPostfixExpression(expression);
+        doWithNode(PostfixExpression, current) {
+            def origExpr = expression.expression
+            def curExpr = (PostfixExpression) current
+            doWithNode(origExpr.class, curExpr.expression) {
+                origExpr.visit(this)
+                match = match &&
+                        (expression.operation.type==curExpr.operation.type)
+            }
+        }
     }
 
     @Override
     public void visitPrefixExpression(final PrefixExpression expression) {
-        super.visitPrefixExpression(expression);
+        doWithNode(PrefixExpression, current) {
+            def origExpr = expression.expression
+            def curExpr = (PrefixExpression) current
+            doWithNode(origExpr.class, curExpr.expression) {
+                origExpr.visit(this)
+                match = match &&
+                        (expression.operation.type==curExpr.operation.type)
+            }
+        }
     }
 
     @Override
@@ -572,25 +590,54 @@ class ASTMatcher extends ClassCodeVisitorSupport {
     }
 
     @Override
+    @CompileStatic(TypeCheckingMode.SKIP)
     public void visitConstantExpression(final ConstantExpression expression) {
-        super.visitConstantExpression(expression);
+        doWithNode(ConstantExpression, current) {
+            def cur = (ConstantExpression) current
+            super.visitConstantExpression(expression)
+            match = match &&
+                    (expression.type==cur.type) &&
+                    (expression.value==cur.value)
+        }
     }
 
     @Override
+    @CompileStatic(TypeCheckingMode.SKIP)
     public void visitClassExpression(final ClassExpression expression) {
-        super.visitClassExpression(expression);
+        doWithNode(ClassExpression, current) {
+            super.visitClassExpression(expression)
+            def cexp = (ClassExpression) current
+            match = match && (cexp.type == expression.type)
+        }
     }
 
     @Override
     public void visitVariableExpression(final VariableExpression expression) {
         doWithNode(VariableExpression, current) {
-            match = expression.name == ((VariableExpression) current).name
+            def curVar = (VariableExpression) current
+            match = match &&
+                    (expression.name == curVar.name) &&
+                    (expression.type == curVar.type) &&
+                    (expression.originType == curVar.originType)
         }
     }
 
     @Override
     public void visitPropertyExpression(final PropertyExpression expression) {
-        super.visitPropertyExpression(expression);
+        doWithNode(PropertyExpression, current) {
+            def currentPexp = (PropertyExpression) current
+            doWithNode(expression.objectExpression.class, currentPexp.objectExpression) {
+                expression.objectExpression.visit(this)
+            }
+            doWithNode(expression.property.class, currentPexp.property) {
+                expression.property.visit(this)
+            }
+            match = match &&
+                    (expression.propertyAsString==currentPexp.propertyAsString) &&
+                    (expression.implicitThis==currentPexp.implicitThis) &&
+                    (expression.safe==currentPexp.safe) &&
+                    (expression.spreadSafe==currentPexp.spreadSafe)
+        }
     }
 
     @Override
@@ -611,7 +658,12 @@ class ASTMatcher extends ClassCodeVisitorSupport {
     @Override
     protected void visitListOfExpressions(final List<? extends Expression> list) {
         if (list == null) return;
-        def iter = ((List<Expression>) current).iterator()
+        def currentExprs = (List<Expression>) current
+        if (currentExprs.size()!=list.size()) {
+            match = false
+            return
+        }
+        def iter = currentExprs.iterator()
         for (Expression expression : list) {
             def next = iter.next()
             if (expression instanceof SpreadExpression) {

http://git-wip-us.apache.org/repos/asf/incubator-groovy/blob/f736c6ad/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
new file mode 100644
index 0000000..6f42859
--- /dev/null
+++ b/subprojects/groovy-macro/src/test/groovy/org/codehaus/groovy/macro/matcher/ASTMatcherTest.groovy
@@ -0,0 +1,174 @@
+/*
+ * Copyright 2003-2014 the original author or authors.
+ *
+ * Licensed 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.matcher
+
+import org.codehaus.groovy.ast.expr.ClassExpression
+import org.codehaus.groovy.control.CompilePhase
+
+class ASTMatcherTest extends GroovyTestCase {
+    void testMatchesSimpleVar() {
+        def ast = macro { a }
+        assert ASTMatcher.matches(ast, ast)
+    }
+    void testMatchesSimpleVarNeg() {
+        def ast = macro { a }
+        def ast2 = macro { b }
+        assert !ASTMatcher.matches(ast, ast2)
+        assert !ASTMatcher.matches(ast2, ast)
+    }
+
+    void testBinaryExpression() {
+        def ast1 = macro { a+b }
+        def ast2 = macro { a+b }
+        def ast3 = macro { b+a }
+        def ast4 = macro { a-b }
+        assert ASTMatcher.matches(ast1, ast1)
+        assert ASTMatcher.matches(ast1, ast2)
+        assert ASTMatcher.matches(ast2, ast1)
+        assert !ASTMatcher.matches(ast1, ast3)
+        assert !ASTMatcher.matches(ast1, ast4)
+    }
+
+    void testMethodCallExpression() {
+        def ast1 = macro { foo() }
+        def ast2 = macro { foo() }
+        def ast3 = macro { this.foo() }
+        def ast4 = macro { bar() }
+        def ast5 = macro { foo(bar) }
+        def ast6 = macro { foo(bar())}
+        def ast7 = macro { foo(bar())}
+        assert ASTMatcher.matches(ast1, ast1)
+        assert ASTMatcher.matches(ast1, ast2)
+        assert ASTMatcher.matches(ast2, ast1)
+        assert !ASTMatcher.matches(ast1, ast3)
+        assert !ASTMatcher.matches(ast1, ast4)
+        assert !ASTMatcher.matches(ast1, ast5)
+        assert ASTMatcher.matches(ast6, ast7)
+    }
+
+    void testPropertyExpression() {
+        def ast1 = macro { this.p }
+        def ast2 = macro { this.p }
+        def ast3 = macro { that.p }
+        def ast4 = macro { this.p2 }
+        def ast5 = macro { this?.p }
+        def ast6 = macro { this*.p }
+        assert ASTMatcher.matches(ast1, ast1)
+        assert ASTMatcher.matches(ast1, ast2)
+        assert ASTMatcher.matches(ast2, ast1)
+        assert !ASTMatcher.matches(ast1, ast3)
+        assert !ASTMatcher.matches(ast1, ast4)
+        assert !ASTMatcher.matches(ast1, ast5)
+        assert !ASTMatcher.matches(ast1, ast6)
+    }
+
+    void testClassExpression() {
+        def ast1 = macro(CompilePhase.SEMANTIC_ANALYSIS) { String }
+        def ast2 = macro(CompilePhase.SEMANTIC_ANALYSIS) { String }
+        def ast3 = macro(CompilePhase.SEMANTIC_ANALYSIS) { Boolean }
+        assert ast1 instanceof ClassExpression
+        assert ast2 instanceof ClassExpression
+        assert ast3 instanceof ClassExpression
+        assert ASTMatcher.matches(ast1, ast1)
+        assert ASTMatcher.matches(ast1, ast2)
+        assert ASTMatcher.matches(ast2, ast1)
+        assert !ASTMatcher.matches(ast1, ast3)
+    }
+
+    void testTernaryExpression() {
+        def ast1 = macro { a?b:c }
+        def ast2 = macro { a?b:c }
+        def ast3 = macro { b?b:c }
+        def ast4 = macro { a?a:c }
+        def ast5 = macro { a?b:a }
+        def ast6 = macro { a?(a+b):a }
+        def ast7 = macro { a?(a+b):a }
+        assert ASTMatcher.matches(ast1, ast1)
+        assert ASTMatcher.matches(ast1, ast2)
+        assert ASTMatcher.matches(ast2, ast1)
+        assert !ASTMatcher.matches(ast1, ast3)
+        assert !ASTMatcher.matches(ast1, ast4)
+        assert !ASTMatcher.matches(ast1, ast5)
+        assert ASTMatcher.matches(ast6, ast7)
+    }
+
+    void testElvis() {
+        def ast1 = macro { a?:c }
+        def ast2 = macro { a?:c }
+        def ast3 = macro { b?:c }
+        def ast4 = macro { a?:a }
+        def ast5 = macro { a?:(a+b) }
+        def ast6 = macro { a?:(a+b) }
+        assert ASTMatcher.matches(ast1, ast1)
+        assert ASTMatcher.matches(ast1, ast2)
+        assert ASTMatcher.matches(ast2, ast1)
+        assert !ASTMatcher.matches(ast1, ast3)
+        assert !ASTMatcher.matches(ast1, ast4)
+        assert !ASTMatcher.matches(ast1, ast5)
+        assert ASTMatcher.matches(ast5, ast6)
+    }
+
+    void testPrefixExpression() {
+        def ast1 = macro { ++a }
+        def ast2 = macro { ++a }
+        def ast3 = macro { ++b }
+        def ast4 = macro { --a }
+        assert ASTMatcher.matches(ast1, ast1)
+        assert ASTMatcher.matches(ast1, ast2)
+        assert ASTMatcher.matches(ast2, ast1)
+        assert !ASTMatcher.matches(ast1, ast3)
+        assert !ASTMatcher.matches(ast1, ast4)
+    }
+
+    void testPostfixExpression() {
+        def ast1 = macro { a++ }
+        def ast2 = macro { a++ }
+        def ast3 = macro { b++ }
+        def ast4 = macro { a-- }
+        assert ASTMatcher.matches(ast1, ast1)
+        assert ASTMatcher.matches(ast1, ast2)
+        assert ASTMatcher.matches(ast2, ast1)
+        assert !ASTMatcher.matches(ast1, ast3)
+        assert !ASTMatcher.matches(ast1, ast4)
+    }
+
+    void testConstructorCall() {
+        def ast1 = macro { new Foo() }
+        def ast2 = macro { new Foo() }
+        def ast3 = macro { new Bar() }
+        def ast4 = macro { new Foo(bar) }
+        assert ASTMatcher.matches(ast1, ast1)
+        assert ASTMatcher.matches(ast1, ast2)
+        assert ASTMatcher.matches(ast2, ast1)
+        assert !ASTMatcher.matches(ast1, ast3)
+        assert !ASTMatcher.matches(ast1, ast4)
+    }
+
+    void testDeclaration() {
+        def ast1 = macro { def x = 1 }
+        def ast2 = macro { def x = 1 }
+        def ast3 = macro { int x = 1 }
+        def ast4 = macro { def y = 1 }
+        def ast5 = macro { def x = 2 }
+        assert ASTMatcher.matches(ast1, ast1)
+        assert ASTMatcher.matches(ast1, ast2)
+        assert ASTMatcher.matches(ast2, ast1)
+        assert !ASTMatcher.matches(ast1, ast3)
+        assert !ASTMatcher.matches(ast1, ast4)
+        assert !ASTMatcher.matches(ast1, ast5)
+    }
+}