@platformos/platformos-language-server-common 0.0.18 → 0.0.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/dist/codeActions/CodeActionsProvider.d.ts +1 -1
  3. package/dist/completions/providers/PartialCompletionProvider.js +6 -1
  4. package/dist/completions/providers/PartialCompletionProvider.js.map +1 -1
  5. package/dist/definitions/providers/RenderPartialDefinitionProvider.js +1 -0
  6. package/dist/definitions/providers/RenderPartialDefinitionProvider.js.map +1 -1
  7. package/dist/documentLinks/DocumentLinksProvider.js +1 -1
  8. package/dist/documentLinks/DocumentLinksProvider.js.map +1 -1
  9. package/dist/documents/DocumentManager.js +2 -3
  10. package/dist/documents/DocumentManager.js.map +1 -1
  11. package/dist/server/AppGraphManager.d.ts +0 -1
  12. package/dist/server/AppGraphManager.js +3 -14
  13. package/dist/server/AppGraphManager.js.map +1 -1
  14. package/dist/server/DocumentBackedFileSystem.d.ts +25 -0
  15. package/dist/server/DocumentBackedFileSystem.js +39 -0
  16. package/dist/server/DocumentBackedFileSystem.js.map +1 -0
  17. package/dist/server/startServer.js +7 -1
  18. package/dist/server/startServer.js.map +1 -1
  19. package/dist/test/CompletionItemsAssertion.js +3 -2
  20. package/dist/test/CompletionItemsAssertion.js.map +1 -1
  21. package/dist/test/HoverAssertion.js +3 -2
  22. package/dist/test/HoverAssertion.js.map +1 -1
  23. package/dist/tsconfig.tsbuildinfo +1 -1
  24. package/package.json +4 -4
  25. package/src/codeActions/providers/FixAllProvider.spec.ts +2 -2
  26. package/src/codeActions/providers/FixProvider.spec.ts +2 -2
  27. package/src/codeActions/providers/SuggestionProvider.spec.ts +2 -2
  28. package/src/commands/providers/ApplyFixesProvider.spec.ts +2 -2
  29. package/src/commands/providers/ApplySuggestionProvider.spec.ts +2 -2
  30. package/src/commands/providers/RunChecksProvider.spec.ts +2 -2
  31. package/src/completions/params/LiquidCompletionParams.spec.ts +2 -2
  32. package/src/completions/providers/ObjectCompletionProvider.spec.ts +4 -1
  33. package/src/completions/providers/PartialCompletionProvider.ts +6 -3
  34. package/src/definitions/providers/RenderPartialDefinitionProvider.spec.ts +20 -0
  35. package/src/definitions/providers/RenderPartialDefinitionProvider.ts +1 -0
  36. package/src/definitions/providers/TranslationStringDefinitionProvider.spec.ts +2 -2
  37. package/src/diagnostics/runChecks.spec.ts +86 -0
  38. package/src/documentHighlights/providers/HtmlTagNameDocumentHighlightsProvider.spec.ts +5 -5
  39. package/src/documentHighlights/providers/LiquidBlockTagDocumentHighlightsProvider.spec.ts +6 -6
  40. package/src/documentLinks/DocumentLinksProvider.spec.ts +1 -1
  41. package/src/documentLinks/DocumentLinksProvider.ts +1 -1
  42. package/src/documents/DocumentManager.ts +3 -3
  43. package/src/formatting/providers/BracketsAutoclosingOnTypeFormattingProvider.spec.ts +4 -4
  44. package/src/formatting/providers/HtmlElementAutoclosingOnTypeFormattingProvider.spec.ts +1 -1
  45. package/src/hover/providers/LiquidObjectHoverProvider.spec.ts +4 -1
  46. package/src/linkedEditingRanges/providers/EmptyHtmlTagLinkedRangesProvider.spec.ts +4 -4
  47. package/src/linkedEditingRanges/providers/HtmlTagNameLinkedRangesProvider.spec.ts +1 -1
  48. package/src/rename/providers/HtmlTagNameRenameProvider.spec.ts +3 -3
  49. package/src/server/AppGraphManager.ts +3 -17
  50. package/src/server/DocumentBackedFileSystem.spec.ts +54 -0
  51. package/src/server/DocumentBackedFileSystem.ts +40 -0
  52. package/src/server/startServer.ts +7 -1
  53. package/src/test/CompletionItemsAssertion.ts +3 -1
  54. package/src/test/HoverAssertion.ts +3 -1
@@ -2,11 +2,9 @@ import { path, SourceCodeType } from '@platformos/platformos-check-common';
2
2
  import { AbstractFileSystem } from '@platformos/platformos-common';
3
3
  import {
4
4
  buildAppGraph,
5
- getWebComponentMap,
6
5
  IDependencies as GraphDependencies,
7
6
  Location,
8
7
  toSourceCode,
9
- WebComponentMap,
10
8
  } from '@platformos/platformos-graph';
11
9
  import { Range } from 'vscode-json-languageservice';
12
10
  import { Connection } from 'vscode-languageserver';
@@ -162,7 +160,7 @@ export class AppGraphManager {
162
160
  const { documentManager } = this;
163
161
  await documentManager.preload(rootUri);
164
162
 
165
- const dependencies = await this.graphDependencies(rootUri);
163
+ const dependencies = this.graphDependencies();
166
164
  const graph = await buildAppGraph(rootUri, dependencies, entryPoints);
167
165
  return graph;
168
166
  };
@@ -175,20 +173,8 @@ export class AppGraphManager {
175
173
  return toSourceCode(uri, source);
176
174
  };
177
175
 
178
- private getWebComponentMap(rootUri: string): Promise<WebComponentMap> {
176
+ private graphDependencies(): GraphDependencies {
179
177
  const { fs, getSourceCode } = this;
180
- return getWebComponentMap(rootUri, { fs, getSourceCode });
181
- }
182
-
183
- private async graphDependencies(rootUri: string): Promise<GraphDependencies> {
184
- const { fs, getSourceCode } = this;
185
- const webComponentDefs = await this.getWebComponentMap(rootUri);
186
- return {
187
- fs: fs,
188
- getSourceCode: getSourceCode,
189
- getWebComponentDefinitionReference(customElementName: string) {
190
- return webComponentDefs.get(customElementName);
191
- },
192
- };
178
+ return { fs, getSourceCode };
193
179
  }
194
180
  }
@@ -0,0 +1,54 @@
1
+ import { AbstractFileSystem, FileType } from '@platformos/platformos-common';
2
+ import { MockFileSystem } from '@platformos/platformos-check-common/src/test';
3
+ import { beforeEach, describe, expect, it } from 'vitest';
4
+ import { DocumentManager } from '../documents';
5
+ import { DocumentBackedFileSystem } from './DocumentBackedFileSystem';
6
+
7
+ describe('Module: DocumentBackedFileSystem', () => {
8
+ const rootUri = 'mock-fs:';
9
+ const fooUri = 'mock-fs:/app/views/partials/foo.liquid';
10
+ const barUri = 'mock-fs:/app/views/partials/bar.liquid';
11
+ let diskFs: AbstractFileSystem;
12
+ let documentManager: DocumentManager;
13
+ let fs: DocumentBackedFileSystem;
14
+
15
+ beforeEach(() => {
16
+ diskFs = new MockFileSystem(
17
+ {
18
+ 'app/views/partials/foo.liquid': 'saved foo',
19
+ 'app/views/partials/bar.liquid': 'saved bar',
20
+ },
21
+ rootUri,
22
+ );
23
+ documentManager = new DocumentManager(diskFs);
24
+ fs = new DocumentBackedFileSystem(diskFs, documentManager);
25
+ });
26
+
27
+ it('serves the in-editor buffer for a tracked document instead of the disk content', async () => {
28
+ documentManager.open(fooUri, 'edited foo', 1);
29
+
30
+ expect(await fs.readFile(fooUri)).to.equal('edited foo');
31
+ });
32
+
33
+ it('reflects later edits to a tracked document without any cache invalidation', async () => {
34
+ documentManager.open(fooUri, 'edited foo', 1);
35
+ documentManager.change(fooUri, 'edited foo again', 2);
36
+
37
+ expect(await fs.readFile(fooUri)).to.equal('edited foo again');
38
+ });
39
+
40
+ it('falls back to the underlying filesystem for untracked documents', async () => {
41
+ expect(await fs.readFile(barUri)).to.equal('saved bar');
42
+ });
43
+
44
+ it('delegates readDirectory to the underlying filesystem', async () => {
45
+ expect(await fs.readDirectory('mock-fs:/app/views/partials')).to.deep.equal([
46
+ ['mock-fs:/app/views/partials/foo.liquid', FileType.File],
47
+ ['mock-fs:/app/views/partials/bar.liquid', FileType.File],
48
+ ]);
49
+ });
50
+
51
+ it('delegates stat to the underlying filesystem', async () => {
52
+ expect(await fs.stat(fooUri)).to.deep.equal({ type: FileType.File, size: 'saved foo'.length });
53
+ });
54
+ });
@@ -0,0 +1,40 @@
1
+ import { AbstractFileSystem, FileStat, FileTuple } from '@platformos/platformos-common';
2
+ import { DocumentManager } from '../documents';
3
+
4
+ /**
5
+ * A filesystem layer that serves the content of tracked documents from the
6
+ * DocumentManager and delegates everything else to the underlying filesystem.
7
+ *
8
+ * Checks read the files they reference (e.g. the partial targeted by a
9
+ * `render`/`function` call) through `context.fs.readFile`. Without this layer
10
+ * those reads hit the disk-backed CachedFileSystem, which returns the last saved
11
+ * — and cached — version of the file. As a result, an edit to a partial did not
12
+ * update cross-file diagnostics on the *calling* file until the partial was saved
13
+ * and its cache entry invalidated.
14
+ *
15
+ * The DocumentManager always holds the latest in-editor buffer for open documents
16
+ * (and the latest disk content for preloaded ones), so preferring it keeps
17
+ * cross-file checks in sync with what the user is actually editing.
18
+ */
19
+ export class DocumentBackedFileSystem implements AbstractFileSystem {
20
+ constructor(
21
+ private readonly fs: AbstractFileSystem,
22
+ private readonly documentManager: DocumentManager,
23
+ ) {}
24
+
25
+ async readFile(uri: string): Promise<string> {
26
+ const document = this.documentManager.get(uri);
27
+ if (document) {
28
+ return document.source;
29
+ }
30
+ return this.fs.readFile(uri);
31
+ }
32
+
33
+ readDirectory(uri: string): Promise<FileTuple[]> {
34
+ return this.fs.readDirectory(uri);
35
+ }
36
+
37
+ stat(uri: string): Promise<FileStat> {
38
+ return this.fs.stat(uri);
39
+ }
40
+ }
@@ -47,6 +47,7 @@ import { debounce } from '../utils';
47
47
  import { SearchPathsLoader } from '../utils/searchPaths';
48
48
  import { VERSION } from '../version';
49
49
  import { CachedFileSystem } from './CachedFileSystem';
50
+ import { DocumentBackedFileSystem } from './DocumentBackedFileSystem';
50
51
  import { Configuration, INCLUDE_FILES_FROM_DISK } from './Configuration';
51
52
  import { safe } from './safe';
52
53
  import { AppGraphManager } from './AppGraphManager';
@@ -163,9 +164,14 @@ export function startServer(
163
164
 
164
165
  // These are augmented here so that the caching is maintained over different runs.
165
166
  const platformosDocset = new AugmentedPlatformOSDocset(remotePlatformOSDocset);
167
+ // Checks read the files they reference (e.g. the partial targeted by a
168
+ // render/function call) through `context.fs`. Serve those reads from the
169
+ // DocumentManager so cross-file diagnostics reflect the latest in-editor buffer
170
+ // rather than a stale, disk-cached copy.
171
+ const checksFs = new DocumentBackedFileSystem(fs, documentManager);
166
172
  const runChecks = debounce(
167
173
  makeRunChecks(documentManager, diagnosticsManager, {
168
- fs,
174
+ fs: checksFs,
169
175
  loadConfig,
170
176
  platformosDocset,
171
177
  jsonValidationSet,
@@ -70,7 +70,9 @@ export const complete: RawMatcherFn<MatcherState> = async function (
70
70
  };
71
71
 
72
72
  function asCompleteContextObject(context: string | CompleteContext): CompleteContext {
73
- if (typeof context === 'string') return { source: context, relativePath: 'file.liquid' };
73
+ if (typeof context === 'string') {
74
+ return { source: context, relativePath: 'app/views/layouts/file.liquid' };
75
+ }
74
76
  return context;
75
77
  }
76
78
 
@@ -79,6 +79,8 @@ export const hover: RawMatcherFn<MatcherState> = async function (
79
79
  };
80
80
 
81
81
  function asHoverContext(context: string | HoverContext): HoverContext {
82
- if (typeof context === 'string') return { source: context, relativePath: 'app/file.liquid' };
82
+ if (typeof context === 'string') {
83
+ return { source: context, relativePath: 'app/views/layouts/file.liquid' };
84
+ }
83
85
  return context;
84
86
  }