Skip to content

Commit

Permalink
Refactor Liquid documentation types and update references to improve …
Browse files Browse the repository at this point in the history
…clarity

- Renamed `GetLiquidDocDefinitionsForURI` to `GetSnippetDefinitionForURI`
- Introduced `SnippetDefinition` type to replace `LiquidDocDefinition`, enhancing type specificity.
  • Loading branch information
jamesmengo committed Jan 22, 2025
1 parent e298ecb commit a167761
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 69 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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[] = [];
Expand All @@ -28,7 +28,7 @@ export class HoverProvider {
readonly getMetafieldDefinitions: (rootUri: string) => Promise<MetafieldDefinitionMap>,
readonly getTranslationsForURI: GetTranslationsForURI = async () => ({}),
readonly getSettingsSchemaForURI: GetThemeSettingsSchemaForURI = async () => [],
readonly getLiquidDocDefinitionsForURI: GetLiquidDocDefinitionsForURI = async (
readonly getSnippetDefinitionForURI: GetSnippetDefinitionForURI = async (
_uri,
snippetName,
) => ({
Expand All @@ -49,7 +49,7 @@ export class HoverProvider {
new HtmlAttributeHoverProvider(),
new HtmlAttributeValueHoverProvider(),
new TranslationHoverProvider(getTranslationsForURI, documentManager),
new RenderSnippetHoverProvider(getLiquidDocDefinitionsForURI),
new RenderSnippetHoverProvider(getSnippetDefinitionForURI),
];
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<LiquidDocDefinition>;
const mockDefinitions = {
'product-card': {
name: 'product-card',
let getSnippetDefinition: GetSnippetDefinitionForURI;
const mockSnippetDefinition: SnippetDefinition = {
name: 'product-card',
liquidDoc: {
parameters: [
{
name: 'title',
Expand All @@ -23,12 +23,9 @@ describe('Module: RenderSnippetHoverProvider', async () => {
},
],
},
'empty-snippet': {
name: 'empty-snippet',
},
};

const createProvider = (getLiquidDoc: () => Promise<LiquidDocDefinition>) => {
const createProvider = (getSnippetDefinition: GetSnippetDefinitionForURI) => {
return new HoverProvider(
new DocumentManager(),
{
Expand All @@ -40,26 +37,26 @@ 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',
);
});

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');
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<LiquidDocDefinition>,
) => Promise<SnippetDefinition>,
) {}

async hover(
Expand All @@ -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 {
Expand Down
50 changes: 27 additions & 23 deletions packages/theme-language-server-common/src/liquidDoc.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ describe('Unit: makeGetLiquidDocDefinitions', () => {
const result = getSnippetDefinition(ast, 'product-card');
expect(result).to.deep.equal({
name: 'product-card',
parameters: [],
liquidDoc: {
parameters: [],
},
});
});

Expand All @@ -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,
},
],
},
});
});
});
19 changes: 14 additions & 5 deletions packages/theme-language-server-common/src/liquidDoc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,30 @@ 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<LiquidDocDefinition>;
) => Promise<SnippetDefinition>;

export type LiquidDocParameter = {
name: string;
description: string | null;
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
Expand All @@ -36,6 +43,8 @@ export function getSnippetDefinition(snippet: LiquidHtmlNode, snippetName: strin

return {
name: snippetName,
parameters: liquidDocAnnotations,
liquidDoc: {
parameters: liquidDocAnnotations,
},
};
}
19 changes: 6 additions & 13 deletions packages/theme-language-server-common/src/server/startServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import {
path,
recursiveReadDirectory,
SourceCodeType,
visit,
} from '@shopify/theme-check-common';
import {
Connection,
Expand All @@ -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';
Expand All @@ -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 = () => {};

Expand Down Expand Up @@ -174,10 +173,10 @@ export function startServer(
return getDefaultSchemaTranslations();
};

const getLiquidDocDefinitionsForURI = async (
const getSnippetDefinitionForURI = async (
uri: string,
snippetName: string,
): Promise<LiquidDocDefinition> => {
): Promise<SnippetDefinition> => {
const rootUri = await findThemeRootURI(uri);
const snippetURI = path.join(rootUri, 'snippets', `${snippetName}.liquid`);
const snippet = documentManager.get(snippetURI);
Expand Down Expand Up @@ -270,7 +269,7 @@ export function startServer(
getMetafieldDefinitions,
getTranslationsForURI,
getThemeSettingsSchemaForURI,
getLiquidDocDefinitionsForURI,
getSnippetDefinitionForURI,
);

const executeCommandProvider = new ExecuteCommandProvider(
Expand Down Expand Up @@ -583,9 +582,3 @@ export function startServer(

connection.listen();
}
function getSnippetDefinition(
ast: LiquidHtmlNode,
snippetName: string,
): LiquidDocDefinition | PromiseLike<LiquidDocDefinition> {
throw new Error('Function not implemented.');
}

0 comments on commit a167761

Please sign in to comment.