I have been viewing the DSL ref and the delegation strategy of Groovy, I know the DependencyHandler is passed to the closure as the closure’s delegate so that the closure could invoke add() method of the DependencyHandler , but I don’t know where does the implementation come from(is it a function of Project class or something, I’m confused with this syntax), I’m new to Gradle.
What you have there is techincally a Groovy script, yes.
You can think of it like method calls and property accesses, yes, as that is how it is implemented.
But actually a Gradle build script is intended to be a custom DSL and should be declarative.
Groovy is an extremely dynamic language with duck-typing and possibilities to handle method calls and property accesses on non-existing methods and properties through meta-programming.
It is the Groovy magic that Gradle employs, that you can use any configuration that is added to the project as a “method call” in the dependencies block to add dependencies to it.
My personal recommendation is, to not bother with the Groovy DSL at all, but to use the Kotlin DSL.
With that you immediately get type-safe build scripts with an amazingly better IDE support.
As I know, dependencies is a method of project, because when I do println project.metaClass.methods.name, the terminal shows me all its method include dependencies, but there is no implementation method, I’m really confused with it.
implementation is not a method on Project but on DependencyHandler.
And even if you list the methods of the meta class of that object, it will not necessarily be listed.
As I said already, Groovy is a very dynamic language where you can do AST rewriting during compilation, add or change methods using meta classes, but also handle calls to non-existing methods or propertyaccesses which will not be listable in any way as their handling can be purely dynamic.
That deep dark Groovy magic you shouldn’t care about just to understand Gradle.
If you want to understand it, you should instead concentrate on learning about Groovy actually.
And as already said, I strongly recommend you use Kotlin DSL, there all methods are really methods, because Kotlin DSL is also very flexible, but not as dynamic and duck-typed as Groovy, but there all methods must exist at compile time.