diff --git a/detekt.yml b/detekt.yml index b14eeb206..f7cf0c72b 100644 --- a/detekt.yml +++ b/detekt.yml @@ -3,10 +3,10 @@ config: warningsAsErrors: false comments: - excludes: ["**/src/test/resources/**"] + excludes: ["**/src/test/**"] complexity: - excludes: ["**/src/test/resources/**"] + excludes: ["**/src/test/**"] empty-blocks: excludes: ["**/src/test/**"] diff --git a/server/src/main/kotlin/org/javacs/kt/CompilerClassPath.kt b/server/src/main/kotlin/org/javacs/kt/CompilerClassPath.kt index 8ec87e5b0..3b25c96ab 100644 --- a/server/src/main/kotlin/org/javacs/kt/CompilerClassPath.kt +++ b/server/src/main/kotlin/org/javacs/kt/CompilerClassPath.kt @@ -15,7 +15,11 @@ import java.nio.file.Path * Manages the class path (compiled JARs, etc), the Java source path * and the compiler. Note that Kotlin sources are stored in SourcePath. */ -class CompilerClassPath(private val config: CompilerConfiguration, private val databaseService: DatabaseService) : Closeable { +class CompilerClassPath( + private val config: CompilerConfiguration, + private val scriptsConfig: ScriptsConfiguration, + private val databaseService: DatabaseService +) : Closeable { val workspaceRoots = mutableSetOf() private val javaSourcePath = mutableSetOf() @@ -24,7 +28,13 @@ class CompilerClassPath(private val config: CompilerConfiguration, private val d val outputDirectory: File = Files.createTempDirectory("klsBuildOutput").toFile() val javaHome: String? = System.getProperty("java.home", null) - var compiler = Compiler(javaSourcePath, classPath.map { it.compiledJar }.toSet(), buildScriptClassPath, outputDirectory) + var compiler = Compiler( + javaSourcePath, + classPath.map { it.compiledJar }.toSet(), + buildScriptClassPath, + scriptsConfig, + outputDirectory + ) private set private val async = AsyncExecutor() @@ -72,7 +82,13 @@ class CompilerClassPath(private val config: CompilerConfiguration, private val d if (refreshCompiler) { LOG.info("Reinstantiating compiler") compiler.close() - compiler = Compiler(javaSourcePath, classPath.map { it.compiledJar }.toSet(), buildScriptClassPath, outputDirectory) + compiler = Compiler( + javaSourcePath, + classPath.map { it.compiledJar }.toSet(), + buildScriptClassPath, + scriptsConfig, + outputDirectory + ) updateCompilerConfiguration() } diff --git a/server/src/main/kotlin/org/javacs/kt/Configuration.kt b/server/src/main/kotlin/org/javacs/kt/Configuration.kt index c15cbb227..76850470e 100644 --- a/server/src/main/kotlin/org/javacs/kt/Configuration.kt +++ b/server/src/main/kotlin/org/javacs/kt/Configuration.kt @@ -30,6 +30,13 @@ public data class DiagnosticsConfiguration( var debounceTime: Long = 250L ) +public data class ScriptsConfiguration( + /** Whether .kts scripts are handled. */ + var enabled: Boolean = false, + /** Whether .gradle.kts scripts are handled. Only considered if scripts are enabled in general. */ + var buildScriptsEnabled: Boolean = false +) + public data class JVMConfiguration( /** Which JVM target the Kotlin compiler uses. See Compiler.jvmTargetFrom for possible values. */ var target: String = "default" @@ -91,7 +98,8 @@ public data class Configuration( val compiler: CompilerConfiguration = CompilerConfiguration(), val completion: CompletionConfiguration = CompletionConfiguration(), val diagnostics: DiagnosticsConfiguration = DiagnosticsConfiguration(), - var indexing: IndexingConfiguration = IndexingConfiguration(), + val scripts: ScriptsConfiguration = ScriptsConfiguration(), + val indexing: IndexingConfiguration = IndexingConfiguration(), val externalSources: ExternalSourcesConfiguration = ExternalSourcesConfiguration(), val hints: InlayHintsConfiguration = InlayHintsConfiguration() ) diff --git a/server/src/main/kotlin/org/javacs/kt/KotlinLanguageServer.kt b/server/src/main/kotlin/org/javacs/kt/KotlinLanguageServer.kt index f243f7977..29998dc3a 100644 --- a/server/src/main/kotlin/org/javacs/kt/KotlinLanguageServer.kt +++ b/server/src/main/kotlin/org/javacs/kt/KotlinLanguageServer.kt @@ -22,15 +22,16 @@ import java.nio.file.Paths import java.util.concurrent.CompletableFuture import java.util.concurrent.CompletableFuture.completedFuture -class KotlinLanguageServer : LanguageServer, LanguageClientAware, Closeable { - val config = Configuration() +class KotlinLanguageServer( + val config: Configuration = Configuration() +) : LanguageServer, LanguageClientAware, Closeable { val databaseService = DatabaseService() - val classPath = CompilerClassPath(config.compiler, databaseService) + val classPath = CompilerClassPath(config.compiler, config.scripts, databaseService) 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) + val sourceFiles = SourceFiles(sourcePath, uriContentProvider, config.scripts) private val textDocuments = KotlinTextDocumentService(sourceFiles, sourcePath, config, tempDirectory, uriContentProvider, classPath) private val workspaces = KotlinWorkspaceService(sourceFiles, sourcePath, classPath, textDocuments, config) diff --git a/server/src/main/kotlin/org/javacs/kt/KotlinWorkspaceService.kt b/server/src/main/kotlin/org/javacs/kt/KotlinWorkspaceService.kt index 9091a0a38..ceafd6d6d 100644 --- a/server/src/main/kotlin/org/javacs/kt/KotlinWorkspaceService.kt +++ b/server/src/main/kotlin/org/javacs/kt/KotlinWorkspaceService.kt @@ -135,6 +135,13 @@ class KotlinWorkspaceService( } } + // Update scripts options + get("scripts")?.asJsonObject?.apply { + val scripts = config.scripts + get("enabled")?.asBoolean?.let { scripts.enabled = it } + get("buildScriptsEnabled")?.asBoolean?.let { scripts.buildScriptsEnabled = it } + } + // Update code-completion options get("completion")?.asJsonObject?.apply { val completion = config.completion diff --git a/server/src/main/kotlin/org/javacs/kt/SourceFiles.kt b/server/src/main/kotlin/org/javacs/kt/SourceFiles.kt index a333d6e69..9a723234d 100644 --- a/server/src/main/kotlin/org/javacs/kt/SourceFiles.kt +++ b/server/src/main/kotlin/org/javacs/kt/SourceFiles.kt @@ -65,7 +65,8 @@ private class NotifySourcePath(private val sp: SourcePath) { */ class SourceFiles( private val sp: SourcePath, - private val contentProvider: URIContentProvider + private val contentProvider: URIContentProvider, + private val scriptsConfig: ScriptsConfiguration ) { private val workspaceRoots = mutableSetOf() private var exclusions = SourceExclusions(workspaceRoots) @@ -175,6 +176,19 @@ class SourceFiles( updateExclusions() } + private fun findSourceFiles(root: Path): Set { + val glob = if (scriptsConfig.enabled) "*.{kt,kts}" else "*.kt" + val sourceMatcher = FileSystems.getDefault().getPathMatcher("glob:$glob") + return SourceExclusions(root) + .walkIncluded() + .filter { + sourceMatcher.matches(it.fileName) + && (scriptsConfig.buildScriptsEnabled || !it.endsWith(".gradle.kts")) + } + .map(Path::toUri) + .toSet() + } + private fun updateExclusions() { exclusions = SourceExclusions(workspaceRoots) } @@ -222,15 +236,6 @@ private fun patch(sourceText: String, change: TextDocumentContentChangeEvent): S } } -private fun findSourceFiles(root: Path): Set { - val sourceMatcher = FileSystems.getDefault().getPathMatcher("glob:*.{kt,kts}") - return SourceExclusions(root) - .walkIncluded() - .filter { sourceMatcher.matches(it.fileName) } - .map(Path::toUri) - .toSet() -} - private fun logAdded(sources: Collection, rootPath: Path?) { LOG.info("Adding {} under {} to source path", describeURIs(sources), rootPath) } diff --git a/server/src/main/kotlin/org/javacs/kt/compiler/Compiler.kt b/server/src/main/kotlin/org/javacs/kt/compiler/Compiler.kt index 1cfc25222..eef04b1dd 100644 --- a/server/src/main/kotlin/org/javacs/kt/compiler/Compiler.kt +++ b/server/src/main/kotlin/org/javacs/kt/compiler/Compiler.kt @@ -58,6 +58,7 @@ import kotlin.script.experimental.jvm.defaultJvmScriptingHostConfiguration import kotlin.script.experimental.jvm.JvmDependency import org.javacs.kt.LOG import org.javacs.kt.CompilerConfiguration +import org.javacs.kt.ScriptsConfiguration import org.javacs.kt.util.KotlinLSException import org.javacs.kt.util.LoggingMessageCollector import org.jetbrains.kotlin.cli.common.output.writeAllTo @@ -86,7 +87,8 @@ private val GRADLE_DSL_DEPENDENCY_PATTERN = Regex("^gradle-(?:kotlin-dsl|core).* */ private class CompilationEnvironment( javaSourcePath: Set, - classPath: Set + classPath: Set, + scriptsConfig: ScriptsConfiguration ) : Closeable { private val disposable = Disposer.newDisposable() @@ -127,275 +129,278 @@ private class CompilationEnvironment( addJvmClasspathRoots(classPath.map { it.toFile() }) addJavaSourceRoots(javaSourcePath.map { it.toFile() }) - // Setup script templates (e.g. used by Gradle's Kotlin DSL) - val scriptDefinitions: MutableList = mutableListOf(ScriptDefinition.getDefault(defaultJvmScriptingHostConfiguration)) - - if (classPath.any { GRADLE_DSL_DEPENDENCY_PATTERN.matches(it.fileName.toString()) }) { - LOG.info("Configuring Kotlin DSL script templates...") - - val scriptTemplates = listOf( - "org.gradle.kotlin.dsl.KotlinInitScript", - "org.gradle.kotlin.dsl.KotlinSettingsScript", - "org.gradle.kotlin.dsl.KotlinBuildScript" - ) - - try { - // Load template classes - val scriptClassLoader = URLClassLoader(classPath.map { it.toUri().toURL() }.toTypedArray()) - val fileClassPath = classPath.map { it.toFile() } - val scriptHostConfig = ScriptingHostConfiguration(defaultJvmScriptingHostConfiguration) { - configurationDependencies(JvmDependency(fileClassPath)) - } - // TODO: KotlinScriptDefinition will soon be deprecated, use - // ScriptDefinition.compilationConfiguration and its defaultImports instead - // of KotlinScriptDefinition.dependencyResolver - // TODO: Use ScriptDefinition.FromLegacyTemplate directly if possible - // scriptDefinitions = scriptTemplates.map { ScriptDefinition.FromLegacyTemplate(scriptHostConfig, scriptClassLoader.loadClass(it).kotlin) } - scriptDefinitions.addAll(scriptTemplates.map { ScriptDefinition.FromLegacy(scriptHostConfig, object : KotlinScriptDefinitionFromAnnotatedTemplate( - scriptClassLoader.loadClass(it).kotlin, - scriptHostConfig[ScriptingHostConfiguration.getEnvironment]?.invoke() - ) { - override fun isScript(fileName: String): Boolean { - // The pattern for KotlinSettingsScript doesn't seem to work well, so kinda "forcing it" for settings.gradle.kts files - if (this.template.simpleName == "KotlinSettingsScript" && fileName.endsWith("settings.gradle.kts")) { - return true - } - - return super.isScript(fileName) + if (scriptsConfig.enabled) { + // Setup script templates (e.g. used by Gradle's Kotlin DSL) + val scriptDefinitions: MutableList = mutableListOf(ScriptDefinition.getDefault(defaultJvmScriptingHostConfiguration)) + + val foundDSLDependency = classPath.any { GRADLE_DSL_DEPENDENCY_PATTERN.matches(it.fileName.toString()) } + if (scriptsConfig.buildScriptsEnabled && foundDSLDependency) { + LOG.info("Configuring Kotlin DSL script templates...") + + val scriptTemplates = listOf( + "org.gradle.kotlin.dsl.KotlinInitScript", + "org.gradle.kotlin.dsl.KotlinSettingsScript", + "org.gradle.kotlin.dsl.KotlinBuildScript" + ) + + try { + // Load template classes + val scriptClassLoader = URLClassLoader(classPath.map { it.toUri().toURL() }.toTypedArray()) + val fileClassPath = classPath.map { it.toFile() } + val scriptHostConfig = ScriptingHostConfiguration(defaultJvmScriptingHostConfiguration) { + configurationDependencies(JvmDependency(fileClassPath)) } + // TODO: KotlinScriptDefinition will soon be deprecated, use + // ScriptDefinition.compilationConfiguration and its defaultImports instead + // of KotlinScriptDefinition.dependencyResolver + // TODO: Use ScriptDefinition.FromLegacyTemplate directly if possible + // scriptDefinitions = scriptTemplates.map { ScriptDefinition.FromLegacyTemplate(scriptHostConfig, scriptClassLoader.loadClass(it).kotlin) } + scriptDefinitions.addAll(scriptTemplates.map { ScriptDefinition.FromLegacy(scriptHostConfig, object : KotlinScriptDefinitionFromAnnotatedTemplate( + scriptClassLoader.loadClass(it).kotlin, + scriptHostConfig[ScriptingHostConfiguration.getEnvironment]?.invoke() + ) { + override fun isScript(fileName: String): Boolean { + // The pattern for KotlinSettingsScript doesn't seem to work well, so kinda "forcing it" for settings.gradle.kts files + if (this.template.simpleName == "KotlinSettingsScript" && fileName.endsWith("settings.gradle.kts")) { + return true + } + + return super.isScript(fileName) + } - override val dependencyResolver: DependenciesResolver = object : DependenciesResolver { - override fun resolve(scriptContents: ScriptContents, environment: Environment) = ResolveResult.Success(ScriptDependencies( - imports = listOf( - "org.gradle.kotlin.dsl.*", - "org.gradle.kotlin.dsl.plugins.dsl.*", - "org.gradle.*", - "org.gradle.api.*", - "org.gradle.api.artifacts.*", - "org.gradle.api.artifacts.component.*", - "org.gradle.api.artifacts.dsl.*", - "org.gradle.api.artifacts.ivy.*", - "org.gradle.api.artifacts.maven.*", - "org.gradle.api.artifacts.query.*", - "org.gradle.api.artifacts.repositories.*", - "org.gradle.api.artifacts.result.*", - "org.gradle.api.artifacts.transform.*", - "org.gradle.api.artifacts.type.*", - "org.gradle.api.artifacts.verification.*", - "org.gradle.api.attributes.*", - "org.gradle.api.attributes.java.*", - "org.gradle.api.capabilities.*", - "org.gradle.api.component.*", - "org.gradle.api.credentials.*", - "org.gradle.api.distribution.*", - "org.gradle.api.distribution.plugins.*", - "org.gradle.api.execution.*", - "org.gradle.api.file.*", - "org.gradle.api.initialization.*", - "org.gradle.api.initialization.definition.*", - "org.gradle.api.initialization.dsl.*", - "org.gradle.api.invocation.*", - "org.gradle.api.java.archives.*", - "org.gradle.api.jvm.*", - "org.gradle.api.logging.*", - "org.gradle.api.logging.configuration.*", - "org.gradle.api.model.*", - "org.gradle.api.plugins.*", - "org.gradle.api.plugins.antlr.*", - "org.gradle.api.plugins.quality.*", - "org.gradle.api.plugins.scala.*", - "org.gradle.api.provider.*", - "org.gradle.api.publish.*", - "org.gradle.api.publish.ivy.*", - "org.gradle.api.publish.ivy.plugins.*", - "org.gradle.api.publish.ivy.tasks.*", - "org.gradle.api.publish.maven.*", - "org.gradle.api.publish.maven.plugins.*", - "org.gradle.api.publish.maven.tasks.*", - "org.gradle.api.publish.plugins.*", - "org.gradle.api.publish.tasks.*", - "org.gradle.api.reflect.*", - "org.gradle.api.reporting.*", - "org.gradle.api.reporting.components.*", - "org.gradle.api.reporting.dependencies.*", - "org.gradle.api.reporting.dependents.*", - "org.gradle.api.reporting.model.*", - "org.gradle.api.reporting.plugins.*", - "org.gradle.api.resources.*", - "org.gradle.api.services.*", - "org.gradle.api.specs.*", - "org.gradle.api.tasks.*", - "org.gradle.api.tasks.ant.*", - "org.gradle.api.tasks.application.*", - "org.gradle.api.tasks.bundling.*", - "org.gradle.api.tasks.compile.*", - "org.gradle.api.tasks.diagnostics.*", - "org.gradle.api.tasks.incremental.*", - "org.gradle.api.tasks.javadoc.*", - "org.gradle.api.tasks.options.*", - "org.gradle.api.tasks.scala.*", - "org.gradle.api.tasks.testing.*", - "org.gradle.api.tasks.testing.junit.*", - "org.gradle.api.tasks.testing.junitplatform.*", - "org.gradle.api.tasks.testing.testng.*", - "org.gradle.api.tasks.util.*", - "org.gradle.api.tasks.wrapper.*", - "org.gradle.authentication.*", - "org.gradle.authentication.aws.*", - "org.gradle.authentication.http.*", - "org.gradle.build.event.*", - "org.gradle.buildinit.plugins.*", - "org.gradle.buildinit.tasks.*", - "org.gradle.caching.*", - "org.gradle.caching.configuration.*", - "org.gradle.caching.http.*", - "org.gradle.caching.local.*", - "org.gradle.concurrent.*", - "org.gradle.external.javadoc.*", - "org.gradle.ide.visualstudio.*", - "org.gradle.ide.visualstudio.plugins.*", - "org.gradle.ide.visualstudio.tasks.*", - "org.gradle.ide.xcode.*", - "org.gradle.ide.xcode.plugins.*", - "org.gradle.ide.xcode.tasks.*", - "org.gradle.ivy.*", - "org.gradle.jvm.*", - "org.gradle.jvm.application.scripts.*", - "org.gradle.jvm.application.tasks.*", - "org.gradle.jvm.platform.*", - "org.gradle.jvm.plugins.*", - "org.gradle.jvm.tasks.*", - "org.gradle.jvm.tasks.api.*", - "org.gradle.jvm.test.*", - "org.gradle.jvm.toolchain.*", - "org.gradle.language.*", - "org.gradle.language.assembler.*", - "org.gradle.language.assembler.plugins.*", - "org.gradle.language.assembler.tasks.*", - "org.gradle.language.base.*", - "org.gradle.language.base.artifact.*", - "org.gradle.language.base.compile.*", - "org.gradle.language.base.plugins.*", - "org.gradle.language.base.sources.*", - "org.gradle.language.c.*", - "org.gradle.language.c.plugins.*", - "org.gradle.language.c.tasks.*", - "org.gradle.language.coffeescript.*", - "org.gradle.language.cpp.*", - "org.gradle.language.cpp.plugins.*", - "org.gradle.language.cpp.tasks.*", - "org.gradle.language.java.*", - "org.gradle.language.java.artifact.*", - "org.gradle.language.java.plugins.*", - "org.gradle.language.java.tasks.*", - "org.gradle.language.javascript.*", - "org.gradle.language.jvm.*", - "org.gradle.language.jvm.plugins.*", - "org.gradle.language.jvm.tasks.*", - "org.gradle.language.nativeplatform.*", - "org.gradle.language.nativeplatform.tasks.*", - "org.gradle.language.objectivec.*", - "org.gradle.language.objectivec.plugins.*", - "org.gradle.language.objectivec.tasks.*", - "org.gradle.language.objectivecpp.*", - "org.gradle.language.objectivecpp.plugins.*", - "org.gradle.language.objectivecpp.tasks.*", - "org.gradle.language.plugins.*", - "org.gradle.language.rc.*", - "org.gradle.language.rc.plugins.*", - "org.gradle.language.rc.tasks.*", - "org.gradle.language.routes.*", - "org.gradle.language.scala.*", - "org.gradle.language.scala.plugins.*", - "org.gradle.language.scala.tasks.*", - "org.gradle.language.scala.toolchain.*", - "org.gradle.language.swift.*", - "org.gradle.language.swift.plugins.*", - "org.gradle.language.swift.tasks.*", - "org.gradle.language.twirl.*", - "org.gradle.maven.*", - "org.gradle.model.*", - "org.gradle.nativeplatform.*", - "org.gradle.nativeplatform.platform.*", - "org.gradle.nativeplatform.plugins.*", - "org.gradle.nativeplatform.tasks.*", - "org.gradle.nativeplatform.test.*", - "org.gradle.nativeplatform.test.cpp.*", - "org.gradle.nativeplatform.test.cpp.plugins.*", - "org.gradle.nativeplatform.test.cunit.*", - "org.gradle.nativeplatform.test.cunit.plugins.*", - "org.gradle.nativeplatform.test.cunit.tasks.*", - "org.gradle.nativeplatform.test.googletest.*", - "org.gradle.nativeplatform.test.googletest.plugins.*", - "org.gradle.nativeplatform.test.plugins.*", - "org.gradle.nativeplatform.test.tasks.*", - "org.gradle.nativeplatform.test.xctest.*", - "org.gradle.nativeplatform.test.xctest.plugins.*", - "org.gradle.nativeplatform.test.xctest.tasks.*", - "org.gradle.nativeplatform.toolchain.*", - "org.gradle.nativeplatform.toolchain.plugins.*", - "org.gradle.normalization.*", - "org.gradle.platform.base.*", - "org.gradle.platform.base.binary.*", - "org.gradle.platform.base.component.*", - "org.gradle.platform.base.plugins.*", - "org.gradle.play.*", - "org.gradle.play.distribution.*", - "org.gradle.play.platform.*", - "org.gradle.play.plugins.*", - "org.gradle.play.plugins.ide.*", - "org.gradle.play.tasks.*", - "org.gradle.play.toolchain.*", - "org.gradle.plugin.devel.*", - "org.gradle.plugin.devel.plugins.*", - "org.gradle.plugin.devel.tasks.*", - "org.gradle.plugin.management.*", - "org.gradle.plugin.use.*", - "org.gradle.plugins.ear.*", - "org.gradle.plugins.ear.descriptor.*", - "org.gradle.plugins.ide.*", - "org.gradle.plugins.ide.api.*", - "org.gradle.plugins.ide.eclipse.*", - "org.gradle.plugins.ide.idea.*", - "org.gradle.plugins.javascript.base.*", - "org.gradle.plugins.javascript.coffeescript.*", - "org.gradle.plugins.javascript.envjs.*", - "org.gradle.plugins.javascript.envjs.browser.*", - "org.gradle.plugins.javascript.envjs.http.*", - "org.gradle.plugins.javascript.envjs.http.simple.*", - "org.gradle.plugins.javascript.jshint.*", - "org.gradle.plugins.javascript.rhino.*", - "org.gradle.plugins.signing.*", - "org.gradle.plugins.signing.signatory.*", - "org.gradle.plugins.signing.signatory.pgp.*", - "org.gradle.plugins.signing.type.*", - "org.gradle.plugins.signing.type.pgp.*", - "org.gradle.process.*", - "org.gradle.swiftpm.*", - "org.gradle.swiftpm.plugins.*", - "org.gradle.swiftpm.tasks.*", - "org.gradle.testing.base.*", - "org.gradle.testing.base.plugins.*", - "org.gradle.testing.jacoco.plugins.*", - "org.gradle.testing.jacoco.tasks.*", - "org.gradle.testing.jacoco.tasks.rules.*", - "org.gradle.testkit.runner.*", - "org.gradle.vcs.*", - "org.gradle.vcs.git.*", - "org.gradle.work.*", - "org.gradle.workers.*" - ) - )) - } - }) }) - } catch (e: Exception) { - LOG.error("Error while loading script template classes") - LOG.printStackTrace(e) + override val dependencyResolver: DependenciesResolver = object : DependenciesResolver { + override fun resolve(scriptContents: ScriptContents, environment: Environment) = ResolveResult.Success(ScriptDependencies( + imports = listOf( + "org.gradle.kotlin.dsl.*", + "org.gradle.kotlin.dsl.plugins.dsl.*", + "org.gradle.*", + "org.gradle.api.*", + "org.gradle.api.artifacts.*", + "org.gradle.api.artifacts.component.*", + "org.gradle.api.artifacts.dsl.*", + "org.gradle.api.artifacts.ivy.*", + "org.gradle.api.artifacts.maven.*", + "org.gradle.api.artifacts.query.*", + "org.gradle.api.artifacts.repositories.*", + "org.gradle.api.artifacts.result.*", + "org.gradle.api.artifacts.transform.*", + "org.gradle.api.artifacts.type.*", + "org.gradle.api.artifacts.verification.*", + "org.gradle.api.attributes.*", + "org.gradle.api.attributes.java.*", + "org.gradle.api.capabilities.*", + "org.gradle.api.component.*", + "org.gradle.api.credentials.*", + "org.gradle.api.distribution.*", + "org.gradle.api.distribution.plugins.*", + "org.gradle.api.execution.*", + "org.gradle.api.file.*", + "org.gradle.api.initialization.*", + "org.gradle.api.initialization.definition.*", + "org.gradle.api.initialization.dsl.*", + "org.gradle.api.invocation.*", + "org.gradle.api.java.archives.*", + "org.gradle.api.jvm.*", + "org.gradle.api.logging.*", + "org.gradle.api.logging.configuration.*", + "org.gradle.api.model.*", + "org.gradle.api.plugins.*", + "org.gradle.api.plugins.antlr.*", + "org.gradle.api.plugins.quality.*", + "org.gradle.api.plugins.scala.*", + "org.gradle.api.provider.*", + "org.gradle.api.publish.*", + "org.gradle.api.publish.ivy.*", + "org.gradle.api.publish.ivy.plugins.*", + "org.gradle.api.publish.ivy.tasks.*", + "org.gradle.api.publish.maven.*", + "org.gradle.api.publish.maven.plugins.*", + "org.gradle.api.publish.maven.tasks.*", + "org.gradle.api.publish.plugins.*", + "org.gradle.api.publish.tasks.*", + "org.gradle.api.reflect.*", + "org.gradle.api.reporting.*", + "org.gradle.api.reporting.components.*", + "org.gradle.api.reporting.dependencies.*", + "org.gradle.api.reporting.dependents.*", + "org.gradle.api.reporting.model.*", + "org.gradle.api.reporting.plugins.*", + "org.gradle.api.resources.*", + "org.gradle.api.services.*", + "org.gradle.api.specs.*", + "org.gradle.api.tasks.*", + "org.gradle.api.tasks.ant.*", + "org.gradle.api.tasks.application.*", + "org.gradle.api.tasks.bundling.*", + "org.gradle.api.tasks.compile.*", + "org.gradle.api.tasks.diagnostics.*", + "org.gradle.api.tasks.incremental.*", + "org.gradle.api.tasks.javadoc.*", + "org.gradle.api.tasks.options.*", + "org.gradle.api.tasks.scala.*", + "org.gradle.api.tasks.testing.*", + "org.gradle.api.tasks.testing.junit.*", + "org.gradle.api.tasks.testing.junitplatform.*", + "org.gradle.api.tasks.testing.testng.*", + "org.gradle.api.tasks.util.*", + "org.gradle.api.tasks.wrapper.*", + "org.gradle.authentication.*", + "org.gradle.authentication.aws.*", + "org.gradle.authentication.http.*", + "org.gradle.build.event.*", + "org.gradle.buildinit.plugins.*", + "org.gradle.buildinit.tasks.*", + "org.gradle.caching.*", + "org.gradle.caching.configuration.*", + "org.gradle.caching.http.*", + "org.gradle.caching.local.*", + "org.gradle.concurrent.*", + "org.gradle.external.javadoc.*", + "org.gradle.ide.visualstudio.*", + "org.gradle.ide.visualstudio.plugins.*", + "org.gradle.ide.visualstudio.tasks.*", + "org.gradle.ide.xcode.*", + "org.gradle.ide.xcode.plugins.*", + "org.gradle.ide.xcode.tasks.*", + "org.gradle.ivy.*", + "org.gradle.jvm.*", + "org.gradle.jvm.application.scripts.*", + "org.gradle.jvm.application.tasks.*", + "org.gradle.jvm.platform.*", + "org.gradle.jvm.plugins.*", + "org.gradle.jvm.tasks.*", + "org.gradle.jvm.tasks.api.*", + "org.gradle.jvm.test.*", + "org.gradle.jvm.toolchain.*", + "org.gradle.language.*", + "org.gradle.language.assembler.*", + "org.gradle.language.assembler.plugins.*", + "org.gradle.language.assembler.tasks.*", + "org.gradle.language.base.*", + "org.gradle.language.base.artifact.*", + "org.gradle.language.base.compile.*", + "org.gradle.language.base.plugins.*", + "org.gradle.language.base.sources.*", + "org.gradle.language.c.*", + "org.gradle.language.c.plugins.*", + "org.gradle.language.c.tasks.*", + "org.gradle.language.coffeescript.*", + "org.gradle.language.cpp.*", + "org.gradle.language.cpp.plugins.*", + "org.gradle.language.cpp.tasks.*", + "org.gradle.language.java.*", + "org.gradle.language.java.artifact.*", + "org.gradle.language.java.plugins.*", + "org.gradle.language.java.tasks.*", + "org.gradle.language.javascript.*", + "org.gradle.language.jvm.*", + "org.gradle.language.jvm.plugins.*", + "org.gradle.language.jvm.tasks.*", + "org.gradle.language.nativeplatform.*", + "org.gradle.language.nativeplatform.tasks.*", + "org.gradle.language.objectivec.*", + "org.gradle.language.objectivec.plugins.*", + "org.gradle.language.objectivec.tasks.*", + "org.gradle.language.objectivecpp.*", + "org.gradle.language.objectivecpp.plugins.*", + "org.gradle.language.objectivecpp.tasks.*", + "org.gradle.language.plugins.*", + "org.gradle.language.rc.*", + "org.gradle.language.rc.plugins.*", + "org.gradle.language.rc.tasks.*", + "org.gradle.language.routes.*", + "org.gradle.language.scala.*", + "org.gradle.language.scala.plugins.*", + "org.gradle.language.scala.tasks.*", + "org.gradle.language.scala.toolchain.*", + "org.gradle.language.swift.*", + "org.gradle.language.swift.plugins.*", + "org.gradle.language.swift.tasks.*", + "org.gradle.language.twirl.*", + "org.gradle.maven.*", + "org.gradle.model.*", + "org.gradle.nativeplatform.*", + "org.gradle.nativeplatform.platform.*", + "org.gradle.nativeplatform.plugins.*", + "org.gradle.nativeplatform.tasks.*", + "org.gradle.nativeplatform.test.*", + "org.gradle.nativeplatform.test.cpp.*", + "org.gradle.nativeplatform.test.cpp.plugins.*", + "org.gradle.nativeplatform.test.cunit.*", + "org.gradle.nativeplatform.test.cunit.plugins.*", + "org.gradle.nativeplatform.test.cunit.tasks.*", + "org.gradle.nativeplatform.test.googletest.*", + "org.gradle.nativeplatform.test.googletest.plugins.*", + "org.gradle.nativeplatform.test.plugins.*", + "org.gradle.nativeplatform.test.tasks.*", + "org.gradle.nativeplatform.test.xctest.*", + "org.gradle.nativeplatform.test.xctest.plugins.*", + "org.gradle.nativeplatform.test.xctest.tasks.*", + "org.gradle.nativeplatform.toolchain.*", + "org.gradle.nativeplatform.toolchain.plugins.*", + "org.gradle.normalization.*", + "org.gradle.platform.base.*", + "org.gradle.platform.base.binary.*", + "org.gradle.platform.base.component.*", + "org.gradle.platform.base.plugins.*", + "org.gradle.play.*", + "org.gradle.play.distribution.*", + "org.gradle.play.platform.*", + "org.gradle.play.plugins.*", + "org.gradle.play.plugins.ide.*", + "org.gradle.play.tasks.*", + "org.gradle.play.toolchain.*", + "org.gradle.plugin.devel.*", + "org.gradle.plugin.devel.plugins.*", + "org.gradle.plugin.devel.tasks.*", + "org.gradle.plugin.management.*", + "org.gradle.plugin.use.*", + "org.gradle.plugins.ear.*", + "org.gradle.plugins.ear.descriptor.*", + "org.gradle.plugins.ide.*", + "org.gradle.plugins.ide.api.*", + "org.gradle.plugins.ide.eclipse.*", + "org.gradle.plugins.ide.idea.*", + "org.gradle.plugins.javascript.base.*", + "org.gradle.plugins.javascript.coffeescript.*", + "org.gradle.plugins.javascript.envjs.*", + "org.gradle.plugins.javascript.envjs.browser.*", + "org.gradle.plugins.javascript.envjs.http.*", + "org.gradle.plugins.javascript.envjs.http.simple.*", + "org.gradle.plugins.javascript.jshint.*", + "org.gradle.plugins.javascript.rhino.*", + "org.gradle.plugins.signing.*", + "org.gradle.plugins.signing.signatory.*", + "org.gradle.plugins.signing.signatory.pgp.*", + "org.gradle.plugins.signing.type.*", + "org.gradle.plugins.signing.type.pgp.*", + "org.gradle.process.*", + "org.gradle.swiftpm.*", + "org.gradle.swiftpm.plugins.*", + "org.gradle.swiftpm.tasks.*", + "org.gradle.testing.base.*", + "org.gradle.testing.base.plugins.*", + "org.gradle.testing.jacoco.plugins.*", + "org.gradle.testing.jacoco.tasks.*", + "org.gradle.testing.jacoco.tasks.rules.*", + "org.gradle.testkit.runner.*", + "org.gradle.vcs.*", + "org.gradle.vcs.git.*", + "org.gradle.work.*", + "org.gradle.workers.*" + ) + )) + } + }) }) + } catch (e: Exception) { + LOG.error("Error while loading script template classes") + LOG.printStackTrace(e) + } } - } - LOG.info("Adding script definitions ${scriptDefinitions.map { it.asLegacyOrNull()?.template?.simpleName }}") - addAll(ScriptingConfigurationKeys.SCRIPT_DEFINITIONS, scriptDefinitions) + LOG.info("Adding script definitions ${scriptDefinitions.map { it.asLegacyOrNull()?.template?.simpleName }}") + addAll(ScriptingConfigurationKeys.SCRIPT_DEFINITIONS, scriptDefinitions) + } }, configFiles = EnvironmentConfigFiles.JVM_CONFIG_FILES ) @@ -450,12 +455,20 @@ enum class CompilationKind { * Incrementally compiles files and expressions. * The basic strategy for compiling one file at-a-time is outlined in OneFilePerformance. */ -class Compiler(javaSourcePath: Set, classPath: Set, buildScriptClassPath: Set = emptySet(), private val outputDirectory: File) : Closeable { +class Compiler( + javaSourcePath: Set, + classPath: Set, + buildScriptClassPath: Set = emptySet(), + scriptsConfig: ScriptsConfiguration, + private val outputDirectory: File, +) : Closeable { private var closed = false private val localFileSystem: VirtualFileSystem - private val defaultCompileEnvironment = CompilationEnvironment(javaSourcePath, classPath) - private val buildScriptCompileEnvironment = buildScriptClassPath.takeIf { it.isNotEmpty() }?.let { CompilationEnvironment(emptySet(), it) } + private val defaultCompileEnvironment = CompilationEnvironment(javaSourcePath, classPath, scriptsConfig) + private val buildScriptCompileEnvironment = buildScriptClassPath + .takeIf { it.isNotEmpty() && scriptsConfig.enabled && scriptsConfig.buildScriptsEnabled } + ?.let { CompilationEnvironment(emptySet(), it, scriptsConfig) } private val compileLock = ReentrantLock() // TODO: Lock at file-level companion object { diff --git a/server/src/test/kotlin/org/javacs/kt/CompiledFileTest.kt b/server/src/test/kotlin/org/javacs/kt/CompiledFileTest.kt index d1e034cea..6a765bf88 100644 --- a/server/src/test/kotlin/org/javacs/kt/CompiledFileTest.kt +++ b/server/src/test/kotlin/org/javacs/kt/CompiledFileTest.kt @@ -3,6 +3,7 @@ package org.javacs.kt import org.hamcrest.Matchers.equalTo import org.javacs.kt.compiler.Compiler import org.javacs.kt.database.DatabaseService +import org.javacs.kt.ScriptsConfiguration import org.junit.AfterClass import org.junit.Assert.assertThat import org.junit.Test @@ -26,11 +27,16 @@ class CompiledFileTest { } } - fun compileFile(): CompiledFile = Compiler(setOf(), setOf(), outputDirectory = outputDirectory).use { compiler -> + fun compileFile(): CompiledFile = Compiler( + javaSourcePath = setOf(), + classPath = setOf(), + scriptsConfig = ScriptsConfiguration(), + outputDirectory = outputDirectory + ).use { compiler -> val file = testResourcesRoot().resolve("compiledFile/CompiledFileExample.kt") val content = Files.readAllLines(file).joinToString("\n") val parse = compiler.createKtFile(content, file) - val classPath = CompilerClassPath(CompilerConfiguration(), DatabaseService()) + val classPath = CompilerClassPath(CompilerConfiguration(), ScriptsConfiguration(), DatabaseService()) val sourcePath = listOf(parse) val (context, container) = compiler.compileKtFiles(sourcePath, sourcePath) CompiledFile(content, parse, context, container, sourcePath, classPath) diff --git a/server/src/test/kotlin/org/javacs/kt/CompilerTest.kt b/server/src/test/kotlin/org/javacs/kt/CompilerTest.kt index 0c96c094c..732dd1403 100644 --- a/server/src/test/kotlin/org/javacs/kt/CompilerTest.kt +++ b/server/src/test/kotlin/org/javacs/kt/CompilerTest.kt @@ -7,6 +7,7 @@ import org.jetbrains.kotlin.psi.KtReferenceExpression import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf import org.jetbrains.kotlin.resolve.BindingContext import org.javacs.kt.compiler.Compiler +import org.javacs.kt.ScriptsConfiguration import org.junit.Assert.assertThat import org.junit.Test import org.junit.After @@ -30,7 +31,12 @@ private class FileToEdit { @JvmStatic @BeforeClass fun setup() { LOG.connectStdioBackend() outputDirectory = Files.createTempDirectory("klsBuildOutput").toFile() - compiler = Compiler(setOf(), setOf(), outputDirectory = outputDirectory) + compiler = Compiler( + javaSourcePath = setOf(), + classPath = setOf(), + scriptsConfig = ScriptsConfiguration(), + outputDirectory = outputDirectory + ) } @JvmStatic @AfterClass diff --git a/server/src/test/kotlin/org/javacs/kt/GradleDSLScriptTest.kt b/server/src/test/kotlin/org/javacs/kt/GradleDSLScriptTest.kt index 0f15e59a4..72de5fe43 100644 --- a/server/src/test/kotlin/org/javacs/kt/GradleDSLScriptTest.kt +++ b/server/src/test/kotlin/org/javacs/kt/GradleDSLScriptTest.kt @@ -1,11 +1,15 @@ package org.javacs.kt +import org.junit.Before import org.junit.Test import org.junit.Assert.assertThat import org.hamcrest.Matchers.* import org.eclipse.lsp4j.MarkupContent -class GradleDSLScriptTest : SingleFileTestFixture("kotlinDSLWorkspace", "build.gradle.kts") { +class GradleDSLScriptTest : SingleFileTestFixture("kotlinDSLWorkspace", "build.gradle.kts", Configuration().apply { + scripts.enabled = true + scripts.buildScriptsEnabled = true +}) { @Test fun `edit repositories`() { val completions = languageServer.textDocumentService.completion(completionParams(file, 7, 13)).get().right!! val labels = completions.items.map { it.label } diff --git a/server/src/test/kotlin/org/javacs/kt/LanguageServerTestFixture.kt b/server/src/test/kotlin/org/javacs/kt/LanguageServerTestFixture.kt index 8b655e8a1..25edde55b 100644 --- a/server/src/test/kotlin/org/javacs/kt/LanguageServerTestFixture.kt +++ b/server/src/test/kotlin/org/javacs/kt/LanguageServerTestFixture.kt @@ -8,9 +8,12 @@ import java.nio.file.Path import java.nio.file.Paths import java.util.concurrent.CompletableFuture -abstract class LanguageServerTestFixture(relativeWorkspaceRoot: String) : LanguageClient { +abstract class LanguageServerTestFixture( + relativeWorkspaceRoot: String, + config: Configuration = Configuration() +) : LanguageClient { val workspaceRoot = absoluteWorkspaceRoot(relativeWorkspaceRoot) - val languageServer = createLanguageServer() + val languageServer = createLanguageServer(config) var diagnostics = listOf() val errors: List @@ -23,8 +26,8 @@ abstract class LanguageServerTestFixture(relativeWorkspaceRoot: String) : Langua return testResources.resolve(relativeWorkspaceRoot) } - private fun createLanguageServer(): KotlinLanguageServer { - val languageServer = KotlinLanguageServer() + private fun createLanguageServer(config: Configuration): KotlinLanguageServer { + val languageServer = KotlinLanguageServer(config) val init = InitializeParams().apply { capabilities = ClientCapabilities().apply { textDocument = TextDocumentClientCapabilities().apply { @@ -177,7 +180,11 @@ fun testResourcesRoot(): Path { return Paths.get(anchorTxt).parent!! } -open class SingleFileTestFixture(relativeWorkspaceRoot: String, val file: String) : LanguageServerTestFixture(relativeWorkspaceRoot) { +open class SingleFileTestFixture( + relativeWorkspaceRoot: String, + val file: String, + config: Configuration = Configuration() +) : LanguageServerTestFixture(relativeWorkspaceRoot, config) { @Before fun openFile() { open(file)