diff --git a/packages/theme-language-server-common/src/hover/HoverProvider.ts b/packages/theme-language-server-common/src/hover/HoverProvider.ts index d77d7c02a..245c07e7c 100644 --- a/packages/theme-language-server-common/src/hover/HoverProvider.ts +++ b/packages/theme-language-server-common/src/hover/HoverProvider.ts @@ -17,7 +17,7 @@ import { import { HtmlAttributeValueHoverProvider } from './providers/HtmlAttributeValueHoverProvider'; import { findCurrentNode } from '@shopify/theme-check-common'; import { GetThemeSettingsSchemaForURI } from '../settings'; -import { GetLiquidDocDefinitionsForURI } from '../liquidDoc'; +import { GetSnippetDefinitionForURI } from '../liquidDoc'; export class HoverProvider { private providers: BaseHoverProvider[] = []; @@ -28,7 +28,7 @@ export class HoverProvider { readonly getMetafieldDefinitions: (rootUri: string) => Promise, readonly getTranslationsForURI: GetTranslationsForURI = async () => ({}), readonly getSettingsSchemaForURI: GetThemeSettingsSchemaForURI = async () => [], - readonly getLiquidDocDefinitionsForURI: GetLiquidDocDefinitionsForURI = async ( + readonly getSnippetDefinitionForURI: GetSnippetDefinitionForURI = async ( _uri, snippetName, ) => ({ @@ -49,7 +49,7 @@ export class HoverProvider { new HtmlAttributeHoverProvider(), new HtmlAttributeValueHoverProvider(), new TranslationHoverProvider(getTranslationsForURI, documentManager), - new RenderSnippetHoverProvider(getLiquidDocDefinitionsForURI), + new RenderSnippetHoverProvider(getSnippetDefinitionForURI), ]; } diff --git a/packages/theme-language-server-common/src/hover/providers/RenderSnippetHoverProvider.spec.ts b/packages/theme-language-server-common/src/hover/providers/RenderSnippetHoverProvider.spec.ts index b0c19e079..a041e3451 100644 --- a/packages/theme-language-server-common/src/hover/providers/RenderSnippetHoverProvider.spec.ts +++ b/packages/theme-language-server-common/src/hover/providers/RenderSnippetHoverProvider.spec.ts @@ -2,14 +2,14 @@ import { describe, beforeEach, it, expect } from 'vitest'; import { DocumentManager } from '../../documents'; import { HoverProvider } from '../HoverProvider'; import { MetafieldDefinitionMap } from '@shopify/theme-check-common'; -import { LiquidDocDefinition } from '../../liquidDoc'; +import { GetSnippetDefinitionForURI, SnippetDefinition } from '../../liquidDoc'; describe('Module: RenderSnippetHoverProvider', async () => { let provider: HoverProvider; - let getLiquidDoc: () => Promise; - const mockDefinitions = { - 'product-card': { - name: 'product-card', + let getSnippetDefinition: GetSnippetDefinitionForURI; + const mockSnippetDefinition: SnippetDefinition = { + name: 'product-card', + liquidDoc: { parameters: [ { name: 'title', @@ -23,12 +23,9 @@ describe('Module: RenderSnippetHoverProvider', async () => { }, ], }, - 'empty-snippet': { - name: 'empty-snippet', - }, }; - const createProvider = (getLiquidDoc: () => Promise) => { + const createProvider = (getSnippetDefinition: GetSnippetDefinitionForURI) => { return new HoverProvider( new DocumentManager(), { @@ -40,17 +37,17 @@ describe('Module: RenderSnippetHoverProvider', async () => { async (_rootUri: string) => ({} as MetafieldDefinitionMap), async () => ({}), async () => [], - getLiquidDoc, + getSnippetDefinition, ); }; beforeEach(async () => { - getLiquidDoc = async () => mockDefinitions['product-card']; - provider = createProvider(getLiquidDoc); + getSnippetDefinition = async () => mockSnippetDefinition; + provider = createProvider(getSnippetDefinition); }); describe('hover', () => { - it('should return snippet documentation with all parameters', async () => { + it('should return snippet definition with all parameters', async () => { await expect(provider).to.hover( `{% render 'product-car█d' %}`, '### product-card\n\n**Parameters:**\n- `title`: string - The title of the product\n- `border-radius`: number - The border radius in px', @@ -58,8 +55,8 @@ describe('Module: RenderSnippetHoverProvider', async () => { }); it('should return an H3 with snippet name if no LiquidDocDefinition found', async () => { - getLiquidDoc = async () => undefined as any; - provider = createProvider(getLiquidDoc); + getSnippetDefinition = async () => ({ name: 'unknown-snippet' }); + provider = createProvider(getSnippetDefinition); await expect(provider).to.hover(`{% render 'unknown-sni█ppet' %}`, '### unknown-snippet'); }); diff --git a/packages/theme-language-server-common/src/hover/providers/RenderSnippetHoverProvider.ts b/packages/theme-language-server-common/src/hover/providers/RenderSnippetHoverProvider.ts index 95f98e3f7..479c535e2 100644 --- a/packages/theme-language-server-common/src/hover/providers/RenderSnippetHoverProvider.ts +++ b/packages/theme-language-server-common/src/hover/providers/RenderSnippetHoverProvider.ts @@ -2,14 +2,17 @@ import { NodeTypes } from '@shopify/liquid-html-parser'; import { LiquidHtmlNode } from '@shopify/theme-check-common'; import { Hover, HoverParams } from 'vscode-languageserver'; import { BaseHoverProvider } from '../BaseHoverProvider'; -import { LiquidDocDefinition, LiquidDocParameter } from '../../liquidDoc'; +import { SnippetDefinition, LiquidDocParameter } from '../../liquidDoc'; +/** + * @param x {string} asdf + */ export class RenderSnippetHoverProvider implements BaseHoverProvider { constructor( - private getLiquidDocDefinitionsForURI: ( + private getSnippetDefinitionForURI: ( uri: string, snippetName: string, - ) => Promise, + ) => Promise, ) {} async hover( @@ -27,30 +30,32 @@ export class RenderSnippetHoverProvider implements BaseHoverProvider { } const snippetName = currentNode.value.replace(/['"]/g, ''); - const liquidDocDefinition = await this.getLiquidDocDefinitionsForURI( + const snippetDefinition = await this.getSnippetDefinitionForURI( params.textDocument.uri, snippetName, ); - if (!liquidDocDefinition) { + if (!snippetDefinition.liquidDoc) { return { contents: { kind: 'markdown', - value: `### ${snippetName}`, + value: `### ${snippetDefinition.name}`, }, }; } - const parameterDocs = liquidDocDefinition.parameters + const liquidDoc = snippetDefinition.liquidDoc; + + const parameters = liquidDoc.parameters ?.map( (param: LiquidDocParameter) => `- \`${param.name}\`${param.type ? `: ${param.type}` : ''} - ${param.description || ''}`, ) .join('\n'); - const parts = [`### ${liquidDocDefinition.name}`]; - if (parameterDocs) { - parts.push('', '**Parameters:**', parameterDocs); + const parts = [`### ${snippetDefinition.name}`]; + if (parameters) { + parts.push('', '**Parameters:**', parameters); } return { diff --git a/packages/theme-language-server-common/src/liquidDoc.spec.ts b/packages/theme-language-server-common/src/liquidDoc.spec.ts index 169c5a461..30dde2b1a 100644 --- a/packages/theme-language-server-common/src/liquidDoc.spec.ts +++ b/packages/theme-language-server-common/src/liquidDoc.spec.ts @@ -20,7 +20,9 @@ describe('Unit: makeGetLiquidDocDefinitions', () => { const result = getSnippetDefinition(ast, 'product-card'); expect(result).to.deep.equal({ name: 'product-card', - parameters: [], + liquidDoc: { + parameters: [], + }, }); }); @@ -37,28 +39,30 @@ describe('Unit: makeGetLiquidDocDefinitions', () => { const result = getSnippetDefinition(ast, 'product-card'); expect(result).to.deep.equal({ name: 'product-card', - parameters: [ - { - name: 'firstParam', - description: 'The first param', - type: 'String', - }, - { - name: 'secondParam', - description: 'The second param', - type: 'Number', - }, - { - name: 'paramWithNoType', - description: 'param with no type', - type: null, - }, - { - name: 'paramWithOnlyName', - description: '', - type: null, - }, - ], + liquidDoc: { + parameters: [ + { + name: 'firstParam', + description: 'The first param', + type: 'String', + }, + { + name: 'secondParam', + description: 'The second param', + type: 'Number', + }, + { + name: 'paramWithNoType', + description: 'param with no type', + type: null, + }, + { + name: 'paramWithOnlyName', + description: '', + type: null, + }, + ], + }, }); }); }); diff --git a/packages/theme-language-server-common/src/liquidDoc.ts b/packages/theme-language-server-common/src/liquidDoc.ts index 89c5db111..516b491fa 100644 --- a/packages/theme-language-server-common/src/liquidDoc.ts +++ b/packages/theme-language-server-common/src/liquidDoc.ts @@ -4,10 +4,10 @@ import { LiquidHtmlNode } from '@shopify/theme-check-common'; import { LiquidDocParamNode } from '@shopify/liquid-html-parser'; -export type GetLiquidDocDefinitionsForURI = ( +export type GetSnippetDefinitionForURI = ( uri: string, snippetName: string, -) => Promise; +) => Promise; export type LiquidDocParameter = { name: string; @@ -15,12 +15,19 @@ export type LiquidDocParameter = { type: string | null; }; -export type LiquidDocDefinition = { +export type SnippetDefinition = { name: string; + liquidDoc?: LiquidDocDefinition; +}; + +type LiquidDocDefinition = { parameters?: LiquidDocParameter[]; }; -export function getSnippetDefinition(snippet: LiquidHtmlNode, snippetName: string) { +export function getSnippetDefinition( + snippet: LiquidHtmlNode, + snippetName: string, +): SnippetDefinition { const liquidDocAnnotations: LiquidDocParameter[] = visit< SourceCodeType.LiquidHtml, LiquidDocParameter @@ -36,6 +43,8 @@ export function getSnippetDefinition(snippet: LiquidHtmlNode, snippetName: strin return { name: snippetName, - parameters: liquidDocAnnotations, + liquidDoc: { + parameters: liquidDocAnnotations, + }, }; } diff --git a/packages/theme-language-server-common/src/server/startServer.ts b/packages/theme-language-server-common/src/server/startServer.ts index 94fca5a92..058d190ef 100644 --- a/packages/theme-language-server-common/src/server/startServer.ts +++ b/packages/theme-language-server-common/src/server/startServer.ts @@ -12,7 +12,6 @@ import { path, recursiveReadDirectory, SourceCodeType, - visit, } from '@shopify/theme-check-common'; import { Connection, @@ -30,7 +29,7 @@ import { GetSnippetNamesForURI } from '../completions/providers/RenderSnippetCom import { DiagnosticsManager, makeRunChecks } from '../diagnostics'; import { DocumentHighlightsProvider } from '../documentHighlights/DocumentHighlightsProvider'; import { DocumentLinksProvider } from '../documentLinks'; -import { AugmentedLiquidSourceCode, DocumentManager } from '../documents'; +import { DocumentManager } from '../documents'; import { OnTypeFormattingProvider } from '../formatting'; import { HoverProvider } from '../hover'; import { JSONLanguageService } from '../json/JSONLanguageService'; @@ -44,8 +43,8 @@ import { snippetName } from '../utils/uri'; import { VERSION } from '../version'; import { CachedFileSystem } from './CachedFileSystem'; import { Configuration } from './Configuration'; -import { LiquidDocParamNode, LiquidHtmlNode } from '@shopify/liquid-html-parser'; -import { LiquidDocDefinition, LiquidDocParameter } from '../liquidDoc'; +import { LiquidHtmlNode } from '@shopify/liquid-html-parser'; +import { getSnippetDefinition, SnippetDefinition } from '../liquidDoc'; const defaultLogger = () => {}; @@ -174,10 +173,10 @@ export function startServer( return getDefaultSchemaTranslations(); }; - const getLiquidDocDefinitionsForURI = async ( + const getSnippetDefinitionForURI = async ( uri: string, snippetName: string, - ): Promise => { + ): Promise => { const rootUri = await findThemeRootURI(uri); const snippetURI = path.join(rootUri, 'snippets', `${snippetName}.liquid`); const snippet = documentManager.get(snippetURI); @@ -270,7 +269,7 @@ export function startServer( getMetafieldDefinitions, getTranslationsForURI, getThemeSettingsSchemaForURI, - getLiquidDocDefinitionsForURI, + getSnippetDefinitionForURI, ); const executeCommandProvider = new ExecuteCommandProvider( @@ -583,9 +582,3 @@ export function startServer( connection.listen(); } -function getSnippetDefinition( - ast: LiquidHtmlNode, - snippetName: string, -): LiquidDocDefinition | PromiseLike { - throw new Error('Function not implemented.'); -}