<commit_before>
This spec defines a number of features to improve the developer experience using Gradle from the IDE. It covers changes in Gradle to improve those features
that directly affect the IDE user experience. This includes the tooling API and tooling models, the Gradle daemon, and the Gradle IDE plugins
(i.e. the plugins that run inside Gradle to provide the IDE models).

Tooling API stories that are not related directly to the IDE experience should go in the `tooling-api-improvements.md` spec.

# Implementation plan

## Feature - Expose source and target platforms of JVM language projects

### Story - Expose Java source level for Java projects to IDEA

This is the IDEA-counterpart of the _Expose Java source level for Java projects to Eclipse_ story. The goal is to expose the source
language levels for each module in a project.

#### Estimate

- 2 days

#### The API

    interface IdeaJavaSourceSettings extends JavaSourceSettings {
        boolean isInherited()
        JavaVersion getSourceLanguageLevel()
    }

    interface IdeaModule extends JavaSourceAware {
        IdeaJavaSourceSettings getJavaSourceSettings()
    }

    interface IdeaProject extends JavaSourceAware {
    }

#### Implementation
- Introduce `IdeaJavaLanguageLevel` extending `JavaLanguageLevel`
- Introduce `IdeaJavaSourceSettings` extending `JavaSourceSettings`.
- Let the `IdeaModule` model extend `JavaSourceAware` and expose specialized `IdeaJavaSourceSettings`.
- Let the `IdeaProject` model extend `JavaSourceAware` to expose `JavaSourceSettings`
- Update `DefaultIdeaProject` to implement new `getJavaSourceSettings()` method
- Update `DefaultIdeaModule` to implement new `getJavaSourceSettings()` method
- Update `IdeaModelBuilder` to set values for `getJavaSourceSettings()` for `IdeaProject` and `IdeaModule`
    - return `null` if not a Java project
    - otherwise configure it as follows
        - `IdeaProject.getJavaSourceSettings().getSourceLanguageLevel()` is calculated from `org.gradle.plugins.ide.idea.model.IdeaProject.getLanguageLevel()`.
        - `IdeaModule.getJavaSourceSettings().getSourceLanguageLevel()` returns same value as root `IdeaProject.getLanguageLevel().getLevel()`
        - `IdeaModule.getSourceLanguageLevel().isInherited` returns true

#### Test coverage
- `IdeaModule.getJavaSourceSettings()` returns null for non java projects
- `IdeaProject.getJavaSourceSettings()` returns null for non java projects
- `IdeaModule.getJavaSourceSettings().isInherited()` returns true.
- `IdeaProject.getJavaSourceSettings()` throws `UnsupportedMethodException`for older target Gradle version.
- `IdeaModule.getJavaSourceSettings()` throws `UnsupportedMethodException`for older target Gradle version.
- `IdeaProject.getJavaSourceSettings().getSourceLanguageLevel()` matches language level information obtained from `project.sourceCompatibility`.
- `IdeaModule.getJavaSourceSettings().getSourceLanguageLevel()` matches custom `idea.project.languageLevel`.
- Can handle multi project builds with different source levels per subproject.

#### Open questions
- configuring per-module source level is currently not supported Idea plugin?


### Story - Expose target JDK for Java projects to Eclipse

#### Estimate
- 3 days


#### The API

    interface JavaRuntime {
        JavaVersion getJavaVersion()
        File getHomeDirectory()
    }

    interface JavaSourceSettings {
        JavaRuntimeEnvironment getTargetRuntime()
        JavaLanguageLevel getTargetLanguageLevel()
    }

    interface EclipseProject extends JavaSourceAware {
        JavaSourceSettings getJavaSourceSettings()
    }

#### Implementation

- Add `JavaRuntimeEnvironment getTargetRuntime()` to `JavaSourceSettings`.
- `JavaRuntimeEnvironment` should expose<commit_msg>Updated the next couple of IDE stories.<commit_after>
This spec defines a number of features to improve the developer experience using Gradle from the IDE. It covers changes in Gradle to improve those features
that directly affect the IDE user experience. This includes the tooling API and tooling models, the Gradle daemon, and the Gradle IDE plugins
(i.e. the plugins that run inside Gradle to provide the IDE models).

Tooling API stories that are not related directly to the IDE experience should go in the `tooling-api-improvements.md` spec.

# Implementation plan

## Feature - Expose source and target platforms of JVM language projects

### Story - Expose Java source level for Java projects to IDEA

This is the IDEA-counterpart of the _Expose Java source level for Java projects to Eclipse_ story. The goal is to expose the source
language levels for each module in a project.

#### Estimate

- 2 days

#### The API

    interface IdeaJavaSourceSettings extends JavaSourceSettings {
        boolean isInherited()
    }

    interface IdeaModule extends JavaSourceAware {
        IdeaJavaSourceSettings getJavaSourceSettings()
    }

    interface IdeaProject extends JavaSourceAware {
    }

TBD: Either add empty `IdeaProjectJavaSourceSettings` or remove `EclipseJavaSourceSettings`, for consistency.

#### Implementation
- Introduce `IdeaJavaLanguageLevel` extending `JavaLanguageLevel`
- Introduce `IdeaJavaSourceSettings` extending `JavaSourceSettings`.
- Let the `IdeaModule` model extend `JavaSourceAware` and expose specialized `IdeaJavaSourceSettings`.
- Let the `IdeaProject` model extend `JavaSourceAware` to expose `JavaSourceSettings`
- Update `DefaultIdeaProject` to implement new `getJavaSourceSettings()` method
- Update `DefaultIdeaModule` to implement new `getJavaSourceSettings()` method
- Update `IdeaModelBuilder` to set values for `getJavaSourceSettings()` for `IdeaProject` and `IdeaModule`
    - return `null` if not a Java project
    - otherwise configure it as follows
        - `IdeaProject.getJavaSourceSettings().getSourceLanguageLevel()` is calculated from `org.gradle.plugins.ide.idea.model.IdeaProject.getLanguageLevel()`.
        - `IdeaModule.getJavaSourceSettings().getSourceLanguageLevel()` is calculated the same way as the default for an Eclipse project, using the same logic.
        - `IdeaModule.getSourceLanguageLevel().isInherited` returns `fale` if different from the IDEA project, `true` if the same.
- Add a comment on `IdeaProject.getLanguageLevel()` that `getJavaSourceSettings()` should be preferred. 
- TBD: provide a value for `javaSourceSettings.sourceLanguageLevel` based on `languageLevel` for older Gradle versions. Given this, could possibly add default module settings.

#### Test coverage
- `IdeaModule.getJavaSourceSettings()` returns null for non java projects
- `IdeaProject.getJavaSourceSettings()` returns null for non java projects
    - TBD: should probably never return null, or return null only when no module has Java source.
- `IdeaModule.getJavaSourceSettings().isInherited()` returns true when the same as project's version, false when different.
- `IdeaProject.getJavaSourceSettings()` throws `UnsupportedMethodException`for older target Gradle version.
    - TBD: could be inferred from `languageLevel`.
- `IdeaModule.getJavaSourceSettings()` throws `UnsupportedMethodException`for older target Gradle version.
    - TBD: could be inferred from project's settings.
- `IdeaProject.getJavaSourceSettings().getSourceLanguageLevel()` matches language level information obtained from `project.sourceCompatibility`.
- `IdeaModule.getJavaSourceSettings().getSourceLanguageLevel()` matches language level information obtained from `project.sourceCompatibility`.
- Can handle multi project builds with different source levels per subproject.
- Can handle multi project builds where some projects are not a Java project and some are.
- Can handle multi project builds where root project is not a Java project, but some of its children are.

#### Open questions

- configuring per-module source level is currently not supported Idea plugin?

### Story - Expose target JDK for Java projects to Eclipse

#### Estimate
- 3 days


#### The API

    interface JavaRuntime {
        JavaVersion getJavaVersion()
        File getHomeDirectory()
    }

    interface JavaSourceSettings {
        JavaRuntimeEnvironment getTargetRuntime()
        JavaLanguageLevel getTargetLanguageLevel()
    }

    interface EclipseProject extends JavaSourceAware {
        JavaSourceSettings getJavaSourceSettings()
    }

TBD: A Java runtime can be used for projects that don't have any Java source. How will we model this?
TBD: Adding properties to `JavaSourceSettings` also adds these to `IdeaProject` and `IdeaModule`. Will need to define some behaviour for the IDEA model. 

#### Implementation

- Add `JavaRuntimeEnvironment getTargetRuntime()` to `JavaSourceSettings`.
- `JavaRuntimeEnvironment` should expose
{'fraction_non_alphanumeric': 0.07040641099026904, 'fraction_numerical': 0.0004579278763594734, 'mean_word_length': 4.796947577969476, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6176249', 'n_tokens_mistral': 2252, 'n_tokens_neox': 2111, 'n_words': 873}