Skip to content

Commit c15b5fe

Browse files
committed
Improve handling of set operator
Signed-off-by: Ben Sherman <bentshermann@gmail.com>
1 parent 5d83b5c commit c15b5fe

File tree

1 file changed

+29
-24
lines changed

1 file changed

+29
-24
lines changed

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

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -453,10 +453,21 @@ public void visitExpressionStatement(ExpressionStatement node) {
453453
visitMutatedVariable(target);
454454
visit(target);
455455
}
456+
return;
456457
}
457-
else {
458-
super.visitExpressionStatement(node);
458+
if( exp instanceof MethodCallExpression mce ) {
459+
var source = mce.getObjectExpression();
460+
var target = checkSetAssignment(mce);
461+
if( target != null ) {
462+
visit(source);
463+
declareAssignedVariable(target);
464+
var ae = new AssignmentExpression(target, source);
465+
ae.setSourcePosition(mce);
466+
node.setExpression(ae);
467+
return;
468+
}
459469
}
470+
super.visitExpressionStatement(node);
460471
}
461472

462473
/**
@@ -485,6 +496,7 @@ private boolean declareAssignedVariable(VariableExpression ve) {
485496
addError("Built-in variable cannot be re-assigned", ve);
486497
else
487498
checkExternalWriteInClosure(ve, variable);
499+
ve.setAccessedVariable(variable);
488500
return false;
489501
}
490502
else if( currentDefinition instanceof ProcessNode || currentDefinition instanceof WorkflowNode ) {
@@ -549,6 +561,21 @@ private void checkExternalWriteInClosure(VariableExpression target, Variable var
549561
addFutureWarning("Mutating an external variable in a closure may lead to a race condition", target, "External variable declared here", (ASTNode) variable);
550562
}
551563

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

554581
private static final List<String> KEYWORDS = List.of(
@@ -560,9 +587,6 @@ private void checkExternalWriteInClosure(VariableExpression target, Variable var
560587

561588
@Override
562589
public void visitMethodCallExpression(MethodCallExpression node) {
563-
if( currentDefinition instanceof WorkflowNode ) {
564-
visitAssignmentOperator(node);
565-
}
566590
if( node.isImplicitThis() && node.getMethod() instanceof ConstantExpression ) {
567591
var name = node.getMethodAsString();
568592
var variable = findVariableDeclaration(name, node);
@@ -574,25 +598,6 @@ public void visitMethodCallExpression(MethodCallExpression node) {
574598
super.visitMethodCallExpression(node);
575599
}
576600

577-
/**
578-
* Treat `set` operator as an assignment.
579-
*/
580-
private void visitAssignmentOperator(MethodCallExpression node) {
581-
var name = node.getMethodAsString();
582-
if( !("set".equals(name) || "tap".equals(name)) )
583-
return;
584-
var code = asDslBlock(node, 1);
585-
if( code == null || code.getStatements().size() != 1 )
586-
return;
587-
var varX = asVarX(code.getStatements().get(0));
588-
if( varX == null )
589-
return;
590-
var scope = currentScope;
591-
currentScope = currentDefinition.getVariableScope();
592-
declare(varX);
593-
currentScope = scope;
594-
}
595-
596601
@Override
597602
public void visitDeclarationExpression(DeclarationExpression node) {
598603
visit(node.getRightExpression());

0 commit comments

Comments
 (0)