DSL Code Complete?

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

DSL Code Complete?

Paul Wilson
Hi there,

I have a closure style DSL that I'm working on, and an associated DSLD too. It is typical closure-based builder style affair:

method {
   foo "bar"
}

Some questions:

 * I can't seem to find a way of prescribing required methods/properties within a closure, such that auto-complete provides them, is there a way to do this?
 * I'd like method calls to auto-complete without the parens, there seems to be tick-box within the groovy properties that suggests that I should be able to force this behaviour, but it doesn't appear to have an effect "Do not use parens around methods with arguments"
 * Is it possible to exclude all of the other methods calls that are external to my DSL from the autocomplete window, such as 'evaluate(File file)' as these are confusing?

Regards,
Paul 
Reply | Threaded
Open this post in threaded view
|

Re: DSL Code Complete?

Andrew Eisenberg
>  * I can't seem to find a way of prescribing required methods/properties
> within a closure, such that auto-complete provides them, is there a way to
> do this?

There is a way of doing this, but it is not direct.  You can only add
properties/methods to a given type. So, you need to know what the
inferred delegate type of the closure body is.  Typically, in the
inferencing engine, the delegate type is declaring type of the
enclosing method.  So:

new Foo().method {
   ...here...
}

In 'here' the delegate type is inferred to be Foo.  And so, you need
to add the methods and properties to 'Foo'.  Currently, this is hard
coded and I know that this is not correct in many cases, but it is
correct in enough cases that it works reasonably well.

You may want to keep an eye on this bug, which is describing exactly
what you need:
http://jira.codehaus.org/browse/GRECLIPSE-1298

The solution here would be to be able to have a bit of DSLD syntax
that allows you to specify the delegate type inside of a closure, but
I haven't really looked at what the syntax and implementation would
be.

>  * I'd like method calls to auto-complete without the parens, there seems to
> be tick-box within the groovy properties that suggests that I should be able
> to force this behaviour, but it doesn't appear to have an effect "Do not use
> parens around methods with arguments"

Not really.  This feature never worked terribly well since the
inferencing engine needs to determine when parens are needed even if
this preference is set.  Eg-

method1 method2(arg1), arg2

Figuring out that we need parens around arg1 is just something I never
spent much time on.  It's something I could revisit, though.  But, it
is surprisingly not a small task.  There would also need to be a way
to specify these kinds of methods in DSLD.

>  * Is it possible to exclude all of the other methods calls that are
> external to my DSL from the autocomplete window, such as 'evaluate(File
> file)' as these are confusing?

There is nothing available to specify that methods should be filtered
only inside a DSL, but there is a preference that allows you to filter
out DGMs (like inspect, evaluate, each, ...) from contents assist.  Go
to Preferences -> Groovy -> Content Assist.  Just add the list of
methods you want filtered and they won't bother you.

However, this is a workspace wide setting, and you would need to ask
your users to enter this information manually.

Feel free to raise a jira issue to describe the exact feature you are
looking for.

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|

Re: DSL Code Complete?

btiernay
In reply to this post by Paul Wilson
If you are trying to achieve something like grail's resources.groovy where you have single file that assigns a closure to a binding variable, the easiest way of "prescribing required methods/properties within a closure" is to simply use enclosingCallName("method"). You can use this in conjunction with fileName("my-file.groovy") to limit the scope of the pointcut.

One thing I find annoying is that, from what I understand, one cannot limit the call to the top-level scope of closure body. What this means is that if you have a structure like:

reports = {
   report {
      params {
          param(...)
      }
   }
}

You cannot limit the applicability of the "param" to "params" unless you do something like the following in your DSLD file:

// Base pointcuts
def reportsFile = fileName("report-definitions.groovy")
def reportsCall = enclosingClosure()
def reportCall  = enclosingCallName("report")
def paramsCall  = enclosingCallName("params")

// Composite pointcuts
def globalScope  = reportsFile & ~reportsCall & ~reportCall & ~paramsCall
def reportsScope = reportsFile & reportsCall & ~reportCall & ~paramsCall
def reportScope  = reportsFile & reportCall & ~paramsCall
def paramsScope  = reportsFile & paramsCall

As you can see, you have to exclude all other scopes to achieve the desired effect. It would be nice if there were a pointcut like enclosingScopeCallName that provided this capability since it is often what is required for builder-based DSLs.
Reply | Threaded
Open this post in threaded view
|

Re: DSL Code Complete?

Andrew Eisenberg
Thanks for explaining this.  It would be helpful if you could add a
comment on http://jira.codehaus.org/browse/GRECLIPSE-1298 to mention
your workaround.  We can try to find a better way of expressing this.

On Mon, Jan 2, 2012 at 10:56 AM, btiernay <[hidden email]> wrote:

> If you are trying to achieve something like grail's resources.groovy where
> you have single file that assigns a closure to a binding variable, the
> easiest way of "prescribing required methods/properties within a closure" is
> to simply use enclosingCallName("method"). You can use this in conjunction
> with fileName("my-file.groovy") to limit the scope of the pointcut.
>
> One thing I find annoying is that, from what I understand, one cannot limit
> the call to the top-level scope of closure body. What this means is that if
> you have a structure like:
>
> reports = {
>   report {
>      params {
>          param(...)
>      }
>   }
> }
>
> You cannot limit the applicability of the "param" to "params" unless you do
> something like the following in your DSLD file:
>
> // Base pointcuts
> def reportsFile = fileName("report-definitions.groovy")
> def reportsCall = enclosingClosure()
> def reportCall  = enclosingCallName("report")
> def paramsCall  = enclosingCallName("params")
>
> // Composite pointcuts
> def globalScope  = reportsFile & ~reportsCall & ~reportCall & ~paramsCall
> def reportsScope = reportsFile & reportsCall & ~reportCall & ~paramsCall
> def reportScope  = reportsFile & reportCall & ~paramsCall
> def paramsScope  = reportsFile & paramsCall
>
> As you can see, you have to exclude all other scopes to achieve the desired
> effect. It would be nice if there were a pointcut like
> enclosingScopeCallName that provided this capability since it is often what
> is required for builder-based DSLs.
>
> --
> View this message in context: http://groovy-eclipse-plugin.42567.n3.nabble.com/DSL-Code-Complete-tp3625705p3627306.html
> Sent from the groovy-eclipse-plugin-user mailing list archive at Nabble.com.
>
> ---------------------------------------------------------------------
> To unsubscribe from this list, please visit:
>
>    http://xircles.codehaus.org/manage_email
>
>

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|

Re: DSL Code Complete?

btiernay
Thanks for replying Andrew. I have added a comment to the jira.

Bob