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:22 UTC
[02/37] incubator-groovy git commit: shared code between MacroGroovy
and AstBuilderTransformation
shared code between MacroGroovy and AstBuilderTransformation
Project: http://git-wip-us.apache.org/repos/asf/incubator-groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-groovy/commit/546868aa
Tree: http://git-wip-us.apache.org/repos/asf/incubator-groovy/tree/546868aa
Diff: http://git-wip-us.apache.org/repos/asf/incubator-groovy/diff/546868aa
Branch: refs/heads/master
Commit: 546868aaae30335b9b6fc1a67bb6cf1dc2b84cff
Parents: 0b5f0b0
Author: Sergey Egorov <bs...@gmail.com>
Authored: Thu Jul 3 12:45:29 2014 +0300
Committer: Sergei Egorov <bs...@gmail.com>
Committed: Mon Sep 28 14:32:03 2015 +0300
----------------------------------------------------------------------
.../groovy/ast/MethodCallTransformation.java | 113 ++++++++++++
.../groovy/ast/MethodInvocationTrap.java | 94 ++++++++++
.../ast/builder/AstBuilderTransformation.java | 181 +++----------------
.../macro/transform/MacroInvocationTrap.java | 148 +++++----------
.../macro/transform/MacroTransformation.java | 41 +----
5 files changed, 289 insertions(+), 288 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-groovy/blob/546868aa/src/main/org/codehaus/groovy/ast/MethodCallTransformation.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/ast/MethodCallTransformation.java b/src/main/org/codehaus/groovy/ast/MethodCallTransformation.java
new file mode 100644
index 0000000..85c6f2c
--- /dev/null
+++ b/src/main/org/codehaus/groovy/ast/MethodCallTransformation.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2003-2013 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.ast;
+
+import groovy.lang.MissingPropertyException;
+import org.codehaus.groovy.ast.stmt.Statement;
+import org.codehaus.groovy.control.SourceUnit;
+import org.codehaus.groovy.transform.ASTTransformation;
+
+/**
+ *
+ * @author Hamlet D'Arcy
+ * @author Sergei Egorov <bs...@gmail.com>
+ */
+
+public abstract class MethodCallTransformation implements ASTTransformation {
+
+ public void visit(ASTNode[] nodes, SourceUnit sourceUnit) {
+
+ GroovyCodeVisitor transformer = getTransformer(nodes, sourceUnit);
+
+ if (nodes != null) {
+ for (ASTNode it : nodes) {
+ if (!(it instanceof AnnotationNode) && !(it instanceof ClassNode)) {
+ it.visit(transformer);
+ }
+ }
+ }
+ if (sourceUnit.getAST() != null) {
+ sourceUnit.getAST().visit(transformer);
+ if (sourceUnit.getAST().getStatementBlock() != null) {
+ sourceUnit.getAST().getStatementBlock().visit(transformer);
+ }
+ if (sourceUnit.getAST().getClasses() != null) {
+ for (ClassNode classNode : sourceUnit.getAST().getClasses()) {
+ if (classNode.getMethods() != null) {
+ for (MethodNode node : classNode.getMethods()) {
+ if (node != null && node.getCode() != null) {
+ node.getCode().visit(transformer);
+ }
+ }
+ }
+
+ try {
+ if (classNode.getDeclaredConstructors() != null) {
+ for (MethodNode node : classNode.getDeclaredConstructors()) {
+ if (node != null && node.getCode() != null) {
+ node.getCode().visit(transformer);
+ }
+ }
+ }
+ } catch (MissingPropertyException ignored) {
+ // todo: inner class nodes don't have a constructors field available
+ }
+
+ // all properties are also always fields
+ if (classNode.getFields() != null) {
+ for (FieldNode node : classNode.getFields()) {
+ if (node.getInitialValueExpression() != null) {
+ node.getInitialValueExpression().visit(transformer);
+ }
+ }
+ }
+
+ try {
+ if (classNode.getObjectInitializerStatements() != null) {
+ for (Statement node : classNode.getObjectInitializerStatements()) {
+ if (node != null) {
+ node.visit(transformer);
+ }
+ }
+ }
+ } catch (MissingPropertyException ignored) {
+ // todo: inner class nodes don't have a objectInitializers field available
+ }
+
+ // todo: is there anything to do with the module ???
+ }
+ }
+ if (sourceUnit.getAST().getMethods() != null) {
+ for (MethodNode node : sourceUnit.getAST().getMethods()) {
+ if (node != null) {
+ if (node.getParameters() != null) {
+ for (Parameter parameter : node.getParameters()) {
+ if (parameter != null && parameter.getInitialExpression() != null) {
+ parameter.getInitialExpression().visit(transformer);
+ }
+ }
+ }
+ if (node.getCode() != null) {
+ node.getCode().visit(transformer);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ protected abstract GroovyCodeVisitor getTransformer(ASTNode[] nodes, SourceUnit sourceUnit);
+}
http://git-wip-us.apache.org/repos/asf/incubator-groovy/blob/546868aa/src/main/org/codehaus/groovy/ast/MethodInvocationTrap.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/ast/MethodInvocationTrap.java b/src/main/org/codehaus/groovy/ast/MethodInvocationTrap.java
new file mode 100644
index 0000000..6d51a5c
--- /dev/null
+++ b/src/main/org/codehaus/groovy/ast/MethodInvocationTrap.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2003-2013 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.ast;
+
+import org.codehaus.groovy.ast.expr.ClosureExpression;
+import org.codehaus.groovy.ast.expr.MethodCallExpression;
+import org.codehaus.groovy.ast.tools.ClosureUtils;
+import org.codehaus.groovy.control.SourceUnit;
+import org.codehaus.groovy.control.io.ReaderSource;
+import org.codehaus.groovy.control.messages.SyntaxErrorMessage;
+import org.codehaus.groovy.syntax.SyntaxException;
+
+/**
+ *
+ * @author Hamlet D'Arcy
+ * @author Sergei Egorov <bs...@gmail.com>
+ */
+public abstract class MethodInvocationTrap extends CodeVisitorSupport {
+
+ protected final ReaderSource source;
+ protected final SourceUnit sourceUnit;
+
+ public MethodInvocationTrap(ReaderSource source, SourceUnit sourceUnit) {
+ if (source == null) throw new IllegalArgumentException("Null: source");
+ if (sourceUnit == null) throw new IllegalArgumentException("Null: sourceUnit");
+ this.source = source;
+ this.sourceUnit = sourceUnit;
+ }
+
+ /**
+ * Attempts to find AstBuilder 'from code' invocations. When found, converts them into calls
+ * to the 'from string' approach.
+ *
+ * @param call the method call expression that may or may not be an AstBuilder 'from code' invocation.
+ */
+ public void visitMethodCallExpression(MethodCallExpression call) {
+ boolean shouldContinueWalking = true;
+
+ if (isBuildInvocation(call)) {
+ shouldContinueWalking = handleTargetMethodCallExpression(call);
+ }
+
+ if(shouldContinueWalking) {
+ // continue normal tree walking
+ call.getObjectExpression().visit(this);
+ call.getMethod().visit(this);
+ call.getArguments().visit(this);
+ }
+ }
+
+ /**
+ * Reports an error back to the source unit.
+ *
+ * @param msg the error message
+ * @param expr the expression that caused the error message.
+ */
+ protected void addError(String msg, ASTNode expr) {
+ sourceUnit.getErrorCollector().addErrorAndContinue(
+ new SyntaxErrorMessage(new SyntaxException(msg + '\n', expr.getLineNumber(), expr.getColumnNumber(), expr.getLastLineNumber(), expr.getLastColumnNumber()), sourceUnit)
+ );
+ }
+
+ /**
+ * Converts a ClosureExpression into the String source.
+ *
+ * @param expression a closure
+ * @return the source the closure was created from
+ */
+ protected String convertClosureToSource(ClosureExpression expression) {
+ try {
+ return ClosureUtils.convertClosureToSource(source, expression);
+ } catch(Exception e) {
+ addError(e.getMessage(), expression);
+ }
+ return null;
+ }
+
+ protected abstract boolean handleTargetMethodCallExpression(MethodCallExpression call);
+
+ protected abstract boolean isBuildInvocation(MethodCallExpression call);
+}
http://git-wip-us.apache.org/repos/asf/incubator-groovy/blob/546868aa/src/main/org/codehaus/groovy/ast/builder/AstBuilderTransformation.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/ast/builder/AstBuilderTransformation.java b/src/main/org/codehaus/groovy/ast/builder/AstBuilderTransformation.java
index 20a4aea..4143e34 100644
--- a/src/main/org/codehaus/groovy/ast/builder/AstBuilderTransformation.java
+++ b/src/main/org/codehaus/groovy/ast/builder/AstBuilderTransformation.java
@@ -18,17 +18,11 @@
*/
package org.codehaus.groovy.ast.builder;
-import groovy.lang.MissingPropertyException;
import org.codehaus.groovy.ast.*;
import org.codehaus.groovy.ast.expr.*;
-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.control.io.ReaderSource;
-import org.codehaus.groovy.control.messages.SyntaxErrorMessage;
-import org.codehaus.groovy.syntax.SyntaxException;
-import org.codehaus.groovy.transform.ASTTransformation;
import org.codehaus.groovy.transform.GroovyASTTransformation;
import java.util.ArrayList;
@@ -49,92 +43,17 @@ import java.util.List;
*/
@GroovyASTTransformation(phase = CompilePhase.SEMANTIC_ANALYSIS)
-public class AstBuilderTransformation implements ASTTransformation {
-
- public void visit(ASTNode[] nodes, SourceUnit sourceUnit) {
+public class AstBuilderTransformation extends MethodCallTransformation {
+ @Override
+ protected GroovyCodeVisitor getTransformer(ASTNode[] nodes, SourceUnit sourceUnit) {
// todo : are there other import types that can be specified?
- AstBuilderInvocationTrap transformer = new AstBuilderInvocationTrap(
- sourceUnit.getAST().getImports(),
- sourceUnit.getAST().getStarImports(),
- sourceUnit.getSource(),
- sourceUnit
+ return new AstBuilderInvocationTrap(
+ sourceUnit.getAST().getImports(),
+ sourceUnit.getAST().getStarImports(),
+ sourceUnit.getSource(),
+ sourceUnit
);
- if (nodes != null) {
- for (ASTNode it : nodes) {
- if (!(it instanceof AnnotationNode) && !(it instanceof ClassNode)) {
- it.visit(transformer);
- }
- }
- }
- if (sourceUnit.getAST() != null) {
- sourceUnit.getAST().visit(transformer);
- if (sourceUnit.getAST().getStatementBlock() != null) {
- sourceUnit.getAST().getStatementBlock().visit(transformer);
- }
- if (sourceUnit.getAST().getClasses() != null) {
- for (ClassNode classNode : sourceUnit.getAST().getClasses()) {
- if (classNode.getMethods() != null) {
- for (MethodNode node : classNode.getMethods()) {
- if (node != null && node.getCode() != null) {
- node.getCode().visit(transformer);
- }
- }
- }
-
- try {
- if (classNode.getDeclaredConstructors() != null) {
- for (MethodNode node : classNode.getDeclaredConstructors()) {
- if (node != null && node.getCode() != null) {
- node.getCode().visit(transformer);
- }
- }
- }
- } catch (MissingPropertyException ignored) {
- // todo: inner class nodes don't have a constructors field available
- }
-
- // all properties are also always fields
- if (classNode.getFields() != null) {
- for (FieldNode node : classNode.getFields()) {
- if (node.getInitialValueExpression() != null) {
- node.getInitialValueExpression().visit(transformer);
- }
- }
- }
-
- try {
- if (classNode.getObjectInitializerStatements() != null) {
- for (Statement node : classNode.getObjectInitializerStatements()) {
- if (node != null) {
- node.visit(transformer);
- }
- }
- }
- } catch (MissingPropertyException ignored) {
- // todo: inner class nodes don't have a objectInitializers field available
- }
-
- // todo: is there anything to do with the module ???
- }
- }
- if (sourceUnit.getAST().getMethods() != null) {
- for (MethodNode node : sourceUnit.getAST().getMethods()) {
- if (node != null) {
- if (node.getParameters() != null) {
- for (Parameter parameter : node.getParameters()) {
- if (parameter != null && parameter.getInitialExpression() != null) {
- parameter.getInitialExpression().visit(transformer);
- }
- }
- }
- if (node.getCode() != null) {
- node.getCode().visit(transformer);
- }
- }
- }
- }
- }
}
/**
@@ -142,11 +61,9 @@ public class AstBuilderTransformation implements ASTTransformation {
* the contents of the closure into expressions by reading the source of the Closure and sending
* that as a String to AstBuilder.build(String, CompilePhase, boolean) at runtime.
*/
- private static class AstBuilderInvocationTrap extends CodeVisitorSupport {
+ private static class AstBuilderInvocationTrap extends MethodInvocationTrap {
private final List<String> factoryTargets = new ArrayList<String>();
- private final ReaderSource source;
- private final SourceUnit sourceUnit;
/**
* Creates the trap and captures all the ways in which a class may be referenced via imports.
@@ -157,10 +74,7 @@ public class AstBuilderTransformation implements ASTTransformation {
* @param sourceUnit the source unit being compiled. Used for error messages.
*/
AstBuilderInvocationTrap(List<ImportNode> imports, List<ImportNode> importPackages, ReaderSource source, SourceUnit sourceUnit) {
- if (source == null) throw new IllegalArgumentException("Null: source");
- if (sourceUnit == null) throw new IllegalArgumentException("Null: sourceUnit");
- this.source = source;
- this.sourceUnit = sourceUnit;
+ super(source, sourceUnit);
// factory type may be references as fully qualified, an import, or an alias
factoryTargets.add("org.codehaus.groovy.ast.builder.AstBuilder");//default package
@@ -182,47 +96,22 @@ public class AstBuilderTransformation implements ASTTransformation {
}
}
}
-
- /**
- * Reports an error back to the source unit.
- *
- * @param msg the error message
- * @param expr the expression that caused the error message.
- */
- private void addError(String msg, ASTNode expr) {
- sourceUnit.getErrorCollector().addErrorAndContinue(
- new SyntaxErrorMessage(new SyntaxException(msg + '\n', expr.getLineNumber(), expr.getColumnNumber(), expr.getLastLineNumber(), expr.getLastColumnNumber()), sourceUnit)
- );
- }
-
-
- /**
- * Attempts to find AstBuilder 'from code' invocations. When found, converts them into calls
- * to the 'from string' approach.
- *
- * @param call the method call expression that may or may not be an AstBuilder 'from code' invocation.
- */
- public void visitMethodCallExpression(MethodCallExpression call) {
-
- if (isBuildInvocation(call)) {
-
- ClosureExpression closureExpression = getClosureArgument(call);
- List<Expression> otherArgs = getNonClosureArguments(call);
- String source = convertClosureToSource(closureExpression);
-
- // parameter order is build(CompilePhase, boolean, String)
- otherArgs.add(new ConstantExpression(source));
- call.setArguments(new ArgumentListExpression(otherArgs));
- call.setMethod(new ConstantExpression("buildFromBlock"));
- call.setSpreadSafe(false);
- call.setSafe(false);
- call.setImplicitThis(false);
- } else {
- // continue normal tree walking
- call.getObjectExpression().visit(this);
- call.getMethod().visit(this);
- call.getArguments().visit(this);
- }
+
+ @Override
+ protected boolean handleTargetMethodCallExpression(MethodCallExpression call) {
+ ClosureExpression closureExpression = getClosureArgument(call);
+ List<Expression> otherArgs = getNonClosureArguments(call);
+ String source = convertClosureToSource(closureExpression);
+
+ // parameter order is build(CompilePhase, boolean, String)
+ otherArgs.add(new ConstantExpression(source));
+ call.setArguments(new ArgumentListExpression(otherArgs));
+ call.setMethod(new ConstantExpression("buildFromBlock"));
+ call.setSpreadSafe(false);
+ call.setSafe(false);
+ call.setImplicitThis(false);
+
+ return false;
}
private List<Expression> getNonClosureArguments(MethodCallExpression call) {
@@ -255,7 +144,8 @@ public class AstBuilderTransformation implements ASTTransformation {
*
* @param call the method call expression, may not be null
*/
- private boolean isBuildInvocation(MethodCallExpression call) {
+ @Override
+ protected boolean isBuildInvocation(MethodCallExpression call) {
if (call == null) throw new IllegalArgumentException("Null: call");
// is method name correct?
@@ -281,21 +171,6 @@ public class AstBuilderTransformation implements ASTTransformation {
}
return false;
}
-
- /**
- * Converts a ClosureExpression into the String source.
- *
- * @param expression a closure
- * @return the source the closure was created from
- */
- private String convertClosureToSource(ClosureExpression expression) {
- try {
- return ClosureUtils.convertClosureToSource(source, expression);
- } catch(Exception e) {
- addError(e.getMessage(), expression);
- }
- return null;
- }
}
}
http://git-wip-us.apache.org/repos/asf/incubator-groovy/blob/546868aa/subprojects/groovy-macro/src/main/java/org/codehaus/groovy/macro/transform/MacroInvocationTrap.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-macro/src/main/java/org/codehaus/groovy/macro/transform/MacroInvocationTrap.java b/subprojects/groovy-macro/src/main/java/org/codehaus/groovy/macro/transform/MacroInvocationTrap.java
index 7ac10df..b082e8b 100644
--- a/subprojects/groovy-macro/src/main/java/org/codehaus/groovy/macro/transform/MacroInvocationTrap.java
+++ b/subprojects/groovy-macro/src/main/java/org/codehaus/groovy/macro/transform/MacroInvocationTrap.java
@@ -15,18 +15,15 @@
*/
package org.codehaus.groovy.macro.transform;
-import org.codehaus.groovy.ast.ASTNode;
import org.codehaus.groovy.ast.ClassHelper;
import org.codehaus.groovy.ast.CodeVisitorSupport;
+import org.codehaus.groovy.ast.MethodInvocationTrap;
import org.codehaus.groovy.ast.expr.*;
import org.codehaus.groovy.ast.stmt.BlockStatement;
-import org.codehaus.groovy.ast.tools.ClosureUtils;
import org.codehaus.groovy.control.SourceUnit;
import org.codehaus.groovy.control.io.ReaderSource;
-import org.codehaus.groovy.control.messages.SyntaxErrorMessage;
import org.codehaus.groovy.macro.runtime.MacroBuilder;
import org.codehaus.groovy.macro.runtime.MacroSubstitutionKey;
-import org.codehaus.groovy.syntax.SyntaxException;
import java.util.ArrayList;
import java.util.List;
@@ -37,106 +34,73 @@ import static org.codehaus.groovy.ast.expr.VariableExpression.THIS_EXPRESSION;
*
* @author Sergei Egorov <bs...@gmail.com>
*/
-public class MacroInvocationTrap {
-
- private final ReaderSource source;
- private final SourceUnit sourceUnit;
-
- /**
- * Creates the trap and captures all macro method calls.
- *
- * @param source the reader source that contains source for the SourceUnit
- * @param sourceUnit the source unit being compiled. Used for error messages.
- */
- MacroInvocationTrap(ReaderSource source, SourceUnit sourceUnit) {
- if (source == null) throw new IllegalArgumentException("Null: source");
- if (sourceUnit == null) throw new IllegalArgumentException("Null: sourceUnit");
- this.source = source;
- this.sourceUnit = sourceUnit;
- }
+public class MacroInvocationTrap extends MethodInvocationTrap {
- /**
- * Reports an error back to the source unit.
- *
- * @param msg the error message
- * @param expr the expression that caused the error message.
- */
- private void addError(String msg, ASTNode expr) {
- sourceUnit.getErrorCollector().addErrorAndContinue(
- new SyntaxErrorMessage(new SyntaxException(msg + '\n', expr.getLineNumber(), expr.getColumnNumber(), expr.getLastLineNumber(), expr.getLastColumnNumber()), sourceUnit)
- );
+ public MacroInvocationTrap(ReaderSource source, SourceUnit sourceUnit) {
+ super(source, sourceUnit);
}
- /**
- * Attempts to find 'macro' invocations. When found, converts them into calls
- * to the 'from string' approach.
- *
- * @param macroCall the method call expression that may or may not be a 'macro' invocation.
- */
- public void visitMethodCallExpression(final MethodCallExpression macroCall) {
-
- if (!isBuildInvocation(macroCall, MacroTransformation.MACRO_METHOD)) {
- return;
- }
-
+ @Override
+ protected boolean handleTargetMethodCallExpression(MethodCallExpression macroCall) {
final ClosureExpression closureExpression = getClosureArgument(macroCall);
-
+
if(closureExpression == null) {
- return;
+ return true;
}
if(closureExpression.getParameters() != null && closureExpression.getParameters().length > 0) {
addError("Macro closure arguments are not allowed", closureExpression);
+ return true;
}
-
+
final MapExpression mapExpression = new MapExpression();
-
+
(new CodeVisitorSupport() {
@Override
public void visitMethodCallExpression(MethodCallExpression call) {
super.visitMethodCallExpression(call);
-
+
if(isBuildInvocation(call, MacroTransformation.DOLLAR_VALUE)) {
ClosureExpression substitutionClosureExpression = getClosureArgument(call);
-
+
if(substitutionClosureExpression == null) {
return;
}
MacroSubstitutionKey key = new MacroSubstitutionKey(call, closureExpression.getLineNumber(), closureExpression.getColumnNumber());
-
+
mapExpression.addMapEntryExpression(key.toConstructorCallExpression(), substitutionClosureExpression);
}
}
}).visitClosureExpression(closureExpression);
-
- String source = convertClosureToSource(this.source, closureExpression);
+
+ String source = convertClosureToSource(closureExpression);
BlockStatement closureBlock = (BlockStatement) closureExpression.getCode();
-
+
Boolean asIs = false;
-
+
TupleExpression macroArguments = getMacroArguments(macroCall);
-
+
if(macroArguments == null) {
- return;
+ return true;
}
List<Expression> macroArgumentsExpressions = macroArguments.getExpressions();
-
+
if(macroArgumentsExpressions.size() > 1) {
Expression firstArgument = macroArgumentsExpressions.get(0);
-
+
if(!(firstArgument instanceof ConstantExpression)) {
addError("AsIs argument value should be constant(true or false)", firstArgument);
- return;
+ return true;
}
-
+
ConstantExpression asIsConstantExpression = (ConstantExpression) firstArgument;
-
+
if(!(asIsConstantExpression.getValue() instanceof Boolean)) {
addError("AsIs argument value should be boolean", asIsConstantExpression);
- return;
+ return true;
}
asIs = (Boolean) asIsConstantExpression.getValue();
@@ -153,6 +117,29 @@ public class MacroInvocationTrap {
macroCall.setSpreadSafe(false);
macroCall.setSafe(false);
macroCall.setImplicitThis(false);
+
+ return true;
+ }
+
+ @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) {
@@ -193,41 +180,4 @@ public class MacroInvocationTrap {
return (ClosureExpression) result;
}
-
- /**
- * Looks for 'macro' method calls.
- *
- * @param call the method call expression, may not be null
- */
- 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;
- }
-
- /**
- * Converts a ClosureExpression into the String source.
- *
- * @param expression a closure
- * @return the source the closure was created from
- */
- private String convertClosureToSource(ReaderSource source, ClosureExpression expression) {
-
- try {
- return ClosureUtils.convertClosureToSource(source, expression);
- } catch (Exception e) {
- addError(e.getMessage(), expression);
- }
- return null;
- }
}
http://git-wip-us.apache.org/repos/asf/incubator-groovy/blob/546868aa/subprojects/groovy-macro/src/main/java/org/codehaus/groovy/macro/transform/MacroTransformation.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-macro/src/main/java/org/codehaus/groovy/macro/transform/MacroTransformation.java b/subprojects/groovy-macro/src/main/java/org/codehaus/groovy/macro/transform/MacroTransformation.java
index cdf0f07..65284b5 100644
--- a/subprojects/groovy-macro/src/main/java/org/codehaus/groovy/macro/transform/MacroTransformation.java
+++ b/subprojects/groovy-macro/src/main/java/org/codehaus/groovy/macro/transform/MacroTransformation.java
@@ -15,56 +15,25 @@
*/
package org.codehaus.groovy.macro.transform;
-import org.codehaus.groovy.ast.ASTNode;
-import org.codehaus.groovy.ast.ClassCodeVisitorSupport;
-import org.codehaus.groovy.ast.ClassNode;
-import org.codehaus.groovy.ast.ModuleNode;
-import org.codehaus.groovy.ast.expr.MethodCallExpression;
+import org.codehaus.groovy.ast.*;
import org.codehaus.groovy.control.CompilePhase;
import org.codehaus.groovy.control.SourceUnit;
-import org.codehaus.groovy.transform.ASTTransformation;
import org.codehaus.groovy.transform.GroovyASTTransformation;
/**
*
* @author Sergei Egorov <bs...@gmail.com>
*/
+
@GroovyASTTransformation(phase = CompilePhase.CONVERSION)
-public class MacroTransformation extends ClassCodeVisitorSupport implements ASTTransformation {
+public class MacroTransformation extends MethodCallTransformation {
public static final String DOLLAR_VALUE = "$v";
public static final String MACRO_METHOD = "macro";
- SourceUnit source;
-
- MacroInvocationTrap transformer;
-
- public void visit(ASTNode[] nodes, SourceUnit source) {
- this.source = source;
-
- transformer = new MacroInvocationTrap(source.getSource(), source);
-
- for(ASTNode node : nodes) {
- if(node instanceof ClassNode) {
- visitClass((ClassNode) node);
- } else if(node instanceof ModuleNode) {
- ModuleNode moduleNode = (ModuleNode) node;
- for (ClassNode classNode : moduleNode.getClasses()) {
- visitClass(classNode);
- }
- }
- }
- }
-
- @Override
- public void visitMethodCallExpression(MethodCallExpression call) {
- transformer.visitMethodCallExpression(call);
- super.visitMethodCallExpression(call);
- }
-
@Override
- protected SourceUnit getSourceUnit() {
- return source;
+ protected GroovyCodeVisitor getTransformer(ASTNode[] nodes, SourceUnit sourceUnit) {
+ return new MacroInvocationTrap(sourceUnit.getSource(), sourceUnit);
}
}