Uploaded image for project: 'Groovy'
  1. Groovy
  2. GROOVY-2643

Delegate property is ignored by closure

Attach filesAttach ScreenshotVotersWatch issueWatchersCreate sub-taskLinkCloneUpdate Comment AuthorReplace String in CommentUpdate Comment VisibilityDelete Comments
    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Blocker
    • Resolution: Fixed
    • 1.5.4, 1.6-beta-1
    • 1.5.5, 1.6-beta-1
    • None
    • None

    Description

      I have attached the following test case. It is interesting to see that the testDelegateFileMethodAccess fails, whereas the other test where delegate methods are accessed succeed. All tests with property access fail. This is a serious bug which for example prevents me to offer important DSL functionality for my build tool.

      import org.apache.tools.ant.Project
      
      class ClosureBug extends GroovyTestCase {
          String expectedFileResult
      
          void setUp() {
              expectedFileResult = 'path'
          }
      
          void testDelegateAntPropertyAccess() {
              assert script(antScriptText('antProject')).run() instanceof Project
          }
      
          void testDelegateAntMethodAccess() {
              assert script(antScriptText('getAntProject()')).run() instanceof Project
          }
      
          void testDelegateFilePropertyAccess() {
              assert script(fileScriptText('path')).run() == expectedFileResult
          }
      
          void testDelegateFileMethodAccess() {
              assert script(fileScriptText('getPath()')).run() == expectedFileResult
          }
      
          void testDelegateCircleAccessGetterWithoutField() {
              assert script(circleScriptText('getProp3()')).run() == 'value3'
          }
      
          void testDelegateCircleAccessGetterWithField() {
              assert script(circleScriptText('getProp2()')).run() == 'value2'
          }
      
          void testDelegateCircleAccessDynamicGetter() {
              assert script(circleScriptText('getProp1()')).run() == 'value1'
          }
      
          void testDelegateCircleAccessPropertyWithoutGetter() {
              assert script(circleScriptText('prop1')).run() == 'value1'
          }
      
          void testDelegateCircleAccessPropertyWithGetter() {
              assert script(circleScriptText('prop2')).run() == 'value2'
          }
      
          void testDelegateCircleAccessPropertyWithoutField() {
              assert script(circleScriptText('prop3')).run() == 'value3'
          }
      
      
          def replaceMetaclass(Script script) {
              ExpandoMetaClass emc = new ExpandoMetaClass(script.class, false)
              emc.methodMissing = {String name, args ->
                  throw new MissingMethodException(name, Script, args)
              }
              emc.propertyMissing = {String name ->
                  throw new MissingPropertyException(name, Script)
              }
              emc.initialize()
              script.metaClass = emc
          }
      
          Script script(String text) {
              GroovyShell groovyShell = new GroovyShell()
              Script script = groovyShell.parse(text)
              replaceMetaclass(script)
              script
          }
      
          String antScriptText(String accessDirective) {
              """          
      AntBuilder ant = new AntBuilder()
      Closure cl = {
           $accessDirective
      }
      cl.delegate = ant
      cl.call()"""
          }
      
          String fileScriptText(String accessDirective) {
              """
      File file = new File('$expectedFileResult')
      Closure cl = {
           $accessDirective
      }
      cl.delegate = file
      cl.call()"""
          }
      
          String circleScriptText(String accessDirective) {
              """
      Circle circle = new Circle()
      Closure cl = {
           $accessDirective
      }
      cl.delegate = circle
      cl.call()"""
          }
      }
      
      class Circle {
          String prop1 = 'value1'
          String prop2 = 'value2'
      
          String getProp2() {
              prop2
          }
      
          String getProp3() {
              'value3'
          }
      
      }
      

      Attachments

        Issue Links

        Activity

          This comment will be Viewable by All Users Viewable by All Users
          Cancel

          People

            blackdrag Jochen Theodorou
            hans_d Hans Dockter
            Votes:
            1 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Slack

                Issue deployment