ts-gem-plugin 0.0.6 → 0.0.8

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 (2) hide show
  1. package/dist/index.js +113 -90
  2. package/package.json +5 -5
package/dist/index.js CHANGED
@@ -158,11 +158,14 @@ var Configuration = class {
158
158
  }
159
159
  };
160
160
 
161
+ // src/constants.ts
162
+ var NAME = "gem-plugin";
163
+
161
164
  // src/context.ts
162
- var import_vscode_html_languageservice2 = require("@mantou/vscode-html-languageservice");
163
- var import_standard_template_source_helper = __toESM(require("@mantou/typescript-template-language-service-decorator/lib/standard-template-source-helper"));
164
165
  var import_standard_script_source_helper = __toESM(require("@mantou/typescript-template-language-service-decorator/lib/standard-script-source-helper"));
166
+ var import_standard_template_source_helper = __toESM(require("@mantou/typescript-template-language-service-decorator/lib/standard-template-source-helper"));
165
167
  var import_vscode_css_languageservice = require("@mantou/vscode-css-languageservice");
168
+ var import_vscode_html_languageservice2 = require("@mantou/vscode-html-languageservice");
166
169
 
167
170
  // ../duoyun-ui/lib/map.js
168
171
  var StringWeakMap = class {
@@ -188,12 +191,83 @@ var StringWeakMap = class {
188
191
  }
189
192
  };
190
193
 
194
+ // ../duoyun-ui/lib/cache.js
195
+ var Cache = class {
196
+ #max;
197
+ #maxAge;
198
+ #renewal;
199
+ #map = /* @__PURE__ */ new Map();
200
+ #reverseMap = /* @__PURE__ */ new Map();
201
+ #addedLinked = new LinkedList();
202
+ constructor({ max = Infinity, maxAge = Infinity, renewal = false } = {}) {
203
+ this.#max = max;
204
+ this.#maxAge = maxAge;
205
+ this.#renewal = renewal;
206
+ }
207
+ setOptions(options) {
208
+ this.#max = options.max ?? this.#max;
209
+ this.#maxAge = options.maxAge ?? this.#maxAge;
210
+ this.#renewal = options.renewal ?? this.#renewal;
211
+ }
212
+ #trim() {
213
+ for (let i = this.#addedLinked.size - this.#max; i > 0; i--) {
214
+ const value = this.#addedLinked.get();
215
+ const key = this.#reverseMap.get(value);
216
+ this.#reverseMap.delete(value);
217
+ this.#map.delete(key);
218
+ }
219
+ }
220
+ set(key, value) {
221
+ this.#addedLinked.add(value);
222
+ this.#reverseMap.set(value, key);
223
+ this.#map.set(key, { value, timestamp: Date.now() });
224
+ this.#trim();
225
+ return value;
226
+ }
227
+ get(key, init) {
228
+ const cache = this.#map.get(key);
229
+ if (!cache) {
230
+ return init && this.set(key, init(key));
231
+ }
232
+ const { timestamp, value } = cache;
233
+ if (Date.now() - timestamp > this.#maxAge) {
234
+ this.#addedLinked.delete(value);
235
+ this.#reverseMap.delete(value);
236
+ this.#map.delete(key);
237
+ return init && this.set(key, init(key));
238
+ }
239
+ if (this.#renewal) {
240
+ cache.timestamp = Date.now();
241
+ }
242
+ this.#addedLinked.add(value);
243
+ return value;
244
+ }
245
+ };
246
+
247
+ // src/cache.ts
248
+ var LRUCache = class {
249
+ #bucket;
250
+ constructor(args) {
251
+ this.#bucket = new Cache({ max: 25, renewal: true, ...args });
252
+ }
253
+ #genKey(context, position) {
254
+ return [context.fileName, position?.line, position?.character, context.text].join(";");
255
+ }
256
+ get(context, position, init) {
257
+ return this.#bucket.get(this.#genKey(context, position), init);
258
+ }
259
+ };
260
+
261
+ // src/data-provider.ts
262
+ var import_vscode_html_languageservice = require("@mantou/vscode-html-languageservice");
263
+
191
264
  // src/utils.ts
192
265
  function isCustomElementTag(tag) {
193
266
  return tag.includes("-");
194
267
  }
195
268
  function isDepElement(node) {
196
- return node.getSourceFile().fileName.includes("/node_modules/");
269
+ const { fileName } = node.getSourceFile();
270
+ return ["/node_modules/", "/dist/", ".d.ts"].some((s) => fileName.includes(s));
197
271
  }
198
272
  function bindMemberFunction(o, keys2 = Object.keys(o)) {
199
273
  return Object.fromEntries(keys2.map((key) => [key, o[key].bind?.(o)]));
@@ -265,12 +339,6 @@ function decorate(origin, cb) {
265
339
  return result;
266
340
  }
267
341
 
268
- // src/data-provider.ts
269
- var import_vscode_html_languageservice = require("@mantou/vscode-html-languageservice");
270
-
271
- // src/constants.ts
272
- var NAME = "gem-plugin";
273
-
274
342
  // src/data-provider.ts
275
343
  var dataProvider = (0, import_vscode_html_languageservice.getDefaultHTMLDataProvider)();
276
344
  var HTMLDataProvider = class {
@@ -373,73 +441,6 @@ function getDocComment(typescript, declaration) {
373
441
  return commentStrings?.join("\n\n");
374
442
  }
375
443
 
376
- // ../duoyun-ui/lib/cache.js
377
- var Cache = class {
378
- #max;
379
- #maxAge;
380
- #renewal;
381
- #map = /* @__PURE__ */ new Map();
382
- #reverseMap = /* @__PURE__ */ new Map();
383
- #addedLinked = new LinkedList();
384
- constructor({ max = Infinity, maxAge = Infinity, renewal = false } = {}) {
385
- this.#max = max;
386
- this.#maxAge = maxAge;
387
- this.#renewal = renewal;
388
- }
389
- setOptions(options) {
390
- this.#max = options.max ?? this.#max;
391
- this.#maxAge = options.maxAge ?? this.#maxAge;
392
- this.#renewal = options.renewal ?? this.#renewal;
393
- }
394
- #trim() {
395
- for (let i = this.#addedLinked.size - this.#max; i > 0; i--) {
396
- const value = this.#addedLinked.get();
397
- const key = this.#reverseMap.get(value);
398
- this.#reverseMap.delete(value);
399
- this.#map.delete(key);
400
- }
401
- }
402
- set(key, value) {
403
- this.#addedLinked.add(value);
404
- this.#reverseMap.set(value, key);
405
- this.#map.set(key, { value, timestamp: Date.now() });
406
- this.#trim();
407
- return value;
408
- }
409
- get(key, init) {
410
- const cache = this.#map.get(key);
411
- if (!cache) {
412
- return init && this.set(key, init(key));
413
- }
414
- const { timestamp, value } = cache;
415
- if (Date.now() - timestamp > this.#maxAge) {
416
- this.#addedLinked.delete(value);
417
- this.#reverseMap.delete(value);
418
- this.#map.delete(key);
419
- return init && this.set(key, init(key));
420
- }
421
- if (this.#renewal) {
422
- cache.timestamp = Date.now();
423
- }
424
- this.#addedLinked.add(value);
425
- return value;
426
- }
427
- };
428
-
429
- // src/cache.ts
430
- var LRUCache = class {
431
- #bucket;
432
- constructor(args) {
433
- this.#bucket = new Cache({ max: 25, renewal: true, ...args });
434
- }
435
- #genKey(context, position) {
436
- return [context.fileName, position?.line, position?.character, context.text].join(";");
437
- }
438
- get(context, position, init) {
439
- return this.#bucket.get(this.#genKey(context, position), init);
440
- }
441
- };
442
-
443
444
  // src/context.ts
444
445
  var Context = class {
445
446
  elements;
@@ -582,7 +583,7 @@ function getSubstitution(templateString, start, end) {
582
583
  function isValidCSSTemplate(typescript, node, callName) {
583
584
  switch (node.kind) {
584
585
  case typescript.SyntaxKind.NoSubstitutionTemplateLiteral:
585
- case typescript.SyntaxKind.TemplateExpression:
586
+ case typescript.SyntaxKind.TemplateExpression: {
586
587
  const parent = node.parent;
587
588
  if (typescript.isCallExpression(parent) && parent.expression.getText() === callName) {
588
589
  return true;
@@ -594,6 +595,7 @@ function isValidCSSTemplate(typescript, node, callName) {
594
595
  }
595
596
  }
596
597
  return false;
598
+ }
597
599
  default:
598
600
  return false;
599
601
  }
@@ -662,8 +664,6 @@ function translationCompletionItemKind(context, kind) {
662
664
  return typescript.ScriptElementKind.alias;
663
665
  case vscode.CompletionItemKind.File:
664
666
  return typescript.ScriptElementKind.moduleElement;
665
- case vscode.CompletionItemKind.Snippet:
666
- case vscode.CompletionItemKind.Text:
667
667
  default:
668
668
  return typescript.ScriptElementKind.unknown;
669
669
  }
@@ -727,11 +727,11 @@ function genDefaultCompletionEntryDetails(context, name) {
727
727
  }
728
728
  function toDisplayParts(text, isDoc = false) {
729
729
  if (!text) return [];
730
- const escape = (unsafe) => unsafe.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;").replaceAll(" ", "&nbsp;").replaceAll("\n", " \n").replaceAll(" ", "&emsp;");
730
+ const escapeText = (unsafe) => unsafe.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;").replaceAll(" ", "&nbsp;").replaceAll("\n", " \n").replaceAll(" ", "&emsp;");
731
731
  return [
732
732
  {
733
733
  kind: "unknown",
734
- text: typeof text !== "string" ? text.value : isDoc ? escape(text) : text
734
+ text: typeof text !== "string" ? text.value : isDoc ? escapeText(text) : text
735
735
  }
736
736
  ];
737
737
  }
@@ -1010,7 +1010,8 @@ var HTMLLanguageService = class {
1010
1010
  const diagnostics = [];
1011
1011
  forEachNode(vHtml.roots, (node) => {
1012
1012
  if (!node.tag) return;
1013
- if (isCustomElementTag(node.tag) && !this.#ctx.elements.get(node.tag)) {
1013
+ const customElementTagDecl = this.#ctx.elements.get(node.tag);
1014
+ if (isCustomElementTag(node.tag) && !customElementTagDecl) {
1014
1015
  diagnostics.push({
1015
1016
  category: context.typescript.DiagnosticCategory.Warning,
1016
1017
  code: 101 /* UnknownTag */,
@@ -1021,13 +1022,13 @@ var HTMLLanguageService = class {
1021
1022
  source: NAME
1022
1023
  });
1023
1024
  }
1024
- const tagDeclaration = this.#ctx.elements.get(node.tag) || this.#ctx.builtInElements.get(node.tag);
1025
+ const tagDeclaration = customElementTagDecl || this.#ctx.builtInElements.get(node.tag);
1025
1026
  if (!tagDeclaration) return;
1026
1027
  for (const [attributeName, { value, start, end }] of node.attributesMap) {
1027
1028
  if (attributeName.startsWith("_")) continue;
1028
1029
  const hasValueSpan = value?.startsWith("_");
1029
1030
  const attrInfo = getAttrName(attributeName);
1030
- const propType = getPropType(typeChecker, tagDeclaration, attrInfo);
1031
+ const propType = getPropType(typeChecker, tagDeclaration, !customElementTagDecl, attrInfo);
1031
1032
  const diagnostic = {
1032
1033
  category: context.typescript.DiagnosticCategory.Warning,
1033
1034
  file,
@@ -1082,7 +1083,7 @@ var HTMLLanguageService = class {
1082
1083
  if (hasValueSpan) {
1083
1084
  const spanType = getSpanType(this.#ctx.ts, typeChecker, file, offset, end);
1084
1085
  switch (attrInfo.decorate) {
1085
- case "?":
1086
+ case "?": {
1086
1087
  const boolType = getUnionType(typeChecker, [
1087
1088
  typeChecker.getBooleanType(),
1088
1089
  typeChecker.getUndefinedType(),
@@ -1092,6 +1093,7 @@ var HTMLLanguageService = class {
1092
1093
  diagnostics.push(diagnostic);
1093
1094
  }
1094
1095
  continue;
1096
+ }
1095
1097
  case ".":
1096
1098
  case "@":
1097
1099
  if (!typeChecker.isTypeAssignableTo(spanType, propType)) {
@@ -1121,7 +1123,6 @@ var HTMLLanguageService = class {
1121
1123
  } else if (types.every((t) => !typeChecker.isTypeAssignableTo(t, propType))) {
1122
1124
  diagnostics.push(diagnostic);
1123
1125
  }
1124
- continue;
1125
1126
  }
1126
1127
  }
1127
1128
  });
@@ -1186,35 +1187,57 @@ function getSpanType(typescript, typeChecker, file, htmlOffset, attrNameEnd) {
1186
1187
  const spanExp = getSpanExpression(typescript, file, valueOffset);
1187
1188
  return typeChecker.getTypeAtLocation(spanExp);
1188
1189
  }
1189
- function getPropType(typeChecker, tagClassDeclaration, attrInfo) {
1190
+ var buildInElementNoGlobalAttrPropMap = /* @__PURE__ */ new Map([
1191
+ ["crossorigin", "crossOrigin"],
1192
+ ["rowspan", "rowSpan"],
1193
+ ["colspan", "colSpan"],
1194
+ // <input> list: string
1195
+ ["list", "ariaLabelledby"]
1196
+ ]);
1197
+ function getPropType(typeChecker, tagClassDeclaration, isBuiltInTag, attrInfo) {
1190
1198
  const classType = typeChecker.getTypeAtLocation(tagClassDeclaration);
1191
1199
  if (attrInfo.attr.startsWith("data-")) {
1192
1200
  return typeChecker.getStringType();
1193
1201
  }
1194
- const propName = kebabToCamelCase(attrInfo.attr);
1202
+ const propName = isBuiltInTag ? buildInElementNoGlobalAttrPropMap.get(attrInfo.attr) || kebabToCamelCase(attrInfo.attr) : kebabToCamelCase(attrInfo.attr);
1195
1203
  switch (propName) {
1196
1204
  case "class":
1197
1205
  case "style":
1198
1206
  case "part":
1199
1207
  case "exportparts":
1208
+ case "xmlns":
1209
+ case "viewBox":
1210
+ case "ariaLabelledby":
1200
1211
  return typeChecker.getStringType();
1201
1212
  case "tabindex":
1202
1213
  return typeChecker.getNumberType();
1203
- case "ariaDisabled":
1214
+ case "ariaAtomic":
1215
+ case "ariaBusy":
1204
1216
  case "ariaChecked":
1217
+ case "ariaDisabled":
1218
+ case "ariaExpanded":
1219
+ case "ariaGrabbed":
1205
1220
  case "ariaHidden":
1221
+ case "ariaModal":
1222
+ case "ariaMultiline":
1223
+ case "ariaMultiselectable":
1224
+ case "ariaReadonly":
1225
+ case "ariaRequired":
1226
+ case "ariaPressed":
1227
+ case "ariaSelected":
1206
1228
  return getUnionType(typeChecker, [
1207
1229
  typeChecker.getStringType(),
1208
1230
  typeChecker.getBooleanType(),
1209
1231
  typeChecker.getUndefinedType()
1210
1232
  ]);
1211
- default:
1233
+ default: {
1212
1234
  const isEvent = attrInfo.decorate === "@";
1213
1235
  const propSymbol = classType.getProperty(propName);
1214
1236
  const propType = propSymbol && typeChecker.getTypeOfSymbol(propSymbol);
1215
1237
  if (!isEvent) return propType;
1216
1238
  const eventHandleType = getEmitterHandleType(typeChecker, classType, propType);
1217
1239
  return getUnionType(typeChecker, [eventHandleType, typeChecker.getUndefinedType()]);
1240
+ }
1218
1241
  }
1219
1242
  }
1220
1243
  function getEmitterHandleType(typeChecker, classType, propType) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ts-gem-plugin",
3
- "version": "0.0.6",
3
+ "version": "0.0.8",
4
4
  "description": "Typescript language service plugin for Gem",
5
5
  "keywords": [
6
6
  "gem",
@@ -14,17 +14,17 @@
14
14
  "prepublishOnly": "pnpm run build"
15
15
  },
16
16
  "dependencies": {
17
- "@mantou/gem": "^2.2.0",
17
+ "@mantou/gem": "^2.2.1",
18
18
  "@mantou/typescript-template-language-service-decorator": "^2.3.4",
19
19
  "@mantou/vscode-css-languageservice": "^6.3.3",
20
20
  "@mantou/vscode-emmet-helper": "^2.9.3",
21
- "@mantou/vscode-html-languageservice": "^5.3.4",
22
- "duoyun-ui": "^2.2.0",
21
+ "@mantou/vscode-html-languageservice": "^5.3.6",
22
+ "duoyun-ui": "^2.2.1",
23
23
  "vscode-languageserver-textdocument": "^1.0.12",
24
24
  "vscode-languageserver-types": "^3.17.5"
25
25
  },
26
26
  "devDependencies": {
27
- "@gemjs/config": "^2.1.0",
27
+ "@gemjs/config": "^2.1.1",
28
28
  "typescript": "^5.6.2"
29
29
  },
30
30
  "author": "mantou132",