Skip to content

Commit

Permalink
GROOVY-11260: ASTMatcher should support matching a var-arg placeholder
Browse files Browse the repository at this point in the history
  • Loading branch information
paulk-asert committed Jan 1, 2024
1 parent 80e92ec commit 412f566
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import org.codehaus.groovy.ast.ModuleNode
import org.codehaus.groovy.ast.PackageNode
import org.codehaus.groovy.ast.Parameter
import org.codehaus.groovy.ast.PropertyNode
import org.codehaus.groovy.ast.expr.ArgumentListExpression
import org.codehaus.groovy.ast.expr.ArrayExpression
import org.codehaus.groovy.ast.expr.AttributeExpression
import org.codehaus.groovy.ast.expr.BinaryExpression
Expand Down Expand Up @@ -159,9 +160,15 @@ class ASTMatcher extends ContextualClassCodeVisitor {
return exp.name
} else if (exp instanceof ConstantExpression && placeholders.contains(exp.value)) {
return exp.value
} else {
return null
} else if (exp instanceof ArgumentListExpression && exp.size() == 1 && exp[0] instanceof VariableExpression) {
// TODO currently matches exactly all args, consider allowing
// other non-vararg nodes before the vararg one
VariableExpression ve = exp[0] as VariableExpression
if (varargPlaceholders.contains(ve.name)) {
return ve.name
}
}
return null
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class MatchingConstraints {
public final static ConstraintPredicate<Token> ANY_TOKEN = AnyTokenMatch.INSTANCE

final Set<String> placeholders
final Set<String> varargPlaceholders
final ConstraintPredicate<Token> tokenPredicate
final ConstraintPredicate<TreeContext> eventually
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import org.codehaus.groovy.syntax.Token

class MatchingConstraintsBuilder {
Set<String> placeholders = new LinkedHashSet<>()
Set<String> varargPlaceholders = new LinkedHashSet<>()
ConstraintPredicate<Token> tokenPredicate
ConstraintPredicate<TreeContext> eventually

Expand All @@ -36,6 +37,7 @@ class MatchingConstraintsBuilder {

new MatchingConstraints(
placeholders: Collections.unmodifiableSet(placeholders),
varargPlaceholders: Collections.unmodifiableSet(varargPlaceholders),
tokenPredicate: tokenPredicate,
eventually: eventually
)
Expand All @@ -50,6 +52,11 @@ class MatchingConstraintsBuilder {
this
}

MatchingConstraintsBuilder varargPlaceholder(String... names) {
names.each { String it -> varargPlaceholders.add(it) }
this
}

MatchingConstraintsBuilder anyToken() {
tokenPredicate = MatchingConstraints.ANY_TOKEN
this
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,24 @@ class ASTMatcherTest extends GroovyTestCase {
'''
}

void testMethodCallExpressionWithVarargs() {
assertScript '''
import org.codehaus.groovy.macro.matcher.ASTMatcher
def pattern = macro { foo(a) }.withConstraints{ varargPlaceholder a }
def ast2 = macro { foo() }
def ast3 = macro { foo(1) }
def ast4 = macro { foo(1, 2) }
def ast5 = macro { foo(1, 2, 3) }
def ast6 = macro { bar() }
assert ASTMatcher.matches(ast2, pattern)
assert ASTMatcher.matches(ast3, pattern)
assert ASTMatcher.matches(ast4, pattern)
assert ASTMatcher.matches(ast5, pattern)
assert !ASTMatcher.matches(ast6, pattern)
'''
}

void testPropertyExpression() {
assertScript '''
import org.codehaus.groovy.macro.matcher.ASTMatcher
Expand Down

0 comments on commit 412f566

Please sign in to comment.