groovy
  1. groovy
  2. GROOVY-6585

Extend @BaseScript so that script bodies can be implemented in a method named something other than run.

    Details

    • Type: Improvement Improvement
    • Status: Closed Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 2.3.0-beta-1
    • Component/s: None
    • Labels:
      None
    • Number of attachments :
      0

      Description

      The @BaseScript annotation allows scripts to be compiled as a class other than a direct subclass of Script. There is a problem though if the new base class wants to control the execution of the script body to do things like setup, teardown, and/or conditional/repeated execution.

      The trouble is that the script body is always a method named "run()" and there is no way for the base class to intercept it. Even GroovyInterceptable won't do the job because Script.run() is called from many contexts that do not honor that marker.

      The solution is for the @BaseScript AST transformation to see whether the base script has an abstract method declared that it should use instead of the default "run()".

        Activity

        Hide
        Jim White added a comment -

        There is a conflict with the @Field and @Secure AST transforms where they assume the script body name is "run". This is fairly easy to work around, at least for @Field, by putting the @BaseScript notation after them.

        I think that the check in MethodNode.isScriptBody() for the method's name to match "run" can be safely removed (how would it ever fail?).

        For @Secure I haven't looked into what the impact is exactly. There is the check in SecureASTCustomizer.filterMethods that only yields "main" and "run" which might block the call to the script, but I'm not sure since "run()" is declared in the parent (base) script and so could be called just like any other method in a class.

        Show
        Jim White added a comment - There is a conflict with the @Field and @Secure AST transforms where they assume the script body name is "run". This is fairly easy to work around, at least for @Field, by putting the @BaseScript notation after them. I think that the check in MethodNode.isScriptBody() for the method's name to match "run" can be safely removed (how would it ever fail?). For @Secure I haven't looked into what the impact is exactly. There is the check in SecureASTCustomizer.filterMethods that only yields "main" and "run" which might block the call to the script, but I'm not sure since "run()" is declared in the parent (base) script and so could be called just like any other method in a class.
        Hide
        Jim White added a comment -

        Pull request for implementation (including a test) on github: https://github.com/groovy/groovy-core/pull/328

        The test case shows that there some bug with the way @BaseScript works for fields in the base script (they can be read but not written properly) but I don't have time for that JIRA at the moment...

        Show
        Jim White added a comment - Pull request for implementation (including a test) on github: https://github.com/groovy/groovy-core/pull/328 The test case shows that there some bug with the way @BaseScript works for fields in the base script (they can be read but not written properly) but I don't have time for that JIRA at the moment...
        Show
        CÚdric Champeau added a comment - PR merged. See https://github.com/groovy/groovy-core/commit/0f9981b406b3627f0768095fd5b5dde1ae25a450 Thank you!

          People

          • Assignee:
            Jim White
            Reporter:
            Jim White
          • Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: