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)
+ }
+}