@platformos/platformos-language-server-common 0.0.8 → 0.0.9

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 +10 -0
  2. package/dist/PropertyShapeInference.js +4 -0
  3. package/dist/PropertyShapeInference.js.map +1 -1
  4. package/dist/TypeSystem.js +19 -9
  5. package/dist/TypeSystem.js.map +1 -1
  6. package/dist/completions/params/LiquidCompletionParams.js +2 -1
  7. package/dist/completions/params/LiquidCompletionParams.js.map +1 -1
  8. package/dist/documents/DocumentManager.js +5 -1
  9. package/dist/documents/DocumentManager.js.map +1 -1
  10. package/dist/tsconfig.tsbuildinfo +1 -1
  11. package/dist/utils/uri.d.ts +2 -1
  12. package/dist/utils/uri.js +5 -5
  13. package/dist/utils/uri.js.map +1 -1
  14. package/package.json +4 -4
  15. package/src/ClientCapabilities.ts +1 -1
  16. package/src/PropertyShapeInference.ts +6 -1
  17. package/src/TypeSystem.spec.ts +19 -0
  18. package/src/TypeSystem.ts +23 -10
  19. package/src/codeActions/providers/FixAllProvider.spec.ts +1 -1
  20. package/src/codeActions/providers/FixProvider.spec.ts +11 -11
  21. package/src/codeActions/providers/SuggestionProvider.spec.ts +2 -2
  22. package/src/commands/providers/ApplyFixesProvider.ts +2 -2
  23. package/src/commands/providers/ApplySuggestionProvider.ts +2 -2
  24. package/src/commands/providers/RunChecksProvider.ts +2 -2
  25. package/src/completions/CompletionsProvider.ts +1 -1
  26. package/src/completions/params/LiquidCompletionParams.ts +4 -3
  27. package/src/completions/providers/LiquidTagsCompletionProvider.spec.ts +2 -2
  28. package/src/completions/providers/PartialCompletionProvider.spec.ts +2 -2
  29. package/src/completions/providers/RenderPartialParameterCompletionProvider.spec.ts +11 -11
  30. package/src/completions/providers/RenderPartialParameterCompletionProvider.ts +2 -2
  31. package/src/completions/providers/TranslationCompletionProvider.ts +3 -3
  32. package/src/diagnostics/runChecks.spec.ts +6 -6
  33. package/src/documentLinks/DocumentLinksProvider.ts +7 -7
  34. package/src/documents/DocumentManager.spec.ts +34 -22
  35. package/src/documents/DocumentManager.ts +6 -1
  36. package/src/hover/providers/LiquidDocTagHoverProvider.spec.ts +1 -1
  37. package/src/hover/providers/RenderPartialHoverProvider.spec.ts +10 -10
  38. package/src/hover/providers/RenderPartialParameterHoverProvider.spec.ts +9 -9
  39. package/src/hover/providers/RenderPartialParameterHoverProvider.ts +2 -2
  40. package/src/index.ts +2 -2
  41. package/src/rename/RenameProvider.ts +1 -1
  42. package/src/rename/providers/LiquidVariableRenameProvider.spec.ts +1 -1
  43. package/src/rename/providers/LiquidVariableRenameProvider.ts +3 -3
  44. package/src/renamed/handlers/AssetRenameHandler.spec.ts +25 -25
  45. package/src/renamed/handlers/AssetRenameHandler.ts +1 -1
  46. package/src/renamed/handlers/PartialRenameHandler.spec.ts +7 -7
  47. package/src/renamed/handlers/PartialRenameHandler.ts +5 -5
  48. package/src/server/safe.ts +1 -1
  49. package/src/server/startServer.spec.ts +3 -3
  50. package/src/server/startServer.ts +4 -5
  51. package/src/utils/debounce.ts +1 -1
  52. package/src/utils/liquidDoc.ts +5 -5
  53. package/src/utils/uri.ts +5 -3
  54. package/src/renamed/handlers/utils.ts +0 -22
@@ -1,4 +1,5 @@
1
+ import { isPartial } from '@platformos/platformos-common';
2
+ export { isPartial };
1
3
  export declare const partialName: (uri: string) => string;
2
- export declare const isPartial: (uri: string) => boolean;
3
4
  export declare const assetName: (uri: string) => string;
4
5
  export declare const isAsset: (uri: string) => boolean;
package/dist/utils/uri.js CHANGED
@@ -1,14 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isAsset = exports.assetName = exports.isPartial = exports.partialName = void 0;
3
+ exports.isAsset = exports.assetName = exports.partialName = exports.isPartial = void 0;
4
4
  const platformos_check_common_1 = require("@platformos/platformos-check-common");
5
+ const platformos_common_1 = require("@platformos/platformos-common");
6
+ Object.defineProperty(exports, "isPartial", { enumerable: true, get: function () { return platformos_common_1.isPartial; } });
5
7
  const partialName = (uri) => platformos_check_common_1.path.basename(uri, '.liquid');
6
8
  exports.partialName = partialName;
7
- const isPartial = (uri) => /\b(partials|lib)(\\|\/)[^\\\/]*\.liquid/.test(uri);
8
- exports.isPartial = isPartial;
9
- // asset urls have their `.liquid`` removed (if present) and require the other extension */
9
+ // asset urls have their `.liquid` removed (if present) and require the other extension
10
10
  const assetName = (uri) => platformos_check_common_1.path.basename(uri, '.liquid');
11
11
  exports.assetName = assetName;
12
- const isAsset = (uri) => /\bassets(\\|\/)[^\\\/]/.test(uri);
12
+ const isAsset = (uri) => (0, platformos_common_1.getFileType)(uri) === platformos_common_1.PlatformOSFileType.Asset;
13
13
  exports.isAsset = isAsset;
14
14
  //# sourceMappingURL=uri.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"uri.js","sourceRoot":"","sources":["../../src/utils/uri.ts"],"names":[],"mappings":";;;AAAA,iFAA2D;AAEpD,MAAM,WAAW,GAAG,CAAC,GAAW,EAAE,EAAE,CAAC,8BAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;AAA7D,QAAA,WAAW,eAAkD;AACnE,MAAM,SAAS,GAAG,CAAC,GAAW,EAAE,EAAE,CAAC,yCAAyC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAAjF,QAAA,SAAS,aAAwE;AAE9F,2FAA2F;AACpF,MAAM,SAAS,GAAG,CAAC,GAAW,EAAE,EAAE,CAAC,8BAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;AAA3D,QAAA,SAAS,aAAkD;AACjE,MAAM,OAAO,GAAG,CAAC,GAAW,EAAE,EAAE,CAAC,wBAAwB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAA9D,QAAA,OAAO,WAAuD"}
1
+ {"version":3,"file":"uri.js","sourceRoot":"","sources":["../../src/utils/uri.ts"],"names":[],"mappings":";;;AAAA,iFAA2D;AAC3D,qEAA2F;AAElF,0FAFA,6BAAS,OAEA;AAEX,MAAM,WAAW,GAAG,CAAC,GAAW,EAAE,EAAE,CAAC,8BAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;AAA7D,QAAA,WAAW,eAAkD;AAE1E,uFAAuF;AAChF,MAAM,SAAS,GAAG,CAAC,GAAW,EAAE,EAAE,CAAC,8BAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;AAA3D,QAAA,SAAS,aAAkD;AACjE,MAAM,OAAO,GAAG,CAAC,GAAW,EAAE,EAAE,CAAC,IAAA,+BAAW,EAAC,GAAG,CAAC,KAAK,sCAAkB,CAAC,KAAK,CAAC;AAAzE,QAAA,OAAO,WAAkE"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@platformos/platformos-language-server-common",
3
- "version": "0.0.8",
3
+ "version": "0.0.9",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "author": "platformOS",
@@ -27,9 +27,9 @@
27
27
  "type-check": "tsc --noEmit -p ./tsconfig.json"
28
28
  },
29
29
  "dependencies": {
30
- "@platformos/liquid-html-parser": "^0.0.8",
31
- "@platformos/platformos-check-common": "0.0.8",
32
- "@platformos/platformos-graph": "0.0.8",
30
+ "@platformos/liquid-html-parser": "^0.0.9",
31
+ "@platformos/platformos-check-common": "0.0.9",
32
+ "@platformos/platformos-graph": "0.0.9",
33
33
  "@vscode/web-custom-data": "^0.4.6",
34
34
  "vscode-json-languageservice": "^5.7.1",
35
35
  "vscode-languageserver": "^9.0.1",
@@ -48,7 +48,7 @@ export class ClientCapabilities {
48
48
  const direct = this.initializationOptions?.[key];
49
49
  if (direct !== undefined) return direct;
50
50
 
51
- // { themeCheck: { checkOnSave: true } }
51
+ // { platformosCheck: { checkOnSave: true } }
52
52
  const nested = pathGet<T>(this.initializationOptions, key);
53
53
  if (nested !== undefined) return nested;
54
54
 
@@ -14,6 +14,7 @@ import {
14
14
  JsonHashLiteral,
15
15
  JsonArrayLiteral,
16
16
  LiquidExpression,
17
+ LiquidVariable,
17
18
  NodeTypes,
18
19
  } from '@platformos/liquid-html-parser';
19
20
 
@@ -164,9 +165,13 @@ function getJsonKeyName(key: LiquidExpression): string | undefined {
164
165
  }
165
166
 
166
167
  function inferShapeFromExpression(
167
- expr: LiquidExpression,
168
+ expr: LiquidExpression | LiquidVariable,
168
169
  resolveExpression?: ExpressionShapeResolver,
169
170
  ): PropertyShape {
171
+ if (expr.type === NodeTypes.LiquidVariable) {
172
+ // A filtered expression's output type can't be statically inferred
173
+ return { kind: 'primitive' };
174
+ }
170
175
  switch (expr.type) {
171
176
  case NodeTypes.JsonHashLiteral:
172
177
  case NodeTypes.JsonArrayLiteral:
@@ -881,5 +881,24 @@ query {
881
881
  });
882
882
  }
883
883
  });
884
+
885
+ it('should support explicit push form (assign a = source << value)', async () => {
886
+ const ast = toLiquidHtmlAST(`{% assign arr = [] %}{% assign arr = arr << "item" %}{{ arr }}`);
887
+ const variableOutput = ast.children[2];
888
+ assert(isLiquidVariableOutput(variableOutput));
889
+ const inferredType = await typeSystem.inferType(
890
+ variableOutput.markup,
891
+ ast,
892
+ 'file:///file.liquid',
893
+ );
894
+ expect(inferredType).to.have.property('kind', 'shape');
895
+ if (typeof inferredType !== 'string' && inferredType.kind === 'shape') {
896
+ expect(inferredType.shape.kind).to.equal('array');
897
+ expect(inferredType.shape.itemShape).to.deep.equal({
898
+ kind: 'primitive',
899
+ primitiveType: 'string',
900
+ });
901
+ }
902
+ });
884
903
  });
885
904
  });
package/src/TypeSystem.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import {
2
2
  AssignMarkup,
3
+ AssignPushRhs,
3
4
  ComplexLiquidExpression,
4
5
  FunctionMarkup,
5
6
  LiquidDocParamNode,
@@ -240,7 +241,7 @@ type FilterEntryName = FilterEntry['name'];
240
241
  export const Untyped = 'untyped' as const;
241
242
  export type Untyped = typeof Untyped;
242
243
 
243
- /** Unknown is for variables that don't exist, type would come from context (e.g. snippet var without LiquidDoc) */
244
+ /** Unknown is for variables that don't exist, type would come from context (e.g. partial var without LiquidDoc) */
244
245
  export const Unknown = 'unknown' as const;
245
246
  export type Unknown = typeof Untyped;
246
247
 
@@ -383,8 +384,15 @@ async function buildSymbolsTable(
383
384
  // {% assign x = {a: 1, b: "hello"} %}
384
385
  // {% assign x["key"] = value %}
385
386
  // {% assign arr << item %}
387
+ // {% assign arr = source << item %}
386
388
  async AssignMarkup(node) {
387
- const expression = node.value.expression;
389
+ // For explicit push form (assign a = source << value), treat as array append
390
+ const isPushRhs = node.value.type === NodeTypes.AssignPushRhs;
391
+ const effectiveValue = isPushRhs
392
+ ? (node.value as AssignPushRhs).pushValue
393
+ : (node.value as LiquidVariable);
394
+ const effectiveOperator = isPushRhs ? '<<' : node.operator;
395
+ const expression = effectiveValue.expression;
388
396
  let valueShape: PropertyShape | undefined;
389
397
 
390
398
  // Resolver for variable references inside JSON literals
@@ -451,7 +459,7 @@ async function buildSymbolsTable(
451
459
 
452
460
  // Case 2: parse_json / to_hash filter on a string
453
461
  if (!valueShape) {
454
- const hasParseJsonFilter = node.value.filters?.some(
462
+ const hasParseJsonFilter = effectiveValue.filters?.some(
455
463
  (f: { name: string }) => f.name === 'parse_json' || f.name === 'to_hash',
456
464
  );
457
465
  if (hasParseJsonFilter) {
@@ -459,8 +467,8 @@ async function buildSymbolsTable(
459
467
  if (expression.type === NodeTypes.String) {
460
468
  jsonString = expression.value;
461
469
  }
462
- if (!jsonString && node.value.filters) {
463
- const defaultFilter = node.value.filters.find(
470
+ if (!jsonString && effectiveValue.filters) {
471
+ const defaultFilter = effectiveValue.filters.find(
464
472
  (f: { name: string }) => f.name === 'default',
465
473
  );
466
474
  if (
@@ -479,7 +487,10 @@ async function buildSymbolsTable(
479
487
  }
480
488
 
481
489
  // Case 3: Infer primitive shape for << and LHS lookup scenarios
482
- if (!valueShape && ((node.lookups && node.lookups.length > 0) || node.operator === '<<')) {
490
+ if (
491
+ !valueShape &&
492
+ ((node.lookups && node.lookups.length > 0) || effectiveOperator === '<<')
493
+ ) {
483
494
  if (expression.type === NodeTypes.String) {
484
495
  valueShape = { kind: 'primitive', primitiveType: 'string' };
485
496
  } else if (expression.type === NodeTypes.Number) {
@@ -537,8 +548,8 @@ async function buildSymbolsTable(
537
548
  }
538
549
  }
539
550
 
540
- // Handle << operator (array append)
541
- if (node.operator === '<<') {
551
+ // Handle << operator (array append), including explicit form (assign a = source << value)
552
+ if (effectiveOperator === '<<') {
542
553
  const itemShape: PropertyShape = valueShape ?? { kind: 'primitive' };
543
554
  const existingShapes = variableShapes.get(node.name) || [];
544
555
  const existingShapeEntry = findLastApplicableShape(existingShapes, node.position.start);
@@ -578,7 +589,7 @@ async function buildSymbolsTable(
578
589
  // Default: lazy variable type
579
590
  return {
580
591
  identifier: node.name,
581
- type: lazyVariable(node.value, node.position.start),
592
+ type: lazyVariable(effectiveValue, node.position.start),
582
593
  range: [node.position.end],
583
594
  };
584
595
  },
@@ -986,7 +997,9 @@ function inferType(
986
997
  // The type of the assign markup is the type of the right hand side.
987
998
  // {% assign x = y.property | filter1 | filter2 %}
988
999
  case NodeTypes.AssignMarkup: {
989
- return inferType(thing.value, symbolsTable, objectMap, filtersMap);
1000
+ const assignValue =
1001
+ thing.value.type === NodeTypes.AssignPushRhs ? thing.value.pushValue : thing.value;
1002
+ return inferType(assignValue, symbolsTable, objectMap, filtersMap);
990
1003
  }
991
1004
 
992
1005
  // A variable lookup is expression[.lookup]*
@@ -73,7 +73,7 @@ describe('Unit: FixAllProvider', () => {
73
73
  isPreferred: false,
74
74
  command: {
75
75
  title: 'applyFixes',
76
- command: 'themeCheck/applyFixes',
76
+ command: 'platformosCheck/applyFixes',
77
77
  arguments: [uri, version, [0, 1, 2]],
78
78
  },
79
79
  });
@@ -75,7 +75,7 @@ describe('Unit: FixProvider', () => {
75
75
  isPreferred: true,
76
76
  command: {
77
77
  title: 'applyFixes',
78
- command: 'themeCheck/applyFixes',
78
+ command: 'platformosCheck/applyFixes',
79
79
  arguments: [uri, 1, [1]],
80
80
  },
81
81
  });
@@ -87,7 +87,7 @@ describe('Unit: FixProvider', () => {
87
87
  isPreferred: false,
88
88
  command: {
89
89
  title: 'applyFixes',
90
- command: 'themeCheck/applyFixes',
90
+ command: 'platformosCheck/applyFixes',
91
91
  arguments: [uri, 1, [1, 2]],
92
92
  },
93
93
  });
@@ -99,7 +99,7 @@ describe('Unit: FixProvider', () => {
99
99
  isPreferred: false,
100
100
  command: {
101
101
  title: 'applyFixes',
102
- command: 'themeCheck/applyFixes',
102
+ command: 'platformosCheck/applyFixes',
103
103
  arguments: [uri, 1, [0, 1, 2]],
104
104
  },
105
105
  });
@@ -135,7 +135,7 @@ describe('Unit: FixProvider', () => {
135
135
  isPreferred: true,
136
136
  command: {
137
137
  title: 'applyFixes',
138
- command: 'themeCheck/applyFixes',
138
+ command: 'platformosCheck/applyFixes',
139
139
  arguments: [uri, 1, [1]],
140
140
  },
141
141
  });
@@ -147,7 +147,7 @@ describe('Unit: FixProvider', () => {
147
147
  isPreferred: false,
148
148
  command: {
149
149
  title: 'applyFixes',
150
- command: 'themeCheck/applyFixes',
150
+ command: 'platformosCheck/applyFixes',
151
151
  arguments: [uri, 1, [0, 1]],
152
152
  },
153
153
  });
@@ -183,7 +183,7 @@ describe('Unit: FixProvider', () => {
183
183
  isPreferred: true,
184
184
  command: {
185
185
  title: 'applyFixes',
186
- command: 'themeCheck/applyFixes',
186
+ command: 'platformosCheck/applyFixes',
187
187
  arguments: [uri, 1, [0]],
188
188
  },
189
189
  });
@@ -195,7 +195,7 @@ describe('Unit: FixProvider', () => {
195
195
  isPreferred: false,
196
196
  command: {
197
197
  title: 'applyFixes',
198
- command: 'themeCheck/applyFixes',
198
+ command: 'platformosCheck/applyFixes',
199
199
  arguments: [uri, 1, [0, 1]],
200
200
  },
201
201
  });
@@ -230,7 +230,7 @@ describe('Unit: FixProvider', () => {
230
230
  isPreferred: true,
231
231
  command: {
232
232
  title: 'applyFixes',
233
- command: 'themeCheck/applyFixes',
233
+ command: 'platformosCheck/applyFixes',
234
234
  arguments: [uri, 1, [0]],
235
235
  },
236
236
  });
@@ -264,7 +264,7 @@ describe('Unit: FixProvider', () => {
264
264
  isPreferred: true,
265
265
  command: {
266
266
  title: 'applyFixes',
267
- command: 'themeCheck/applyFixes',
267
+ command: 'platformosCheck/applyFixes',
268
268
  arguments: [uri, 1, [1]],
269
269
  },
270
270
  });
@@ -276,7 +276,7 @@ describe('Unit: FixProvider', () => {
276
276
  isPreferred: false,
277
277
  command: {
278
278
  title: 'applyFixes',
279
- command: 'themeCheck/applyFixes',
279
+ command: 'platformosCheck/applyFixes',
280
280
  arguments: [uri, 1, [1, 2]],
281
281
  },
282
282
  });
@@ -288,7 +288,7 @@ describe('Unit: FixProvider', () => {
288
288
  isPreferred: false,
289
289
  command: {
290
290
  title: 'applyFixes',
291
- command: 'themeCheck/applyFixes',
291
+ command: 'platformosCheck/applyFixes',
292
292
  arguments: [uri, 1, [0, 1, 2]],
293
293
  },
294
294
  });
@@ -88,7 +88,7 @@ describe('Unit: SuggestionProvider', () => {
88
88
  isPreferred: false,
89
89
  command: {
90
90
  title: 'applySuggestion',
91
- command: 'themeCheck/applySuggestion',
91
+ command: 'platformosCheck/applySuggestion',
92
92
  arguments: [uri, version, anomalyId, 0],
93
93
  },
94
94
  });
@@ -100,7 +100,7 @@ describe('Unit: SuggestionProvider', () => {
100
100
  isPreferred: false,
101
101
  command: {
102
102
  title: 'applySuggestion',
103
- command: 'themeCheck/applySuggestion',
103
+ command: 'platformosCheck/applySuggestion',
104
104
  arguments: [uri, version, anomalyId, 1],
105
105
  },
106
106
  });
@@ -14,7 +14,7 @@ import { TextDocument } from 'vscode-languageserver-textdocument';
14
14
  import { BaseExecuteCommandProvider } from '../BaseExecuteCommandProvider';
15
15
 
16
16
  /**
17
- * The ApplyFixesProvider is responsible for handling the `themeCheck/applyFixes` command.
17
+ * The ApplyFixesProvider is responsible for handling the `platformosCheck/applyFixes` command.
18
18
  *
19
19
  * To create a command, use the `applyFixCommand` function.
20
20
  * The provider will execute the command with the given arguments.
@@ -23,7 +23,7 @@ import { BaseExecuteCommandProvider } from '../BaseExecuteCommandProvider';
23
23
  * applies them, and forwards the result to the client using the 'workspace/applyEdit' request.
24
24
  */
25
25
  export class ApplyFixesProvider extends BaseExecuteCommandProvider {
26
- static command = 'themeCheck/applyFixes' as const;
26
+ static command = 'platformosCheck/applyFixes' as const;
27
27
 
28
28
  async execute(uri: string, version: number | undefined, ids: number[]) {
29
29
  if (!this.clientCapabilities.hasApplyEditSupport) return;
@@ -14,7 +14,7 @@ import { TextDocument } from 'vscode-languageserver-textdocument';
14
14
  import { BaseExecuteCommandProvider } from '../BaseExecuteCommandProvider';
15
15
 
16
16
  /**
17
- * The ApplySuggestionProvider is responsible for handling the `themeCheck/applySuggestion` command.
17
+ * The ApplySuggestionProvider is responsible for handling the `platformosCheck/applySuggestion` command.
18
18
  *
19
19
  * To create a command, use the `applySuggestionCommand` function.
20
20
  * The provider will execute the command with the given arguments.
@@ -23,7 +23,7 @@ import { BaseExecuteCommandProvider } from '../BaseExecuteCommandProvider';
23
23
  * applies them, and forwards the result to the client using the 'workspace/applyEdit' request.
24
24
  */
25
25
  export class ApplySuggestionProvider extends BaseExecuteCommandProvider {
26
- static command = 'themeCheck/applySuggestion' as const;
26
+ static command = 'platformosCheck/applySuggestion' as const;
27
27
 
28
28
  async execute(
29
29
  uri: string,
@@ -6,7 +6,7 @@ import { DebouncedFunction } from '../../utils';
6
6
  import { BaseExecuteCommandProvider } from '../BaseExecuteCommandProvider';
7
7
 
8
8
  /**
9
- * The RunChecksProvider runs theme check on all open files.
9
+ * The RunChecksProvider runs platformos-check on all open files.
10
10
  *
11
11
  * It is triggered by the cmd+p command in the VS Code extension and is
12
12
  * otherwise not used internally, which is why there is no
@@ -16,7 +16,7 @@ import { BaseExecuteCommandProvider } from '../BaseExecuteCommandProvider';
16
16
  * `checkOnOpen` are all false.
17
17
  */
18
18
  export class RunChecksProvider extends BaseExecuteCommandProvider {
19
- static command = 'themeCheck/runChecks' as const;
19
+ static command = 'platformosCheck/runChecks' as const;
20
20
 
21
21
  constructor(
22
22
  protected documentManager: DocumentManager,
@@ -38,7 +38,7 @@ export interface CompletionProviderDependencies {
38
38
  fs?: AbstractFileSystem;
39
39
  /** Locator for finding documents by type */
40
40
  documentsLocator?: DocumentsLocator;
41
- /** Function to find the theme root URI for a given file */
41
+ /** Function to find the app root URI for a given file */
42
42
  findAppRootURI?: FindAppRootURI;
43
43
  log?: (message: string) => void;
44
44
  /** Callback to notify when unable to infer properties for a variable */
@@ -373,8 +373,8 @@ function findCurrentNode(
373
373
  finder.current = last(current.args);
374
374
  } else if (current.variable && isCovered(cursor, current.variable.position)) {
375
375
  finder.current = current.variable;
376
- } else if (current.snippet && isCovered(cursor, current.snippet.position)) {
377
- finder.current = current.snippet;
376
+ } else if (current.partial && isCovered(cursor, current.partial.position)) {
377
+ finder.current = current.partial;
378
378
  }
379
379
 
380
380
  break;
@@ -442,7 +442,8 @@ function findCurrentNode(
442
442
  case NodeTypes.ExportMarkup:
443
443
  case NodeTypes.RedirectToMarkup:
444
444
  case NodeTypes.IncludeFormMarkup:
445
- case NodeTypes.SpamProtectionMarkup: {
445
+ case NodeTypes.SpamProtectionMarkup:
446
+ case NodeTypes.AssignPushRhs: {
446
447
  break;
447
448
  }
448
449
 
@@ -38,8 +38,8 @@ endcase`;
38
38
  export const tags: TagEntry[] = [
39
39
  {
40
40
  name: 'render',
41
- syntax: "{% render 'snippet' %}",
42
- syntax_keywords: [{ keyword: 'snippet', description: '...' }],
41
+ syntax: "{% render 'partial' %}",
42
+ syntax_keywords: [{ keyword: 'partial', description: '...' }],
43
43
  },
44
44
  {
45
45
  name: 'for',
@@ -2,7 +2,7 @@ import { describe, beforeEach, it, expect } from 'vitest';
2
2
  import { DocumentManager } from '../../documents';
3
3
  import { CompletionsProvider } from '../CompletionsProvider';
4
4
 
5
- describe('Module: RenderSnippetCompletionProvider', async () => {
5
+ describe('Module: RenderPartialCompletionProvider', async () => {
6
6
  let provider: CompletionsProvider;
7
7
 
8
8
  beforeEach(async () => {
@@ -20,7 +20,7 @@ describe('Module: RenderSnippetCompletionProvider', async () => {
20
20
  });
21
21
  });
22
22
 
23
- it('should complete snippets correctly', async () => {
23
+ it('should complete partials correctly', async () => {
24
24
  await expect(provider).to.complete('{% render "', ['product-card', 'image']);
25
25
  });
26
26
  });
@@ -3,12 +3,12 @@ import { CompletionsProvider } from '../CompletionsProvider';
3
3
  import { DocumentManager } from '../../documents';
4
4
  import { DocDefinition } from '@platformos/platformos-check-common';
5
5
 
6
- const uri = 'file:///snippets/product-card.liquid';
6
+ const uri = 'file:///app/views/partials/product-card.liquid';
7
7
 
8
- describe('Module: RenderSnippetParameterCompletionProvider', async () => {
8
+ describe('Module: RenderPartialParameterCompletionProvider', async () => {
9
9
  let provider: CompletionsProvider;
10
- const mockSnippetName = 'product-card';
11
- const mockSnippetDefinition: DocDefinition = {
10
+ const mockPartialName = 'product-card';
11
+ const mockPartialDefinition: DocDefinition = {
12
12
  uri,
13
13
  liquidDoc: {
14
14
  parameters: [
@@ -61,16 +61,16 @@ describe('Module: RenderSnippetParameterCompletionProvider', async () => {
61
61
  liquidDrops: async () => [],
62
62
  tags: async () => [],
63
63
  },
64
- getDocDefinitionForURI: async (_uri, snippetName) => {
65
- if (mockSnippetName === snippetName) {
66
- return mockSnippetDefinition;
64
+ getDocDefinitionForURI: async (_uri, partialName) => {
65
+ if (mockPartialName === partialName) {
66
+ return mockPartialDefinition;
67
67
  }
68
68
  },
69
69
  });
70
70
  });
71
71
 
72
72
  it("provide completion options that doesn't already exist in render tag", async () => {
73
- await expect(provider).to.complete(`{% render '${mockSnippetName}', █ %}`, [
73
+ await expect(provider).to.complete(`{% render '${mockPartialName}', █ %}`, [
74
74
  'title',
75
75
  'border-radius',
76
76
  'no-type',
@@ -78,12 +78,12 @@ describe('Module: RenderSnippetParameterCompletionProvider', async () => {
78
78
  'no-type-or-description',
79
79
  ]);
80
80
  await expect(provider).to.complete(
81
- `{% render '${mockSnippetName}', title: 'foo', border-radius: 5, █ %}`,
81
+ `{% render '${mockPartialName}', title: 'foo', border-radius: 5, █ %}`,
82
82
  ['no-type', 'no-description', 'no-type-or-description'],
83
83
  );
84
84
  });
85
85
 
86
- it('does not provide completion options if the snippet does not exist', async () => {
87
- await expect(provider).to.complete(`{% render 'fake-snippet', █ %}`, []);
86
+ it('does not provide completion options if the partial does not exist', async () => {
87
+ await expect(provider).to.complete(`{% render 'fake-partial', █ %}`, []);
88
88
  });
89
89
  });
@@ -28,7 +28,7 @@ export class RenderPartialParameterCompletionProvider implements Provider {
28
28
  !parentNode ||
29
29
  node.type !== NodeTypes.VariableLookup ||
30
30
  parentNode.type !== NodeTypes.RenderMarkup ||
31
- parentNode.snippet.type !== 'String'
31
+ parentNode.partial.type !== 'String'
32
32
  ) {
33
33
  return [];
34
34
  }
@@ -37,7 +37,7 @@ export class RenderPartialParameterCompletionProvider implements Provider {
37
37
 
38
38
  const partialDefinition = await this.getDocDefinitionForURI(
39
39
  params.textDocument.uri,
40
- parentNode.snippet.value,
40
+ parentNode.partial.value,
41
41
  );
42
42
 
43
43
  const liquidDocParams = partialDefinition?.liquidDoc?.parameters;
@@ -41,10 +41,10 @@ export class TranslationCompletionProvider implements Provider {
41
41
  const translations = await this.getTranslationsForURI(params.textDocument.uri);
42
42
  const partial = node.value;
43
43
 
44
- // We only want to show standard translations to complete if the translation
45
- // is prefixed by shopify. Otherwise it's too noisy.
44
+ // We only want to show platformos system translations if the user is already
45
+ // typing that namespace prefix. Otherwise it's too noisy.
46
46
  const options = translationOptions(translations).filter(
47
- (option) => !option.path[0]?.startsWith('shopify') || partial.startsWith('shopify'),
47
+ (option) => !option.path[0]?.startsWith('platformos') || partial.startsWith('platformos'),
48
48
  );
49
49
 
50
50
  const [_currentNode, realAncestors] =
@@ -46,7 +46,7 @@ describe('Module: runChecks', () => {
46
46
  let runChecks: ReturnType<typeof makeRunChecks>;
47
47
  let fs: MockFileSystem;
48
48
  const rootUri = path.normalize('browser:///app');
49
- const fileUri = path.join(rootUri, 'app', 'input.liquid');
49
+ const fileUri = path.join(rootUri, 'app', 'views', 'pages', 'input.liquid');
50
50
 
51
51
  beforeEach(() => {
52
52
  connection = {
@@ -58,7 +58,7 @@ describe('Module: runChecks', () => {
58
58
  fs = new MockFileSystem(
59
59
  {
60
60
  '.pos': '',
61
- 'app/input.liquid': `{{ 'any' | filter }}`,
61
+ 'app/views/pages/input.liquid': `{{ 'any' | filter }}`,
62
62
  '.git/test': 'test',
63
63
  'modules/test': 'test',
64
64
  },
@@ -140,7 +140,7 @@ describe('Module: runChecks', () => {
140
140
  it('should send diagnostics per URI when there are errors', async () => {
141
141
  const files = [
142
142
  {
143
- fileURI: path.join(rootUri, 'app', 'input1.liquid'),
143
+ fileURI: path.join(rootUri, 'app', 'views', 'pages', 'input1.liquid'),
144
144
  fileContents: `{{ 'any' | filter }}`,
145
145
  fileVersion: 0,
146
146
  diagnostics: [
@@ -163,7 +163,7 @@ describe('Module: runChecks', () => {
163
163
  ],
164
164
  },
165
165
  {
166
- fileURI: path.join(rootUri, 'app', 'input2.liquid'),
166
+ fileURI: path.join(rootUri, 'app', 'views', 'pages', 'input2.liquid'),
167
167
  // same but on a new line
168
168
  fileContents: `\n{{ 'any' | filter }}`,
169
169
  fileVersion: 0,
@@ -192,7 +192,7 @@ describe('Module: runChecks', () => {
192
192
  documentManager.open(fileURI, fileContents, fileVersion);
193
193
  });
194
194
 
195
- await runChecks([path.join(rootUri, 'app', 'input1.liquid')]);
195
+ await runChecks([path.join(rootUri, 'app', 'views', 'pages', 'input1.liquid')]);
196
196
 
197
197
  files.forEach(({ fileURI, fileVersion, diagnostics }) => {
198
198
  expect(connection.sendDiagnostics).toBeCalledWith({
@@ -250,7 +250,7 @@ describe('Module: runChecks', () => {
250
250
  source: 'platformos-check',
251
251
  code: 'MatchingTranslations',
252
252
  codeDescription: { href: expect.any(String) },
253
- message: `A default translation for 'hi' does not exist`,
253
+ message: `A translation for 'hi' does not exist in the en locale`,
254
254
  severity: 1,
255
255
  range: {
256
256
  // 'fr:\n hello: bonjour\n hi: salut'
@@ -53,12 +53,12 @@ function documentLinksVisitor(
53
53
  if (
54
54
  (node.name === 'render' || node.name === 'include') &&
55
55
  typeof node.markup !== 'string' &&
56
- isLiquidString(node.markup.snippet)
56
+ isLiquidString(node.markup.partial)
57
57
  ) {
58
- const snippet = node.markup.snippet;
58
+ const partial = node.markup.partial;
59
59
  return DocumentLink.create(
60
- range(textDocument, snippet),
61
- await documentsLocator.locate(root, node.name, snippet.value),
60
+ range(textDocument, partial),
61
+ await documentsLocator.locate(root, node.name, partial.value),
62
62
  );
63
63
  }
64
64
 
@@ -67,10 +67,10 @@ function documentLinksVisitor(
67
67
  typeof node.markup !== 'string' &&
68
68
  isLiquidString(node.markup.partial)
69
69
  ) {
70
- const snippet = node.markup.partial;
70
+ const partial = node.markup.partial;
71
71
  return DocumentLink.create(
72
- range(textDocument, snippet),
73
- await documentsLocator.locate(root, node.name, snippet.value),
72
+ range(textDocument, partial),
73
+ await documentsLocator.locate(root, node.name, partial.value),
74
74
  );
75
75
  }
76
76