Skip to content
This repository has been archived by the owner on Aug 10, 2024. It is now read-only.

Commit

Permalink
Merge pull request #36 from mulesoft-labs/ALS-1706/cv-client-capabili…
Browse files Browse the repository at this point in the history
…ties

Adopt new typings and client capabilities
agusayerza authored Oct 7, 2021
2 parents 6e8bd83 + 92c8869 commit 0ba23d2
Showing 14 changed files with 165 additions and 6,167 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -9,4 +9,5 @@ als.log
.vscode-test/**
.gradle/**
.idea/**
*.code-workspace
*.code-workspace
testFixture/.vscode/
2 changes: 1 addition & 1 deletion Jenkinsfile
Original file line number Diff line number Diff line change
@@ -27,7 +27,7 @@ pipeline {
dockerfile true
}
parameters {
string(name: 'ALS_VERSION', defaultValue: '4.2.0-SNAPSHOT.340', description: 'ALS node client version')
string(name: 'ALS_VERSION', defaultValue: '4.2.0-SNAPSHOT.357', description: 'ALS node client version')
}

environment {
4 changes: 2 additions & 2 deletions install_compile.sh
Original file line number Diff line number Diff line change
@@ -21,8 +21,8 @@ if [ $retVal -ne 0 ]; then
fi


echo "npm i @mulesoft/als-node-client@$ALS_VERSION"
npm i @mulesoft/als-node-client@$ALS_VERSION
echo "npm i @aml-org/als-node-client@$ALS_VERSION"
npm i @aml-org/als-node-client@$ALS_VERSION

retVal=$?
if [ $retVal -ne 0 ]; then
6,056 changes: 33 additions & 6,023 deletions package-lock.json

Large diffs are not rendered by default.

24 changes: 21 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -124,7 +124,7 @@
"command",
"file"
],
"description": "Select how should ALS determine a project configuration, either by `didChangeConfiguration` command or by reading an exchange.json file. For more informaiton please read the [documentation](https://github.com/aml-org/als/blob/7397005c8a17a580c8a102a2537f1a50ca66c965/documentation/features/features.md#als-initialize-params) (Reload required)",
"description": "Select how should ALS determine a project configuration, either by `didChangeConfiguration` command or by reading an exchange.json file. (Reload required)",
"enumDescription": [
"ALS projects can only be configured by using the `didChangeConfiguration`",
"ALS will try to find and read an exchange.json file at the root of the workspace to configure the project."
@@ -206,6 +206,15 @@
"dark": "path/to/dark/icon.svg"
}
},
{
"command": "als.setMainFile",
"title": "Set as Main File",
"category": "Modifications",
"icon": {
"light": "path/to/light/icon.svg",
"dark": "path/to/dark/icon.svg"
}
},
{
"command": "als.registerProfile",
"title": "Register profile",
@@ -223,7 +232,8 @@
"light": "path/to/light/icon.svg",
"dark": "path/to/dark/icon.svg"
}
},{
},
{
"command": "als.registerSemantic",
"title": "Register Semantic",
"category": "Modifications",
@@ -269,6 +279,11 @@
"command": "als.registerProfile",
"group": "7_modification"
},
{
"when": "resourceLangId == aml",
"command": "als.setMainFile",
"group": "7_modification"
},
{
"when": "resourceLangId == aml",
"command": "als.unregisterProfile",
@@ -305,7 +320,7 @@
}
},
"dependencies": {
"@mulesoft/als-node-client": "4.2.0-SNAPSHOT.340",
"@aml-org/als-node-client": "4.2.0-SNAPSHOT.357",
"@types/mocha": "^8.2.1",
"@types/node": "^11.15.20",
"@types/vscode": "1.52.0",
@@ -327,5 +342,8 @@
"test-compile": "tsc -p ./",
"pretest": "npm run test-compile",
"test": "node ./out/test/runTest.js"
},
"devDependencies": {
"@aml-org/amf-custom-validator": "0.1.0-SNAPSHOT.16"
}
}
10 changes: 4 additions & 6 deletions src/extension.ts
Original file line number Diff line number Diff line change
@@ -18,7 +18,7 @@ import { AlsInitializeParamsFeature, ConversionFeature } from './features'
import { AlsLanguageClient } from './server/als'
import { SettingsManager } from './settings'

var jsAls = require.resolve("@mulesoft/als-node-client")
var jsAls = require.resolve("@aml-org/als-node-client")
export let alsLog = vscode.window.createOutputChannel("alsLog");

export class AlsResolver {
@@ -29,9 +29,6 @@ export class AlsResolver {
}
export async function activate(context: ExtensionContext): Promise<AlsResolver> {
const resolver = new AlsResolver();
//Create output channel
// let alsLog = vscode.window.createOutputChannel("alsLog");

//Write to output.
alsLog.appendLine("Hi! I am alsLog, and I will be your troubleshooting companion for the day. I hope you won't need me!");
await createLanguageClient(alsLog, context).then(alsClient => {
@@ -81,8 +78,10 @@ async function createLanguageClient(alsLog: vscode.OutputChannel, context: Exten
const settingsManager = new SettingsManager(["amlLanguageServer.run"])
const als = new AlsLanguageClient(languageClient, settingsManager)


const isJVM = runParams.get("platform") === "jvm";
languageClient.registerFeatures([
new AlsInitializeParamsFeature(runParams.get("configurationStyle")),
new AlsInitializeParamsFeature(runParams.get("configurationStyle"), isJVM),
new ConversionFeature()
])

@@ -125,7 +124,6 @@ function createServer(alsLog: vscode.OutputChannel, context: ExtensionContext):

const jarPath = isLocal ? customPath : `${extensionPath}/lib/als-server.jar`
const jsPath = isLocal ? customPath : jsAls
// const jsPath = require.resolve(`${extensionPath}/lib/node-package/dist/als-node-client.min.js`)

const logFile = logPath !== null ? logPath : `${storagePath}/vscode-aml-language-server.log`

19 changes: 12 additions & 7 deletions src/features.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { AlsClientCapabilities, AlsInitializeParams } from '@aml-org/als-node-client';
import { DocumentSelector } from 'vscode';
import { ClientCapabilities, InitializeParams, ServerCapabilities, StaticFeature } from 'vscode-languageclient';
import { AlsInitializeParams, ProjectConfigurationStyles } from './types';
import { ProjectConfigurationStyles } from './types';
export class ConversionFeature implements StaticFeature {
fillInitializeParams?: (params: InitializeParams) => void;
dispose(): void {
@@ -27,9 +28,9 @@ export class SerializationNotificationFeature implements StaticFeature {
}

export class AlsInitializeParamsFeature implements StaticFeature {
private configurationStyle: ProjectConfigurationStyles = ProjectConfigurationStyles.Command;
constructor(configurationStyle: String) {
switch(configurationStyle) {
private configurationStyle: string = ProjectConfigurationStyles.Command;
constructor(configStyle: String, readonly isJvm: boolean) {
switch(configStyle) {
case ProjectConfigurationStyles.Command:
this.configurationStyle = ProjectConfigurationStyles.Command;
break;
@@ -40,15 +41,19 @@ export class AlsInitializeParamsFeature implements StaticFeature {
this.configurationStyle = ProjectConfigurationStyles.Command;
break;
}
console.log("ProjectConfigurationStyle: " + this.configurationStyle)
}
fillInitializeParams?: (params: InitializeParams) => void = (params: InitializeParams) => {
var castedParams = params as AlsInitializeParams
castedParams.projectConfigurationStyle = {
style: this.configurationStyle.toString()
style: this.configurationStyle
}
}
fillClientCapabilities(capabilities: ClientCapabilities): void {}
fillClientCapabilities(capabilities: ClientCapabilities): void {
var castedCapabilities = capabilities as AlsClientCapabilities;
castedCapabilities.customValidations = {
enabled: !this.isJvm // Custom validations are not supported in JVM
}
}
initialize(capabilities: ServerCapabilities<any>, documentSelector: DocumentSelector): void {}
dispose(): void {}

18 changes: 13 additions & 5 deletions src/server/als.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,37 @@

import * as vscode from 'vscode';
import { RenameFileActionParams, messages, RenameFileActionResult, SerializationParams, SerializationResult, ConversionParams, SerializedDocument, GetWorkspaceConfigurationParams, GetWorkspaceConfigurationResult, DidChangeConfigurationNotificationParams } from '../types';
import { ExecuteCommandRequest, StateChangeEvent } from 'vscode-languageclient';
import { notifyConfig } from './alsConfiguration';
import { FormattingProvider, LANGUAGE_ID } from '../language';
import { LanguageClient } from 'vscode-languageclient/node';
import { conversionHandler, registerProfileHandler, registerSemanticHandler, renameFileHandler, serializationHandler, unregisterProfileHandler, unregisterSemanticHandler } from './handlers';
import { conversionHandler, registerProfileHandler, registerSemanticHandler, renameFileHandler, serializationHandler, setMainFileHandler, unregisterProfileHandler, unregisterSemanticHandler } from './handlers';
import { ConfigurationViewProvider } from '../ui/configurationView';
import { SettingsManager } from '../settings';
import { Disposable } from 'vscode';
import { ConversionParams, DidChangeConfigurationNotificationParams, GetWorkspaceConfigurationParams, GetWorkspaceConfigurationResult, RenameFileActionParams, RenameFileActionResult, SerializationParams, SerializationResult, SerializedDocument } from '@aml-org/als-node-client';
import { messages, ProjectConfigurationStyles } from '../types';


// todo: cleanup all URIs using languageClient.code2ProtocolConverter.asUri(fileUri)
// vscode.Uri with `toString()` causes issues with windows paths
export class AlsLanguageClient {
disposables: Disposable[] = []

configurationStyle: string = vscode.workspace.getConfiguration(`amlLanguageServer.run`).get("configurationStyle")
configurationByCommand: Boolean = this.configurationStyle == ProjectConfigurationStyles.Command

readonly wsConfigTreeViewProvider = new ConfigurationViewProvider(vscode.workspace.workspaceFolders, this)
constructor(readonly languageClient: LanguageClient, private readonly extensionConfigurationManager: SettingsManager) {
this.disposable(vscode.commands.registerCommand("als.renameFile", renameFileHandler(this)))
this.disposable(vscode.commands.registerCommand("als.conversion", conversionHandler(this)))
this.disposable(vscode.commands.registerCommand("als.serialization", serializationHandler(this)))
this.disposable(vscode.commands.registerCommand("als.registerProfile", registerProfileHandler(this)))
this.disposable(vscode.commands.registerCommand("als.unregisterProfile", unregisterProfileHandler(this)))
this.disposable(vscode.commands.registerCommand("als.registerSemantic", registerSemanticHandler(this)))
if(this.configurationByCommand){
this.disposable(vscode.commands.registerCommand("als.setMainFile", setMainFileHandler(this)))
this.disposable(vscode.commands.registerCommand("als.registerProfile", registerProfileHandler(this)))
this.disposable(vscode.commands.registerCommand("als.unregisterProfile", unregisterProfileHandler(this)))
this.disposable(vscode.commands.registerCommand("als.registerSemantic", registerSemanticHandler(this)))
this.disposable(vscode.commands.registerCommand("als.unregisterSemantic", unregisterSemanticHandler(this)))
}
this.disposable(this.languageClient.onDidChangeState(this.languageClientStateListener))
this.disposable(vscode.languages.registerDocumentFormattingEditProvider(LANGUAGE_ID, new FormattingProvider(languageClient)))
this.disposable(vscode.languages.registerDocumentRangeFormattingEditProvider(LANGUAGE_ID, new FormattingProvider(languageClient)))
3 changes: 2 additions & 1 deletion src/server/alsConfiguration.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { AlsConfiguration, messages } from "../types";
import { messages } from "../types";
import { LanguageClient } from "vscode-languageclient/node";
import { workspace } from "vscode";
import { AlsConfiguration } from "@aml-org/als-node-client";


export const initialConfiguration: AlsConfiguration = {
19 changes: 16 additions & 3 deletions src/server/handlers.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,23 @@
import { AlsLanguageClient } from "./als"
import * as vscode from 'vscode';
import { DidChangeConfigurationNotificationParams, DependencyConfiguration, isDependencyConfiguration } from "../types";
import { awaitInputBox } from "../ui/ui";
import {alsLog} from "../extension"
import { DidChangeConfigurationNotificationParams } from "@aml-org/als-node-client";
import { isDependencyConfiguration } from "../types";

export const setMainFileHandler = (als: AlsLanguageClient) => {
return (fileUri: vscode.Uri) => {
alsLog.appendLine("Setting main file: " + fileUri.toString())
const uri = als.languageClient.code2ProtocolConverter.asUri(fileUri);
als.getWorkspaceConfiguration(uri).then(workspaceConfig => {
const newWorkspaceConfig: DidChangeConfigurationNotificationParams = {
...workspaceConfig.configuration,
mainUri: uri
};
als.changeWorkspaceConfigurationCommand(newWorkspaceConfig);
});
}
}

export const registerProfileHandler = (als: AlsLanguageClient) => {
return (fileUri: vscode.Uri) => {
@@ -103,8 +118,6 @@ function unregisterDependency(scopeName: string, fileUri: vscode.Uri, als: AlsLa
folder: uri,
dependencies: workspaceConfig.configuration.dependencies
.filter(v => {
// alsLog.appendLine("isDependencyConfiguration " + isDependencyConfiguration(v))
// alsLog.appendLine("scope and uri " + (!isDependencyConfiguration(v) || !(v.scope == scopeName && v.file.toLowerCase() == uri.toLowerCase())))
return !isDependencyConfiguration(v) || !(v.scope == scopeName && v.file.toLowerCase() == uri.toLowerCase());
})
};
11 changes: 6 additions & 5 deletions src/settings.ts
Original file line number Diff line number Diff line change
@@ -8,13 +8,14 @@ export class SettingsManager {
settingRequiresRestart(config: string) {
vscode.workspace.onDidChangeConfiguration(event => {
event.affectsConfiguration(config)
const errMsg = "AML Support configuration has changed and requires a reload.";
const reload: string = "Reload";
vscode.window.showInformationMessage(errMsg, reload).then(async (value?: string) => {
if (value === reload) {
vscode.commands.executeCommand("workbench.action.reloadWindow");
const errMsg = "AML Support configuration has changed and requires a restart.";
const restart: string = "Restart";
vscode.window.showInformationMessage(errMsg, restart).then(async (value?: string) => {
if (value === restart) {
vscode.commands.executeCommand("als.restart");
}
});

})
}
}
3 changes: 2 additions & 1 deletion src/test/e2e/fileRename.test.ts
Original file line number Diff line number Diff line change
@@ -3,7 +3,8 @@
import * as vscode from 'vscode';
import * as assert from 'assert';
import { getDocUri, activate, testFilesDirectory, activateExtension } from '../helper';
import { messages, RenameFileActionParams, RenameFileActionResult } from '../../types';
import { messages } from '../../types';
import { RenameFileActionParams, RenameFileActionResult } from '@aml-org/als-node-client';

suite('Should rename file', async function () {
test('Rename file DataType.raml', async () => {
99 changes: 13 additions & 86 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -1,103 +1,30 @@
import { TextDocumentIdentifier, InitializeParams, NotificationType, RequestType, WorkspaceEdit } from "vscode-languageclient"

interface IMap<V> { [key: string]: V }

import { AlsConfiguration, ConfigurationNotification, GetWorkspaceConfigurationRequestType, AlsRenameFileRequestType, RenameFileActionParams, RenameFileActionResult, SerializationRequestType, SerializationParams, SerializationResult, ConversionParams, SerializedDocument, ConversionRequestType, GetWorkspaceConfigurationParams, GetWorkspaceConfigurationResult, AlsDependency, Dependency } from "@aml-org/als-node-client"
import { NotificationType, RequestType } from "vscode-languageclient"

export namespace messages {
export const AlsConfigurationNotification = {
export const AlsConfigurationNotification: ConfigurationNotification = {
type: new NotificationType<AlsConfiguration>("updateConfiguration")
}
export const AlsRenameFileRequest = {
export const AlsRenameFileRequest: AlsRenameFileRequestType = {
type: new RequestType<RenameFileActionParams, RenameFileActionResult, void>("renameFile")
}
export const AlsSerializationRequest = {
export const AlsSerializationRequest: SerializationRequestType = {
type: new RequestType<SerializationParams, SerializationResult, void>("serialization")
}
export const AlsConversionRequest = {
export const AlsConversionRequest: ConversionRequestType = {
type: new RequestType<ConversionParams, SerializedDocument, void>("conversion")
}

export const AlsGetWorkspaceConfiguration = {
export const AlsGetWorkspaceConfiguration: GetWorkspaceConfigurationRequestType = {
type: new RequestType<GetWorkspaceConfigurationParams, GetWorkspaceConfigurationResult, void>("getWorkspaceConfiguration")
}
}

export type SerializationParams = {
documentIdentifier: TextDocumentIdentifier
}

export type SerializationResult = {
uri: string,
model: any
}

export type ConversionParams = {
uri: string,
target: string,
syntax?: string
}

export type SerializedDocument = {
uri: string,
document: string
}


export type RenameFileActionParams = {
oldDocument: TextDocumentIdentifier,
newDocument: TextDocumentIdentifier
}

export type RenameFileActionResult = {
edits: WorkspaceEdit
}


export type AlsConfiguration = {
formattingOptions: IMap<AlsFormattingOptions>
templateType: String
prettyPrintSerialization: boolean
}

export type AlsFormattingOptions = {
tabSize: number,
preferSpaces: Boolean,
}

export type ProjectConfigurationStyle = {
style: String
}

export type AlsInitializeParams = InitializeParams & {
configuration: AlsConfiguration,
projectConfigurationStyle: ProjectConfigurationStyle
}

export type DidChangeConfigurationNotificationParams = {
mainUri: string,
folder?: string,
dependencies: (string | DependencyConfiguration)[]
}

export type DependencyConfiguration = {
file: string,
scope: string
}

export function isDependencyConfiguration(t: string | DependencyConfiguration): t is DependencyConfiguration {
return (<DependencyConfiguration>t).scope !== undefined;
export function isDependencyConfiguration(t: AlsDependency): t is Dependency {
return (<Dependency>t).scope !== undefined;
}

export type GetWorkspaceConfigurationParams = {
textDocument: TextDocumentIdentifier
}

export type GetWorkspaceConfigurationResult = {
workspace: string,
configuration: DidChangeConfigurationNotificationParams
}

export enum ProjectConfigurationStyles {
Command = "command",
File = "file"
}
export const ProjectConfigurationStyles = {
Command: "command",
File: "file"
}
61 changes: 38 additions & 23 deletions src/ui/configurationView.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import * as vscode from 'vscode';
import * as path from 'path';
import { AlsLanguageClient } from '../server/als';
import { GetWorkspaceConfigurationResult, isDependencyConfiguration } from '../types';
import { isDependencyConfiguration } from '../types';
import { AlsDependency, Dependency, GetWorkspaceConfigurationResult } from '@aml-org/als-node-client';

export class ConfigurationViewProvider implements vscode.TreeDataProvider<WorkspaceConfigurationEntry> {
constructor(private workspaces: ReadonlyArray<vscode.WorkspaceFolder>, private als: AlsLanguageClient) {}
constructor(private workspaces: ReadonlyArray<vscode.WorkspaceFolder>, private als: AlsLanguageClient) { }

getTreeItem(element: WorkspaceConfigurationEntry): vscode.TreeItem {
return element;
@@ -17,32 +18,30 @@ export class ConfigurationViewProvider implements vscode.TreeDataProvider<Worksp
return resolve([]);
}

if(!this.als.ready()) {
if (!this.als.ready()) {
vscode.window.showInformationMessage('ALS not ready yet');
return resolve([]);
}

if (element && element instanceof WorkspaceConfigurationParent) {
const result = new Array<WorkspaceConfigurationEntry>()
if(element.configuration.configuration.mainUri != "") {
return resolve([new MainFileEntry(element.configuration.configuration.mainUri)])
if (element.configuration.configuration.mainUri != "") {
result.push(new MainFileEntry(element.configuration.configuration.mainUri))
}
if(element.configuration.configuration.dependencies.filter(isDependencyConfiguration).filter(v => v.scope == "custom-validation").length > 0) {
if (element.configuration.configuration.dependencies.filter(isDependencyConfiguration).filter(v => v.scope == "custom-validation").length > 0) {
result.push(new DependencyHolderEntry("Profiles", vscode.TreeItemCollapsibleState.Collapsed, element.configuration))
}
if(element.configuration.configuration.dependencies.filter(isDependencyConfiguration).filter(v => v.scope == "semantic-extension").length > 0) {
if (element.configuration.configuration.dependencies.filter(isDependencyConfiguration).filter(v => v.scope == "semantic-extension").length > 0) {
result.push(new DependencyHolderEntry("Extensions", vscode.TreeItemCollapsibleState.Collapsed, element.configuration))
}
return resolve(result);
} else if(element && element instanceof DependencyHolderEntry && element.label == "Profiles"){
} else if (element && element instanceof DependencyHolderEntry && element.label == "Profiles") {
return resolve(element.configuration.configuration.dependencies.filter(isDependencyConfiguration).filter(v => v.scope == "custom-validation").map(profile => {
console.log(element.iconPath);
return new DependencyEntry(profile.file, vscode.TreeItemCollapsibleState.None, element.configuration)
return new DependencyEntryBuilder(profile, vscode.TreeItemCollapsibleState.Expanded, element.configuration).build();
}))
} else if(element && element instanceof DependencyHolderEntry && element.label == "Extensions"){
} else if (element && element instanceof DependencyHolderEntry && element.label == "Extensions") {
return resolve(element.configuration.configuration.dependencies.filter(isDependencyConfiguration).filter(v => v.scope == "semantic-extension").map(profile => {
console.log(element.iconPath);
return new DependencyEntry(profile.file, vscode.TreeItemCollapsibleState.None, element.configuration)
return new DependencyEntryBuilder(profile, vscode.TreeItemCollapsibleState.Expanded, element.configuration).build();
}))
} else {
return resolve(Promise.all(this.workspaces.map<Promise<WorkspaceConfigurationEntry>>(async ws => {
@@ -67,7 +66,7 @@ export class ConfigurationViewProvider implements vscode.TreeDataProvider<Worksp
this.workspaces = workspaces;
this._onDidChangeTreeData.fire(undefined);
}

}

class WorkspaceConfigurationEntry extends vscode.TreeItem {
@@ -106,15 +105,31 @@ class DependencyHolderEntry extends WorkspaceConfigurationEntry {
};
}

class DependencyEntryBuilder {
constructor(
public readonly dependency: AlsDependency,
public readonly collapsibleState: vscode.TreeItemCollapsibleState,
public readonly configuration: GetWorkspaceConfigurationResult
) { }

build = () => {
const fullPath = (isDependencyConfiguration(this.dependency)) ? this.dependency.file : this.dependency;
const shortPath = fullPath.replace(this.configuration.workspace + path.sep, "")
return new DependencyEntry(fullPath, shortPath, vscode.TreeItemCollapsibleState.None, this.configuration)
}

}

class DependencyEntry extends WorkspaceConfigurationEntry {
constructor(
public readonly label: string,
readonly fullPath: string,
public readonly shortPath: string,
public readonly collapsibleState: vscode.TreeItemCollapsibleState,
public readonly configuration: GetWorkspaceConfigurationResult
) {
super(label, collapsibleState);
this.tooltip = `${this.label}`;
this.description = "";
super(shortPath, collapsibleState);
this.tooltip = fullPath;
this.description = fullPath;
}

iconPath = {
@@ -126,11 +141,11 @@ class DependencyEntry extends WorkspaceConfigurationEntry {

class MainFileEntry extends WorkspaceConfigurationEntry {
constructor(
public readonly label: string
public readonly uri: string
) {
super(label, vscode.TreeItemCollapsibleState.None);
this.tooltip = `${this.label}`;
this.description = this.label;
super("Main file: " + uri, vscode.TreeItemCollapsibleState.None);
this.tooltip = `${this.uri}`;
this.description = this.uri;
}

iconPath = {

0 comments on commit 0ba23d2

Please sign in to comment.