On 25/11/2011, at 12:31 AM, Adam Murdoch wrote:

> This is another small step towards a cross-cutting DSL. The idea is that when 
> you define a hook point, you add a method that takes an Action<SomeType> to 
> the API, so that the hook is usable from java and other not-groovy languages, 
> and the DSL mapping takes care of making it easier to use from the DSL. Also 
> useful for factory methods such as RepositoryHandler.ivy(Action) and friends.

What about the return type? Can that be anything?

> I'll update the DSL reference guide generation at some point soon to take 
> this (and the 'set method', ie the generated void <propName>(value) method) 
> into account.

Don't follow here sorry.

> One question is how should we figure out which types are decorated, for the 
> purposes of documenting this behaviour in the DSL guide? Some manual markup 
> in the <type>.xml source page? An annotation on the type? Assume everything 
> in the DSL guide is decorated (it should be), and manually check for and fix 
> those that are not?

I'd rather drive this from code than an external xml file. I need to know 
everything about the class when looking at its source. It also will help users 
when looking at the Javadoc as the annotation should show up there. 

> Another question is what to do with those existing hook points which have 
> both void hookPoint(Action) and void hookPoint(Closure), now that we don't 
> need the hookPoint(Closure) overload. I guess we leave the redundant method, 
> and at some point deprecate and remove them from the API (but not the DSL, of 
> course).

Sounds right.

> I'd like to tidy-up a few more patterns at some point:
> 
> * Factory methods. If we have T someThing(Action<T>), mix in T 
> someAction(Closure) and T someAction(Map<String, ?>). I wonder if we should 
> annotate the factory methods, and only decorate those methods that are 
> annotated?
> 
> * Configure methods. If we have T getSomeProperty(), mix in void 
> someProperty(Closure) and void someProperty(Map<String, ?>). Again, I wonder 
> if we should annotate these properties as 'nested dsl elements', and only 
> decorate those methods?
> 
> * Multi-valued properties. If we have T getSomeProperty() and void 
> setSomeProperty(T), where T is a multi-valued type with element type E, then 
> mix in void someProperty(E...), void someProperty(Iterable<? extends E>) and 
> so on.

I'm for all of these in principle, but haven't thought about it deeply enough 
to be confident there aren't bad consequences. I'm strongly for having an 
annotation at some level. Perhaps a class level annotation that turns on all 
this decoration, then an exclusion annotation that can prevent a certain 
method/property from being annotated.

It should be easy to see just from the Javadoc/Groovydoc what behaviour you can 
expect.

> * Properties of type File. If we have void setSomeProperty(File), mix in void 
> setSomeProperty(Object). One question is how to figure out what base 
> directory to use to convert these values. One option would be that every 
> domain object created within a project would use that project's base 
> directory.

This is an interesting one. Perhaps that should be the default, but then have 
an escape hatch. Maybe if the type already has a FileResolver property then 
that should be used.

All in all, cool stuff.

-- 
Luke Daley
Principal Engineer, Gradleware 
http://gradleware.com

Reply via email to