On 26/11/2011, at 12:24 AM, Luke Daley wrote:

> 
> 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?

It can at the moment, but probably should be void, if this is to represent an 
event or hook point.


> 
>> 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.

You should be able to tell from the dsl reference that these are all options 
for setting a property:
setMyProp('value')
myProp = 'value'
myProp 'value'

And you probably should be able to use the dsl reference to work backwards from 
myProp 'value' in the code to find what that method does and where it comes 
from.


> 
>> 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. 

I agree. It would also be nice to drive the stuff that's currently in 
plugins.xml (and gradle-plugins/<plugin>.properties) from annotations and other 
static stuff on the plugin class.


> 
>> 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.

I think this is a good option. You're basically marking up a type as a 'dsl 
type', and all the decoration happens.

At the moment you would have to both annotate the type, and use an Instantiator 
to create it.  Which means there will be cases where we miss one of these 
things. At some point we'll get rid of the need to use the Instantiator. In the 
meantime, should we care?


> 
> 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
> 


--
Adam Murdoch
Gradle Co-founder
http://www.gradle.org
VP of Engineering, Gradleware Inc. - Gradle Training, Support, Consulting
http://www.gradleware.com

Reply via email to