@@ -2,51 +2,64 @@ package org.javacs.kt
2
2
3
3
import org.javacs.kt.classpath.defaultClassPathResolver
4
4
import java.io.Closeable
5
+ import java.nio.file.Files
6
+ import java.nio.file.FileSystems
5
7
import java.nio.file.Path
8
+ import java.util.stream.Collectors
6
9
7
10
class CompilerClassPath (private val config : CompilerConfiguration ) : Closeable {
8
11
private val workspaceRoots = mutableSetOf<Path >()
12
+ private val javaSourcePath = mutableSetOf<Path >()
9
13
private val classPath = mutableSetOf<Path >()
10
14
private val buildScriptClassPath = mutableSetOf<Path >()
11
- var compiler = Compiler (workspaceRoots , classPath, buildScriptClassPath)
15
+ var compiler = Compiler (javaSourcePath , classPath, buildScriptClassPath)
12
16
private set
13
17
14
18
init {
15
19
compiler.updateConfiguration(config)
16
20
}
17
21
18
- private fun refresh (updateBuildScriptClassPath : Boolean = true) {
22
+ private fun refresh (
23
+ updateClassPath : Boolean = true,
24
+ updateBuildScriptClassPath : Boolean = true,
25
+ updateJavaSourcePath : Boolean = false
26
+ ): Boolean {
19
27
// TODO: Fetch class path and build script class path concurrently (and asynchronously)
20
28
val resolver = defaultClassPathResolver(workspaceRoots)
21
- var refreshCompiler = false
29
+ var refreshCompiler = updateJavaSourcePath
22
30
23
- val newClassPath = resolver.classpathOrEmpty
24
- if (newClassPath != classPath) {
25
- syncClassPath(classPath, newClassPath)
26
- refreshCompiler = true
31
+ if (updateClassPath) {
32
+ val newClassPath = resolver.classpathOrEmpty
33
+ if (newClassPath != classPath) {
34
+ syncPath(classPath, newClassPath, " class path" )
35
+ refreshCompiler = true
36
+ }
27
37
}
28
38
29
39
if (updateBuildScriptClassPath) {
40
+ LOG .info(" Update build script path" )
30
41
val newBuildScriptClassPath = resolver.buildScriptClasspathOrEmpty
31
42
if (newBuildScriptClassPath != buildScriptClassPath) {
32
- syncClassPath (buildScriptClassPath, newBuildScriptClassPath)
43
+ syncPath (buildScriptClassPath, newBuildScriptClassPath, " class path " )
33
44
refreshCompiler = true
34
45
}
35
46
}
36
47
37
48
if (refreshCompiler) {
38
49
compiler.close()
39
- compiler = Compiler (workspaceRoots , classPath, buildScriptClassPath)
50
+ compiler = Compiler (javaSourcePath , classPath, buildScriptClassPath)
40
51
updateCompilerConfiguration()
41
52
}
53
+
54
+ return refreshCompiler
42
55
}
43
56
44
- private fun syncClassPath (dest : MutableSet <Path >, new : Set <Path >) {
57
+ private fun syncPath (dest : MutableSet <Path >, new : Set <Path >, name : String ) {
45
58
val added = new - dest
46
59
val removed = dest - new
47
60
48
- logAdded(added)
49
- logRemoved(removed)
61
+ logAdded(added, name )
62
+ logRemoved(removed, name )
50
63
51
64
dest.removeAll(removed)
52
65
dest.addAll(added)
@@ -56,53 +69,78 @@ class CompilerClassPath(private val config: CompilerConfiguration) : Closeable {
56
69
compiler.updateConfiguration(config)
57
70
}
58
71
59
- fun addWorkspaceRoot (root : Path ) {
60
- LOG .info(" Searching for dependencies in workspace root {}" , root)
72
+ fun addWorkspaceRoot (root : Path ): Boolean {
73
+ LOG .info(" Searching for dependencies and Java sources in workspace root {}" , root)
61
74
62
75
workspaceRoots.add(root)
76
+ javaSourcePath.addAll(findJavaSourceFiles(root))
63
77
64
- refresh()
78
+ return refresh(updateJavaSourcePath = true )
65
79
}
66
80
67
- fun removeWorkspaceRoot (root : Path ) {
68
- LOG .info(" Remove dependencies from workspace root {}" , root)
81
+ fun removeWorkspaceRoot (root : Path ): Boolean {
82
+ LOG .info(" Removing dependencies and Java source path from workspace root {}" , root)
69
83
70
84
workspaceRoots.remove(root)
85
+ javaSourcePath.removeAll(findJavaSourceFiles(root))
71
86
72
- refresh()
87
+ return refresh(updateJavaSourcePath = true )
73
88
}
74
89
75
- fun createdOnDisk (file : Path ) {
76
- changedOnDisk(file)
90
+ fun createdOnDisk (file : Path ): Boolean {
91
+ if (isJavaSource(file)) {
92
+ javaSourcePath.add(file)
93
+ }
94
+ return changedOnDisk(file)
77
95
}
78
96
79
- fun deletedOnDisk (file : Path ) {
80
- changedOnDisk(file)
97
+ fun deletedOnDisk (file : Path ): Boolean {
98
+ if (isJavaSource(file)) {
99
+ javaSourcePath.remove(file)
100
+ }
101
+ return changedOnDisk(file)
81
102
}
82
103
83
- fun changedOnDisk (file : Path ) {
84
- val name = file.fileName.toString()
85
- if (name == " pom.xml" || name == " build.gradle" || name == " build.gradle.kts" )
86
- refresh(updateBuildScriptClassPath = false )
104
+ fun changedOnDisk (file : Path ): Boolean {
105
+ val buildScript = isBuildScript(file)
106
+ val javaSource = isJavaSource(file)
107
+ if (buildScript || javaSource) {
108
+ return refresh(updateClassPath = buildScript, updateBuildScriptClassPath = false , updateJavaSourcePath = javaSource)
109
+ } else {
110
+ return false
111
+ }
87
112
}
88
113
114
+ private fun isJavaSource (file : Path ): Boolean = file.fileName.toString().endsWith(" .java" )
115
+
116
+ private fun isBuildScript (file : Path ): Boolean = file.fileName.toString().let { it == " pom.xml" || it == " build.gradle" || it == " build.gradle.kts" }
117
+
89
118
override fun close () {
90
119
compiler.close()
91
120
}
92
121
}
93
122
94
- private fun logAdded (sources : Collection <Path >) {
123
+ // TODO: Cut off branches that are excluded in the walker directly
124
+ private fun findJavaSourceFiles (root : Path ): Set <Path > {
125
+ val sourceMatcher = FileSystems .getDefault().getPathMatcher(" glob:*.java" )
126
+ val exclusions = SourceExclusions (root)
127
+ return Files .walk(root)
128
+ .filter { exclusions.isPathIncluded(it) && sourceMatcher.matches(it.fileName) }
129
+ .collect(Collectors .toSet())
130
+ }
131
+
132
+ private fun logAdded (sources : Collection <Path >, name : String ) {
95
133
when {
96
134
sources.isEmpty() -> return
97
- sources.size > 5 -> LOG .info(" Adding {} files to class path " , sources.size)
98
- else -> LOG .info(" Adding {} to class path " , sources)
135
+ sources.size > 5 -> LOG .info(" Adding {} files to {} " , sources.size, name )
136
+ else -> LOG .info(" Adding {} to {} " , sources, name )
99
137
}
100
138
}
101
139
102
- private fun logRemoved (sources : Collection <Path >) {
140
+ private fun logRemoved (sources : Collection <Path >, name : String ) {
103
141
when {
104
142
sources.isEmpty() -> return
105
- sources.size > 5 -> LOG .info(" Removing {} files from class path " , sources.size)
106
- else -> LOG .info(" Removing {} from class path " , sources)
143
+ sources.size > 5 -> LOG .info(" Removing {} files from {} " , sources.size, name )
144
+ else -> LOG .info(" Removing {} from {} " , sources, name )
107
145
}
108
146
}
0 commit comments