Skip to content

Commit

Permalink
Add basic completion service
Browse files Browse the repository at this point in the history
Still WIP
  • Loading branch information
davelopez committed Jul 31, 2022
1 parent c9a5635 commit cbae97e
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 3 deletions.
5 changes: 4 additions & 1 deletion server/gx-workflow-ls-format2/src/languageService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
import { LanguageService, getLanguageService } from "@gxwf/yaml-language-service/src/yamlLanguageService";
import { GxFormat2WorkflowDocument } from "./gxFormat2WorkflowDocument";
import { GalaxyWorkflowFormat2SchemaLoader } from "./schema";
import { GxFormat2CompletionService } from "./services/completionService";
import { GxFormat2HoverService } from "./services/hoverService";

/**
Expand All @@ -23,11 +24,13 @@ export class GxFormat2WorkflowLanguageService extends WorkflowLanguageService {
private _yamlLanguageService: LanguageService;
private _schemaLoader: GalaxyWorkflowFormat2SchemaLoader;
private _hoverService: GxFormat2HoverService;
private _completionService: GxFormat2CompletionService;
constructor() {
super();
this._schemaLoader = new GalaxyWorkflowFormat2SchemaLoader();
this._yamlLanguageService = getLanguageService();
this._hoverService = new GxFormat2HoverService(this._schemaLoader.nodeResolver);
this._completionService = new GxFormat2CompletionService(this._schemaLoader.nodeResolver);
}

public override parseWorkflowDocument(document: TextDocument): WorkflowDocument {
Expand All @@ -47,7 +50,7 @@ export class GxFormat2WorkflowLanguageService extends WorkflowLanguageService {
workflowDocument: WorkflowDocument,
position: Position
): Promise<CompletionList | null> {
return null;
return this._completionService.doComplete(workflowDocument.textDocument, position, workflowDocument.nodeManager);
}

protected override async doValidation(workflowDocument: WorkflowDocument): Promise<Diagnostic[]> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ export class SchemaNodeResolver {
return this.getSchemaNodeForSegment(parentNode.typeRef);
}
}

return schemaNodeFound;
}

Expand Down
82 changes: 82 additions & 0 deletions server/gx-workflow-ls-format2/src/services/completionService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { ASTNodeManager } from "@gxwf/server-common/src/ast/nodeManager";
import { ASTNode } from "@gxwf/server-common/src/ast/types";
import {
CompletionItem,
CompletionItemKind,
CompletionList,
Position,
TextDocument,
} from "@gxwf/server-common/src/languageTypes";
import { TextBuffer } from "@gxwf/yaml-language-service/src/utils/textBuffer";
import { SchemaNode, SchemaNodeResolver } from "../schema";

export class GxFormat2CompletionService {
constructor(protected readonly schemaNodeResolver: SchemaNodeResolver) {}

public doComplete(
textDocument: TextDocument,
position: Position,
nodeManager: ASTNodeManager
): Promise<CompletionList> {
const result: CompletionList = {
items: [],
isIncomplete: false,
};

const textBuffer = new TextBuffer(textDocument);
const text = textBuffer.getText();
const offset = textBuffer.getOffsetAt(position);
const node = nodeManager.getNodeFromOffset(offset);
if (!node) {
return Promise.resolve(result);
}
if (text.charAt(offset - 1) === ":") {
return Promise.resolve(result);
}

DEBUG_printNodeName(node);

const existing = nodeManager.getDeclaredPropertyNames(node);
if (nodeManager.isRoot(node)) {
result.items = this.getProposedItems(this.schemaNodeResolver.rootNode, existing);
return Promise.resolve(result);
}
const nodePath = nodeManager.getPathFromNode(node);
const schemaNode = this.schemaNodeResolver.resolveSchemaContext(nodePath);
if (schemaNode) {
result.items = this.getProposedItems(schemaNode, existing);
}
return Promise.resolve(result);
}

private getProposedItems(schemaNode: SchemaNode, exclude: Set<string>): CompletionItem[] {
const result: CompletionItem[] = [];
schemaNode.children.forEach((child) => {
if (exclude.has(child.name)) return;
const item: CompletionItem = {
label: child.name,
documentation: child.documentation,
sortText: `_${child.name}`,
kind: CompletionItemKind.Field,
insertText: `${child.name}: `,
};
result.push(item);
});
return result;
}
}

function DEBUG_printNodeName(node: ASTNode): void {
let nodeName = "_root_";
if (node?.type === "property") {
nodeName = node.keyNode.value;
console.debug("COMPLETION NODE PROPERTY", nodeName);
} else if (node?.type === "object") {
console.debug(`COMPLETION NODE OBJECT:`);
node.properties.forEach((p) => {
console.debug(` ${p.keyNode.value}`);
});
} else {
console.debug("UNKNOWN");
}
}
2 changes: 1 addition & 1 deletion server/gx-workflow-ls-format2/tests/unit/schema.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ describe("Gxformat2 Schema Handling", () => {
describe("SchemaNodeResolver", () => {
let nodeResolver: SchemaNodeResolver;
beforeAll(() => {
nodeResolver = new SchemaNodeResolver(schemaLoader.definitions);
nodeResolver = schemaLoader.nodeResolver;
});
describe("resolveSchemaContext", () => {
it.each([
Expand Down

0 comments on commit cbae97e

Please sign in to comment.