nextflow.ast.TaskTemplateVisitor.groovy Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of nextflow Show documentation
Show all versions of nextflow Show documentation
A DSL modelled around the UNIX pipe concept, that simplifies writing parallel and scalable pipelines in a portable manner
The newest version!
/*
* Copyright 2013-2024, Seqera Labs
*
* 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 nextflow.ast
import groovy.transform.CompileStatic
import org.codehaus.groovy.ast.ClassNode
import org.codehaus.groovy.ast.ConstructorNode
import org.codehaus.groovy.ast.expr.ArgumentListExpression
import org.codehaus.groovy.ast.expr.ConstantExpression
import org.codehaus.groovy.ast.expr.GStringExpression
import org.codehaus.groovy.ast.expr.ListExpression
import org.codehaus.groovy.ast.expr.MethodCallExpression
import org.codehaus.groovy.ast.expr.VariableExpression
import org.codehaus.groovy.ast.stmt.BlockStatement
import org.codehaus.groovy.ast.stmt.ExpressionStatement
import org.codehaus.groovy.ast.stmt.Statement
import org.codehaus.groovy.control.SourceUnit
/**
* Inject string var names in the script binding object
*
* @author Paolo Di Tommaso
*/
@CompileStatic
class TaskTemplateVisitor extends VariableVisitor {
int withinGString
TaskTemplateVisitor(SourceUnit unit) {
super(unit)
}
@Override
protected boolean scopeEnabled() {
return withinGString>0
}
@Override
void visitGStringExpression(GStringExpression expression) {
try {
withinGString++
super.visitGStringExpression(expression)
}
finally {
withinGString--
}
}
@Override
protected void visitObjectInitializerStatements(ClassNode node) {
injectMetadata(node)
super.visitObjectInitializerStatements(node)
}
protected void injectMetadata(ClassNode node) {
// inject the invocation of a custom method
// as last statement of the constructor invocation
for( ConstructorNode constructor : node.getDeclaredConstructors() ) {
def code = constructor.getCode()
if( code instanceof BlockStatement ) {
code.addStatement(makeSetVariableNamesStm())
}
else if( code instanceof ExpressionStatement ) {
def expr = code
def block = new BlockStatement()
block.addStatement(expr)
block.addStatement(makeSetVariableNamesStm())
constructor.setCode(block)
}
else
throw new IllegalStateException("Invalid constructor expression: $code")
}
}
protected Statement makeSetVariableNamesStm() {
final names = new ListExpression()
for( String it: getAllVariableNames() ) {
names.addExpression(new ConstantExpression(it))
}
final varArgs = new ArgumentListExpression()
varArgs.addExpression( new ConstantExpression('__$$_template_vars') )
varArgs.addExpression( names )
// some magic code
// this generates the invocation of the method:
// this.getBinding().setVariable('__$$_template_vars', [variable names])
final thiz = new VariableExpression('this')
final bind = new MethodCallExpression( thiz, 'getBinding', ArgumentListExpression.EMPTY_ARGUMENTS )
final call = new MethodCallExpression( bind, 'setVariable', varArgs )
final stm = new ExpressionStatement(call)
return stm
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy