Skip to content

Commit

Permalink
[Task IAC-805] Externalized language server configuration, code refac…
Browse files Browse the repository at this point in the history
…toring

Signed-off-by: Alexander Kantchev <[email protected]>
  • Loading branch information
akantchev committed Jan 25, 2024
1 parent b010d79 commit 509d209
Show file tree
Hide file tree
Showing 8 changed files with 94 additions and 61 deletions.
8 changes: 3 additions & 5 deletions extension/src/client/command/TriggerCollection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { AutoWire, Logger, sleep } from "@vmware/vrdt-common"
import { remote } from "@vmware/vro-language-server"
import * as vscode from "vscode"

import { Commands } from "../constants"
import { Commands, LanguageServerConfig } from "../constants"
import { LanguageServices } from "../lang"
import { Command } from "./Command"

Expand All @@ -30,7 +30,7 @@ export class TriggerCollection extends Command<void> {
const languageClient = this.languageServices.client

if (!languageClient) {
this.logger.warn("The vRO language server is not running")
this.logger.warn(`The ${LanguageServerConfig.DisplayName} is not running`)
return
}
await vscode.commands.executeCommand(Commands.EventCollectionStart)
Expand All @@ -48,15 +48,13 @@ export class TriggerCollection extends Command<void> {
while (status && !status.finished) {
this.logger.info("Collection status:", status)
progress.report(status)
await sleep(1000)
await sleep(LanguageServerConfig.SleepTime)
status = await languageClient.sendRequest(remote.server.giveVroCollectionStatus)
}

this.logger.info("Collection finished:", status)

if (status.error !== undefined) {
await vscode.commands.executeCommand(Commands.EventCollectionError, status.error)

if (status.data.hintsPluginBuild === 0) {
vscode.window.showErrorMessage(
"The vRO Hint plug-in is not installed on the configured vRO server"
Expand Down
8 changes: 8 additions & 0 deletions extension/src/client/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,3 +110,11 @@ export enum ProjectArchetypes {
VraNg = "com.vmware.pscoe.vra-ng:vra-ng-package",
Polyglot = "com.vmware.pscoe.polyglot:polyglot-project"
}

export enum LanguageServerConfig {
Port = 6014,
LoadType = "nolazy",
NodeType = "node-ipc",
DisplayName = "vRO Language Server",
SleepTime = 1000
}
15 changes: 9 additions & 6 deletions extension/src/client/lang/LanguageServices.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { remote } from "@vmware/vro-language-server"
import * as vscode from "vscode"
import * as client from "vscode-languageclient"

import { OutputChannels } from "../constants"
import { LanguageServerConfig, OutputChannels } from "../constants"
import { Registrable } from "../Registrable"
import { ConfigurationManager, EnvironmentManager } from "../system"

Expand Down Expand Up @@ -82,20 +82,23 @@ export class LanguageServices implements Registrable, vscode.Disposable {
? path.join(module, "dist", "langserver.js")
: path.join(module, "out", "server", "langserver.js")

this.logger.info(`Starting vRO language server on port 6014`)
this.logger.info(`Starting vRO language server on port '${LanguageServerConfig.Port}'`)

const serverOptions = {
run: {
module: executable,
transport: client.TransportKind.ipc,
args: ["--node-ipc"],
args: [`--${LanguageServerConfig.NodeType}`],
options: { cwd: module }
},
debug: {
module: executable,
transport: client.TransportKind.ipc,
args: ["--node-ipc"],
options: { cwd: module, execArgv: ["--nolazy", "--inspect=6014"] }
args: [`--${LanguageServerConfig.NodeType}`],
options: {
cwd: module,
execArgv: [`--${LanguageServerConfig.LoadType}`, `--inspect=${LanguageServerConfig.Port}`]
}
}
}

Expand All @@ -119,6 +122,6 @@ export class LanguageServices implements Registrable, vscode.Disposable {
]
}
}
return new client.LanguageClient("vRO LS", serverOptions, clientOptions)
return new client.LanguageClient(LanguageServerConfig.DisplayName, serverOptions, clientOptions)
}
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -525,7 +525,7 @@
"vrdev.vro.inventory.cache": {
"type": "boolean",
"default": true,
"description": "Enable / Disable vRO Inventory Caching",
"description": "Enable vRO inventory caching (can be used in heavily loaded environments)",
"scope": "window"
}
}
Expand Down
11 changes: 7 additions & 4 deletions packages/node/vrdt-common/src/rest/VroRestClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export class VroRestClient {

constructor(private settings: BaseConfiguration) {
this.auth = this.getInitialAuth()
this.isCachingEnabled = this.settings?.vrdev?.vro?.inventory?.cache ?? false
this.loadCacheConfiguration()
}

private get hostname(): string {
Expand Down Expand Up @@ -182,6 +182,8 @@ export class VroRestClient {
options?: Partial<request.OptionsWithUrl>
): Promise<T> {
const url = route.indexOf("://") > 0 ? route : `https://${this.hostname}:${this.port}/vco/api/${route}`
// reload the cache configuration in order cache to take effect when settings are changed
this.loadCacheConfiguration()
return request({
headers: {
"Accept": "application/json",
Expand Down Expand Up @@ -675,15 +677,12 @@ export class VroRestClient {
if (!child.attributes) {
return undefined
}

const id =
child.attributes.find(att => att.name === "id") ??
child.attributes.find(att => att.name === "dunesId")

const name =
child.attributes.find(att => att.name === "displayName") ??
child.attributes.find(att => att.name === "name")

const type =
child.attributes.find(att => att.name === "type") ??
child.attributes.find(att => att.name === "@type")
Expand Down Expand Up @@ -825,4 +824,8 @@ export class VroRestClient {
async getPluginDetails(link: string) {
return this.send("GET", `server-configuration/api/plugins/${link}`)
}

private loadCacheConfiguration(): void {
this.isCachingEnabled = this.settings?.vrdev?.vro?.inventory?.cache ?? false
}
}
9 changes: 9 additions & 0 deletions packages/node/vro-language-server/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,12 @@ message Action {
export const Timeout = {
ONE_SECOND: 1000
}

export enum CompletionPrefixKind {
UNKNOWN = "Unknown",
CLASS_IMPORT = "Class Import",
CLASS_REFERENCE = "Class Reference",
STATIC_MEMBER_REFERENCE = "Static Member Reference",
NEW_INSTANCE = "New Instance",
MODULE_IMPORT = "Module Import"
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,8 @@ import { URI } from "vscode-uri"
import { ConnectionLocator, Environment, HintLookup } from "../core"
import { Synchronizer, TextDocumentWrapper } from "../document"
import { Previewer } from "../util"

enum CompletionPrefixKind {
UNKNOWN = "Unknown",
CLASS_IMPORT = "Class Import",
CLASS_REFERENCE = "Class Reference",
STATIC_MEMBER_REFERENCE = "Static Member Reference",
NEW_INSTANCE = "New Instance",
MODULE_IMPORT = "Module Import"
}
import { CompletionPrefixKind } from "../../constants"
import { vmw } from "../../proto"

interface CompletionPrefix {
readonly value: string
Expand Down Expand Up @@ -172,7 +165,7 @@ export class CompletionProvider {
.concat(this.hints.getFunctionSets())
.filter(cls => !!cls.name && cls.name.startsWith(prefix.filter || ""))
.map(cls => {
const name = cls.name || ""
const name = cls.name ?? ""
const completionItem = CompletionItem.create(name)
completionItem.kind = CompletionItemKind.Class
completionItem.documentation = cls.description ? cls.description.trim() : undefined
Expand All @@ -196,44 +189,63 @@ export class CompletionProvider {
if (!cls) return []

const suggestions: CompletionItem[] = []
const methods: CompletionItem[] = this.getMethodsSuggestions(cls, prefix)
const properties: CompletionItem[] = this.getPropertiesSuggestions(cls, prefix)

if (cls.methods && cls.methods.length > 0) {
cls.methods
.filter(method => !!method.name && method.name.startsWith(prefix.filter || ""))
.forEach(method => {
const name = method.name || ""
const completionItem = CompletionItem.create(name)
completionItem.kind = CompletionItemKind.Method
completionItem.documentation = Previewer.extendDescriptionWithParams(
method.description,
method.parameters
)
completionItem.detail = Previewer.computeDetailsForMethod(method)
completionItem.sortText = `000${name}`
suggestions.push(completionItem)
})
methods.forEach(item => suggestions.push(item))
properties.forEach(item => suggestions.push(item))

return suggestions
}

private getMethodsSuggestions(cls: vmw.pscoe.hints.IClass, prefix: CompletionPrefix): CompletionItem[] {
if (!cls.methods?.length) {
return []
}

if (cls.properties && cls.properties.length > 0) {
cls.properties
.filter(prop => !!prop.name && prop.name.startsWith(prefix.filter || ""))
.forEach(prop => {
const name = prop.name || ""
const completionItem = CompletionItem.create(name)
completionItem.kind = CompletionItemKind.Variable
const suggestions: CompletionItem[] = []
cls.methods
.filter((method: vmw.pscoe.hints.IMethod) => !!method.name && method.name.startsWith(prefix.filter || ""))
.forEach((method: vmw.pscoe.hints.IMethod) => {
const name = method.name ?? ""
const completionItem = CompletionItem.create(name)
completionItem.kind = CompletionItemKind.Method
completionItem.documentation = Previewer.extendDescriptionWithParams(
method.description,
method.parameters
)
completionItem.detail = Previewer.computeDetailsForMethod(method)
completionItem.sortText = `000${name}`
suggestions.push(completionItem)
})

if (prop.readOnly) {
completionItem.kind =
name.toUpperCase() === name ? CompletionItemKind.Enum : CompletionItemKind.Value
}
return suggestions
}

completionItem.documentation = prop.description ? prop.description.trim() : undefined
completionItem.detail = Previewer.computeDetailsForProperty(prop)
completionItem.sortText = `000${name}`
suggestions.push(completionItem)
})
private getPropertiesSuggestions(cls: vmw.pscoe.hints.IClass, prefix: CompletionPrefix): CompletionItem[] {
if (!cls.properties?.length) {
return []
}

const suggestions: CompletionItem[] = []
cls.properties
.filter((prop: vmw.pscoe.hints.IProperty) => !!prop.name && prop.name.startsWith(prefix.filter || ""))
.forEach((prop: vmw.pscoe.hints.IProperty) => {
const name = prop.name ?? ""
const completionItem = CompletionItem.create(name)
completionItem.kind = CompletionItemKind.Variable

if (prop.readOnly) {
completionItem.kind =
name.toUpperCase() === name ? CompletionItemKind.Enum : CompletionItemKind.Value
}

completionItem.documentation = prop.description ? prop.description.trim() : undefined
completionItem.detail = Previewer.computeDetailsForProperty(prop)
completionItem.sortText = `000${name}`
suggestions.push(completionItem)
})

return suggestions
}

Expand All @@ -246,7 +258,7 @@ export class CompletionProvider {
.forEach(cls => {
if (cls.constructors && cls.constructors.length > 0) {
for (const constr of cls.constructors) {
const name = cls.name || ""
const name = cls.name ?? ""
const completionItem = CompletionItem.create(name)
completionItem.kind = CompletionItemKind.Constructor

Expand Down Expand Up @@ -274,9 +286,9 @@ export class CompletionProvider {
.getActionsIn(prefix.value, workspaceFolder)
.filter(a => !!a.name && a.name.startsWith(prefix.filter || ""))
.map(action => {
const name = action.name || ""
const name = action.name ?? ""
const completionItem = CompletionItem.create(name)
const isClass = name[0] === name[0].toUpperCase()
const isClass = name[0].startsWith(name[0].toUpperCase())
completionItem.kind = isClass ? CompletionItemKind.Class : CompletionItemKind.Function
completionItem.documentation = Previewer.extendDescriptionWithParams(
action.description,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ export class ServerCollection {
this.logger.error("No vRO objects found")
} else {
for (const plugin of plugins) {
const link = plugin.detailsLink.match(regex)
const link = RegExp(regex).exec(plugin.detailsLink)
if (!link) {
throw new Error(`No plugin details found`)
}
Expand Down

0 comments on commit 509d209

Please sign in to comment.