Skip to content

Commit a8ebc05

Browse files
committed
Merge branch 'stdlib-resolution'
2 parents c36c516 + 9a66e16 commit a8ebc05

File tree

1 file changed

+48
-3
lines changed

1 file changed

+48
-3
lines changed

src/main/kotlin/org/javacs/kt/classpath/findClassPath.kt

+48-3
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,55 @@ fun findClassPath(workspaceRoots: Collection<Path>): Set<Path> {
2828
}
2929

3030
private fun ensureStdlibInPaths(paths: Set<Path>): Set<Path> {
31-
// Ensure that there is exactly one kotlin-stdlib present
31+
// Ensure that there is exactly one kotlin-stdlib present, and/or exactly one of kotlin-stdlib-common, -jdk8, etc.
3232
val isStdlib: ((Path) -> Boolean) = { it.toString().contains("kotlin-stdlib") }
33-
val stdlib = paths.firstOrNull(isStdlib) ?: findKotlinStdlib()
34-
return paths.filterNot(isStdlib).union(listOf(stdlib).filterNotNull())
33+
34+
val linkedStdLibs = paths.filter(isStdlib)
35+
.mapNotNull { StdLibItem.from(it) }
36+
.groupBy { it.key }
37+
.map { candidates ->
38+
// For each "kotlin-stdlib-blah", use the newest. This may not be correct behavior if the project has lots of
39+
// conflicting dependencies, but in general should get enough of the stdlib loaded that we can display errors
40+
41+
candidates.value.sortedWith(
42+
compareByDescending<StdLibItem> { it.major } then
43+
compareByDescending { it.minor } then
44+
compareByDescending { it.patch }
45+
).first().path
46+
}
47+
48+
val stdlibs = if (linkedStdLibs.isNotEmpty()) {
49+
linkedStdLibs
50+
} else {
51+
findKotlinStdlib()?.let { listOf(it) } ?: listOf()
52+
}
53+
54+
return paths.filterNot(isStdlib).union(stdlibs)
55+
}
56+
57+
private data class StdLibItem(
58+
val key : String,
59+
val major : Int,
60+
val minor: Int,
61+
val patch : Int,
62+
val path: Path
63+
) {
64+
companion object {
65+
// Matches names like: "kotlin-stdlib-jdk7-1.2.51.jar"
66+
val parser = Regex("""(kotlin-stdlib(-[^-]+)?)-(\d+)\.(\d+)\.(\d+)\.jar""")
67+
68+
fun from(path: Path) : StdLibItem? {
69+
return parser.matchEntire(path.fileName.toString())?.let { match ->
70+
StdLibItem(
71+
key = match.groups[1]?.value ?: match.groups[0]?.value!!,
72+
major = match.groups[3]?.value?.toInt() ?: 0,
73+
minor = match.groups[4]?.value?.toInt() ?: 0,
74+
patch = match.groups[5]?.value?.toInt() ?: 0,
75+
path = path
76+
)
77+
}
78+
}
79+
}
3580
}
3681

3782
private fun backupClassPath() =

0 commit comments

Comments
 (0)