@azerothjs/language-service 0.4.0-beta.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 (98) hide show
  1. package/README.md +259 -0
  2. package/dist/html-source.d.ts +12 -0
  3. package/dist/html-source.d.ts.map +1 -0
  4. package/dist/html-source.js +108 -0
  5. package/dist/html-source.js.map +1 -0
  6. package/dist/index.d.ts +12 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +29 -0
  9. package/dist/index.js.map +1 -0
  10. package/dist/language-data.d.ts +41 -0
  11. package/dist/language-data.d.ts.map +1 -0
  12. package/dist/language-data.js +164 -0
  13. package/dist/language-data.js.map +1 -0
  14. package/dist/mapping.d.ts +71 -0
  15. package/dist/mapping.d.ts.map +1 -0
  16. package/dist/mapping.js +123 -0
  17. package/dist/mapping.js.map +1 -0
  18. package/dist/markup-model.d.ts +67 -0
  19. package/dist/markup-model.d.ts.map +1 -0
  20. package/dist/markup-model.js +313 -0
  21. package/dist/markup-model.js.map +1 -0
  22. package/dist/protocol.d.ts +176 -0
  23. package/dist/protocol.d.ts.map +1 -0
  24. package/dist/protocol.js +58 -0
  25. package/dist/protocol.js.map +1 -0
  26. package/dist/providers/completion.d.ts +26 -0
  27. package/dist/providers/completion.d.ts.map +1 -0
  28. package/dist/providers/completion.js +339 -0
  29. package/dist/providers/completion.js.map +1 -0
  30. package/dist/providers/css-service.d.ts +7 -0
  31. package/dist/providers/css-service.d.ts.map +1 -0
  32. package/dist/providers/css-service.js +84 -0
  33. package/dist/providers/css-service.js.map +1 -0
  34. package/dist/providers/diagnostics.d.ts +5 -0
  35. package/dist/providers/diagnostics.d.ts.map +1 -0
  36. package/dist/providers/diagnostics.js +89 -0
  37. package/dist/providers/diagnostics.js.map +1 -0
  38. package/dist/providers/editing.d.ts +17 -0
  39. package/dist/providers/editing.d.ts.map +1 -0
  40. package/dist/providers/editing.js +176 -0
  41. package/dist/providers/editing.js.map +1 -0
  42. package/dist/providers/hover.d.ts +5 -0
  43. package/dist/providers/hover.d.ts.map +1 -0
  44. package/dist/providers/hover.js +213 -0
  45. package/dist/providers/hover.js.map +1 -0
  46. package/dist/providers/html-service.d.ts +8 -0
  47. package/dist/providers/html-service.d.ts.map +1 -0
  48. package/dist/providers/html-service.js +108 -0
  49. package/dist/providers/html-service.js.map +1 -0
  50. package/dist/providers/inlay-hints.d.ts +25 -0
  51. package/dist/providers/inlay-hints.d.ts.map +1 -0
  52. package/dist/providers/inlay-hints.js +52 -0
  53. package/dist/providers/inlay-hints.js.map +1 -0
  54. package/dist/providers/navigation.d.ts +16 -0
  55. package/dist/providers/navigation.d.ts.map +1 -0
  56. package/dist/providers/navigation.js +107 -0
  57. package/dist/providers/navigation.js.map +1 -0
  58. package/dist/providers/semantic-tokens.d.ts +5 -0
  59. package/dist/providers/semantic-tokens.d.ts.map +1 -0
  60. package/dist/providers/semantic-tokens.js +63 -0
  61. package/dist/providers/semantic-tokens.js.map +1 -0
  62. package/dist/providers/signature.d.ts +5 -0
  63. package/dist/providers/signature.d.ts.map +1 -0
  64. package/dist/providers/signature.js +38 -0
  65. package/dist/providers/signature.js.map +1 -0
  66. package/dist/providers/structure.d.ts +19 -0
  67. package/dist/providers/structure.d.ts.map +1 -0
  68. package/dist/providers/structure.js +188 -0
  69. package/dist/providers/structure.js.map +1 -0
  70. package/dist/providers/symbols.d.ts +8 -0
  71. package/dist/providers/symbols.d.ts.map +1 -0
  72. package/dist/providers/symbols.js +108 -0
  73. package/dist/providers/symbols.js.map +1 -0
  74. package/dist/request.d.ts +37 -0
  75. package/dist/request.d.ts.map +1 -0
  76. package/dist/request.js +49 -0
  77. package/dist/request.js.map +1 -0
  78. package/dist/service.d.ts +73 -0
  79. package/dist/service.d.ts.map +1 -0
  80. package/dist/service.js +177 -0
  81. package/dist/service.js.map +1 -0
  82. package/dist/text.d.ts +25 -0
  83. package/dist/text.d.ts.map +1 -0
  84. package/dist/text.js +66 -0
  85. package/dist/text.js.map +1 -0
  86. package/dist/ts-project.d.ts +75 -0
  87. package/dist/ts-project.d.ts.map +1 -0
  88. package/dist/ts-project.js +266 -0
  89. package/dist/ts-project.js.map +1 -0
  90. package/dist/uri.d.ts +21 -0
  91. package/dist/uri.d.ts.map +1 -0
  92. package/dist/uri.js +41 -0
  93. package/dist/uri.js.map +1 -0
  94. package/dist/virtual-code.d.ts +27 -0
  95. package/dist/virtual-code.d.ts.map +1 -0
  96. package/dist/virtual-code.js +360 -0
  97. package/dist/virtual-code.js.map +1 -0
  98. package/package.json +61 -0
@@ -0,0 +1,84 @@
1
+ // CSS intelligence for inline `style="…"` values, via `vscode-css-languageservice`
2
+ // (the engine behind VS Code's CSS support). An inline style is a declaration
3
+ // list, not a full stylesheet, so we wrap it in a synthetic rule `*{ … }` and
4
+ // shift positions by the 2-character prefix - the same trick VS Code uses for
5
+ // embedded styles. Only static `style="…"` values reach here; `style={…}` is a
6
+ // JavaScript expression handled by the TypeScript bridge.
7
+ import { getCSSLanguageService } from 'vscode-css-languageservice';
8
+ import { TextDocument } from 'vscode-languageserver-textdocument';
9
+ import { CompletionItemKind } from "../protocol.js";
10
+ /** The `*{` we prepend so the declaration list parses as a stylesheet. */
11
+ const WRAP_PREFIX = '*{';
12
+ let service = null;
13
+ const css = () => (service ??= getCSSLanguageService());
14
+ /** The `[start, end)` of the style value's content around `offset`, or null. */
15
+ function styleValueSpan(source, offset) {
16
+ let i = offset - 1;
17
+ while (i >= 0 && source[i] !== '"' && source[i] !== '\'' && source[i] !== '<' && source[i] !== '>') {
18
+ i--;
19
+ }
20
+ if (i < 0 || (source[i] !== '"' && source[i] !== '\'')) {
21
+ return null;
22
+ }
23
+ const quote = source[i];
24
+ const start = i + 1;
25
+ let j = offset;
26
+ while (j < source.length && source[j] !== quote && source[j] !== '<' && source[j] !== '>') {
27
+ j++;
28
+ }
29
+ return { start, end: j, quote };
30
+ }
31
+ /** Builds the wrapped CSS document and the caret offset within it. */
32
+ function wrap(source, offset) {
33
+ const span = styleValueSpan(source, offset);
34
+ if (span === null) {
35
+ return null;
36
+ }
37
+ const content = source.slice(span.start, span.end);
38
+ const doc = TextDocument.create('inline://style.css', 'css', 0, `${WRAP_PREFIX}${content}}`);
39
+ return { doc, caret: WRAP_PREFIX.length + (offset - span.start), contentStart: span.start };
40
+ }
41
+ /** CSS property/value completion inside an inline `style="…"`. */
42
+ export function cssCompletions(source, offset) {
43
+ const wrapped = wrap(source, offset);
44
+ if (wrapped === null) {
45
+ return [];
46
+ }
47
+ const stylesheet = css().parseStylesheet(wrapped.doc);
48
+ const list = css().doComplete(wrapped.doc, wrapped.doc.positionAt(wrapped.caret), stylesheet);
49
+ return list.items.map(item => ({
50
+ label: item.label,
51
+ kind: (item.kind ?? CompletionItemKind.Property),
52
+ detail: item.detail,
53
+ documentation: typeof item.documentation === 'string' ? item.documentation : item.documentation?.value,
54
+ insertText: item.textEdit && 'newText' in item.textEdit ? item.textEdit.newText : item.insertText ?? item.label,
55
+ insertTextFormat: item.insertTextFormat ?? 1,
56
+ sortText: item.sortText
57
+ }));
58
+ }
59
+ /** CSS hover (property/value docs) inside an inline `style="…"`. */
60
+ export function cssHover(source, offset, lineIndex) {
61
+ const wrapped = wrap(source, offset);
62
+ if (wrapped === null) {
63
+ return null;
64
+ }
65
+ const stylesheet = css().parseStylesheet(wrapped.doc);
66
+ const hover = css().doHover(wrapped.doc, wrapped.doc.positionAt(wrapped.caret), stylesheet);
67
+ if (!hover) {
68
+ return null;
69
+ }
70
+ const contents = typeof hover.contents === 'string'
71
+ ? hover.contents
72
+ : Array.isArray(hover.contents)
73
+ ? hover.contents.map(part => (typeof part === 'string' ? part : part.value)).join('\n\n')
74
+ : hover.contents.value;
75
+ let range;
76
+ if (hover.range) {
77
+ // Map the css-doc range back to the original source.
78
+ const startOffset = wrapped.doc.offsetAt(hover.range.start) - WRAP_PREFIX.length + wrapped.contentStart;
79
+ const endOffset = wrapped.doc.offsetAt(hover.range.end) - WRAP_PREFIX.length + wrapped.contentStart;
80
+ range = lineIndex.rangeAt(startOffset, endOffset);
81
+ }
82
+ return { contents, range };
83
+ }
84
+ //# sourceMappingURL=css-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"css-service.js","sourceRoot":"","sources":["../../src/providers/css-service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import { type Diagnostic } from '../protocol.ts';
2
+ import { type RequestContext } from '../request.ts';
3
+ /** All diagnostics for the document. */
4
+ export declare function getDiagnostics(ctx: RequestContext): Diagnostic[];
5
+ //# sourceMappingURL=diagnostics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostics.d.ts","sourceRoot":"","sources":["../../src/providers/diagnostics.ts"],"names":[],"mappings":"AAYA,OAAO,EAEH,KAAK,UAAU,EAElB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD,wCAAwC;AACxC,wBAAgB,cAAc,CAAC,GAAG,EAAE,cAAc,GAAG,UAAU,EAAE,CAUhE"}
@@ -0,0 +1,89 @@
1
+ // Diagnostics from two sources:
2
+ // 1. The compiler's own parser - a CompileError (mismatched/closing tag,
3
+ // missing attribute value, ...) is reported at its exact offset.
4
+ // 2. TypeScript's syntactic + semantic diagnostics over the virtual module,
5
+ // mapped back to original ranges. Diagnostics that land purely in
6
+ // generated scaffolding are dropped (there is no original code to flag),
7
+ // so what surfaces are genuine type errors in the user's expressions and
8
+ // script.
9
+ import ts from 'typescript';
10
+ import { findMarkupStart } from '@azerothjs/compiler';
11
+ import { parseMarkup, CompileError } from '@azerothjs/compiler';
12
+ import { DiagnosticSeverity } from "../protocol.js";
13
+ /** All diagnostics for the document. */
14
+ export function getDiagnostics(ctx) {
15
+ const markup = markupDiagnostics(ctx);
16
+ // A hard markup parse error means the virtual module is incomplete; TS
17
+ // diagnostics would be noise, so report only the markup error.
18
+ if (markup.length > 0) {
19
+ return markup;
20
+ }
21
+ return typeScriptDiagnostics(ctx);
22
+ }
23
+ /** Reports the first unparseable markup region as a CompileError diagnostic. */
24
+ function markupDiagnostics(ctx) {
25
+ const out = [];
26
+ let i = 0;
27
+ for (;;) {
28
+ const start = findMarkupStart(ctx.source, i);
29
+ if (start === -1) {
30
+ break;
31
+ }
32
+ try {
33
+ const { end } = parseMarkup(ctx.source, start);
34
+ i = end;
35
+ }
36
+ catch (err) {
37
+ if (err instanceof CompileError) {
38
+ const at = Math.min(err.offset, ctx.source.length);
39
+ out.push({
40
+ range: ctx.lineIndex.rangeAt(at, Math.min(at + 1, ctx.source.length)),
41
+ severity: DiagnosticSeverity.Error,
42
+ message: err.message,
43
+ source: 'azeroth'
44
+ });
45
+ }
46
+ break;
47
+ }
48
+ }
49
+ return out;
50
+ }
51
+ /** TypeScript syntactic + semantic diagnostics, mapped to original ranges. */
52
+ function typeScriptDiagnostics(ctx) {
53
+ const raw = [
54
+ ...ctx.project.service.getSyntacticDiagnostics(ctx.virtualFile),
55
+ ...ctx.project.service.getSemanticDiagnostics(ctx.virtualFile)
56
+ ];
57
+ const out = [];
58
+ for (const diag of raw) {
59
+ if (diag.start === undefined || diag.length === undefined) {
60
+ continue;
61
+ }
62
+ const mapped = ctx.virtual.mapping.toOriginalRange(diag.start, diag.start + diag.length);
63
+ if (mapped === null) {
64
+ continue;
65
+ }
66
+ out.push({
67
+ range: ctx.lineIndex.rangeAt(mapped.start, mapped.end),
68
+ severity: categoryToSeverity(diag.category),
69
+ message: ts.flattenDiagnosticMessageText(diag.messageText, '\n'),
70
+ code: diag.code,
71
+ source: 'azeroth-ts'
72
+ });
73
+ }
74
+ return out;
75
+ }
76
+ /** Maps a TS diagnostic category to an LSP severity. */
77
+ function categoryToSeverity(category) {
78
+ switch (category) {
79
+ case ts.DiagnosticCategory.Error:
80
+ return DiagnosticSeverity.Error;
81
+ case ts.DiagnosticCategory.Warning:
82
+ return DiagnosticSeverity.Warning;
83
+ case ts.DiagnosticCategory.Suggestion:
84
+ return DiagnosticSeverity.Hint;
85
+ default:
86
+ return DiagnosticSeverity.Information;
87
+ }
88
+ }
89
+ //# sourceMappingURL=diagnostics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostics.js","sourceRoot":"","sources":["../../src/providers/diagnostics.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { Range } from '../protocol.ts';
2
+ import type { RequestContext } from '../request.ts';
3
+ /**
4
+ * After the user types `>`, returns a snippet that closes the just-opened tag
5
+ * (`$0</div>`), or null when there's nothing to close (self-closing tag, void
6
+ * element, fragment, or a `>` that wasn't a tag end).
7
+ *
8
+ * `offset` is the position immediately after the typed `>`.
9
+ */
10
+ export declare function getAutoCloseTag(ctx: RequestContext, offset: number): string | null;
11
+ /**
12
+ * Returns the opening- and closing-tag name ranges for the element under the
13
+ * caret, so the editor can edit them together (linked editing). Null unless the
14
+ * caret is on a tag name of an element that has a matching closing tag.
15
+ */
16
+ export declare function getLinkedEditingRanges(ctx: RequestContext, offset: number): Range[] | null;
17
+ //# sourceMappingURL=editing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"editing.d.ts","sourceRoot":"","sources":["../../src/providers/editing.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AASpD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAwClF;AAqGD;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,GAAG,KAAK,EAAE,GAAG,IAAI,CAoB1F"}
@@ -0,0 +1,176 @@
1
+ // Markup editing behaviours that make `.azeroth` feel like a first-class
2
+ // JSX-aware language:
3
+ //
4
+ // - auto-close tags: typing the `>` of `<div>` returns `</div>` so the editor
5
+ // can complete the pair (mirroring VS Code's JSX behaviour);
6
+ // - linked editing: renaming an opening tag updates its closing tag live, and
7
+ // vice-versa.
8
+ //
9
+ // Both reuse the compiler's scanner (to skip strings/expressions correctly) and
10
+ // parser (to understand structure), so a `<` inside an attribute expression
11
+ // like `title={a < b}` is never mistaken for a tag.
12
+ import { findMarkupStart, skipBalanced, skipString, isIdentStart, isIdentPart, isWhitespace } from '@azerothjs/compiler';
13
+ import { parseMarkup } from '@azerothjs/compiler';
14
+ import { collectMarkupNodes } from "../markup-model.js";
15
+ /** Void HTML elements have no closing tag, so they are never auto-closed. */
16
+ const VOID_ELEMENTS = new Set([
17
+ 'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input',
18
+ 'link', 'meta', 'param', 'source', 'track', 'wbr'
19
+ ]);
20
+ /**
21
+ * After the user types `>`, returns a snippet that closes the just-opened tag
22
+ * (`$0</div>`), or null when there's nothing to close (self-closing tag, void
23
+ * element, fragment, or a `>` that wasn't a tag end).
24
+ *
25
+ * `offset` is the position immediately after the typed `>`.
26
+ */
27
+ export function getAutoCloseTag(ctx, offset) {
28
+ const source = ctx.source;
29
+ if (source[offset - 1] !== '>') {
30
+ return null;
31
+ }
32
+ // Find the markup region the caret is in, then walk its tags forward to the
33
+ // one whose opening tag ends exactly at the caret.
34
+ let i = 0;
35
+ for (;;) {
36
+ const start = findMarkupStart(source, i);
37
+ if (start === -1 || start >= offset) {
38
+ return null;
39
+ }
40
+ let parsedEnd;
41
+ try {
42
+ parsedEnd = parseMarkup(source, start).end;
43
+ }
44
+ catch {
45
+ parsedEnd = null;
46
+ }
47
+ if (parsedEnd === null || (start < offset && parsedEnd >= offset)) {
48
+ // This region contains (or is) the incomplete tag being typed.
49
+ const tag = tagEndingAt(source, start, offset);
50
+ if (tag === null || tag === '' || VOID_ELEMENTS.has(tag)) {
51
+ return null;
52
+ }
53
+ return `$0</${tag}>`;
54
+ }
55
+ i = parsedEnd;
56
+ }
57
+ }
58
+ /**
59
+ * Walks markup tags forward from a region start, returning the name of the
60
+ * opening tag whose `>` lands at `offset` (skipping completed children and
61
+ * expression holes), or null.
62
+ */
63
+ function tagEndingAt(source, start, offset) {
64
+ let i = start;
65
+ while (i < offset) {
66
+ const ch = source[i];
67
+ if (ch === '{') {
68
+ i = skipBalanced(source, i);
69
+ continue;
70
+ }
71
+ if (ch !== '<') {
72
+ i++;
73
+ continue;
74
+ }
75
+ const next = source[i + 1];
76
+ if (next === '/') {
77
+ const gt = source.indexOf('>', i);
78
+ i = gt === -1 ? source.length : gt + 1;
79
+ continue;
80
+ }
81
+ if (next === '>' || isIdentStart(next)) {
82
+ const open = readOpenTag(source, i);
83
+ if (open === null) {
84
+ return null;
85
+ }
86
+ if (open.end === offset) {
87
+ return open.selfClosing ? null : open.tag;
88
+ }
89
+ i = open.end;
90
+ continue;
91
+ }
92
+ i++;
93
+ }
94
+ return null;
95
+ }
96
+ /** Reads a `<...>` opening tag, returning its name, end offset, and self-closing flag. */
97
+ function readOpenTag(source, ltIndex) {
98
+ let i = ltIndex + 1;
99
+ if (source[i] === '>') {
100
+ return { tag: '', end: i + 1, selfClosing: false };
101
+ }
102
+ if (!isIdentStart(source[i])) {
103
+ return null;
104
+ }
105
+ const nameStart = i;
106
+ i++;
107
+ while (i < source.length && (isIdentPart(source[i]) || source[i] === '.' || source[i] === '-')) {
108
+ i++;
109
+ }
110
+ const tag = source.slice(nameStart, i);
111
+ while (i < source.length) {
112
+ const ch = source[i];
113
+ if (isWhitespace(ch)) {
114
+ i++;
115
+ continue;
116
+ }
117
+ if (ch === '>') {
118
+ return { tag, end: i + 1, selfClosing: false };
119
+ }
120
+ if (ch === '/' && source[i + 1] === '>') {
121
+ return { tag, end: i + 2, selfClosing: true };
122
+ }
123
+ if (ch === '{') {
124
+ i = skipBalanced(source, i);
125
+ continue;
126
+ }
127
+ if (ch === '"' || ch === '\'') {
128
+ i = skipString(source, i);
129
+ continue;
130
+ }
131
+ i++;
132
+ }
133
+ return null;
134
+ }
135
+ /**
136
+ * Returns the opening- and closing-tag name ranges for the element under the
137
+ * caret, so the editor can edit them together (linked editing). Null unless the
138
+ * caret is on a tag name of an element that has a matching closing tag.
139
+ */
140
+ export function getLinkedEditingRanges(ctx, offset) {
141
+ for (const node of collectMarkupNodes(ctx.source)) {
142
+ if (node.kind !== 'element' || node.tag === '') {
143
+ continue;
144
+ }
145
+ const ranges = tagNameRanges(ctx, node);
146
+ if (ranges === null) {
147
+ continue;
148
+ }
149
+ const [open, close] = ranges;
150
+ if (within(open, offset) || within(close, offset)) {
151
+ return [ctx.lineIndex.rangeAt(open.start, open.end), ctx.lineIndex.rangeAt(close.start, close.end)];
152
+ }
153
+ }
154
+ return null;
155
+ }
156
+ /** Computes the opening/closing tag-name offset spans for an element, if it has a close tag. */
157
+ function tagNameRanges(ctx, node) {
158
+ const source = ctx.source;
159
+ const openStart = node.start + 1;
160
+ const openEnd = openStart + node.tag.length;
161
+ // A closing tag occupies `</tag>` ending at node.end. Verify it's really there
162
+ // (self-closing elements end with `/>` and have no closing tag).
163
+ const closeEnd = node.end - 1;
164
+ const closeStart = closeEnd - node.tag.length;
165
+ if (closeStart < openEnd
166
+ || source[closeStart - 1] !== '/'
167
+ || source.slice(closeStart, closeEnd) !== node.tag) {
168
+ return null;
169
+ }
170
+ return [{ start: openStart, end: openEnd }, { start: closeStart, end: closeEnd }];
171
+ }
172
+ /** True when `offset` is inside (or touching) `[start, end]`. */
173
+ function within(span, offset) {
174
+ return offset >= span.start && offset <= span.end;
175
+ }
176
+ //# sourceMappingURL=editing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"editing.js","sourceRoot":"","sources":["../../src/providers/editing.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { Hover } from '../protocol.ts';
2
+ import { type RequestContext } from '../request.ts';
3
+ /** Hover content for the caret at `offset`, or null. */
4
+ export declare function getHover(ctx: RequestContext, offset: number): Hover | null;
5
+ //# sourceMappingURL=hover.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hover.d.ts","sourceRoot":"","sources":["../../src/providers/hover.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAK5C,OAAO,EAA4B,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;AAE9E,wDAAwD;AACxD,wBAAgB,QAAQ,CAAC,GAAG,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,GAAG,KAAK,GAAG,IAAI,CAqE1E"}
@@ -0,0 +1,213 @@
1
+ // Hover, routed by caret context:
2
+ // - expression / script / text -> TypeScript quick-info at the mapped offset
3
+ // (authoritative signatures + JSDoc, full type inference);
4
+ // - a built-in component tag/prop -> the framework's documentation table;
5
+ // - a user component tag -> TypeScript quick-info (the tag is mapped 1:1);
6
+ // - a host element tag/attribute/value -> the HTML language service's
7
+ // MDN-backed hover.
8
+ //
9
+ // Context is decided first (not the offset map) so a host tag never shows a
10
+ // stray TS result even when the surrounding markup is mid-edit.
11
+ import ts from 'typescript';
12
+ import { skipBalanced, skipString, skipTemplate, isWhitespace, isIdentPart } from '@azerothjs/compiler';
13
+ import { classifyPosition, enclosingElement } from "../markup-model.js";
14
+ import { BUILTIN_COMPONENT_MAP, attributeDocumentation } from "../language-data.js";
15
+ import { htmlHover, eventDocumentation } from "./html-service.js";
16
+ import { cssHover } from "./css-service.js";
17
+ import { spanToRange, toGenerated } from "../request.js";
18
+ /** Hover content for the caret at `offset`, or null. */
19
+ export function getHover(ctx, offset) {
20
+ const context = classifyPosition(ctx.source, offset);
21
+ const position = ctx.lineIndex.positionAt(offset);
22
+ switch (context.kind) {
23
+ case 'expression':
24
+ case 'script':
25
+ case 'text':
26
+ return tsHover(ctx, offset);
27
+ case 'tagName':
28
+ {
29
+ const name = fullTagName(ctx, offset);
30
+ const builtin = BUILTIN_COMPONENT_MAP.get(name);
31
+ if (builtin) {
32
+ return { contents: `**<${builtin.name}>** — built-in component\n\n${builtin.detail}\n\n${builtin.doc}` };
33
+ }
34
+ return isComponentName(name) ? tsHover(ctx, offset) : htmlHover(ctx.source, position);
35
+ }
36
+ case 'attributeName':
37
+ {
38
+ const attribute = fullAttributeName(ctx, offset);
39
+ // Component prop: read its type/JSDoc from the component's props
40
+ // type, falling back to the built-in table.
41
+ if (isComponentName(context.tag) || BUILTIN_COMPONENT_MAP.has(context.tag)) {
42
+ const typed = typedPropHover(ctx, offset, attribute);
43
+ if (typed) {
44
+ return typed;
45
+ }
46
+ const prop = BUILTIN_COMPONENT_MAP.get(context.tag)?.props.find(candidate => candidate.name === attribute);
47
+ return prop
48
+ ? { contents: `**${prop.name}** — \`<${context.tag}>\` prop${prop.required ? ' (required)' : ''}\n\n${prop.doc}` }
49
+ : null;
50
+ }
51
+ // AzerothJS binds camelCase events; the HTML engine only knows the
52
+ // lowercase form, so look its MDN docs up explicitly.
53
+ if (/^on[A-Z]/.test(attribute)) {
54
+ const doc = eventDocumentation(attribute);
55
+ return { contents: `**${attribute}** — DOM event handler${doc ? `\n\n${doc}` : ''}` };
56
+ }
57
+ // The HTML engine first; fall back to our docs for the common
58
+ // element attributes the standard dataset leaves undocumented.
59
+ const html = htmlHover(ctx.source, position);
60
+ if (html) {
61
+ return html;
62
+ }
63
+ const fallback = attributeDocumentation(attribute);
64
+ return fallback ? { contents: `**${attribute}** — attribute\n\n${fallback}` } : null;
65
+ }
66
+ case 'attributeValue':
67
+ if (isComponentName(context.tag)) {
68
+ return null;
69
+ }
70
+ return context.attribute === 'style'
71
+ ? cssHover(ctx.source, offset, ctx.lineIndex)
72
+ : htmlHover(ctx.source, position);
73
+ }
74
+ }
75
+ /**
76
+ * Hover for a component prop, read from the component's props type (the same
77
+ * generated `Tag({ … })` object literal completion uses). Null when the type
78
+ * can't be resolved.
79
+ */
80
+ function typedPropHover(ctx, offset, prop) {
81
+ const element = enclosingElement(ctx.source, offset);
82
+ if (!element || !element.isComponent) {
83
+ return null;
84
+ }
85
+ const generatedTag = ctx.virtual.mapping.toGenerated(element.start + 1);
86
+ if (generatedTag === null) {
87
+ return null;
88
+ }
89
+ const brace = ctx.virtual.code.indexOf('{', generatedTag + element.tag.length);
90
+ if (brace === -1) {
91
+ return null;
92
+ }
93
+ // Query the type at the generated property key (works whether or not other
94
+ // props are present, unlike completion details which skip filled props).
95
+ const key = propertyKeyOffset(ctx.virtual.code, brace, prop);
96
+ if (key === -1) {
97
+ return null;
98
+ }
99
+ const info = ctx.project.service.getQuickInfoAtPosition(ctx.virtualFile, key);
100
+ if (!info) {
101
+ return null;
102
+ }
103
+ const signature = ts.displayPartsToString(info.displayParts);
104
+ const doc = ts.displayPartsToString(info.documentation);
105
+ if (!signature && !doc) {
106
+ return null;
107
+ }
108
+ return { contents: '```typescript\n' + signature + '\n```' + (doc ? `\n\n${doc}` : '') };
109
+ }
110
+ /**
111
+ * Finds the offset of `prop`'s key inside the generated object literal that
112
+ * starts at `brace`, skipping over each entry's value (which may contain
113
+ * commas, braces, strings). Returns -1 if not present.
114
+ */
115
+ function propertyKeyOffset(code, brace, prop) {
116
+ let i = brace + 1;
117
+ while (i < code.length) {
118
+ while (i < code.length && isWhitespace(code[i])) {
119
+ i++;
120
+ }
121
+ if (code[i] === '}' || i >= code.length) {
122
+ return -1;
123
+ }
124
+ const keyStart = i;
125
+ while (i < code.length && isIdentPart(code[i])) {
126
+ i++;
127
+ }
128
+ if (code.slice(keyStart, i) === prop) {
129
+ return keyStart;
130
+ }
131
+ while (i < code.length && code[i] !== ':' && code[i] !== ',' && code[i] !== '}') {
132
+ i++;
133
+ }
134
+ if (code[i] !== ':') {
135
+ // A spread (`...x`) or malformed entry; advance to the next one.
136
+ i = skipEntryValue(code, i);
137
+ continue;
138
+ }
139
+ i = skipEntryValue(code, i + 1);
140
+ }
141
+ return -1;
142
+ }
143
+ /** Skips an object-literal entry's value, stopping at a top-level `,` or `}`. */
144
+ function skipEntryValue(code, start) {
145
+ let i = start;
146
+ while (i < code.length) {
147
+ const ch = code[i];
148
+ if (ch === ',') {
149
+ return i + 1;
150
+ }
151
+ if (ch === '}') {
152
+ return i;
153
+ }
154
+ if (ch === '"' || ch === '\'') {
155
+ i = skipString(code, i);
156
+ continue;
157
+ }
158
+ if (ch === '`') {
159
+ i = skipTemplate(code, i);
160
+ continue;
161
+ }
162
+ if (ch === '{' || ch === '(' || ch === '[') {
163
+ i = skipBalanced(code, i);
164
+ continue;
165
+ }
166
+ i++;
167
+ }
168
+ return i;
169
+ }
170
+ /** TypeScript quick-info at the mapped offset. */
171
+ function tsHover(ctx, offset) {
172
+ const generated = toGenerated(ctx, offset);
173
+ if (generated === null) {
174
+ return null;
175
+ }
176
+ const info = ctx.project.service.getQuickInfoAtPosition(ctx.virtualFile, generated);
177
+ if (!info) {
178
+ return null;
179
+ }
180
+ const signature = ts.displayPartsToString(info.displayParts);
181
+ const doc = ts.displayPartsToString(info.documentation);
182
+ const contents = '```typescript\n' + signature + '\n```' + (doc ? `\n\n${doc}` : '');
183
+ return { contents, range: spanToRange(ctx, info.textSpan) ?? undefined };
184
+ }
185
+ /** True for a component tag name (PascalCase or dotted). */
186
+ function isComponentName(name) {
187
+ return /^[A-Z]/.test(name) || name.includes('.');
188
+ }
189
+ /** The full tag name under the caret (the model only knows the typed prefix). */
190
+ function fullTagName(ctx, offset) {
191
+ let start = offset;
192
+ while (start > 0 && /[A-Za-z0-9_$.-]/.test(ctx.source[start - 1]) && ctx.source[start - 1] !== '<') {
193
+ start--;
194
+ }
195
+ let end = offset;
196
+ while (end < ctx.source.length && /[A-Za-z0-9_$.-]/.test(ctx.source[end])) {
197
+ end++;
198
+ }
199
+ return ctx.source.slice(start, end);
200
+ }
201
+ /** The full attribute name under the caret. */
202
+ function fullAttributeName(ctx, offset) {
203
+ let start = offset;
204
+ while (start > 0 && /[A-Za-z0-9_$:-]/.test(ctx.source[start - 1])) {
205
+ start--;
206
+ }
207
+ let end = offset;
208
+ while (end < ctx.source.length && /[A-Za-z0-9_$:-]/.test(ctx.source[end])) {
209
+ end++;
210
+ }
211
+ return ctx.source.slice(start, end);
212
+ }
213
+ //# sourceMappingURL=hover.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hover.js","sourceRoot":"","sources":["../../src/providers/hover.ts"],"names":[],"mappings":"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"}