Open tudortimi opened 8 months ago
Here's a zip with a reproducible example: example.zip
Discussed also on the Gradle forum: https://discuss.gradle.org/t/no-kotlin-type-safe-accessor-for-extension-of-element-in-project-extension-container/47740/7
This issue needs a decision from the team responsible for that area. They have been informed. Response time may vary.
Thank you, we think it is a valid feature request. We put it to the backlog of the team responsible for this area. It may take a while to get processed.
This is related to
In the same vein, observing extensions of each element instance will defeat containers laziness.
Also see https://github.com/gradle/gradle/issues/9277#issuecomment-486635757
Because observing task instances will get in the way of lazy task creation, the only way to provide type-safe accessors would be an extension model where, instead of registering extensions on task instances, the extensions would be registered by task type and could be queried without realizing the tasks.
You can replace "task" with "container element" in the above quote.
How does this work for the Groovy plugin, when using the Kotlin DSL? The documentation shows the following (comments mine):
sourceSets { // container added as project extension
main { // element in the container
groovy { // extension of element in container
// ...
}
}
}
I had a look at the code and groovy
is contributed using an extension. This is the same situation as in the code from the issue, where the accessor doesn't get added. Is there some extra magic somewhere that triggers the creation of the accessor?
That's because source sets are handled specially. Other core plugins eagerly resolve them already so it's not a big deal. But this is not done for all containers as explained above.
Now I get what is meant with getting in the way of lazy creation.
Is this something that I could do in my own code, for my own containers? I can find ProjectSchemaProvider
in the javadoc, so I guess it's not public.
Your plugin could ship static Kotlin extensions for your containers' elements. They would require an import but should be discoverable from the IDE content assist.
Is there a shorthand to access the someStringProperty
extension, aside from getting project.projectExtensionContainerOfElement.foo.extensions.get("someStringProperty")
and having to cast? With the old convention API, there was a withConvention()
method, does something similar exist also for extensions?
Current Behavior
I have a project extension which is a container which contains elements. These elements themselves have extensions added. There are type safe accessors added for each of the elements in that container, but there is no type safe container for the extension added to each element.
Expected Behavior
According to the Kotlin DSL primer accessors are available for:
The accessors for the elements should be covered by the first statement. The accessor for the extension on the elements should be covered by the second statement.
This is exactly what would cover, for example, the Groovy source directory sets added as extensions to the source sets by the Groovy plugin.
Context (optional)
No response
Steps to Reproduce
I add all extensions from a plugin, because they have to be added when the
plugins
block is evaluated.In my plugin, I created a dummy type for the elements to store in a container:
I add a container to the project as an extension:
This leads to a type-safe accessor for it being generated:
Type safe accessors are also added to elements in the container:
I also add an extension to the
foo
element:According to the Kotlin DSL primer, I expected also a type-safe accessor for the property:
This unfortunately doesn't work. I get a compile error.
Gradle version
8.6
Build scan URL (optional)
No response
Your Environment (optional)
No response