Skip to content

Commit 52fccb1

Browse files
committed
feat: gradle source sets support
1 parent 6b03d09 commit 52fccb1

File tree

2 files changed

+84
-35
lines changed

2 files changed

+84
-35
lines changed

app/src/main/kotlin/org/kotlinlsp/buildsystem/Gradle.kt

Lines changed: 60 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ class GradleBuildSystem(
3636

3737
override fun resolveModulesIfNeeded(cachedMetadata: String?): BuildSystem.Result? {
3838
val androidVariant = "debug" // TODO Make it a config parameter
39+
3940
if(!shouldReloadGradleProject(cachedMetadata)) {
4041
return null
4142
}
@@ -59,7 +60,7 @@ class GradleBuildSystem(
5960
println(output)
6061

6162
val jvmTarget = checkNotNull(JvmTarget.fromString(ideaProject.jdkName)) { "Unknown jdk target" }
62-
val jdkModule = ideaProject.javaLanguageSettings?.jdk?.let { jdk ->
63+
val jdkModule = ideaProject.javaLanguageSettings.jdk?.let { jdk ->
6364
LibraryModule(
6465
id = "JDK ${jvmTarget.description}",
6566
appEnvironment = appEnvironment,
@@ -70,43 +71,73 @@ class GradleBuildSystem(
7071
)
7172
}
7273

73-
val modules = ideaProject.modules.map { module ->
74-
val dependencies = module
75-
.dependencies
76-
.filterIsInstance<IdeaSingleEntryLibraryDependency>()
77-
.map { dependency ->
78-
LibraryModule(
79-
id = dependency.file.name,
80-
appEnvironment = appEnvironment,
81-
project = project,
82-
javaVersion = jvmTarget,
83-
contentRoots = listOf(dependency.file.toPath()),
84-
)
74+
val modules = ideaProject
75+
.modules
76+
.asSequence()
77+
.mapNotNull { module ->
78+
val contentRoot =
79+
module.contentRoots.first() // Don't know in which cases we would have multiple contentRoots
80+
val sourceDirs = contentRoot.sourceDirectories.map { it.directory.toPath() }
81+
val testDirs = contentRoot.testDirectories.map { it.directory.toPath() }
82+
83+
// Ignore empty modules
84+
if(sourceDirs.isEmpty()) return@mapNotNull null
85+
86+
// Seems that dependencies are the same for source and test source-sets?
87+
val dependencies: MutableList<Module> = module
88+
.dependencies
89+
.filterIsInstance<IdeaSingleEntryLibraryDependency>()
90+
.map { dependency ->
91+
LibraryModule(
92+
id = dependency.file.name,
93+
appEnvironment = appEnvironment,
94+
project = project,
95+
javaVersion = jvmTarget,
96+
contentRoots = listOf(dependency.file.toPath()),
97+
)
98+
}
99+
.toMutableList()
100+
101+
if (jdkModule != null) {
102+
dependencies.add(jdkModule)
85103
}
86104

87-
val allDependencies: MutableList<Module> = dependencies.toMutableList()
88-
if (jdkModule != null) {
89-
allDependencies.add(jdkModule)
105+
val sourceModule = SourceModule(
106+
id = module.name,
107+
project = project,
108+
contentRoots = sourceDirs,
109+
dependencies = dependencies,
110+
javaVersion = jvmTarget,
111+
kotlinVersion = LanguageVersion.KOTLIN_2_1,
112+
)
113+
114+
if (testDirs.isEmpty()) return@mapNotNull listOf(sourceModule)
115+
116+
val testDependencies = dependencies.toMutableList()
117+
testDependencies.add(sourceModule)
118+
119+
val testModule = SourceModule(
120+
id = module.name,
121+
project = project,
122+
contentRoots = testDirs,
123+
dependencies = testDependencies,
124+
javaVersion = jvmTarget,
125+
kotlinVersion = LanguageVersion.KOTLIN_2_1,
126+
)
127+
128+
return@mapNotNull listOf(sourceModule, testModule)
90129
}
91-
92-
SourceModule(
93-
id = module.name,
94-
project = project,
95-
contentRoots = listOf(module.contentRoots.first().rootDirectory.toPath()),
96-
dependencies = allDependencies,
97-
javaVersion = jvmTarget,
98-
kotlinVersion = LanguageVersion.KOTLIN_2_1,
99-
)
100-
}
130+
.flatten()
131+
.toList()
101132

102-
// TODO Support multiple modules, for now take the last one
103-
val rootModule = modules.last()
104133
progressNotifier.onReportProgress(WorkDoneProgressKind.end, PROGRESS_TOKEN, "[GRADLE] Done")
105134

106135
val metadata = Gson().toJson(computeGradleMetadata(ideaProject))
136+
107137
connection.close()
108138
androidInitScript.delete()
109-
return BuildSystem.Result(listOf(rootModule), metadata)
139+
140+
return BuildSystem.Result(modules, metadata)
110141
}
111142
}
112143

app/src/test/kotlin/org/kotlinlsp/Gradle.kt

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import org.kotlinlsp.buildsystem.GradleBuildSystem
1313
import org.mockito.Mockito.mock
1414
import java.nio.file.Paths
1515
import org.kotlinlsp.analysis.modules.Module
16+
import kotlin.io.path.Path
1617
import kotlin.io.path.absolutePathString
1718

1819
class Gradle {
@@ -45,19 +46,36 @@ class Gradle {
4546
fun `loads single module project successfully`() = scenario("single-module") { buildSystem ->
4647
// Act
4748
val (modules, _) = buildSystem.resolveModulesIfNeeded(cachedMetadata = null)!!
48-
val rootModule = modules.first()
4949

5050
// Assert
51-
assertEquals(rootModule.isSourceModule, true)
52-
assertEquals(rootModule.contentRoots.first().absolutePathString(), "$cwd/test-projects/single-module/app")
53-
assertEquals(rootModule.dependencies.size, 3)
54-
rootModule.dependencies.forEach {
51+
assertEquals(modules.size, 2)
52+
assertEquals(modules[0].isSourceModule, true)
53+
assertEquals(
54+
modules[0].contentRoots,
55+
listOf(
56+
Path("$cwd/test-projects/single-module/app/src/main/java"),
57+
Path("$cwd/test-projects/single-module/app/src/main/kotlin"),
58+
)
59+
)
60+
assertEquals(modules[0].dependencies.size, 3)
61+
modules[0].dependencies.forEach {
5562
assertEquals(it.dependencies.size, 0)
5663
assertEquals(it.contentRoots.size, 1)
5764
}
58-
val depNames = rootModule.dependencies.map { it.firstContentRootFilename() }.toSet()
65+
val depNames = modules[0].dependencies.map { it.firstContentRootFilename() }.toSet()
5966
assertTrue("annotations-13.0.jar" in depNames)
6067
assertTrue("kotlin-stdlib-2.1.20.jar" in depNames)
68+
69+
assertEquals(modules[1].isSourceModule, true)
70+
assertEquals(
71+
modules[1].contentRoots,
72+
listOf(
73+
Path("$cwd/test-projects/single-module/app/src/test/java"),
74+
Path("$cwd/test-projects/single-module/app/src/test/kotlin"),
75+
)
76+
)
77+
assertEquals(modules[1].dependencies.size, 4)
78+
assertEquals(modules[1].dependencies.filter { it.isSourceModule }.size, 1)
6179
}
6280

6381
@Test

0 commit comments

Comments
 (0)