Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add prototype for Gradle Kotlin script support #202

Merged
merged 6 commits into from
Jan 31, 2017
Merged

Conversation

donat
Copy link
Contributor

@donat donat commented Jan 27, 2017

No description provided.

@donat donat force-pushed the dc-kotlin-script branch 2 times, most recently from ce0bfc3 to 6d2256a Compare January 30, 2017 09:58
Copy link
Member

@oehme oehme left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a great start!

The biggest issue I see is the fact that we do an expensive computation synchronously in order to get information that is already there.

Basically the Kotlin plugin asks us for the template classpath in order to load our template class in order to read the annotation on it in order to find out the file regex. Instead, our TemplateProvider could tell the Kotlin plugin the regex directly (that's what the isApplicable method should be for). The Kotlin plugin should not even try to load the template up-front.

As long as we have this unnecessary up-front call, we'll pay the price of a synchronous TAPI operation, which might block the UI in order to download Gradle, which would be a really bad user experience.

The other comments are mostly cosmetic or out of curiosity. None of this should stop us from merging, but it would be great if you could create issues to follow up on these problems @donat

@@ -240,13 +240,14 @@ subprojects {
targetCompatibility = 1.8
}

tasks.withType(AbstractCompile).all {
tasks.matching { it instanceof JavaCompile || it instanceof GroovyCompile }.all {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why no stick with AbstractCompile?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The kotlin plugin contributes KotlinCompile which extends AbstractCompile but doesn't have attributes like options.

if (targetPlatformVersion >= '46') {
options.compilerArgs << '-Werror'
}
// TODO (donat) kotlin compilation currently fails with bad path error
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kotlin uses the -Werror flag too?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I got the following Java compilation error which I wanted to deal with later:
warning: [path] bad path element "/Users/donat/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-reflect/1.1-M04/50e442efdd3eab1dcf2ddbf4b3ec5dabecf1b2b2/kotlin-runtime.jar": no such file or directory

apply plugin: 'kotlin'

dependencies {
compile 'org.gradle:gradle-core:3.3'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be parametrized, some as the TAPI version we use.

Copy link
Contributor Author

@donat donat Jan 31, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

try {
connection = GradleConnector.newConnector()
.forProjectDirectory(projectDir)
.useDistribution(new URI("https://repo.gradle.org/gradle/dist-snapshots/gradle-script-kotlin-3.3-20161205200654+0000-all.zip"))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we still need a special distribution to use Kotlin? I thought this worked now with the standard Gradle distros? We should use whatever is specified in the project settings.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When I first created the prototype, this is how it was done in gradle-script-kotlin. It's no longer necessary, I've changed that. (will push the changes later)

.forProjectDirectory(projectDir)
.useDistribution(new URI("https://repo.gradle.org/gradle/dist-snapshots/gradle-script-kotlin-3.3-20161205200654+0000-all.zip"))
.connect();
KotlinBuildScriptModel model = connection.getModel(KotlinBuildScriptModel.class);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should respect offline mode, console listener etc. like our other model operations.

Copy link
Contributor Author

@donat donat Jan 31, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From the dependency resolver class we don't see the eclipse dependencies (because it runs separately). We should discuss this with JetBrains.

@ScriptTemplateDefinition(
resolver = GradleKotlinScriptDependenciesResolver::class,
scriptFilePattern = ".*\\.gradle\\.kts")
abstract class KotlinBuildScript(project: Project) : Project by project {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this duplicated? This should already be in GSK

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here the resolver = GradleKotlinScriptDependenciesResolver::class, part is the interesting one: it references the class from the org.eclipse.buildship.kotlin plugin instead of from GSK.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, same comment as above: This shows that loading the template to configure the IDE is wrong.

}

fun connectorFor(projectDir: File): GradleConnector =
GradleConnector.newConnector().forProjectDirectory(projectDir).useDistribution(URI("https://repo.gradle.org/gradle/dist-snapshots/gradle-script-kotlin-3.3-20161205200654+0000-all.zip"))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hardcoded gradle-script-kotlin distro

Copy link
Contributor Author

@donat donat Jan 31, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

}

private static List<String> templateClasspathFor(File projectDir) {
ProjectConnection connection = null;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duplicated code between here and KotlinModelQuery.

Copy link
Contributor Author

@donat donat Jan 31, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

return classpath;
}

private static List<String> templateClasspathFor(File projectDir) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should not even be necessary, we should talk to the JetBrains team about this. There absolutely no need to load the template class at this point. It introduces a synchronous call which may result in synchronously downloading Gradle etc. Our ScriptTemplateProvider can already tell the Kotlin plugin if it applies and what dependency resolver to use. So there is no need to load the template in order to look for the same information on some annotation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


dependencies {
compile 'org.gradle:gradle-core:3.3'
compile 'org.gradle:gradle-process-services:3.3'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need core and process-services?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some random class was needed for the compilation.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some random class? Can you be more specific? As far as I can see this should only be using the TAPI, not Gradle core.

Copy link
Contributor Author

@donat donat Jan 31, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the sketchy answer. We need them to compile KotlinBuildScript.kt. The class was copied from gradle-script-kotlin which depends on those libraries. Without the dependencies we get the following compile errors:

:org.eclipse.buildship.kotlin:compileKotlin
e: /Development/git/buildship/org.eclipse.buildship.kotlin/src/main/kotlin/org/eclipse/buildship/kotlin/KotlinBuildScript.kt: (11, 23): Unresolved reference: Project
e: /Development/git/buildship/org.eclipse.buildship.kotlin/src/main/kotlin/org/eclipse/buildship/kotlin/KotlinBuildScript.kt: (12, 23): Unresolved reference: plugins
e: /Development/git/buildship/org.eclipse.buildship.kotlin/src/main/kotlin/org/eclipse/buildship/kotlin/KotlinBuildScript.kt: (19, 43): Unresolved reference: Project
e: /Development/git/buildship/org.eclipse.buildship.kotlin/src/main/kotlin/org/eclipse/buildship/kotlin/KotlinBuildScript.kt: (19, 54): Only interfaces can be delegated to
e: /Development/git/buildship/org.eclipse.buildship.kotlin/src/main/kotlin/org/eclipse/buildship/kotlin/KotlinBuildScript.kt: (19, 54): Unresolved reference: Project
e: /Development/git/buildship/org.eclipse.buildship.kotlin/src/main/kotlin/org/eclipse/buildship/kotlin/KotlinBuildScript.kt: (28, 49): Unresolved reference: ObjectConfigurationAction
e: /Development/git/buildship/org.eclipse.buildship.kotlin/src/main/kotlin/org/eclipse/buildship/kotlin/KotlinBuildScript.kt: (29, 9): Unresolved reference: project
e: /Development/git/buildship/org.eclipse.buildship.kotlin/src/main/kotlin/org/eclipse/buildship/kotlin/KotlinBuildScript.kt: (29, 17): Public-API inline function cannot access non-public-API 'internal open fun <ERROR FUNCTION>(): [ERROR : <ERROR FUNCTION RETURN TYPE>] defined in root package'
e: /Development/git/buildship/org.eclipse.buildship.kotlin/src/main/kotlin/org/eclipse/buildship/kotlin/KotlinBuildScript.kt: (29, 25): Unresolved reference: it
e: /Development/git/buildship/org.eclipse.buildship.kotlin/src/main/kotlin/org/eclipse/buildship/kotlin/KotlinBuildScript.kt: (29, 28): Public-API inline function cannot access non-public-API 'internal open fun <ERROR FUNCTION>(): [ERROR : <ERROR FUNCTION RETURN TYPE>] defined in root package'

I had to copy the class to reference my altered version of GradleKotlinScriptDependenciesResolver in the annotation. That, I needed to change to leverage the differences in Eclipse (I had to pass different attributes to just to highlight one). We should discuss with Rodrigo how to share the implementation between Buildship and gradle-script-kotlin.

Copy link
Member

@oehme oehme Jan 31, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This just shows that defining this stuff in the annotation doesn't make sense for the IDE. It should be provided by the ScriptTemplateProvider. Same as with the isApplicable check. We should not need to load the template at all at this point.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I agree with you.

@donat
Copy link
Contributor Author

donat commented Jan 31, 2017

I've created new issues for all your concerns @oehme. Once I manage to get rid of the ip-validation failure I'll merge the branch to master.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants