-
Notifications
You must be signed in to change notification settings - Fork 173
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
Conversation
ce0bfc3
to
6d2256a
Compare
6d2256a
to
51c72f6
Compare
There was a problem hiding this 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 { |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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' |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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")) |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 { |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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")) |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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; |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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) { |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I created https://github.com/gradle/buildship/issues/153 for that.
|
||
dependencies { | ||
compile 'org.gradle:gradle-core:3.3' | ||
compile 'org.gradle:gradle-process-services:3.3' |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
I've created new issues for all your concerns @oehme. Once I manage to get rid of the |
No description provided.