Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow user specified exclusion patterns #574

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion server/src/main/kotlin/org/javacs/kt/CompilerClassPath.kt
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ class CompilerClassPath(

private fun findJavaSourceFiles(root: Path): Set<Path> {
val sourceMatcher = FileSystems.getDefault().getPathMatcher("glob:*.java")
return SourceExclusions(listOf(root), scriptsConfig)
return SourceExclusions(listOf(root), scriptsConfig, mutableListOf())
.walkIncluded()
.filter { sourceMatcher.matches(it.fileName) }
.toSet()
Expand Down
8 changes: 5 additions & 3 deletions server/src/main/kotlin/org/javacs/kt/Configuration.kt
Original file line number Diff line number Diff line change
Expand Up @@ -70,20 +70,22 @@ data class FormattingConfiguration(
var ktfmt: KtfmtConfiguration = KtfmtConfiguration()
)

fun getStoragePath(params: InitializeParams): Path? {
fun getInitializationOptions(params: InitializeParams): InitializationOptions? {
params.initializationOptions?.let { initializationOptions ->
val gson = GsonBuilder().registerTypeHierarchyAdapter(Path::class.java, GsonPathConverter()).create()
val options = gson.fromJson(initializationOptions as JsonElement, InitializationOptions::class.java)

return options?.storagePath
return options
}

return null
}

data class InitializationOptions(
// A path to a directory used by the language server to store data. Used for caching purposes.
val storagePath: Path?
val storagePath: Path?,
// Additional paths to exclude from source files.
val additionalSourceExclusions: List<String>?
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure about whether we should put this into the initialization options. That makes it a bit more cumbersome on the VSCode side and I think it could be nice (in the future) if these options could be updated while the language server is running, even if we don't fully support "hot" configuration updates yet.

)

class GsonPathConverter : JsonDeserializer<Path?> {
Expand Down
12 changes: 9 additions & 3 deletions server/src/main/kotlin/org/javacs/kt/KotlinLanguageServer.kt
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class KotlinLanguageServer(
private val tempDirectory = TemporaryDirectory()
private val uriContentProvider = URIContentProvider(ClassContentProvider(config.externalSources, classPath, tempDirectory, CompositeSourceArchiveProvider(JdkSourceArchiveProvider(classPath), ClassPathSourceArchiveProvider(classPath))))
val sourcePath = SourcePath(classPath, uriContentProvider, config.indexing, databaseService)
val sourceFiles = SourceFiles(sourcePath, uriContentProvider, config.scripts)
val sourceFiles = SourceFiles(sourcePath, uriContentProvider, config.scripts, mutableListOf())

private val textDocuments = KotlinTextDocumentService(sourceFiles, sourcePath, config, tempDirectory, uriContentProvider, classPath)
private val workspaces = KotlinWorkspaceService(sourceFiles, sourcePath, classPath, textDocuments, config)
Expand Down Expand Up @@ -72,6 +72,14 @@ class KotlinLanguageServer(
fun getProtocolExtensionService(): KotlinProtocolExtensions = protocolExtensions

override fun initialize(params: InitializeParams): CompletableFuture<InitializeResult> = async.compute {
// Parse initialization options
val options = getInitializationOptions(params)
databaseService.setup(options?.storagePath)

if(options?.additionalSourceExclusions != null) {
sourceFiles.updateAdditionalExclusions(options.additionalSourceExclusions.toMutableList())
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we refactor this to use immutable lists?

Mutable structures make it harder to reason about where updates are happening and passing them around make it easier for things to get out-of-sync, therefore I usually prefer the functional style.

}

val serverCapabilities = ServerCapabilities()
serverCapabilities.setTextDocumentSync(TextDocumentSyncKind.Incremental)
serverCapabilities.workspace = WorkspaceServerCapabilities()
Expand All @@ -94,8 +102,6 @@ class KotlinLanguageServer(
serverCapabilities.executeCommandProvider = ExecuteCommandOptions(ALL_COMMANDS)
serverCapabilities.documentHighlightProvider = Either.forLeft(true)

val storagePath = getStoragePath(params)
databaseService.setup(storagePath)

val clientCapabilities = params.capabilities
config.completion.snippets.enabled = clientCapabilities?.textDocument?.completion?.completionItem?.snippetSupport ?: false
Expand Down
18 changes: 14 additions & 4 deletions server/src/main/kotlin/org/javacs/kt/SourceFiles.kt
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,15 @@ private class NotifySourcePath(private val sp: SourcePath) {
class SourceFiles(
private val sp: SourcePath,
private val contentProvider: URIContentProvider,
private val scriptsConfig: ScriptsConfiguration
private val scriptsConfig: ScriptsConfiguration,
private val additionalSourceExclusions: MutableList<String>,
) {
private val workspaceRoots = mutableSetOf<Path>()
private var exclusions = SourceExclusions(workspaceRoots, scriptsConfig)
private var exclusions = SourceExclusions(
workspaceRoots,
scriptsConfig,
additionalSourceExclusions
)
Comment on lines +73 to +77
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Style nit:

Suggested change
private var exclusions = SourceExclusions(
workspaceRoots,
scriptsConfig,
additionalSourceExclusions
)
private var exclusions = SourceExclusions(
workspaceRoots,
scriptsConfig,
additionalSourceExclusions
)

private val files = NotifySourcePath(sp)
private val open = mutableSetOf<URI>()

Expand Down Expand Up @@ -181,18 +186,23 @@ class SourceFiles(

private fun findSourceFiles(root: Path): Set<URI> {
val sourceMatcher = FileSystems.getDefault().getPathMatcher("glob:*.{kt,kts}")
return SourceExclusions(listOf(root), scriptsConfig)
return SourceExclusions(listOf(root), scriptsConfig, additionalSourceExclusions)
.walkIncluded()
.filter { sourceMatcher.matches(it.fileName) }
.map(Path::toUri)
.toSet()
}

fun updateExclusions() {
exclusions = SourceExclusions(workspaceRoots, scriptsConfig)
exclusions = SourceExclusions(workspaceRoots, scriptsConfig, additionalSourceExclusions)
LOG.info("Updated exclusions: ${exclusions.excludedPatterns}")
}

fun updateAdditionalExclusions(exclusions: MutableList<String>) {
additionalSourceExclusions.addAll(exclusions)
updateExclusions()
}

fun isOpen(uri: URI): Boolean = (uri in open)

fun isIncluded(uri: URI): Boolean = exclusions.isURIIncluded(uri)
Expand Down
5 changes: 3 additions & 2 deletions shared/src/main/kotlin/org/javacs/kt/SourceExclusions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@ import java.nio.file.Paths
// hardcoding them
class SourceExclusions(
private val workspaceRoots: Collection<Path>,
private val scriptsConfig: ScriptsConfiguration
private val scriptsConfig: ScriptsConfiguration,
private val additionalSourceExclusions: List<String>
) {
val excludedPatterns = (listOf(
".git", ".hg", ".svn", // Version control systems
".idea", ".idea_modules", ".vs", ".vscode", ".code-workspace", ".settings", // IDEs
"bazel-*", "bin", "build", "node_modules", "target", // Build systems
) + when {
) + additionalSourceExclusions + when {
!scriptsConfig.enabled -> listOf("*.kts")
!scriptsConfig.buildScriptsEnabled -> listOf("*.gradle.kts")
else -> emptyList()
Expand Down