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("jps-compatible") }
@@ -16,14 +15,30 @@ dependencies {
compile(project(":js:js.frontend"))
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("junit")) { includeJars("idea-junit") }
testCompile(projectTests(":idea"))
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(intellijDep()) { includeJars("groovy-all", "idea_rt", rootProject = rootProject) }
@@ -23,10 +23,12 @@ import com.intellij.psi.PsiElement
interface GradleBuildScriptManipulator {
fun isConfigured(kotlinPluginName: String): Boolean
fun configureModuleBuildScript(kotlinPluginName: String,
stdlibArtifactName: String,
version: String,
jvmTarget: String?): Boolean
fun configureModuleBuildScript(
kotlinPluginName: String,
stdlibArtifactName: String,
version: String,
jvmTarget: String?
): Boolean
fun configureProjectBuildScript(version: String): Boolean
@@ -37,9 +39,10 @@ interface GradleBuildScriptManipulator {
fun changeApiVersion(version: String, forTests: Boolean): PsiElement?
fun addKotlinLibraryToModuleBuildScript(
scope: DependencyScope,
libraryDescriptor: ExternalLibraryDescriptor,
isAndroidModule: Boolean)
scope: DependencyScope,
libraryDescriptor: ExternalLibraryDescriptor,
isAndroidModule: Boolean
)
fun getKotlinStdlibVersion(): String?
}
@@ -32,9 +32,11 @@ import javax.swing.Icon
import javax.swing.JComponent
import javax.swing.JLabel
abstract class GradleKotlinFrameworkSupportProvider(val frameworkTypeId: String,
val displayName: String,
val frameworkIcon: Icon) : GradleFrameworkSupportProvider() {
abstract class GradleKotlinFrameworkSupportProvider(
val frameworkTypeId: String,
val displayName: String,
val frameworkIcon: Icon
) : GradleFrameworkSupportProvider() {
override fun getFrameworkType(): FrameworkTypeEx = object : FrameworkTypeEx(frameworkTypeId) {
override fun getIcon(): Icon = frameworkIcon
@@ -54,10 +56,12 @@ abstract class GradleKotlinFrameworkSupportProvider(val frameworkTypeId: String,
}
}
override fun addSupport(module: Module,
rootModel: ModifiableRootModel,
modifiableModelsProvider: ModifiableModelsProvider,
buildScriptData: BuildScriptDataBuilder) {
override fun addSupport(
module: Module,
rootModel: ModifiableRootModel,
modifiableModelsProvider: ModifiableModelsProvider,
buildScriptData: BuildScriptDataBuilder
) {
addSupport(buildScriptData, rootModel.sdk)
}
@@ -89,10 +93,10 @@ abstract class GradleKotlinFrameworkSupportProvider(val frameworkTypeId: String,
}
for (dependency in getTestDependencies()) {
buildScriptData.addDependencyNotation(
if (":" in dependency)
"testCompile \"$dependency\""
else
KotlinWithGradleConfigurator.getGroovyDependencySnippet(dependency, "testCompile")
if (":" in dependency)
"testCompile \"$dependency\""
else
KotlinWithGradleConfigurator.getGroovyDependencySnippet(dependency, "testCompile")
)
}
buildScriptData.addBuildscriptDependencyNotation(KotlinWithGradleConfigurator.CLASSPATH)
@@ -106,9 +110,10 @@ abstract class GradleKotlinFrameworkSupportProvider(val frameworkTypeId: String,
protected abstract fun getDescription(): String
}
open class GradleKotlinJavaFrameworkSupportProvider(frameworkTypeId: String = "KOTLIN",
displayName: String = "Kotlin (Java)")
: GradleKotlinFrameworkSupportProvider(frameworkTypeId, displayName, KotlinIcons.SMALL_LOGO) {
open class GradleKotlinJavaFrameworkSupportProvider(
frameworkTypeId: String = "KOTLIN",
displayName: String = "Kotlin (Java)"
) : GradleKotlinFrameworkSupportProvider(frameworkTypeId, displayName, KotlinIcons.SMALL_LOGO) {
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"
}
open class GradleKotlinJSFrameworkSupportProvider(frameworkTypeId: String = "KOTLIN_JS",
displayName: String = "Kotlin (JavaScript)")
: GradleKotlinFrameworkSupportProvider(frameworkTypeId, displayName, KotlinIcons.JS) {
open class GradleKotlinJSFrameworkSupportProvider(
frameworkTypeId: String = "KOTLIN_JS",
displayName: String = "Kotlin (JavaScript)"
) : GradleKotlinFrameworkSupportProvider(frameworkTypeId, displayName, KotlinIcons.JS) {
override fun getPluginId() = KotlinJsGradleModuleConfigurator.KOTLIN_JS
@@ -141,7 +147,7 @@ open class GradleKotlinJSFrameworkSupportProvider(frameworkTypeId: String = "KOT
}
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 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 {
val fileText = runReadAction { groovyScript.text }
return containsDirective(fileText, getApplyPluginDirective(kotlinPluginName)) &&
fileText.contains("org.jetbrains.kotlin") &&
fileText.contains("kotlin-stdlib")
fileText.contains("org.jetbrains.kotlin") &&
fileText.contains("kotlin-stdlib")
}
override fun configureModuleBuildScript(
kotlinPluginName: String,
stdlibArtifactName: String,
version: String,
jvmTarget: String?
kotlinPluginName: String,
stdlibArtifactName: String,
version: String,
jvmTarget: String?
): Boolean {
val oldText = groovyScript.text
val applyPluginDirective = getGroovyApplyPluginDirective(kotlinPluginName)
@@ -53,13 +53,11 @@ class GroovyBuildScriptManipulator(private val groovyScript: GroovyFile) : Gradl
val applyStatement = getApplyStatement(groovyScript)
if (applyStatement != null) {
groovyScript.addAfter(apply, applyStatement)
}
else {
} else {
val buildScriptBlock = groovyScript.getBlockByName("buildscript")
if (buildScriptBlock != null) {
groovyScript.addAfter(apply, buildScriptBlock.parent)
}
else {
} else {
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? =
changeKotlinTaskParameter(groovyScript, "languageVersion", version, forTests)
changeKotlinTaskParameter(groovyScript, "languageVersion", version, forTests)
override fun changeApiVersion(version: String, forTests: Boolean): PsiElement? =
changeKotlinTaskParameter(groovyScript, "apiVersion", version, forTests)
changeKotlinTaskParameter(groovyScript, "apiVersion", version, forTests)
override fun addKotlinLibraryToModuleBuildScript(
scope: DependencyScope,
libraryDescriptor: ExternalLibraryDescriptor,
isAndroidModule: Boolean
scope: DependencyScope,
libraryDescriptor: ExternalLibraryDescriptor,
isAndroidModule: Boolean
) {
val dependencyString = String.format(
"%s \"%s:%s:%s\"",
scope.toGradleCompileScope(isAndroidModule),
libraryDescriptor.libraryGroupId,
libraryDescriptor.libraryArtifactId,
libraryDescriptor.maxVersion)
"%s \"%s:%s:%s\"",
scope.toGradleCompileScope(isAndroidModule),
libraryDescriptor.libraryGroupId,
libraryDescriptor.libraryArtifactId,
libraryDescriptor.maxVersion
)
groovyScript.getDependenciesBlock().apply {
addLastExpressionInBlockIfNeeded(dependencyString)
@@ -160,10 +159,10 @@ class GroovyBuildScriptManipulator(private val groovyScript: GroovyFile) : Gradl
}
private fun changeKotlinTaskParameter(
gradleFile: GroovyFile,
parameterName: String,
parameterValue: String,
forTests: Boolean
gradleFile: GroovyFile,
parameterName: String,
parameterValue: String,
forTests: Boolean
): PsiElement? {
val snippet = "$parameterName = \"$parameterValue\""
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 {
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? =
file.getChildrenOfType<GrApplicationStatement>().find { it.invokedExpression.text == "apply" }
file.getChildrenOfType<GrApplicationStatement>().find { it.invokedExpression.text == "apply" }
private fun PsiElement.getBlockByName(name: String): GrClosableBlock? {
return getChildrenOfType<GrMethodCallExpression>()
.filter { it.closureArguments.isNotEmpty() }
.find { it.invokedExpression.text == name }
?.let { it.closureArguments[0] }
.filter { it.closureArguments.isNotEmpty() }
.find { it.invokedExpression.text == name }
?.let { it.closureArguments[0] }
}
private fun GrClosableBlock.addRepository(version: String): Boolean {
@@ -214,7 +213,7 @@ class GroovyBuildScriptManipulator(private val groovyScript: GroovyFile) : Gradl
}
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")
@@ -223,10 +222,10 @@ class GroovyBuildScriptManipulator(private val groovyScript: GroovyFile) : Gradl
private fun GrStatementOwner.getBuildScriptBlock() = getBlockOrCreate("buildscript")
private fun GrStatementOwner.getBuildScriptRepositoriesBlock(): GrClosableBlock =
getBuildScriptBlock().getBlockOrCreate("repositories")
getBuildScriptBlock().getBlockOrCreate("repositories")
private fun GrStatementOwner.getBuildScriptDependenciesBlock(): GrClosableBlock =
getBuildScriptBlock().getBlockOrCreate("dependencies")
getBuildScriptBlock().getBlockOrCreate("dependencies")
private fun GrStatementOwner.getBlockOrCreate(name: String): GrClosableBlock {
var block = getBlockByName(name)
@@ -248,10 +247,10 @@ class GroovyBuildScriptManipulator(private val groovyScript: GroovyFile) : Gradl
}
private fun GrClosableBlock.addLastExpressionInBlockIfNeeded(expressionText: String): Boolean =
addExpressionInBlockIfNeeded(expressionText, false)
addExpressionInBlockIfNeeded(expressionText, false)
private fun GrClosableBlock.addFirstExpressionInBlockIfNeeded(expressionText: String): Boolean =
addExpressionInBlockIfNeeded(expressionText, true)
addExpressionInBlockIfNeeded(expressionText, true)
private fun GrClosableBlock.addExpressionInBlockIfNeeded(expressionText: String, isFirst: Boolean): Boolean {
if (text.contains(expressionText)) return false
@@ -262,8 +261,7 @@ class GroovyBuildScriptManipulator(private val groovyScript: GroovyFile) : Gradl
if (lastStatement != null) {
addAfter(newStatement, lastStatement)
}
}
else {
} else {
if (firstChild != null) {
addAfter(newStatement, firstChild)
}
@@ -28,9 +28,9 @@ import org.jetbrains.kotlin.utils.addToStdlib.cast
class KotlinBuildScriptManipulator(private val kotlinScript: KtFile) : GradleBuildScriptManipulator {
override fun isConfigured(kotlinPluginName: String): Boolean =
runReadAction {
kotlinScript.containsApplyKotlinPlugin(kotlinPluginName) && kotlinScript.containsCompileStdLib()
}
runReadAction {
kotlinScript.containsApplyKotlinPlugin(kotlinPluginName) && kotlinScript.containsCompileStdLib()
}
override fun configureProjectBuildScript(version: String): Boolean {
val originalText = kotlinScript.text
@@ -51,10 +51,10 @@ class KotlinBuildScriptManipulator(private val kotlinScript: KtFile) : GradleBui
}
override fun configureModuleBuildScript(
kotlinPluginName: String,
stdlibArtifactName: String,
version: String,
jvmTarget: String?
kotlinPluginName: String,
stdlibArtifactName: String,
version: String,
jvmTarget: String?
): Boolean {
val originalText = kotlinScript.text
kotlinScript.apply {
@@ -76,40 +76,42 @@ class KotlinBuildScriptManipulator(private val kotlinScript: KtFile) : GradleBui
}
override fun changeCoroutineConfiguration(coroutineOption: String): PsiElement? =
kotlinScript.changeCoroutineConfiguration(coroutineOption)
kotlinScript.changeCoroutineConfiguration(coroutineOption)
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? =
kotlinScript.changeKotlinTaskParameter("apiVersion", version, forTests)
kotlinScript.changeKotlinTaskParameter("apiVersion", version, forTests)
override fun addKotlinLibraryToModuleBuildScript(
scope: DependencyScope,
libraryDescriptor: ExternalLibraryDescriptor,
isAndroidModule: Boolean
scope: DependencyScope,
libraryDescriptor: ExternalLibraryDescriptor,
isAndroidModule: Boolean
) {
val kotlinLibraryVersion = libraryDescriptor.maxVersion.takeIf { it != GSK_KOTLIN_VERSION_PROPERTY_NAME }
kotlinScript.getDependenciesBlock()?.apply {
addExpressionIfMissing(
getCompileDependencySnippet(
libraryDescriptor.libraryGroupId,
libraryDescriptor.libraryArtifactId,
scope.toGradleCompileScope(isAndroidModule),
kotlinLibraryVersion))
getCompileDependencySnippet(
libraryDescriptor.libraryGroupId,
libraryDescriptor.libraryArtifactId,
scope.toGradleCompileScope(isAndroidModule),
kotlinLibraryVersion
)
)
}
}
override fun getKotlinStdlibVersion(): String? = kotlinScript.getKotlinStdlibVersion()
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 =
findScriptInitializer("dependencies")?.getBlock()?.findCompileStdLib() != null
findScriptInitializer("dependencies")?.getBlock()?.findCompileStdLib() != null
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? {
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? =
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? {
return getChildrenOfType<KtCallExpression>().find {
it.calleeExpression?.text == name &&
it.valueArguments.singleOrNull()?.getArgumentExpression() is KtLambdaExpression
it.valueArguments.singleOrNull()?.getArgumentExpression() is KtLambdaExpression
}?.getBlock()
}
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? =
(valueArguments.singleOrNull()?.getArgumentExpression() as? KtLambdaExpression)?.bodyExpression
(valueArguments.singleOrNull()?.getArgumentExpression() as? KtLambdaExpression)?.bodyExpression
private fun KtFile.getKotlinStdlibVersion(): String? {
return findScriptInitializer("dependencies")?.getBlock()?.let {
@@ -152,16 +154,16 @@ class KotlinBuildScriptManipulator(private val kotlinScript: KtFile) : GradleBui
private fun KtExpression.isKotlinStdLib(): Boolean = when (this) {
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")
else -> false
}
private fun KtFile.getRepositoriesBlock(): KtBlockExpression? =
findScriptInitializer("repositories")?.getBlock() ?: addTopLevelBlock("repositories")
findScriptInitializer("repositories")?.getBlock() ?: addTopLevelBlock("repositories")
private fun KtFile.getDependenciesBlock(): KtBlockExpression? =
findScriptInitializer("dependencies")?.getBlock() ?: addTopLevelBlock("dependencies")
findScriptInitializer("dependencies")?.getBlock() ?: addTopLevelBlock("dependencies")
private fun KtFile.createApplyBlock(): KtBlockExpression? {
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 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? {
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") }
return if (statement != null) {
statement.replace(psiFactory.createExpression(snippet))
}
else {
} else {
kotlinBlock.add(psiFactory.createExpression(snippet)).apply { addNewLinesIfNeeded() }
}
}
@@ -199,12 +200,10 @@ class KotlinBuildScriptManipulator(private val kotlinScript: KtFile) : GradleBui
}
if (assignment != null) {
assignment.replace(psiFactory.createExpression(snippet))
}
else {
} else {
optionsBlock.addExpressionIfMissing(snippet)
}
}
else {
} else {
addImportIfMissing("org.jetbrains.kotlin.gradle.tasks.KotlinCompile")
script?.blockExpression?.addDeclarationIfMissing("val $taskName: KotlinCompile by tasks")
addTopLevelBlock("$taskName.kotlinOptions")?.addExpressionIfMissing(snippet)
@@ -212,13 +211,13 @@ class KotlinBuildScriptManipulator(private val kotlinScript: KtFile) : GradleBui
}
private fun KtFile.getBuildScriptBlock(): KtBlockExpression? =
findScriptInitializer("buildscript")?.getBlock() ?: addTopLevelBlock("buildscript", true)
findScriptInitializer("buildscript")?.getBlock() ?: addTopLevelBlock("buildscript", true)
private fun KtBlockExpression.getRepositoriesBlock(): KtBlockExpression? =
findBlock("repositories") ?: addBlock("repositories")
findBlock("repositories") ?: addBlock("repositories")
private fun KtBlockExpression.getDependenciesBlock(): KtBlockExpression? =
findBlock("dependencies") ?: addBlock("dependencies")
findBlock("dependencies") ?: addBlock("dependencies")
private fun KtBlockExpression.addRepositoryIfMissing(version: String): KtCallExpression? {
val repository = getRepositoryForVersion(version)
@@ -232,16 +231,16 @@ class KotlinBuildScriptManipulator(private val kotlinScript: KtFile) : GradleBui
}
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? =
addExpressionIfMissing(getKotlinGradlePluginClassPathSnippet()) as? KtCallExpression
addExpressionIfMissing(getKotlinGradlePluginClassPathSnippet()) as? KtCallExpression
private fun KtBlockExpression.addBlock(name: String): KtBlockExpression? {
return add(psiFactory.createExpression("$name {\n}"))
?.apply { addNewLinesIfNeeded() }
?.cast<KtCallExpression>()
?.getBlock()
?.apply { addNewLinesIfNeeded() }
?.cast<KtCallExpression>()
?.getBlock()
}
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? =
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 =
importDirectives.find { it.importPath?.pathStr == path } ?:
importList?.add(psiFactory.createImportDirective(ImportPath.fromString(path))) as KtImportDirective
importDirectives.find { it.importPath?.pathStr == path } ?: importList?.add(
psiFactory.createImportDirective(
ImportPath.fromString(
path
)
)
) as KtImportDirective
private fun KtBlockExpression.addExpressionAfterIfMissing(text: String, after: PsiElement): KtExpression = addStatementIfMissing(text) {
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) {
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) {
psiFactory.createDeclaration<KtDeclaration>(it).let { created ->
if(first) addAfter(created, null) else add(created)
private fun KtBlockExpression.addDeclarationIfMissing(text: String, first: Boolean = false): KtDeclaration =
addStatementIfMissing(text) {
psiFactory.createDeclaration<KtDeclaration>(it).let { created ->
if (first) addAfter(created, null) else add(created)
}
}
}
private inline fun <reified T: PsiElement> KtBlockExpression.addStatementIfMissing(
text: String,
crossinline factory: (String) -> PsiElement): T {
private inline fun <reified T : PsiElement> KtBlockExpression.addStatementIfMissing(
text: String,
crossinline factory: (String) -> PsiElement
): T {
statements.find { it.text == text }?.let {
return it as T
}
@@ -307,7 +313,7 @@ class KotlinBuildScriptManipulator(private val kotlinScript: KtFile) : GradleBui
}
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
get() = KtPsiFactory(this)
@@ -319,12 +325,17 @@ class KotlinBuildScriptManipulator(private val kotlinScript: KtFile) : GradleBui
fun getKotlinGradlePluginClassPathSnippet(): String = "classpath(${getKotlinModuleDependencySnippet("gradle-plugin")})"
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 =
if (groupId == KOTLIN_GROUP_ID)
"$compileScope(${Companion.getKotlinModuleDependencySnippet(artifactId, version)})"
else
"$compileScope(\"$groupId:$artifactId:$version\")"
fun getCompileDependencySnippet(
groupId: String,
artifactId: String,
compileScope: String = "compile",
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
abstract class KotlinDslGradleKotlinFrameworkSupportProvider(
val frameworkTypeId: String,
val displayName: String,
val frameworkIcon: Icon
val frameworkTypeId: String,
val displayName: String,
val frameworkIcon: Icon
) : KotlinDslGradleFrameworkSupportProvider() {
override fun getFrameworkType(): FrameworkTypeEx = object : FrameworkTypeEx(frameworkTypeId) {
override fun getIcon(): Icon = frameworkIcon
@@ -42,11 +42,13 @@ abstract class KotlinDslGradleKotlinFrameworkSupportProvider(
override fun createProvider(): FrameworkSupportInModuleProvider = this@KotlinDslGradleKotlinFrameworkSupportProvider
}
override fun addSupport(projectId: ProjectId,
module: Module,
rootModel: ModifiableRootModel,
modifiableModelsProvider: ModifiableModelsProvider,
buildScriptData: BuildScriptDataBuilder) {
override fun addSupport(
projectId: ProjectId,
module: Module,
rootModel: ModifiableRootModel,
modifiableModelsProvider: ModifiableModelsProvider,
buildScriptData: BuildScriptDataBuilder
) {
var kotlinVersion = bundledRuntimeVersion()
val additionalRepository = getRepositoryForVersion(kotlinVersion)
if (isSnapshot(bundledRuntimeVersion())) {
@@ -61,14 +63,14 @@ abstract class KotlinDslGradleKotlinFrameworkSupportProvider(
}
buildScriptData
.addPropertyDefinition("val $GSK_KOTLIN_VERSION_PROPERTY_NAME: String by extra")
.addPluginDefinition(getPluginDefinition())
.addBuildscriptRepositoriesDefinition("mavenCentral()")
.addRepositoriesDefinition("mavenCentral()")
// 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\"")
.addDependencyNotation(getRuntimeLibrary(rootModel))
.addBuildscriptDependencyNotation(getKotlinGradlePluginClassPathSnippet())
.addPropertyDefinition("val $GSK_KOTLIN_VERSION_PROPERTY_NAME: String by extra")
.addPluginDefinition(getPluginDefinition())
.addBuildscriptRepositoriesDefinition("mavenCentral()")
.addRepositoriesDefinition("mavenCentral()")
// 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\"")
.addDependencyNotation(getRuntimeLibrary(rootModel))
.addBuildscriptDependencyNotation(getKotlinGradlePluginClassPathSnippet())
}
private fun RepositoryDescription.toKotlinRepositorySnippet() = "maven { setUrl(\"$url\") }"
@@ -79,35 +81,35 @@ abstract class KotlinDslGradleKotlinFrameworkSupportProvider(
}
class KotlinDslGradleKotlinJavaFrameworkSupportProvider :
KotlinDslGradleKotlinFrameworkSupportProvider("KOTLIN", "Kotlin (Java)", KotlinIcons.SMALL_LOGO) {
KotlinDslGradleKotlinFrameworkSupportProvider("KOTLIN", "Kotlin (Java)", KotlinIcons.SMALL_LOGO) {
override fun getPluginDefinition() = "plugin(\"${KotlinGradleModuleConfigurator.KOTLIN}\")"
override fun getRuntimeLibrary(rootModel: ModifiableRootModel) =
getCompileDependencySnippet(KOTLIN_GROUP_ID, getStdlibArtifactId(rootModel.sdk, bundledRuntimeVersion()))
getCompileDependencySnippet(KOTLIN_GROUP_ID, getStdlibArtifactId(rootModel.sdk, bundledRuntimeVersion()))
override fun addSupport(
projectId: ProjectId,
module: Module,
rootModel: ModifiableRootModel,
modifiableModelsProvider: ModifiableModelsProvider,
buildScriptData: BuildScriptDataBuilder
projectId: ProjectId,
module: Module,
rootModel: ModifiableRootModel,
modifiableModelsProvider: ModifiableModelsProvider,
buildScriptData: BuildScriptDataBuilder
) {
super.addSupport(projectId, module, rootModel, modifiableModelsProvider, buildScriptData)
val jvmTarget = getDefaultJvmTarget(rootModel.sdk, bundledRuntimeVersion())
if (jvmTarget != null) {
buildScriptData
.addImport("import org.jetbrains.kotlin.gradle.tasks.KotlinCompile")
.addOther("tasks.withType<KotlinCompile> {\n kotlinOptions.jvmTarget = \"1.8\"\n}\n")
.addImport("import org.jetbrains.kotlin.gradle.tasks.KotlinCompile")
.addOther("tasks.withType<KotlinCompile> {\n kotlinOptions.jvmTarget = \"1.8\"\n}\n")
}
}
}
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 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 configureModule(
module: Module,
file: PsiFile,
isTopLevelProjectFile: Boolean,
version: String, collector: NotificationMessageCollector,
filesToOpen: MutableCollection<PsiFile>
module: Module,
file: PsiFile,
isTopLevelProjectFile: Boolean,
version: String, collector: NotificationMessageCollector,
filesToOpen: MutableCollection<PsiFile>
) {
super.configureModule(module, file, isTopLevelProjectFile, version, collector, filesToOpen)
@@ -53,7 +53,9 @@ class KotlinGradleMultiplatformModuleBuilder : GradleModuleBuilder() {
super.createWizardSteps(wizardContext, modulesProvider) // initializes GradleModuleBuilder.myWizardContext
return arrayOf(
KotlinGradleMultiplatformWizardStep(this, wizardContext),
ExternalModuleSettingsStep(wizardContext, this, GradleProjectSettingsControl(externalProjectSettings))
ExternalModuleSettingsStep(
wizardContext, this, GradleProjectSettingsControl(externalProjectSettings)
)
)
}
@@ -96,6 +98,7 @@ class KotlinGradleMultiplatformModuleBuilder : GradleModuleBuilder() {
extendScript: (BuildScriptDataBuilder, Sdk?) -> Unit = { _, _ -> }
) {
if (childModuleName.isNullOrEmpty()) return
val moduleDir = contentRoot.createChildDirectory(this, childModuleName!!)
val buildGradle = moduleDir.createChildData(null, "build.gradle")
val buildScriptData = BuildScriptDataBuilder(buildGradle)
@@ -71,14 +71,16 @@ class KotlinGradleProjectResolverExtension : AbstractProjectResolverExtension()
return resolverCtx.isResolveModulePerSourceSet
}
override fun populateModuleDependencies(gradleModule: IdeaModule,
ideModule: DataNode<ModuleData>,
ideProject: DataNode<ProjectData>) {
override fun populateModuleDependencies(
gradleModule: IdeaModule,
ideModule: DataNode<ModuleData>,
ideProject: DataNode<ProjectData>
) {
val outputToSourceSet = ideProject.getUserData(GradleProjectResolver.MODULES_OUTPUTS)
val sourceSetByName = ideProject.getUserData(GradleProjectResolver.RESOLVED_SOURCE_SETS)
val gradleModel = resolverCtx.getExtraProject(gradleModule, KotlinGradleModel::class.java)
?: return super.populateModuleDependencies(gradleModule, ideModule, ideProject)
?: return super.populateModuleDependencies(gradleModule, ideModule, ideProject)
val gradleIdeaProject = gradleModule.project
@@ -92,16 +94,17 @@ class KotlinGradleProjectResolverExtension : AbstractProjectResolverExtension()
val targetModuleNode = ExternalSystemApiUtil.findFirstRecursively(ideProject) {
(it.data as? ModuleData)?.id == dependency.projectPath
} 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 -> {
dependency.files
.mapTo(HashSet()) {
val path = FileUtil.toSystemIndependentName(it.path)
val targetSourceSetId = outputToSourceSet?.get(path)?.first ?: return@mapTo null
sourceSetByName[targetSourceSetId]?.first
}
.singleOrNull()
.mapTo(HashSet()) {
val path = FileUtil.toSystemIndependentName(it.path)
val targetSourceSetId = outputToSourceSet?.get(path)?.first ?: return@mapTo null
sourceSetByName[targetSourceSetId]?.first
}
.singleOrNull()
}
else -> null
}
@@ -114,8 +117,7 @@ class KotlinGradleProjectResolverExtension : AbstractProjectResolverExtension()
fun addTransitiveDependenciesOnImplementedModules() {
val moduleNodesToProcess = if (useModulePerSourceSet()) {
ExternalSystemApiUtil.findAll(ideModule, GradleSourceSetData.KEY)
}
else listOf(ideModule)
} else listOf(ideModule)
for (currentModuleNode in moduleNodesToProcess) {
val toProcess = LinkedList<DataNode<out ModuleData>>()
@@ -128,18 +130,17 @@ class KotlinGradleProjectResolverExtension : AbstractProjectResolverExtension()
val moduleNodeForGradleModel = if (useModulePerSourceSet()) {
ExternalSystemApiUtil.findParent(moduleNode, ProjectKeys.MODULE)
}
else moduleNode
} else moduleNode
val ideaModule = if (moduleNodeForGradleModel != ideModule) {
gradleIdeaProject.modules.firstOrNull { it.gradleProject.path == moduleNodeForGradleModel?.data?.id }
}
else gradleModule
} else gradleModule
val implementsModuleIds = resolverCtx.getExtraProject(ideaModule, KotlinGradleModel::class.java)?.implements
?: emptyList()
for (implementsModuleId in implementsModuleIds) {
val compositePrefix = if (resolverCtx.models.ideaProject != gradleModule.project
&& implementsModuleId.startsWith(":")) {
&& implementsModuleId.startsWith(":")
) {
gradleModule.project.name
} else {
""
@@ -159,8 +160,7 @@ class KotlinGradleProjectResolverExtension : AbstractProjectResolverExtension()
if (currentModuleNode.sourceSetName == "test" && targetMainSourceSet != targetSourceSet) {
addDependency(currentModuleNode, targetMainSourceSet)
}
}
else {
} else {
addDependency(currentModuleNode, targetModule)
}
}
@@ -189,9 +189,9 @@ class KotlinGradleProjectResolverExtension : AbstractProjectResolverExtension()
}
private fun addImplementedModuleNames(
dependentModule: DataNode<ModuleData>,
ideProject: DataNode<ProjectData>,
gradleModel: KotlinGradleModel
dependentModule: DataNode<ModuleData>,
ideProject: DataNode<ProjectData>,
gradleModel: KotlinGradleModel
) {
val implementedModules = gradleModel.implements.mapNotNull { findModuleById(ideProject, it) }
if (resolverCtx.isResolveModulePerSourceSet) {
@@ -206,7 +206,7 @@ class KotlinGradleProjectResolverExtension : AbstractProjectResolverExtension()
}
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
get() = (data as? GradleSourceSetData)?.id?.substringAfterLast(':')
@@ -27,7 +27,7 @@ class KotlinJsGradleModuleConfigurator : KotlinWithGradleConfigurator() {
override val targetPlatform: TargetPlatform = JsPlatform
override val kotlinPluginName: String = KOTLIN_JS
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 {
val KOTLIN_JS = "kotlin2js"
@@ -27,7 +27,6 @@ import com.intellij.psi.PsiManager
import org.jetbrains.kotlin.config.ApiVersion
import org.jetbrains.kotlin.config.CoroutineSupport
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.idea.KotlinPluginUtil
import org.jetbrains.kotlin.idea.facet.getRuntimeLibraryVersion
import org.jetbrains.kotlin.idea.framework.ui.ConfigureDialogWithModulesAndVersion
import org.jetbrains.kotlin.idea.quickfix.ChangeCoroutineSupportFix
@@ -56,8 +55,8 @@ abstract class KotlinWithGradleConfigurator : KotlinProjectConfigurator {
val buildFiles = runReadAction {
listOf(
module.getBuildScriptPsiFile(),
module.project.getTopLevelBuildScriptPsiFile()
module.getBuildScriptPsiFile(),
module.project.getTopLevelBuildScriptPsiFile()
).filterNotNull()
}
@@ -74,12 +73,12 @@ abstract class KotlinWithGradleConfigurator : KotlinProjectConfigurator {
private fun PsiFile.isConfiguredByAnyGradleConfigurator(): Boolean {
return Extensions.getExtensions(KotlinProjectConfigurator.EP_NAME)
.filterIsInstance<KotlinWithGradleConfigurator>()
.any { it.isFileConfigured(this) }
.filterIsInstance<KotlinWithGradleConfigurator>()
.any { it.isFileConfigured(this) }
}
protected open fun isApplicable(module: Module): Boolean =
module.getBuildSystemType() == Gradle
module.getBuildSystemType() == Gradle
protected open fun getMinimumSupportedVersion() = "1.0.0"
@@ -103,10 +102,12 @@ abstract class KotlinWithGradleConfigurator : KotlinProjectConfigurator {
}
}
fun configureWithVersion(project: Project,
modulesToConfigure: List<Module>,
kotlinVersion: String,
collector: NotificationMessageCollector): HashSet<PsiFile> {
fun configureWithVersion(
project: Project,
modulesToConfigure: List<Module>,
kotlinVersion: String,
collector: NotificationMessageCollector
): HashSet<PsiFile> {
val filesToOpen = HashSet<PsiFile>()
val buildScript = project.getTopLevelBuildScriptPsiFile()
if (buildScript != null && canConfigureFile(buildScript)) {
@@ -120,8 +121,7 @@ abstract class KotlinWithGradleConfigurator : KotlinProjectConfigurator {
val file = module.getBuildScriptPsiFile()
if (file != null && canConfigureFile(file)) {
configureModule(module, file, false, kotlinVersion, collector, filesToOpen)
}
else {
} else {
showErrorMessage(project, "Cannot find build.gradle file for module " + module.name)
}
}
@@ -129,12 +129,12 @@ abstract class KotlinWithGradleConfigurator : KotlinProjectConfigurator {
}
open fun configureModule(
module: Module,
file: PsiFile,
isTopLevelProjectFile: Boolean,
version: String,
collector: NotificationMessageCollector,
filesToOpen: MutableCollection<PsiFile>
module: Module,
file: PsiFile,
isTopLevelProjectFile: Boolean,
version: String,
collector: NotificationMessageCollector,
filesToOpen: MutableCollection<PsiFile>
) {
val isModified = configureBuildScript(file, isTopLevelProjectFile, version, collector)
if (isModified) {
@@ -146,10 +146,11 @@ abstract class KotlinWithGradleConfigurator : KotlinProjectConfigurator {
val sdk = ModuleUtil.findModuleForPsiElement(file)?.let { ModuleRootManager.getInstance(it).sdk }
val jvmTarget = getJvmTarget(sdk, version)
return getManipulator(file).configureModuleBuildScript(
kotlinPluginName,
getStdlibArtifactName(sdk, version),
version,
jvmTarget)
kotlinPluginName,
getStdlibArtifactName(sdk, version),
version,
jvmTarget
)
}
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 open fun addElementsToFile(
file: PsiFile,
isTopLevelProjectFile: Boolean,
version: String
file: PsiFile,
isTopLevelProjectFile: Boolean,
version: String
): Boolean {
if (!isTopLevelProjectFile) {
var wasModified = configureProjectFile(file, version)
@@ -172,10 +173,10 @@ abstract class KotlinWithGradleConfigurator : KotlinProjectConfigurator {
}
private fun configureBuildScript(
file: PsiFile,
isTopLevelProjectFile: Boolean,
version: String,
collector: NotificationMessageCollector
file: PsiFile,
isTopLevelProjectFile: Boolean,
version: String,
collector: NotificationMessageCollector
): Boolean {
val isModified = file.project.executeWriteCommand("Configure ${file.name}", null) {
val isModified = addElementsToFile(file, isTopLevelProjectFile, version)
@@ -192,21 +193,23 @@ abstract class KotlinWithGradleConfigurator : KotlinProjectConfigurator {
}
override fun updateLanguageVersion(
module: Module,
languageVersion: String?,
apiVersion: String?,
requiredStdlibVersion: ApiVersion,
forTests: Boolean
module: Module,
languageVersion: String?,
apiVersion: String?,
requiredStdlibVersion: ApiVersion,
forTests: Boolean
) {
val runtimeUpdateRequired = getRuntimeLibraryVersion(module)?.let { ApiVersion.parse(it) }?.let { runtimeVersion ->
runtimeVersion < requiredStdlibVersion
} ?: false
if (runtimeUpdateRequired) {
Messages.showErrorDialog(module.project,
"This language feature requires version $requiredStdlibVersion or later of the Kotlin runtime library. " +
"Please update the version in your build script.",
"Update Language Version")
Messages.showErrorDialog(
module.project,
"This language feature requires version $requiredStdlibVersion or later of the Kotlin runtime library. " +
"Please update the version in your build script.",
"Update Language Version"
)
return
}
@@ -219,13 +222,15 @@ abstract class KotlinWithGradleConfigurator : KotlinProjectConfigurator {
override fun changeCoroutineConfiguration(module: Module, state: LanguageFeature.State) {
val runtimeUpdateRequired = state != LanguageFeature.State.DISABLED &&
(getRuntimeLibraryVersion(module)?.startsWith("1.0") ?: false)
(getRuntimeLibraryVersion(module)?.startsWith("1.0") ?: false)
if (runtimeUpdateRequired) {
Messages.showErrorDialog(module.project,
"Coroutines support requires version 1.1 or later of the Kotlin runtime library. " +
"Please update the version in your build script.",
ChangeCoroutineSupportFix.getFixText(state))
Messages.showErrorDialog(
module.project,
"Coroutines support requires version 1.1 or later of the Kotlin runtime library. " +
"Please update the version in your build script.",
ChangeCoroutineSupportFix.getFixText(state)
)
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)
KotlinWithGradleConfigurator.addKotlinLibraryToModule(module, scope, library)
}
@@ -255,7 +265,7 @@ abstract class KotlinWithGradleConfigurator : KotlinProjectConfigurator {
private val KOTLIN_BUILD_SCRIPT_NAME = "build.gradle.kts"
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'"
@@ -266,12 +276,12 @@ abstract class KotlinWithGradleConfigurator : KotlinProjectConfigurator {
}
getManipulator(buildScript)
.addKotlinLibraryToModuleBuildScript(scope, libraryDescriptor, module.getBuildSystemType() == AndroidGradle)
.addKotlinLibraryToModuleBuildScript(scope, libraryDescriptor, module.getBuildSystemType() == AndroidGradle)
buildScript.virtualFile?.let {
createConfigureKotlinNotificationCollector(buildScript.project)
.addMessage(it.path + " was modified")
.showNotification()
.addMessage(it.path + " was modified")
.showNotification()
}
}
@@ -280,20 +290,20 @@ abstract class KotlinWithGradleConfigurator : KotlinProjectConfigurator {
}
fun changeLanguageVersion(module: Module, languageVersion: String?, apiVersion: String?, forTests: Boolean) =
changeBuildGradle(module) { buildScriptFile ->
val manipulator = getManipulator(buildScriptFile)
var result: PsiElement? = null
if (languageVersion != null) {
result = manipulator.changeLanguageVersion(languageVersion, forTests)
}
if (apiVersion != null) {
result = manipulator.changeApiVersion(apiVersion, forTests)
}
result
changeBuildGradle(module) { buildScriptFile ->
val manipulator = getManipulator(buildScriptFile)
var result: PsiElement? = null
if (languageVersion != null) {
result = manipulator.changeLanguageVersion(languageVersion, forTests)
}
if (apiVersion != null) {
result = manipulator.changeApiVersion(apiVersion, forTests)
}
result
}
private fun changeBuildGradle(module: Module, body: (PsiFile) -> PsiElement?): PsiElement? {
val buildScriptFile = module.getBuildScriptPsiFile()
if (buildScriptFile != null && canConfigureFile(buildScriptFile)) {
@@ -340,19 +350,21 @@ abstract class KotlinWithGradleConfigurator : KotlinProjectConfigurator {
}
private fun findBuildGradleFile(path: String): File? =
File(path + "/" + GradleConstants.DEFAULT_SCRIPT_NAME).takeIf { it.exists() } ?:
File(path + "/" + KOTLIN_BUILD_SCRIPT_NAME).takeIf { it.exists() }
File(path + "/" + GradleConstants.DEFAULT_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 {
PsiManager.getInstance(project).findFile(it)
}
private fun showErrorMessage(project: Project, message: String?) {
Messages.showErrorDialog(project,
"<html>Couldn't configure kotlin-gradle plugin automatically.<br/>" +
(if (message != null) message + "<br/>" else "") +
"<br/>See manual installation instructions <a href=\"https://kotlinlang.org/docs/reference/using-gradle.html\">here</a>.</html>",
"Configure Kotlin-Gradle Plugin")
Messages.showErrorDialog(
project,
"<html>Couldn't configure kotlin-gradle plugin automatically.<br/>" +
(if (message != null) message + "<br/>" else "") +
"<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
class GradleScriptDefinitionsContributor(private val project: Project): ScriptDefinitionContributor {
class GradleScriptDefinitionsContributor(private val project: Project) : ScriptDefinitionContributor {
override val id: String = "Gradle Kotlin DSL"
private val failedToLoad = AtomicBoolean(false)
@@ -126,16 +126,15 @@ class GradleScriptDefinitionsContributor(private val project: Project): ScriptDe
private fun kotlinStdlibAndCompiler(gradleLibDir: File): List<File> {
// additionally need compiler jar to load gradle resolver
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(
templateClass: String, dependencySelector: Regex,
additionalResolverClasspath: (gradleLibDir: File) -> List<File>
templateClass: String, dependencySelector: Regex,
additionalResolverClasspath: (gradleLibDir: File) -> List<File>
): List<KotlinScriptDefinition> = try {
doLoadGradleTemplates(templateClass, dependencySelector, additionalResolverClasspath)
}
catch (t: Throwable) {
} catch (t: Throwable) {
// TODO: review exception handling
failedToLoad.set(true)
emptyList()
@@ -143,27 +142,27 @@ class GradleScriptDefinitionsContributor(private val project: Project): ScriptDe
private fun doLoadGradleTemplates(
templateClass: String, dependencySelector: Regex,
additionalResolverClasspath: (gradleLibDir: File) -> List<File>
templateClass: String, dependencySelector: Regex,
additionalResolverClasspath: (gradleLibDir: File) -> List<File>
): List<KotlinScriptDefinition> {
fun createEnvironment(gradleExeSettings: GradleExecutionSettings): Environment {
val gradleJvmOptions = gradleExeSettings.daemonVmOptions?.let { vmOptions ->
CommandLineTokenizer(vmOptions).toList()
.mapNotNull { it?.let { it as? String } }
.filterNot(String::isBlank)
.distinct()
.mapNotNull { it?.let { it as? String } }
.filterNot(String::isBlank)
.distinct()
} ?: emptyList()
return mapOf(
"gradleHome" to gradleExeSettings.gradleHome?.let(::File),
"projectRoot" to (project.basePath ?: project.baseDir.canonicalPath)?.let(::File),
"gradleWithConnection" to { action: (ProjectConnection) -> Unit ->
GradleExecutionHelper().execute(project.basePath!!, null) { action(it) }
},
"gradleJavaHome" to gradleExeSettings.javaHome,
"gradleJvmOptions" to gradleJvmOptions,
"getScriptSectionTokens" to ::topLevelSectionCodeTextTokens
"gradleHome" to gradleExeSettings.gradleHome?.let(::File),
"projectRoot" to (project.basePath ?: project.baseDir.canonicalPath)?.let(::File),
"gradleWithConnection" to { action: (ProjectConnection) -> Unit ->
GradleExecutionHelper().execute(project.basePath!!, null) { action(it) }
},
"gradleJavaHome" to gradleExeSettings.javaHome,
"gradleJvmOptions" to gradleJvmOptions,
"getScriptSectionTokens" to ::topLevelSectionCodeTextTokens
)
}
@@ -171,12 +170,14 @@ class GradleScriptDefinitionsContributor(private val project: Project): ScriptDe
val gradleSettings = ExternalSystemApiUtil.getSettings(project, GradleConstants.SYSTEM_ID)
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>(
project,
projectSettings.externalProjectPath,
GradleConstants.SYSTEM_ID)
project,
projectSettings.externalProjectPath,
GradleConstants.SYSTEM_ID
)
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")
return loadDefinitionsFromTemplates(
listOf(templateClass),
templateClasspath,
createEnvironment(gradleExeSettings),
additionalResolverClasspath(gradleLibDir)
listOf(templateClass),
templateClasspath,
createEnvironment(gradleExeSettings),
additionalResolverClasspath(gradleLibDir)
)
}
@@ -268,15 +269,15 @@ class TopLevelSectionTokensEnumerator(script: CharSequence, identifier: String)
}
fun topLevelSectionCodeTextTokens(script: CharSequence, sectionIdentifier: String): Sequence<CharSequence> =
TopLevelSectionTokensEnumerator(script, sectionIdentifier).asSequence()
.filter { it.tokenType !in KtTokens.WHITE_SPACE_OR_COMMENT_BIT_SET }
.map { it.tokenSequence }
TopLevelSectionTokensEnumerator(script, sectionIdentifier).asSequence()
.filter { it.tokenType !in KtTokens.WHITE_SPACE_OR_COMMENT_BIT_SET }
.map { it.tokenSequence }
private const val KOTLIN_BUILD_FILE_SUFFIX = ".gradle.kts"
class GradleScriptDefaultDependenciesProvider(
private val scriptDependenciesCache: ScriptDependenciesCache
private val scriptDependenciesCache: ScriptDependenciesCache
) : DefaultScriptDependenciesProvider {
override fun defaultDependenciesFor(scriptFile: VirtualFile): ScriptDependencies? {
if (!scriptFile.name.endsWith(KOTLIN_BUILD_FILE_SUFFIX)) return null
@@ -285,5 +286,5 @@ class GradleScriptDefaultDependenciesProvider(
}
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.getWholeModuleGroup
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.DeprecatedLibInfo
import org.jetbrains.kotlin.idea.versions.LibInfo
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
import org.jetbrains.plugins.gradle.codeInspection.GradleBaseInspection
import org.jetbrains.plugins.groovy.codeInspection.BaseInspectionVisitor
@@ -60,19 +60,24 @@ class DeprecatedGradleDependencyInspection : GradleBaseInspection() {
if (dependencyText.contains(libMarker)) {
// Should be generified for any library, not exactly Kotlin stdlib
val libVersion =
DifferentStdlibGradleVersionInspection.getResolvedKotlinStdlibVersion(
dependencyStatement.containingFile, listOf(outdatedInfo.old.name)) ?:
libraryVersionFromOrderEntry(dependencyStatement.containingFile, outdatedInfo.old.name)
val libVersion =
DifferentStdlibGradleVersionInspection.getResolvedKotlinStdlibVersion(
dependencyStatement.containingFile, listOf(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)
registerError(
reportOnElement, outdatedInfo.message,
arrayOf(ReplaceStringInDocumentFix(reportOnElement, outdatedInfo.old.name, outdatedInfo.new.name)),
ProblemHighlightType.LIKE_DEPRECATED)
reportOnElement, outdatedInfo.message,
arrayOf(ReplaceStringInDocumentFix(reportOnElement, outdatedInfo.old.name, outdatedInfo.new.name)),
ProblemHighlightType.LIKE_DEPRECATED
)
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.path.GrCallExpression
class DifferentKotlinGradleVersionInspection : GradleBaseInspection(), PluginVersionDependentInspection{
class DifferentKotlinGradleVersionInspection : GradleBaseInspection(), PluginVersionDependentInspection {
override var testVersionMessage: String? = null
@TestOnly set
@@ -58,15 +58,15 @@ class DifferentKotlinGradleVersionInspection : GradleBaseInspection(), PluginVer
} ?: return
val kotlinPluginVersion =
GradleHeuristicHelper.getHeuristicVersionInBuildScriptDependency(kotlinPluginStatement) ?:
getResolvedKotlinGradleVersion(closure.containingFile) ?:
return
GradleHeuristicHelper.getHeuristicVersionInBuildScriptDependency(kotlinPluginStatement) ?: getResolvedKotlinGradleVersion(
closure.containingFile
) ?: return
onFound(kotlinPluginVersion, kotlinPluginStatement)
}
}
private inner class MyVisitor: VersionFinder() {
private inner class MyVisitor : VersionFinder() {
private val idePluginVersion by lazy { bundledRuntimeVersion() }
override fun onFound(kotlinPluginVersion: String, kotlinPluginStatement: GrCallExpression) {
@@ -35,10 +35,11 @@ import java.util.*
class DifferentStdlibGradleVersionInspection : GradleBaseInspection() {
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) =
"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() {
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) {
val gradlePluginVersion = getResolvedKotlinGradleVersion(stdlibStatement.containingFile)
@@ -116,6 +117,6 @@ class DifferentStdlibGradleVersionInspection : GradleBaseInspection() {
internal fun DataNode<*>.getResolvedKotlinStdlibVersionByModuleData(libraryIds: List<String>): String? {
return KotlinGradleModelFacade.EP_NAME.extensions.asSequence()
.mapNotNull { it.getResolvedKotlinStdlibVersionByModuleData(this, libraryIds) }
.firstOrNull()
.mapNotNull { it.getResolvedKotlinStdlibVersionByModuleData(this, libraryIds) }
.firstOrNull()
}
@@ -32,16 +32,16 @@ import java.util.*
object GradleHeuristicHelper {
fun getHeuristicVersionInBuildScriptDependency(classpathStatement: GrCallExpression): String? {
val argumentList = when (classpathStatement) {
is GrMethodCall -> classpathStatement.argumentList // classpath('argument')
else -> classpathStatement.getChildrenOfType<GrCommandArgumentList>().singleOrNull() // classpath 'argument'
} ?: return null
is GrMethodCall -> classpathStatement.argumentList // classpath('argument')
else -> classpathStatement.getChildrenOfType<GrCommandArgumentList>().singleOrNull() // classpath 'argument'
} ?: return null
val grLiteral = argumentList.children.firstOrNull() as? GrLiteral ?: return null
if (grLiteral is GrString && grLiteral.injections.size == 1) {
val versionInjection = grLiteral.injections.first() ?: return null
val expression = versionInjection.expression as? GrReferenceExpression ?: // $some_variable
versionInjection.closableBlock?.getChildrenOfType<GrReferenceExpression>()?.singleOrNull() ?: // ${some_variable}
return null
versionInjection.closableBlock?.getChildrenOfType<GrReferenceExpression>()?.singleOrNull() ?: // ${some_variable}
return null
return resolveVariableInBuildScript(classpathStatement, expression.text)
}
@@ -45,7 +45,7 @@ abstract class KotlinGradleInspectionVisitor : BaseInspectionVisitor() {
}
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? {
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>
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? {
for (classPathEntry in classpathData.classpathEntries.asReversed()) {
@@ -78,7 +78,8 @@ internal fun findKotlinPluginVersion(classpathData: BuildScriptClasspathData): S
return versionSubstring
}
} 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>") {
return versionSubstring
}
@@ -91,7 +92,7 @@ internal fun findKotlinPluginVersion(classpathData: BuildScriptClasspathData): S
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)
return nodes.mapNotNull {
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) =
ModuleUtilCore.findModuleForFile(file.virtualFile, file.project)?.let { findGradleProjectStructure(it) }
ModuleUtilCore.findModuleForFile(file.virtualFile, file.project)?.let { findGradleProjectStructure(it) }
fun findGradleProjectStructure(module: Module): DataNode<ProjectData>? {
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>> {
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)
}
}
@@ -64,7 +65,11 @@ fun getDependencyModules(moduleData: DataNode<ModuleData>, gradleIdeaProject: Id
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)
return modules.filterTo(LinkedHashSet()) { it.data.externalName in dependencyModuleNames }
}
@@ -31,9 +31,11 @@ import org.jetbrains.plugins.gradle.util.GradleConstants
class KotlinTestClassGradleConfigurationProducer : TestClassGradleConfigurationProducer() {
override fun doSetupConfigurationFromContext(configuration: ExternalSystemRunConfiguration,
context: ConfigurationContext,
sourceElement: Ref<PsiElement>): Boolean {
override fun doSetupConfigurationFromContext(
configuration: ExternalSystemRunConfiguration,
context: ConfigurationContext,
sourceElement: Ref<PsiElement>
): Boolean {
val contextLocation = context.location ?: return false
val module = context.module ?: return false
@@ -93,9 +95,11 @@ class KotlinTestClassGradleConfigurationProducer : TestClassGradleConfigurationP
class KotlinTestMethodGradleConfigurationProducer
: TestMethodGradleConfigurationProducer() {
override fun doSetupConfigurationFromContext(configuration: ExternalSystemRunConfiguration,
context: ConfigurationContext,
sourceElement: Ref<PsiElement>): Boolean {
override fun doSetupConfigurationFromContext(
configuration: ExternalSystemRunConfiguration,
context: ConfigurationContext,
sourceElement: Ref<PsiElement>
): Boolean {
val contextLocation = context.location ?: return false
if (context.module == null) return false
@@ -142,10 +146,12 @@ class KotlinTestMethodGradleConfigurationProducer
return scriptParameters.contains(testFilter!!)
}
private fun applyTestMethodConfiguration(configuration: ExternalSystemRunConfiguration,
context: ConfigurationContext,
psiMethod: PsiMethod,
vararg containingClasses: PsiClass): Boolean {
private fun applyTestMethodConfiguration(
configuration: ExternalSystemRunConfiguration,
context: ConfigurationContext,
psiMethod: PsiMethod,
vararg containingClasses: PsiClass
): Boolean {
val module = context.module ?: return false
if (!ExternalSystemApiUtil.isExternalSystemAwareModule(GradleConstants.SYSTEM_ID, module)) return false
@@ -48,24 +48,23 @@ import kotlin.concurrent.getOrSet
class MultiplatformGradleProjectTaskRunner : GradleProjectTaskRunner() {
override fun canRun(projectTask: ProjectTask) =
when (projectTask) {
is ModuleBuildTask ->
projectTask.module.isMultiplatformModule()
when (projectTask) {
is ModuleBuildTask ->
projectTask.module.isMultiplatformModule()
is ExecuteRunConfigurationTask -> {
val runProfile = projectTask.runProfile
if (runProfile is ModuleBasedConfiguration<*>) {
runProfile.configurationModule.module?.isMultiplatformModule() == true
}
else {
false
}
is ExecuteRunConfigurationTask -> {
val runProfile = projectTask.runProfile
if (runProfile is ModuleBasedConfiguration<*>) {
runProfile.configurationModule.module?.isMultiplatformModule() == true
} else {
false
}
else -> false
}
else -> false
}
override fun run(
project: Project,
context: ProjectTaskContext,
@@ -74,7 +73,8 @@ class MultiplatformGradleProjectTaskRunner : GradleProjectTaskRunner() {
) {
val configuration = context.runConfiguration
if (configuration is ModuleBasedConfiguration<*> &&
(configuration.configurationModule is JavaRunConfigurationModule || configuration is KotlinRunConfiguration)) {
(configuration.configurationModule is JavaRunConfigurationModule || configuration is KotlinRunConfiguration)
) {
val module = configuration.configurationModule.module
if (module?.targetPlatform == TargetPlatformKind.Common) {
@@ -91,21 +91,28 @@ class MultiplatformGradleProjectTaskRunner : GradleProjectTaskRunner() {
}
private fun ProjectTask.replaceModule(origin: Module, replacement: Module): ProjectTask =
when (this) {
is ModuleFilesBuildTask -> this
when (this) {
is ModuleFilesBuildTask -> this
is ModuleBuildTask ->
if (module == origin)
ModuleBuildTaskImpl(replacement, isIncrementalBuild, isIncludeDependentModules, isIncludeRuntimeDependencies)
else
this
is ModuleBuildTask ->
if (module == origin)
ModuleBuildTaskImpl(replacement, isIncrementalBuild, isIncludeDependentModules, isIncludeRuntimeDependencies)
else
this
else -> this
}
else -> this
}
}
class MultiplatformGradleOrderEnumeratorHandler(val factory: MultiplatformGradleOrderEnumeratorHandler.FactoryImpl) : OrderEnumerationHandler() {
override fun addCustomModuleRoots(type: OrderRootType, rootModel: ModuleRootModel, result: MutableCollection<String>, includeProduction: Boolean, includeTests: Boolean): Boolean {
class MultiplatformGradleOrderEnumeratorHandler(val factory: MultiplatformGradleOrderEnumeratorHandler.FactoryImpl) :
OrderEnumerationHandler() {
override fun addCustomModuleRoots(
type: OrderRootType,
rootModel: ModuleRootModel,
result: MutableCollection<String>,
includeProduction: Boolean,
includeTests: Boolean
): Boolean {
if (factory.isEnumerating(rootModel.module)) return false
factory.startEnumerating(rootModel.module)
try {
@@ -113,10 +120,13 @@ class MultiplatformGradleOrderEnumeratorHandler(val factory: MultiplatformGradle
if (!ExternalSystemApiUtil.isExternalSystemAwareModule(GradleConstants.SYSTEM_ID, rootModel.module)) return false
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 externalRootProject = externalProjectDataCache.getRootExternalProject(GradleConstants.SYSTEM_ID,
File(gradleProjectPath)) ?: return false
val externalRootProject = externalProjectDataCache.getRootExternalProject(
GradleConstants.SYSTEM_ID,
File(gradleProjectPath)
) ?: return false
val externalSourceSets = externalProjectDataCache.findExternalProject(externalRootProject, rootModel.module)
@@ -132,12 +142,12 @@ class MultiplatformGradleOrderEnumeratorHandler(val factory: MultiplatformGradle
val implModule = rootModel.module.findJvmImplementationModule()
implModule
?.rootManager
?.orderEntries()
?.satisfying { orderEntry -> (orderEntry as? ModuleOrderEntry)?.module != rootModel.module }
?.compileOnly()
?.classesRoots
?.mapTo(result) { it.url }
?.rootManager
?.orderEntries()
?.satisfying { orderEntry -> (orderEntry as? ModuleOrderEntry)?.module != rootModel.module }
?.compileOnly()
?.classesRoots
?.mapTo(result) { it.url }
} finally {
factory.doneEnumerating(rootModel.module)
@@ -164,8 +174,8 @@ class MultiplatformGradleOrderEnumeratorHandler(val factory: MultiplatformGradle
override fun isApplicable(module: Module): Boolean {
return ExternalSystemApiUtil.isExternalSystemAwareModule(GradleConstants.SYSTEM_ID, module) &&
module.isMultiplatformModule() &&
!isEnumerating(module)
module.isMultiplatformModule() &&
!isEnumerating(module)
}
override fun createHandler(module: Module): OrderEnumerationHandler =
@@ -31,7 +31,8 @@ class MultiplatformProjectImportingTest : GradleImportingTestCase() {
val kotlinVersion = "1.1.0"
createProjectSubFile("build.gradle", """
createProjectSubFile(
"build.gradle", """
buildscript {
repositories {
mavenCentral()
@@ -61,7 +62,8 @@ class MultiplatformProjectImportingTest : GradleImportingTestCase() {
implement project(':common')
}
}
""")
"""
)
importProject()
assertModuleModuleDepScope("jvm_main", "common_main", DependencyScope.COMPILE)
@@ -76,7 +78,8 @@ class MultiplatformProjectImportingTest : GradleImportingTestCase() {
val kotlinVersion = "1.2.40-dev-610"
createProjectSubFile("build.gradle", """
createProjectSubFile(
"build.gradle", """
buildscript {
repositories {
mavenCentral()
@@ -112,7 +115,8 @@ class MultiplatformProjectImportingTest : GradleImportingTestCase() {
expectedBy project(':common1')
}
}
""")
"""
)
importProject()
assertModuleModuleDepScope("jvm_main", "common1_main", DependencyScope.COMPILE)
@@ -131,7 +135,8 @@ class MultiplatformProjectImportingTest : GradleImportingTestCase() {
val kotlinVersion = "1.2.0-beta-74"
createProjectSubFile("toInclude/build.gradle", """
createProjectSubFile(
"toInclude/build.gradle", """
buildscript {
repositories {
mavenCentral()
@@ -162,10 +167,12 @@ class MultiplatformProjectImportingTest : GradleImportingTestCase() {
expectedBy project(':common')
}
}
""")
"""
)
createProjectSubFile("settings.gradle", "includeBuild('toInclude')")
createProjectSubFile("build.gradle", """
createProjectSubFile(
"build.gradle", """
buildscript {
repositories {
mavenCentral()
@@ -178,7 +185,8 @@ class MultiplatformProjectImportingTest : GradleImportingTestCase() {
}
apply plugin: 'kotlin'
""".trimIndent())
""".trimIndent()
)
importProject()
assertModuleModuleDepScope("jvm_main", "common_main", DependencyScope.COMPILE)
@@ -193,7 +201,8 @@ class MultiplatformProjectImportingTest : GradleImportingTestCase() {
val kotlinVersion = "1.1.0"
createProjectSubFile("build.gradle", """
createProjectSubFile(
"build.gradle", """
buildscript {
repositories {
mavenCentral()
@@ -221,7 +230,8 @@ class MultiplatformProjectImportingTest : GradleImportingTestCase() {
implement project(':')
}
}
""")
"""
)
importProject()
assertModuleModuleDepScope("jvm_main", "foo_main", DependencyScope.COMPILE)
@@ -236,7 +246,8 @@ class MultiplatformProjectImportingTest : GradleImportingTestCase() {
val kotlinVersion = "1.1.0"
createProjectSubFile("build.gradle", """
createProjectSubFile(
"build.gradle", """
buildscript {
repositories {
mavenCentral()
@@ -292,7 +303,8 @@ class MultiplatformProjectImportingTest : GradleImportingTestCase() {
compile project(':js-lib')
}
}
""")
"""
)
importProject()
@@ -308,13 +320,14 @@ class MultiplatformProjectImportingTest : GradleImportingTestCase() {
@Test
fun testDependenciesReachableViaImpl() {
createProjectSubFile(
"settings.gradle",
"include ':common-lib1', ':common-lib2', ':jvm-lib1', ':jvm-lib2', ':jvm-app'"
"settings.gradle",
"include ':common-lib1', ':common-lib2', ':jvm-lib1', ':jvm-lib2', ':jvm-app'"
)
val kotlinVersion = "1.1.0"
createProjectSubFile("build.gradle", """
createProjectSubFile(
"build.gradle", """
buildscript {
repositories {
mavenCentral()
@@ -357,7 +370,8 @@ class MultiplatformProjectImportingTest : GradleImportingTestCase() {
compile project(':jvm-lib2')
}
}
""")
"""
)
importProject()
@@ -375,13 +389,14 @@ class MultiplatformProjectImportingTest : GradleImportingTestCase() {
@Test
fun testTransitiveImplement() {
createProjectSubFile(
"settings.gradle",
"include ':project1', ':project2', ':project3'"
"settings.gradle",
"include ':project1', ':project2', ':project3'"
)
val kotlinVersion = "1.1.51"
createProjectSubFile("build.gradle", """
createProjectSubFile(
"build.gradle", """
buildscript {
repositories {
mavenCentral()
@@ -434,7 +449,8 @@ class MultiplatformProjectImportingTest : GradleImportingTestCase() {
testCompile(project(':project2').sourceSets.test.output)
}
}
""")
"""
)
val isResolveModulePerSourceSet = getCurrentExternalProjectSettings().isResolveModulePerSourceSet
@@ -478,13 +494,14 @@ class MultiplatformProjectImportingTest : GradleImportingTestCase() {
@Test
fun testTransitiveImplementWithAndroid() {
createProjectSubFile(
"settings.gradle",
"include ':project1', ':project2', ':project3'"
"settings.gradle",
"include ':project1', ':project2', ':project3'"
)
val kotlinVersion = "1.1.51"
createProjectSubFile("build.gradle", """
createProjectSubFile(
"build.gradle", """
buildscript {
repositories {
jcenter()
@@ -552,10 +569,13 @@ class MultiplatformProjectImportingTest : GradleImportingTestCase() {
testCompile(project(':project2').sourceSets.test.output)
}
}
""")
createProjectSubFile("local.properties", """
"""
)
createProjectSubFile(
"local.properties", """
sdk.dir=/${KotlinTestUtils.getAndroidSdkSystemIndependentPath()}
""")
"""
)
importProject()
@@ -568,13 +588,14 @@ class MultiplatformProjectImportingTest : GradleImportingTestCase() {
@Test
fun testJsTestOutputFile() {
createProjectSubFile(
"settings.gradle",
"include ':project1', ':project2', ':project3'"
"settings.gradle",
"include ':project1', ':project2', ':project3'"
)
val kotlinVersion = "1.1.51"
createProjectSubFile("build.gradle", """
createProjectSubFile(
"build.gradle", """
buildscript {
repositories {
jcenter()
@@ -602,30 +623,32 @@ class MultiplatformProjectImportingTest : GradleImportingTestCase() {
implement project(':project1')
}
}
""")
"""
)
importProject()
TestCase.assertEquals(
projectPath + "/project2/build/classes/test/project2_test.js",
PathUtil.toSystemIndependentName(KotlinFacet.get (getModule("project2_main"))!!.configuration.settings.testOutputPath)
projectPath + "/project2/build/classes/test/project2_test.js",
PathUtil.toSystemIndependentName(KotlinFacet.get(getModule("project2_main"))!!.configuration.settings.testOutputPath)
)
TestCase.assertEquals(
projectPath + "/project2/build/classes/test/project2_test.js",
PathUtil.toSystemIndependentName(KotlinFacet.get (getModule("project2_test"))!!.configuration.settings.testOutputPath)
projectPath + "/project2/build/classes/test/project2_test.js",
PathUtil.toSystemIndependentName(KotlinFacet.get(getModule("project2_test"))!!.configuration.settings.testOutputPath)
)
}
@Test
fun testJsProductionOutputFile() {
createProjectSubFile(
"settings.gradle",
"include ':project1', ':project2', ':project3'"
"settings.gradle",
"include ':project1', ':project2', ':project3'"
)
val kotlinVersion = "1.1.51"
createProjectSubFile("build.gradle", """
createProjectSubFile(
"build.gradle", """
buildscript {
repositories {
jcenter()
@@ -653,30 +676,32 @@ class MultiplatformProjectImportingTest : GradleImportingTestCase() {
implement project(':project1')
}
}
""")
"""
)
importProject()
TestCase.assertEquals(
projectPath + "/project2/build/classes/main/project2.js",
PathUtil.toSystemIndependentName(KotlinFacet.get (getModule("project2_main"))!!.configuration.settings.productionOutputPath)
projectPath + "/project2/build/classes/main/project2.js",
PathUtil.toSystemIndependentName(KotlinFacet.get(getModule("project2_main"))!!.configuration.settings.productionOutputPath)
)
TestCase.assertEquals(
projectPath + "/project2/build/classes/main/project2.js",
PathUtil.toSystemIndependentName(KotlinFacet.get (getModule("project2_test"))!!.configuration.settings.productionOutputPath)
projectPath + "/project2/build/classes/main/project2.js",
PathUtil.toSystemIndependentName(KotlinFacet.get(getModule("project2_test"))!!.configuration.settings.productionOutputPath)
)
}
@Test
fun testJsTestOutputFileInProjectWithAndroid() {
createProjectSubFile(
"settings.gradle",
"include ':project1', ':project2', ':project3'"
"settings.gradle",
"include ':project1', ':project2', ':project3'"
)
val kotlinVersion = "1.1.51"
createProjectSubFile("build.gradle", """
createProjectSubFile(
"build.gradle", """
buildscript {
repositories {
jcenter()
@@ -730,16 +755,19 @@ class MultiplatformProjectImportingTest : GradleImportingTestCase() {
}
}
}
""")
createProjectSubFile("local.properties", """
"""
)
createProjectSubFile(
"local.properties", """
sdk.dir=/${KotlinTestUtils.getAndroidSdkSystemIndependentPath()}
""")
"""
)
importProject()
TestCase.assertEquals(
projectPath + "/project2/build/classes/test/project2_test.js",
PathUtil.toSystemIndependentName(KotlinFacet.get (getModule("project2"))!!.configuration.settings.testOutputPath)
projectPath + "/project2/build/classes/test/project2_test.js",
PathUtil.toSystemIndependentName(KotlinFacet.get(getModule("project2"))!!.configuration.settings.testOutputPath)
)
}
}
@@ -60,196 +60,202 @@ import static org.junit.Assume.assumeThat;
@RunWith(value = Parameterized.class)
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
private final String gradleVersion;
private File testDir;
private ProjectImportAction.AllModels allModels;
@NotNull
private final String gradleVersion;
private File testDir;
private ProjectImportAction.AllModels allModels;
@Rule public TestName name = new TestName();
@Rule public VersionMatcherRule versionMatcherRule = new VersionMatcherRule();
@Rule public TestName name = new TestName();
@Rule public VersionMatcherRule versionMatcherRule = new VersionMatcherRule();
public AbstractModelBuilderTest(@NotNull String 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);
public AbstractModelBuilderTest(@NotNull String gradleVersion) {
this.gradleVersion = gradleVersion;
}
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);
@Parameterized.Parameters(name = "{index}: with Gradle-{0}")
public static Collection<Object[]> data() {
return Arrays.asList(SUPPORTED_GRADLE_VERSIONS);
}
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)
@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);
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();
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;
ContainerUtil.addAllNotNull(classes, doGetToolingExtensionClasses());
return classes;
}
@NotNull
public URI getDistributionFor(@NotNull GradleVersion version) throws URISyntaxException {
return getDistribution(getDistributionRepository(version), version, "gradle", "bin");
private static Set<Class> doGetToolingExtensionClasses() {
return Collections.emptySet();
}
@NotNull
private String getDistributionRepository(@NotNull GradleVersion version) {
return version.isSnapshot() ? mySnapshotRepoUrl : myReleaseRepoUrl;
@After
public void tearDown() throws Exception {
if (testDir != null) {
FileUtil.delete(testDir);
}
}
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));
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;
}
@NotNull
public static String getRepoUrl(boolean isSnapshotUrl) {
String envRepoUrl = System.getenv(isSnapshotUrl ? SNAPSHOT_REPOSITORY_ENV : RELEASE_REPOSITORY_ENV);
if (envRepoUrl != null) return envRepoUrl;
private static void ensureTempDirCreated() throws IOException {
if (ourTempDir != null) return;
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
public abstract class ExternalSystemImportingTestCase extends ExternalSystemTestCase {
@Override
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;
@Override
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();
}
}
finally {
accessToken.finish();
protected void importProject(@NonNls String config) throws IOException {
createProjectConfig(config);
importProject();
}
}
protected void importProject(@NonNls String config) throws IOException {
createProjectConfig(config);
importProject();
}
protected void importProject() {
doImportProject();
}
protected void importProject() {
doImportProject();
}
private void 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() {
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);
final Ref<Couple<String>> error = Ref.create();
ExternalSystemUtil.refreshProjects(
new ImportSpecBuilder(myProject, getExternalSystemId())
.use(ProgressExecutionMode.MODAL_SYNC)
.callback(new ExternalProjectRefreshCallback() {
@Override
public void onSuccess(@Nullable DataNode<ProjectData> externalProject) {
if (externalProject == null) {
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();
ExternalSystemUtil.refreshProjects(
new ImportSpecBuilder(myProject, getExternalSystemId())
.use(ProgressExecutionMode.MODAL_SYNC)
.callback(new ExternalProjectRefreshCallback() {
@Override
public void onSuccess(@Nullable DataNode<ProjectData> externalProject) {
if (externalProject == null) {
System.err.println("Got null External project after import");
return;
@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;
}
ServiceManager.getService(ProjectDataManager.class).importData(externalProject, myProject, true);
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);
}
fail(failureMsg);
}
}
return deps;
}
protected abstract ExternalProjectSettings getCurrentExternalProjectSettings();
private List<String> collectModuleDepsNames(String moduleName, Class clazz) {
List<String> actual = new ArrayList<String>();
protected abstract ProjectSystemId getExternalSystemId();
for (OrderEntry e : getRootManager(moduleName).getOrderEntries()) {
if (clazz.isInstance(e)) {
actual.add(e.getPresentableName());
}
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;
}
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
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 VirtualFile myProjectRoot;
private final List<VirtualFile> myAllConfigs = new ArrayList<VirtualFile>();
private File myTestDir;
private VirtualFile myProjectRoot;
private final List<VirtualFile> myAllConfigs = new ArrayList<VirtualFile>();
@Before
@Override
public void setUp() throws Exception {
super.setUp();
ensureTempDirCreated();
@Before
@Override
public void setUp() throws Exception {
super.setUp();
ensureTempDirCreated();
myTestDir = new File(ourTempDir, getTestName(false));
FileUtil.ensureExists(myTestDir);
myTestDir = new File(ourTempDir, getTestName(false));
FileUtil.ensureExists(myTestDir);
setUpFixtures();
myProject = myTestFixture.getProject();
setUpFixtures();
myProject = myTestFixture.getProject();
invokeTestRunnable(new Runnable() {
@Override
public void run() {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
try {
setUpInWriteAction();
invokeTestRunnable(new Runnable() {
@Override
public void run() {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
try {
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>();
collectAllowedRoots(allowedRoots);
if (!allowedRoots.isEmpty()) {
VfsRootAccess.allowRootAccess(getTestRootDisposable(), ArrayUtil.toStringArray(allowedRoots));
List<String> allowedRoots = new ArrayList<String>();
collectAllowedRoots(allowedRoots);
if (!allowedRoots.isEmpty()) {
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) {
final List<String> roots = ContainerUtil.newSmartList();
roots.add(root);
FileUtil.processFilesRecursively(new File(root), new Processor<File>() {
@Override
public boolean process(File file) {
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 {
String path = file.getCanonicalPath();
if (!FileUtil.isAncestor(path, path, false)) {
roots.add(path);
}
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();
}
}
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();
resetClassFields(getClass());
protected void tearDownFixtures() throws Exception {
myTestFixture.tearDown();
myTestFixture = null;
}
}
protected void tearDownFixtures() throws Exception {
myTestFixture.tearDown();
myTestFixture = null;
}
private void resetClassFields(Class<?> aClass) {
if (aClass == null) return;
private void resetClassFields(Class<?> aClass) {
if (aClass == null) return;
Field[] fields = aClass.getDeclaredFields();
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();
for (Field field : fields) {
final int modifiers = field.getModifiers();
if ((modifiers & Modifier.FINAL) == 0
&& (modifiers & Modifier.STATIC) == 0
&& !field.getType().isPrimitive()) {
field.setAccessible(true);
if (aClass == ExternalSystemTestCase.class) return;
resetClassFields(aClass.getSuperclass());
}
@Override
protected void runTest() throws Throwable {
try {
field.set(this, null);
super.runTest();
}
catch (IllegalAccessException e) {
e.printStackTrace();
catch (Exception throwable) {
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;
resetClassFields(aClass.getSuperclass());
}
@Override
protected void runTest() throws Throwable {
try {
super.runTest();
@Override
protected void invokeTestRunnable(@NotNull Runnable runnable) throws Exception {
runInEdtAndWait(runnable);
}
catch (Exception throwable) {
Throwable each = throwable;
do {
if (each instanceof HeadlessException) {
printIgnoredMessage("Doesn't work in Headless environment");
return;
protected static String getRoot() {
if (SystemInfo.isWindows) return "c:";
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);
}
}
while ((each = each.getCause()) != null);
throw throwable;
setFileContent(f, config, true);
return f;
}
}
@Override
protected void invokeTestRunnable(@NotNull Runnable runnable) throws Exception {
runInEdtAndWait(runnable);
}
protected abstract String getExternalSystemConfigFileName();
protected static String getRoot() {
if (SystemInfo.isWindows) return "c:";
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);
protected VirtualFile createProjectSubFile(String relativePath) throws IOException {
File f = new File(getProjectPath(), relativePath);
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());
}
}.execute().getResultObject();
myAllConfigs.add(f);
return LocalFileSystem.getInstance().refreshAndFindFileByIoFile(f);
}
setFileContent(f, config, true);
return f;
}
protected abstract String getExternalSystemConfigFileName();
protected VirtualFile createProjectSubFile(String relativePath) throws IOException {
File f = new File(getProjectPath(), relativePath);
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());
protected VirtualFile createProjectSubFile(String relativePath, String content) throws IOException {
VirtualFile file = createProjectSubFile(relativePath);
setFileContent(file, content, false);
return file;
}
return LocalFileSystem.getInstance().refreshAndFindFileByIoFile(f);
}
protected VirtualFile createProjectSubFile(String relativePath, String content) throws IOException {
VirtualFile file = createProjectSubFile(relativePath);
setFileContent(file, content, false);
return file;
}
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);
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;
}
else {
file.setBinaryContent(content.getBytes(CharsetToolkit.UTF8_CHARSET), file.getModificationStamp(), file.getTimeStamp());
finally {
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
fun testProjectWithModule() {
createProjectSubFile("settings.gradle", "include ':app'")
createProjectSubFile("app/build.gradle", """
createProjectSubFile(
"app/build.gradle", """
buildscript {
repositories {
jcenter()
@@ -39,7 +40,8 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-0.0" // intentionally invalid version
}
""".trimIndent())
""".trimIndent()
)
importProject()
@@ -62,14 +64,16 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
@Test
fun testConfigure10() {
createProjectSubFile("settings.gradle", "include ':app'")
val file = createProjectSubFile("app/build.gradle", """
val file = createProjectSubFile(
"app/build.gradle", """
buildscript {
repositories {
jcenter()
mavenCentral()
}
}
""".trimIndent())
""".trimIndent()
)
importProject()
@@ -82,7 +86,8 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
FileDocumentManager.getInstance().saveAllDocuments()
val content = LoadTextUtil.loadText(file).toString()
assertEquals("""
assertEquals(
"""
buildscript {
ext.kotlin_version = '1.0.6'
repositories {
@@ -100,28 +105,35 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib:${"$"}kotlin_version"
}
""".trimIndent(), content)
""".trimIndent(), content
)
}
}
}
private fun findGradleModuleConfigurator() = Extensions.findExtension(KotlinProjectConfigurator.EP_NAME,
KotlinGradleModuleConfigurator::class.java)
private fun findGradleModuleConfigurator() = Extensions.findExtension(
KotlinProjectConfigurator.EP_NAME,
KotlinGradleModuleConfigurator::class.java
)
private fun findJsGradleModuleConfigurator() = Extensions.findExtension(KotlinProjectConfigurator.EP_NAME,
KotlinJsGradleModuleConfigurator::class.java)
private fun findJsGradleModuleConfigurator() = Extensions.findExtension(
KotlinProjectConfigurator.EP_NAME,
KotlinJsGradleModuleConfigurator::class.java
)
@Test
fun testConfigureGSK() {
createProjectSubFile("settings.gradle", "include ':app'")
val file = createProjectSubFile("app/build.gradle.kts", """
val file = createProjectSubFile(
"app/build.gradle.kts", """
buildscript {
repositories {
jcenter()
mavenCentral()
}
}
""".trimIndent())
""".trimIndent()
)
importProject()
@@ -134,7 +146,8 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
FileDocumentManager.getInstance().saveAllDocuments()
val content = LoadTextUtil.loadText(file).toString()
assertEquals("""
assertEquals(
"""
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
val kotlin_version: String by extra
@@ -166,7 +179,8 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
compileTestKotlin.kotlinOptions {
jvmTarget = "1.8"
}
""".trimIndent(), content)
""".trimIndent(), content
)
}
}
}
@@ -174,7 +188,8 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
@Test
fun testListNonConfiguredModules() {
createProjectSubFile("settings.gradle", "include ':app'")
createProjectSubFile("app/build.gradle", """
createProjectSubFile(
"app/build.gradle", """
buildscript {
repositories {
jcenter()
@@ -183,7 +198,8 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
}
apply plugin: 'java'
""".trimIndent())
""".trimIndent()
)
createProjectSubFile("app/src/main/java/foo.kt", "")
importProject()
@@ -208,7 +224,8 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
@Test
fun testListNonConfiguredModules_Configured() {
createProjectSubFile("settings.gradle", "include ':app'")
createProjectSubFile("app/build.gradle", """
createProjectSubFile(
"app/build.gradle", """
buildscript {
repositories {
jcenter()
@@ -226,7 +243,8 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib:1.1.3"
}
""".trimIndent())
""".trimIndent()
)
createProjectSubFile("app/src/main/java/foo.kt", "")
importProject()
@@ -239,7 +257,8 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
@Test
fun testListNonConfiguredModules_ConfiguredOnlyTest() {
createProjectSubFile("settings.gradle", "include ':app'")
createProjectSubFile("app/build.gradle", """
createProjectSubFile(
"app/build.gradle", """
buildscript {
repositories {
jcenter()
@@ -257,7 +276,8 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
dependencies {
testCompile "org.jetbrains.kotlin:kotlin-stdlib:1.1.3"
}
""".trimIndent())
""".trimIndent()
)
createProjectSubFile("app/src/test/java/foo.kt", "")
importProject()
@@ -269,50 +289,55 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
@Test
fun testAddNonKotlinLibraryGSK() {
val buildScript = createProjectSubFile("build.gradle.kts",
"""
val buildScript = createProjectSubFile(
"build.gradle.kts",
"""
|dependencies {
| testCompile("junit:junit:4.12")
| compile(kotlinModule("stdlib-jre8"))
|}
|""".trimMargin("|"))
|""".trimMargin("|")
)
importProject()
runInEdtAndWait {
myTestFixture.project.executeWriteCommand("") {
KotlinWithGradleConfigurator.addKotlinLibraryToModule(
myTestFixture.module,
DependencyScope.COMPILE,
object: ExternalLibraryDescriptor("org.a.b", "lib", "1.0.0", "1.0.0") {
override fun getLibraryClassesRoots() = emptyList<String>()
})
myTestFixture.module,
DependencyScope.COMPILE,
object : ExternalLibraryDescriptor("org.a.b", "lib", "1.0.0", "1.0.0") {
override fun getLibraryClassesRoots() = emptyList<String>()
})
}
FileDocumentManager.getInstance().saveAllDocuments()
}
assertEquals(
"""
"""
|dependencies {
| testCompile("junit:junit:4.12")
| compile(kotlinModule("stdlib-jre8"))
| compile("org.a.b:lib:1.0.0")
|}
|""".trimMargin("|"),
LoadTextUtil.loadText(buildScript).toString())
LoadTextUtil.loadText(buildScript).toString()
)
}
@Test
fun testAddLibraryGSK_WithKotlinVersion() {
val buildScript = createProjectSubFile("build.gradle.kts",
"""
val buildScript = createProjectSubFile(
"build.gradle.kts",
"""
|val kotlin_version: String by extra
|dependencies {
| testCompile("junit:junit:4.12")
| compile(kotlinModule("stdlib-jre8", kotlin_version))
|}
|""".trimMargin("|"))
|""".trimMargin("|")
)
importProject()
@@ -320,18 +345,18 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
myTestFixture.project.executeWriteCommand("") {
val stdLibVersion = KotlinWithGradleConfigurator.getKotlinStdlibVersion(myTestFixture.module)
KotlinWithGradleConfigurator.addKotlinLibraryToModule(
myTestFixture.module,
DependencyScope.COMPILE,
object : ExternalLibraryDescriptor("org.jetbrains.kotlin", "kotlin-reflect", stdLibVersion, stdLibVersion) {
override fun getLibraryClassesRoots() = emptyList<String>()
})
myTestFixture.module,
DependencyScope.COMPILE,
object : ExternalLibraryDescriptor("org.jetbrains.kotlin", "kotlin-reflect", stdLibVersion, stdLibVersion) {
override fun getLibraryClassesRoots() = emptyList<String>()
})
}
FileDocumentManager.getInstance().saveAllDocuments()
}
assertEquals(
"""
"""
|val kotlin_version: String by extra
|dependencies {
| testCompile("junit:junit:4.12")
@@ -339,90 +364,98 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
| compile(kotlinModule("reflect", kotlin_version))
|}
|""".trimMargin("|"),
LoadTextUtil.loadText(buildScript).toString())
LoadTextUtil.loadText(buildScript).toString()
)
}
@Test
fun testAddTestLibraryGSK() {
val buildScript = createProjectSubFile("build.gradle.kts",
"""
val buildScript = createProjectSubFile(
"build.gradle.kts",
"""
|dependencies {
| compile(kotlinModule("stdlib-jre8"))
|}
|""".trimMargin("|"))
|""".trimMargin("|")
)
importProject()
runInEdtAndWait {
myTestFixture.project.executeWriteCommand("") {
KotlinWithGradleConfigurator.addKotlinLibraryToModule(
myTestFixture.module,
DependencyScope.TEST,
object : ExternalLibraryDescriptor("junit", "junit", "4.12", "4.12") {
override fun getLibraryClassesRoots() = emptyList<String>()
})
myTestFixture.module,
DependencyScope.TEST,
object : ExternalLibraryDescriptor("junit", "junit", "4.12", "4.12") {
override fun getLibraryClassesRoots() = emptyList<String>()
})
KotlinWithGradleConfigurator.addKotlinLibraryToModule(
myTestFixture.module,
DependencyScope.TEST,
object : ExternalLibraryDescriptor("org.jetbrains.kotlin", "kotlin-test", "1.1.2", "1.1.2") {
override fun getLibraryClassesRoots() = emptyList<String>()
})
myTestFixture.module,
DependencyScope.TEST,
object : ExternalLibraryDescriptor("org.jetbrains.kotlin", "kotlin-test", "1.1.2", "1.1.2") {
override fun getLibraryClassesRoots() = emptyList<String>()
})
}
FileDocumentManager.getInstance().saveAllDocuments()
}
assertEquals(
"""
"""
|dependencies {
| compile(kotlinModule("stdlib-jre8"))
| testCompile("junit:junit:4.12")
| testCompile(kotlinModule("test", "1.1.2"))
|}
|""".trimMargin("|"),
LoadTextUtil.loadText(buildScript).toString())
LoadTextUtil.loadText(buildScript).toString()
)
}
@Test
fun testAddLibraryGSK() {
val buildScript = createProjectSubFile("build.gradle.kts",
"""
val buildScript = createProjectSubFile(
"build.gradle.kts",
"""
|dependencies {
| testCompile("junit:junit:4.12")
| compile(kotlinModule("stdlib-jre8"))
|}
|""".trimMargin("|"))
|""".trimMargin("|")
)
importProject()
runInEdtAndWait {
myTestFixture.project.executeWriteCommand("") {
KotlinWithGradleConfigurator.addKotlinLibraryToModule(
myTestFixture.module,
DependencyScope.COMPILE,
object: ExternalLibraryDescriptor("org.jetbrains.kotlin", "kotlin-reflect", "1.0.0", "1.0.0") {
override fun getLibraryClassesRoots() = emptyList<String>()
})
myTestFixture.module,
DependencyScope.COMPILE,
object : ExternalLibraryDescriptor("org.jetbrains.kotlin", "kotlin-reflect", "1.0.0", "1.0.0") {
override fun getLibraryClassesRoots() = emptyList<String>()
})
}
FileDocumentManager.getInstance().saveAllDocuments()
}
assertEquals(
"""
"""
|dependencies {
| testCompile("junit:junit:4.12")
| compile(kotlinModule("stdlib-jre8"))
| compile(kotlinModule("reflect", "1.0.0"))
|}
|""".trimMargin("|"),
LoadTextUtil.loadText(buildScript).toString())
LoadTextUtil.loadText(buildScript).toString()
)
}
@Test
fun testAddCoroutinesSupport() {
val buildScript = createProjectSubFile("build.gradle", """
val buildScript = createProjectSubFile(
"build.gradle", """
buildscript {
repositories {
jcenter()
@@ -438,7 +471,8 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-1.1.0"
}
""".trimIndent())
""".trimIndent()
)
importProject()
@@ -450,7 +484,8 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
FileDocumentManager.getInstance().saveAllDocuments()
}
assertEquals("""
assertEquals(
"""
buildscript {
repositories {
jcenter()
@@ -472,7 +507,8 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
}
}
""".trimIndent(),
LoadTextUtil.loadText(buildScript).toString())
LoadTextUtil.loadText(buildScript).toString()
)
}
@Test
@@ -490,17 +526,19 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
}
assertEquals(
"""import org.jetbrains.kotlin.gradle.dsl.Coroutines
"""import org.jetbrains.kotlin.gradle.dsl.Coroutines
|
|kotlin {
| experimental.coroutines = Coroutines.ENABLE
|}""".trimMargin("|"),
LoadTextUtil.loadText(buildScript).toString())
LoadTextUtil.loadText(buildScript).toString()
)
}
@Test
fun testChangeCoroutinesSupport() {
val buildScript = createProjectSubFile("build.gradle", """
val buildScript = createProjectSubFile(
"build.gradle", """
buildscript {
repositories {
jcenter()
@@ -521,7 +559,8 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
coroutines "error"
}
}
""".trimIndent())
""".trimIndent()
)
importProject()
@@ -533,7 +572,8 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
FileDocumentManager.getInstance().saveAllDocuments()
}
assertEquals("""
assertEquals(
"""
buildscript {
repositories {
jcenter()
@@ -554,18 +594,21 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
coroutines "enable"
}
}
""".trimIndent(), LoadTextUtil.loadText(buildScript).toString())
""".trimIndent(), LoadTextUtil.loadText(buildScript).toString()
)
}
@Test
fun testChangeCoroutinesSupportGSK() {
val buildScript = createProjectSubFile("build.gradle.kts",
"""import org.jetbrains.kotlin.gradle.dsl.Coroutines
val buildScript = createProjectSubFile(
"build.gradle.kts",
"""import org.jetbrains.kotlin.gradle.dsl.Coroutines
|
|kotlin {
| experimental.coroutines = Coroutines.DISABLE
|}
|""".trimMargin("|"))
|""".trimMargin("|")
)
importProject()
@@ -578,18 +621,20 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
}
assertEquals(
"""import org.jetbrains.kotlin.gradle.dsl.Coroutines
"""import org.jetbrains.kotlin.gradle.dsl.Coroutines
|
|kotlin {
| experimental.coroutines = Coroutines.ENABLE
|}
|""".trimMargin("|"),
LoadTextUtil.loadText(buildScript).toString())
LoadTextUtil.loadText(buildScript).toString()
)
}
@Test
fun testAddLanguageVersion() {
val buildScript = createProjectSubFile("build.gradle", """
val buildScript = createProjectSubFile(
"build.gradle", """
buildscript {
repositories {
jcenter()
@@ -605,7 +650,8 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-1.1.0"
}
""".trimIndent())
""".trimIndent()
)
importProject()
@@ -617,7 +663,8 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
FileDocumentManager.getInstance().saveAllDocuments()
}
assertEquals("""
assertEquals(
"""
buildscript {
repositories {
jcenter()
@@ -638,7 +685,8 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
languageVersion = "1.1"
}
}
""".trimIndent(), LoadTextUtil.loadText(buildScript).toString())
""".trimIndent(), LoadTextUtil.loadText(buildScript).toString()
)
}
@Test
@@ -656,18 +704,20 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
}
assertEquals(
"""import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
"""import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
|val compileKotlin: KotlinCompile by tasks
|compileKotlin.kotlinOptions {
| languageVersion = "1.1"
|}""".trimMargin("|"),
LoadTextUtil.loadText(buildScript).toString())
LoadTextUtil.loadText(buildScript).toString()
)
}
@Test
fun testChangeLanguageVersion() {
val buildScript = createProjectSubFile("build.gradle", """
val buildScript = createProjectSubFile(
"build.gradle", """
buildscript {
repositories {
jcenter()
@@ -688,7 +738,8 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
languageVersion = "1.0"
}
}
""".trimIndent())
""".trimIndent()
)
importProject()
@@ -700,7 +751,8 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
FileDocumentManager.getInstance().saveAllDocuments()
}
assertEquals("""
assertEquals(
"""
buildscript {
repositories {
jcenter()
@@ -721,17 +773,20 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
languageVersion = "1.1"
}
}
""".trimIndent(), LoadTextUtil.loadText(buildScript).toString())
""".trimIndent(), LoadTextUtil.loadText(buildScript).toString()
)
}
@Test
fun testChangeLanguageVersionGSK() {
val buildScript = createProjectSubFile("build.gradle.kts",
"""val compileKotlin: KotlinCompile by tasks
val buildScript = createProjectSubFile(
"build.gradle.kts",
"""val compileKotlin: KotlinCompile by tasks
|compileKotlin.kotlinOptions {
| languageVersion = "1.0"
|}
|""".trimMargin("|"))
|""".trimMargin("|")
)
importProject()
@@ -744,17 +799,19 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
}
assertEquals(
"""val compileKotlin: KotlinCompile by tasks
"""val compileKotlin: KotlinCompile by tasks
|compileKotlin.kotlinOptions {
| languageVersion = "1.1"
|}
|""".trimMargin("|"),
LoadTextUtil.loadText(buildScript).toString())
LoadTextUtil.loadText(buildScript).toString()
)
}
@Test
fun testAddLibrary() {
val buildScript = createProjectSubFile("build.gradle", """
val buildScript = createProjectSubFile(
"build.gradle", """
buildscript {
repositories {
jcenter()
@@ -770,24 +827,26 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-1.1.0"
}
""".trimIndent())
""".trimIndent()
)
importProject()
runInEdtAndWait {
myTestFixture.project.executeWriteCommand("") {
KotlinWithGradleConfigurator.addKotlinLibraryToModule(
myTestFixture.module,
DependencyScope.COMPILE,
object: ExternalLibraryDescriptor("org.jetbrains.kotlin", "kotlin-reflect", "1.0.0", "1.0.0") {
override fun getLibraryClassesRoots() = emptyList<String>()
})
myTestFixture.module,
DependencyScope.COMPILE,
object : ExternalLibraryDescriptor("org.jetbrains.kotlin", "kotlin-reflect", "1.0.0", "1.0.0") {
override fun getLibraryClassesRoots() = emptyList<String>()
})
}
FileDocumentManager.getInstance().saveAllDocuments()
}
assertEquals("""
assertEquals(
"""
buildscript {
repositories {
jcenter()
@@ -804,6 +863,7 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
compile "org.jetbrains.kotlin:kotlin-stdlib-1.1.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
@RunWith(value = Parameterized.class)
public abstract class GradleImportingTestCase extends ExternalSystemImportingTestCase {
private static final String GRADLE_JDK_NAME = "Gradle JDK";
private static final int GRADLE_DAEMON_TTL_MS = 10000;
private static final String GRADLE_JDK_NAME = "Gradle JDK";
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
@Parameterized.Parameter() public String gradleVersion;
@SuppressWarnings({"NullableProblems", "WeakerAccess"}) @NotNull
@Parameterized.Parameter() public String gradleVersion;
private GradleProjectSettings myProjectSettings;
private String myJdkHome;
private GradleProjectSettings myProjectSettings;
private String myJdkHome;
@Override
public void setUp() throws Exception {
myJdkHome = IdeaTestUtil.requireRealJdkHome();
super.setUp();
assumeThat(gradleVersion, versionMatcherRule.getMatcher());
new WriteAction() {
@Override
protected void run(@NotNull Result result) throws Throwable {
Sdk oldJdk = ProjectJdkTable.getInstance().findJdk(GRADLE_JDK_NAME);
if (oldJdk != null) {
ProjectJdkTable.getInstance().removeJdk(oldJdk);
}
VirtualFile jdkHomeDir = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(new File(myJdkHome));
assert jdkHomeDir != null;
Sdk jdk = SdkConfigurationUtil.setupSdk(new Sdk[0], jdkHomeDir, JavaSdk.getInstance(), true, null, GRADLE_JDK_NAME);
assertNotNull("Cannot create JDK for " + myJdkHome, jdk);
ProjectJdkTable.getInstance().addJdk(jdk);
}
}.execute();
myProjectSettings = new GradleProjectSettings();
GradleSettings.getInstance(myProject).setGradleVmOptions("-Xmx128m -XX:MaxPermSize=64m");
System.setProperty(ExternalSystemExecutionSettings.REMOTE_PROCESS_IDLE_TTL_IN_MS_KEY, String.valueOf(GRADLE_DAEMON_TTL_MS));
configureWrapper();
}
@Override
public void tearDown() throws Exception {
if (myJdkHome == null) {
//super.setUp() wasn't called
return;
@Override
public void setUp() throws Exception {
myJdkHome = IdeaTestUtil.requireRealJdkHome();
super.setUp();
assumeThat(gradleVersion, versionMatcherRule.getMatcher());
new WriteAction() {
@Override
protected void run(@NotNull Result result) throws Throwable {
Sdk oldJdk = ProjectJdkTable.getInstance().findJdk(GRADLE_JDK_NAME);
if (oldJdk != null) {
ProjectJdkTable.getInstance().removeJdk(oldJdk);
}
VirtualFile jdkHomeDir = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(new File(myJdkHome));
assert jdkHomeDir != null;
Sdk jdk = SdkConfigurationUtil.setupSdk(new Sdk[0], jdkHomeDir, JavaSdk.getInstance(), true, null, GRADLE_JDK_NAME);
assertNotNull("Cannot create JDK for " + myJdkHome, jdk);
ProjectJdkTable.getInstance().addJdk(jdk);
}
}.execute();
myProjectSettings = new GradleProjectSettings();
GradleSettings.getInstance(myProject).setGradleVmOptions("-Xmx128m -XX:MaxPermSize=64m");
System.setProperty(ExternalSystemExecutionSettings.REMOTE_PROCESS_IDLE_TTL_IN_MS_KEY, String.valueOf(GRADLE_DAEMON_TTL_MS));
configureWrapper();
}
try {
new WriteAction() {
@Override
protected void run(@NotNull Result result) throws Throwable {
Sdk old = ProjectJdkTable.getInstance().findJdk(GRADLE_JDK_NAME);
if (old != null) {
SdkConfigurationUtil.removeSdk(old);
}
@Override
public void tearDown() throws Exception {
if (myJdkHome == null) {
//super.setUp() wasn't called
return;
}
}.execute();
Messages.setTestDialog(TestDialog.DEFAULT);
FileUtil.delete(BuildManager.getInstance().getBuildSystemDirectory().toFile());
}
finally {
super.tearDown();
}
}
@Override
protected void collectAllowedRoots(List<String> roots) throws IOException {
roots.add(myJdkHome);
roots.addAll(collectRootsInside(myJdkHome));
roots.add(PathManager.getConfigPath());
}
@Override
public String getName() {
return name.getMethodName() == null ? super.getName() : FileUtil.sanitizeFileName(name.getMethodName());
}
@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);
try {
new WriteAction() {
@Override
protected void run(@NotNull Result result) throws Throwable {
Sdk old = ProjectJdkTable.getInstance().findJdk(GRADLE_JDK_NAME);
if (old != null) {
SdkConfigurationUtil.removeSdk(old);
}
}
}.execute();
Messages.setTestDialog(TestDialog.DEFAULT);
FileUtil.delete(BuildManager.getInstance().getBuildSystemDirectory().toFile());
}
}
});
super.importProject();
}
finally {
super.tearDown();
}
}
@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 void collectAllowedRoots(List<String> roots) throws IOException {
roots.add(myJdkHome);
roots.addAll(collectRootsInside(myJdkHome));
roots.add(PathManager.getConfigPath());
}
@Override
protected GradleProjectSettings getCurrentExternalProjectSettings() {
return myProjectSettings;
}
@Override
public String getName() {
return name.getMethodName() == null ? super.getName() : FileUtil.sanitizeFileName(name.getMethodName());
}
@Override
protected ProjectSystemId getExternalSystemId() {
return GradleConstants.SYSTEM_ID;
}
@Parameterized.Parameters(name = "{index}: with Gradle-{0}")
public static Collection<Object[]> data() throws Throwable {
return Arrays.asList(AbstractModelBuilderTest.SUPPORTED_GRADLE_VERSIONS);
}
private void configureWrapper() throws IOException, URISyntaxException {
URI distributionUri = new AbstractModelBuilderTest.DistributionLocator().getDistributionFor(GradleVersion.version(gradleVersion));
@Override
protected String getTestsTempDir() {
return "gradleImportTests";
}
myProjectSettings.setDistributionType(DistributionType.DEFAULT_WRAPPED);
final VirtualFile wrapperJarFrom = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(wrapperJar());
assert wrapperJarFrom != null;
@Override
protected String getExternalSystemConfigFileName() {
return "build.gradle";
}
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();
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);
}
}
});
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.setProperty("distributionBase", "GRADLE_USER_HOME");
properties.setProperty("distributionPath", "wrapper/dists");
properties.setProperty("zipStoreBase", "GRADLE_USER_HOME");
properties.setProperty("zipStorePath", "wrapper/dists");
properties.setProperty("distributionUrl", distributionUri.toString());
Properties properties = new Properties();
properties.setProperty("distributionBase", "GRADLE_USER_HOME");
properties.setProperty("distributionPath", "wrapper/dists");
properties.setProperty("zipStoreBase", "GRADLE_USER_HOME");
properties.setProperty("zipStorePath", "wrapper/dists");
properties.setProperty("distributionUrl", distributionUri.toString());
StringWriter writer = new StringWriter();
properties.store(writer, null);
StringWriter writer = new StringWriter();
properties.store(writer, null);
createProjectSubFile("gradle/wrapper/gradle-wrapper.properties", writer.toString());
}
createProjectSubFile("gradle/wrapper/gradle-wrapper.properties", writer.toString());
}
@NotNull
private static File wrapperJar() {
return new File(PathUtil.getJarPathForClass(GradleWrapperMain.class));
}
@NotNull
private static File wrapperJar() {
return new File(PathUtil.getJarPathForClass(GradleWrapperMain.class));
}
}
@@ -20,9 +20,9 @@ import com.intellij.codeInspection.LocalInspectionTool
import com.intellij.codeInspection.ProblemDescriptorBase
import com.intellij.openapi.util.Ref
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.DifferentStdlibGradleVersionInspection
import org.jetbrains.kotlin.idea.inspections.gradle.DeprecatedGradleDependencyInspection
import org.jetbrains.kotlin.idea.inspections.runInspection
import org.junit.Assert
import org.junit.Test
@@ -30,7 +30,8 @@ import org.junit.Test
class GradleInspectionTest : GradleImportingTestCase() {
@Test
fun testDifferentStdlibGradleVersion() {
val localFile = createProjectSubFile("build.gradle", """
val localFile = createProjectSubFile(
"build.gradle", """
group 'Again'
version '1.0-SNAPSHOT'
@@ -49,7 +50,8 @@ class GradleInspectionTest : GradleImportingTestCase() {
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib:1.0.3"
}
""")
"""
)
importProject()
val tool = DifferentStdlibGradleVersionInspection()
@@ -61,7 +63,8 @@ class GradleInspectionTest : GradleImportingTestCase() {
@Test
fun testDifferentStdlibJre7GradleVersion() {
val localFile = createProjectSubFile("build.gradle", """
val localFile = createProjectSubFile(
"build.gradle", """
group 'Again'
version '1.0-SNAPSHOT'
@@ -83,7 +86,8 @@ class GradleInspectionTest : GradleImportingTestCase() {
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:1.1.0-beta-22"
}
""")
"""
)
importProject()
val tool = DifferentStdlibGradleVersionInspection()
@@ -95,7 +99,8 @@ class GradleInspectionTest : GradleImportingTestCase() {
@Test
fun testDifferentStdlibJdk7GradleVersion() {
val localFile = createProjectSubFile("build.gradle", """
val localFile = createProjectSubFile(
"build.gradle", """
group 'Again'
version '1.0-SNAPSHOT'
@@ -117,7 +122,8 @@ class GradleInspectionTest : GradleImportingTestCase() {
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.1.0-beta-22"
}
""")
"""
)
importProject()
val tool = DifferentStdlibGradleVersionInspection()
@@ -130,10 +136,13 @@ class GradleInspectionTest : GradleImportingTestCase() {
@Test
fun testDifferentStdlibGradleVersionWithVariables() {
createProjectSubFile("gradle.properties", """
createProjectSubFile(
"gradle.properties", """
|kotlin=1.0.1
|lib_version=1.0.3""".trimMargin())
val localFile = createProjectSubFile("build.gradle", """
|lib_version=1.0.3""".trimMargin()
)
val localFile = createProjectSubFile(
"build.gradle", """
group 'Again'
version '1.0-SNAPSHOT'
@@ -152,7 +161,8 @@ class GradleInspectionTest : GradleImportingTestCase() {
dependencies {
compile group: 'org.jetbrains.kotlin', name: 'kotlin-stdlib', version: lib_version
}
""")
"""
)
importProject()
val tool = DifferentStdlibGradleVersionInspection()
@@ -165,7 +175,8 @@ class GradleInspectionTest : GradleImportingTestCase() {
@Test
fun testDifferentKotlinGradleVersion() {
createProjectSubFile("gradle.properties", """test=1.0.1""")
val localFile = createProjectSubFile("build.gradle", """
val localFile = createProjectSubFile(
"build.gradle", """
group 'Again'
version '1.0-SNAPSHOT'
@@ -180,7 +191,8 @@ class GradleInspectionTest : GradleImportingTestCase() {
}
apply plugin: 'kotlin'
""")
"""
)
importProject()
val tool = DifferentKotlinGradleVersionInspection()
@@ -188,12 +200,16 @@ class GradleInspectionTest : GradleImportingTestCase() {
val problems = getInspectionResult(tool, localFile)
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
fun testJreInOldVersion() {
val localFile = createProjectSubFile("build.gradle", """
val localFile = createProjectSubFile(
"build.gradle", """
group 'Again'
version '1.0-SNAPSHOT'
@@ -212,7 +228,8 @@ class GradleInspectionTest : GradleImportingTestCase() {
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-jre8:1.1.60"
}
""")
"""
)
importProject()
val tool = DeprecatedGradleDependencyInspection()
@@ -223,7 +240,8 @@ class GradleInspectionTest : GradleImportingTestCase() {
@Test
fun testJreIsDeprecated() {
val localFile = createProjectSubFile("build.gradle", """
val localFile = createProjectSubFile(
"build.gradle", """
group 'Again'
version '1.0-SNAPSHOT'
@@ -242,14 +260,18 @@ class GradleInspectionTest : GradleImportingTestCase() {
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:1.2.0"
}
""")
"""
)
importProject()
val tool = DeprecatedGradleDependencyInspection()
val problems = getInspectionResult(tool, localFile)
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> {
@@ -258,9 +280,9 @@ class GradleInspectionTest : GradleImportingTestCase() {
val presentation = runInspection(tool, myProject, listOf(file))
val foundProblems = presentation.problemElements
.values
.mapNotNull { it as? ProblemDescriptorBase }
.map { it.descriptionTemplate }
.values
.mapNotNull { it as? ProblemDescriptorBase }
.map { it.descriptionTemplate }
resultRef.set(foundProblems)
}
@@ -38,8 +38,8 @@ class GradleMultiplatformRunTest : GradleImportingTestCase() {
@Test
fun testMultiplatformClasspath() {
createProjectSubFile(
"build.gradle",
"""
"build.gradle",
"""
buildscript {
repositories {
jcenter()
@@ -64,15 +64,15 @@ class GradleMultiplatformRunTest : GradleImportingTestCase() {
""".trimIndent()
)
createProjectSubFile(
"settings.gradle",
"""
"settings.gradle",
"""
rootProject.name = 'MultiTest'
include 'MultiTest-jvm', 'MultiTest-js'
""".trimIndent()
)
createProjectSubFile(
"MultiTest-js/build.gradle",
"""
"MultiTest-js/build.gradle",
"""
buildscript {
repositories {
jcenter()
@@ -98,8 +98,8 @@ class GradleMultiplatformRunTest : GradleImportingTestCase() {
""".trimIndent()
)
createProjectSubFile(
"MultiTest-jvm/build.gradle",
"""
"MultiTest-jvm/build.gradle",
"""
buildscript {
repositories {
jcenter()
@@ -140,16 +140,23 @@ class GradleMultiplatformRunTest : GradleImportingTestCase() {
val producer = RunConfigurationProducer.getInstance(KotlinRunConfigurationProducer::class.java)
val configuration = producer.createConfigurationFromContext(configurationContext)!!
val executionEnvironment = ExecutionEnvironmentBuilder.create(myProject,
DefaultRunExecutor.getRunExecutorInstance(),
configuration.configuration)
val executionEnvironment = ExecutionEnvironmentBuilder.create(
myProject,
DefaultRunExecutor.getRunExecutorInstance(),
configuration.configuration
)
.build()
val compileStepBeforeRun = CompileStepBeforeRun(myProject)
compileStepBeforeRun.executeTask(dataContext, configuration.configuration, executionEnvironment,
CompileStepBeforeRun.MakeBeforeRunTask())
compileStepBeforeRun.executeTask(
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
}
@@ -46,23 +46,28 @@ class GradleUpdateConfigurationQuickFixTest : GradleImportingTestCase() {
myTestFixture = null
}
@Test fun testUpdateLanguageVersion() {
@Test
fun testUpdateLanguageVersion() {
doTest("Set module language version to 1.1")
}
@Test fun testUpdateApiVersion() {
@Test
fun testUpdateApiVersion() {
doTest("Set module API version to 1.1")
}
@Test fun testUpdateLanguageAndApiVersion() {
@Test
fun testUpdateLanguageAndApiVersion() {
doTest("Set module language version to 1.1")
}
@Test fun testEnableCoroutines() {
@Test
fun testEnableCoroutines() {
doTest("Enable coroutine support in the current module")
}
@Test fun testAddKotlinReflect() {
@Test
fun testAddKotlinReflect() {
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
public class VersionMatcherRule extends TestWatcher {
@Nullable
private CustomMatcher myMatcher;
@Nullable
private CustomMatcher myMatcher;
@NotNull
public Matcher getMatcher() {
return myMatcher != null ? myMatcher : CoreMatchers.anything();
}
@NotNull
public Matcher getMatcher() {
return myMatcher != null ? myMatcher : CoreMatchers.anything();
}
@Override
protected void starting(Description d) {
final TargetVersions targetVersions = d.getAnnotation(TargetVersions.class);
if (targetVersions == null) return;
@Override
protected void starting(Description d) {
final TargetVersions targetVersions = d.getAnnotation(TargetVersions.class);
if (targetVersions == null) return;
myMatcher = new CustomMatcher<String>("Gradle version '" + targetVersions.value() + "'") {
@Override
public boolean matches(Object item) {
return item instanceof String && new VersionMatcher(GradleVersion.version(item.toString())).isVersionMatch(targetVersions);
}
};
}
myMatcher = new CustomMatcher<String>("Gradle version '" + targetVersions.value() + "'") {
@Override
public boolean matches(Object item) {
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 java.io.File
abstract class AbstractGradleConfigureProjectByChangingFileTest : AbstractConfigureProjectByChangingFileTest<KotlinWithGradleConfigurator>() {
abstract class AbstractGradleConfigureProjectByChangingFileTest :
AbstractConfigureProjectByChangingFileTest<KotlinWithGradleConfigurator>() {
fun doTestGradle(path: String) {
val (before, after) = beforeAfterFiles()
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) {
fail("file $file is not a GroovyFile or KtFile")
return