From 8942a05502e14ed4b1f55dd3e1ddbe472598d814 Mon Sep 17 00:00:00 2001 From: Josh Gross Date: Fri, 17 Mar 2023 13:23:43 -0400 Subject: [PATCH] Handle undefined templates in workflow template cache --- languageservice/src/complete.ts | 16 +++++++--- languageservice/src/document-links.ts | 14 ++++++--- languageservice/src/hover.ts | 16 +++++++--- languageservice/src/utils/workflow-cache.ts | 34 +++++++++++---------- languageservice/src/validate.ts | 2 +- 5 files changed, 51 insertions(+), 31 deletions(-) diff --git a/languageservice/src/complete.ts b/languageservice/src/complete.ts index e998cd8..870138d 100644 --- a/languageservice/src/complete.ts +++ b/languageservice/src/complete.ts @@ -66,14 +66,20 @@ export async function complete( }; const parsedWorkflow = fetchOrParseWorkflow(file, textDocument.uri); - if (!parsedWorkflow) { + if (!parsedWorkflow?.value) { return []; } - const template = await fetchOrConvertWorkflowTemplate(parsedWorkflow, textDocument.uri, config, { - fetchReusableWorkflowDepth: config?.fileProvider ? 1 : 0, - errorPolicy: ErrorPolicy.TryConversion - }); + const template = await fetchOrConvertWorkflowTemplate( + parsedWorkflow.context, + parsedWorkflow.value, + textDocument.uri, + config, + { + fetchReusableWorkflowDepth: config?.fileProvider ? 1 : 0, + errorPolicy: ErrorPolicy.TryConversion + } + ); const {token, keyToken, parent, path} = findToken(newPos, parsedWorkflow.value); const workflowContext = getWorkflowContext(textDocument.uri, template, path); diff --git a/languageservice/src/document-links.ts b/languageservice/src/document-links.ts index 6341cae..5c335e0 100644 --- a/languageservice/src/document-links.ts +++ b/languageservice/src/document-links.ts @@ -16,13 +16,19 @@ export async function documentLinks(document: TextDocument, workspace: string | }; const parsedWorkflow = fetchOrParseWorkflow(file, document.uri); - if (!parsedWorkflow) { + if (!parsedWorkflow?.value) { return []; } - const template = await fetchOrConvertWorkflowTemplate(parsedWorkflow, document.uri, undefined, { - errorPolicy: ErrorPolicy.TryConversion - }); + const template = await fetchOrConvertWorkflowTemplate( + parsedWorkflow.context, + parsedWorkflow.value, + document.uri, + undefined, + { + errorPolicy: ErrorPolicy.TryConversion + } + ); const links: DocumentLink[] = []; diff --git a/languageservice/src/hover.ts b/languageservice/src/hover.ts index acc7b3a..f2cfed0 100644 --- a/languageservice/src/hover.ts +++ b/languageservice/src/hover.ts @@ -44,14 +44,20 @@ export async function hover(document: TextDocument, position: Position, config?: }; const parsedWorkflow = fetchOrParseWorkflow(file, document.uri); - if (!parsedWorkflow) { + if (!parsedWorkflow?.value) { return null; } - const template = await fetchOrConvertWorkflowTemplate(parsedWorkflow, document.uri, config, { - errorPolicy: ErrorPolicy.TryConversion, - fetchReusableWorkflowDepth: config?.fileProvider ? 1 : 0 - }); + const template = await fetchOrConvertWorkflowTemplate( + parsedWorkflow.context, + parsedWorkflow.value, + document.uri, + config, + { + errorPolicy: ErrorPolicy.TryConversion, + fetchReusableWorkflowDepth: config?.fileProvider ? 1 : 0 + } + ); const tokenResult = findToken(position, parsedWorkflow.value); const {token, keyToken, parent} = tokenResult; diff --git a/languageservice/src/utils/workflow-cache.ts b/languageservice/src/utils/workflow-cache.ts index 1e5ca85..8589c62 100644 --- a/languageservice/src/utils/workflow-cache.ts +++ b/languageservice/src/utils/workflow-cache.ts @@ -1,8 +1,14 @@ -import {convertWorkflowTemplate, parseWorkflow} from "@github/actions-workflow-parser"; -import {WorkflowTemplateConverterOptions} from "@github/actions-workflow-parser/model/convert"; +import { + convertWorkflowTemplate, + parseWorkflow, + ParseWorkflowResult, + WorkflowTemplate +} from "@github/actions-workflow-parser"; import {File} from "@github/actions-workflow-parser/workflows/file"; -import {ParseWorkflowResult} from "@github/actions-workflow-parser"; -import {WorkflowTemplate} from "@github/actions-workflow-parser"; +import {WorkflowTemplateConverterOptions} from "@github/actions-workflow-parser/model/convert"; +import {TemplateContext} from "@github/actions-workflow-parser/templates/template-context"; +import {TemplateToken} from "@github/actions-workflow-parser/templates/tokens/template-token"; + import {nullTrace} from "../nulltrace"; import {CompletionConfig} from "../complete"; @@ -30,21 +36,17 @@ export function fetchOrParseWorkflow(file: File, uri: string): ParseWorkflowResu } export async function fetchOrConvertWorkflowTemplate( - parsedWorkflow: ParseWorkflowResult, + context: TemplateContext, + template: TemplateToken, uri: string, config?: CompletionConfig, options?: WorkflowTemplateConverterOptions ): Promise { - let template = workflowTemplateCache.get(uri); - if (!template) { - template = await convertWorkflowTemplate( - parsedWorkflow.context, - // TODO: @joshmgross We can't assume that the value is non-null here - parsedWorkflow.value!, // eslint-disable-line @typescript-eslint/no-non-null-assertion - config?.fileProvider, - options - ); - workflowTemplateCache.set(uri, template); + const cachedTemplate = workflowTemplateCache.get(uri); + if (cachedTemplate) { + return cachedTemplate; } - return template; + const workflowTemplate = await convertWorkflowTemplate(context, template, config?.fileProvider, options); + workflowTemplateCache.set(uri, workflowTemplate); + return workflowTemplate; } diff --git a/languageservice/src/validate.ts b/languageservice/src/validate.ts index 27f5010..f422873 100644 --- a/languageservice/src/validate.ts +++ b/languageservice/src/validate.ts @@ -53,7 +53,7 @@ export async function validate(textDocument: TextDocument, config?: ValidationCo if (result.value) { // Errors will be updated in the context. Attempt to do the conversion anyway in order to give the user more information - const template = await fetchOrConvertWorkflowTemplate(result, textDocument.uri, config, { + const template = await fetchOrConvertWorkflowTemplate(result.context, result.value, textDocument.uri, config, { fetchReusableWorkflowDepth: config?.fileProvider ? 1 : 0, errorPolicy: ErrorPolicy.TryConversion });