@tamagui/language-service 0.0.0-bootstrap.0 → 3.0.0-beta.643.1

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 (80) hide show
  1. package/README.md +140 -1
  2. package/dist/cjs/check.cjs +173 -0
  3. package/dist/cjs/check.native.cjs +369 -0
  4. package/dist/cjs/check.native.js +371 -0
  5. package/dist/cjs/check.native.js.map +1 -0
  6. package/dist/cjs/core.cjs +221 -0
  7. package/dist/cjs/core.native.cjs +305 -0
  8. package/dist/cjs/core.native.js +307 -0
  9. package/dist/cjs/core.native.js.map +1 -0
  10. package/dist/cjs/document.cjs +82 -0
  11. package/dist/cjs/document.native.cjs +158 -0
  12. package/dist/cjs/document.native.js +160 -0
  13. package/dist/cjs/document.native.js.map +1 -0
  14. package/dist/cjs/extract-estree.cjs +193 -0
  15. package/dist/cjs/extract-estree.native.cjs +296 -0
  16. package/dist/cjs/extract-estree.native.js +298 -0
  17. package/dist/cjs/extract-estree.native.js.map +1 -0
  18. package/dist/cjs/extract-sucrase.cjs +222 -0
  19. package/dist/cjs/extract-sucrase.native.cjs +256 -0
  20. package/dist/cjs/extract-sucrase.native.js +258 -0
  21. package/dist/cjs/extract-sucrase.native.js.map +1 -0
  22. package/dist/cjs/host.cjs +38 -0
  23. package/dist/cjs/host.native.cjs +61 -0
  24. package/dist/cjs/host.native.js +63 -0
  25. package/dist/cjs/host.native.js.map +1 -0
  26. package/dist/cjs/index.cjs +301 -0
  27. package/dist/cjs/index.native.cjs +414 -0
  28. package/dist/cjs/index.native.js +416 -0
  29. package/dist/cjs/index.native.js.map +1 -0
  30. package/dist/esm/check.mjs +148 -0
  31. package/dist/esm/check.mjs.map +1 -0
  32. package/dist/esm/check.native.js +342 -0
  33. package/dist/esm/check.native.js.map +1 -0
  34. package/dist/esm/core.mjs +198 -0
  35. package/dist/esm/core.mjs.map +1 -0
  36. package/dist/esm/core.native.js +280 -0
  37. package/dist/esm/core.native.js.map +1 -0
  38. package/dist/esm/document.mjs +61 -0
  39. package/dist/esm/document.mjs.map +1 -0
  40. package/dist/esm/document.native.js +135 -0
  41. package/dist/esm/document.native.js.map +1 -0
  42. package/dist/esm/extract-estree.mjs +172 -0
  43. package/dist/esm/extract-estree.mjs.map +1 -0
  44. package/dist/esm/extract-estree.native.js +273 -0
  45. package/dist/esm/extract-estree.native.js.map +1 -0
  46. package/dist/esm/extract-sucrase.mjs +201 -0
  47. package/dist/esm/extract-sucrase.mjs.map +1 -0
  48. package/dist/esm/extract-sucrase.native.js +233 -0
  49. package/dist/esm/extract-sucrase.native.js.map +1 -0
  50. package/dist/esm/host.mjs +17 -0
  51. package/dist/esm/host.mjs.map +1 -0
  52. package/dist/esm/host.native.js +38 -0
  53. package/dist/esm/host.native.js.map +1 -0
  54. package/dist/esm/index.mjs +281 -0
  55. package/dist/esm/index.mjs.map +1 -0
  56. package/dist/esm/index.native.js +392 -0
  57. package/dist/esm/index.native.js.map +1 -0
  58. package/index.cjs +1 -0
  59. package/package.json +79 -7
  60. package/src/check.ts +204 -0
  61. package/src/core.ts +355 -0
  62. package/src/document.ts +140 -0
  63. package/src/extract-estree.ts +251 -0
  64. package/src/extract-sucrase.ts +308 -0
  65. package/src/host.ts +32 -0
  66. package/src/index.ts +452 -0
  67. package/types/check.d.ts +31 -0
  68. package/types/check.d.ts.map +11 -0
  69. package/types/core.d.ts +68 -0
  70. package/types/core.d.ts.map +11 -0
  71. package/types/document.d.ts +42 -0
  72. package/types/document.d.ts.map +11 -0
  73. package/types/extract-estree.d.ts +19 -0
  74. package/types/extract-estree.d.ts.map +11 -0
  75. package/types/extract-sucrase.d.ts +26 -0
  76. package/types/extract-sucrase.d.ts.map +11 -0
  77. package/types/host.d.ts +10 -0
  78. package/types/host.d.ts.map +11 -0
  79. package/types/index.d.ts +9 -0
  80. package/types/index.d.ts.map +11 -0
@@ -0,0 +1,301 @@
1
+
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all) __defProp(target, name, {
8
+ get: all[name],
9
+ enumerable: true
10
+ });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
15
+ get: () => from[key],
16
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
17
+ });
18
+ }
19
+ return to;
20
+ };
21
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
22
+ var index_exports = {};
23
+ __export(index_exports, { default: () => index_default });
24
+ module.exports = __toCommonJS(index_exports);
25
+ var import_node_path = require("node:path");
26
+ var import_core = require("./core.cjs");
27
+ var import_host = require("./host.cjs");
28
+ const completionSource = "@tamagui/language-service";
29
+ const diagnosticCode = 78711;
30
+ const defaultConfigPath = ".tamagui/tamagui.config.json";
31
+ const flatStyledModules = /* @__PURE__ */ new Set([
32
+ "tamagui",
33
+ "tamagui/unstyled",
34
+ "@tamagui/core",
35
+ "@tamagui/ui",
36
+ "@tamagui/web"
37
+ ]);
38
+ function loadTooling(info, configPath) {
39
+ const contents = info.serverHost.readFile(configPath);
40
+ if (contents === void 0) return null;
41
+ try {
42
+ return (0, import_core.createStyleTooling)(JSON.parse(contents));
43
+ } catch {
44
+ return null;
45
+ }
46
+ }
47
+ function findStringLiteralAtPosition(typescript, sourceFile, position) {
48
+ let found = null;
49
+ const visit = (node) => {
50
+ if (position < node.getFullStart() || position > node.getEnd()) return;
51
+ if (typescript.isStringLiteralLike(node) && position >= node.getStart(sourceFile) + 1 && position <= node.getEnd() - 1) {
52
+ found = node;
53
+ return;
54
+ }
55
+ typescript.forEachChild(node, visit);
56
+ };
57
+ visit(sourceFile);
58
+ return found;
59
+ }
60
+ function importedBindings(typescript, sourceFile) {
61
+ const styled = /* @__PURE__ */ new Set();
62
+ for (const statement of sourceFile.statements) {
63
+ if (!typescript.isImportDeclaration(statement) || !typescript.isStringLiteral(statement.moduleSpecifier)) {
64
+ continue;
65
+ }
66
+ const source = statement.moduleSpecifier.text;
67
+ if (!flatStyledModules.has(source)) continue;
68
+ const bindings = statement.importClause?.namedBindings;
69
+ if (!bindings) continue;
70
+ if (typescript.isNamespaceImport(bindings)) continue;
71
+ for (const element of bindings.elements) {
72
+ const imported = element.propertyName?.text || element.name.text;
73
+ if (imported === "styled") styled.add(element.name.text);
74
+ }
75
+ }
76
+ return { styled };
77
+ }
78
+ function propertyName(typescript, name) {
79
+ if (typescript.isIdentifier(name) || typescript.isStringLiteral(name)) {
80
+ return name.text;
81
+ }
82
+ return null;
83
+ }
84
+ function completionProperty(typescript, literal, tooling, checker, bindings) {
85
+ let parent = literal.parent;
86
+ if (typescript.isJsxExpression(parent)) parent = parent.parent;
87
+ if (typescript.isJsxAttribute(parent)) {
88
+ if (!typescript.isIdentifier(parent.name)) return null;
89
+ const property2 = parent.name.text;
90
+ if (!tooling.styleProps.has(property2)) return null;
91
+ const opening = parent.parent.parent;
92
+ if (!typescript.isJsxOpeningLikeElement(opening)) return null;
93
+ const host2 = (0, import_host.resolveTamaguiHost)(checker, opening.tagName);
94
+ if (!host2?.accepts(property2)) return null;
95
+ return { property: property2 };
96
+ }
97
+ if (!typescript.isPropertyAssignment(parent)) return null;
98
+ const property = propertyName(typescript, parent.name);
99
+ if (!property || !tooling.styleProps.has(property)) return null;
100
+ let current = parent;
101
+ while (current.parent && !typescript.isCallExpression(current.parent)) {
102
+ current = current.parent;
103
+ }
104
+ if (!current.parent || !typescript.isCallExpression(current.parent)) return null;
105
+ const call = current.parent;
106
+ if (call.arguments[1] !== current || !typescript.isIdentifier(call.expression) || !bindings.styled.has(call.expression.text)) {
107
+ return null;
108
+ }
109
+ const component = call.arguments[0];
110
+ const host = component && (0, import_host.resolveTamaguiHost)(checker, component);
111
+ if (!host?.accepts(property)) return null;
112
+ return { property };
113
+ }
114
+ function siteForLiteral(typescript, sourceFile, literal, tooling, checker, bindings) {
115
+ const site = completionProperty(typescript, literal, tooling, checker, bindings);
116
+ if (!site) return null;
117
+ const contentStart = literal.getStart(sourceFile) + 1;
118
+ const contentEnd = literal.getEnd() - 1;
119
+ const sourceInput = sourceFile.text.slice(contentStart, contentEnd);
120
+ if (literal.text !== sourceInput) return null;
121
+ return {
122
+ property: site.property,
123
+ value: literal.text,
124
+ contentStart,
125
+ literal
126
+ };
127
+ }
128
+ function collectLiteralSites(typescript, sourceFile, tooling, checker, bindings) {
129
+ const sites = [];
130
+ const visit = (node) => {
131
+ if (typescript.isStringLiteralLike(node)) {
132
+ const site = siteForLiteral(typescript, sourceFile, node, tooling, checker, bindings);
133
+ if (site) sites.push(site);
134
+ return;
135
+ }
136
+ typescript.forEachChild(node, visit);
137
+ };
138
+ visit(sourceFile);
139
+ return sites;
140
+ }
141
+ function copyLanguageService(service) {
142
+ const proxy = /* @__PURE__ */ Object.create(null);
143
+ for (const key of Object.keys(service)) {
144
+ const value = service[key];
145
+ proxy[key] = typeof value === "function" ? value.bind(service) : value;
146
+ }
147
+ return proxy;
148
+ }
149
+ const init = ({ typescript }) => ({ create(info) {
150
+ const pluginConfig = info.config;
151
+ const configuredPath = pluginConfig?.configPath || defaultConfigPath;
152
+ const configPath = (0, import_node_path.isAbsolute)(configuredPath) ? configuredPath : (0, import_node_path.resolve)(info.project.getCurrentDirectory(), configuredPath);
153
+ let tooling = loadTooling(info, configPath);
154
+ const watcher = info.serverHost.watchFile(configPath, () => {
155
+ tooling = loadTooling(info, configPath);
156
+ });
157
+ const proxy = copyLanguageService(info.languageService);
158
+ const baseCompletions = info.languageService.getCompletionsAtPosition.bind(info.languageService);
159
+ const baseDetails = info.languageService.getCompletionEntryDetails.bind(info.languageService);
160
+ const baseSemanticDiagnostics = info.languageService.getSemanticDiagnostics.bind(info.languageService);
161
+ const baseQuickInfo = info.languageService.getQuickInfoAtPosition.bind(info.languageService);
162
+ const baseDispose = info.languageService.dispose.bind(info.languageService);
163
+ const bindingsBySourceFile = /* @__PURE__ */ new WeakMap();
164
+ const fileContext = (fileName) => {
165
+ const program = info.languageService.getProgram();
166
+ const sourceFile = program?.getSourceFile(fileName);
167
+ if (!program || !sourceFile) return null;
168
+ let bindings = bindingsBySourceFile.get(sourceFile);
169
+ if (!bindings) {
170
+ bindings = importedBindings(typescript, sourceFile);
171
+ bindingsBySourceFile.set(sourceFile, bindings);
172
+ }
173
+ return {
174
+ sourceFile,
175
+ checker: program.getTypeChecker(),
176
+ bindings
177
+ };
178
+ };
179
+ proxy.getCompletionsAtPosition = (fileName, position, options, formattingSettings) => {
180
+ const getBaseCompletions = () => baseCompletions(fileName, position, options, formattingSettings);
181
+ if (!tooling) return getBaseCompletions();
182
+ const context = fileContext(fileName);
183
+ if (!context) return getBaseCompletions();
184
+ const { sourceFile, checker, bindings } = context;
185
+ const literal = findStringLiteralAtPosition(typescript, sourceFile, position);
186
+ if (!literal) return getBaseCompletions();
187
+ const site = siteForLiteral(typescript, sourceFile, literal, tooling, checker, bindings);
188
+ if (!site) return getBaseCompletions();
189
+ const cursorCompletions = tooling.completions(site.property, site.value, position - site.contentStart);
190
+ if (!cursorCompletions) return getBaseCompletions();
191
+ const replacementSpan = {
192
+ start: site.contentStart + cursorCompletions.replaceStart,
193
+ length: cursorCompletions.replaceLength
194
+ };
195
+ const entries = [];
196
+ let contextualType;
197
+ for (const completion of cursorCompletions.completions) {
198
+ const insertText = completion.insertText || completion.value;
199
+ const modifierKind = completion.kind === "modifier" ? tooling.modifierKind(completion.value) : void 0;
200
+ if (completion.kind === "keyword") {
201
+ contextualType ||= checker.getContextualType(literal);
202
+ if (!contextualType || !checker.isTypeAssignableTo(checker.getStringLiteralType(insertText), contextualType)) {
203
+ continue;
204
+ }
205
+ }
206
+ entries.push({
207
+ name: completion.value,
208
+ kind: typescript.ScriptElementKind.string,
209
+ kindModifiers: "",
210
+ sortText: (0, import_core.completionSortText)(completion, modifierKind),
211
+ insertText,
212
+ replacementSpan,
213
+ source: completionSource,
214
+ labelDetails: { description: modifierKind ? `Tamagui ${modifierKind} modifier` : completion.kind === "configured" ? "Tamagui configured value" : "Tamagui style keyword" }
215
+ });
216
+ }
217
+ if (entries.length === 0) return getBaseCompletions();
218
+ return {
219
+ isGlobalCompletion: false,
220
+ isMemberCompletion: false,
221
+ isNewIdentifierLocation: true,
222
+ isIncomplete: true,
223
+ entries
224
+ };
225
+ };
226
+ proxy.getCompletionEntryDetails = (fileName, position, entryName, formatOptions, source, preferences, data) => {
227
+ if (source === completionSource) {
228
+ return {
229
+ name: entryName,
230
+ kind: typescript.ScriptElementKind.string,
231
+ kindModifiers: "",
232
+ displayParts: [{
233
+ text: entryName,
234
+ kind: "stringLiteral"
235
+ }],
236
+ documentation: [{
237
+ text: "Resolved from the active Tamagui config.",
238
+ kind: "text"
239
+ }],
240
+ tags: []
241
+ };
242
+ }
243
+ return baseDetails(fileName, position, entryName, formatOptions, source, preferences, data);
244
+ };
245
+ proxy.getSemanticDiagnostics = (fileName) => {
246
+ const diagnostics = [...baseSemanticDiagnostics(fileName)];
247
+ if (!tooling) return diagnostics;
248
+ const context = fileContext(fileName);
249
+ if (!context) return diagnostics;
250
+ const { sourceFile, checker, bindings } = context;
251
+ for (const site of collectLiteralSites(typescript, sourceFile, tooling, checker, bindings)) {
252
+ for (const diagnostic of tooling.diagnostics(site.property, site.value)) {
253
+ diagnostics.push({
254
+ file: sourceFile,
255
+ start: site.contentStart + diagnostic.start,
256
+ length: Math.max(1, diagnostic.end - diagnostic.start),
257
+ messageText: diagnostic.message,
258
+ category: typescript.DiagnosticCategory.Error,
259
+ code: diagnosticCode,
260
+ source: completionSource
261
+ });
262
+ }
263
+ }
264
+ return diagnostics;
265
+ };
266
+ proxy.getQuickInfoAtPosition = (fileName, position) => {
267
+ const getBaseQuickInfo = () => baseQuickInfo(fileName, position);
268
+ if (!tooling) return getBaseQuickInfo();
269
+ const context = fileContext(fileName);
270
+ if (!context) return getBaseQuickInfo();
271
+ const { sourceFile, checker, bindings } = context;
272
+ const literal = findStringLiteralAtPosition(typescript, sourceFile, position);
273
+ if (!literal) return getBaseQuickInfo();
274
+ const site = siteForLiteral(typescript, sourceFile, literal, tooling, checker, bindings);
275
+ if (!site) return getBaseQuickInfo();
276
+ const hover = tooling.hover(site.property, site.value, position - site.contentStart);
277
+ if (!hover) return getBaseQuickInfo();
278
+ return {
279
+ kind: typescript.ScriptElementKind.string,
280
+ kindModifiers: "",
281
+ textSpan: {
282
+ start: site.contentStart + hover.start,
283
+ length: hover.end - hover.start
284
+ },
285
+ displayParts: [{
286
+ text: hover.text,
287
+ kind: "stringLiteral"
288
+ }],
289
+ documentation: [{
290
+ text: hover.markdown,
291
+ kind: "text"
292
+ }]
293
+ };
294
+ };
295
+ proxy.dispose = () => {
296
+ watcher.close();
297
+ baseDispose();
298
+ };
299
+ return proxy;
300
+ } });
301
+ var index_default = init;