diff --git a/README.md b/README.md index 91a4d7c2..6e8c45ff 100644 --- a/README.md +++ b/README.md @@ -37,15 +37,15 @@ The project uses the internal APIs of the [Kotlin compiler](https://github.com/J ### Figuring out the dependencies -Dependencies are determined by the [DefaultClassPathResolver.kt](shared/src/main/kotlin/org/javacs/kt/classpath/DefaultClassPathResolver.kt), which invokes Maven or Gradle to get a list of classpath JARs. Alternatively, projects can also 'manually' provide a list of dependencies through a shell script, located either at `[project root]/kotlinLspClasspath.{sh,bat,cmd}` or `[config root]/KotlinLanguageServer/classpath.{sh,bat,cmd}`, which outputs a list of JARs. +Dependencies are determined by the [DefaultClassPathResolver.kt](shared/src/main/kotlin/org/javacs/kt/classpath/DefaultClassPathResolver.kt), which invokes Maven or Gradle to get a list of classpath JARs. Alternatively, projects can also 'manually' provide a list of dependencies through a shell script, located either at `[project root]/kls-classpath` or `[config root]/kotlin-language-server/classpath`, which outputs a list of JARs. Depending on your platform, the scripts also can be suffixed with `.{sh,bat,cmd}`. -* Example of the `~/.config/KotlinLanguageServer/classpath.sh` on Linux: +* Example of the `~/.config/kotlin-language-server/classpath` on Linux: ```bash #!/bin/bash echo /my/path/kotlin-compiler-1.4.10/lib/kotlin-stdlib.jar:/my/path/my-lib.jar ``` -* Example of the `%HOMEPATH%\.config\KotlinLanguageServer\classpath.bat` on Windows: +* Example of the `%HOMEPATH%\.config\kotlin-language-server\classpath.bat` on Windows: ```cmd @echo off echo C:\my\path\kotlin-compiler-1.4.10\lib\kotlin-stdlib.jar;C:\my\path\my-lib.jar diff --git a/detekt.yml b/detekt.yml index 79817ef8..c63e1b45 100644 --- a/detekt.yml +++ b/detekt.yml @@ -10,3 +10,7 @@ exceptions: - NumberFormatException - ParseException - MissingPropertyException + +style: + MaxLineLength: + active: false diff --git a/detekt_baseline.xml b/detekt_baseline.xml index c6681def..f2aada54 100644 --- a/detekt_baseline.xml +++ b/detekt_baseline.xml @@ -181,245 +181,6 @@ MatchingDeclarationName:Main.kt$Args MatchingDeclarationName:Spaces.kt$Test MatchingDeclarationName:When.kt$SealedClass - MaxLineLength:Accessors46nwrg1rs44ofdqpi7vyy3pfc.kt$(this as org.gradle.api.plugins.ExtensionAware).extensions.getByName("ext") as org.gradle.api.plugins.ExtraPropertiesExtension - MaxLineLength:Accessors46nwrg1rs44ofdqpi7vyy3pfc.kt$fun - MaxLineLength:Accessors8lcri9ibgd9oj8dt3t8z8nvfx.kt$(this as org.gradle.api.plugins.ExtensionAware).extensions.getByName("ext") as org.gradle.api.plugins.ExtraPropertiesExtension - MaxLineLength:Accessors8lcri9ibgd9oj8dt3t8z8nvfx.kt$fun - MaxLineLength:Accessorsasa455whv8s4bk3c97fzgde0p.kt$(this as org.gradle.api.plugins.ExtensionAware).extensions.getByName("ext") as org.gradle.api.plugins.ExtraPropertiesExtension - MaxLineLength:Accessorsasa455whv8s4bk3c97fzgde0p.kt$fun - MaxLineLength:Accessorsblypoh2ruc9u3bx9djsfqsntg.kt$(this as org.gradle.api.plugins.ExtensionAware).extensions.getByName("ext") as org.gradle.api.plugins.ExtraPropertiesExtension - MaxLineLength:Accessorscchdiujech8u294vwhihsq7gh.kt$(this as org.gradle.api.plugins.ExtensionAware).extensions.getByName("publishing") as org.gradle.api.publish.PublishingExtension - MaxLineLength:AddMissingImportsQuickFix.kt$AddMissingImportsQuickFix$override - MaxLineLength:AddMissingImportsQuickFix.kt$AddMissingImportsQuickFix$private - MaxLineLength:AdditionalWorkspaceTest.kt$AdditionalWorkspaceTest$val hoverAgain = languageServer.textDocumentService.hover(hoverParams(file, 5, 14)).get() ?: return fail("No hover") - MaxLineLength:BackupClassPathResolver.kt$?: - MaxLineLength:BackupClassPathResolver.kt$BackupClassPathResolver$override val classpath: Set<ClassPathEntry> get() = findKotlinStdlib()?.let { setOf(it) }.orEmpty().map { ClassPathEntry(it, null) }.toSet() - MaxLineLength:BackupClassPathResolver.kt$private - MaxLineLength:BackupClassPathResolver.kt$private fun Path.resolveStartingWith(prefix: String) - MaxLineLength:BackupClassPathResolver.kt$tryResolving("$artifact using Maven") { tryFindingLocalArtifactUsing(group, artifact, findLocalArtifactDirUsingMaven(group, artifact)) } - MaxLineLength:BigFile.kt$BigFile$println("You have passed '${args[0]}' as a number of bottles, " + "but it is not a valid integer number") - MaxLineLength:ClassContentProvider.kt$ClassContentProvider$"java" -> if (uri.source) Pair(uri.readContents(), "java") else Pair(convertToKotlinIfNeeded(uri.readContents()), "kt") - MaxLineLength:ClassContentProvider.kt$ClassContentProvider$val resolvedUri = sourceArchiveProvider.fetchSourceArchive(uri.archivePath)?.let(uri.withSource(true)::withArchivePath) ?: uri - MaxLineLength:ClassPathResolver.kt$FirstNonEmptyClassPathResolver$internal - MaxLineLength:ClassPathResolver.kt$FirstNonEmptyClassPathResolver$override val buildScriptClasspath get() = lhs.buildScriptClasspath.takeIf { it.isNotEmpty() } ?: rhs.buildScriptClasspath - MaxLineLength:ClassPathResolver.kt$FirstNonEmptyClassPathResolver$override val buildScriptClasspathOrEmpty get() = lhs.buildScriptClasspathOrEmpty.takeIf { it.isNotEmpty() } ?: rhs.buildScriptClasspathOrEmpty - MaxLineLength:ClassPathResolver.kt$infix - MaxLineLength:CodeAction.kt$fun - MaxLineLength:CompiledFile.kt$CompiledFile$// Otherwise the compiler/analyzer would throw an exception due to a missing TopLevelDescriptorProvider - MaxLineLength:CompiledFile.kt$CompiledFile$fun - MaxLineLength:CompiledFile.kt$CompiledFile$private - MaxLineLength:CompiledFile.kt$CompiledFile$surroundingContent = content.substring(recoveryRange.startOffset, content.length - (parse.text.length - recoveryRange.endOffset)) - MaxLineLength:CompiledFile.kt$CompiledFile$val cursorExpr = element?.findParent<KtExpression>() ?: return nullResult("Couldn't find expression at ${describePosition(cursor)} (only found $element)") - MaxLineLength:CompiledFile.kt$CompiledFile$val cursorExpr = parseAtPoint(cursor, asReference = true)?.findParent<KtExpression>() ?: return nullResult("Couldn't find expression at ${describePosition(cursor)}") - MaxLineLength:CompiledFile.kt$CompiledFile$val psi = parse.findElementAt(oldCursor) ?: return nullResult("Couldn't find anything at ${describePosition(cursor)}") - MaxLineLength:CompiledFile.kt$CompiledFile$val recompile = classPath.compiler.createKtFile(padOffset + surroundingContent, Paths.get("dummy.virtual" + if (isScript) ".kts" else ".kt"), kind) - MaxLineLength:Compiler.kt$CompilationEnvironment$// scriptDefinitions = scriptTemplates.map { ScriptDefinition.FromLegacyTemplate(scriptHostConfig, scriptClassLoader.loadClass(it).kotlin) } - MaxLineLength:Compiler.kt$CompilationEnvironment$LOG.info("Adding script definitions ${scriptDefinitions.map { it.asLegacyOrNull<KotlinScriptDefinition>()?.template?.simpleName }}") - MaxLineLength:Compiler.kt$CompilationEnvironment$StorageComponentContainerContributor.registerExtension(environment.project, CliSamWithReceiverComponentContributor(annotations)) - MaxLineLength:Compiler.kt$CompilationEnvironment$scriptDefinitions - MaxLineLength:Compiler.kt$CompilationEnvironment$val annotations = scriptDefinitions.flatMap { it.asLegacyOrNull<KotlinScriptDefinition>()?.annotationsForSamWithReceivers ?: emptyList() } - MaxLineLength:Compiler.kt$CompilationEnvironment$val scriptDefinitions: List<ScriptDefinition> = environment.configuration.getList(ScriptingConfigurationKeys.SCRIPT_DEFINITIONS) - MaxLineLength:Compiler.kt$CompilationEnvironment$val scriptDefinitions: MutableList<ScriptDefinition> = mutableListOf(ScriptDefinition.getDefault(defaultJvmScriptingHostConfiguration)) - MaxLineLength:Compiler.kt$CompilationEnvironment.<no name provided>$// The pattern for KotlinSettingsScript doesn't seem to work well, so kinda "forcing it" for settings.gradle.kts files - MaxLineLength:Compiler.kt$CompilationEnvironment.<no name provided>$if - MaxLineLength:Compiler.kt$CompilationEnvironment.<no name provided>.<no name provided>$override - MaxLineLength:Compiler.kt$Compiler$class - MaxLineLength:Compiler.kt$Compiler$file.packageFqName.asString().replace(".", File.separator) + File.separator + declaration.name + ".class" - MaxLineLength:Compiler.kt$Compiler$files.forEach { LOG.debug { "$it -> ScriptDefinition: ${it.findScriptDefinition()?.asLegacyOrNull<KotlinScriptDefinition>()?.template?.simpleName}" } } - MaxLineLength:Compiler.kt$Compiler$fun - MaxLineLength:Compiler.kt$Compiler$private val buildScriptCompileEnvironment = buildScriptClassPath.takeIf { it.isNotEmpty() }?.let { CompilationEnvironment(emptySet(), it) } - MaxLineLength:CompilerClassPath.kt$CompilerClassPath$compiler = Compiler(javaSourcePath, classPath.map { it.compiledJar }.toSet(), buildScriptClassPath, outputDirectory) - MaxLineLength:CompilerClassPath.kt$CompilerClassPath$private fun isBuildScript(file: Path): Boolean - MaxLineLength:CompilerClassPath.kt$CompilerClassPath$return refresh(updateClassPath = buildScript, updateBuildScriptClassPath = false, updateJavaSourcePath = javaSource) - MaxLineLength:CompilerClassPath.kt$CompilerClassPath$var - MaxLineLength:CompilerTest.kt$CompilerTest$val intFunctionRef = recompile.findElementAt(41)!!.parentsWithSelf.filterIsInstance<KtReferenceExpression>().first() - MaxLineLength:Completions.kt$+ - MaxLineLength:Completions.kt$. - MaxLineLength:Completions.kt$LOG.info("{} {} didn't look like a type, a member, or an identifier", surroundingElement::class.simpleName, surroundingElement.text) - MaxLineLength:Completions.kt$completeMembers(file, cursor, surroundingElement.receiverExpression, surroundingElement is KtSafeQualifiedExpression) - MaxLineLength:Completions.kt$is KtQualifiedExpression -> getQueryNameFromExpression(element.receiverExpression, element.receiverExpression.startOffset, file) - MaxLineLength:Completions.kt$private - MaxLineLength:Completions.kt$private val TYPES_FILTER = DescriptorKindFilter(DescriptorKindFilter.NON_SINGLETON_CLASSIFIERS_MASK or DescriptorKindFilter.TYPE_ALIASES_MASK) - MaxLineLength:Completions.kt$private val loggedHidden = CacheBuilder.newBuilder().expireAfterWrite(1, TimeUnit.MINUTES).build<Pair<Name, Name>, Unit>() - MaxLineLength:Completions.kt$return ElementCompletionItems(visible.map { completionItem(it, surroundingElement, file, config) }, surroundingElement) - MaxLineLength:Completions.kt$val - MaxLineLength:Completions.kt$val companionDescriptors = if (hasCompanionObject && companionObjectDescriptor != null) companionObjectDescriptor!!.getDescriptors() else emptySequence() - MaxLineLength:Completions.kt$val match = Regex("import ((\\w+\\.)*)[\\w*]*").matchEntire(surroundingElement.text) ?: return doesntLookLikeImport(surroundingElement) - MaxLineLength:Completions.kt$val receiverType = extensionFunction.extensionReceiverParameter?.type?.replaceArgumentsWithStarProjections() ?: return false - MaxLineLength:Completions.kt$val scope = file.scopeAtPoint(surroundingElement.startOffset) ?: return noResult("No scope at ${file.describePosition(cursor)}", emptySequence()) - MaxLineLength:CompletionsTest.kt$EditCallTest$assertThat(completions.items.find { it.label.startsWith("println") }, hasProperty("insertText", equalTo("println"))) - MaxLineLength:CompletionsTest.kt$FunctionScopeTest$assertThat("Reports aClassFun only once", completions.items.filter { it.label.startsWith("aClassFun") }, hasSize(1)) - MaxLineLength:CompletionsTest.kt$FunctionScopeTest$assertThat("Reports aCompanionFun only once", completions.items.filter { it.label.startsWith("aCompanionFun") }, hasSize(1)) - MaxLineLength:CompletionsTest.kt$FunctionScopeTest$assertThat("Reports aCompanionVal only once", completions.items.filter { it.label == "aCompanionVal" }, hasSize(1)) - MaxLineLength:CompletionsTest.kt$InstanceMemberTest$assertThat("Reports extensionFoo only once", completions.items.filter { it.label.startsWith("extensionFoo") }, hasSize(1)) - MaxLineLength:CompletionsTest.kt$InstanceMemberTest$assertThat("Reports instanceFoo only once", completions.items.filter { it.label.startsWith("instanceFoo") }, hasSize(1)) - MaxLineLength:CompletionsTest.kt$InstanceMemberTest$assertThat(completions.items.filter { it.label.startsWith("instanceFoo") }.firstOrNull(), hasProperty("insertText", equalTo("instanceFoo"))) - MaxLineLength:CompletionsTest.kt$TrailingLambdaTest$assertThat(completions.items.find { it.label.startsWith("lambdaParameter") }, hasProperty("insertText", equalTo("lambdaParameter { \${1:x} }"))) - MaxLineLength:CompletionsTest.kt$TrailingLambdaTest$assertThat(completions.items.find { it.label.startsWith("mixedParameters") }, hasProperty("insertText", equalTo("mixedParameters(\${1:a}) { \${2:b} }"))) - MaxLineLength:CompletionsTest.kt$VisibilityTest$assertThat(labels, hasItems(startsWith("privateThisFun"), startsWith("protectedThisFun"), startsWith("publicThisFun"), startsWith("privateThisCompanionFun"), startsWith("protectedThisCompanionFun"), startsWith("publicThisCompanionFun"), startsWith("privateTopLevelFun"))) - MaxLineLength:CompletionsTest.kt$VisibilityTest$assertThat(labels, hasItems(startsWith("protectedSuperFun"), startsWith("publicSuperFun"), startsWith("protectedSuperCompanionFun"), startsWith("publicSuperCompanionFun"))) - MaxLineLength:CompletionsTest.kt$VisibilityTest$assertThat(labels, not(hasItems(startsWith("privateSuperFun"), startsWith("privateSuperCompanionFun"), startsWith("publicExtensionFun")))) - MaxLineLength:Debouncer.kt$Debouncer$val currentTask = executor.schedule({ task { currentTaskRef.get()?.isCancelled() ?: false } }, delayMs, TimeUnit.MILLISECONDS) - MaxLineLength:DocumentSymbolsTest.kt$DocumentSymbolsTest$DocumentSymbol("DocumentSymbols", SymbolKind.Constructor, Range(Position(0, 29), Position(0, 31)), Range(Position(0, 29), Position(0, 31)), null, listOf()) - MaxLineLength:DocumentSymbolsTest.kt$DocumentSymbolsTest$DocumentSymbol("DocumentSymbols", SymbolKind.Constructor, Range(Position(6, 4), Position(7, 5)), Range(Position(6, 4), Position(7, 5)), null, listOf()) - MaxLineLength:DocumentSymbolsTest.kt$DocumentSymbolsTest$DocumentSymbol("aFunction", SymbolKind.Function, Range(Position(3, 4), Position(4, 5)), Range(Position(3, 8), Position(3, 17)), null, listOf()) - MaxLineLength:DocumentSymbolsTest.kt$DocumentSymbolsTest$DocumentSymbol("aProperty", SymbolKind.Property, Range(Position(1, 4), Position(1, 21)), Range(Position(1, 8), Position(1, 17)), null, listOf()) - MaxLineLength:DocumentSymbolsTest.kt$DocumentSymbolsTest$val - MaxLineLength:ExtractSymbolExtensionReceiverType.kt$ExtractSymbolExtensionReceiverType$override fun visitFunctionDescriptor(desc: FunctionDescriptor, nothing: Unit?) - MaxLineLength:ExtractSymbolExtensionReceiverType.kt$ExtractSymbolExtensionReceiverType$override fun visitVariableDescriptor(desc: VariableDescriptor, nothing: Unit?) - MaxLineLength:ExtractSymbolExtensionReceiverType.kt$ExtractSymbolExtensionReceiverType$private fun convert(desc: ReceiverParameterDescriptor): FqName? - MaxLineLength:ExtractSymbolKind.kt$ExtractSymbolKind$override fun visitReceiverParameterDescriptor(desc: ReceiverParameterDescriptor, nothing: Unit?) - MaxLineLength:ExtractSymbolVisibility.kt$ExtractSymbolVisibility$override fun visitPackageFragmentDescriptor(desc: PackageFragmentDescriptor, nothing: Unit?) - MaxLineLength:ExtractSymbolVisibility.kt$ExtractSymbolVisibility$override fun visitPropertyGetterDescriptor(desc: PropertyGetterDescriptor, nothing: Unit?) - MaxLineLength:ExtractSymbolVisibility.kt$ExtractSymbolVisibility$override fun visitPropertySetterDescriptor(desc: PropertySetterDescriptor, nothing: Unit?) - MaxLineLength:ExtractSymbolVisibility.kt$ExtractSymbolVisibility$override fun visitReceiverParameterDescriptor(desc: ReceiverParameterDescriptor, nothing: Unit?) - MaxLineLength:ExtractSymbolVisibility.kt$ExtractSymbolVisibility$override fun visitValueParameterDescriptor(desc: ValueParameterDescriptor, nothing: Unit?) - MaxLineLength:FernflowerDecompiler.kt$FernflowerDecompiler$throw KotlinLSException("Could not decompile ${compiledClassOrJar.fileName}: Fernflower did not generate sources at ${srcOutPath.fileName}") - MaxLineLength:FindReferences.kt$if - MaxLineLength:FindReferences.kt$isComponent(descriptor) -> findComponentReferences(declaration, bindingContext) + findNameReferences(declaration, bindingContext) - MaxLineLength:FindReferences.kt$isIterator(descriptor) -> findIteratorReferences(declaration, bindingContext) + findNameReferences(declaration, bindingContext) - MaxLineLength:FindReferences.kt$isPropertyDelegate(declaration) -> findDelegateReferences(element, recompile) + findNameReferences(element, recompile) - MaxLineLength:FindReferences.kt$isPropertyDelegate(descriptor) -> findDelegateReferences(declaration, bindingContext) + findNameReferences(declaration, bindingContext) - MaxLineLength:FindReferences.kt$private - MaxLineLength:FindReferences.kt$val declaration = recover.compile[BindingContext.DECLARATION_TO_DESCRIPTOR, element] ?: return emptyResult("Declaration ${element.fqName} has no descriptor") - MaxLineLength:FindReferences.kt$val descriptor = file.compile[BindingContext.DECLARATION_TO_DESCRIPTOR, declaration] ?: return emptyResult("Declaration ${declaration.fqName} has no descriptor") - MaxLineLength:FindReferences.kt$val element = recover.elementAtPoint(cursor)?.findParent<KtNamedDeclaration>() ?: return emptyResult("No declaration at ${recover.describePosition(cursor)}") - MaxLineLength:GradleClassPathResolver.kt$. - MaxLineLength:GradleClassPathResolver.kt$GradleClassPathResolver$. - MaxLineLength:GradleClassPathResolver.kt$GradleClassPathResolver$internal - MaxLineLength:GradleClassPathResolver.kt$LOG.info("Resolving dependencies for '{}' through Gradle's CLI using tasks {}...", projectDirectory.fileName, gradleTasks) - MaxLineLength:GradleClassPathResolver.kt$private - MaxLineLength:GradleClassPathResolver.kt$val command = listOf(gradle.toString()) + tmpScripts.flatMap { listOf("-I", it.toString()) } + gradleTasks + listOf("--console=plain") - MaxLineLength:GradleDSLScriptTest.kt$GradleDSLScriptTest$assertThat(contents.value, containsString("fun PluginDependenciesSpec.kotlin(module: String): PluginDependencySpec")) - MaxLineLength:Hovers.kt$val expressionType = bindingContext[BindingContext.EXPRESSION_TYPE_INFO, element]?.type ?: element.getType(bindingContext) - MaxLineLength:Hovers.kt$val hover = MarkupContent("markdown", listOf("```kotlin\n$hoverText\n```", javaDoc).filter { it.isNotEmpty() }.joinToString("\n---\n")) - MaxLineLength:Hovers.kt$val javaDoc: String = expression.children.mapNotNull { (it as? PsiDocCommentBase)?.text }.map(::renderJavaDoc).firstOrNull() ?: "" - MaxLineLength:ImplementAbstractMembersQuickFix.kt$(classMember is FunctionDescriptor && classMember.modality == Modality.ABSTRACT && !overridesDeclaration(kotlinClass, classMember)) || (classMember is PropertyDescriptor && classMember.modality == Modality.ABSTRACT && !overridesDeclaration(kotlinClass, classMember)) - MaxLineLength:ImplementAbstractMembersQuickFix.kt$ImplementAbstractMembersQuickFix$override - MaxLineLength:ImplementAbstractMembersQuickFix.kt$ImplementAbstractMembersQuickFix$val bodyAppendBeginning = listOf(TextEdit(Range(newMembersStartPosition, newMembersStartPosition), "{")).takeIf { kotlinClass.hasNoBody() } ?: emptyList() - MaxLineLength:ImplementAbstractMembersQuickFix.kt$ImplementAbstractMembersQuickFix$val bodyAppendEnd = listOf(TextEdit(Range(newMembersStartPosition, newMembersStartPosition), System.lineSeparator() + "}")).takeIf { kotlinClass.hasNoBody() } ?: emptyList() - MaxLineLength:ImplementAbstractMembersQuickFix.kt$diagnostics.any { diagnosticMatch(it, startCursor, endCursor, hashSetOf("ABSTRACT_MEMBER_NOT_IMPLEMENTED", "ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED")) } - MaxLineLength:ImplementAbstractMembersQuickFix.kt$diagnostics.find { diagnosticMatch(it, range, hashSetOf("ABSTRACT_MEMBER_NOT_IMPLEMENTED", "ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED")) } - MaxLineLength:ImplementAbstractMembersQuickFix.kt$if - MaxLineLength:JavaElementConverter.kt$JavaElementConverter$private fun List<String>.buildCodeBlock(indentDelta: Int = 1, separatorNewlines: Int = 1): String - MaxLineLength:JavaElementConverter.kt$JavaElementConverter$translatedKotlinCode = "${expression.lExpression.translate()} ${expression.operationSign.text} ${expression.rExpression.translate()}" - MaxLineLength:JavaElementConverter.kt$JavaElementConverter$translatedKotlinCode = "${expression.lOperand.translate()} ${expression.operationSign.text} ${expression.rOperand.translate()}" - MaxLineLength:JavaElementConverter.kt$JavaElementConverter$translatedKotlinCode = "${statement.initialization.translate()}\n${indent}while (${statement.condition.translate()}) $translatedBody" - MaxLineLength:KlsURI.kt$KlsURI$URI(newArchivePath.toUri().toString() + (innerPath.let { "!$it" } )).toKlsURI()?.let { KlsURI(it.fileUri, query) } - MaxLineLength:KlsURI.kt$KlsURI$get() = if (query.isEmpty()) "" else query.entries.fold("?") { accum, next -> "$accum${next.key}=${next.value}" } - MaxLineLength:KlsURI.kt$private fun parseKlsURIQuery(uri: URI): Map<KlsURI.QueryParam, String> - MaxLineLength:KotlinLanguageServer.kt$KotlinLanguageServer$config.completion.snippets.enabled = clientCapabilities?.textDocument?.completion?.completionItem?.snippetSupport ?: false - MaxLineLength:KotlinLanguageServer.kt$KotlinLanguageServer$private val textDocuments = KotlinTextDocumentService(sourceFiles, sourcePath, config, tempDirectory, uriContentProvider, classPath) - MaxLineLength:KotlinLanguageServer.kt$KotlinLanguageServer$private val uriContentProvider = URIContentProvider(ClassContentProvider(config.externalSources, classPath, tempDirectory, CompositeSourceArchiveProvider(JdkSourceArchiveProvider(classPath), ClassPathSourceArchiveProvider(classPath)))) - MaxLineLength:KotlinLanguageServer.kt$KotlinLanguageServer$serverCapabilities.semanticTokensProvider = SemanticTokensWithRegistrationOptions(semanticTokensLegend, true, true) - MaxLineLength:KotlinProtocolExtensionService.kt$KotlinProtocolExtensionService$override - MaxLineLength:KotlinTextDocumentService.kt$KotlinTextDocumentService$fetchSignatureHelpAt(file, cursor) ?: noResult("No function call around ${describePosition(position)}", null) - MaxLineLength:KotlinTextDocumentService.kt$KotlinTextDocumentService$goToDefinition(file, cursor, uriContentProvider.classContentProvider, tempDirectory, config.externalSources, cp) - MaxLineLength:KotlinTextDocumentService.kt$KotlinTextDocumentService$override - MaxLineLength:KotlinTextDocumentService.kt$KotlinTextDocumentService$return "${describeURI(position.textDocument.uri)} ${position.position.line + 1}:${position.position.character + 1}" - MaxLineLength:KotlinWorkspaceService.kt$KotlinWorkspaceService$languageClient - MaxLineLength:KotlinWorkspaceService.kt$KotlinWorkspaceService$override - MaxLineLength:LanguageServerTestFixture.kt$LanguageServerTestFixture$fun - MaxLineLength:LanguageServerTestFixture.kt$SingleFileTestFixture$open - MaxLineLength:LintTest.kt$LintTest$languageServer.textDocumentService.documentSymbol(DocumentSymbolParams(TextDocumentIdentifier(uri(file).toString()))).get() - MaxLineLength:Logger.kt$Logger$fun deepTrace(msg: String, vararg placeholders: Any?) - MaxLineLength:Main.kt$Args$/* * The language server can currently be launched in three modes: * - Stdio, in which case no argument should be specified (used by default) * - TCP Server, in which case the client has to connect to the specified tcpServerPort (used by the Docker image) * - TCP Client, in whcih case the server will connect to the specified tcpClientPort/tcpClientHost (optionally used by VSCode) */ - MaxLineLength:MavenArtifactParsingTest.kt$MavenArtifactParsingTest$assertThat - MaxLineLength:MavenClassPathResolver.kt$val command = listOf(mvnCommand(pom).toString(), "dependency:list", "-DincludeScope=test", "-DoutputFile=$mavenOutput", "-Dstyle.color=never") - MaxLineLength:MavenClassPathResolver.kt$val command = listOf(mvnCommand(pom).toString(), "dependency:sources", "-DincludeScope=test", "-DoutputFile=$mavenOutput", "-Dstyle.color=never") - MaxLineLength:MavenClassPathResolver.kt$version = version ?: parts[4].split(" ")[0] - MaxLineLength:OverrideMemberTest.kt$OverrideMemberTest$"override fun getStackTrace(): (Array<(StackTraceElement..StackTraceElement?)>..Array<out (StackTraceElement..StackTraceElement?)>) { }" - MaxLineLength:OverrideMemberTest.kt$OverrideMemberTest$"override fun getUncaughtExceptionHandler(): UncaughtExceptionHandler { }" - MaxLineLength:OverrideMemberTest.kt$OverrideMemberTest$"override fun setUncaughtExceptionHandler(eh: UncaughtExceptionHandler) { }" - MaxLineLength:OverrideMemberTest.kt$OverrideMemberTest$padding + "override fun getStackTrace(): (Array<(StackTraceElement..StackTraceElement?)>..Array<out (StackTraceElement..StackTraceElement?)>) { }" - MaxLineLength:OverrideMemberTest.kt$OverrideMemberTest$padding + "override fun getUncaughtExceptionHandler(): UncaughtExceptionHandler { }" - MaxLineLength:OverrideMemberTest.kt$OverrideMemberTest$padding + "override fun setUncaughtExceptionHandler(eh: UncaughtExceptionHandler) { }" - MaxLineLength:OverrideMemberTest.kt$OverrideMemberTest$val result = languageServer.getProtocolExtensionService().overrideMember(TextDocumentPositionParams(TextDocumentIdentifier(fileUri), position(11, 8))).get() - MaxLineLength:OverrideMemberTest.kt$OverrideMemberTest$val result = languageServer.getProtocolExtensionService().overrideMember(TextDocumentPositionParams(TextDocumentIdentifier(fileUri), position(15, 8))).get() - MaxLineLength:OverrideMemberTest.kt$OverrideMemberTest$val result = languageServer.getProtocolExtensionService().overrideMember(TextDocumentPositionParams(TextDocumentIdentifier(fileUri), position(37, 8))).get() - MaxLineLength:OverrideMemberTest.kt$OverrideMemberTest$val result = languageServer.getProtocolExtensionService().overrideMember(TextDocumentPositionParams(TextDocumentIdentifier(fileUri), position(39, 9))).get() - MaxLineLength:OverrideMemberTest.kt$OverrideMemberTest$val result = languageServer.getProtocolExtensionService().overrideMember(TextDocumentPositionParams(TextDocumentIdentifier(fileUri), position(9, 8))).get() - MaxLineLength:OverrideMembers.kt$// TODO: any way can repeat less code between this and the getAbstractMembersStubs in the ImplementAbstractMembersQuickfix? - MaxLineLength:OverrideMembers.kt$// TODO: does not seem to handle the implicit Any and Object super types that well. Need to find out if that is easily solvable. Finds the methods from them if any super class or interface is present - MaxLineLength:OverrideMembers.kt$// interfaces are ClassDescriptors by default. When calling AbstractClass super methods, we get a ClassConstructorDescriptor - MaxLineLength:OverrideMembers.kt$private fun MemberDescriptor.canBeOverriden() - MaxLineLength:PluginSpecBuilders.kt$* The `org.gradle.clang-compiler` plugin implemented by [org.gradle.nativeplatform.toolchain.plugins.ClangCompilerPlugin]. - MaxLineLength:PluginSpecBuilders.kt$* The `org.gradle.component-model-base` plugin implemented by [org.gradle.language.base.plugins.ComponentModelBasePlugin]. - MaxLineLength:PluginSpecBuilders.kt$* The `org.gradle.google-test-test-suite` plugin implemented by [org.gradle.nativeplatform.test.googletest.plugins.GoogleTestPlugin]. - MaxLineLength:PluginSpecBuilders.kt$* The `org.gradle.google-test` plugin implemented by [org.gradle.nativeplatform.test.googletest.plugins.GoogleTestConventionPlugin]. - MaxLineLength:PluginSpecBuilders.kt$* The `org.gradle.groovy-gradle-plugin` plugin implemented by [org.gradle.plugin.devel.internal.precompiled.PrecompiledGroovyPluginsPlugin]. - MaxLineLength:PluginSpecBuilders.kt$* The `org.gradle.jacoco-report-aggregation` plugin implemented by [org.gradle.testing.jacoco.plugins.JacocoReportAggregationPlugin]. - MaxLineLength:PluginSpecBuilders.kt$* The `org.gradle.java-library-distribution` plugin implemented by [org.gradle.api.plugins.JavaLibraryDistributionPlugin]. - MaxLineLength:PluginSpecBuilders.kt$* The `org.gradle.microsoft-visual-cpp-compiler` plugin implemented by [org.gradle.nativeplatform.toolchain.plugins.MicrosoftVisualCppCompilerPlugin]. - MaxLineLength:PluginSpecBuilders.kt$* The `org.gradle.native-component-model` plugin implemented by [org.gradle.nativeplatform.plugins.NativeComponentModelPlugin]. - MaxLineLength:PluginSpecBuilders.kt$* The `org.gradle.objective-c-lang` plugin implemented by [org.gradle.language.objectivec.plugins.ObjectiveCLangPlugin]. - MaxLineLength:PluginSpecBuilders.kt$* The `org.gradle.objective-cpp-lang` plugin implemented by [org.gradle.language.objectivecpp.plugins.ObjectiveCppLangPlugin]. - MaxLineLength:PluginSpecBuilders.kt$* The `org.gradle.standard-tool-chains` plugin implemented by [org.gradle.nativeplatform.toolchain.internal.plugins.StandardToolChainsPlugin]. - MaxLineLength:PluginSpecBuilders.kt$* The `org.gradle.validate-external-gradle-plugin` plugin implemented by [org.gradle.plugin.devel.plugins.ExternalPluginValidationPlugin]. - MaxLineLength:PluginSpecBuilders.kt$* The `org.gradle.windows-resource-script` plugin implemented by [org.gradle.language.rc.plugins.WindowsResourceScriptPlugin]. - MaxLineLength:Progress.kt$Progress.Factory.None$override fun create(label: String): CompletableFuture<Progress> - MaxLineLength:QuickFix.kt$QuickFix$fun - MaxLineLength:QuickFix.kt$diagnostic.textRanges.any { it.startOffset <= startCursor && it.endOffset >= endCursor } && diagnosticTypes.contains(diagnostic.factory.name) - MaxLineLength:QuickFix.kt$fun - MaxLineLength:QuickFixesTest.kt$ImplementAbstractMembersQuickFixExternalLibraryTest$assertThat(firstMemberToImplementEdit?.newText, equalTo(System.lineSeparator() + System.lineSeparator() + " override val size: Int = TODO(\"SET VALUE\")")) - MaxLineLength:QuickFixesTest.kt$ImplementAbstractMembersQuickFixExternalLibraryTest$assertThat(functionToImplementEdit?.newText, equalTo(System.lineSeparator() + System.lineSeparator() + " override fun compare(p0: String, p1: String): Int { }")) - MaxLineLength:QuickFixesTest.kt$ImplementAbstractMembersQuickFixExternalLibraryTest$assertThat(functionToImplementEdit?.newText, equalTo(System.lineSeparator() + System.lineSeparator() + " override fun run() { }")) - MaxLineLength:QuickFixesTest.kt$ImplementAbstractMembersQuickFixExternalLibraryTest$assertThat(secondMemberToImplementEdit?.newText, equalTo(System.lineSeparator() + System.lineSeparator() + " override fun get(index: Int): String { }")) - MaxLineLength:QuickFixesTest.kt$ImplementAbstractMembersQuickFixSameFileTest$assertThat(firstFunctionToImplementEdit?.newText, equalTo(System.lineSeparator() + System.lineSeparator() + " override fun print() { }")) - MaxLineLength:QuickFixesTest.kt$ImplementAbstractMembersQuickFixSameFileTest$assertThat(firstMemberToImplementEdit?.newText, equalTo(System.lineSeparator() + System.lineSeparator() + " override val name: String = TODO(\"SET VALUE\")")) - MaxLineLength:QuickFixesTest.kt$ImplementAbstractMembersQuickFixSameFileTest$assertThat(functionToImplementEdit?.newText, equalTo(System.lineSeparator() + System.lineSeparator() + " override fun myMethod(myStr: String?): String? { }")) - MaxLineLength:QuickFixesTest.kt$ImplementAbstractMembersQuickFixSameFileTest$assertThat(functionToImplementEdit?.newText, equalTo(System.lineSeparator() + System.lineSeparator() + " override fun print() { }")) - MaxLineLength:QuickFixesTest.kt$ImplementAbstractMembersQuickFixSameFileTest$assertThat(functionToImplementEdit?.newText, equalTo(System.lineSeparator() + System.lineSeparator() + " override fun test(input: String, otherInput: Int) { }")) - MaxLineLength:QuickFixesTest.kt$ImplementAbstractMembersQuickFixSameFileTest$assertThat(memberToImplementEdit?.newText, equalTo(System.lineSeparator() + System.lineSeparator() + " override fun myFun() { }")) - MaxLineLength:QuickFixesTest.kt$ImplementAbstractMembersQuickFixSameFileTest$assertThat(secondFunctionToImplementEdit?.newText, equalTo(System.lineSeparator() + System.lineSeparator() + " override fun test(input: String, otherInput: Int) { }")) - MaxLineLength:QuickFixesTest.kt$ImplementAbstractMembersQuickFixSameFileTest$assertThat(secondMemberToImplementEdit?.newText, equalTo(System.lineSeparator() + System.lineSeparator() + " override fun behaviour() { }")) - MaxLineLength:QuickFixesTest.kt$ImplementAbstractMembersQuickFixSameFileTest$assertThat(secondMemberToImplementEdit?.newText, equalTo(System.lineSeparator() + System.lineSeparator() + " override fun myFun() { }")) - MaxLineLength:QuickFixesTest.kt$ImplementAbstractMembersQuickFixTest$equalTo(System.lineSeparator() + System.lineSeparator() + " override fun someSuperMethod(someParameter: String): Int { }") - MaxLineLength:QuickFixesTest.kt$ImplementAbstractMembersQuickFixTest$val codeActionParams = codeActionParams(file, 10, 1, 10, 25, listOf(diagnostic), listOf(CodeActionKind.QuickFix)) - MaxLineLength:ReferencesTest.kt$ReferenceConstructorTest$assertThat("Finds reference to a secondary constructor", referenceStrs, hasItem(containsString("ReferenceConstructor.kt"))) - MaxLineLength:ReferencesTest.kt$ReferenceConstructorTest$assertThat("Finds reference to the main constructor", referenceStrs, hasItem(containsString("ReferenceConstructor.kt"))) - MaxLineLength:RenderCompletionItem.kt$RenderCompletionItem$val parenthesizedParams = parameters.dropLast(1).ifEmpty { null }?.let { "(${valueParametersSnippet(it)})" } ?: "" - MaxLineLength:ResolveMain.kt$// a little ugly, but because of success of the above, we know that "it" has 4 layers of parent objects (child of companion object body, companion object body, companion object, outer class) - MaxLineLength:ResolveMain.kt$// the KtFiles name is weird. Full path. This causes the class to have full path in name as well. Correcting to top level only - MaxLineLength:SemanticTokens.kt$SemanticToken - MaxLineLength:SemanticTokens.kt$if - MaxLineLength:SemanticTokens.kt$private - MaxLineLength:SemanticTokens.kt$val deltaStart = token.range.start.character - (last?.takeIf { deltaLine == 0 }?.range?.start?.character ?: 0) - MaxLineLength:SemanticTokensTest.kt$SemanticTokensTest$SemanticToken(range(classLine, 12, classLine, 16), SemanticTokenType.CLASS, setOf(SemanticTokenModifier.DECLARATION)) - MaxLineLength:SemanticTokensTest.kt$SemanticTokensTest$SemanticToken(range(classLine, 21, classLine, 29), SemanticTokenType.PARAMETER, setOf(SemanticTokenModifier.DECLARATION, SemanticTokenModifier.READONLY)) - MaxLineLength:SemanticTokensTest.kt$SemanticTokensTest$SemanticToken(range(constLine, 5, constLine, 13), SemanticTokenType.PROPERTY, setOf(SemanticTokenModifier.DECLARATION, SemanticTokenModifier.READONLY)) - MaxLineLength:SemanticTokensTest.kt$SemanticTokensTest$SemanticToken(range(enumLine, 12, enumLine, 16), SemanticTokenType.CLASS, setOf(SemanticTokenModifier.DECLARATION)) - MaxLineLength:SemanticTokensTest.kt$SemanticTokensTest$SemanticToken(range(enumLine, 19, enumLine, 27), SemanticTokenType.ENUM_MEMBER, setOf(SemanticTokenModifier.DECLARATION)) - MaxLineLength:SemanticTokensTest.kt$SemanticTokensTest$SemanticToken(range(funLine, 32, funLine, 33), SemanticTokenType.VARIABLE, setOf(SemanticTokenModifier.READONLY)) - MaxLineLength:SemanticTokensTest.kt$SemanticTokensTest$SemanticToken(range(funLine, 5, funLine, 6), SemanticTokenType.FUNCTION, setOf(SemanticTokenModifier.DECLARATION)) - MaxLineLength:SemanticTokensTest.kt$SemanticTokensTest$SemanticToken(range(funLine, 7, funLine, 8), SemanticTokenType.PARAMETER, setOf(SemanticTokenModifier.DECLARATION, SemanticTokenModifier.READONLY)) - MaxLineLength:SemanticTokensTest.kt$SemanticTokensTest$SemanticToken(range(varLine, 5, varLine, 13), SemanticTokenType.PROPERTY, setOf(SemanticTokenModifier.DECLARATION)) - MaxLineLength:SemanticTokensTest.kt$SemanticTokensTest$val partialResponse = languageServer.textDocumentService.semanticTokensRange(semanticTokensRangeParams(file, range(constLine, 0, classLine + 1, 0))).get()!! - MaxLineLength:SignatureHelp.kt$* - MaxLineLength:SignatureHelp.kt$val (signatures, activeDeclaration, activeParameter) = getSignatureTriplet(file, cursor) ?: return nullResult("No call around ${file.describePosition(cursor)}") - MaxLineLength:SignatureHelpTest.kt$SignatureHelpTest$assertThat(help.signatures.flatMap { it.parameters.map { it.documentation.left }}, hasItems("String param", "Int param")) - MaxLineLength:SignatureHelpTest.kt$SignatureHelpTest$assertThat(help.signatures.map { it.documentation.left }, hasItems("Call foo with a String", "Call foo with an Int")) - MaxLineLength:SignatureHelpTest.kt$SignatureHelpTest$assertThat(help.signatures.map { it.documentation.left }, hasItems("Construct with a String", "Construct with an Int")) - MaxLineLength:SignatureHelpTest.kt$SignatureHelpTest$assertThat(help.signatures.map { it.label }, hasItems("constructor Constructor(bar: String)", "constructor Constructor(bar: Int)")) - MaxLineLength:SignatureHelpTest.kt$SignatureHelpTest$assertThat(help.signatures[help.activeSignature].label, equalTo("fun multiParam(first: String, second: String): Unit")) - MaxLineLength:SignatureHelpTest.kt$SignatureHelpTest$assertThat(help.signatures[help.activeSignature].label, equalTo("fun oneOrTwoArgs(first: String, second: String): Unit")) - MaxLineLength:SourceArchiveProvider.kt$CompositeSourceArchiveProvider$class - MaxLineLength:SourceExclusions.kt$SourceExclusions$private val excludedPatterns = listOf(".*", "bazel-*", "bin", "build", "node_modules", "target").map { FileSystems.getDefault().getPathMatcher("glob:$it") } - MaxLineLength:SourcePath.kt$SourcePath$LOG.warn("Requested source file {} is not on source path, this is most likely a bug. Adding it now temporarily...", describeURI(uri)) - MaxLineLength:SourcePath.kt$SourcePath.SourceFile$CompiledFile(content, compiledFile!!, compiledContext!!, module!!, allIncludingThis(), cp, isScript, kind) - MaxLineLength:SourcePath.kt$SourcePath.SourceFile$fun - MaxLineLength:SourcePath.kt$SourcePath.SourceFile$val extension: String? = uri.fileExtension ?: "kt" // TODO: Use language?.associatedFileType?.defaultExtension again - MaxLineLength:Symbol.kt$Symbol.Visibility.Companion$fun fromRaw(rawValue: Int) - MaxLineLength:SymbolIndex.kt$SymbolIndex$(Symbols.fqName eq descriptorFqn.toString()) and (Symbols.extensionReceiverType eq extensionReceiverFqn?.toString()) - MaxLineLength:SymbolIndex.kt$SymbolIndex$fun - MaxLineLength:SymbolIndex.kt$SymbolIndex$private - MaxLineLength:Symbols.kt$val symbol = DocumentSymbol(currentDecl.name ?: "<anonymous>", symbolKind(currentDecl), span, nameSpan, null, children) - MaxLineLength:TemporaryDirectory.kt$TemporaryDirectory$fun createTempFile(prefix: String = "tmp", suffix: String = ""): Path - MaxLineLength:URIs.kt$URI.create(runCatching { URLDecoder.decode(uri, StandardCharsets.UTF_8.toString()).replace(" ", "%20") }.getOrDefault(uri)) - MaxLineLength:Utils.kt$fun <T> noFuture(message: String, contents: T): CompletableFuture<T> - MaxLineLength:WithStdlibResolver.kt$// For each "kotlin-stdlib-blah", use the newest. This may not be correct behavior if the project has lots of - MaxLineLength:WithStdlibResolver.kt$// conflicting dependencies, but in general should get enough of the stdlib loaded that we can display errors - MaxLineLength:WithStdlibResolver.kt$return wrapWithStdlib(paths.map { it.compiledJar }.toSet()).map { ClassPathEntry(it, paths.find { it1 -> it1.compiledJar == it }?.sourceJar) }.toSet() MayBeConst:CompanionObject.kt$val SOME_GLOBAL_CONSTANT = 42 MayBeConst:DeclSite.kt$val myvar = 2 MayBeConst:DocumentHighlight.kt$val globalval = 23 diff --git a/shared/src/main/kotlin/org/javacs/kt/classpath/BackupClassPathResolver.kt b/shared/src/main/kotlin/org/javacs/kt/classpath/BackupClassPathResolver.kt index 9057a344..c8b6d6b4 100644 --- a/shared/src/main/kotlin/org/javacs/kt/classpath/BackupClassPathResolver.kt +++ b/shared/src/main/kotlin/org/javacs/kt/classpath/BackupClassPathResolver.kt @@ -7,6 +7,7 @@ import java.nio.file.attribute.BasicFileAttributes import java.util.function.BiPredicate import org.javacs.kt.util.tryResolving import org.javacs.kt.util.findCommandOnPath +import org.javacs.kt.LOG import java.nio.file.Paths /** Backup classpath that find Kotlin in the user's Maven/Gradle home or kotlinc's libraries folder. */ @@ -16,8 +17,8 @@ object BackupClassPathResolver : ClassPathResolver { } fun findKotlinStdlib(): Path? = - findLocalArtifact("org.jetbrains.kotlin", "kotlin-stdlib") - ?: findKotlinCliCompilerLibrary("kotlin-stdlib") + findKotlinCliCompilerLibrary("kotlin-stdlib") + ?: findLocalArtifact("org.jetbrains.kotlin", "kotlin-stdlib") ?: findAlternativeLibraryLocation("kotlin-stdlib") private fun findLocalArtifact(group: String, artifact: String) = @@ -33,7 +34,7 @@ private fun tryFindingLocalArtifactUsing(@Suppress("UNUSED_PARAMETER") group: St val expected = "${artifact}-${version}.jar" name == expected } - else -> name.startsWith(artifact) && name.endsWith(".jar") + else -> name.startsWith(artifact) && ("-sources" !in name) && name.endsWith(".jar") } } return Files.list(artifactDirResolution.artifactDir) @@ -69,6 +70,9 @@ private fun findKotlinCliCompilerLibrary(name: String): Path? = ?.filter { it.fileName.toString() == "$name.jar" } ?.findFirst() ?.orElse(null) + ?.also { + LOG.info("Found Kotlin CLI compiler library $name at $it") + } // alternative library locations like for snap diff --git a/shared/src/main/kotlin/org/javacs/kt/classpath/ShellClassPathResolver.kt b/shared/src/main/kotlin/org/javacs/kt/classpath/ShellClassPathResolver.kt index 3f3dfefe..65e43be4 100644 --- a/shared/src/main/kotlin/org/javacs/kt/classpath/ShellClassPathResolver.kt +++ b/shared/src/main/kotlin/org/javacs/kt/classpath/ShellClassPathResolver.kt @@ -5,6 +5,7 @@ import java.nio.file.Files import java.nio.file.Path import java.nio.file.Paths import org.javacs.kt.util.userHome +import org.javacs.kt.util.isOSWindows import org.javacs.kt.LOG /** Executes a shell script to determine the classpath */ @@ -29,11 +30,20 @@ internal class ShellClassPathResolver( } companion object { - private val scriptExtensions = listOf("sh", "bat", "cmd") + private val configDirNames = listOf("kotlin-language-server", "KotlinLanguageServer") + private val scriptNames = listOf("kls-classpath", "kotlinLspClasspath") + private val scriptExtensions = if (isOSWindows()) listOf(".bat", ".cmd", ".ps1") else listOf("", ".sh", ".bash") /** Create a shell resolver if a file is a pom. */ fun maybeCreate(file: Path): ShellClassPathResolver? = - file.takeIf { scriptExtensions.any { file.endsWith("kotlinLspClasspath.$it") } } + file.takeIf { scriptNames.any { name -> scriptExtensions.any { file.endsWith("$name$it") } } } + ?.takeIf { + val isExecutable = Files.isExecutable(it) + if (!isExecutable) { + LOG.warn("Found classpath script $it that is NOT executable and therefore cannot be used. Perhaps you'd want to chmod +x it?") + } + isExecutable + } ?.let { ShellClassPathResolver(it) } /** The root directory for config files. */ @@ -42,12 +52,10 @@ internal class ShellClassPathResolver( /** Returns the ShellClassPathResolver for the global home directory shell script. */ fun global(workingDir: Path?): ClassPathResolver = - globalConfigRoot.resolve("KotlinLanguageServer") - ?.let { root -> - scriptExtensions - .map { root.resolve("classpath.$it") } - .firstOrNull { Files.exists(it) } - } + configDirNames + .map(globalConfigRoot::resolve) + .flatMap { root -> scriptExtensions.map { root.resolve("classpath$it") } } + .firstOrNull(Files::exists) ?.let { ShellClassPathResolver(it, workingDir) } ?: ClassPathResolver.empty } diff --git a/shared/src/main/kotlin/org/javacs/kt/classpath/WithStdlibResolver.kt b/shared/src/main/kotlin/org/javacs/kt/classpath/WithStdlibResolver.kt index 9d832114..0cd25707 100644 --- a/shared/src/main/kotlin/org/javacs/kt/classpath/WithStdlibResolver.kt +++ b/shared/src/main/kotlin/org/javacs/kt/classpath/WithStdlibResolver.kt @@ -45,15 +45,15 @@ private fun wrapWithStdlib(paths: Set): Set { } private data class StdLibItem( - val key : String, - val major : Int, + val key: String, + val major: Int, val minor: Int, - val patch : Int, + val patch: Int, val path: Path ) { companion object { // Matches names like: "kotlin-stdlib-jdk7-1.2.51.jar" - val parser = Regex("""(kotlin-stdlib(-[^-]+)?)-(\d+)\.(\d+)\.(\d+)\.jar""") + val parser = Regex("""(kotlin-stdlib(-[^-]+)?)(?:-(\d+)\.(\d+)\.(\d+))?\.jar""") fun from(path: Path) : StdLibItem? { return parser.matchEntire(path.fileName.toString())?.let { match -> diff --git a/shared/src/main/kotlin/org/javacs/kt/util/Utils.kt b/shared/src/main/kotlin/org/javacs/kt/util/Utils.kt index 3dfc8507..36907d60 100644 --- a/shared/src/main/kotlin/org/javacs/kt/util/Utils.kt +++ b/shared/src/main/kotlin/org/javacs/kt/util/Utils.kt @@ -90,7 +90,7 @@ inline fun tryResolving(what: String, resolver: () -> T?): T? { try { val resolved = resolver() if (resolved != null) { - LOG.info("Successfully resolved {}", what) + LOG.info("Successfully resolved {} to {}", what, resolved) return resolved } else { LOG.info("Could not resolve {} as it is null", what)