Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-62064

CPS-transformed assignment expressions evaluate to null instead of the value of the RHS

    • workflow-cps 3520.va_8fc49e2f96f

      As described in https://stackoverflow.com/questions/61420959/jenkins-interpretation-of-multiple-object-declarations-on-one-line, CPS-transformed assignment expressions evaluate to null instead of the value of the RHS of the expression. Here is an example:

      def a = b = c = 1 

      In a Pipeline, after executing that expression a == null, b == null, and c == 1.

      In regular Groovy, after executing that expression, a, b, and c, are all equal to 1.

      Here is a (failing) workflow-cps test case (for CpsFlowDefinition2Test) that demonstrates the bug:

      @Test public void assignmentExprsReturnRhs() throws Exception {
          WorkflowJob p = jenkins.createProject(WorkflowJob.class);
          p.setDefinition(new CpsFlowDefinition(
                  "def a = b = c = 1\n" +
                  "println([a, b, c].toString())", true));
          WorkflowRun b = jenkins.buildAndAssertSuccess(p);
          jenkins.assertLogContains("[1, 1, 1]", b); // Actual output today is "[null, null, 1]".
      } 

      I think the relevant code is AssignmentBlock in groovy-cps. In particular, I think that assignAndDone needs to create a new continuation to pass to lhs.set that calls k.receive(rhs) internally.

          [JENKINS-62064] CPS-transformed assignment expressions evaluate to null instead of the value of the RHS

          Devin Nusbaum created issue -
          Devin Nusbaum made changes -
          Summary Original: CPS transformed assignment expressions do not return their result New: CPS-transformed assignment expressions do not return their result
          Devin Nusbaum made changes -
          Summary Original: CPS-transformed assignment expressions do not return their result New: CPS-transformed assignment expressions evaluate to null instead of the value of the RHS
          Devin Nusbaum made changes -
          Description Original: As described in [https://stackoverflow.com/questions/61420959/jenkins-interpretation-of-multiple-object-declarations-on-one-line], CPS-transformed assignment expressions do not return their result. Here is an example:
          {code:java}
          def a = b = c = 1 {code}
          In a Pipeline, after executing that expression {{a == null}}, {{b == null}}, and {{c == 1}}.

          In regular Groovy, after executing that expression, {{a}}, {{b}}, and {{c}}, are all equal to 1.

          Here is a (failing) {{workflow-cps}} test case (for {{CpsFlowDefinition2Test}}) that demonstrates the bug:
          {code:java}
          @Test public void assignmentExprsReturnRhs() throws Exception {
              WorkflowJob p = jenkins.createProject(WorkflowJob.class);
              p.setDefinition(new CpsFlowDefinition(
                      "def a = b = c = 1\n" +
                      "println(/a == ${a}/)\n" +
                      "println(/b == ${b}/)\n" +
                      "println(/c == ${c}/)\n", true));
              WorkflowRun b = jenkins.buildAndAssertSuccess(p);
              jenkins.assertLogContains("a == 1", b);
              jenkins.assertLogContains("b == 1", b);
              jenkins.assertLogContains("c == 1", b);
          } {code}
          I think the relevant code is [AssignmentBlock|https://github.com/cloudbees/groovy-cps/blob/94939d33fab9b04be76b9fbd0477b9807bf1ad32/lib/src/main/java/com/cloudbees/groovy/cps/impl/AssignmentBlock.java] in {{groovy-cps}}. In particular, I think that [assignAndDone|https://github.com/cloudbees/groovy-cps/blob/94939d33fab9b04be76b9fbd0477b9807bf1ad32/lib/src/main/java/com/cloudbees/groovy/cps/impl/AssignmentBlock.java#L70] needs to create a new continuation to pass to {{lhs.set}} that calls {{k.receive(rhs)}} internally.
          New: As described in [https://stackoverflow.com/questions/61420959/jenkins-interpretation-of-multiple-object-declarations-on-one-line], CPS-transformed assignment expressions evaluate to {{null}} instead of the value of the RHS of the expression. Here is an example:
          {code:java}
          def a = b = c = 1 {code}
          In a Pipeline, after executing that expression {{a == null}}, {{b == null}}, and {{c == 1}}.

          In regular Groovy, after executing that expression, {{a}}, {{b}}, and {{c}}, are all equal to 1.

          Here is a (failing) {{workflow-cps}} test case (for {{CpsFlowDefinition2Test}}) that demonstrates the bug:
          {code:java}
          @Test public void assignmentExprsReturnRhs() throws Exception {
              WorkflowJob p = jenkins.createProject(WorkflowJob.class);
              p.setDefinition(new CpsFlowDefinition(
                      "def a = b = c = 1\n" +
                      "println(/a == ${a}/)\n" +
                      "println(/b == ${b}/)\n" +
                      "println(/c == ${c}/)\n", true));
              WorkflowRun b = jenkins.buildAndAssertSuccess(p);
              jenkins.assertLogContains("a == 1", b);
              jenkins.assertLogContains("b == 1", b);
              jenkins.assertLogContains("c == 1", b);
          } {code}
          I think the relevant code is [AssignmentBlock|https://github.com/cloudbees/groovy-cps/blob/94939d33fab9b04be76b9fbd0477b9807bf1ad32/lib/src/main/java/com/cloudbees/groovy/cps/impl/AssignmentBlock.java] in {{groovy-cps}}. In particular, I think that [assignAndDone|https://github.com/cloudbees/groovy-cps/blob/94939d33fab9b04be76b9fbd0477b9807bf1ad32/lib/src/main/java/com/cloudbees/groovy/cps/impl/AssignmentBlock.java#L70] needs to create a new continuation to pass to {{lhs.set}} that calls {{k.receive(rhs)}} internally.
          Devin Nusbaum made changes -
          Description Original: As described in [https://stackoverflow.com/questions/61420959/jenkins-interpretation-of-multiple-object-declarations-on-one-line], CPS-transformed assignment expressions evaluate to {{null}} instead of the value of the RHS of the expression. Here is an example:
          {code:java}
          def a = b = c = 1 {code}
          In a Pipeline, after executing that expression {{a == null}}, {{b == null}}, and {{c == 1}}.

          In regular Groovy, after executing that expression, {{a}}, {{b}}, and {{c}}, are all equal to 1.

          Here is a (failing) {{workflow-cps}} test case (for {{CpsFlowDefinition2Test}}) that demonstrates the bug:
          {code:java}
          @Test public void assignmentExprsReturnRhs() throws Exception {
              WorkflowJob p = jenkins.createProject(WorkflowJob.class);
              p.setDefinition(new CpsFlowDefinition(
                      "def a = b = c = 1\n" +
                      "println(/a == ${a}/)\n" +
                      "println(/b == ${b}/)\n" +
                      "println(/c == ${c}/)\n", true));
              WorkflowRun b = jenkins.buildAndAssertSuccess(p);
              jenkins.assertLogContains("a == 1", b);
              jenkins.assertLogContains("b == 1", b);
              jenkins.assertLogContains("c == 1", b);
          } {code}
          I think the relevant code is [AssignmentBlock|https://github.com/cloudbees/groovy-cps/blob/94939d33fab9b04be76b9fbd0477b9807bf1ad32/lib/src/main/java/com/cloudbees/groovy/cps/impl/AssignmentBlock.java] in {{groovy-cps}}. In particular, I think that [assignAndDone|https://github.com/cloudbees/groovy-cps/blob/94939d33fab9b04be76b9fbd0477b9807bf1ad32/lib/src/main/java/com/cloudbees/groovy/cps/impl/AssignmentBlock.java#L70] needs to create a new continuation to pass to {{lhs.set}} that calls {{k.receive(rhs)}} internally.
          New: As described in [https://stackoverflow.com/questions/61420959/jenkins-interpretation-of-multiple-object-declarations-on-one-line], CPS-transformed assignment expressions evaluate to {{null}} instead of the value of the RHS of the expression. Here is an example:
          {code:java}
          def a = b = c = 1 {code}
          In a Pipeline, after executing that expression {{a == null}}, {{b == null}}, and {{c == 1}}.

          In regular Groovy, after executing that expression, {{a}}, {{b}}, and {{c}}, are all equal to 1.

          Here is a (failing) {{workflow-cps}} test case (for {{CpsFlowDefinition2Test}}) that demonstrates the bug:
          {code:java}
          @Test public void assignmentExprsReturnRhs() throws Exception {
              WorkflowJob p = jenkins.createProject(WorkflowJob.class);
              p.setDefinition(new CpsFlowDefinition(
                      "def a = b = c = 1\n" +
                      "println([a, b, c].toString())", true));
              WorkflowRun b = jenkins.buildAndAssertSuccess(p);
              jenkins.assertLogContains("[1, 1, 1]", b); // Actual output today is "[null, null, 1]".
          } {code}
          I think the relevant code is [AssignmentBlock|https://github.com/cloudbees/groovy-cps/blob/94939d33fab9b04be76b9fbd0477b9807bf1ad32/lib/src/main/java/com/cloudbees/groovy/cps/impl/AssignmentBlock.java] in {{groovy-cps}}. In particular, I think that [assignAndDone|https://github.com/cloudbees/groovy-cps/blob/94939d33fab9b04be76b9fbd0477b9807bf1ad32/lib/src/main/java/com/cloudbees/groovy/cps/impl/AssignmentBlock.java#L70] needs to create a new continuation to pass to {{lhs.set}} that calls {{k.receive(rhs)}} internally.
          Devin Nusbaum made changes -
          Remote Link New: This issue links to "cloudbees/groovy-cps#108 (Web Link)" [ 24898 ]
          Devin Nusbaum made changes -
          Assignee New: Devin Nusbaum [ dnusbaum ]
          Devin Nusbaum made changes -
          Status Original: Open [ 1 ] New: In Progress [ 3 ]
          Devin Nusbaum made changes -
          Status Original: In Progress [ 3 ] New: In Review [ 10005 ]
          Devin Nusbaum made changes -
          Resolution New: Fixed [ 1 ]
          Status Original: In Review [ 10005 ] New: Fixed but Unreleased [ 10203 ]
          Devin Nusbaum made changes -
          Released As New: workflow-cps 3520.va_8fc49e2f96f
          Status Original: Fixed but Unreleased [ 10203 ] New: Resolved [ 5 ]

            dnusbaum Devin Nusbaum
            dnusbaum Devin Nusbaum
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: