Skip to content
Open
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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test failures look real:

-             "uri": "mock-fs:/templates/index.json",
+             "uri": "mock-fs:sections/header.json",

I'm not sure what's going on there.

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