groovy-notifications mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From melix <...@git.apache.org>
Subject [GitHub] groovy pull request #472: Macro methods
Date Mon, 27 Feb 2017 18:07:35 GMT
Github user melix commented on a diff in the pull request:

    https://github.com/apache/groovy/pull/472#discussion_r103271019
  
    --- Diff: subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroTransformation.java
---
    @@ -18,42 +18,113 @@
      */
     package org.codehaus.groovy.macro.transform;
     
    +import groovy.transform.CompilationUnitAware;
     import org.codehaus.groovy.ast.*;
     import org.codehaus.groovy.ast.expr.*;
    +import org.codehaus.groovy.classgen.asm.InvocationWriter;
    +import org.codehaus.groovy.control.CompilationUnit;
     import org.codehaus.groovy.control.CompilePhase;
     import org.codehaus.groovy.control.SourceUnit;
    +import org.codehaus.groovy.macro.runtime.MacroContext;
    +import org.codehaus.groovy.macro.runtime.MacroStub;
    +import org.codehaus.groovy.runtime.InvokerHelper;
     import org.codehaus.groovy.transform.GroovyASTTransformation;
    +import org.codehaus.groovy.transform.stc.ExtensionMethodNode;
    +import org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport;
    +
    +import java.util.ArrayList;
    +import java.util.List;
     
     /**
    - *
      * @author Sergei Egorov <bsideup@gmail.com>
      */
     
     @GroovyASTTransformation(phase = CompilePhase.CONVERSION)
    -public class MacroTransformation extends MethodCallTransformation {
    +public class MacroTransformation extends MethodCallTransformation implements CompilationUnitAware
{
    +
    +    private static final ClassNode MACRO_CONTEXT_CLASS_NODE = ClassHelper.make(MacroContext.class);
    +
    +    private static final ClassNode MACRO_STUB_CLASS_NODE = ClassHelper.make(MacroStub.class);
    +
    +    private static final PropertyExpression MACRO_STUB_INSTANCE = new PropertyExpression(new
ClassExpression(MACRO_STUB_CLASS_NODE), "INSTANCE");
    +
    +    private static final String MACRO_STUB_METHOD_NAME = "macroMethod";
    +
    +    protected CompilationUnit unit;
     
    -    public static final String DOLLAR_VALUE = "$v";
    -    public static final String MACRO_METHOD = "macro";
    +    @Override
    +    public void setCompilationUnit(CompilationUnit unit) {
    +        this.unit = unit;
    +    }
     
         @Override
    -    protected GroovyCodeVisitor getTransformer(final ASTNode[] nodes, final SourceUnit
sourceUnit) {
    -        final ClassCodeExpressionTransformer trn = new ClassCodeExpressionTransformer()
{
    +    protected GroovyCodeVisitor getTransformer(ASTNode[] nodes, final SourceUnit sourceUnit)
{
    +        // Macro methods should on a classpath of the compiler because we invoke them
during the compilation
    +        final ClassLoader classLoader = this.getClass().getClassLoader();
    +        return new ClassCodeVisitorSupport() {
    +
                 @Override
                 protected SourceUnit getSourceUnit() {
                     return sourceUnit;
                 }
     
                 @Override
    -            public Expression transform(final Expression exp) {
    -                if (exp instanceof ConstructorCallExpression) {
    -                    MethodCallExpression call = exp.getNodeMetaData(MacroTransformation.class);
    -                    if (call!=null) {
    -                        return call;
    +            public void visitMethodCallExpression(MethodCallExpression call) {
    +                super.visitMethodCallExpression(call);
    +
    +                List<MethodNode> methods = MacroMethodsCache.get(classLoader).get(call.getMethodAsString());
    +
    +                if (methods == null) {
    +                    // Not a macro call
    +                    return;
    +                }
    +
    +                List<Expression> callArguments = InvocationWriter.makeArgumentList(call.getArguments()).getExpressions();
    +
    +                ClassNode[] argumentsList = new ClassNode[callArguments.size()];
    +
    +                for (int i = 0; i < callArguments.size(); i++) {
    +                    argumentsList[i] = ClassHelper.make(callArguments.get(i).getClass());
    +                }
    +
    +                methods = StaticTypeCheckingSupport.chooseBestMethod(MACRO_CONTEXT_CLASS_NODE,
methods, argumentsList);
    +
    +                for (MethodNode macroMethodNode : methods) {
    +                    if (!(macroMethodNode instanceof ExtensionMethodNode)) {
    +                        // TODO is it even possible?
    --- End diff --
    
    If you don't know if it's possible, it's probably better to throw an error. Then if the
case appears we know we need to fix it.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

Mime
View raw message