Skip to content

Commit dff88b5

Browse files
committed
Fix detection of tap assignment (close #89)
Signed-off-by: Ben Sherman <bentshermann@gmail.com>
1 parent 34e5fdc commit dff88b5

File tree

2 files changed

+32
-24
lines changed

2 files changed

+32
-24
lines changed

modules/compiler/src/main/java/script/control/VariableScopeVisitor.java

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -456,15 +456,6 @@ public void visitExpressionStatement(ExpressionStatement node) {
456456
}
457457
return;
458458
}
459-
if( exp instanceof MethodCallExpression mce ) {
460-
var source = mce.getObjectExpression();
461-
var target = checkSetAssignment(mce);
462-
if( target != null ) {
463-
visit(source);
464-
declareAssignedVariable(target);
465-
return;
466-
}
467-
}
468459
super.visitExpressionStatement(node);
469460
}
470461

@@ -562,21 +553,6 @@ private void checkExternalWriteInAsyncClosure(VariableExpression target, Variabl
562553
addFutureWarning("Mutating an external variable in an operator closure may lead to a race condition", target, "External variable declared here", (ASTNode) variable);
563554
}
564555

565-
/**
566-
* Treat `set` operator as an assignment.
567-
*/
568-
private VariableExpression checkSetAssignment(MethodCallExpression node) {
569-
if( !(currentDefinition instanceof WorkflowNode) )
570-
return null;
571-
var name = node.getMethodAsString();
572-
if( !"set".equals(name) )
573-
return null;
574-
var code = asDslBlock(node, 1);
575-
if( code == null || code.getStatements().size() != 1 )
576-
return null;
577-
return asVarX(code.getStatements().get(0));
578-
}
579-
580556
// expressions
581557

582558
private static final List<String> KEYWORDS = List.of(
@@ -588,6 +564,15 @@ private VariableExpression checkSetAssignment(MethodCallExpression node) {
588564

589565
@Override
590566
public void visitMethodCallExpression(MethodCallExpression node) {
567+
if( !node.isImplicitThis() ) {
568+
var source = node.getObjectExpression();
569+
var target = checkSetAssignment(node);
570+
if( target != null ) {
571+
visit(source);
572+
declareAssignedVariable(target);
573+
return;
574+
}
575+
}
591576
if( node.isImplicitThis() && node.getMethod() instanceof ConstantExpression ) {
592577
var name = node.getMethodAsString();
593578
var variable = findVariableDeclaration(name, node);
@@ -599,6 +584,21 @@ public void visitMethodCallExpression(MethodCallExpression node) {
599584
super.visitMethodCallExpression(node);
600585
}
601586

587+
/**
588+
* Treat `set` and `tap` operators as assignments.
589+
*/
590+
private VariableExpression checkSetAssignment(MethodCallExpression node) {
591+
if( !(currentDefinition instanceof WorkflowNode) )
592+
return null;
593+
var name = node.getMethodAsString();
594+
if( !"set".equals(name) && !"tap".equals(name) )
595+
return null;
596+
var code = asDslBlock(node, 1);
597+
if( code == null || code.getStatements().size() != 1 )
598+
return null;
599+
return asVarX(code.getStatements().get(0));
600+
}
601+
602602
@Override
603603
public void visitDeclarationExpression(DeclarationExpression node) {
604604
visit(node.getRightExpression());

modules/compiler/src/main/java/script/types/Channel.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,14 @@ public static Channel<Path> watchPath(String filePattern, String events) {
419419
""")
420420
public abstract Channel take(int n);
421421

422+
@Operator
423+
@Description("""
424+
The `tap` operator assigns a source channel to a variable, whose name is specified in a closure.
425+
426+
[Read more](https://nextflow.io/docs/latest/reference/operator.html#tap)
427+
""")
428+
public abstract Channel tap(Closure holder);
429+
422430
@Operator
423431
@Description("""
424432
The `toList` operator collects all the values from a source channel into a list and emits the list as a single value.

0 commit comments

Comments
 (0)