Tooling API: Fetch multiple models in a single method call


(Attila Kelemen) #1

I have heard that the Tooling API in 1.6 will have a preliminary support for custom models defined by 3rd party plugins. This is good news, however for good and efficient IDE integration, we will need a little more. I will describe our needs through an example (real need).

I have been working with Radim Kubacki (the developer of NetBeans Android plugin) to provide support for Android project using the new build system. This is how things go (or rather, will go) in NetBeans: Determine what models can be queried from the project (IdeaProject, AndroidProject) and load them. The problem is that I cannot determine this. Currently, the only way I can think of is to attempt requesting each model separately and see if they are available. This is however has an unacceptable performance overhead (last time I checked it had) in a common case where not every model is available (possibly because it is a plain j2se project).

My idea is that I can specify all my possible needs to Gradle in a single call. This way, I expect that Gradle can efficiently decide what is available and what is not and return only the available models.

One extra useful feature would help with possible future evolution of models: For each queried model, allow to specify a fall-back model. That is, assume that the ProjectConnection.getModel takes an argument ‘List<List<Class<?>> requested’, then each element of ‘requested’ defines a single model request. An element of ‘requested’ (a ‘List<Class<?>’) requires that a single model is to be returned, the first model that is available as defined by the order of the list. As an example assume the following request: ‘[[IdeaProject.class], [AndroidProject2.class, AndroidProject.class]]’. If all these classes are available then an instance of ‘IdeaProject’ and ‘AndroidProject2’ is returned. If ‘AndroidProject2’ is not available then ‘AndroidProject’ is returned instead. If not even ‘AndroidProject’ is available then only ‘IdeaProject’ is returned (etc.).


(Luke Daley) #2

Hi Attila,

Interestingly, these are all use cases that we’ve already discovered through supporting the Android plugin efforts and plan to address. We plan to do at least some of this in 1.7.

I suggest keeping an eye on the relevant spec. It’s not quite up to date with the results of latest discussions, but will be soon.


(Attila Kelemen) #3

Thank you, I will keep an eye on the docs. Is there also a branch where adjustements related to this go, or changes are pushed to master?


(Luke Daley) #4

Straight to master. We only use branches for spikes and even then try to avoid it.


(Attila Kelemen) #5

I have found another use case which I would like you to consider:

Don’t request a model if the version of Gradle (used to evaluate the project) is higher than a certain value.

Here is an example, why this might be necessary: I hope that one day IdeaProject and EclipseProject will be deprecated and be replaced by a non-ide specific but rather plugin specific models. Say, “JavaProject” for the “java” plugin. Assume that the project is an Android project. In this case I only need the AndroidProject and not the JavaProject nor the IdeaProject. The problem is that IdeaProject is always available (and due to backward compatibilty I expect it to be available until Gradle 2), therefore I cannot just tell Gradle [AndroidProject.class, [JavaProject.class, IdeaProject.class]], leading to unnecessarily loading of the model IdeaProject.

This is relatively a minor issue however because even if it is implemented, I still must handle the case when I receive the unneeded IdeaProject.