Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/afraid-years-rule.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@shopify/theme-language-server-common": patch
---

Read only liquid and JSON files from theme directories (assets, blocks, config, layout, locales, sections, snippets, templates) when preloading files
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ describe('Module: DocumentManager', () => {
beforeEach(async () => {
fs = new MockFileSystem(
{
'snippet/foo.liquid': `hello {% render 'bar' %}`,
'snippet/bar.liquid': `world`,
'snippets/foo.liquid': `hello {% render 'bar' %}`,
'snippets/bar.liquid': `world`,
},
'mock-fs:',
);
Expand All @@ -58,14 +58,14 @@ describe('Module: DocumentManager', () => {
});

it('preloads source codes with a version of undefined', async () => {
const sc = documentManager.get('mock-fs:/snippet/foo.liquid');
const sc = documentManager.get('mock-fs:/snippets/foo.liquid');
assert(sc);
expect(sc.version).to.equal(undefined);
});

it('returns defined versions of opened files', () => {
documentManager.open('mock-fs:/snippet/foo.liquid', 'hello {% render "bar" %}', 0);
const sc = documentManager.get('mock-fs:/snippet/foo.liquid');
documentManager.open('mock-fs:/snippets/foo.liquid', 'hello {% render "bar" %}', 0);
const sc = documentManager.get('mock-fs:/snippets/foo.liquid');
assert(sc);
expect(sc.version).to.equal(0);
});
Expand All @@ -84,9 +84,9 @@ describe('Module: DocumentManager', () => {

describe('Unit: close(uri)', () => {
it('sets the source version to undefined (value is on disk)', () => {
documentManager.open('mock-fs:/snippet/foo.liquid', 'hello {% render "bar" %}', 10);
documentManager.close('mock-fs:/snippet/foo.liquid');
const sc = documentManager.get('mock-fs:/snippet/foo.liquid');
documentManager.open('mock-fs:/snippets/foo.liquid', 'hello {% render "bar" %}', 10);
documentManager.close('mock-fs:/snippets/foo.liquid');
const sc = documentManager.get('mock-fs:/snippets/foo.liquid');
assert(sc);
expect(sc.source).to.equal('hello {% render "bar" %}');
expect(sc.version).to.equal(undefined);
Expand All @@ -96,9 +96,9 @@ describe('Module: DocumentManager', () => {
describe('Unit: delete(uri)', () => {
it('deletes the source code from the document manager', () => {
// as though the file no longer exists
documentManager.open('mock-fs:/snippet/foo.liquid', 'hello {% render "bar" %}', 10);
documentManager.delete('mock-fs:/snippet/foo.liquid');
const sc = documentManager.get('mock-fs:/snippet/foo.liquid');
documentManager.open('mock-fs:/snippets/foo.liquid', 'hello {% render "bar" %}', 10);
documentManager.delete('mock-fs:/snippets/foo.liquid');
const sc = documentManager.get('mock-fs:/snippets/foo.liquid');
assert(!sc);
});
});
Expand Down Expand Up @@ -137,16 +137,16 @@ describe('Module: DocumentManager', () => {

fs = new MockFileSystem(
{
'snippet/1.liquid': `hello {% render 'bar' %}`,
'snippet/2.liquid': `hello {% render 'bar' %}`,
'snippet/3.liquid': `hello {% render 'bar' %}`,
'snippet/4.liquid': `hello {% render 'bar' %}`,
'snippet/5.liquid': `hello {% render 'bar' %}`,
'snippet/6.liquid': `hello {% render 'bar' %}`,
'snippet/7.liquid': `hello {% render 'bar' %}`,
'snippet/8.liquid': `hello {% render 'bar' %}`,
'snippet/9.liquid': `hello {% render 'bar' %}`,
'snippet/10.liquid': `hello {% render 'bar' %}`,
'snippets/1.liquid': `hello {% render 'bar' %}`,
'snippets/2.liquid': `hello {% render 'bar' %}`,
'snippets/3.liquid': `hello {% render 'bar' %}`,
'snippets/4.liquid': `hello {% render 'bar' %}`,
'snippets/5.liquid': `hello {% render 'bar' %}`,
'snippets/6.liquid': `hello {% render 'bar' %}`,
'snippets/7.liquid': `hello {% render 'bar' %}`,
'snippets/8.liquid': `hello {% render 'bar' %}`,
'snippets/9.liquid': `hello {% render 'bar' %}`,
'snippets/10.liquid': `hello {% render 'bar' %}`,
},
mockRoot,
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import {
assertNever,
memoize,
path,
recursiveReadDirectory,
SourceCodeType,
Theme,
toSourceCode,
Expand All @@ -13,6 +12,7 @@ import {
memo,
Mode,
isError,
recursiveReadDirectory,
} from '@shopify/theme-check-common';
import { Connection } from 'vscode-languageserver';
import { TextDocument } from 'vscode-languageserver-textdocument';
Expand Down Expand Up @@ -131,13 +131,28 @@ export class DocumentManager {

progress.start('Initializing Liquid LSP');

// We'll only load the files that aren't already in the store. No need to
// parse a file we already parsed.
const filesToLoad = await recursiveReadDirectory(
this.fs,
rootUri,
([uri]) => /\.(liquid|json)$/.test(uri) && !this.sourceCodes.has(uri),
);
// NOTE: Only read known theme dirs, a stray 100MB JSON file can consume 1-2GB of heap.
// See https://shopify.dev/docs/storefronts/themes/architecture#directory-structure-and-component-types
const filesToLoad = (
await Promise.all(
[
'assets',
'blocks',
'config',
'layout',
'locales',
'sections',
'snippets',
'templates',
].map((dir) =>
recursiveReadDirectory(
fs,
path.join(rootUri, dir),
([uri]) => /\.(liquid|json)$/.test(uri) && !this.sourceCodes.has(uri),
).catch(() => []),
),
)
).flat();

progress.report(10, 'Preloading files');

Expand Down
Loading