Reformat: idea-gradle module

This commit is contained in:
Nikolay Krasko
2018-03-06 15:03:01 +03:00
parent cff88a3f8b
commit 9004cdfa45
32 changed files with 1708 additions and 1388 deletions
+18 -3
View File
@@ -1,4 +1,3 @@
apply { plugin("kotlin") } apply { plugin("kotlin") }
apply { plugin("jps-compatible") } apply { plugin("jps-compatible") }
@@ -16,14 +15,30 @@ dependencies {
compile(project(":js:js.frontend")) compile(project(":js:js.frontend"))
compileOnly(intellijDep()) { includeJars("openapi", "idea", "external-system-rt", "forms_rt", "extensions", "jdom", "util") } compileOnly(intellijDep()) { includeJars("openapi", "idea", "external-system-rt", "forms_rt", "extensions", "jdom", "util") }
compileOnly(intellijPluginDep("gradle")) { includeJars("gradle-tooling-api", "gradle", "gradle-base-services", rootProject = rootProject) } compileOnly(intellijPluginDep("gradle")) {
includeJars(
"gradle-tooling-api",
"gradle",
"gradle-base-services",
rootProject = rootProject
)
}
compileOnly(intellijPluginDep("Groovy")) { includeJars("Groovy") } compileOnly(intellijPluginDep("Groovy")) { includeJars("Groovy") }
compileOnly(intellijPluginDep("junit")) { includeJars("idea-junit") } compileOnly(intellijPluginDep("junit")) { includeJars("idea-junit") }
testCompile(projectTests(":idea")) testCompile(projectTests(":idea"))
testCompile(projectTests(":idea:idea-test-framework")) testCompile(projectTests(":idea:idea-test-framework"))
testCompile(intellijPluginDep("gradle")) { includeJars("gradle-wrapper", "gradle-base-services", "gradle-tooling-extension-impl", "gradle-tooling-api", "gradle", rootProject = rootProject) } testCompile(intellijPluginDep("gradle")) {
includeJars(
"gradle-wrapper",
"gradle-base-services",
"gradle-tooling-extension-impl",
"gradle-tooling-api",
"gradle",
rootProject = rootProject
)
}
testCompileOnly(intellijPluginDep("Groovy")) { includeJars("Groovy") } testCompileOnly(intellijPluginDep("Groovy")) { includeJars("Groovy") }
testCompileOnly(intellijDep()) { includeJars("groovy-all", "idea_rt", rootProject = rootProject) } testCompileOnly(intellijDep()) { includeJars("groovy-all", "idea_rt", rootProject = rootProject) }
@@ -23,10 +23,12 @@ import com.intellij.psi.PsiElement
interface GradleBuildScriptManipulator { interface GradleBuildScriptManipulator {
fun isConfigured(kotlinPluginName: String): Boolean fun isConfigured(kotlinPluginName: String): Boolean
fun configureModuleBuildScript(kotlinPluginName: String, fun configureModuleBuildScript(
stdlibArtifactName: String, kotlinPluginName: String,
version: String, stdlibArtifactName: String,
jvmTarget: String?): Boolean version: String,
jvmTarget: String?
): Boolean
fun configureProjectBuildScript(version: String): Boolean fun configureProjectBuildScript(version: String): Boolean
@@ -37,9 +39,10 @@ interface GradleBuildScriptManipulator {
fun changeApiVersion(version: String, forTests: Boolean): PsiElement? fun changeApiVersion(version: String, forTests: Boolean): PsiElement?
fun addKotlinLibraryToModuleBuildScript( fun addKotlinLibraryToModuleBuildScript(
scope: DependencyScope, scope: DependencyScope,
libraryDescriptor: ExternalLibraryDescriptor, libraryDescriptor: ExternalLibraryDescriptor,
isAndroidModule: Boolean) isAndroidModule: Boolean
)
fun getKotlinStdlibVersion(): String? fun getKotlinStdlibVersion(): String?
} }
@@ -32,9 +32,11 @@ import javax.swing.Icon
import javax.swing.JComponent import javax.swing.JComponent
import javax.swing.JLabel import javax.swing.JLabel
abstract class GradleKotlinFrameworkSupportProvider(val frameworkTypeId: String, abstract class GradleKotlinFrameworkSupportProvider(
val displayName: String, val frameworkTypeId: String,
val frameworkIcon: Icon) : GradleFrameworkSupportProvider() { val displayName: String,
val frameworkIcon: Icon
) : GradleFrameworkSupportProvider() {
override fun getFrameworkType(): FrameworkTypeEx = object : FrameworkTypeEx(frameworkTypeId) { override fun getFrameworkType(): FrameworkTypeEx = object : FrameworkTypeEx(frameworkTypeId) {
override fun getIcon(): Icon = frameworkIcon override fun getIcon(): Icon = frameworkIcon
@@ -54,10 +56,12 @@ abstract class GradleKotlinFrameworkSupportProvider(val frameworkTypeId: String,
} }
} }
override fun addSupport(module: Module, override fun addSupport(
rootModel: ModifiableRootModel, module: Module,
modifiableModelsProvider: ModifiableModelsProvider, rootModel: ModifiableRootModel,
buildScriptData: BuildScriptDataBuilder) { modifiableModelsProvider: ModifiableModelsProvider,
buildScriptData: BuildScriptDataBuilder
) {
addSupport(buildScriptData, rootModel.sdk) addSupport(buildScriptData, rootModel.sdk)
} }
@@ -89,10 +93,10 @@ abstract class GradleKotlinFrameworkSupportProvider(val frameworkTypeId: String,
} }
for (dependency in getTestDependencies()) { for (dependency in getTestDependencies()) {
buildScriptData.addDependencyNotation( buildScriptData.addDependencyNotation(
if (":" in dependency) if (":" in dependency)
"testCompile \"$dependency\"" "testCompile \"$dependency\""
else else
KotlinWithGradleConfigurator.getGroovyDependencySnippet(dependency, "testCompile") KotlinWithGradleConfigurator.getGroovyDependencySnippet(dependency, "testCompile")
) )
} }
buildScriptData.addBuildscriptDependencyNotation(KotlinWithGradleConfigurator.CLASSPATH) buildScriptData.addBuildscriptDependencyNotation(KotlinWithGradleConfigurator.CLASSPATH)
@@ -106,9 +110,10 @@ abstract class GradleKotlinFrameworkSupportProvider(val frameworkTypeId: String,
protected abstract fun getDescription(): String protected abstract fun getDescription(): String
} }
open class GradleKotlinJavaFrameworkSupportProvider(frameworkTypeId: String = "KOTLIN", open class GradleKotlinJavaFrameworkSupportProvider(
displayName: String = "Kotlin (Java)") frameworkTypeId: String = "KOTLIN",
: GradleKotlinFrameworkSupportProvider(frameworkTypeId, displayName, KotlinIcons.SMALL_LOGO) { displayName: String = "Kotlin (Java)"
) : GradleKotlinFrameworkSupportProvider(frameworkTypeId, displayName, KotlinIcons.SMALL_LOGO) {
override fun getPluginId() = KotlinGradleModuleConfigurator.KOTLIN override fun getPluginId() = KotlinGradleModuleConfigurator.KOTLIN
@@ -127,9 +132,10 @@ open class GradleKotlinJavaFrameworkSupportProvider(frameworkTypeId: String = "K
override fun getDescription() = "A Kotlin library or application targeting the JVM" override fun getDescription() = "A Kotlin library or application targeting the JVM"
} }
open class GradleKotlinJSFrameworkSupportProvider(frameworkTypeId: String = "KOTLIN_JS", open class GradleKotlinJSFrameworkSupportProvider(
displayName: String = "Kotlin (JavaScript)") frameworkTypeId: String = "KOTLIN_JS",
: GradleKotlinFrameworkSupportProvider(frameworkTypeId, displayName, KotlinIcons.JS) { displayName: String = "Kotlin (JavaScript)"
) : GradleKotlinFrameworkSupportProvider(frameworkTypeId, displayName, KotlinIcons.JS) {
override fun getPluginId() = KotlinJsGradleModuleConfigurator.KOTLIN_JS override fun getPluginId() = KotlinJsGradleModuleConfigurator.KOTLIN_JS
@@ -141,7 +147,7 @@ open class GradleKotlinJSFrameworkSupportProvider(frameworkTypeId: String = "KOT
} }
open class GradleKotlinMPPCommonFrameworkSupportProvider : open class GradleKotlinMPPCommonFrameworkSupportProvider :
GradleKotlinFrameworkSupportProvider("KOTLIN_MPP_COMMON", "Kotlin (Multiplatform Common - Experimental)", KotlinIcons.MPP) { GradleKotlinFrameworkSupportProvider("KOTLIN_MPP_COMMON", "Kotlin (Multiplatform Common - Experimental)", KotlinIcons.MPP) {
override fun getPluginId() = "kotlin-platform-common" override fun getPluginId() = "kotlin-platform-common"
override fun getDependencies(sdk: Sdk?) = listOf(MAVEN_COMMON_STDLIB_ID) override fun getDependencies(sdk: Sdk?) = listOf(MAVEN_COMMON_STDLIB_ID)
@@ -36,15 +36,15 @@ class GroovyBuildScriptManipulator(private val groovyScript: GroovyFile) : Gradl
override fun isConfigured(kotlinPluginName: String): Boolean { override fun isConfigured(kotlinPluginName: String): Boolean {
val fileText = runReadAction { groovyScript.text } val fileText = runReadAction { groovyScript.text }
return containsDirective(fileText, getApplyPluginDirective(kotlinPluginName)) && return containsDirective(fileText, getApplyPluginDirective(kotlinPluginName)) &&
fileText.contains("org.jetbrains.kotlin") && fileText.contains("org.jetbrains.kotlin") &&
fileText.contains("kotlin-stdlib") fileText.contains("kotlin-stdlib")
} }
override fun configureModuleBuildScript( override fun configureModuleBuildScript(
kotlinPluginName: String, kotlinPluginName: String,
stdlibArtifactName: String, stdlibArtifactName: String,
version: String, version: String,
jvmTarget: String? jvmTarget: String?
): Boolean { ): Boolean {
val oldText = groovyScript.text val oldText = groovyScript.text
val applyPluginDirective = getGroovyApplyPluginDirective(kotlinPluginName) val applyPluginDirective = getGroovyApplyPluginDirective(kotlinPluginName)
@@ -53,13 +53,11 @@ class GroovyBuildScriptManipulator(private val groovyScript: GroovyFile) : Gradl
val applyStatement = getApplyStatement(groovyScript) val applyStatement = getApplyStatement(groovyScript)
if (applyStatement != null) { if (applyStatement != null) {
groovyScript.addAfter(apply, applyStatement) groovyScript.addAfter(apply, applyStatement)
} } else {
else {
val buildScriptBlock = groovyScript.getBlockByName("buildscript") val buildScriptBlock = groovyScript.getBlockByName("buildscript")
if (buildScriptBlock != null) { if (buildScriptBlock != null) {
groovyScript.addAfter(apply, buildScriptBlock.parent) groovyScript.addAfter(apply, buildScriptBlock.parent)
} } else {
else {
groovyScript.addAfter(apply, groovyScript.statements.lastOrNull() ?: groovyScript.firstChild) groovyScript.addAfter(apply, groovyScript.statements.lastOrNull() ?: groovyScript.firstChild)
} }
} }
@@ -115,22 +113,23 @@ class GroovyBuildScriptManipulator(private val groovyScript: GroovyFile) : Gradl
} }
override fun changeLanguageVersion(version: String, forTests: Boolean): PsiElement? = override fun changeLanguageVersion(version: String, forTests: Boolean): PsiElement? =
changeKotlinTaskParameter(groovyScript, "languageVersion", version, forTests) changeKotlinTaskParameter(groovyScript, "languageVersion", version, forTests)
override fun changeApiVersion(version: String, forTests: Boolean): PsiElement? = override fun changeApiVersion(version: String, forTests: Boolean): PsiElement? =
changeKotlinTaskParameter(groovyScript, "apiVersion", version, forTests) changeKotlinTaskParameter(groovyScript, "apiVersion", version, forTests)
override fun addKotlinLibraryToModuleBuildScript( override fun addKotlinLibraryToModuleBuildScript(
scope: DependencyScope, scope: DependencyScope,
libraryDescriptor: ExternalLibraryDescriptor, libraryDescriptor: ExternalLibraryDescriptor,
isAndroidModule: Boolean isAndroidModule: Boolean
) { ) {
val dependencyString = String.format( val dependencyString = String.format(
"%s \"%s:%s:%s\"", "%s \"%s:%s:%s\"",
scope.toGradleCompileScope(isAndroidModule), scope.toGradleCompileScope(isAndroidModule),
libraryDescriptor.libraryGroupId, libraryDescriptor.libraryGroupId,
libraryDescriptor.libraryArtifactId, libraryDescriptor.libraryArtifactId,
libraryDescriptor.maxVersion) libraryDescriptor.maxVersion
)
groovyScript.getDependenciesBlock().apply { groovyScript.getDependenciesBlock().apply {
addLastExpressionInBlockIfNeeded(dependencyString) addLastExpressionInBlockIfNeeded(dependencyString)
@@ -160,10 +159,10 @@ class GroovyBuildScriptManipulator(private val groovyScript: GroovyFile) : Gradl
} }
private fun changeKotlinTaskParameter( private fun changeKotlinTaskParameter(
gradleFile: GroovyFile, gradleFile: GroovyFile,
parameterName: String, parameterName: String,
parameterValue: String, parameterValue: String,
forTests: Boolean forTests: Boolean
): PsiElement? { ): PsiElement? {
val snippet = "$parameterName = \"$parameterValue\"" val snippet = "$parameterName = \"$parameterValue\""
val kotlinBlock = gradleFile.getBlockOrCreate(if (forTests) "compileTestKotlin" else "compileKotlin") val kotlinBlock = gradleFile.getBlockOrCreate(if (forTests) "compileTestKotlin" else "compileKotlin")
@@ -189,18 +188,18 @@ class GroovyBuildScriptManipulator(private val groovyScript: GroovyFile) : Gradl
private fun containsDirective(fileText: String, directive: String): Boolean { private fun containsDirective(fileText: String, directive: String): Boolean {
return fileText.contains(directive) return fileText.contains(directive)
|| fileText.contains(directive.replace("\"", "'")) || fileText.contains(directive.replace("\"", "'"))
|| fileText.contains(directive.replace("'", "\"")) || fileText.contains(directive.replace("'", "\""))
} }
private fun getApplyStatement(file: GroovyFile): GrApplicationStatement? = private fun getApplyStatement(file: GroovyFile): GrApplicationStatement? =
file.getChildrenOfType<GrApplicationStatement>().find { it.invokedExpression.text == "apply" } file.getChildrenOfType<GrApplicationStatement>().find { it.invokedExpression.text == "apply" }
private fun PsiElement.getBlockByName(name: String): GrClosableBlock? { private fun PsiElement.getBlockByName(name: String): GrClosableBlock? {
return getChildrenOfType<GrMethodCallExpression>() return getChildrenOfType<GrMethodCallExpression>()
.filter { it.closureArguments.isNotEmpty() } .filter { it.closureArguments.isNotEmpty() }
.find { it.invokedExpression.text == name } .find { it.invokedExpression.text == name }
?.let { it.closureArguments[0] } ?.let { it.closureArguments[0] }
} }
private fun GrClosableBlock.addRepository(version: String): Boolean { private fun GrClosableBlock.addRepository(version: String): Boolean {
@@ -214,7 +213,7 @@ class GroovyBuildScriptManipulator(private val groovyScript: GroovyFile) : Gradl
} }
private fun GrClosableBlock.addMavenCentralIfMissing(): Boolean = private fun GrClosableBlock.addMavenCentralIfMissing(): Boolean =
if (!isRepositoryConfigured(text)) addLastExpressionInBlockIfNeeded(MAVEN_CENTRAL) else false if (!isRepositoryConfigured(text)) addLastExpressionInBlockIfNeeded(MAVEN_CENTRAL) else false
private fun GrStatementOwner.getRepositoriesBlock() = getBlockOrCreate("repositories") private fun GrStatementOwner.getRepositoriesBlock() = getBlockOrCreate("repositories")
@@ -223,10 +222,10 @@ class GroovyBuildScriptManipulator(private val groovyScript: GroovyFile) : Gradl
private fun GrStatementOwner.getBuildScriptBlock() = getBlockOrCreate("buildscript") private fun GrStatementOwner.getBuildScriptBlock() = getBlockOrCreate("buildscript")
private fun GrStatementOwner.getBuildScriptRepositoriesBlock(): GrClosableBlock = private fun GrStatementOwner.getBuildScriptRepositoriesBlock(): GrClosableBlock =
getBuildScriptBlock().getBlockOrCreate("repositories") getBuildScriptBlock().getBlockOrCreate("repositories")
private fun GrStatementOwner.getBuildScriptDependenciesBlock(): GrClosableBlock = private fun GrStatementOwner.getBuildScriptDependenciesBlock(): GrClosableBlock =
getBuildScriptBlock().getBlockOrCreate("dependencies") getBuildScriptBlock().getBlockOrCreate("dependencies")
private fun GrStatementOwner.getBlockOrCreate(name: String): GrClosableBlock { private fun GrStatementOwner.getBlockOrCreate(name: String): GrClosableBlock {
var block = getBlockByName(name) var block = getBlockByName(name)
@@ -248,10 +247,10 @@ class GroovyBuildScriptManipulator(private val groovyScript: GroovyFile) : Gradl
} }
private fun GrClosableBlock.addLastExpressionInBlockIfNeeded(expressionText: String): Boolean = private fun GrClosableBlock.addLastExpressionInBlockIfNeeded(expressionText: String): Boolean =
addExpressionInBlockIfNeeded(expressionText, false) addExpressionInBlockIfNeeded(expressionText, false)
private fun GrClosableBlock.addFirstExpressionInBlockIfNeeded(expressionText: String): Boolean = private fun GrClosableBlock.addFirstExpressionInBlockIfNeeded(expressionText: String): Boolean =
addExpressionInBlockIfNeeded(expressionText, true) addExpressionInBlockIfNeeded(expressionText, true)
private fun GrClosableBlock.addExpressionInBlockIfNeeded(expressionText: String, isFirst: Boolean): Boolean { private fun GrClosableBlock.addExpressionInBlockIfNeeded(expressionText: String, isFirst: Boolean): Boolean {
if (text.contains(expressionText)) return false if (text.contains(expressionText)) return false
@@ -262,8 +261,7 @@ class GroovyBuildScriptManipulator(private val groovyScript: GroovyFile) : Gradl
if (lastStatement != null) { if (lastStatement != null) {
addAfter(newStatement, lastStatement) addAfter(newStatement, lastStatement)
} }
} } else {
else {
if (firstChild != null) { if (firstChild != null) {
addAfter(newStatement, firstChild) addAfter(newStatement, firstChild)
} }
@@ -28,9 +28,9 @@ import org.jetbrains.kotlin.utils.addToStdlib.cast
class KotlinBuildScriptManipulator(private val kotlinScript: KtFile) : GradleBuildScriptManipulator { class KotlinBuildScriptManipulator(private val kotlinScript: KtFile) : GradleBuildScriptManipulator {
override fun isConfigured(kotlinPluginName: String): Boolean = override fun isConfigured(kotlinPluginName: String): Boolean =
runReadAction { runReadAction {
kotlinScript.containsApplyKotlinPlugin(kotlinPluginName) && kotlinScript.containsCompileStdLib() kotlinScript.containsApplyKotlinPlugin(kotlinPluginName) && kotlinScript.containsCompileStdLib()
} }
override fun configureProjectBuildScript(version: String): Boolean { override fun configureProjectBuildScript(version: String): Boolean {
val originalText = kotlinScript.text val originalText = kotlinScript.text
@@ -51,10 +51,10 @@ class KotlinBuildScriptManipulator(private val kotlinScript: KtFile) : GradleBui
} }
override fun configureModuleBuildScript( override fun configureModuleBuildScript(
kotlinPluginName: String, kotlinPluginName: String,
stdlibArtifactName: String, stdlibArtifactName: String,
version: String, version: String,
jvmTarget: String? jvmTarget: String?
): Boolean { ): Boolean {
val originalText = kotlinScript.text val originalText = kotlinScript.text
kotlinScript.apply { kotlinScript.apply {
@@ -76,40 +76,42 @@ class KotlinBuildScriptManipulator(private val kotlinScript: KtFile) : GradleBui
} }
override fun changeCoroutineConfiguration(coroutineOption: String): PsiElement? = override fun changeCoroutineConfiguration(coroutineOption: String): PsiElement? =
kotlinScript.changeCoroutineConfiguration(coroutineOption) kotlinScript.changeCoroutineConfiguration(coroutineOption)
override fun changeLanguageVersion(version: String, forTests: Boolean): PsiElement? = override fun changeLanguageVersion(version: String, forTests: Boolean): PsiElement? =
kotlinScript.changeKotlinTaskParameter("languageVersion", version, forTests) kotlinScript.changeKotlinTaskParameter("languageVersion", version, forTests)
override fun changeApiVersion(version: String, forTests: Boolean): PsiElement? = override fun changeApiVersion(version: String, forTests: Boolean): PsiElement? =
kotlinScript.changeKotlinTaskParameter("apiVersion", version, forTests) kotlinScript.changeKotlinTaskParameter("apiVersion", version, forTests)
override fun addKotlinLibraryToModuleBuildScript( override fun addKotlinLibraryToModuleBuildScript(
scope: DependencyScope, scope: DependencyScope,
libraryDescriptor: ExternalLibraryDescriptor, libraryDescriptor: ExternalLibraryDescriptor,
isAndroidModule: Boolean isAndroidModule: Boolean
) { ) {
val kotlinLibraryVersion = libraryDescriptor.maxVersion.takeIf { it != GSK_KOTLIN_VERSION_PROPERTY_NAME } val kotlinLibraryVersion = libraryDescriptor.maxVersion.takeIf { it != GSK_KOTLIN_VERSION_PROPERTY_NAME }
kotlinScript.getDependenciesBlock()?.apply { kotlinScript.getDependenciesBlock()?.apply {
addExpressionIfMissing( addExpressionIfMissing(
getCompileDependencySnippet( getCompileDependencySnippet(
libraryDescriptor.libraryGroupId, libraryDescriptor.libraryGroupId,
libraryDescriptor.libraryArtifactId, libraryDescriptor.libraryArtifactId,
scope.toGradleCompileScope(isAndroidModule), scope.toGradleCompileScope(isAndroidModule),
kotlinLibraryVersion)) kotlinLibraryVersion
)
)
} }
} }
override fun getKotlinStdlibVersion(): String? = kotlinScript.getKotlinStdlibVersion() override fun getKotlinStdlibVersion(): String? = kotlinScript.getKotlinStdlibVersion()
private fun KtBlockExpression.addCompileStdlibIfMissing(stdlibArtifactName: String): KtCallExpression? = private fun KtBlockExpression.addCompileStdlibIfMissing(stdlibArtifactName: String): KtCallExpression? =
findCompileStdLib() ?: addExpressionIfMissing(getCompileDependencySnippet(KOTLIN_GROUP_ID, stdlibArtifactName)) as? KtCallExpression findCompileStdLib() ?: addExpressionIfMissing(getCompileDependencySnippet(KOTLIN_GROUP_ID, stdlibArtifactName)) as? KtCallExpression
private fun KtFile.containsCompileStdLib(): Boolean = private fun KtFile.containsCompileStdLib(): Boolean =
findScriptInitializer("dependencies")?.getBlock()?.findCompileStdLib() != null findScriptInitializer("dependencies")?.getBlock()?.findCompileStdLib() != null
private fun KtFile.containsApplyKotlinPlugin(pluginName: String): Boolean = private fun KtFile.containsApplyKotlinPlugin(pluginName: String): Boolean =
findScriptInitializer("apply")?.getBlock()?.findPlugin(pluginName) != null findScriptInitializer("apply")?.getBlock()?.findPlugin(pluginName) != null
private fun KtBlockExpression.findPlugin(pluginName: String): KtCallExpression? { private fun KtBlockExpression.findPlugin(pluginName: String): KtCallExpression? {
return PsiTreeUtil.getChildrenOfType(this, KtCallExpression::class.java)?.find { return PsiTreeUtil.getChildrenOfType(this, KtCallExpression::class.java)?.find {
@@ -118,20 +120,20 @@ class KotlinBuildScriptManipulator(private val kotlinScript: KtFile) : GradleBui
} }
private fun KtFile.findScriptInitializer(startsWith: String): KtScriptInitializer? = private fun KtFile.findScriptInitializer(startsWith: String): KtScriptInitializer? =
PsiTreeUtil.findChildrenOfType(this, KtScriptInitializer::class.java).find { it.text.startsWith(startsWith) } PsiTreeUtil.findChildrenOfType(this, KtScriptInitializer::class.java).find { it.text.startsWith(startsWith) }
private fun KtBlockExpression.findBlock(name: String): KtBlockExpression? { private fun KtBlockExpression.findBlock(name: String): KtBlockExpression? {
return getChildrenOfType<KtCallExpression>().find { return getChildrenOfType<KtCallExpression>().find {
it.calleeExpression?.text == name && it.calleeExpression?.text == name &&
it.valueArguments.singleOrNull()?.getArgumentExpression() is KtLambdaExpression it.valueArguments.singleOrNull()?.getArgumentExpression() is KtLambdaExpression
}?.getBlock() }?.getBlock()
} }
private fun KtScriptInitializer.getBlock(): KtBlockExpression? = private fun KtScriptInitializer.getBlock(): KtBlockExpression? =
PsiTreeUtil.findChildOfType<KtCallExpression>(this, KtCallExpression::class.java)?.getBlock() PsiTreeUtil.findChildOfType<KtCallExpression>(this, KtCallExpression::class.java)?.getBlock()
private fun KtCallExpression.getBlock(): KtBlockExpression? = private fun KtCallExpression.getBlock(): KtBlockExpression? =
(valueArguments.singleOrNull()?.getArgumentExpression() as? KtLambdaExpression)?.bodyExpression (valueArguments.singleOrNull()?.getArgumentExpression() as? KtLambdaExpression)?.bodyExpression
private fun KtFile.getKotlinStdlibVersion(): String? { private fun KtFile.getKotlinStdlibVersion(): String? {
return findScriptInitializer("dependencies")?.getBlock()?.let { return findScriptInitializer("dependencies")?.getBlock()?.let {
@@ -152,16 +154,16 @@ class KotlinBuildScriptManipulator(private val kotlinScript: KtFile) : GradleBui
private fun KtExpression.isKotlinStdLib(): Boolean = when (this) { private fun KtExpression.isKotlinStdLib(): Boolean = when (this) {
is KtCallExpression -> calleeExpression?.text == "kotlinModule" && is KtCallExpression -> calleeExpression?.text == "kotlinModule" &&
valueArguments.firstOrNull()?.getArgumentExpression()?.text?.startsWith("\"stdlib") ?: false valueArguments.firstOrNull()?.getArgumentExpression()?.text?.startsWith("\"stdlib") ?: false
is KtStringTemplateExpression -> text.startsWith("\"$STDLIB_ARTIFACT_PREFIX") is KtStringTemplateExpression -> text.startsWith("\"$STDLIB_ARTIFACT_PREFIX")
else -> false else -> false
} }
private fun KtFile.getRepositoriesBlock(): KtBlockExpression? = private fun KtFile.getRepositoriesBlock(): KtBlockExpression? =
findScriptInitializer("repositories")?.getBlock() ?: addTopLevelBlock("repositories") findScriptInitializer("repositories")?.getBlock() ?: addTopLevelBlock("repositories")
private fun KtFile.getDependenciesBlock(): KtBlockExpression? = private fun KtFile.getDependenciesBlock(): KtBlockExpression? =
findScriptInitializer("dependencies")?.getBlock() ?: addTopLevelBlock("dependencies") findScriptInitializer("dependencies")?.getBlock() ?: addTopLevelBlock("dependencies")
private fun KtFile.createApplyBlock(): KtBlockExpression? { private fun KtFile.createApplyBlock(): KtBlockExpression? {
val apply = psiFactory.createScriptInitializer("apply {\n}") val apply = psiFactory.createScriptInitializer("apply {\n}")
@@ -174,7 +176,7 @@ class KotlinBuildScriptManipulator(private val kotlinScript: KtFile) : GradleBui
private fun KtFile.getApplyBlock(): KtBlockExpression? = findScriptInitializer("apply")?.getBlock() ?: createApplyBlock() private fun KtFile.getApplyBlock(): KtBlockExpression? = findScriptInitializer("apply")?.getBlock() ?: createApplyBlock()
private fun KtBlockExpression.createPluginIfMissing(pluginName: String): KtCallExpression? = private fun KtBlockExpression.createPluginIfMissing(pluginName: String): KtCallExpression? =
findPlugin(pluginName) ?: addExpressionIfMissing("plugin(\"$pluginName\")") as? KtCallExpression findPlugin(pluginName) ?: addExpressionIfMissing("plugin(\"$pluginName\")") as? KtCallExpression
private fun KtFile.changeCoroutineConfiguration(coroutineOption: String): PsiElement? { private fun KtFile.changeCoroutineConfiguration(coroutineOption: String): PsiElement? {
val snippet = "experimental.coroutines = Coroutines.${coroutineOption.toUpperCase()}" val snippet = "experimental.coroutines = Coroutines.${coroutineOption.toUpperCase()}"
@@ -183,8 +185,7 @@ class KotlinBuildScriptManipulator(private val kotlinScript: KtFile) : GradleBui
val statement = kotlinBlock.statements.find { it.text.startsWith("experimental.coroutines") } val statement = kotlinBlock.statements.find { it.text.startsWith("experimental.coroutines") }
return if (statement != null) { return if (statement != null) {
statement.replace(psiFactory.createExpression(snippet)) statement.replace(psiFactory.createExpression(snippet))
} } else {
else {
kotlinBlock.add(psiFactory.createExpression(snippet)).apply { addNewLinesIfNeeded() } kotlinBlock.add(psiFactory.createExpression(snippet)).apply { addNewLinesIfNeeded() }
} }
} }
@@ -199,12 +200,10 @@ class KotlinBuildScriptManipulator(private val kotlinScript: KtFile) : GradleBui
} }
if (assignment != null) { if (assignment != null) {
assignment.replace(psiFactory.createExpression(snippet)) assignment.replace(psiFactory.createExpression(snippet))
} } else {
else {
optionsBlock.addExpressionIfMissing(snippet) optionsBlock.addExpressionIfMissing(snippet)
} }
} } else {
else {
addImportIfMissing("org.jetbrains.kotlin.gradle.tasks.KotlinCompile") addImportIfMissing("org.jetbrains.kotlin.gradle.tasks.KotlinCompile")
script?.blockExpression?.addDeclarationIfMissing("val $taskName: KotlinCompile by tasks") script?.blockExpression?.addDeclarationIfMissing("val $taskName: KotlinCompile by tasks")
addTopLevelBlock("$taskName.kotlinOptions")?.addExpressionIfMissing(snippet) addTopLevelBlock("$taskName.kotlinOptions")?.addExpressionIfMissing(snippet)
@@ -212,13 +211,13 @@ class KotlinBuildScriptManipulator(private val kotlinScript: KtFile) : GradleBui
} }
private fun KtFile.getBuildScriptBlock(): KtBlockExpression? = private fun KtFile.getBuildScriptBlock(): KtBlockExpression? =
findScriptInitializer("buildscript")?.getBlock() ?: addTopLevelBlock("buildscript", true) findScriptInitializer("buildscript")?.getBlock() ?: addTopLevelBlock("buildscript", true)
private fun KtBlockExpression.getRepositoriesBlock(): KtBlockExpression? = private fun KtBlockExpression.getRepositoriesBlock(): KtBlockExpression? =
findBlock("repositories") ?: addBlock("repositories") findBlock("repositories") ?: addBlock("repositories")
private fun KtBlockExpression.getDependenciesBlock(): KtBlockExpression? = private fun KtBlockExpression.getDependenciesBlock(): KtBlockExpression? =
findBlock("dependencies") ?: addBlock("dependencies") findBlock("dependencies") ?: addBlock("dependencies")
private fun KtBlockExpression.addRepositoryIfMissing(version: String): KtCallExpression? { private fun KtBlockExpression.addRepositoryIfMissing(version: String): KtCallExpression? {
val repository = getRepositoryForVersion(version) val repository = getRepositoryForVersion(version)
@@ -232,16 +231,16 @@ class KotlinBuildScriptManipulator(private val kotlinScript: KtFile) : GradleBui
} }
private fun KtBlockExpression.addMavenCentralIfMissing(): KtCallExpression? = private fun KtBlockExpression.addMavenCentralIfMissing(): KtCallExpression? =
if (!isRepositoryConfigured(text)) addExpressionIfMissing(MAVEN_CENTRAL) as? KtCallExpression else null if (!isRepositoryConfigured(text)) addExpressionIfMissing(MAVEN_CENTRAL) as? KtCallExpression else null
private fun KtBlockExpression.addPluginToClassPathIfMissing(): KtCallExpression? = private fun KtBlockExpression.addPluginToClassPathIfMissing(): KtCallExpression? =
addExpressionIfMissing(getKotlinGradlePluginClassPathSnippet()) as? KtCallExpression addExpressionIfMissing(getKotlinGradlePluginClassPathSnippet()) as? KtCallExpression
private fun KtBlockExpression.addBlock(name: String): KtBlockExpression? { private fun KtBlockExpression.addBlock(name: String): KtBlockExpression? {
return add(psiFactory.createExpression("$name {\n}")) return add(psiFactory.createExpression("$name {\n}"))
?.apply { addNewLinesIfNeeded() } ?.apply { addNewLinesIfNeeded() }
?.cast<KtCallExpression>() ?.cast<KtCallExpression>()
?.getBlock() ?.getBlock()
} }
private fun KtFile.addTopLevelBlock(name: String, first: Boolean = false): KtBlockExpression? { private fun KtFile.addTopLevelBlock(name: String, first: Boolean = false): KtBlockExpression? {
@@ -272,11 +271,16 @@ class KotlinBuildScriptManipulator(private val kotlinScript: KtFile) : GradleBui
} }
private fun KtFile.addToScriptBlock(element: PsiElement, first: Boolean = false): PsiElement? = private fun KtFile.addToScriptBlock(element: PsiElement, first: Boolean = false): PsiElement? =
if (first) script?.blockExpression?.addAfter(element, null) else script?.blockExpression?.add(element) if (first) script?.blockExpression?.addAfter(element, null) else script?.blockExpression?.add(element)
private fun KtFile.addImportIfMissing(path: String): KtImportDirective = private fun KtFile.addImportIfMissing(path: String): KtImportDirective =
importDirectives.find { it.importPath?.pathStr == path } ?: importDirectives.find { it.importPath?.pathStr == path } ?: importList?.add(
importList?.add(psiFactory.createImportDirective(ImportPath.fromString(path))) as KtImportDirective psiFactory.createImportDirective(
ImportPath.fromString(
path
)
)
) as KtImportDirective
private fun KtBlockExpression.addExpressionAfterIfMissing(text: String, after: PsiElement): KtExpression = addStatementIfMissing(text) { private fun KtBlockExpression.addExpressionAfterIfMissing(text: String, after: PsiElement): KtExpression = addStatementIfMissing(text) {
psiFactory.createExpression(it).let { created -> psiFactory.createExpression(it).let { created ->
@@ -286,19 +290,21 @@ class KotlinBuildScriptManipulator(private val kotlinScript: KtFile) : GradleBui
private fun KtBlockExpression.addExpressionIfMissing(text: String, first: Boolean = false): KtExpression = addStatementIfMissing(text) { private fun KtBlockExpression.addExpressionIfMissing(text: String, first: Boolean = false): KtExpression = addStatementIfMissing(text) {
psiFactory.createExpression(it).let { created -> psiFactory.createExpression(it).let { created ->
if(first) addAfter(created, null) else add(created) if (first) addAfter(created, null) else add(created)
} }
} }
private fun KtBlockExpression.addDeclarationIfMissing(text: String, first: Boolean = false): KtDeclaration = addStatementIfMissing(text) { private fun KtBlockExpression.addDeclarationIfMissing(text: String, first: Boolean = false): KtDeclaration =
psiFactory.createDeclaration<KtDeclaration>(it).let { created -> addStatementIfMissing(text) {
if(first) addAfter(created, null) else add(created) psiFactory.createDeclaration<KtDeclaration>(it).let { created ->
if (first) addAfter(created, null) else add(created)
}
} }
}
private inline fun <reified T: PsiElement> KtBlockExpression.addStatementIfMissing( private inline fun <reified T : PsiElement> KtBlockExpression.addStatementIfMissing(
text: String, text: String,
crossinline factory: (String) -> PsiElement): T { crossinline factory: (String) -> PsiElement
): T {
statements.find { it.text == text }?.let { statements.find { it.text == text }?.let {
return it as T return it as T
} }
@@ -307,7 +313,7 @@ class KotlinBuildScriptManipulator(private val kotlinScript: KtFile) : GradleBui
} }
private fun KtPsiFactory.createScriptInitializer(text: String): KtScriptInitializer = private fun KtPsiFactory.createScriptInitializer(text: String): KtScriptInitializer =
createFile("dummy.kts", text).script?.blockExpression?.firstChild as KtScriptInitializer createFile("dummy.kts", text).script?.blockExpression?.firstChild as KtScriptInitializer
private val PsiElement.psiFactory: KtPsiFactory private val PsiElement.psiFactory: KtPsiFactory
get() = KtPsiFactory(this) get() = KtPsiFactory(this)
@@ -319,12 +325,17 @@ class KotlinBuildScriptManipulator(private val kotlinScript: KtFile) : GradleBui
fun getKotlinGradlePluginClassPathSnippet(): String = "classpath(${getKotlinModuleDependencySnippet("gradle-plugin")})" fun getKotlinGradlePluginClassPathSnippet(): String = "classpath(${getKotlinModuleDependencySnippet("gradle-plugin")})"
fun getKotlinModuleDependencySnippet(artifactId: String, version: String? = null): String = fun getKotlinModuleDependencySnippet(artifactId: String, version: String? = null): String =
"kotlinModule(\"${artifactId.removePrefix("kotlin-")}\", ${version?.let { "\"$it\"" } ?: GSK_KOTLIN_VERSION_PROPERTY_NAME})" "kotlinModule(\"${artifactId.removePrefix("kotlin-")}\", ${version?.let { "\"$it\"" } ?: GSK_KOTLIN_VERSION_PROPERTY_NAME})"
fun getCompileDependencySnippet(groupId: String, artifactId: String, compileScope: String = "compile", version: String? = null): String = fun getCompileDependencySnippet(
if (groupId == KOTLIN_GROUP_ID) groupId: String,
"$compileScope(${Companion.getKotlinModuleDependencySnippet(artifactId, version)})" artifactId: String,
else compileScope: String = "compile",
"$compileScope(\"$groupId:$artifactId:$version\")" version: String? = null
): String =
if (groupId == KOTLIN_GROUP_ID)
"$compileScope(${Companion.getKotlinModuleDependencySnippet(artifactId, version)})"
else
"$compileScope(\"$groupId:$artifactId:$version\")"
} }
} }
@@ -32,9 +32,9 @@ import org.jetbrains.plugins.gradle.frameworkSupport.KotlinDslGradleFrameworkSup
import javax.swing.Icon import javax.swing.Icon
abstract class KotlinDslGradleKotlinFrameworkSupportProvider( abstract class KotlinDslGradleKotlinFrameworkSupportProvider(
val frameworkTypeId: String, val frameworkTypeId: String,
val displayName: String, val displayName: String,
val frameworkIcon: Icon val frameworkIcon: Icon
) : KotlinDslGradleFrameworkSupportProvider() { ) : KotlinDslGradleFrameworkSupportProvider() {
override fun getFrameworkType(): FrameworkTypeEx = object : FrameworkTypeEx(frameworkTypeId) { override fun getFrameworkType(): FrameworkTypeEx = object : FrameworkTypeEx(frameworkTypeId) {
override fun getIcon(): Icon = frameworkIcon override fun getIcon(): Icon = frameworkIcon
@@ -42,11 +42,13 @@ abstract class KotlinDslGradleKotlinFrameworkSupportProvider(
override fun createProvider(): FrameworkSupportInModuleProvider = this@KotlinDslGradleKotlinFrameworkSupportProvider override fun createProvider(): FrameworkSupportInModuleProvider = this@KotlinDslGradleKotlinFrameworkSupportProvider
} }
override fun addSupport(projectId: ProjectId, override fun addSupport(
module: Module, projectId: ProjectId,
rootModel: ModifiableRootModel, module: Module,
modifiableModelsProvider: ModifiableModelsProvider, rootModel: ModifiableRootModel,
buildScriptData: BuildScriptDataBuilder) { modifiableModelsProvider: ModifiableModelsProvider,
buildScriptData: BuildScriptDataBuilder
) {
var kotlinVersion = bundledRuntimeVersion() var kotlinVersion = bundledRuntimeVersion()
val additionalRepository = getRepositoryForVersion(kotlinVersion) val additionalRepository = getRepositoryForVersion(kotlinVersion)
if (isSnapshot(bundledRuntimeVersion())) { if (isSnapshot(bundledRuntimeVersion())) {
@@ -61,14 +63,14 @@ abstract class KotlinDslGradleKotlinFrameworkSupportProvider(
} }
buildScriptData buildScriptData
.addPropertyDefinition("val $GSK_KOTLIN_VERSION_PROPERTY_NAME: String by extra") .addPropertyDefinition("val $GSK_KOTLIN_VERSION_PROPERTY_NAME: String by extra")
.addPluginDefinition(getPluginDefinition()) .addPluginDefinition(getPluginDefinition())
.addBuildscriptRepositoriesDefinition("mavenCentral()") .addBuildscriptRepositoriesDefinition("mavenCentral()")
.addRepositoriesDefinition("mavenCentral()") .addRepositoriesDefinition("mavenCentral()")
// TODO: in gradle > 4.1 this could be single declaration e.g. 'val kotlin_version: String by extra { "1.1.11" }' // TODO: in gradle > 4.1 this could be single declaration e.g. 'val kotlin_version: String by extra { "1.1.11" }'
.addBuildscriptPropertyDefinition("var $GSK_KOTLIN_VERSION_PROPERTY_NAME: String by extra\n $GSK_KOTLIN_VERSION_PROPERTY_NAME = \"$kotlinVersion\"") .addBuildscriptPropertyDefinition("var $GSK_KOTLIN_VERSION_PROPERTY_NAME: String by extra\n $GSK_KOTLIN_VERSION_PROPERTY_NAME = \"$kotlinVersion\"")
.addDependencyNotation(getRuntimeLibrary(rootModel)) .addDependencyNotation(getRuntimeLibrary(rootModel))
.addBuildscriptDependencyNotation(getKotlinGradlePluginClassPathSnippet()) .addBuildscriptDependencyNotation(getKotlinGradlePluginClassPathSnippet())
} }
private fun RepositoryDescription.toKotlinRepositorySnippet() = "maven { setUrl(\"$url\") }" private fun RepositoryDescription.toKotlinRepositorySnippet() = "maven { setUrl(\"$url\") }"
@@ -79,35 +81,35 @@ abstract class KotlinDslGradleKotlinFrameworkSupportProvider(
} }
class KotlinDslGradleKotlinJavaFrameworkSupportProvider : class KotlinDslGradleKotlinJavaFrameworkSupportProvider :
KotlinDslGradleKotlinFrameworkSupportProvider("KOTLIN", "Kotlin (Java)", KotlinIcons.SMALL_LOGO) { KotlinDslGradleKotlinFrameworkSupportProvider("KOTLIN", "Kotlin (Java)", KotlinIcons.SMALL_LOGO) {
override fun getPluginDefinition() = "plugin(\"${KotlinGradleModuleConfigurator.KOTLIN}\")" override fun getPluginDefinition() = "plugin(\"${KotlinGradleModuleConfigurator.KOTLIN}\")"
override fun getRuntimeLibrary(rootModel: ModifiableRootModel) = override fun getRuntimeLibrary(rootModel: ModifiableRootModel) =
getCompileDependencySnippet(KOTLIN_GROUP_ID, getStdlibArtifactId(rootModel.sdk, bundledRuntimeVersion())) getCompileDependencySnippet(KOTLIN_GROUP_ID, getStdlibArtifactId(rootModel.sdk, bundledRuntimeVersion()))
override fun addSupport( override fun addSupport(
projectId: ProjectId, projectId: ProjectId,
module: Module, module: Module,
rootModel: ModifiableRootModel, rootModel: ModifiableRootModel,
modifiableModelsProvider: ModifiableModelsProvider, modifiableModelsProvider: ModifiableModelsProvider,
buildScriptData: BuildScriptDataBuilder buildScriptData: BuildScriptDataBuilder
) { ) {
super.addSupport(projectId, module, rootModel, modifiableModelsProvider, buildScriptData) super.addSupport(projectId, module, rootModel, modifiableModelsProvider, buildScriptData)
val jvmTarget = getDefaultJvmTarget(rootModel.sdk, bundledRuntimeVersion()) val jvmTarget = getDefaultJvmTarget(rootModel.sdk, bundledRuntimeVersion())
if (jvmTarget != null) { if (jvmTarget != null) {
buildScriptData buildScriptData
.addImport("import org.jetbrains.kotlin.gradle.tasks.KotlinCompile") .addImport("import org.jetbrains.kotlin.gradle.tasks.KotlinCompile")
.addOther("tasks.withType<KotlinCompile> {\n kotlinOptions.jvmTarget = \"1.8\"\n}\n") .addOther("tasks.withType<KotlinCompile> {\n kotlinOptions.jvmTarget = \"1.8\"\n}\n")
} }
} }
} }
class KotlinDslGradleKotlinJSFrameworkSupportProvider : class KotlinDslGradleKotlinJSFrameworkSupportProvider :
KotlinDslGradleKotlinFrameworkSupportProvider("KOTLIN_JS", "Kotlin (JavaScript)", KotlinIcons.JS) { KotlinDslGradleKotlinFrameworkSupportProvider("KOTLIN_JS", "Kotlin (JavaScript)", KotlinIcons.JS) {
override fun getPluginDefinition(): String = "plugin(\"${KotlinJsGradleModuleConfigurator.KOTLIN_JS}\")" override fun getPluginDefinition(): String = "plugin(\"${KotlinJsGradleModuleConfigurator.KOTLIN_JS}\")"
override fun getRuntimeLibrary(rootModel: ModifiableRootModel) = override fun getRuntimeLibrary(rootModel: ModifiableRootModel) =
getCompileDependencySnippet(KOTLIN_GROUP_ID, MAVEN_JS_STDLIB_ID.removePrefix("kotlin-")) getCompileDependencySnippet(KOTLIN_GROUP_ID, MAVEN_JS_STDLIB_ID.removePrefix("kotlin-"))
} }
@@ -40,11 +40,11 @@ class KotlinGradleModuleConfigurator : KotlinWithGradleConfigurator() {
override fun getJvmTarget(sdk: Sdk?, version: String) = getDefaultJvmTarget(sdk, version)?.description override fun getJvmTarget(sdk: Sdk?, version: String) = getDefaultJvmTarget(sdk, version)?.description
override fun configureModule( override fun configureModule(
module: Module, module: Module,
file: PsiFile, file: PsiFile,
isTopLevelProjectFile: Boolean, isTopLevelProjectFile: Boolean,
version: String, collector: NotificationMessageCollector, version: String, collector: NotificationMessageCollector,
filesToOpen: MutableCollection<PsiFile> filesToOpen: MutableCollection<PsiFile>
) { ) {
super.configureModule(module, file, isTopLevelProjectFile, version, collector, filesToOpen) super.configureModule(module, file, isTopLevelProjectFile, version, collector, filesToOpen)
@@ -53,7 +53,9 @@ class KotlinGradleMultiplatformModuleBuilder : GradleModuleBuilder() {
super.createWizardSteps(wizardContext, modulesProvider) // initializes GradleModuleBuilder.myWizardContext super.createWizardSteps(wizardContext, modulesProvider) // initializes GradleModuleBuilder.myWizardContext
return arrayOf( return arrayOf(
KotlinGradleMultiplatformWizardStep(this, wizardContext), KotlinGradleMultiplatformWizardStep(this, wizardContext),
ExternalModuleSettingsStep(wizardContext, this, GradleProjectSettingsControl(externalProjectSettings)) ExternalModuleSettingsStep(
wizardContext, this, GradleProjectSettingsControl(externalProjectSettings)
)
) )
} }
@@ -96,6 +98,7 @@ class KotlinGradleMultiplatformModuleBuilder : GradleModuleBuilder() {
extendScript: (BuildScriptDataBuilder, Sdk?) -> Unit = { _, _ -> } extendScript: (BuildScriptDataBuilder, Sdk?) -> Unit = { _, _ -> }
) { ) {
if (childModuleName.isNullOrEmpty()) return if (childModuleName.isNullOrEmpty()) return
val moduleDir = contentRoot.createChildDirectory(this, childModuleName!!) val moduleDir = contentRoot.createChildDirectory(this, childModuleName!!)
val buildGradle = moduleDir.createChildData(null, "build.gradle") val buildGradle = moduleDir.createChildData(null, "build.gradle")
val buildScriptData = BuildScriptDataBuilder(buildGradle) val buildScriptData = BuildScriptDataBuilder(buildGradle)
@@ -71,14 +71,16 @@ class KotlinGradleProjectResolverExtension : AbstractProjectResolverExtension()
return resolverCtx.isResolveModulePerSourceSet return resolverCtx.isResolveModulePerSourceSet
} }
override fun populateModuleDependencies(gradleModule: IdeaModule, override fun populateModuleDependencies(
ideModule: DataNode<ModuleData>, gradleModule: IdeaModule,
ideProject: DataNode<ProjectData>) { ideModule: DataNode<ModuleData>,
ideProject: DataNode<ProjectData>
) {
val outputToSourceSet = ideProject.getUserData(GradleProjectResolver.MODULES_OUTPUTS) val outputToSourceSet = ideProject.getUserData(GradleProjectResolver.MODULES_OUTPUTS)
val sourceSetByName = ideProject.getUserData(GradleProjectResolver.RESOLVED_SOURCE_SETS) val sourceSetByName = ideProject.getUserData(GradleProjectResolver.RESOLVED_SOURCE_SETS)
val gradleModel = resolverCtx.getExtraProject(gradleModule, KotlinGradleModel::class.java) val gradleModel = resolverCtx.getExtraProject(gradleModule, KotlinGradleModel::class.java)
?: return super.populateModuleDependencies(gradleModule, ideModule, ideProject) ?: return super.populateModuleDependencies(gradleModule, ideModule, ideProject)
val gradleIdeaProject = gradleModule.project val gradleIdeaProject = gradleModule.project
@@ -92,16 +94,17 @@ class KotlinGradleProjectResolverExtension : AbstractProjectResolverExtension()
val targetModuleNode = ExternalSystemApiUtil.findFirstRecursively(ideProject) { val targetModuleNode = ExternalSystemApiUtil.findFirstRecursively(ideProject) {
(it.data as? ModuleData)?.id == dependency.projectPath (it.data as? ModuleData)?.id == dependency.projectPath
} as DataNode<ModuleData>? ?: return@mapNotNullTo null } as DataNode<ModuleData>? ?: return@mapNotNullTo null
ExternalSystemApiUtil.findAll(targetModuleNode, GradleSourceSetData.KEY).firstOrNull { it.sourceSetName == "main" } ExternalSystemApiUtil.findAll(targetModuleNode, GradleSourceSetData.KEY)
.firstOrNull { it.sourceSetName == "main" }
} }
is FileCollectionDependency -> { is FileCollectionDependency -> {
dependency.files dependency.files
.mapTo(HashSet()) { .mapTo(HashSet()) {
val path = FileUtil.toSystemIndependentName(it.path) val path = FileUtil.toSystemIndependentName(it.path)
val targetSourceSetId = outputToSourceSet?.get(path)?.first ?: return@mapTo null val targetSourceSetId = outputToSourceSet?.get(path)?.first ?: return@mapTo null
sourceSetByName[targetSourceSetId]?.first sourceSetByName[targetSourceSetId]?.first
} }
.singleOrNull() .singleOrNull()
} }
else -> null else -> null
} }
@@ -114,8 +117,7 @@ class KotlinGradleProjectResolverExtension : AbstractProjectResolverExtension()
fun addTransitiveDependenciesOnImplementedModules() { fun addTransitiveDependenciesOnImplementedModules() {
val moduleNodesToProcess = if (useModulePerSourceSet()) { val moduleNodesToProcess = if (useModulePerSourceSet()) {
ExternalSystemApiUtil.findAll(ideModule, GradleSourceSetData.KEY) ExternalSystemApiUtil.findAll(ideModule, GradleSourceSetData.KEY)
} } else listOf(ideModule)
else listOf(ideModule)
for (currentModuleNode in moduleNodesToProcess) { for (currentModuleNode in moduleNodesToProcess) {
val toProcess = LinkedList<DataNode<out ModuleData>>() val toProcess = LinkedList<DataNode<out ModuleData>>()
@@ -128,18 +130,17 @@ class KotlinGradleProjectResolverExtension : AbstractProjectResolverExtension()
val moduleNodeForGradleModel = if (useModulePerSourceSet()) { val moduleNodeForGradleModel = if (useModulePerSourceSet()) {
ExternalSystemApiUtil.findParent(moduleNode, ProjectKeys.MODULE) ExternalSystemApiUtil.findParent(moduleNode, ProjectKeys.MODULE)
} } else moduleNode
else moduleNode
val ideaModule = if (moduleNodeForGradleModel != ideModule) { val ideaModule = if (moduleNodeForGradleModel != ideModule) {
gradleIdeaProject.modules.firstOrNull { it.gradleProject.path == moduleNodeForGradleModel?.data?.id } gradleIdeaProject.modules.firstOrNull { it.gradleProject.path == moduleNodeForGradleModel?.data?.id }
} } else gradleModule
else gradleModule
val implementsModuleIds = resolverCtx.getExtraProject(ideaModule, KotlinGradleModel::class.java)?.implements val implementsModuleIds = resolverCtx.getExtraProject(ideaModule, KotlinGradleModel::class.java)?.implements
?: emptyList() ?: emptyList()
for (implementsModuleId in implementsModuleIds) { for (implementsModuleId in implementsModuleIds) {
val compositePrefix = if (resolverCtx.models.ideaProject != gradleModule.project val compositePrefix = if (resolverCtx.models.ideaProject != gradleModule.project
&& implementsModuleId.startsWith(":")) { && implementsModuleId.startsWith(":")
) {
gradleModule.project.name gradleModule.project.name
} else { } else {
"" ""
@@ -159,8 +160,7 @@ class KotlinGradleProjectResolverExtension : AbstractProjectResolverExtension()
if (currentModuleNode.sourceSetName == "test" && targetMainSourceSet != targetSourceSet) { if (currentModuleNode.sourceSetName == "test" && targetMainSourceSet != targetSourceSet) {
addDependency(currentModuleNode, targetMainSourceSet) addDependency(currentModuleNode, targetMainSourceSet)
} }
} } else {
else {
addDependency(currentModuleNode, targetModule) addDependency(currentModuleNode, targetModule)
} }
} }
@@ -189,9 +189,9 @@ class KotlinGradleProjectResolverExtension : AbstractProjectResolverExtension()
} }
private fun addImplementedModuleNames( private fun addImplementedModuleNames(
dependentModule: DataNode<ModuleData>, dependentModule: DataNode<ModuleData>,
ideProject: DataNode<ProjectData>, ideProject: DataNode<ProjectData>,
gradleModel: KotlinGradleModel gradleModel: KotlinGradleModel
) { ) {
val implementedModules = gradleModel.implements.mapNotNull { findModuleById(ideProject, it) } val implementedModules = gradleModel.implements.mapNotNull { findModuleById(ideProject, it) }
if (resolverCtx.isResolveModulePerSourceSet) { if (resolverCtx.isResolveModulePerSourceSet) {
@@ -206,7 +206,7 @@ class KotlinGradleProjectResolverExtension : AbstractProjectResolverExtension()
} }
private fun DataNode<ModuleData>.getSourceSetsMap() = private fun DataNode<ModuleData>.getSourceSetsMap() =
ExternalSystemApiUtil.getChildren(this, GradleSourceSetData.KEY).associateBy { it.sourceSetName } ExternalSystemApiUtil.getChildren(this, GradleSourceSetData.KEY).associateBy { it.sourceSetName }
private val DataNode<out ModuleData>.sourceSetName private val DataNode<out ModuleData>.sourceSetName
get() = (data as? GradleSourceSetData)?.id?.substringAfterLast(':') get() = (data as? GradleSourceSetData)?.id?.substringAfterLast(':')
@@ -27,7 +27,7 @@ class KotlinJsGradleModuleConfigurator : KotlinWithGradleConfigurator() {
override val targetPlatform: TargetPlatform = JsPlatform override val targetPlatform: TargetPlatform = JsPlatform
override val kotlinPluginName: String = KOTLIN_JS override val kotlinPluginName: String = KOTLIN_JS
override fun getMinimumSupportedVersion() = "1.1.0" override fun getMinimumSupportedVersion() = "1.1.0"
override fun getStdlibArtifactName(sdk: Sdk?, version: String): String = MAVEN_JS_STDLIB_ID override fun getStdlibArtifactName(sdk: Sdk?, version: String): String = MAVEN_JS_STDLIB_ID
companion object { companion object {
val KOTLIN_JS = "kotlin2js" val KOTLIN_JS = "kotlin2js"
@@ -27,7 +27,6 @@ import com.intellij.psi.PsiManager
import org.jetbrains.kotlin.config.ApiVersion import org.jetbrains.kotlin.config.ApiVersion
import org.jetbrains.kotlin.config.CoroutineSupport import org.jetbrains.kotlin.config.CoroutineSupport
import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.idea.KotlinPluginUtil
import org.jetbrains.kotlin.idea.facet.getRuntimeLibraryVersion import org.jetbrains.kotlin.idea.facet.getRuntimeLibraryVersion
import org.jetbrains.kotlin.idea.framework.ui.ConfigureDialogWithModulesAndVersion import org.jetbrains.kotlin.idea.framework.ui.ConfigureDialogWithModulesAndVersion
import org.jetbrains.kotlin.idea.quickfix.ChangeCoroutineSupportFix import org.jetbrains.kotlin.idea.quickfix.ChangeCoroutineSupportFix
@@ -56,8 +55,8 @@ abstract class KotlinWithGradleConfigurator : KotlinProjectConfigurator {
val buildFiles = runReadAction { val buildFiles = runReadAction {
listOf( listOf(
module.getBuildScriptPsiFile(), module.getBuildScriptPsiFile(),
module.project.getTopLevelBuildScriptPsiFile() module.project.getTopLevelBuildScriptPsiFile()
).filterNotNull() ).filterNotNull()
} }
@@ -74,12 +73,12 @@ abstract class KotlinWithGradleConfigurator : KotlinProjectConfigurator {
private fun PsiFile.isConfiguredByAnyGradleConfigurator(): Boolean { private fun PsiFile.isConfiguredByAnyGradleConfigurator(): Boolean {
return Extensions.getExtensions(KotlinProjectConfigurator.EP_NAME) return Extensions.getExtensions(KotlinProjectConfigurator.EP_NAME)
.filterIsInstance<KotlinWithGradleConfigurator>() .filterIsInstance<KotlinWithGradleConfigurator>()
.any { it.isFileConfigured(this) } .any { it.isFileConfigured(this) }
} }
protected open fun isApplicable(module: Module): Boolean = protected open fun isApplicable(module: Module): Boolean =
module.getBuildSystemType() == Gradle module.getBuildSystemType() == Gradle
protected open fun getMinimumSupportedVersion() = "1.0.0" protected open fun getMinimumSupportedVersion() = "1.0.0"
@@ -103,10 +102,12 @@ abstract class KotlinWithGradleConfigurator : KotlinProjectConfigurator {
} }
} }
fun configureWithVersion(project: Project, fun configureWithVersion(
modulesToConfigure: List<Module>, project: Project,
kotlinVersion: String, modulesToConfigure: List<Module>,
collector: NotificationMessageCollector): HashSet<PsiFile> { kotlinVersion: String,
collector: NotificationMessageCollector
): HashSet<PsiFile> {
val filesToOpen = HashSet<PsiFile>() val filesToOpen = HashSet<PsiFile>()
val buildScript = project.getTopLevelBuildScriptPsiFile() val buildScript = project.getTopLevelBuildScriptPsiFile()
if (buildScript != null && canConfigureFile(buildScript)) { if (buildScript != null && canConfigureFile(buildScript)) {
@@ -120,8 +121,7 @@ abstract class KotlinWithGradleConfigurator : KotlinProjectConfigurator {
val file = module.getBuildScriptPsiFile() val file = module.getBuildScriptPsiFile()
if (file != null && canConfigureFile(file)) { if (file != null && canConfigureFile(file)) {
configureModule(module, file, false, kotlinVersion, collector, filesToOpen) configureModule(module, file, false, kotlinVersion, collector, filesToOpen)
} } else {
else {
showErrorMessage(project, "Cannot find build.gradle file for module " + module.name) showErrorMessage(project, "Cannot find build.gradle file for module " + module.name)
} }
} }
@@ -129,12 +129,12 @@ abstract class KotlinWithGradleConfigurator : KotlinProjectConfigurator {
} }
open fun configureModule( open fun configureModule(
module: Module, module: Module,
file: PsiFile, file: PsiFile,
isTopLevelProjectFile: Boolean, isTopLevelProjectFile: Boolean,
version: String, version: String,
collector: NotificationMessageCollector, collector: NotificationMessageCollector,
filesToOpen: MutableCollection<PsiFile> filesToOpen: MutableCollection<PsiFile>
) { ) {
val isModified = configureBuildScript(file, isTopLevelProjectFile, version, collector) val isModified = configureBuildScript(file, isTopLevelProjectFile, version, collector)
if (isModified) { if (isModified) {
@@ -146,10 +146,11 @@ abstract class KotlinWithGradleConfigurator : KotlinProjectConfigurator {
val sdk = ModuleUtil.findModuleForPsiElement(file)?.let { ModuleRootManager.getInstance(it).sdk } val sdk = ModuleUtil.findModuleForPsiElement(file)?.let { ModuleRootManager.getInstance(it).sdk }
val jvmTarget = getJvmTarget(sdk, version) val jvmTarget = getJvmTarget(sdk, version)
return getManipulator(file).configureModuleBuildScript( return getManipulator(file).configureModuleBuildScript(
kotlinPluginName, kotlinPluginName,
getStdlibArtifactName(sdk, version), getStdlibArtifactName(sdk, version),
version, version,
jvmTarget) jvmTarget
)
} }
protected open fun getStdlibArtifactName(sdk: Sdk?, version: String) = getStdlibArtifactId(sdk, version) protected open fun getStdlibArtifactName(sdk: Sdk?, version: String) = getStdlibArtifactId(sdk, version)
@@ -159,9 +160,9 @@ abstract class KotlinWithGradleConfigurator : KotlinProjectConfigurator {
protected abstract val kotlinPluginName: String protected abstract val kotlinPluginName: String
protected open fun addElementsToFile( protected open fun addElementsToFile(
file: PsiFile, file: PsiFile,
isTopLevelProjectFile: Boolean, isTopLevelProjectFile: Boolean,
version: String version: String
): Boolean { ): Boolean {
if (!isTopLevelProjectFile) { if (!isTopLevelProjectFile) {
var wasModified = configureProjectFile(file, version) var wasModified = configureProjectFile(file, version)
@@ -172,10 +173,10 @@ abstract class KotlinWithGradleConfigurator : KotlinProjectConfigurator {
} }
private fun configureBuildScript( private fun configureBuildScript(
file: PsiFile, file: PsiFile,
isTopLevelProjectFile: Boolean, isTopLevelProjectFile: Boolean,
version: String, version: String,
collector: NotificationMessageCollector collector: NotificationMessageCollector
): Boolean { ): Boolean {
val isModified = file.project.executeWriteCommand("Configure ${file.name}", null) { val isModified = file.project.executeWriteCommand("Configure ${file.name}", null) {
val isModified = addElementsToFile(file, isTopLevelProjectFile, version) val isModified = addElementsToFile(file, isTopLevelProjectFile, version)
@@ -192,21 +193,23 @@ abstract class KotlinWithGradleConfigurator : KotlinProjectConfigurator {
} }
override fun updateLanguageVersion( override fun updateLanguageVersion(
module: Module, module: Module,
languageVersion: String?, languageVersion: String?,
apiVersion: String?, apiVersion: String?,
requiredStdlibVersion: ApiVersion, requiredStdlibVersion: ApiVersion,
forTests: Boolean forTests: Boolean
) { ) {
val runtimeUpdateRequired = getRuntimeLibraryVersion(module)?.let { ApiVersion.parse(it) }?.let { runtimeVersion -> val runtimeUpdateRequired = getRuntimeLibraryVersion(module)?.let { ApiVersion.parse(it) }?.let { runtimeVersion ->
runtimeVersion < requiredStdlibVersion runtimeVersion < requiredStdlibVersion
} ?: false } ?: false
if (runtimeUpdateRequired) { if (runtimeUpdateRequired) {
Messages.showErrorDialog(module.project, Messages.showErrorDialog(
"This language feature requires version $requiredStdlibVersion or later of the Kotlin runtime library. " + module.project,
"Please update the version in your build script.", "This language feature requires version $requiredStdlibVersion or later of the Kotlin runtime library. " +
"Update Language Version") "Please update the version in your build script.",
"Update Language Version"
)
return return
} }
@@ -219,13 +222,15 @@ abstract class KotlinWithGradleConfigurator : KotlinProjectConfigurator {
override fun changeCoroutineConfiguration(module: Module, state: LanguageFeature.State) { override fun changeCoroutineConfiguration(module: Module, state: LanguageFeature.State) {
val runtimeUpdateRequired = state != LanguageFeature.State.DISABLED && val runtimeUpdateRequired = state != LanguageFeature.State.DISABLED &&
(getRuntimeLibraryVersion(module)?.startsWith("1.0") ?: false) (getRuntimeLibraryVersion(module)?.startsWith("1.0") ?: false)
if (runtimeUpdateRequired) { if (runtimeUpdateRequired) {
Messages.showErrorDialog(module.project, Messages.showErrorDialog(
"Coroutines support requires version 1.1 or later of the Kotlin runtime library. " + module.project,
"Please update the version in your build script.", "Coroutines support requires version 1.1 or later of the Kotlin runtime library. " +
ChangeCoroutineSupportFix.getFixText(state)) "Please update the version in your build script.",
ChangeCoroutineSupportFix.getFixText(state)
)
return return
} }
@@ -235,7 +240,12 @@ abstract class KotlinWithGradleConfigurator : KotlinProjectConfigurator {
} }
} }
override fun addLibraryDependency(module: Module, element: PsiElement, library: ExternalLibraryDescriptor, libraryJarDescriptors: List<LibraryJarDescriptor>) { override fun addLibraryDependency(
module: Module,
element: PsiElement,
library: ExternalLibraryDescriptor,
libraryJarDescriptors: List<LibraryJarDescriptor>
) {
val scope = OrderEntryFix.suggestScopeByLocation(module, element) val scope = OrderEntryFix.suggestScopeByLocation(module, element)
KotlinWithGradleConfigurator.addKotlinLibraryToModule(module, scope, library) KotlinWithGradleConfigurator.addKotlinLibraryToModule(module, scope, library)
} }
@@ -255,7 +265,7 @@ abstract class KotlinWithGradleConfigurator : KotlinProjectConfigurator {
private val KOTLIN_BUILD_SCRIPT_NAME = "build.gradle.kts" private val KOTLIN_BUILD_SCRIPT_NAME = "build.gradle.kts"
fun getGroovyDependencySnippet(artifactName: String, scope: String = "compile") = fun getGroovyDependencySnippet(artifactName: String, scope: String = "compile") =
"$scope \"org.jetbrains.kotlin:$artifactName:\$kotlin_version\"" "$scope \"org.jetbrains.kotlin:$artifactName:\$kotlin_version\""
fun getGroovyApplyPluginDirective(pluginName: String) = "apply plugin: '$pluginName'" fun getGroovyApplyPluginDirective(pluginName: String) = "apply plugin: '$pluginName'"
@@ -266,12 +276,12 @@ abstract class KotlinWithGradleConfigurator : KotlinProjectConfigurator {
} }
getManipulator(buildScript) getManipulator(buildScript)
.addKotlinLibraryToModuleBuildScript(scope, libraryDescriptor, module.getBuildSystemType() == AndroidGradle) .addKotlinLibraryToModuleBuildScript(scope, libraryDescriptor, module.getBuildSystemType() == AndroidGradle)
buildScript.virtualFile?.let { buildScript.virtualFile?.let {
createConfigureKotlinNotificationCollector(buildScript.project) createConfigureKotlinNotificationCollector(buildScript.project)
.addMessage(it.path + " was modified") .addMessage(it.path + " was modified")
.showNotification() .showNotification()
} }
} }
@@ -280,20 +290,20 @@ abstract class KotlinWithGradleConfigurator : KotlinProjectConfigurator {
} }
fun changeLanguageVersion(module: Module, languageVersion: String?, apiVersion: String?, forTests: Boolean) = fun changeLanguageVersion(module: Module, languageVersion: String?, apiVersion: String?, forTests: Boolean) =
changeBuildGradle(module) { buildScriptFile -> changeBuildGradle(module) { buildScriptFile ->
val manipulator = getManipulator(buildScriptFile) val manipulator = getManipulator(buildScriptFile)
var result: PsiElement? = null var result: PsiElement? = null
if (languageVersion != null) { if (languageVersion != null) {
result = manipulator.changeLanguageVersion(languageVersion, forTests) result = manipulator.changeLanguageVersion(languageVersion, forTests)
}
if (apiVersion != null) {
result = manipulator.changeApiVersion(apiVersion, forTests)
}
result
} }
if (apiVersion != null) {
result = manipulator.changeApiVersion(apiVersion, forTests)
}
result
}
private fun changeBuildGradle(module: Module, body: (PsiFile) -> PsiElement?): PsiElement? { private fun changeBuildGradle(module: Module, body: (PsiFile) -> PsiElement?): PsiElement? {
val buildScriptFile = module.getBuildScriptPsiFile() val buildScriptFile = module.getBuildScriptPsiFile()
if (buildScriptFile != null && canConfigureFile(buildScriptFile)) { if (buildScriptFile != null && canConfigureFile(buildScriptFile)) {
@@ -340,19 +350,21 @@ abstract class KotlinWithGradleConfigurator : KotlinProjectConfigurator {
} }
private fun findBuildGradleFile(path: String): File? = private fun findBuildGradleFile(path: String): File? =
File(path + "/" + GradleConstants.DEFAULT_SCRIPT_NAME).takeIf { it.exists() } ?: File(path + "/" + GradleConstants.DEFAULT_SCRIPT_NAME).takeIf { it.exists() }
File(path + "/" + KOTLIN_BUILD_SCRIPT_NAME).takeIf { it.exists() } ?: File(path + "/" + KOTLIN_BUILD_SCRIPT_NAME).takeIf { it.exists() }
private fun File.getPsiFile(project: Project) = VfsUtil.findFileByIoFile(this, true)?.let { private fun File.getPsiFile(project: Project) = VfsUtil.findFileByIoFile(this, true)?.let {
PsiManager.getInstance(project).findFile(it) PsiManager.getInstance(project).findFile(it)
} }
private fun showErrorMessage(project: Project, message: String?) { private fun showErrorMessage(project: Project, message: String?) {
Messages.showErrorDialog(project, Messages.showErrorDialog(
"<html>Couldn't configure kotlin-gradle plugin automatically.<br/>" + project,
(if (message != null) message + "<br/>" else "") + "<html>Couldn't configure kotlin-gradle plugin automatically.<br/>" +
"<br/>See manual installation instructions <a href=\"https://kotlinlang.org/docs/reference/using-gradle.html\">here</a>.</html>", (if (message != null) message + "<br/>" else "") +
"Configure Kotlin-Gradle Plugin") "<br/>See manual installation instructions <a href=\"https://kotlinlang.org/docs/reference/using-gradle.html\">here</a>.</html>",
"Configure Kotlin-Gradle Plugin"
)
} }
} }
} }
@@ -43,7 +43,7 @@ import kotlin.script.dependencies.Environment
import kotlin.script.experimental.dependencies.ScriptDependencies import kotlin.script.experimental.dependencies.ScriptDependencies
class GradleScriptDefinitionsContributor(private val project: Project): ScriptDefinitionContributor { class GradleScriptDefinitionsContributor(private val project: Project) : ScriptDefinitionContributor {
override val id: String = "Gradle Kotlin DSL" override val id: String = "Gradle Kotlin DSL"
private val failedToLoad = AtomicBoolean(false) private val failedToLoad = AtomicBoolean(false)
@@ -126,16 +126,15 @@ class GradleScriptDefinitionsContributor(private val project: Project): ScriptDe
private fun kotlinStdlibAndCompiler(gradleLibDir: File): List<File> { private fun kotlinStdlibAndCompiler(gradleLibDir: File): List<File> {
// additionally need compiler jar to load gradle resolver // additionally need compiler jar to load gradle resolver
return gradleLibDir.listFiles { file -> file.name.startsWith("kotlin-compiler-embeddable") || file.name.startsWith("kotlin-stdlib") } return gradleLibDir.listFiles { file -> file.name.startsWith("kotlin-compiler-embeddable") || file.name.startsWith("kotlin-stdlib") }
.firstOrNull()?.let(::listOf).orEmpty() .firstOrNull()?.let(::listOf).orEmpty()
} }
private fun loadGradleTemplates( private fun loadGradleTemplates(
templateClass: String, dependencySelector: Regex, templateClass: String, dependencySelector: Regex,
additionalResolverClasspath: (gradleLibDir: File) -> List<File> additionalResolverClasspath: (gradleLibDir: File) -> List<File>
): List<KotlinScriptDefinition> = try { ): List<KotlinScriptDefinition> = try {
doLoadGradleTemplates(templateClass, dependencySelector, additionalResolverClasspath) doLoadGradleTemplates(templateClass, dependencySelector, additionalResolverClasspath)
} } catch (t: Throwable) {
catch (t: Throwable) {
// TODO: review exception handling // TODO: review exception handling
failedToLoad.set(true) failedToLoad.set(true)
emptyList() emptyList()
@@ -143,27 +142,27 @@ class GradleScriptDefinitionsContributor(private val project: Project): ScriptDe
private fun doLoadGradleTemplates( private fun doLoadGradleTemplates(
templateClass: String, dependencySelector: Regex, templateClass: String, dependencySelector: Regex,
additionalResolverClasspath: (gradleLibDir: File) -> List<File> additionalResolverClasspath: (gradleLibDir: File) -> List<File>
): List<KotlinScriptDefinition> { ): List<KotlinScriptDefinition> {
fun createEnvironment(gradleExeSettings: GradleExecutionSettings): Environment { fun createEnvironment(gradleExeSettings: GradleExecutionSettings): Environment {
val gradleJvmOptions = gradleExeSettings.daemonVmOptions?.let { vmOptions -> val gradleJvmOptions = gradleExeSettings.daemonVmOptions?.let { vmOptions ->
CommandLineTokenizer(vmOptions).toList() CommandLineTokenizer(vmOptions).toList()
.mapNotNull { it?.let { it as? String } } .mapNotNull { it?.let { it as? String } }
.filterNot(String::isBlank) .filterNot(String::isBlank)
.distinct() .distinct()
} ?: emptyList() } ?: emptyList()
return mapOf( return mapOf(
"gradleHome" to gradleExeSettings.gradleHome?.let(::File), "gradleHome" to gradleExeSettings.gradleHome?.let(::File),
"projectRoot" to (project.basePath ?: project.baseDir.canonicalPath)?.let(::File), "projectRoot" to (project.basePath ?: project.baseDir.canonicalPath)?.let(::File),
"gradleWithConnection" to { action: (ProjectConnection) -> Unit -> "gradleWithConnection" to { action: (ProjectConnection) -> Unit ->
GradleExecutionHelper().execute(project.basePath!!, null) { action(it) } GradleExecutionHelper().execute(project.basePath!!, null) { action(it) }
}, },
"gradleJavaHome" to gradleExeSettings.javaHome, "gradleJavaHome" to gradleExeSettings.javaHome,
"gradleJvmOptions" to gradleJvmOptions, "gradleJvmOptions" to gradleJvmOptions,
"getScriptSectionTokens" to ::topLevelSectionCodeTextTokens "getScriptSectionTokens" to ::topLevelSectionCodeTextTokens
) )
} }
@@ -171,12 +170,14 @@ class GradleScriptDefinitionsContributor(private val project: Project): ScriptDe
val gradleSettings = ExternalSystemApiUtil.getSettings(project, GradleConstants.SYSTEM_ID) val gradleSettings = ExternalSystemApiUtil.getSettings(project, GradleConstants.SYSTEM_ID)
if (gradleSettings.getLinkedProjectsSettings().isEmpty()) return emptyList() if (gradleSettings.getLinkedProjectsSettings().isEmpty()) return emptyList()
val projectSettings = gradleSettings.getLinkedProjectsSettings().filterIsInstance<GradleProjectSettings>().firstOrNull() ?: return emptyList() val projectSettings =
gradleSettings.getLinkedProjectsSettings().filterIsInstance<GradleProjectSettings>().firstOrNull() ?: return emptyList()
val gradleExeSettings = ExternalSystemApiUtil.getExecutionSettings<GradleExecutionSettings>( val gradleExeSettings = ExternalSystemApiUtil.getExecutionSettings<GradleExecutionSettings>(
project, project,
projectSettings.externalProjectPath, projectSettings.externalProjectPath,
GradleConstants.SYSTEM_ID) GradleConstants.SYSTEM_ID
)
val gradleHome = gradleExeSettings.gradleHome ?: error("Unable to get Gradle home directory") val gradleHome = gradleExeSettings.gradleHome ?: error("Unable to get Gradle home directory")
@@ -189,10 +190,10 @@ class GradleScriptDefinitionsContributor(private val project: Project): ScriptDe
}.takeIf { it.isNotEmpty() }?.asList() ?: error("Missing jars in gradle directory") }.takeIf { it.isNotEmpty() }?.asList() ?: error("Missing jars in gradle directory")
return loadDefinitionsFromTemplates( return loadDefinitionsFromTemplates(
listOf(templateClass), listOf(templateClass),
templateClasspath, templateClasspath,
createEnvironment(gradleExeSettings), createEnvironment(gradleExeSettings),
additionalResolverClasspath(gradleLibDir) additionalResolverClasspath(gradleLibDir)
) )
} }
@@ -268,15 +269,15 @@ class TopLevelSectionTokensEnumerator(script: CharSequence, identifier: String)
} }
fun topLevelSectionCodeTextTokens(script: CharSequence, sectionIdentifier: String): Sequence<CharSequence> = fun topLevelSectionCodeTextTokens(script: CharSequence, sectionIdentifier: String): Sequence<CharSequence> =
TopLevelSectionTokensEnumerator(script, sectionIdentifier).asSequence() TopLevelSectionTokensEnumerator(script, sectionIdentifier).asSequence()
.filter { it.tokenType !in KtTokens.WHITE_SPACE_OR_COMMENT_BIT_SET } .filter { it.tokenType !in KtTokens.WHITE_SPACE_OR_COMMENT_BIT_SET }
.map { it.tokenSequence } .map { it.tokenSequence }
private const val KOTLIN_BUILD_FILE_SUFFIX = ".gradle.kts" private const val KOTLIN_BUILD_FILE_SUFFIX = ".gradle.kts"
class GradleScriptDefaultDependenciesProvider( class GradleScriptDefaultDependenciesProvider(
private val scriptDependenciesCache: ScriptDependenciesCache private val scriptDependenciesCache: ScriptDependenciesCache
) : DefaultScriptDependenciesProvider { ) : DefaultScriptDependenciesProvider {
override fun defaultDependenciesFor(scriptFile: VirtualFile): ScriptDependencies? { override fun defaultDependenciesFor(scriptFile: VirtualFile): ScriptDependencies? {
if (!scriptFile.name.endsWith(KOTLIN_BUILD_FILE_SUFFIX)) return null if (!scriptFile.name.endsWith(KOTLIN_BUILD_FILE_SUFFIX)) return null
@@ -285,5 +286,5 @@ class GradleScriptDefaultDependenciesProvider(
} }
private fun previouslyAnalyzedScriptsCombinedDependencies() = private fun previouslyAnalyzedScriptsCombinedDependencies() =
scriptDependenciesCache.combineDependencies { it.name.endsWith(KOTLIN_BUILD_FILE_SUFFIX) } scriptDependenciesCache.combineDependencies { it.name.endsWith(KOTLIN_BUILD_FILE_SUFFIX) }
} }
@@ -25,9 +25,9 @@ import com.intellij.util.text.VersionComparatorUtil
import org.jetbrains.kotlin.idea.configuration.allModules import org.jetbrains.kotlin.idea.configuration.allModules
import org.jetbrains.kotlin.idea.configuration.getWholeModuleGroup import org.jetbrains.kotlin.idea.configuration.getWholeModuleGroup
import org.jetbrains.kotlin.idea.inspections.ReplaceStringInDocumentFix import org.jetbrains.kotlin.idea.inspections.ReplaceStringInDocumentFix
import org.jetbrains.kotlin.idea.versions.LibInfo
import org.jetbrains.kotlin.idea.versions.DEPRECATED_LIBRARIES_INFORMATION import org.jetbrains.kotlin.idea.versions.DEPRECATED_LIBRARIES_INFORMATION
import org.jetbrains.kotlin.idea.versions.DeprecatedLibInfo import org.jetbrains.kotlin.idea.versions.DeprecatedLibInfo
import org.jetbrains.kotlin.idea.versions.LibInfo
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
import org.jetbrains.plugins.gradle.codeInspection.GradleBaseInspection import org.jetbrains.plugins.gradle.codeInspection.GradleBaseInspection
import org.jetbrains.plugins.groovy.codeInspection.BaseInspectionVisitor import org.jetbrains.plugins.groovy.codeInspection.BaseInspectionVisitor
@@ -60,19 +60,24 @@ class DeprecatedGradleDependencyInspection : GradleBaseInspection() {
if (dependencyText.contains(libMarker)) { if (dependencyText.contains(libMarker)) {
// Should be generified for any library, not exactly Kotlin stdlib // Should be generified for any library, not exactly Kotlin stdlib
val libVersion = val libVersion =
DifferentStdlibGradleVersionInspection.getResolvedKotlinStdlibVersion( DifferentStdlibGradleVersionInspection.getResolvedKotlinStdlibVersion(
dependencyStatement.containingFile, listOf(outdatedInfo.old.name)) ?: dependencyStatement.containingFile, listOf(outdatedInfo.old.name)
libraryVersionFromOrderEntry(dependencyStatement.containingFile, outdatedInfo.old.name) ) ?: libraryVersionFromOrderEntry(dependencyStatement.containingFile, outdatedInfo.old.name)
if (libVersion != null && VersionComparatorUtil.COMPARATOR.compare(libVersion, outdatedInfo.outdatedAfterVersion) >= 0) { if (libVersion != null && VersionComparatorUtil.COMPARATOR.compare(
libVersion,
outdatedInfo.outdatedAfterVersion
) >= 0
) {
val reportOnElement = reportOnElement(dependencyStatement, outdatedInfo) val reportOnElement = reportOnElement(dependencyStatement, outdatedInfo)
registerError( registerError(
reportOnElement, outdatedInfo.message, reportOnElement, outdatedInfo.message,
arrayOf(ReplaceStringInDocumentFix(reportOnElement, outdatedInfo.old.name, outdatedInfo.new.name)), arrayOf(ReplaceStringInDocumentFix(reportOnElement, outdatedInfo.old.name, outdatedInfo.new.name)),
ProblemHighlightType.LIKE_DEPRECATED) ProblemHighlightType.LIKE_DEPRECATED
)
break break
} }
@@ -29,7 +29,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlo
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrCallExpression import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrCallExpression
class DifferentKotlinGradleVersionInspection : GradleBaseInspection(), PluginVersionDependentInspection{ class DifferentKotlinGradleVersionInspection : GradleBaseInspection(), PluginVersionDependentInspection {
override var testVersionMessage: String? = null override var testVersionMessage: String? = null
@TestOnly set @TestOnly set
@@ -58,15 +58,15 @@ class DifferentKotlinGradleVersionInspection : GradleBaseInspection(), PluginVer
} ?: return } ?: return
val kotlinPluginVersion = val kotlinPluginVersion =
GradleHeuristicHelper.getHeuristicVersionInBuildScriptDependency(kotlinPluginStatement) ?: GradleHeuristicHelper.getHeuristicVersionInBuildScriptDependency(kotlinPluginStatement) ?: getResolvedKotlinGradleVersion(
getResolvedKotlinGradleVersion(closure.containingFile) ?: closure.containingFile
return ) ?: return
onFound(kotlinPluginVersion, kotlinPluginStatement) onFound(kotlinPluginVersion, kotlinPluginStatement)
} }
} }
private inner class MyVisitor: VersionFinder() { private inner class MyVisitor : VersionFinder() {
private val idePluginVersion by lazy { bundledRuntimeVersion() } private val idePluginVersion by lazy { bundledRuntimeVersion() }
override fun onFound(kotlinPluginVersion: String, kotlinPluginStatement: GrCallExpression) { override fun onFound(kotlinPluginVersion: String, kotlinPluginStatement: GrCallExpression) {
@@ -35,10 +35,11 @@ import java.util.*
class DifferentStdlibGradleVersionInspection : GradleBaseInspection() { class DifferentStdlibGradleVersionInspection : GradleBaseInspection() {
override fun buildVisitor(): BaseInspectionVisitor = MyVisitor( override fun buildVisitor(): BaseInspectionVisitor = MyVisitor(
listOf(MAVEN_STDLIB_ID, MAVEN_STDLIB_ID_JRE7, MAVEN_STDLIB_ID_JDK7, MAVEN_STDLIB_ID_JRE8, MAVEN_STDLIB_ID_JDK8)) listOf(MAVEN_STDLIB_ID, MAVEN_STDLIB_ID_JRE7, MAVEN_STDLIB_ID_JDK7, MAVEN_STDLIB_ID_JRE8, MAVEN_STDLIB_ID_JDK8)
)
override fun buildErrorString(vararg args: Any) = override fun buildErrorString(vararg args: Any) =
"Plugin version (${args[0]}) is not the same as library version (${args[1]})" "Plugin version (${args[0]}) is not the same as library version (${args[1]})"
private abstract class VersionFinder(private val libraryIds: List<String>) : KotlinGradleInspectionVisitor() { private abstract class VersionFinder(private val libraryIds: List<String>) : KotlinGradleInspectionVisitor() {
protected abstract fun onFound(stdlibVersion: String, stdlibStatement: GrCallExpression) protected abstract fun onFound(stdlibVersion: String, stdlibStatement: GrCallExpression)
@@ -58,7 +59,7 @@ class DifferentStdlibGradleVersionInspection : GradleBaseInspection() {
} }
} }
private inner class MyVisitor(libraryIds: List<String>): VersionFinder(libraryIds) { private inner class MyVisitor(libraryIds: List<String>) : VersionFinder(libraryIds) {
override fun onFound(stdlibVersion: String, stdlibStatement: GrCallExpression) { override fun onFound(stdlibVersion: String, stdlibStatement: GrCallExpression) {
val gradlePluginVersion = getResolvedKotlinGradleVersion(stdlibStatement.containingFile) val gradlePluginVersion = getResolvedKotlinGradleVersion(stdlibStatement.containingFile)
@@ -116,6 +117,6 @@ class DifferentStdlibGradleVersionInspection : GradleBaseInspection() {
internal fun DataNode<*>.getResolvedKotlinStdlibVersionByModuleData(libraryIds: List<String>): String? { internal fun DataNode<*>.getResolvedKotlinStdlibVersionByModuleData(libraryIds: List<String>): String? {
return KotlinGradleModelFacade.EP_NAME.extensions.asSequence() return KotlinGradleModelFacade.EP_NAME.extensions.asSequence()
.mapNotNull { it.getResolvedKotlinStdlibVersionByModuleData(this, libraryIds) } .mapNotNull { it.getResolvedKotlinStdlibVersionByModuleData(this, libraryIds) }
.firstOrNull() .firstOrNull()
} }
@@ -32,16 +32,16 @@ import java.util.*
object GradleHeuristicHelper { object GradleHeuristicHelper {
fun getHeuristicVersionInBuildScriptDependency(classpathStatement: GrCallExpression): String? { fun getHeuristicVersionInBuildScriptDependency(classpathStatement: GrCallExpression): String? {
val argumentList = when (classpathStatement) { val argumentList = when (classpathStatement) {
is GrMethodCall -> classpathStatement.argumentList // classpath('argument') is GrMethodCall -> classpathStatement.argumentList // classpath('argument')
else -> classpathStatement.getChildrenOfType<GrCommandArgumentList>().singleOrNull() // classpath 'argument' else -> classpathStatement.getChildrenOfType<GrCommandArgumentList>().singleOrNull() // classpath 'argument'
} ?: return null } ?: return null
val grLiteral = argumentList.children.firstOrNull() as? GrLiteral ?: return null val grLiteral = argumentList.children.firstOrNull() as? GrLiteral ?: return null
if (grLiteral is GrString && grLiteral.injections.size == 1) { if (grLiteral is GrString && grLiteral.injections.size == 1) {
val versionInjection = grLiteral.injections.first() ?: return null val versionInjection = grLiteral.injections.first() ?: return null
val expression = versionInjection.expression as? GrReferenceExpression ?: // $some_variable val expression = versionInjection.expression as? GrReferenceExpression ?: // $some_variable
versionInjection.closableBlock?.getChildrenOfType<GrReferenceExpression>()?.singleOrNull() ?: // ${some_variable} versionInjection.closableBlock?.getChildrenOfType<GrReferenceExpression>()?.singleOrNull() ?: // ${some_variable}
return null return null
return resolveVariableInBuildScript(classpathStatement, expression.text) return resolveVariableInBuildScript(classpathStatement, expression.text)
} }
@@ -45,7 +45,7 @@ abstract class KotlinGradleInspectionVisitor : BaseInspectionVisitor() {
} }
fun getResolvedKotlinGradleVersion(file: PsiFile) = fun getResolvedKotlinGradleVersion(file: PsiFile) =
ModuleUtilCore.findModuleForFile(file.virtualFile, file.project)?.let { getResolvedKotlinGradleVersion(it) } ModuleUtilCore.findModuleForFile(file.virtualFile, file.project)?.let { getResolvedKotlinGradleVersion(it) }
fun getResolvedKotlinGradleVersion(module: Module): String? { fun getResolvedKotlinGradleVersion(module: Module): String? {
val projectStructureNode = findGradleProjectStructure(module) ?: return null val projectStructureNode = findGradleProjectStructure(module) ?: return null
@@ -65,7 +65,7 @@ private val KOTLIN_PLUGIN_PATH_MARKER = "${KotlinWithGradleConfigurator.GROUP_ID
// Maven local repo path (example): ~/.m2/repository/org/jetbrains/kotlin/kotlin-runtime/<version> // Maven local repo path (example): ~/.m2/repository/org/jetbrains/kotlin/kotlin-runtime/<version>
private val KOTLIN_PLUGIN_PATH_MARKER_FOR_MAVEN_LOCAL_REPO = private val KOTLIN_PLUGIN_PATH_MARKER_FOR_MAVEN_LOCAL_REPO =
"${KotlinWithGradleConfigurator.GROUP_ID.replace('.', '/')}/${KotlinWithGradleConfigurator.GRADLE_PLUGIN_ID}/" "${KotlinWithGradleConfigurator.GROUP_ID.replace('.', '/')}/${KotlinWithGradleConfigurator.GRADLE_PLUGIN_ID}/"
internal fun findKotlinPluginVersion(classpathData: BuildScriptClasspathData): String? { internal fun findKotlinPluginVersion(classpathData: BuildScriptClasspathData): String? {
for (classPathEntry in classpathData.classpathEntries.asReversed()) { for (classPathEntry in classpathData.classpathEntries.asReversed()) {
@@ -78,7 +78,8 @@ internal fun findKotlinPluginVersion(classpathData: BuildScriptClasspathData): S
return versionSubstring return versionSubstring
} }
} else if (uniformedPath.contains(KOTLIN_PLUGIN_PATH_MARKER_FOR_MAVEN_LOCAL_REPO)) { } else if (uniformedPath.contains(KOTLIN_PLUGIN_PATH_MARKER_FOR_MAVEN_LOCAL_REPO)) {
val versionSubstring = uniformedPath.substringAfter(KOTLIN_PLUGIN_PATH_MARKER_FOR_MAVEN_LOCAL_REPO).substringBefore('/', "<error>") val versionSubstring =
uniformedPath.substringAfter(KOTLIN_PLUGIN_PATH_MARKER_FOR_MAVEN_LOCAL_REPO).substringBefore('/', "<error>")
if (versionSubstring != "<error>") { if (versionSubstring != "<error>") {
return versionSubstring return versionSubstring
} }
@@ -91,7 +92,7 @@ internal fun findKotlinPluginVersion(classpathData: BuildScriptClasspathData): S
class NodeWithData<T>(val node: DataNode<*>, val data: T) class NodeWithData<T>(val node: DataNode<*>, val data: T)
fun <T: Any> DataNode<*>.findAll(key: Key<T>): List<NodeWithData<T>> { fun <T : Any> DataNode<*>.findAll(key: Key<T>): List<NodeWithData<T>> {
val nodes = ExternalSystemApiUtil.findAll(this, key) val nodes = ExternalSystemApiUtil.findAll(this, key)
return nodes.mapNotNull { return nodes.mapNotNull {
val data = it.getData(key) ?: return@mapNotNull null val data = it.getData(key) ?: return@mapNotNull null
@@ -100,7 +101,7 @@ fun <T: Any> DataNode<*>.findAll(key: Key<T>): List<NodeWithData<T>> {
} }
fun findGradleProjectStructure(file: PsiFile) = fun findGradleProjectStructure(file: PsiFile) =
ModuleUtilCore.findModuleForFile(file.virtualFile, file.project)?.let { findGradleProjectStructure(it) } ModuleUtilCore.findModuleForFile(file.virtualFile, file.project)?.let { findGradleProjectStructure(it) }
fun findGradleProjectStructure(module: Module): DataNode<ProjectData>? { fun findGradleProjectStructure(module: Module): DataNode<ProjectData>? {
val externalProjectPath = ExternalSystemApiUtil.getExternalProjectPath(module) ?: return null val externalProjectPath = ExternalSystemApiUtil.getExternalProjectPath(module) ?: return null
@@ -49,7 +49,8 @@ class DefaultGradleModelFacade : KotlinGradleModelFacade {
override fun getDependencyModules(ideModule: DataNode<ModuleData>, gradleIdeaProject: IdeaProject): Collection<DataNode<ModuleData>> { override fun getDependencyModules(ideModule: DataNode<ModuleData>, gradleIdeaProject: IdeaProject): Collection<DataNode<ModuleData>> {
val ideProject = ideModule.parent as DataNode<ProjectData> val ideProject = ideModule.parent as DataNode<ProjectData>
val dependencyModuleNames = ExternalSystemApiUtil.getChildren(ideModule, ProjectKeys.MODULE_DEPENDENCY).map { it.data.target.externalName }.toHashSet() val dependencyModuleNames =
ExternalSystemApiUtil.getChildren(ideModule, ProjectKeys.MODULE_DEPENDENCY).map { it.data.target.externalName }.toHashSet()
return findModulesByNames(dependencyModuleNames, gradleIdeaProject, ideProject) return findModulesByNames(dependencyModuleNames, gradleIdeaProject, ideProject)
} }
} }
@@ -64,7 +65,11 @@ fun getDependencyModules(moduleData: DataNode<ModuleData>, gradleIdeaProject: Id
return emptyList() return emptyList()
} }
fun findModulesByNames(dependencyModuleNames: Set<String>, gradleIdeaProject: IdeaProject, ideProject: DataNode<ProjectData>): LinkedHashSet<DataNode<ModuleData>> { fun findModulesByNames(
dependencyModuleNames: Set<String>,
gradleIdeaProject: IdeaProject,
ideProject: DataNode<ProjectData>
): LinkedHashSet<DataNode<ModuleData>> {
val modules = ExternalSystemApiUtil.getChildren(ideProject, ProjectKeys.MODULE) val modules = ExternalSystemApiUtil.getChildren(ideProject, ProjectKeys.MODULE)
return modules.filterTo(LinkedHashSet()) { it.data.externalName in dependencyModuleNames } return modules.filterTo(LinkedHashSet()) { it.data.externalName in dependencyModuleNames }
} }
@@ -31,9 +31,11 @@ import org.jetbrains.plugins.gradle.util.GradleConstants
class KotlinTestClassGradleConfigurationProducer : TestClassGradleConfigurationProducer() { class KotlinTestClassGradleConfigurationProducer : TestClassGradleConfigurationProducer() {
override fun doSetupConfigurationFromContext(configuration: ExternalSystemRunConfiguration, override fun doSetupConfigurationFromContext(
context: ConfigurationContext, configuration: ExternalSystemRunConfiguration,
sourceElement: Ref<PsiElement>): Boolean { context: ConfigurationContext,
sourceElement: Ref<PsiElement>
): Boolean {
val contextLocation = context.location ?: return false val contextLocation = context.location ?: return false
val module = context.module ?: return false val module = context.module ?: return false
@@ -93,9 +95,11 @@ class KotlinTestClassGradleConfigurationProducer : TestClassGradleConfigurationP
class KotlinTestMethodGradleConfigurationProducer class KotlinTestMethodGradleConfigurationProducer
: TestMethodGradleConfigurationProducer() { : TestMethodGradleConfigurationProducer() {
override fun doSetupConfigurationFromContext(configuration: ExternalSystemRunConfiguration, override fun doSetupConfigurationFromContext(
context: ConfigurationContext, configuration: ExternalSystemRunConfiguration,
sourceElement: Ref<PsiElement>): Boolean { context: ConfigurationContext,
sourceElement: Ref<PsiElement>
): Boolean {
val contextLocation = context.location ?: return false val contextLocation = context.location ?: return false
if (context.module == null) return false if (context.module == null) return false
@@ -142,10 +146,12 @@ class KotlinTestMethodGradleConfigurationProducer
return scriptParameters.contains(testFilter!!) return scriptParameters.contains(testFilter!!)
} }
private fun applyTestMethodConfiguration(configuration: ExternalSystemRunConfiguration, private fun applyTestMethodConfiguration(
context: ConfigurationContext, configuration: ExternalSystemRunConfiguration,
psiMethod: PsiMethod, context: ConfigurationContext,
vararg containingClasses: PsiClass): Boolean { psiMethod: PsiMethod,
vararg containingClasses: PsiClass
): Boolean {
val module = context.module ?: return false val module = context.module ?: return false
if (!ExternalSystemApiUtil.isExternalSystemAwareModule(GradleConstants.SYSTEM_ID, module)) return false if (!ExternalSystemApiUtil.isExternalSystemAwareModule(GradleConstants.SYSTEM_ID, module)) return false
@@ -48,24 +48,23 @@ import kotlin.concurrent.getOrSet
class MultiplatformGradleProjectTaskRunner : GradleProjectTaskRunner() { class MultiplatformGradleProjectTaskRunner : GradleProjectTaskRunner() {
override fun canRun(projectTask: ProjectTask) = override fun canRun(projectTask: ProjectTask) =
when (projectTask) { when (projectTask) {
is ModuleBuildTask -> is ModuleBuildTask ->
projectTask.module.isMultiplatformModule() projectTask.module.isMultiplatformModule()
is ExecuteRunConfigurationTask -> { is ExecuteRunConfigurationTask -> {
val runProfile = projectTask.runProfile val runProfile = projectTask.runProfile
if (runProfile is ModuleBasedConfiguration<*>) { if (runProfile is ModuleBasedConfiguration<*>) {
runProfile.configurationModule.module?.isMultiplatformModule() == true runProfile.configurationModule.module?.isMultiplatformModule() == true
} } else {
else { false
false
}
} }
else -> false
} }
else -> false
}
override fun run( override fun run(
project: Project, project: Project,
context: ProjectTaskContext, context: ProjectTaskContext,
@@ -74,7 +73,8 @@ class MultiplatformGradleProjectTaskRunner : GradleProjectTaskRunner() {
) { ) {
val configuration = context.runConfiguration val configuration = context.runConfiguration
if (configuration is ModuleBasedConfiguration<*> && if (configuration is ModuleBasedConfiguration<*> &&
(configuration.configurationModule is JavaRunConfigurationModule || configuration is KotlinRunConfiguration)) { (configuration.configurationModule is JavaRunConfigurationModule || configuration is KotlinRunConfiguration)
) {
val module = configuration.configurationModule.module val module = configuration.configurationModule.module
if (module?.targetPlatform == TargetPlatformKind.Common) { if (module?.targetPlatform == TargetPlatformKind.Common) {
@@ -91,21 +91,28 @@ class MultiplatformGradleProjectTaskRunner : GradleProjectTaskRunner() {
} }
private fun ProjectTask.replaceModule(origin: Module, replacement: Module): ProjectTask = private fun ProjectTask.replaceModule(origin: Module, replacement: Module): ProjectTask =
when (this) { when (this) {
is ModuleFilesBuildTask -> this is ModuleFilesBuildTask -> this
is ModuleBuildTask -> is ModuleBuildTask ->
if (module == origin) if (module == origin)
ModuleBuildTaskImpl(replacement, isIncrementalBuild, isIncludeDependentModules, isIncludeRuntimeDependencies) ModuleBuildTaskImpl(replacement, isIncrementalBuild, isIncludeDependentModules, isIncludeRuntimeDependencies)
else else
this this
else -> this else -> this
} }
} }
class MultiplatformGradleOrderEnumeratorHandler(val factory: MultiplatformGradleOrderEnumeratorHandler.FactoryImpl) : OrderEnumerationHandler() { class MultiplatformGradleOrderEnumeratorHandler(val factory: MultiplatformGradleOrderEnumeratorHandler.FactoryImpl) :
override fun addCustomModuleRoots(type: OrderRootType, rootModel: ModuleRootModel, result: MutableCollection<String>, includeProduction: Boolean, includeTests: Boolean): Boolean { OrderEnumerationHandler() {
override fun addCustomModuleRoots(
type: OrderRootType,
rootModel: ModuleRootModel,
result: MutableCollection<String>,
includeProduction: Boolean,
includeTests: Boolean
): Boolean {
if (factory.isEnumerating(rootModel.module)) return false if (factory.isEnumerating(rootModel.module)) return false
factory.startEnumerating(rootModel.module) factory.startEnumerating(rootModel.module)
try { try {
@@ -113,10 +120,13 @@ class MultiplatformGradleOrderEnumeratorHandler(val factory: MultiplatformGradle
if (!ExternalSystemApiUtil.isExternalSystemAwareModule(GradleConstants.SYSTEM_ID, rootModel.module)) return false if (!ExternalSystemApiUtil.isExternalSystemAwareModule(GradleConstants.SYSTEM_ID, rootModel.module)) return false
if (!GradleSystemRunningSettings.getInstance().isUseGradleAwareMake) { if (!GradleSystemRunningSettings.getInstance().isUseGradleAwareMake) {
val gradleProjectPath = ExternalSystemModulePropertyManager.getInstance(rootModel.module).getRootProjectPath() ?: return false val gradleProjectPath =
ExternalSystemModulePropertyManager.getInstance(rootModel.module).getRootProjectPath() ?: return false
val externalProjectDataCache = ExternalProjectDataCache.getInstance(rootModel.module.project)!! val externalProjectDataCache = ExternalProjectDataCache.getInstance(rootModel.module.project)!!
val externalRootProject = externalProjectDataCache.getRootExternalProject(GradleConstants.SYSTEM_ID, val externalRootProject = externalProjectDataCache.getRootExternalProject(
File(gradleProjectPath)) ?: return false GradleConstants.SYSTEM_ID,
File(gradleProjectPath)
) ?: return false
val externalSourceSets = externalProjectDataCache.findExternalProject(externalRootProject, rootModel.module) val externalSourceSets = externalProjectDataCache.findExternalProject(externalRootProject, rootModel.module)
@@ -132,12 +142,12 @@ class MultiplatformGradleOrderEnumeratorHandler(val factory: MultiplatformGradle
val implModule = rootModel.module.findJvmImplementationModule() val implModule = rootModel.module.findJvmImplementationModule()
implModule implModule
?.rootManager ?.rootManager
?.orderEntries() ?.orderEntries()
?.satisfying { orderEntry -> (orderEntry as? ModuleOrderEntry)?.module != rootModel.module } ?.satisfying { orderEntry -> (orderEntry as? ModuleOrderEntry)?.module != rootModel.module }
?.compileOnly() ?.compileOnly()
?.classesRoots ?.classesRoots
?.mapTo(result) { it.url } ?.mapTo(result) { it.url }
} finally { } finally {
factory.doneEnumerating(rootModel.module) factory.doneEnumerating(rootModel.module)
@@ -164,8 +174,8 @@ class MultiplatformGradleOrderEnumeratorHandler(val factory: MultiplatformGradle
override fun isApplicable(module: Module): Boolean { override fun isApplicable(module: Module): Boolean {
return ExternalSystemApiUtil.isExternalSystemAwareModule(GradleConstants.SYSTEM_ID, module) && return ExternalSystemApiUtil.isExternalSystemAwareModule(GradleConstants.SYSTEM_ID, module) &&
module.isMultiplatformModule() && module.isMultiplatformModule() &&
!isEnumerating(module) !isEnumerating(module)
} }
override fun createHandler(module: Module): OrderEnumerationHandler = override fun createHandler(module: Module): OrderEnumerationHandler =
@@ -31,7 +31,8 @@ class MultiplatformProjectImportingTest : GradleImportingTestCase() {
val kotlinVersion = "1.1.0" val kotlinVersion = "1.1.0"
createProjectSubFile("build.gradle", """ createProjectSubFile(
"build.gradle", """
buildscript { buildscript {
repositories { repositories {
mavenCentral() mavenCentral()
@@ -61,7 +62,8 @@ class MultiplatformProjectImportingTest : GradleImportingTestCase() {
implement project(':common') implement project(':common')
} }
} }
""") """
)
importProject() importProject()
assertModuleModuleDepScope("jvm_main", "common_main", DependencyScope.COMPILE) assertModuleModuleDepScope("jvm_main", "common_main", DependencyScope.COMPILE)
@@ -76,7 +78,8 @@ class MultiplatformProjectImportingTest : GradleImportingTestCase() {
val kotlinVersion = "1.2.40-dev-610" val kotlinVersion = "1.2.40-dev-610"
createProjectSubFile("build.gradle", """ createProjectSubFile(
"build.gradle", """
buildscript { buildscript {
repositories { repositories {
mavenCentral() mavenCentral()
@@ -112,7 +115,8 @@ class MultiplatformProjectImportingTest : GradleImportingTestCase() {
expectedBy project(':common1') expectedBy project(':common1')
} }
} }
""") """
)
importProject() importProject()
assertModuleModuleDepScope("jvm_main", "common1_main", DependencyScope.COMPILE) assertModuleModuleDepScope("jvm_main", "common1_main", DependencyScope.COMPILE)
@@ -131,7 +135,8 @@ class MultiplatformProjectImportingTest : GradleImportingTestCase() {
val kotlinVersion = "1.2.0-beta-74" val kotlinVersion = "1.2.0-beta-74"
createProjectSubFile("toInclude/build.gradle", """ createProjectSubFile(
"toInclude/build.gradle", """
buildscript { buildscript {
repositories { repositories {
mavenCentral() mavenCentral()
@@ -162,10 +167,12 @@ class MultiplatformProjectImportingTest : GradleImportingTestCase() {
expectedBy project(':common') expectedBy project(':common')
} }
} }
""") """
)
createProjectSubFile("settings.gradle", "includeBuild('toInclude')") createProjectSubFile("settings.gradle", "includeBuild('toInclude')")
createProjectSubFile("build.gradle", """ createProjectSubFile(
"build.gradle", """
buildscript { buildscript {
repositories { repositories {
mavenCentral() mavenCentral()
@@ -178,7 +185,8 @@ class MultiplatformProjectImportingTest : GradleImportingTestCase() {
} }
apply plugin: 'kotlin' apply plugin: 'kotlin'
""".trimIndent()) """.trimIndent()
)
importProject() importProject()
assertModuleModuleDepScope("jvm_main", "common_main", DependencyScope.COMPILE) assertModuleModuleDepScope("jvm_main", "common_main", DependencyScope.COMPILE)
@@ -193,7 +201,8 @@ class MultiplatformProjectImportingTest : GradleImportingTestCase() {
val kotlinVersion = "1.1.0" val kotlinVersion = "1.1.0"
createProjectSubFile("build.gradle", """ createProjectSubFile(
"build.gradle", """
buildscript { buildscript {
repositories { repositories {
mavenCentral() mavenCentral()
@@ -221,7 +230,8 @@ class MultiplatformProjectImportingTest : GradleImportingTestCase() {
implement project(':') implement project(':')
} }
} }
""") """
)
importProject() importProject()
assertModuleModuleDepScope("jvm_main", "foo_main", DependencyScope.COMPILE) assertModuleModuleDepScope("jvm_main", "foo_main", DependencyScope.COMPILE)
@@ -236,7 +246,8 @@ class MultiplatformProjectImportingTest : GradleImportingTestCase() {
val kotlinVersion = "1.1.0" val kotlinVersion = "1.1.0"
createProjectSubFile("build.gradle", """ createProjectSubFile(
"build.gradle", """
buildscript { buildscript {
repositories { repositories {
mavenCentral() mavenCentral()
@@ -292,7 +303,8 @@ class MultiplatformProjectImportingTest : GradleImportingTestCase() {
compile project(':js-lib') compile project(':js-lib')
} }
} }
""") """
)
importProject() importProject()
@@ -308,13 +320,14 @@ class MultiplatformProjectImportingTest : GradleImportingTestCase() {
@Test @Test
fun testDependenciesReachableViaImpl() { fun testDependenciesReachableViaImpl() {
createProjectSubFile( createProjectSubFile(
"settings.gradle", "settings.gradle",
"include ':common-lib1', ':common-lib2', ':jvm-lib1', ':jvm-lib2', ':jvm-app'" "include ':common-lib1', ':common-lib2', ':jvm-lib1', ':jvm-lib2', ':jvm-app'"
) )
val kotlinVersion = "1.1.0" val kotlinVersion = "1.1.0"
createProjectSubFile("build.gradle", """ createProjectSubFile(
"build.gradle", """
buildscript { buildscript {
repositories { repositories {
mavenCentral() mavenCentral()
@@ -357,7 +370,8 @@ class MultiplatformProjectImportingTest : GradleImportingTestCase() {
compile project(':jvm-lib2') compile project(':jvm-lib2')
} }
} }
""") """
)
importProject() importProject()
@@ -375,13 +389,14 @@ class MultiplatformProjectImportingTest : GradleImportingTestCase() {
@Test @Test
fun testTransitiveImplement() { fun testTransitiveImplement() {
createProjectSubFile( createProjectSubFile(
"settings.gradle", "settings.gradle",
"include ':project1', ':project2', ':project3'" "include ':project1', ':project2', ':project3'"
) )
val kotlinVersion = "1.1.51" val kotlinVersion = "1.1.51"
createProjectSubFile("build.gradle", """ createProjectSubFile(
"build.gradle", """
buildscript { buildscript {
repositories { repositories {
mavenCentral() mavenCentral()
@@ -434,7 +449,8 @@ class MultiplatformProjectImportingTest : GradleImportingTestCase() {
testCompile(project(':project2').sourceSets.test.output) testCompile(project(':project2').sourceSets.test.output)
} }
} }
""") """
)
val isResolveModulePerSourceSet = getCurrentExternalProjectSettings().isResolveModulePerSourceSet val isResolveModulePerSourceSet = getCurrentExternalProjectSettings().isResolveModulePerSourceSet
@@ -478,13 +494,14 @@ class MultiplatformProjectImportingTest : GradleImportingTestCase() {
@Test @Test
fun testTransitiveImplementWithAndroid() { fun testTransitiveImplementWithAndroid() {
createProjectSubFile( createProjectSubFile(
"settings.gradle", "settings.gradle",
"include ':project1', ':project2', ':project3'" "include ':project1', ':project2', ':project3'"
) )
val kotlinVersion = "1.1.51" val kotlinVersion = "1.1.51"
createProjectSubFile("build.gradle", """ createProjectSubFile(
"build.gradle", """
buildscript { buildscript {
repositories { repositories {
jcenter() jcenter()
@@ -552,10 +569,13 @@ class MultiplatformProjectImportingTest : GradleImportingTestCase() {
testCompile(project(':project2').sourceSets.test.output) testCompile(project(':project2').sourceSets.test.output)
} }
} }
""") """
createProjectSubFile("local.properties", """ )
createProjectSubFile(
"local.properties", """
sdk.dir=/${KotlinTestUtils.getAndroidSdkSystemIndependentPath()} sdk.dir=/${KotlinTestUtils.getAndroidSdkSystemIndependentPath()}
""") """
)
importProject() importProject()
@@ -568,13 +588,14 @@ class MultiplatformProjectImportingTest : GradleImportingTestCase() {
@Test @Test
fun testJsTestOutputFile() { fun testJsTestOutputFile() {
createProjectSubFile( createProjectSubFile(
"settings.gradle", "settings.gradle",
"include ':project1', ':project2', ':project3'" "include ':project1', ':project2', ':project3'"
) )
val kotlinVersion = "1.1.51" val kotlinVersion = "1.1.51"
createProjectSubFile("build.gradle", """ createProjectSubFile(
"build.gradle", """
buildscript { buildscript {
repositories { repositories {
jcenter() jcenter()
@@ -602,30 +623,32 @@ class MultiplatformProjectImportingTest : GradleImportingTestCase() {
implement project(':project1') implement project(':project1')
} }
} }
""") """
)
importProject() importProject()
TestCase.assertEquals( TestCase.assertEquals(
projectPath + "/project2/build/classes/test/project2_test.js", projectPath + "/project2/build/classes/test/project2_test.js",
PathUtil.toSystemIndependentName(KotlinFacet.get (getModule("project2_main"))!!.configuration.settings.testOutputPath) PathUtil.toSystemIndependentName(KotlinFacet.get(getModule("project2_main"))!!.configuration.settings.testOutputPath)
) )
TestCase.assertEquals( TestCase.assertEquals(
projectPath + "/project2/build/classes/test/project2_test.js", projectPath + "/project2/build/classes/test/project2_test.js",
PathUtil.toSystemIndependentName(KotlinFacet.get (getModule("project2_test"))!!.configuration.settings.testOutputPath) PathUtil.toSystemIndependentName(KotlinFacet.get(getModule("project2_test"))!!.configuration.settings.testOutputPath)
) )
} }
@Test @Test
fun testJsProductionOutputFile() { fun testJsProductionOutputFile() {
createProjectSubFile( createProjectSubFile(
"settings.gradle", "settings.gradle",
"include ':project1', ':project2', ':project3'" "include ':project1', ':project2', ':project3'"
) )
val kotlinVersion = "1.1.51" val kotlinVersion = "1.1.51"
createProjectSubFile("build.gradle", """ createProjectSubFile(
"build.gradle", """
buildscript { buildscript {
repositories { repositories {
jcenter() jcenter()
@@ -653,30 +676,32 @@ class MultiplatformProjectImportingTest : GradleImportingTestCase() {
implement project(':project1') implement project(':project1')
} }
} }
""") """
)
importProject() importProject()
TestCase.assertEquals( TestCase.assertEquals(
projectPath + "/project2/build/classes/main/project2.js", projectPath + "/project2/build/classes/main/project2.js",
PathUtil.toSystemIndependentName(KotlinFacet.get (getModule("project2_main"))!!.configuration.settings.productionOutputPath) PathUtil.toSystemIndependentName(KotlinFacet.get(getModule("project2_main"))!!.configuration.settings.productionOutputPath)
) )
TestCase.assertEquals( TestCase.assertEquals(
projectPath + "/project2/build/classes/main/project2.js", projectPath + "/project2/build/classes/main/project2.js",
PathUtil.toSystemIndependentName(KotlinFacet.get (getModule("project2_test"))!!.configuration.settings.productionOutputPath) PathUtil.toSystemIndependentName(KotlinFacet.get(getModule("project2_test"))!!.configuration.settings.productionOutputPath)
) )
} }
@Test @Test
fun testJsTestOutputFileInProjectWithAndroid() { fun testJsTestOutputFileInProjectWithAndroid() {
createProjectSubFile( createProjectSubFile(
"settings.gradle", "settings.gradle",
"include ':project1', ':project2', ':project3'" "include ':project1', ':project2', ':project3'"
) )
val kotlinVersion = "1.1.51" val kotlinVersion = "1.1.51"
createProjectSubFile("build.gradle", """ createProjectSubFile(
"build.gradle", """
buildscript { buildscript {
repositories { repositories {
jcenter() jcenter()
@@ -730,16 +755,19 @@ class MultiplatformProjectImportingTest : GradleImportingTestCase() {
} }
} }
} }
""") """
createProjectSubFile("local.properties", """ )
createProjectSubFile(
"local.properties", """
sdk.dir=/${KotlinTestUtils.getAndroidSdkSystemIndependentPath()} sdk.dir=/${KotlinTestUtils.getAndroidSdkSystemIndependentPath()}
""") """
)
importProject() importProject()
TestCase.assertEquals( TestCase.assertEquals(
projectPath + "/project2/build/classes/test/project2_test.js", projectPath + "/project2/build/classes/test/project2_test.js",
PathUtil.toSystemIndependentName(KotlinFacet.get (getModule("project2"))!!.configuration.settings.testOutputPath) PathUtil.toSystemIndependentName(KotlinFacet.get(getModule("project2"))!!.configuration.settings.testOutputPath)
) )
} }
} }
@@ -60,196 +60,202 @@ import static org.junit.Assume.assumeThat;
@RunWith(value = Parameterized.class) @RunWith(value = Parameterized.class)
public abstract class AbstractModelBuilderTest { public abstract class AbstractModelBuilderTest {
public static final Object[][] SUPPORTED_GRADLE_VERSIONS = { {"3.5"} }; public static final Object[][] SUPPORTED_GRADLE_VERSIONS = {{"3.5"}};
private static final Pattern TEST_METHOD_NAME_PATTERN = Pattern.compile("(.*)\\[(\\d*: with Gradle-.*)\\]"); private static final Pattern TEST_METHOD_NAME_PATTERN = Pattern.compile("(.*)\\[(\\d*: with Gradle-.*)\\]");
private static File ourTempDir; private static File ourTempDir;
@NotNull @NotNull
private final String gradleVersion; private final String gradleVersion;
private File testDir; private File testDir;
private ProjectImportAction.AllModels allModels; private ProjectImportAction.AllModels allModels;
@Rule public TestName name = new TestName(); @Rule public TestName name = new TestName();
@Rule public VersionMatcherRule versionMatcherRule = new VersionMatcherRule(); @Rule public VersionMatcherRule versionMatcherRule = new VersionMatcherRule();
public AbstractModelBuilderTest(@NotNull String gradleVersion) { public AbstractModelBuilderTest(@NotNull String gradleVersion) {
this.gradleVersion = gradleVersion; this.gradleVersion = gradleVersion;
}
@Parameterized.Parameters(name = "{index}: with Gradle-{0}")
public static Collection<Object[]> data() {
return Arrays.asList(SUPPORTED_GRADLE_VERSIONS);
}
@Before
public void setUp() throws Exception {
assumeThat(gradleVersion, versionMatcherRule.getMatcher());
ensureTempDirCreated();
String methodName = name.getMethodName();
Matcher m = TEST_METHOD_NAME_PATTERN.matcher(methodName);
if (m.matches()) {
methodName = m.group(1);
} }
testDir = new File(ourTempDir, methodName); @Parameterized.Parameters(name = "{index}: with Gradle-{0}")
FileUtil.ensureExists(testDir); public static Collection<Object[]> data() {
return Arrays.asList(SUPPORTED_GRADLE_VERSIONS);
InputStream buildScriptStream = getClass().getResourceAsStream("/" + methodName + "/" + GradleConstants.DEFAULT_SCRIPT_NAME);
try {
FileUtil.writeToFile(
new File(testDir, GradleConstants.DEFAULT_SCRIPT_NAME),
FileUtil.loadTextAndClose(buildScriptStream)
);
}
finally {
StreamUtil.closeStream(buildScriptStream);
} }
InputStream settingsStream = getClass().getResourceAsStream("/" + methodName + "/" + GradleConstants.SETTINGS_FILE_NAME);
try { @Before
if(settingsStream != null) { public void setUp() throws Exception {
FileUtil.writeToFile( assumeThat(gradleVersion, versionMatcherRule.getMatcher());
new File(testDir, GradleConstants.SETTINGS_FILE_NAME),
FileUtil.loadTextAndClose(settingsStream) ensureTempDirCreated();
String methodName = name.getMethodName();
Matcher m = TEST_METHOD_NAME_PATTERN.matcher(methodName);
if (m.matches()) {
methodName = m.group(1);
}
testDir = new File(ourTempDir, methodName);
FileUtil.ensureExists(testDir);
InputStream buildScriptStream = getClass().getResourceAsStream("/" + methodName + "/" + GradleConstants.DEFAULT_SCRIPT_NAME);
try {
FileUtil.writeToFile(
new File(testDir, GradleConstants.DEFAULT_SCRIPT_NAME),
FileUtil.loadTextAndClose(buildScriptStream)
);
}
finally {
StreamUtil.closeStream(buildScriptStream);
}
InputStream settingsStream = getClass().getResourceAsStream("/" + methodName + "/" + GradleConstants.SETTINGS_FILE_NAME);
try {
if (settingsStream != null) {
FileUtil.writeToFile(
new File(testDir, GradleConstants.SETTINGS_FILE_NAME),
FileUtil.loadTextAndClose(settingsStream)
);
}
}
finally {
StreamUtil.closeStream(settingsStream);
}
GradleConnector connector = GradleConnector.newConnector();
URI distributionUri = new DistributionLocator().getDistributionFor(GradleVersion.version(gradleVersion));
connector.useDistribution(distributionUri);
connector.forProjectDirectory(testDir);
int daemonMaxIdleTime = 10;
try {
daemonMaxIdleTime = Integer.parseInt(System.getProperty("gradleDaemonMaxIdleTime", "10"));
}
catch (NumberFormatException ignore) {
}
((DefaultGradleConnector) connector).daemonMaxIdleTime(daemonMaxIdleTime, TimeUnit.SECONDS);
ProjectConnection connection = connector.connect();
try {
ProjectImportAction projectImportAction = new ProjectImportAction(false);
projectImportAction.addExtraProjectModelClasses(getModels());
BuildActionExecuter<ProjectImportAction.AllModels> buildActionExecutor = connection.action(projectImportAction);
File initScript = GradleExecutionHelper.generateInitScript(false, getToolingExtensionClasses());
assertNotNull(initScript);
String jdkHome = IdeaTestUtil.requireRealJdkHome();
buildActionExecutor.setJavaHome(new File(jdkHome));
buildActionExecutor.setJvmArguments("-Xmx128m", "-XX:MaxPermSize=64m");
buildActionExecutor
.withArguments("--info", "--recompile-scripts", GradleConstants.INIT_SCRIPT_CMD_OPTION, initScript.getAbsolutePath());
allModels = buildActionExecutor.run();
assertNotNull(allModels);
}
finally {
connection.close();
}
}
@NotNull
private static Set<Class> getToolingExtensionClasses() {
Set<Class> classes = ContainerUtil.<Class>set(
ExternalProject.class,
// gradle-tooling-extension-api jar
ProjectImportAction.class,
// gradle-tooling-extension-impl jar
ModelBuildScriptClasspathBuilderImpl.class,
Multimap.class,
ShortTypeHandling.class
); );
}
} finally {
StreamUtil.closeStream(settingsStream);
}
GradleConnector connector = GradleConnector.newConnector(); ContainerUtil.addAllNotNull(classes, doGetToolingExtensionClasses());
return classes;
URI distributionUri = new DistributionLocator().getDistributionFor(GradleVersion.version(gradleVersion));
connector.useDistribution(distributionUri);
connector.forProjectDirectory(testDir);
int daemonMaxIdleTime = 10;
try {
daemonMaxIdleTime = Integer.parseInt(System.getProperty("gradleDaemonMaxIdleTime", "10"));
}
catch (NumberFormatException ignore) {}
((DefaultGradleConnector)connector).daemonMaxIdleTime(daemonMaxIdleTime, TimeUnit.SECONDS);
ProjectConnection connection = connector.connect();
try {
ProjectImportAction projectImportAction = new ProjectImportAction(false);
projectImportAction.addExtraProjectModelClasses(getModels());
BuildActionExecuter<ProjectImportAction.AllModels> buildActionExecutor = connection.action(projectImportAction);
File initScript = GradleExecutionHelper.generateInitScript(false, getToolingExtensionClasses());
assertNotNull(initScript);
String jdkHome = IdeaTestUtil.requireRealJdkHome();
buildActionExecutor.setJavaHome(new File(jdkHome));
buildActionExecutor.setJvmArguments("-Xmx128m", "-XX:MaxPermSize=64m");
buildActionExecutor.withArguments("--info", "--recompile-scripts", GradleConstants.INIT_SCRIPT_CMD_OPTION, initScript.getAbsolutePath());
allModels = buildActionExecutor.run();
assertNotNull(allModels);
} finally {
connection.close();
}
}
@NotNull
private static Set<Class> getToolingExtensionClasses() {
Set<Class> classes = ContainerUtil.<Class>set(
ExternalProject.class,
// gradle-tooling-extension-api jar
ProjectImportAction.class,
// gradle-tooling-extension-impl jar
ModelBuildScriptClasspathBuilderImpl.class,
Multimap.class,
ShortTypeHandling.class
);
ContainerUtil.addAllNotNull(classes, doGetToolingExtensionClasses());
return classes;
}
@NotNull
private static Set<Class> doGetToolingExtensionClasses() {
return Collections.emptySet();
}
@After
public void tearDown() throws Exception {
if (testDir != null) {
FileUtil.delete(testDir);
}
}
protected abstract Set<Class> getModels();
private <T> Map<String, T> getModulesMap(final Class<T> aClass) {
DomainObjectSet<? extends IdeaModule> ideaModules = allModels.getIdeaProject().getModules();
final String filterKey = "to_filter";
Map<String, T> map = ContainerUtil.map2Map(ideaModules, new Function<IdeaModule, Pair<String, T>>() {
@Override
public Pair<String, T> fun(IdeaModule module) {
T value = allModels.getExtraProject(module, aClass);
String key = value != null ? module.getGradleProject().getPath() : filterKey;
return Pair.create(key, value);
}
});
map.remove(filterKey);
return map;
}
private static void ensureTempDirCreated() throws IOException {
if (ourTempDir != null) return;
ourTempDir = new File(FileUtil.getTempDirectory(), "gradleTests");
FileUtil.delete(ourTempDir);
FileUtil.ensureExists(ourTempDir);
}
public static class DistributionLocator {
private static final String RELEASE_REPOSITORY_ENV = "GRADLE_RELEASE_REPOSITORY";
private static final String SNAPSHOT_REPOSITORY_ENV = "GRADLE_SNAPSHOT_REPOSITORY";
private static final String GRADLE_RELEASE_REPO = "http://services.gradle.org/distributions";
private static final String GRADLE_SNAPSHOT_REPO = "http://services.gradle.org/distributions-snapshots";
@NotNull private final String myReleaseRepoUrl;
@NotNull private final String mySnapshotRepoUrl;
public DistributionLocator() {
this(DistributionLocator.getRepoUrl(false), DistributionLocator.getRepoUrl(true));
}
public DistributionLocator(@NotNull String releaseRepoUrl, @NotNull String snapshotRepoUrl) {
myReleaseRepoUrl = releaseRepoUrl;
mySnapshotRepoUrl = snapshotRepoUrl;
} }
@NotNull @NotNull
public URI getDistributionFor(@NotNull GradleVersion version) throws URISyntaxException { private static Set<Class> doGetToolingExtensionClasses() {
return getDistribution(getDistributionRepository(version), version, "gradle", "bin"); return Collections.emptySet();
} }
@NotNull @After
private String getDistributionRepository(@NotNull GradleVersion version) { public void tearDown() throws Exception {
return version.isSnapshot() ? mySnapshotRepoUrl : myReleaseRepoUrl; if (testDir != null) {
FileUtil.delete(testDir);
}
} }
private static URI getDistribution(@NotNull String repositoryUrl, protected abstract Set<Class> getModels();
@NotNull GradleVersion version,
@NotNull String archiveName,
@NotNull String archiveClassifier) throws URISyntaxException { private <T> Map<String, T> getModulesMap(final Class<T> aClass) {
return new URI(String.format("%s/%s-%s-%s.zip", repositoryUrl, archiveName, version.getVersion(), archiveClassifier)); DomainObjectSet<? extends IdeaModule> ideaModules = allModels.getIdeaProject().getModules();
final String filterKey = "to_filter";
Map<String, T> map = ContainerUtil.map2Map(ideaModules, new Function<IdeaModule, Pair<String, T>>() {
@Override
public Pair<String, T> fun(IdeaModule module) {
T value = allModels.getExtraProject(module, aClass);
String key = value != null ? module.getGradleProject().getPath() : filterKey;
return Pair.create(key, value);
}
});
map.remove(filterKey);
return map;
} }
@NotNull private static void ensureTempDirCreated() throws IOException {
public static String getRepoUrl(boolean isSnapshotUrl) { if (ourTempDir != null) return;
String envRepoUrl = System.getenv(isSnapshotUrl ? SNAPSHOT_REPOSITORY_ENV : RELEASE_REPOSITORY_ENV);
if (envRepoUrl != null) return envRepoUrl;
return isSnapshotUrl ? GRADLE_SNAPSHOT_REPO : GRADLE_RELEASE_REPO; ourTempDir = new File(FileUtil.getTempDirectory(), "gradleTests");
FileUtil.delete(ourTempDir);
FileUtil.ensureExists(ourTempDir);
}
public static class DistributionLocator {
private static final String RELEASE_REPOSITORY_ENV = "GRADLE_RELEASE_REPOSITORY";
private static final String SNAPSHOT_REPOSITORY_ENV = "GRADLE_SNAPSHOT_REPOSITORY";
private static final String GRADLE_RELEASE_REPO = "http://services.gradle.org/distributions";
private static final String GRADLE_SNAPSHOT_REPO = "http://services.gradle.org/distributions-snapshots";
@NotNull private final String myReleaseRepoUrl;
@NotNull private final String mySnapshotRepoUrl;
public DistributionLocator() {
this(DistributionLocator.getRepoUrl(false), DistributionLocator.getRepoUrl(true));
}
public DistributionLocator(@NotNull String releaseRepoUrl, @NotNull String snapshotRepoUrl) {
myReleaseRepoUrl = releaseRepoUrl;
mySnapshotRepoUrl = snapshotRepoUrl;
}
@NotNull
public URI getDistributionFor(@NotNull GradleVersion version) throws URISyntaxException {
return getDistribution(getDistributionRepository(version), version, "gradle", "bin");
}
@NotNull
private String getDistributionRepository(@NotNull GradleVersion version) {
return version.isSnapshot() ? mySnapshotRepoUrl : myReleaseRepoUrl;
}
private static URI getDistribution(
@NotNull String repositoryUrl,
@NotNull GradleVersion version,
@NotNull String archiveName,
@NotNull String archiveClassifier
) throws URISyntaxException {
return new URI(String.format("%s/%s-%s-%s.zip", repositoryUrl, archiveName, version.getVersion(), archiveClassifier));
}
@NotNull
public static String getRepoUrl(boolean isSnapshotUrl) {
String envRepoUrl = System.getenv(isSnapshotUrl ? SNAPSHOT_REPOSITORY_ENV : RELEASE_REPOSITORY_ENV);
if (envRepoUrl != null) return envRepoUrl;
return isSnapshotUrl ? GRADLE_SNAPSHOT_REPO : GRADLE_RELEASE_REPO;
}
} }
}
} }
@@ -49,127 +49,133 @@ import java.util.*;
// part of com.intellij.openapi.externalSystem.test.ExternalSystemImportingTestCase // part of com.intellij.openapi.externalSystem.test.ExternalSystemImportingTestCase
public abstract class ExternalSystemImportingTestCase extends ExternalSystemTestCase { public abstract class ExternalSystemImportingTestCase extends ExternalSystemTestCase {
@Override @Override
protected Module getModule(String name) { protected Module getModule(String name) {
AccessToken accessToken = ApplicationManager.getApplication().acquireReadActionLock(); AccessToken accessToken = ApplicationManager.getApplication().acquireReadActionLock();
try { try {
Module m = ModuleManager.getInstance(myProject).findModuleByName(name); Module m = ModuleManager.getInstance(myProject).findModuleByName(name);
assertNotNull("Module " + name + " not found", m); assertNotNull("Module " + name + " not found", m);
return m; return m;
}
finally {
accessToken.finish();
}
} }
finally {
accessToken.finish(); protected void importProject(@NonNls String config) throws IOException {
createProjectConfig(config);
importProject();
} }
}
protected void importProject(@NonNls String config) throws IOException { protected void importProject() {
createProjectConfig(config); doImportProject();
importProject(); }
}
protected void importProject() { private void doImportProject() {
doImportProject(); AbstractExternalSystemSettings systemSettings = ExternalSystemApiUtil.getSettings(myProject, getExternalSystemId());
} ExternalProjectSettings projectSettings = getCurrentExternalProjectSettings();
projectSettings.setExternalProjectPath(getProjectPath());
@SuppressWarnings("unchecked") Set<ExternalProjectSettings> projects =
ContainerUtilRt.newHashSet(systemSettings.getLinkedProjectsSettings());
projects.remove(projectSettings);
projects.add(projectSettings);
//noinspection unchecked
systemSettings.setLinkedProjectsSettings(projects);
private void doImportProject() { final Ref<Couple<String>> error = Ref.create();
AbstractExternalSystemSettings systemSettings = ExternalSystemApiUtil.getSettings(myProject, getExternalSystemId()); ExternalSystemUtil.refreshProjects(
ExternalProjectSettings projectSettings = getCurrentExternalProjectSettings(); new ImportSpecBuilder(myProject, getExternalSystemId())
projectSettings.setExternalProjectPath(getProjectPath()); .use(ProgressExecutionMode.MODAL_SYNC)
@SuppressWarnings("unchecked") Set<ExternalProjectSettings> projects = ContainerUtilRt.newHashSet(systemSettings.getLinkedProjectsSettings()); .callback(new ExternalProjectRefreshCallback() {
projects.remove(projectSettings); @Override
projects.add(projectSettings); public void onSuccess(@Nullable DataNode<ProjectData> externalProject) {
//noinspection unchecked if (externalProject == null) {
systemSettings.setLinkedProjectsSettings(projects); System.err.println("Got null External project after import");
return;
}
ServiceManager.getService(ProjectDataManager.class).importData(externalProject, myProject, true);
System.out.println("External project was successfully imported");
}
final Ref<Couple<String>> error = Ref.create(); @Override
ExternalSystemUtil.refreshProjects( public void onFailure(@NotNull String errorMessage, @Nullable String errorDetails) {
new ImportSpecBuilder(myProject, getExternalSystemId()) error.set(Couple.of(errorMessage, errorDetails));
.use(ProgressExecutionMode.MODAL_SYNC) }
.callback(new ExternalProjectRefreshCallback() { })
@Override .forceWhenUptodate()
public void onSuccess(@Nullable DataNode<ProjectData> externalProject) { );
if (externalProject == null) {
System.err.println("Got null External project after import"); if (!error.isNull()) {
return; String failureMsg = "Import failed: " + error.get().first;
if (StringUtil.isNotEmpty(error.get().second)) {
failureMsg += "\nError details: \n" + error.get().second;
} }
ServiceManager.getService(ProjectDataManager.class).importData(externalProject, myProject, true); fail(failureMsg);
System.out.println("External project was successfully imported"); }
}
@Override
public void onFailure(@NotNull String errorMessage, @Nullable String errorDetails) {
error.set(Couple.of(errorMessage, errorDetails));
}
})
.forceWhenUptodate()
);
if (!error.isNull()) {
String failureMsg = "Import failed: " + error.get().first;
if (StringUtil.isNotEmpty(error.get().second)) {
failureMsg += "\nError details: \n" + error.get().second;
}
fail(failureMsg);
}
}
protected abstract ExternalProjectSettings getCurrentExternalProjectSettings();
protected abstract ProjectSystemId getExternalSystemId();
protected void assertModuleModuleDepScope(String moduleName, String depName, DependencyScope... scopes) {
List<ModuleOrderEntry> deps = getModuleModuleDeps(moduleName, depName);
Set<DependencyScope> actualScopes = new HashSet<DependencyScope>();
for (ModuleOrderEntry dep : deps) {
actualScopes.add(dep.getScope());
}
HashSet<DependencyScope> expectedScopes = new HashSet<DependencyScope>(Arrays.asList(scopes));
assertEquals("Dependency '" + depName + "' for module '" + moduleName + "' has unexpected scope",
expectedScopes, actualScopes);
}
protected void assertNoDepForModule(String moduleName, String depName) {
assertEmpty("No dependency '" + depName + "' was expected", collectModuleDeps(moduleName, depName, ModuleOrderEntry.class));
}
@NotNull
private List<ModuleOrderEntry> getModuleModuleDeps(@NotNull String moduleName, @NotNull String depName) {
return getModuleDep(moduleName, depName, ModuleOrderEntry.class);
}
private ModuleRootManager getRootManager(String module) {
return ModuleRootManager.getInstance(getModule(module));
}
@NotNull
private <T> List<T> getModuleDep(@NotNull String moduleName, @NotNull String depName, @NotNull Class<T> clazz) {
List<T> deps = collectModuleDeps(moduleName, depName, clazz);
assertTrue("Dependency '" + depName + "' for module '" + moduleName + "' not found among: " + collectModuleDepsNames(moduleName, clazz),
!deps.isEmpty());
return deps;
}
@NotNull
private <T> List<T> collectModuleDeps(@NotNull String moduleName, @NotNull String depName, @NotNull Class<T> clazz) {
List<T> deps = ContainerUtil.newArrayList();
for (OrderEntry e : getRootManager(moduleName).getOrderEntries()) {
if (clazz.isInstance(e) && e.getPresentableName().equals(depName)) {
deps.add((T)e);
}
} }
return deps; protected abstract ExternalProjectSettings getCurrentExternalProjectSettings();
}
private List<String> collectModuleDepsNames(String moduleName, Class clazz) { protected abstract ProjectSystemId getExternalSystemId();
List<String> actual = new ArrayList<String>();
for (OrderEntry e : getRootManager(moduleName).getOrderEntries()) { protected void assertModuleModuleDepScope(String moduleName, String depName, DependencyScope... scopes) {
if (clazz.isInstance(e)) { List<ModuleOrderEntry> deps = getModuleModuleDeps(moduleName, depName);
actual.add(e.getPresentableName()); Set<DependencyScope> actualScopes = new HashSet<DependencyScope>();
} for (ModuleOrderEntry dep : deps) {
actualScopes.add(dep.getScope());
}
HashSet<DependencyScope> expectedScopes = new HashSet<DependencyScope>(Arrays.asList(scopes));
assertEquals("Dependency '" + depName + "' for module '" + moduleName + "' has unexpected scope",
expectedScopes, actualScopes);
}
protected void assertNoDepForModule(String moduleName, String depName) {
assertEmpty("No dependency '" + depName + "' was expected", collectModuleDeps(moduleName, depName, ModuleOrderEntry.class));
}
@NotNull
private List<ModuleOrderEntry> getModuleModuleDeps(@NotNull String moduleName, @NotNull String depName) {
return getModuleDep(moduleName, depName, ModuleOrderEntry.class);
}
private ModuleRootManager getRootManager(String module) {
return ModuleRootManager.getInstance(getModule(module));
}
@NotNull
private <T> List<T> getModuleDep(@NotNull String moduleName, @NotNull String depName, @NotNull Class<T> clazz) {
List<T> deps = collectModuleDeps(moduleName, depName, clazz);
assertTrue("Dependency '" +
depName +
"' for module '" +
moduleName +
"' not found among: " +
collectModuleDepsNames(moduleName, clazz),
!deps.isEmpty());
return deps;
}
@NotNull
private <T> List<T> collectModuleDeps(@NotNull String moduleName, @NotNull String depName, @NotNull Class<T> clazz) {
List<T> deps = ContainerUtil.newArrayList();
for (OrderEntry e : getRootManager(moduleName).getOrderEntries()) {
if (clazz.isInstance(e) && e.getPresentableName().equals(depName)) {
deps.add((T) e);
}
}
return deps;
}
private List<String> collectModuleDepsNames(String moduleName, Class clazz) {
List<String> actual = new ArrayList<String>();
for (OrderEntry e : getRootManager(moduleName).getOrderEntries()) {
if (clazz.isInstance(e)) {
actual.add(e.getPresentableName());
}
}
return actual;
} }
return actual;
}
} }
@@ -55,261 +55,261 @@ import static org.jetbrains.kotlin.test.testFramework.EdtTestUtil.runInEdtAndWai
// part of com.intellij.openapi.externalSystem.test.ExternalSystemTestCase // part of com.intellij.openapi.externalSystem.test.ExternalSystemTestCase
public abstract class ExternalSystemTestCase extends UsefulTestCase { public abstract class ExternalSystemTestCase extends UsefulTestCase {
private File ourTempDir; private File ourTempDir;
protected IdeaProjectTestFixture myTestFixture; protected IdeaProjectTestFixture myTestFixture;
protected Project myProject; protected Project myProject;
private File myTestDir; private File myTestDir;
private VirtualFile myProjectRoot; private VirtualFile myProjectRoot;
private final List<VirtualFile> myAllConfigs = new ArrayList<VirtualFile>(); private final List<VirtualFile> myAllConfigs = new ArrayList<VirtualFile>();
@Before @Before
@Override @Override
public void setUp() throws Exception { public void setUp() throws Exception {
super.setUp(); super.setUp();
ensureTempDirCreated(); ensureTempDirCreated();
myTestDir = new File(ourTempDir, getTestName(false)); myTestDir = new File(ourTempDir, getTestName(false));
FileUtil.ensureExists(myTestDir); FileUtil.ensureExists(myTestDir);
setUpFixtures(); setUpFixtures();
myProject = myTestFixture.getProject(); myProject = myTestFixture.getProject();
invokeTestRunnable(new Runnable() { invokeTestRunnable(new Runnable() {
@Override @Override
public void run() { public void run() {
ApplicationManager.getApplication().runWriteAction(new Runnable() { ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override @Override
public void run() { public void run() {
try { try {
setUpInWriteAction(); setUpInWriteAction();
}
catch (Throwable e) {
try {
tearDown();
}
catch (Exception e1) {
e1.printStackTrace();
}
throw new RuntimeException(e);
}
}
});
} }
catch (Throwable e) {
try {
tearDown();
}
catch (Exception e1) {
e1.printStackTrace();
}
throw new RuntimeException(e);
}
}
}); });
}
});
List<String> allowedRoots = new ArrayList<String>(); List<String> allowedRoots = new ArrayList<String>();
collectAllowedRoots(allowedRoots); collectAllowedRoots(allowedRoots);
if (!allowedRoots.isEmpty()) { if (!allowedRoots.isEmpty()) {
VfsRootAccess.allowRootAccess(getTestRootDisposable(), ArrayUtil.toStringArray(allowedRoots)); VfsRootAccess.allowRootAccess(getTestRootDisposable(), ArrayUtil.toStringArray(allowedRoots));
}
CompilerTestUtil.enableExternalCompiler();
} }
CompilerTestUtil.enableExternalCompiler(); protected void collectAllowedRoots(List<String> roots) throws IOException {
} }
protected void collectAllowedRoots(List<String> roots) throws IOException { public static Collection<String> collectRootsInside(String root) {
} final List<String> roots = ContainerUtil.newSmartList();
roots.add(root);
FileUtil.processFilesRecursively(new File(root), new Processor<File>() {
@Override
public boolean process(File file) {
try {
String path = file.getCanonicalPath();
if (!FileUtil.isAncestor(path, path, false)) {
roots.add(path);
}
}
catch (IOException ignore) {
}
return true;
}
});
public static Collection<String> collectRootsInside(String root) { return roots;
final List<String> roots = ContainerUtil.newSmartList(); }
roots.add(root);
FileUtil.processFilesRecursively(new File(root), new Processor<File>() { private void ensureTempDirCreated() throws IOException {
@Override if (ourTempDir != null) return;
public boolean process(File file) {
ourTempDir = new File(FileUtil.getTempDirectory(), getTestsTempDir());
FileUtil.delete(ourTempDir);
FileUtil.ensureExists(ourTempDir);
}
protected abstract String getTestsTempDir();
protected void setUpFixtures() throws Exception {
myTestFixture = IdeaTestFixtureFactory.getFixtureFactory().createFixtureBuilder(getName()).getFixture();
myTestFixture.setUp();
}
private void setUpInWriteAction() throws Exception {
File projectDir = new File(myTestDir, "project");
FileUtil.ensureExists(projectDir);
myProjectRoot = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(projectDir);
}
@After
@Override
public void tearDown() throws Exception {
try { try {
String path = file.getCanonicalPath(); EdtTestUtil.runInEdtAndWait(new ThrowableRunnable<Throwable>() {
if (!FileUtil.isAncestor(path, path, false)) { @Override
roots.add(path); public void run() throws Throwable {
} CompilerTestUtil.disableExternalCompiler(myProject);
tearDownFixtures();
}
});
myProject = null;
if (!FileUtil.delete(myTestDir) && myTestDir.exists()) {
System.err.println("Cannot delete " + myTestDir);
//printDirectoryContent(myDir);
myTestDir.deleteOnExit();
}
} }
catch (IOException ignore) { finally {
super.tearDown();
resetClassFields(getClass());
} }
return true;
}
});
return roots;
}
private void ensureTempDirCreated() throws IOException {
if (ourTempDir != null) return;
ourTempDir = new File(FileUtil.getTempDirectory(), getTestsTempDir());
FileUtil.delete(ourTempDir);
FileUtil.ensureExists(ourTempDir);
}
protected abstract String getTestsTempDir();
protected void setUpFixtures() throws Exception {
myTestFixture = IdeaTestFixtureFactory.getFixtureFactory().createFixtureBuilder(getName()).getFixture();
myTestFixture.setUp();
}
private void setUpInWriteAction() throws Exception {
File projectDir = new File(myTestDir, "project");
FileUtil.ensureExists(projectDir);
myProjectRoot = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(projectDir);
}
@After
@Override
public void tearDown() throws Exception {
try {
EdtTestUtil.runInEdtAndWait(new ThrowableRunnable<Throwable>() {
@Override
public void run() throws Throwable {
CompilerTestUtil.disableExternalCompiler(myProject);
tearDownFixtures();
}
});
myProject = null;
if (!FileUtil.delete(myTestDir) && myTestDir.exists()) {
System.err.println("Cannot delete " + myTestDir);
//printDirectoryContent(myDir);
myTestDir.deleteOnExit();
}
} }
finally {
super.tearDown(); protected void tearDownFixtures() throws Exception {
resetClassFields(getClass()); myTestFixture.tearDown();
myTestFixture = null;
} }
}
protected void tearDownFixtures() throws Exception { private void resetClassFields(Class<?> aClass) {
myTestFixture.tearDown(); if (aClass == null) return;
myTestFixture = null;
}
private void resetClassFields(Class<?> aClass) { Field[] fields = aClass.getDeclaredFields();
if (aClass == null) return; for (Field field : fields) {
final int modifiers = field.getModifiers();
if ((modifiers & Modifier.FINAL) == 0
&& (modifiers & Modifier.STATIC) == 0
&& !field.getType().isPrimitive()) {
field.setAccessible(true);
try {
field.set(this, null);
}
catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
Field[] fields = aClass.getDeclaredFields(); if (aClass == ExternalSystemTestCase.class) return;
for (Field field : fields) { resetClassFields(aClass.getSuperclass());
final int modifiers = field.getModifiers(); }
if ((modifiers & Modifier.FINAL) == 0
&& (modifiers & Modifier.STATIC) == 0 @Override
&& !field.getType().isPrimitive()) { protected void runTest() throws Throwable {
field.setAccessible(true);
try { try {
field.set(this, null); super.runTest();
} }
catch (IllegalAccessException e) { catch (Exception throwable) {
e.printStackTrace(); Throwable each = throwable;
do {
if (each instanceof HeadlessException) {
printIgnoredMessage("Doesn't work in Headless environment");
return;
}
}
while ((each = each.getCause()) != null);
throw throwable;
} }
}
} }
if (aClass == ExternalSystemTestCase.class) return; @Override
resetClassFields(aClass.getSuperclass()); protected void invokeTestRunnable(@NotNull Runnable runnable) throws Exception {
} runInEdtAndWait(runnable);
@Override
protected void runTest() throws Throwable {
try {
super.runTest();
} }
catch (Exception throwable) {
Throwable each = throwable; protected static String getRoot() {
do { if (SystemInfo.isWindows) return "c:";
if (each instanceof HeadlessException) { return "";
printIgnoredMessage("Doesn't work in Headless environment"); }
return;
protected String getProjectPath() {
return myProjectRoot.getPath();
}
protected VirtualFile createProjectConfig(@NonNls String config) throws IOException {
return createConfigFile(myProjectRoot, config);
}
private VirtualFile createConfigFile(final VirtualFile dir, String config) throws IOException {
final String configFileName = getExternalSystemConfigFileName();
VirtualFile f = dir.findChild(configFileName);
if (f == null) {
f = new WriteAction<VirtualFile>() {
@Override
protected void run(@NotNull Result<VirtualFile> result) throws Throwable {
VirtualFile res = dir.createChildData(null, configFileName);
result.setResult(res);
}
}.execute().getResultObject();
myAllConfigs.add(f);
} }
} setFileContent(f, config, true);
while ((each = each.getCause()) != null); return f;
throw throwable;
} }
}
@Override protected abstract String getExternalSystemConfigFileName();
protected void invokeTestRunnable(@NotNull Runnable runnable) throws Exception {
runInEdtAndWait(runnable);
}
protected static String getRoot() { protected VirtualFile createProjectSubFile(String relativePath) throws IOException {
if (SystemInfo.isWindows) return "c:"; File f = new File(getProjectPath(), relativePath);
return ""; FileUtil.ensureExists(f.getParentFile());
} FileUtil.ensureCanCreateFile(f);
boolean created = f.createNewFile();
protected String getProjectPath() { if (!created) {
return myProjectRoot.getPath(); throw new AssertionError("Unable to create the project sub file: " + f.getAbsolutePath());
}
protected VirtualFile createProjectConfig(@NonNls String config) throws IOException {
return createConfigFile(myProjectRoot, config);
}
private VirtualFile createConfigFile(final VirtualFile dir, String config) throws IOException {
final String configFileName = getExternalSystemConfigFileName();
VirtualFile f = dir.findChild(configFileName);
if (f == null) {
f = new WriteAction<VirtualFile>() {
@Override
protected void run(@NotNull Result<VirtualFile> result) throws Throwable {
VirtualFile res = dir.createChildData(null, configFileName);
result.setResult(res);
} }
}.execute().getResultObject(); return LocalFileSystem.getInstance().refreshAndFindFileByIoFile(f);
myAllConfigs.add(f);
} }
setFileContent(f, config, true);
return f;
}
protected abstract String getExternalSystemConfigFileName(); protected VirtualFile createProjectSubFile(String relativePath, String content) throws IOException {
VirtualFile file = createProjectSubFile(relativePath);
protected VirtualFile createProjectSubFile(String relativePath) throws IOException { setFileContent(file, content, false);
File f = new File(getProjectPath(), relativePath); return file;
FileUtil.ensureExists(f.getParentFile());
FileUtil.ensureCanCreateFile(f);
boolean created = f.createNewFile();
if(!created) {
throw new AssertionError("Unable to create the project sub file: " + f.getAbsolutePath());
} }
return LocalFileSystem.getInstance().refreshAndFindFileByIoFile(f);
}
protected VirtualFile createProjectSubFile(String relativePath, String content) throws IOException { protected Module getModule(String name) {
VirtualFile file = createProjectSubFile(relativePath); AccessToken accessToken = ApplicationManager.getApplication().acquireReadActionLock();
setFileContent(file, content, false); try {
return file; Module m = ModuleManager.getInstance(myProject).findModuleByName(name);
} assertNotNull("Module " + name + " not found", m);
return m;
protected Module getModule(String name) {
AccessToken accessToken = ApplicationManager.getApplication().acquireReadActionLock();
try {
Module m = ModuleManager.getInstance(myProject).findModuleByName(name);
assertNotNull("Module " + name + " not found", m);
return m;
}
finally {
accessToken.finish();
}
}
private static void setFileContent(final VirtualFile file, final String content, final boolean advanceStamps) throws IOException {
new WriteAction<VirtualFile>() {
@Override
protected void run(@NotNull Result<VirtualFile> result) throws Throwable {
if (advanceStamps) {
file.setBinaryContent(content.getBytes(CharsetToolkit.UTF8_CHARSET), -1, file.getTimeStamp() + 4000);
} }
else { finally {
file.setBinaryContent(content.getBytes(CharsetToolkit.UTF8_CHARSET), file.getModificationStamp(), file.getTimeStamp()); accessToken.finish();
} }
}
}.execute().getResultObject();
}
private void printIgnoredMessage(String message) {
String toPrint = "Ignored";
if (message != null) {
toPrint += ", because " + message;
} }
toPrint += ": " + getClass().getSimpleName() + "." + getName();
System.out.println(toPrint); private static void setFileContent(final VirtualFile file, final String content, final boolean advanceStamps) throws IOException {
} new WriteAction<VirtualFile>() {
@Override
protected void run(@NotNull Result<VirtualFile> result) throws Throwable {
if (advanceStamps) {
file.setBinaryContent(content.getBytes(CharsetToolkit.UTF8_CHARSET), -1, file.getTimeStamp() + 4000);
}
else {
file.setBinaryContent(content.getBytes(CharsetToolkit.UTF8_CHARSET), file.getModificationStamp(), file.getTimeStamp());
}
}
}.execute().getResultObject();
}
private void printIgnoredMessage(String message) {
String toPrint = "Ignored";
if (message != null) {
toPrint += ", because " + message;
}
toPrint += ": " + getClass().getSimpleName() + "." + getName();
System.out.println(toPrint);
}
} }
@@ -23,7 +23,8 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
@Test @Test
fun testProjectWithModule() { fun testProjectWithModule() {
createProjectSubFile("settings.gradle", "include ':app'") createProjectSubFile("settings.gradle", "include ':app'")
createProjectSubFile("app/build.gradle", """ createProjectSubFile(
"app/build.gradle", """
buildscript { buildscript {
repositories { repositories {
jcenter() jcenter()
@@ -39,7 +40,8 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
dependencies { dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-0.0" // intentionally invalid version compile "org.jetbrains.kotlin:kotlin-stdlib-0.0" // intentionally invalid version
} }
""".trimIndent()) """.trimIndent()
)
importProject() importProject()
@@ -62,14 +64,16 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
@Test @Test
fun testConfigure10() { fun testConfigure10() {
createProjectSubFile("settings.gradle", "include ':app'") createProjectSubFile("settings.gradle", "include ':app'")
val file = createProjectSubFile("app/build.gradle", """ val file = createProjectSubFile(
"app/build.gradle", """
buildscript { buildscript {
repositories { repositories {
jcenter() jcenter()
mavenCentral() mavenCentral()
} }
} }
""".trimIndent()) """.trimIndent()
)
importProject() importProject()
@@ -82,7 +86,8 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
FileDocumentManager.getInstance().saveAllDocuments() FileDocumentManager.getInstance().saveAllDocuments()
val content = LoadTextUtil.loadText(file).toString() val content = LoadTextUtil.loadText(file).toString()
assertEquals(""" assertEquals(
"""
buildscript { buildscript {
ext.kotlin_version = '1.0.6' ext.kotlin_version = '1.0.6'
repositories { repositories {
@@ -100,28 +105,35 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
dependencies { dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib:${"$"}kotlin_version" compile "org.jetbrains.kotlin:kotlin-stdlib:${"$"}kotlin_version"
} }
""".trimIndent(), content) """.trimIndent(), content
)
} }
} }
} }
private fun findGradleModuleConfigurator() = Extensions.findExtension(KotlinProjectConfigurator.EP_NAME, private fun findGradleModuleConfigurator() = Extensions.findExtension(
KotlinGradleModuleConfigurator::class.java) KotlinProjectConfigurator.EP_NAME,
KotlinGradleModuleConfigurator::class.java
)
private fun findJsGradleModuleConfigurator() = Extensions.findExtension(KotlinProjectConfigurator.EP_NAME, private fun findJsGradleModuleConfigurator() = Extensions.findExtension(
KotlinJsGradleModuleConfigurator::class.java) KotlinProjectConfigurator.EP_NAME,
KotlinJsGradleModuleConfigurator::class.java
)
@Test @Test
fun testConfigureGSK() { fun testConfigureGSK() {
createProjectSubFile("settings.gradle", "include ':app'") createProjectSubFile("settings.gradle", "include ':app'")
val file = createProjectSubFile("app/build.gradle.kts", """ val file = createProjectSubFile(
"app/build.gradle.kts", """
buildscript { buildscript {
repositories { repositories {
jcenter() jcenter()
mavenCentral() mavenCentral()
} }
} }
""".trimIndent()) """.trimIndent()
)
importProject() importProject()
@@ -134,7 +146,8 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
FileDocumentManager.getInstance().saveAllDocuments() FileDocumentManager.getInstance().saveAllDocuments()
val content = LoadTextUtil.loadText(file).toString() val content = LoadTextUtil.loadText(file).toString()
assertEquals(""" assertEquals(
"""
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
val kotlin_version: String by extra val kotlin_version: String by extra
@@ -166,7 +179,8 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
compileTestKotlin.kotlinOptions { compileTestKotlin.kotlinOptions {
jvmTarget = "1.8" jvmTarget = "1.8"
} }
""".trimIndent(), content) """.trimIndent(), content
)
} }
} }
} }
@@ -174,7 +188,8 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
@Test @Test
fun testListNonConfiguredModules() { fun testListNonConfiguredModules() {
createProjectSubFile("settings.gradle", "include ':app'") createProjectSubFile("settings.gradle", "include ':app'")
createProjectSubFile("app/build.gradle", """ createProjectSubFile(
"app/build.gradle", """
buildscript { buildscript {
repositories { repositories {
jcenter() jcenter()
@@ -183,7 +198,8 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
} }
apply plugin: 'java' apply plugin: 'java'
""".trimIndent()) """.trimIndent()
)
createProjectSubFile("app/src/main/java/foo.kt", "") createProjectSubFile("app/src/main/java/foo.kt", "")
importProject() importProject()
@@ -208,7 +224,8 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
@Test @Test
fun testListNonConfiguredModules_Configured() { fun testListNonConfiguredModules_Configured() {
createProjectSubFile("settings.gradle", "include ':app'") createProjectSubFile("settings.gradle", "include ':app'")
createProjectSubFile("app/build.gradle", """ createProjectSubFile(
"app/build.gradle", """
buildscript { buildscript {
repositories { repositories {
jcenter() jcenter()
@@ -226,7 +243,8 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
dependencies { dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib:1.1.3" compile "org.jetbrains.kotlin:kotlin-stdlib:1.1.3"
} }
""".trimIndent()) """.trimIndent()
)
createProjectSubFile("app/src/main/java/foo.kt", "") createProjectSubFile("app/src/main/java/foo.kt", "")
importProject() importProject()
@@ -239,7 +257,8 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
@Test @Test
fun testListNonConfiguredModules_ConfiguredOnlyTest() { fun testListNonConfiguredModules_ConfiguredOnlyTest() {
createProjectSubFile("settings.gradle", "include ':app'") createProjectSubFile("settings.gradle", "include ':app'")
createProjectSubFile("app/build.gradle", """ createProjectSubFile(
"app/build.gradle", """
buildscript { buildscript {
repositories { repositories {
jcenter() jcenter()
@@ -257,7 +276,8 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
dependencies { dependencies {
testCompile "org.jetbrains.kotlin:kotlin-stdlib:1.1.3" testCompile "org.jetbrains.kotlin:kotlin-stdlib:1.1.3"
} }
""".trimIndent()) """.trimIndent()
)
createProjectSubFile("app/src/test/java/foo.kt", "") createProjectSubFile("app/src/test/java/foo.kt", "")
importProject() importProject()
@@ -269,50 +289,55 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
@Test @Test
fun testAddNonKotlinLibraryGSK() { fun testAddNonKotlinLibraryGSK() {
val buildScript = createProjectSubFile("build.gradle.kts", val buildScript = createProjectSubFile(
""" "build.gradle.kts",
"""
|dependencies { |dependencies {
| testCompile("junit:junit:4.12") | testCompile("junit:junit:4.12")
| compile(kotlinModule("stdlib-jre8")) | compile(kotlinModule("stdlib-jre8"))
|} |}
|""".trimMargin("|")) |""".trimMargin("|")
)
importProject() importProject()
runInEdtAndWait { runInEdtAndWait {
myTestFixture.project.executeWriteCommand("") { myTestFixture.project.executeWriteCommand("") {
KotlinWithGradleConfigurator.addKotlinLibraryToModule( KotlinWithGradleConfigurator.addKotlinLibraryToModule(
myTestFixture.module, myTestFixture.module,
DependencyScope.COMPILE, DependencyScope.COMPILE,
object: ExternalLibraryDescriptor("org.a.b", "lib", "1.0.0", "1.0.0") { object : ExternalLibraryDescriptor("org.a.b", "lib", "1.0.0", "1.0.0") {
override fun getLibraryClassesRoots() = emptyList<String>() override fun getLibraryClassesRoots() = emptyList<String>()
}) })
} }
FileDocumentManager.getInstance().saveAllDocuments() FileDocumentManager.getInstance().saveAllDocuments()
} }
assertEquals( assertEquals(
""" """
|dependencies { |dependencies {
| testCompile("junit:junit:4.12") | testCompile("junit:junit:4.12")
| compile(kotlinModule("stdlib-jre8")) | compile(kotlinModule("stdlib-jre8"))
| compile("org.a.b:lib:1.0.0") | compile("org.a.b:lib:1.0.0")
|} |}
|""".trimMargin("|"), |""".trimMargin("|"),
LoadTextUtil.loadText(buildScript).toString()) LoadTextUtil.loadText(buildScript).toString()
)
} }
@Test @Test
fun testAddLibraryGSK_WithKotlinVersion() { fun testAddLibraryGSK_WithKotlinVersion() {
val buildScript = createProjectSubFile("build.gradle.kts", val buildScript = createProjectSubFile(
""" "build.gradle.kts",
"""
|val kotlin_version: String by extra |val kotlin_version: String by extra
|dependencies { |dependencies {
| testCompile("junit:junit:4.12") | testCompile("junit:junit:4.12")
| compile(kotlinModule("stdlib-jre8", kotlin_version)) | compile(kotlinModule("stdlib-jre8", kotlin_version))
|} |}
|""".trimMargin("|")) |""".trimMargin("|")
)
importProject() importProject()
@@ -320,18 +345,18 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
myTestFixture.project.executeWriteCommand("") { myTestFixture.project.executeWriteCommand("") {
val stdLibVersion = KotlinWithGradleConfigurator.getKotlinStdlibVersion(myTestFixture.module) val stdLibVersion = KotlinWithGradleConfigurator.getKotlinStdlibVersion(myTestFixture.module)
KotlinWithGradleConfigurator.addKotlinLibraryToModule( KotlinWithGradleConfigurator.addKotlinLibraryToModule(
myTestFixture.module, myTestFixture.module,
DependencyScope.COMPILE, DependencyScope.COMPILE,
object : ExternalLibraryDescriptor("org.jetbrains.kotlin", "kotlin-reflect", stdLibVersion, stdLibVersion) { object : ExternalLibraryDescriptor("org.jetbrains.kotlin", "kotlin-reflect", stdLibVersion, stdLibVersion) {
override fun getLibraryClassesRoots() = emptyList<String>() override fun getLibraryClassesRoots() = emptyList<String>()
}) })
} }
FileDocumentManager.getInstance().saveAllDocuments() FileDocumentManager.getInstance().saveAllDocuments()
} }
assertEquals( assertEquals(
""" """
|val kotlin_version: String by extra |val kotlin_version: String by extra
|dependencies { |dependencies {
| testCompile("junit:junit:4.12") | testCompile("junit:junit:4.12")
@@ -339,90 +364,98 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
| compile(kotlinModule("reflect", kotlin_version)) | compile(kotlinModule("reflect", kotlin_version))
|} |}
|""".trimMargin("|"), |""".trimMargin("|"),
LoadTextUtil.loadText(buildScript).toString()) LoadTextUtil.loadText(buildScript).toString()
)
} }
@Test @Test
fun testAddTestLibraryGSK() { fun testAddTestLibraryGSK() {
val buildScript = createProjectSubFile("build.gradle.kts", val buildScript = createProjectSubFile(
""" "build.gradle.kts",
"""
|dependencies { |dependencies {
| compile(kotlinModule("stdlib-jre8")) | compile(kotlinModule("stdlib-jre8"))
|} |}
|""".trimMargin("|")) |""".trimMargin("|")
)
importProject() importProject()
runInEdtAndWait { runInEdtAndWait {
myTestFixture.project.executeWriteCommand("") { myTestFixture.project.executeWriteCommand("") {
KotlinWithGradleConfigurator.addKotlinLibraryToModule( KotlinWithGradleConfigurator.addKotlinLibraryToModule(
myTestFixture.module, myTestFixture.module,
DependencyScope.TEST, DependencyScope.TEST,
object : ExternalLibraryDescriptor("junit", "junit", "4.12", "4.12") { object : ExternalLibraryDescriptor("junit", "junit", "4.12", "4.12") {
override fun getLibraryClassesRoots() = emptyList<String>() override fun getLibraryClassesRoots() = emptyList<String>()
}) })
KotlinWithGradleConfigurator.addKotlinLibraryToModule( KotlinWithGradleConfigurator.addKotlinLibraryToModule(
myTestFixture.module, myTestFixture.module,
DependencyScope.TEST, DependencyScope.TEST,
object : ExternalLibraryDescriptor("org.jetbrains.kotlin", "kotlin-test", "1.1.2", "1.1.2") { object : ExternalLibraryDescriptor("org.jetbrains.kotlin", "kotlin-test", "1.1.2", "1.1.2") {
override fun getLibraryClassesRoots() = emptyList<String>() override fun getLibraryClassesRoots() = emptyList<String>()
}) })
} }
FileDocumentManager.getInstance().saveAllDocuments() FileDocumentManager.getInstance().saveAllDocuments()
} }
assertEquals( assertEquals(
""" """
|dependencies { |dependencies {
| compile(kotlinModule("stdlib-jre8")) | compile(kotlinModule("stdlib-jre8"))
| testCompile("junit:junit:4.12") | testCompile("junit:junit:4.12")
| testCompile(kotlinModule("test", "1.1.2")) | testCompile(kotlinModule("test", "1.1.2"))
|} |}
|""".trimMargin("|"), |""".trimMargin("|"),
LoadTextUtil.loadText(buildScript).toString()) LoadTextUtil.loadText(buildScript).toString()
)
} }
@Test @Test
fun testAddLibraryGSK() { fun testAddLibraryGSK() {
val buildScript = createProjectSubFile("build.gradle.kts", val buildScript = createProjectSubFile(
""" "build.gradle.kts",
"""
|dependencies { |dependencies {
| testCompile("junit:junit:4.12") | testCompile("junit:junit:4.12")
| compile(kotlinModule("stdlib-jre8")) | compile(kotlinModule("stdlib-jre8"))
|} |}
|""".trimMargin("|")) |""".trimMargin("|")
)
importProject() importProject()
runInEdtAndWait { runInEdtAndWait {
myTestFixture.project.executeWriteCommand("") { myTestFixture.project.executeWriteCommand("") {
KotlinWithGradleConfigurator.addKotlinLibraryToModule( KotlinWithGradleConfigurator.addKotlinLibraryToModule(
myTestFixture.module, myTestFixture.module,
DependencyScope.COMPILE, DependencyScope.COMPILE,
object: ExternalLibraryDescriptor("org.jetbrains.kotlin", "kotlin-reflect", "1.0.0", "1.0.0") { object : ExternalLibraryDescriptor("org.jetbrains.kotlin", "kotlin-reflect", "1.0.0", "1.0.0") {
override fun getLibraryClassesRoots() = emptyList<String>() override fun getLibraryClassesRoots() = emptyList<String>()
}) })
} }
FileDocumentManager.getInstance().saveAllDocuments() FileDocumentManager.getInstance().saveAllDocuments()
} }
assertEquals( assertEquals(
""" """
|dependencies { |dependencies {
| testCompile("junit:junit:4.12") | testCompile("junit:junit:4.12")
| compile(kotlinModule("stdlib-jre8")) | compile(kotlinModule("stdlib-jre8"))
| compile(kotlinModule("reflect", "1.0.0")) | compile(kotlinModule("reflect", "1.0.0"))
|} |}
|""".trimMargin("|"), |""".trimMargin("|"),
LoadTextUtil.loadText(buildScript).toString()) LoadTextUtil.loadText(buildScript).toString()
)
} }
@Test @Test
fun testAddCoroutinesSupport() { fun testAddCoroutinesSupport() {
val buildScript = createProjectSubFile("build.gradle", """ val buildScript = createProjectSubFile(
"build.gradle", """
buildscript { buildscript {
repositories { repositories {
jcenter() jcenter()
@@ -438,7 +471,8 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
dependencies { dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-1.1.0" compile "org.jetbrains.kotlin:kotlin-stdlib-1.1.0"
} }
""".trimIndent()) """.trimIndent()
)
importProject() importProject()
@@ -450,7 +484,8 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
FileDocumentManager.getInstance().saveAllDocuments() FileDocumentManager.getInstance().saveAllDocuments()
} }
assertEquals(""" assertEquals(
"""
buildscript { buildscript {
repositories { repositories {
jcenter() jcenter()
@@ -472,7 +507,8 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
} }
} }
""".trimIndent(), """.trimIndent(),
LoadTextUtil.loadText(buildScript).toString()) LoadTextUtil.loadText(buildScript).toString()
)
} }
@Test @Test
@@ -490,17 +526,19 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
} }
assertEquals( assertEquals(
"""import org.jetbrains.kotlin.gradle.dsl.Coroutines """import org.jetbrains.kotlin.gradle.dsl.Coroutines
| |
|kotlin { |kotlin {
| experimental.coroutines = Coroutines.ENABLE | experimental.coroutines = Coroutines.ENABLE
|}""".trimMargin("|"), |}""".trimMargin("|"),
LoadTextUtil.loadText(buildScript).toString()) LoadTextUtil.loadText(buildScript).toString()
)
} }
@Test @Test
fun testChangeCoroutinesSupport() { fun testChangeCoroutinesSupport() {
val buildScript = createProjectSubFile("build.gradle", """ val buildScript = createProjectSubFile(
"build.gradle", """
buildscript { buildscript {
repositories { repositories {
jcenter() jcenter()
@@ -521,7 +559,8 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
coroutines "error" coroutines "error"
} }
} }
""".trimIndent()) """.trimIndent()
)
importProject() importProject()
@@ -533,7 +572,8 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
FileDocumentManager.getInstance().saveAllDocuments() FileDocumentManager.getInstance().saveAllDocuments()
} }
assertEquals(""" assertEquals(
"""
buildscript { buildscript {
repositories { repositories {
jcenter() jcenter()
@@ -554,18 +594,21 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
coroutines "enable" coroutines "enable"
} }
} }
""".trimIndent(), LoadTextUtil.loadText(buildScript).toString()) """.trimIndent(), LoadTextUtil.loadText(buildScript).toString()
)
} }
@Test @Test
fun testChangeCoroutinesSupportGSK() { fun testChangeCoroutinesSupportGSK() {
val buildScript = createProjectSubFile("build.gradle.kts", val buildScript = createProjectSubFile(
"""import org.jetbrains.kotlin.gradle.dsl.Coroutines "build.gradle.kts",
"""import org.jetbrains.kotlin.gradle.dsl.Coroutines
| |
|kotlin { |kotlin {
| experimental.coroutines = Coroutines.DISABLE | experimental.coroutines = Coroutines.DISABLE
|} |}
|""".trimMargin("|")) |""".trimMargin("|")
)
importProject() importProject()
@@ -578,18 +621,20 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
} }
assertEquals( assertEquals(
"""import org.jetbrains.kotlin.gradle.dsl.Coroutines """import org.jetbrains.kotlin.gradle.dsl.Coroutines
| |
|kotlin { |kotlin {
| experimental.coroutines = Coroutines.ENABLE | experimental.coroutines = Coroutines.ENABLE
|} |}
|""".trimMargin("|"), |""".trimMargin("|"),
LoadTextUtil.loadText(buildScript).toString()) LoadTextUtil.loadText(buildScript).toString()
)
} }
@Test @Test
fun testAddLanguageVersion() { fun testAddLanguageVersion() {
val buildScript = createProjectSubFile("build.gradle", """ val buildScript = createProjectSubFile(
"build.gradle", """
buildscript { buildscript {
repositories { repositories {
jcenter() jcenter()
@@ -605,7 +650,8 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
dependencies { dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-1.1.0" compile "org.jetbrains.kotlin:kotlin-stdlib-1.1.0"
} }
""".trimIndent()) """.trimIndent()
)
importProject() importProject()
@@ -617,7 +663,8 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
FileDocumentManager.getInstance().saveAllDocuments() FileDocumentManager.getInstance().saveAllDocuments()
} }
assertEquals(""" assertEquals(
"""
buildscript { buildscript {
repositories { repositories {
jcenter() jcenter()
@@ -638,7 +685,8 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
languageVersion = "1.1" languageVersion = "1.1"
} }
} }
""".trimIndent(), LoadTextUtil.loadText(buildScript).toString()) """.trimIndent(), LoadTextUtil.loadText(buildScript).toString()
)
} }
@Test @Test
@@ -656,18 +704,20 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
} }
assertEquals( assertEquals(
"""import org.jetbrains.kotlin.gradle.tasks.KotlinCompile """import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
| |
|val compileKotlin: KotlinCompile by tasks |val compileKotlin: KotlinCompile by tasks
|compileKotlin.kotlinOptions { |compileKotlin.kotlinOptions {
| languageVersion = "1.1" | languageVersion = "1.1"
|}""".trimMargin("|"), |}""".trimMargin("|"),
LoadTextUtil.loadText(buildScript).toString()) LoadTextUtil.loadText(buildScript).toString()
)
} }
@Test @Test
fun testChangeLanguageVersion() { fun testChangeLanguageVersion() {
val buildScript = createProjectSubFile("build.gradle", """ val buildScript = createProjectSubFile(
"build.gradle", """
buildscript { buildscript {
repositories { repositories {
jcenter() jcenter()
@@ -688,7 +738,8 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
languageVersion = "1.0" languageVersion = "1.0"
} }
} }
""".trimIndent()) """.trimIndent()
)
importProject() importProject()
@@ -700,7 +751,8 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
FileDocumentManager.getInstance().saveAllDocuments() FileDocumentManager.getInstance().saveAllDocuments()
} }
assertEquals(""" assertEquals(
"""
buildscript { buildscript {
repositories { repositories {
jcenter() jcenter()
@@ -721,17 +773,20 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
languageVersion = "1.1" languageVersion = "1.1"
} }
} }
""".trimIndent(), LoadTextUtil.loadText(buildScript).toString()) """.trimIndent(), LoadTextUtil.loadText(buildScript).toString()
)
} }
@Test @Test
fun testChangeLanguageVersionGSK() { fun testChangeLanguageVersionGSK() {
val buildScript = createProjectSubFile("build.gradle.kts", val buildScript = createProjectSubFile(
"""val compileKotlin: KotlinCompile by tasks "build.gradle.kts",
"""val compileKotlin: KotlinCompile by tasks
|compileKotlin.kotlinOptions { |compileKotlin.kotlinOptions {
| languageVersion = "1.0" | languageVersion = "1.0"
|} |}
|""".trimMargin("|")) |""".trimMargin("|")
)
importProject() importProject()
@@ -744,17 +799,19 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
} }
assertEquals( assertEquals(
"""val compileKotlin: KotlinCompile by tasks """val compileKotlin: KotlinCompile by tasks
|compileKotlin.kotlinOptions { |compileKotlin.kotlinOptions {
| languageVersion = "1.1" | languageVersion = "1.1"
|} |}
|""".trimMargin("|"), |""".trimMargin("|"),
LoadTextUtil.loadText(buildScript).toString()) LoadTextUtil.loadText(buildScript).toString()
)
} }
@Test @Test
fun testAddLibrary() { fun testAddLibrary() {
val buildScript = createProjectSubFile("build.gradle", """ val buildScript = createProjectSubFile(
"build.gradle", """
buildscript { buildscript {
repositories { repositories {
jcenter() jcenter()
@@ -770,24 +827,26 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
dependencies { dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-1.1.0" compile "org.jetbrains.kotlin:kotlin-stdlib-1.1.0"
} }
""".trimIndent()) """.trimIndent()
)
importProject() importProject()
runInEdtAndWait { runInEdtAndWait {
myTestFixture.project.executeWriteCommand("") { myTestFixture.project.executeWriteCommand("") {
KotlinWithGradleConfigurator.addKotlinLibraryToModule( KotlinWithGradleConfigurator.addKotlinLibraryToModule(
myTestFixture.module, myTestFixture.module,
DependencyScope.COMPILE, DependencyScope.COMPILE,
object: ExternalLibraryDescriptor("org.jetbrains.kotlin", "kotlin-reflect", "1.0.0", "1.0.0") { object : ExternalLibraryDescriptor("org.jetbrains.kotlin", "kotlin-reflect", "1.0.0", "1.0.0") {
override fun getLibraryClassesRoots() = emptyList<String>() override fun getLibraryClassesRoots() = emptyList<String>()
}) })
} }
FileDocumentManager.getInstance().saveAllDocuments() FileDocumentManager.getInstance().saveAllDocuments()
} }
assertEquals(""" assertEquals(
"""
buildscript { buildscript {
repositories { repositories {
jcenter() jcenter()
@@ -804,6 +863,7 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
compile "org.jetbrains.kotlin:kotlin-stdlib-1.1.0" compile "org.jetbrains.kotlin:kotlin-stdlib-1.1.0"
compile "org.jetbrains.kotlin:kotlin-reflect:1.0.0" compile "org.jetbrains.kotlin:kotlin-reflect:1.0.0"
} }
""".trimIndent(), LoadTextUtil.loadText(buildScript).toString()) """.trimIndent(), LoadTextUtil.loadText(buildScript).toString()
)
} }
} }
@@ -64,168 +64,168 @@ import static org.junit.Assume.assumeThat;
// part of org.jetbrains.plugins.gradle.importing.GradleImportingTestCase // part of org.jetbrains.plugins.gradle.importing.GradleImportingTestCase
@RunWith(value = Parameterized.class) @RunWith(value = Parameterized.class)
public abstract class GradleImportingTestCase extends ExternalSystemImportingTestCase { public abstract class GradleImportingTestCase extends ExternalSystemImportingTestCase {
private static final String GRADLE_JDK_NAME = "Gradle JDK"; private static final String GRADLE_JDK_NAME = "Gradle JDK";
private static final int GRADLE_DAEMON_TTL_MS = 10000; private static final int GRADLE_DAEMON_TTL_MS = 10000;
@Rule public TestName name = new TestName(); @Rule public TestName name = new TestName();
@Rule public VersionMatcherRule versionMatcherRule = new VersionMatcherRule(); @Rule public VersionMatcherRule versionMatcherRule = new VersionMatcherRule();
@SuppressWarnings({"NullableProblems", "WeakerAccess"}) @NotNull @SuppressWarnings({"NullableProblems", "WeakerAccess"}) @NotNull
@Parameterized.Parameter() public String gradleVersion; @Parameterized.Parameter() public String gradleVersion;
private GradleProjectSettings myProjectSettings; private GradleProjectSettings myProjectSettings;
private String myJdkHome; private String myJdkHome;
@Override @Override
public void setUp() throws Exception { public void setUp() throws Exception {
myJdkHome = IdeaTestUtil.requireRealJdkHome(); myJdkHome = IdeaTestUtil.requireRealJdkHome();
super.setUp(); super.setUp();
assumeThat(gradleVersion, versionMatcherRule.getMatcher()); assumeThat(gradleVersion, versionMatcherRule.getMatcher());
new WriteAction() { new WriteAction() {
@Override @Override
protected void run(@NotNull Result result) throws Throwable { protected void run(@NotNull Result result) throws Throwable {
Sdk oldJdk = ProjectJdkTable.getInstance().findJdk(GRADLE_JDK_NAME); Sdk oldJdk = ProjectJdkTable.getInstance().findJdk(GRADLE_JDK_NAME);
if (oldJdk != null) { if (oldJdk != null) {
ProjectJdkTable.getInstance().removeJdk(oldJdk); ProjectJdkTable.getInstance().removeJdk(oldJdk);
} }
VirtualFile jdkHomeDir = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(new File(myJdkHome)); VirtualFile jdkHomeDir = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(new File(myJdkHome));
assert jdkHomeDir != null; assert jdkHomeDir != null;
Sdk jdk = SdkConfigurationUtil.setupSdk(new Sdk[0], jdkHomeDir, JavaSdk.getInstance(), true, null, GRADLE_JDK_NAME); Sdk jdk = SdkConfigurationUtil.setupSdk(new Sdk[0], jdkHomeDir, JavaSdk.getInstance(), true, null, GRADLE_JDK_NAME);
assertNotNull("Cannot create JDK for " + myJdkHome, jdk); assertNotNull("Cannot create JDK for " + myJdkHome, jdk);
ProjectJdkTable.getInstance().addJdk(jdk); ProjectJdkTable.getInstance().addJdk(jdk);
} }
}.execute(); }.execute();
myProjectSettings = new GradleProjectSettings(); myProjectSettings = new GradleProjectSettings();
GradleSettings.getInstance(myProject).setGradleVmOptions("-Xmx128m -XX:MaxPermSize=64m"); GradleSettings.getInstance(myProject).setGradleVmOptions("-Xmx128m -XX:MaxPermSize=64m");
System.setProperty(ExternalSystemExecutionSettings.REMOTE_PROCESS_IDLE_TTL_IN_MS_KEY, String.valueOf(GRADLE_DAEMON_TTL_MS)); System.setProperty(ExternalSystemExecutionSettings.REMOTE_PROCESS_IDLE_TTL_IN_MS_KEY, String.valueOf(GRADLE_DAEMON_TTL_MS));
configureWrapper(); configureWrapper();
}
@Override
public void tearDown() throws Exception {
if (myJdkHome == null) {
//super.setUp() wasn't called
return;
} }
try { @Override
new WriteAction() { public void tearDown() throws Exception {
@Override if (myJdkHome == null) {
protected void run(@NotNull Result result) throws Throwable { //super.setUp() wasn't called
Sdk old = ProjectJdkTable.getInstance().findJdk(GRADLE_JDK_NAME); return;
if (old != null) {
SdkConfigurationUtil.removeSdk(old);
}
} }
}.execute();
Messages.setTestDialog(TestDialog.DEFAULT);
FileUtil.delete(BuildManager.getInstance().getBuildSystemDirectory().toFile());
}
finally {
super.tearDown();
}
}
@Override try {
protected void collectAllowedRoots(List<String> roots) throws IOException { new WriteAction() {
roots.add(myJdkHome); @Override
roots.addAll(collectRootsInside(myJdkHome)); protected void run(@NotNull Result result) throws Throwable {
roots.add(PathManager.getConfigPath()); Sdk old = ProjectJdkTable.getInstance().findJdk(GRADLE_JDK_NAME);
} if (old != null) {
SdkConfigurationUtil.removeSdk(old);
@Override }
public String getName() { }
return name.getMethodName() == null ? super.getName() : FileUtil.sanitizeFileName(name.getMethodName()); }.execute();
} Messages.setTestDialog(TestDialog.DEFAULT);
FileUtil.delete(BuildManager.getInstance().getBuildSystemDirectory().toFile());
@Parameterized.Parameters(name = "{index}: with Gradle-{0}")
public static Collection<Object[]> data() throws Throwable {
return Arrays.asList(AbstractModelBuilderTest.SUPPORTED_GRADLE_VERSIONS);
}
@Override
protected String getTestsTempDir() {
return "gradleImportTests";
}
@Override
protected String getExternalSystemConfigFileName() {
return "build.gradle";
}
protected void importProjectUsingSingeModulePerGradleProject() {
getCurrentExternalProjectSettings().setResolveModulePerSourceSet(false);
importProject();
}
@Override
protected void importProject() {
ExternalSystemApiUtil.subscribe(myProject, GradleConstants.SYSTEM_ID, new ExternalSystemSettingsListenerAdapter() {
@Override
public void onProjectsLinked(@NotNull Collection settings) {
Object item = ContainerUtil.getFirstItem(settings);
if (item instanceof GradleProjectSettings) {
((GradleProjectSettings)item).setGradleJvm(GRADLE_JDK_NAME);
} }
} finally {
}); super.tearDown();
super.importProject(); }
} }
@Override @Override
protected void importProject(@NonNls @Language("Groovy") String config) throws IOException { protected void collectAllowedRoots(List<String> roots) throws IOException {
config = "allprojects {\n" + roots.add(myJdkHome);
" repositories {\n" + roots.addAll(collectRootsInside(myJdkHome));
" maven {\n" + roots.add(PathManager.getConfigPath());
" url 'http://maven.labs.intellij.net/repo1'\n" + }
" }\n" +
" }" +
"}\n" + config;
super.importProject(config);
}
@Override @Override
protected GradleProjectSettings getCurrentExternalProjectSettings() { public String getName() {
return myProjectSettings; return name.getMethodName() == null ? super.getName() : FileUtil.sanitizeFileName(name.getMethodName());
} }
@Override @Parameterized.Parameters(name = "{index}: with Gradle-{0}")
protected ProjectSystemId getExternalSystemId() { public static Collection<Object[]> data() throws Throwable {
return GradleConstants.SYSTEM_ID; return Arrays.asList(AbstractModelBuilderTest.SUPPORTED_GRADLE_VERSIONS);
} }
private void configureWrapper() throws IOException, URISyntaxException { @Override
URI distributionUri = new AbstractModelBuilderTest.DistributionLocator().getDistributionFor(GradleVersion.version(gradleVersion)); protected String getTestsTempDir() {
return "gradleImportTests";
}
myProjectSettings.setDistributionType(DistributionType.DEFAULT_WRAPPED); @Override
final VirtualFile wrapperJarFrom = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(wrapperJar()); protected String getExternalSystemConfigFileName() {
assert wrapperJarFrom != null; return "build.gradle";
}
final VirtualFile wrapperJarFromTo = createProjectSubFile("gradle/wrapper/gradle-wrapper.jar"); protected void importProjectUsingSingeModulePerGradleProject() {
new WriteAction() { getCurrentExternalProjectSettings().setResolveModulePerSourceSet(false);
@Override importProject();
protected void run(@NotNull Result result) throws Throwable { }
wrapperJarFromTo.setBinaryContent(wrapperJarFrom.contentsToByteArray());
} @Override
}.execute().throwException(); protected void importProject() {
ExternalSystemApiUtil.subscribe(myProject, GradleConstants.SYSTEM_ID, new ExternalSystemSettingsListenerAdapter() {
@Override
public void onProjectsLinked(@NotNull Collection settings) {
Object item = ContainerUtil.getFirstItem(settings);
if (item instanceof GradleProjectSettings) {
((GradleProjectSettings) item).setGradleJvm(GRADLE_JDK_NAME);
}
}
});
super.importProject();
}
@Override
protected void importProject(@NonNls @Language("Groovy") String config) throws IOException {
config = "allprojects {\n" +
" repositories {\n" +
" maven {\n" +
" url 'http://maven.labs.intellij.net/repo1'\n" +
" }\n" +
" }" +
"}\n" + config;
super.importProject(config);
}
@Override
protected GradleProjectSettings getCurrentExternalProjectSettings() {
return myProjectSettings;
}
@Override
protected ProjectSystemId getExternalSystemId() {
return GradleConstants.SYSTEM_ID;
}
private void configureWrapper() throws IOException, URISyntaxException {
URI distributionUri = new AbstractModelBuilderTest.DistributionLocator().getDistributionFor(GradleVersion.version(gradleVersion));
myProjectSettings.setDistributionType(DistributionType.DEFAULT_WRAPPED);
final VirtualFile wrapperJarFrom = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(wrapperJar());
assert wrapperJarFrom != null;
final VirtualFile wrapperJarFromTo = createProjectSubFile("gradle/wrapper/gradle-wrapper.jar");
new WriteAction() {
@Override
protected void run(@NotNull Result result) throws Throwable {
wrapperJarFromTo.setBinaryContent(wrapperJarFrom.contentsToByteArray());
}
}.execute().throwException();
Properties properties = new Properties(); Properties properties = new Properties();
properties.setProperty("distributionBase", "GRADLE_USER_HOME"); properties.setProperty("distributionBase", "GRADLE_USER_HOME");
properties.setProperty("distributionPath", "wrapper/dists"); properties.setProperty("distributionPath", "wrapper/dists");
properties.setProperty("zipStoreBase", "GRADLE_USER_HOME"); properties.setProperty("zipStoreBase", "GRADLE_USER_HOME");
properties.setProperty("zipStorePath", "wrapper/dists"); properties.setProperty("zipStorePath", "wrapper/dists");
properties.setProperty("distributionUrl", distributionUri.toString()); properties.setProperty("distributionUrl", distributionUri.toString());
StringWriter writer = new StringWriter(); StringWriter writer = new StringWriter();
properties.store(writer, null); properties.store(writer, null);
createProjectSubFile("gradle/wrapper/gradle-wrapper.properties", writer.toString()); createProjectSubFile("gradle/wrapper/gradle-wrapper.properties", writer.toString());
} }
@NotNull @NotNull
private static File wrapperJar() { private static File wrapperJar() {
return new File(PathUtil.getJarPathForClass(GradleWrapperMain.class)); return new File(PathUtil.getJarPathForClass(GradleWrapperMain.class));
} }
} }
@@ -20,9 +20,9 @@ import com.intellij.codeInspection.LocalInspectionTool
import com.intellij.codeInspection.ProblemDescriptorBase import com.intellij.codeInspection.ProblemDescriptorBase
import com.intellij.openapi.util.Ref import com.intellij.openapi.util.Ref
import com.intellij.openapi.vfs.VirtualFile import com.intellij.openapi.vfs.VirtualFile
import org.jetbrains.kotlin.idea.inspections.gradle.DeprecatedGradleDependencyInspection
import org.jetbrains.kotlin.idea.inspections.gradle.DifferentKotlinGradleVersionInspection import org.jetbrains.kotlin.idea.inspections.gradle.DifferentKotlinGradleVersionInspection
import org.jetbrains.kotlin.idea.inspections.gradle.DifferentStdlibGradleVersionInspection import org.jetbrains.kotlin.idea.inspections.gradle.DifferentStdlibGradleVersionInspection
import org.jetbrains.kotlin.idea.inspections.gradle.DeprecatedGradleDependencyInspection
import org.jetbrains.kotlin.idea.inspections.runInspection import org.jetbrains.kotlin.idea.inspections.runInspection
import org.junit.Assert import org.junit.Assert
import org.junit.Test import org.junit.Test
@@ -30,7 +30,8 @@ import org.junit.Test
class GradleInspectionTest : GradleImportingTestCase() { class GradleInspectionTest : GradleImportingTestCase() {
@Test @Test
fun testDifferentStdlibGradleVersion() { fun testDifferentStdlibGradleVersion() {
val localFile = createProjectSubFile("build.gradle", """ val localFile = createProjectSubFile(
"build.gradle", """
group 'Again' group 'Again'
version '1.0-SNAPSHOT' version '1.0-SNAPSHOT'
@@ -49,7 +50,8 @@ class GradleInspectionTest : GradleImportingTestCase() {
dependencies { dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib:1.0.3" compile "org.jetbrains.kotlin:kotlin-stdlib:1.0.3"
} }
""") """
)
importProject() importProject()
val tool = DifferentStdlibGradleVersionInspection() val tool = DifferentStdlibGradleVersionInspection()
@@ -61,7 +63,8 @@ class GradleInspectionTest : GradleImportingTestCase() {
@Test @Test
fun testDifferentStdlibJre7GradleVersion() { fun testDifferentStdlibJre7GradleVersion() {
val localFile = createProjectSubFile("build.gradle", """ val localFile = createProjectSubFile(
"build.gradle", """
group 'Again' group 'Again'
version '1.0-SNAPSHOT' version '1.0-SNAPSHOT'
@@ -83,7 +86,8 @@ class GradleInspectionTest : GradleImportingTestCase() {
dependencies { dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:1.1.0-beta-22" compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:1.1.0-beta-22"
} }
""") """
)
importProject() importProject()
val tool = DifferentStdlibGradleVersionInspection() val tool = DifferentStdlibGradleVersionInspection()
@@ -95,7 +99,8 @@ class GradleInspectionTest : GradleImportingTestCase() {
@Test @Test
fun testDifferentStdlibJdk7GradleVersion() { fun testDifferentStdlibJdk7GradleVersion() {
val localFile = createProjectSubFile("build.gradle", """ val localFile = createProjectSubFile(
"build.gradle", """
group 'Again' group 'Again'
version '1.0-SNAPSHOT' version '1.0-SNAPSHOT'
@@ -117,7 +122,8 @@ class GradleInspectionTest : GradleImportingTestCase() {
dependencies { dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.1.0-beta-22" compile "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.1.0-beta-22"
} }
""") """
)
importProject() importProject()
val tool = DifferentStdlibGradleVersionInspection() val tool = DifferentStdlibGradleVersionInspection()
@@ -130,10 +136,13 @@ class GradleInspectionTest : GradleImportingTestCase() {
@Test @Test
fun testDifferentStdlibGradleVersionWithVariables() { fun testDifferentStdlibGradleVersionWithVariables() {
createProjectSubFile("gradle.properties", """ createProjectSubFile(
"gradle.properties", """
|kotlin=1.0.1 |kotlin=1.0.1
|lib_version=1.0.3""".trimMargin()) |lib_version=1.0.3""".trimMargin()
val localFile = createProjectSubFile("build.gradle", """ )
val localFile = createProjectSubFile(
"build.gradle", """
group 'Again' group 'Again'
version '1.0-SNAPSHOT' version '1.0-SNAPSHOT'
@@ -152,7 +161,8 @@ class GradleInspectionTest : GradleImportingTestCase() {
dependencies { dependencies {
compile group: 'org.jetbrains.kotlin', name: 'kotlin-stdlib', version: lib_version compile group: 'org.jetbrains.kotlin', name: 'kotlin-stdlib', version: lib_version
} }
""") """
)
importProject() importProject()
val tool = DifferentStdlibGradleVersionInspection() val tool = DifferentStdlibGradleVersionInspection()
@@ -165,7 +175,8 @@ class GradleInspectionTest : GradleImportingTestCase() {
@Test @Test
fun testDifferentKotlinGradleVersion() { fun testDifferentKotlinGradleVersion() {
createProjectSubFile("gradle.properties", """test=1.0.1""") createProjectSubFile("gradle.properties", """test=1.0.1""")
val localFile = createProjectSubFile("build.gradle", """ val localFile = createProjectSubFile(
"build.gradle", """
group 'Again' group 'Again'
version '1.0-SNAPSHOT' version '1.0-SNAPSHOT'
@@ -180,7 +191,8 @@ class GradleInspectionTest : GradleImportingTestCase() {
} }
apply plugin: 'kotlin' apply plugin: 'kotlin'
""") """
)
importProject() importProject()
val tool = DifferentKotlinGradleVersionInspection() val tool = DifferentKotlinGradleVersionInspection()
@@ -188,12 +200,16 @@ class GradleInspectionTest : GradleImportingTestCase() {
val problems = getInspectionResult(tool, localFile) val problems = getInspectionResult(tool, localFile)
Assert.assertTrue(problems.size == 1) Assert.assertTrue(problems.size == 1)
Assert.assertEquals("Kotlin version that is used for building with Gradle (1.0.1) differs from the one bundled into the IDE plugin (\$PLUGIN_VERSION)", problems.single()) Assert.assertEquals(
"Kotlin version that is used for building with Gradle (1.0.1) differs from the one bundled into the IDE plugin (\$PLUGIN_VERSION)",
problems.single()
)
} }
@Test @Test
fun testJreInOldVersion() { fun testJreInOldVersion() {
val localFile = createProjectSubFile("build.gradle", """ val localFile = createProjectSubFile(
"build.gradle", """
group 'Again' group 'Again'
version '1.0-SNAPSHOT' version '1.0-SNAPSHOT'
@@ -212,7 +228,8 @@ class GradleInspectionTest : GradleImportingTestCase() {
dependencies { dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-jre8:1.1.60" compile "org.jetbrains.kotlin:kotlin-stdlib-jre8:1.1.60"
} }
""") """
)
importProject() importProject()
val tool = DeprecatedGradleDependencyInspection() val tool = DeprecatedGradleDependencyInspection()
@@ -223,7 +240,8 @@ class GradleInspectionTest : GradleImportingTestCase() {
@Test @Test
fun testJreIsDeprecated() { fun testJreIsDeprecated() {
val localFile = createProjectSubFile("build.gradle", """ val localFile = createProjectSubFile(
"build.gradle", """
group 'Again' group 'Again'
version '1.0-SNAPSHOT' version '1.0-SNAPSHOT'
@@ -242,14 +260,18 @@ class GradleInspectionTest : GradleImportingTestCase() {
dependencies { dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:1.2.0" compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:1.2.0"
} }
""") """
)
importProject() importProject()
val tool = DeprecatedGradleDependencyInspection() val tool = DeprecatedGradleDependencyInspection()
val problems = getInspectionResult(tool, localFile) val problems = getInspectionResult(tool, localFile)
Assert.assertTrue(problems.size == 1) Assert.assertTrue(problems.size == 1)
Assert.assertEquals("kotlin-stdlib-jre7 is deprecated since 1.2.0 and should be replaced with kotlin-stdlib-jdk7", problems.single()) Assert.assertEquals(
"kotlin-stdlib-jre7 is deprecated since 1.2.0 and should be replaced with kotlin-stdlib-jdk7",
problems.single()
)
} }
fun getInspectionResult(tool: LocalInspectionTool, file: VirtualFile): List<String> { fun getInspectionResult(tool: LocalInspectionTool, file: VirtualFile): List<String> {
@@ -258,9 +280,9 @@ class GradleInspectionTest : GradleImportingTestCase() {
val presentation = runInspection(tool, myProject, listOf(file)) val presentation = runInspection(tool, myProject, listOf(file))
val foundProblems = presentation.problemElements val foundProblems = presentation.problemElements
.values .values
.mapNotNull { it as? ProblemDescriptorBase } .mapNotNull { it as? ProblemDescriptorBase }
.map { it.descriptionTemplate } .map { it.descriptionTemplate }
resultRef.set(foundProblems) resultRef.set(foundProblems)
} }
@@ -38,8 +38,8 @@ class GradleMultiplatformRunTest : GradleImportingTestCase() {
@Test @Test
fun testMultiplatformClasspath() { fun testMultiplatformClasspath() {
createProjectSubFile( createProjectSubFile(
"build.gradle", "build.gradle",
""" """
buildscript { buildscript {
repositories { repositories {
jcenter() jcenter()
@@ -64,15 +64,15 @@ class GradleMultiplatformRunTest : GradleImportingTestCase() {
""".trimIndent() """.trimIndent()
) )
createProjectSubFile( createProjectSubFile(
"settings.gradle", "settings.gradle",
""" """
rootProject.name = 'MultiTest' rootProject.name = 'MultiTest'
include 'MultiTest-jvm', 'MultiTest-js' include 'MultiTest-jvm', 'MultiTest-js'
""".trimIndent() """.trimIndent()
) )
createProjectSubFile( createProjectSubFile(
"MultiTest-js/build.gradle", "MultiTest-js/build.gradle",
""" """
buildscript { buildscript {
repositories { repositories {
jcenter() jcenter()
@@ -98,8 +98,8 @@ class GradleMultiplatformRunTest : GradleImportingTestCase() {
""".trimIndent() """.trimIndent()
) )
createProjectSubFile( createProjectSubFile(
"MultiTest-jvm/build.gradle", "MultiTest-jvm/build.gradle",
""" """
buildscript { buildscript {
repositories { repositories {
jcenter() jcenter()
@@ -140,16 +140,23 @@ class GradleMultiplatformRunTest : GradleImportingTestCase() {
val producer = RunConfigurationProducer.getInstance(KotlinRunConfigurationProducer::class.java) val producer = RunConfigurationProducer.getInstance(KotlinRunConfigurationProducer::class.java)
val configuration = producer.createConfigurationFromContext(configurationContext)!! val configuration = producer.createConfigurationFromContext(configurationContext)!!
val executionEnvironment = ExecutionEnvironmentBuilder.create(myProject, val executionEnvironment = ExecutionEnvironmentBuilder.create(
DefaultRunExecutor.getRunExecutorInstance(), myProject,
configuration.configuration) DefaultRunExecutor.getRunExecutorInstance(),
configuration.configuration
)
.build() .build()
val compileStepBeforeRun = CompileStepBeforeRun(myProject) val compileStepBeforeRun = CompileStepBeforeRun(myProject)
compileStepBeforeRun.executeTask(dataContext, configuration.configuration, executionEnvironment, compileStepBeforeRun.executeTask(
CompileStepBeforeRun.MakeBeforeRunTask()) dataContext, configuration.configuration, executionEnvironment,
CompileStepBeforeRun.MakeBeforeRunTask()
)
val state = configuration.configuration.getState(DefaultRunExecutor.getRunExecutorInstance(), executionEnvironment) as JavaCommandLineState val state = configuration.configuration.getState(
DefaultRunExecutor.getRunExecutorInstance(),
executionEnvironment
) as JavaCommandLineState
state.javaParameters state.javaParameters
} }
@@ -46,23 +46,28 @@ class GradleUpdateConfigurationQuickFixTest : GradleImportingTestCase() {
myTestFixture = null myTestFixture = null
} }
@Test fun testUpdateLanguageVersion() { @Test
fun testUpdateLanguageVersion() {
doTest("Set module language version to 1.1") doTest("Set module language version to 1.1")
} }
@Test fun testUpdateApiVersion() { @Test
fun testUpdateApiVersion() {
doTest("Set module API version to 1.1") doTest("Set module API version to 1.1")
} }
@Test fun testUpdateLanguageAndApiVersion() { @Test
fun testUpdateLanguageAndApiVersion() {
doTest("Set module language version to 1.1") doTest("Set module language version to 1.1")
} }
@Test fun testEnableCoroutines() { @Test
fun testEnableCoroutines() {
doTest("Enable coroutine support in the current module") doTest("Enable coroutine support in the current module")
} }
@Test fun testAddKotlinReflect() { @Test
fun testAddKotlinReflect() {
doTest("Add kotlin-reflect.jar to the classpath") doTest("Add kotlin-reflect.jar to the classpath")
} }
@@ -29,24 +29,24 @@ import org.junit.runner.Description;
// copy of org.jetbrains.plugins.gradle.tooling.VersionMatcherRule // copy of org.jetbrains.plugins.gradle.tooling.VersionMatcherRule
public class VersionMatcherRule extends TestWatcher { public class VersionMatcherRule extends TestWatcher {
@Nullable @Nullable
private CustomMatcher myMatcher; private CustomMatcher myMatcher;
@NotNull @NotNull
public Matcher getMatcher() { public Matcher getMatcher() {
return myMatcher != null ? myMatcher : CoreMatchers.anything(); return myMatcher != null ? myMatcher : CoreMatchers.anything();
} }
@Override @Override
protected void starting(Description d) { protected void starting(Description d) {
final TargetVersions targetVersions = d.getAnnotation(TargetVersions.class); final TargetVersions targetVersions = d.getAnnotation(TargetVersions.class);
if (targetVersions == null) return; if (targetVersions == null) return;
myMatcher = new CustomMatcher<String>("Gradle version '" + targetVersions.value() + "'") { myMatcher = new CustomMatcher<String>("Gradle version '" + targetVersions.value() + "'") {
@Override @Override
public boolean matches(Object item) { public boolean matches(Object item) {
return item instanceof String && new VersionMatcher(GradleVersion.version(item.toString())).isVersionMatch(targetVersions); return item instanceof String && new VersionMatcher(GradleVersion.version(item.toString())).isVersionMatch(targetVersions);
} }
}; };
} }
} }
@@ -26,7 +26,8 @@ import org.jetbrains.kotlin.test.KotlinTestUtils.isAllFilesPresentTest
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile import org.jetbrains.plugins.groovy.lang.psi.GroovyFile
import java.io.File import java.io.File
abstract class AbstractGradleConfigureProjectByChangingFileTest : AbstractConfigureProjectByChangingFileTest<KotlinWithGradleConfigurator>() { abstract class AbstractGradleConfigureProjectByChangingFileTest :
AbstractConfigureProjectByChangingFileTest<KotlinWithGradleConfigurator>() {
fun doTestGradle(path: String) { fun doTestGradle(path: String) {
val (before, after) = beforeAfterFiles() val (before, after) = beforeAfterFiles()
doTest(before, after, if ("js" in path) KotlinJsGradleModuleConfigurator() else KotlinGradleModuleConfigurator()) doTest(before, after, if ("js" in path) KotlinJsGradleModuleConfigurator() else KotlinGradleModuleConfigurator())
@@ -53,7 +54,13 @@ abstract class AbstractGradleConfigureProjectByChangingFileTest : AbstractConfig
} }
} }
override fun runConfigurator(module: Module, file: PsiFile, configurator: KotlinWithGradleConfigurator, version: String, collector: NotificationMessageCollector) { override fun runConfigurator(
module: Module,
file: PsiFile,
configurator: KotlinWithGradleConfigurator,
version: String,
collector: NotificationMessageCollector
) {
if (file !is GroovyFile && file !is KtFile) { if (file !is GroovyFile && file !is KtFile) {
fail("file $file is not a GroovyFile or KtFile") fail("file $file is not a GroovyFile or KtFile")
return return