@coherent.js/language-server 1.0.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 (43) hide show
  1. package/LICENSE +21 -0
  2. package/dist/analysis/coherent-analyzer.d.ts +93 -0
  3. package/dist/analysis/coherent-analyzer.d.ts.map +1 -0
  4. package/dist/analysis/coherent-analyzer.js +288 -0
  5. package/dist/analysis/coherent-analyzer.js.map +1 -0
  6. package/dist/analysis/element-validator.d.ts +45 -0
  7. package/dist/analysis/element-validator.d.ts.map +1 -0
  8. package/dist/analysis/element-validator.js +84 -0
  9. package/dist/analysis/element-validator.js.map +1 -0
  10. package/dist/analysis/nesting-validator.d.ts +49 -0
  11. package/dist/analysis/nesting-validator.d.ts.map +1 -0
  12. package/dist/analysis/nesting-validator.js +68 -0
  13. package/dist/analysis/nesting-validator.js.map +1 -0
  14. package/dist/data/element-attributes.d.ts +92 -0
  15. package/dist/data/element-attributes.d.ts.map +1 -0
  16. package/dist/data/element-attributes.generated.json +7085 -0
  17. package/dist/data/element-attributes.js +282 -0
  18. package/dist/data/element-attributes.js.map +1 -0
  19. package/dist/data/nesting-rules.d.ts +67 -0
  20. package/dist/data/nesting-rules.d.ts.map +1 -0
  21. package/dist/data/nesting-rules.js +240 -0
  22. package/dist/data/nesting-rules.js.map +1 -0
  23. package/dist/providers/code-actions.d.ts +15 -0
  24. package/dist/providers/code-actions.d.ts.map +1 -0
  25. package/dist/providers/code-actions.js +191 -0
  26. package/dist/providers/code-actions.js.map +1 -0
  27. package/dist/providers/completion.d.ts +15 -0
  28. package/dist/providers/completion.d.ts.map +1 -0
  29. package/dist/providers/completion.js +247 -0
  30. package/dist/providers/completion.js.map +1 -0
  31. package/dist/providers/diagnostics.d.ts +26 -0
  32. package/dist/providers/diagnostics.d.ts.map +1 -0
  33. package/dist/providers/diagnostics.js +143 -0
  34. package/dist/providers/diagnostics.js.map +1 -0
  35. package/dist/providers/hover.d.ts +15 -0
  36. package/dist/providers/hover.d.ts.map +1 -0
  37. package/dist/providers/hover.js +215 -0
  38. package/dist/providers/hover.js.map +1 -0
  39. package/dist/server.d.ts +17 -0
  40. package/dist/server.d.ts.map +1 -0
  41. package/dist/server.js +82 -0
  42. package/dist/server.js.map +1 -0
  43. package/package.json +53 -0
@@ -0,0 +1,191 @@
1
+ /**
2
+ * Code Action Provider
3
+ *
4
+ * Provides quick fix code actions for validation errors.
5
+ */
6
+ import { CodeActionKind, TextEdit, } from 'vscode-languageserver';
7
+ /**
8
+ * Register the code action provider.
9
+ *
10
+ * @param connection - LSP connection
11
+ * @param documents - Text document manager
12
+ */
13
+ export function registerCodeActionProvider(connection, documents) {
14
+ connection.onCodeAction((params) => {
15
+ const document = documents.get(params.textDocument.uri);
16
+ if (!document) {
17
+ return [];
18
+ }
19
+ const actions = [];
20
+ for (const diagnostic of params.context.diagnostics) {
21
+ // Only process diagnostics from our language server
22
+ if (diagnostic.source !== 'coherent') {
23
+ continue;
24
+ }
25
+ const codeActions = getCodeActionsForDiagnostic(diagnostic, document, params);
26
+ actions.push(...codeActions);
27
+ }
28
+ return actions;
29
+ });
30
+ }
31
+ /**
32
+ * Get code actions for a specific diagnostic.
33
+ */
34
+ function getCodeActionsForDiagnostic(diagnostic, document, params) {
35
+ const actions = [];
36
+ const uri = params.textDocument.uri;
37
+ switch (diagnostic.code) {
38
+ case 'typo-attribute': {
39
+ // Get suggestion from diagnostic data
40
+ const suggestion = diagnostic.data?.suggestion;
41
+ if (suggestion) {
42
+ actions.push({
43
+ title: `Change to '${suggestion}'`,
44
+ kind: CodeActionKind.QuickFix,
45
+ diagnostics: [diagnostic],
46
+ isPreferred: true,
47
+ edit: {
48
+ changes: {
49
+ [uri]: [
50
+ TextEdit.replace(diagnostic.range, suggestion),
51
+ ],
52
+ },
53
+ },
54
+ });
55
+ }
56
+ // Also offer to remove the attribute
57
+ actions.push(createRemoveAttributeAction(diagnostic, uri, document));
58
+ break;
59
+ }
60
+ case 'invalid-attribute': {
61
+ // Offer to remove the invalid attribute
62
+ actions.push(createRemoveAttributeAction(diagnostic, uri, document));
63
+ break;
64
+ }
65
+ case 'void-children': {
66
+ // Offer to remove the children property
67
+ const removeAction = createRemovePropertyAction(diagnostic, uri, document, 'Remove children property', 'children');
68
+ if (removeAction) {
69
+ actions.push(removeAction);
70
+ }
71
+ break;
72
+ }
73
+ case 'invalid-nesting':
74
+ case 'invalid-parent':
75
+ case 'block-in-inline':
76
+ case 'invalid-child': {
77
+ // For nesting errors, we can't easily auto-fix, but we can provide documentation
78
+ actions.push({
79
+ title: 'Learn about HTML nesting rules',
80
+ kind: CodeActionKind.QuickFix,
81
+ diagnostics: [diagnostic],
82
+ command: {
83
+ title: 'Open HTML nesting documentation',
84
+ command: 'coherent.openNestingDocs',
85
+ arguments: [diagnostic.data],
86
+ },
87
+ });
88
+ break;
89
+ }
90
+ }
91
+ return actions;
92
+ }
93
+ /**
94
+ * Create a code action to remove an invalid attribute.
95
+ */
96
+ function createRemoveAttributeAction(diagnostic, uri, document) {
97
+ // Find the full property (including value and trailing comma)
98
+ const range = expandRangeToFullProperty(diagnostic.range, document);
99
+ return {
100
+ title: 'Remove invalid attribute',
101
+ kind: CodeActionKind.QuickFix,
102
+ diagnostics: [diagnostic],
103
+ edit: {
104
+ changes: {
105
+ [uri]: [TextEdit.del(range)],
106
+ },
107
+ },
108
+ };
109
+ }
110
+ /**
111
+ * Create a code action to remove a specific property.
112
+ */
113
+ function createRemovePropertyAction(diagnostic, uri, document, title, _propertyName) {
114
+ // Find the full property line
115
+ const range = expandRangeToFullProperty(diagnostic.range, document);
116
+ return {
117
+ title,
118
+ kind: CodeActionKind.QuickFix,
119
+ diagnostics: [diagnostic],
120
+ edit: {
121
+ changes: {
122
+ [uri]: [TextEdit.del(range)],
123
+ },
124
+ },
125
+ };
126
+ }
127
+ /**
128
+ * Expand a range to include the full property assignment and trailing comma.
129
+ *
130
+ * This ensures clean removal without leaving orphan commas or whitespace.
131
+ */
132
+ function expandRangeToFullProperty(range, document) {
133
+ const text = document.getText();
134
+ const startOffset = document.offsetAt(range.start);
135
+ const endOffset = document.offsetAt(range.end);
136
+ // Find start of the line (for property removal)
137
+ let newStart = startOffset;
138
+ while (newStart > 0 && text[newStart - 1] !== '\n') {
139
+ newStart--;
140
+ }
141
+ // Find end of the property (including : and value)
142
+ let newEnd = endOffset;
143
+ // Skip to end of value
144
+ let depth = 0;
145
+ let inString = false;
146
+ let stringChar = '';
147
+ while (newEnd < text.length) {
148
+ const char = text[newEnd];
149
+ // Handle string literals
150
+ if ((char === '"' || char === "'") && text[newEnd - 1] !== '\\') {
151
+ if (!inString) {
152
+ inString = true;
153
+ stringChar = char;
154
+ }
155
+ else if (char === stringChar) {
156
+ inString = false;
157
+ }
158
+ }
159
+ if (!inString) {
160
+ // Track nesting depth
161
+ if (char === '{' || char === '[' || char === '(') {
162
+ depth++;
163
+ }
164
+ else if (char === '}' || char === ']' || char === ')') {
165
+ if (depth === 0)
166
+ break;
167
+ depth--;
168
+ }
169
+ else if (depth === 0 && char === ',') {
170
+ newEnd++; // Include the comma
171
+ break;
172
+ }
173
+ else if (depth === 0 && (char === '\n' || char === '\r')) {
174
+ break;
175
+ }
176
+ }
177
+ newEnd++;
178
+ }
179
+ // Skip trailing whitespace and newline
180
+ while (newEnd < text.length && (text[newEnd] === ' ' || text[newEnd] === '\t')) {
181
+ newEnd++;
182
+ }
183
+ if (newEnd < text.length && text[newEnd] === '\n') {
184
+ newEnd++;
185
+ }
186
+ return {
187
+ start: document.positionAt(newStart),
188
+ end: document.positionAt(newEnd),
189
+ };
190
+ }
191
+ //# sourceMappingURL=code-actions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"code-actions.js","sourceRoot":"","sources":["../../src/providers/code-actions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Completion Provider
3
+ *
4
+ * Provides autocomplete suggestions for Coherent.js elements and attributes.
5
+ */
6
+ import { Connection, TextDocuments } from 'vscode-languageserver';
7
+ import { TextDocument } from 'vscode-languageserver-textdocument';
8
+ /**
9
+ * Register the completion provider.
10
+ *
11
+ * @param connection - LSP connection
12
+ * @param documents - Text document manager
13
+ */
14
+ export declare function registerCompletionProvider(connection: Connection, documents: TextDocuments<TextDocument>): void;
15
+ //# sourceMappingURL=completion.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"completion.d.ts","sourceRoot":"","sources":["../../src/providers/completion.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,UAAU,EACV,aAAa,EAMd,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAalE;;;;;GAKG;AACH,wBAAgB,0BAA0B,CACxC,UAAU,EAAE,UAAU,EACtB,SAAS,EAAE,aAAa,CAAC,YAAY,CAAC,GACrC,IAAI,CAkEN"}
@@ -0,0 +1,247 @@
1
+ /**
2
+ * Completion Provider
3
+ *
4
+ * Provides autocomplete suggestions for Coherent.js elements and attributes.
5
+ */
6
+ import { CompletionItemKind, InsertTextFormat, } from 'vscode-languageserver';
7
+ import { createSourceFile, getPositionContext, } from '../analysis/coherent-analyzer.js';
8
+ import { HTML_ELEMENTS, getAttributesForElement, getElementDescription, getAttributeDescription, isVoidElement, } from '../data/element-attributes.js';
9
+ /**
10
+ * Register the completion provider.
11
+ *
12
+ * @param connection - LSP connection
13
+ * @param documents - Text document manager
14
+ */
15
+ export function registerCompletionProvider(connection, documents) {
16
+ // Handle completion requests
17
+ connection.onCompletion((params) => {
18
+ const document = documents.get(params.textDocument.uri);
19
+ if (!document) {
20
+ return [];
21
+ }
22
+ try {
23
+ const content = document.getText();
24
+ const sourceFile = createSourceFile(content, params.textDocument.uri);
25
+ const context = getPositionContext(sourceFile, params.position);
26
+ switch (context.type) {
27
+ case 'tag-name':
28
+ return getTagNameCompletions();
29
+ case 'attribute-name':
30
+ if (context.element) {
31
+ return getAttributeCompletions(context.element.tagName);
32
+ }
33
+ return [];
34
+ case 'children':
35
+ return getChildCompletions();
36
+ case 'attribute-value':
37
+ // Future: could provide value suggestions for specific attributes
38
+ return [];
39
+ case 'outside':
40
+ // When outside any element, suggest starting an element
41
+ return getElementStartCompletions();
42
+ default:
43
+ return [];
44
+ }
45
+ }
46
+ catch (error) {
47
+ console.error('[coherent-lsp] Completion error:', error);
48
+ return [];
49
+ }
50
+ });
51
+ // Handle completion item resolve for additional detail
52
+ connection.onCompletionResolve((item) => {
53
+ // Add documentation on resolve
54
+ if (item.data?.type === 'tag') {
55
+ const tagName = item.label;
56
+ item.documentation = {
57
+ kind: 'markdown',
58
+ value: getElementDescription(tagName) + '\n\n' + getElementDocumentation(tagName),
59
+ };
60
+ }
61
+ else if (item.data?.type === 'attribute' && item.data?.tagName) {
62
+ const attrName = item.label;
63
+ const tagName = item.data.tagName;
64
+ const description = getAttributeDescription(tagName, attrName);
65
+ if (description) {
66
+ item.documentation = {
67
+ kind: 'markdown',
68
+ value: description,
69
+ };
70
+ }
71
+ }
72
+ return item;
73
+ });
74
+ }
75
+ /**
76
+ * Get completions for HTML tag names.
77
+ */
78
+ function getTagNameCompletions() {
79
+ const items = [];
80
+ // Sort elements by common usage
81
+ const commonElements = [
82
+ 'div', 'span', 'p', 'a', 'button', 'input', 'img', 'form',
83
+ 'ul', 'ol', 'li', 'h1', 'h2', 'h3', 'section', 'article',
84
+ ];
85
+ for (const tagName of commonElements) {
86
+ if (HTML_ELEMENTS.has(tagName)) {
87
+ items.push(createTagCompletion(tagName, true));
88
+ }
89
+ }
90
+ // Add remaining elements
91
+ for (const tagName of HTML_ELEMENTS) {
92
+ if (!commonElements.includes(tagName)) {
93
+ items.push(createTagCompletion(tagName, false));
94
+ }
95
+ }
96
+ return items;
97
+ }
98
+ /**
99
+ * Create a completion item for a tag name.
100
+ */
101
+ function createTagCompletion(tagName, isCommon) {
102
+ return {
103
+ label: tagName,
104
+ kind: CompletionItemKind.Class,
105
+ detail: isVoidElement(tagName) ? `<${tagName}/> (void element)` : `<${tagName}>`,
106
+ sortText: isCommon ? `0${tagName}` : `1${tagName}`,
107
+ data: { type: 'tag', tagName },
108
+ };
109
+ }
110
+ /**
111
+ * Get completions for attributes on a specific element.
112
+ */
113
+ function getAttributeCompletions(tagName) {
114
+ const attributes = getAttributesForElement(tagName);
115
+ const items = [];
116
+ // Common attributes first
117
+ const commonAttrs = ['className', 'id', 'onClick', 'style', 'children', 'text'];
118
+ for (const attr of attributes) {
119
+ const isCommon = commonAttrs.includes(attr.name);
120
+ items.push({
121
+ label: attr.name,
122
+ kind: CompletionItemKind.Property,
123
+ detail: formatType(attr.type),
124
+ sortText: isCommon ? `0${attr.name}` : `1${attr.name}`,
125
+ insertText: getAttributeInsertText(attr.name, attr.type),
126
+ insertTextFormat: InsertTextFormat.Snippet,
127
+ data: { type: 'attribute', tagName, attributeName: attr.name },
128
+ });
129
+ }
130
+ return items;
131
+ }
132
+ /**
133
+ * Get insert text for an attribute with appropriate value placeholder.
134
+ */
135
+ function getAttributeInsertText(name, type) {
136
+ // Boolean attributes
137
+ if (type === 'boolean') {
138
+ return `${name}: \${1|true,false|}`;
139
+ }
140
+ // String attributes
141
+ if (type === 'string' || type.includes('string')) {
142
+ return `${name}: '\${1}'`;
143
+ }
144
+ // Number attributes
145
+ if (type === 'number') {
146
+ return `${name}: \${1:0}`;
147
+ }
148
+ // Event handlers
149
+ if (name.startsWith('on') && name[2] === name[2].toUpperCase()) {
150
+ return `${name}: () => {\n \${1}\n}`;
151
+ }
152
+ // Children array
153
+ if (name === 'children') {
154
+ return `${name}: [\n \${1}\n]`;
155
+ }
156
+ // Style object
157
+ if (name === 'style') {
158
+ return `${name}: {\n \${1}\n}`;
159
+ }
160
+ // Default
161
+ return `${name}: \${1}`;
162
+ }
163
+ /**
164
+ * Format type for display.
165
+ */
166
+ function formatType(type) {
167
+ // Simplify complex types for display
168
+ if (type.length > 50) {
169
+ return type.substring(0, 47) + '...';
170
+ }
171
+ return type;
172
+ }
173
+ /**
174
+ * Get completions for starting a child element.
175
+ */
176
+ function getChildCompletions() {
177
+ const items = [];
178
+ // Suggest opening an element
179
+ items.push({
180
+ label: '{ element }',
181
+ kind: CompletionItemKind.Snippet,
182
+ detail: 'Create a child element',
183
+ insertText: '{ ${1:div}: { ${2} } }',
184
+ insertTextFormat: InsertTextFormat.Snippet,
185
+ sortText: '0element',
186
+ });
187
+ // Common child elements
188
+ const commonChildren = ['div', 'span', 'p', 'a', 'button', 'li'];
189
+ for (const tagName of commonChildren) {
190
+ items.push({
191
+ label: `{ ${tagName}: {} }`,
192
+ kind: CompletionItemKind.Snippet,
193
+ detail: `Create a <${tagName}> child`,
194
+ insertText: `{ ${tagName}: { \${1} } }`,
195
+ insertTextFormat: InsertTextFormat.Snippet,
196
+ sortText: `1${tagName}`,
197
+ });
198
+ }
199
+ return items;
200
+ }
201
+ /**
202
+ * Get completions for starting an element (outside any existing element).
203
+ */
204
+ function getElementStartCompletions() {
205
+ const items = [];
206
+ // Coherent element snippet
207
+ items.push({
208
+ label: 'coherent-element',
209
+ kind: CompletionItemKind.Snippet,
210
+ detail: 'Create a Coherent.js element',
211
+ insertText: '{\n ${1:div}: {\n ${2:className}: \'${3}\',\n ${4:children}: [${5}]\n }\n}',
212
+ insertTextFormat: InsertTextFormat.Snippet,
213
+ sortText: '0coherent',
214
+ });
215
+ // Coherent component snippet
216
+ items.push({
217
+ label: 'coherent-component',
218
+ kind: CompletionItemKind.Snippet,
219
+ detail: 'Create a Coherent.js component function',
220
+ insertText: 'function ${1:ComponentName}(${2:props}) {\n return {\n ${3:div}: {\n className: \'${4:component}\',\n children: [${5}]\n }\n };\n}',
221
+ insertTextFormat: InsertTextFormat.Snippet,
222
+ sortText: '0component',
223
+ });
224
+ return items;
225
+ }
226
+ /**
227
+ * Get detailed documentation for an element.
228
+ */
229
+ function getElementDocumentation(tagName) {
230
+ const attrs = getAttributesForElement(tagName);
231
+ const isVoid = isVoidElement(tagName);
232
+ let doc = `### Example\n\`\`\`javascript\n`;
233
+ if (isVoid) {
234
+ doc += `{ ${tagName}: { /* attributes */ } }\n`;
235
+ }
236
+ else {
237
+ doc += `{ ${tagName}: {\n className: 'example',\n children: [/* elements */]\n} }\n`;
238
+ }
239
+ doc += `\`\`\`\n\n`;
240
+ // List some common attributes
241
+ const commonAttrs = attrs.slice(0, 5).map(a => `- \`${a.name}\`: ${a.type}`).join('\n');
242
+ if (commonAttrs) {
243
+ doc += `### Common Attributes\n${commonAttrs}\n`;
244
+ }
245
+ return doc;
246
+ }
247
+ //# sourceMappingURL=completion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"completion.js","sourceRoot":"","sources":["../../src/providers/completion.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Diagnostics Provider
3
+ *
4
+ * Validates documents and publishes diagnostics (errors/warnings)
5
+ * to the LSP client for display in the IDE.
6
+ */
7
+ import { Connection, TextDocuments, Diagnostic } from 'vscode-languageserver';
8
+ import { TextDocument } from 'vscode-languageserver-textdocument';
9
+ /**
10
+ * Validate a single document and return diagnostics.
11
+ *
12
+ * @param document - Text document to validate
13
+ * @returns Array of diagnostics
14
+ */
15
+ export declare function validateDocument(document: TextDocument): Diagnostic[];
16
+ /**
17
+ * Register the diagnostics provider.
18
+ *
19
+ * Sets up document change listeners to trigger validation
20
+ * with debouncing.
21
+ *
22
+ * @param connection - LSP connection
23
+ * @param documents - Text document manager
24
+ */
25
+ export declare function registerDiagnosticProvider(connection: Connection, documents: TextDocuments<TextDocument>): void;
26
+ //# sourceMappingURL=diagnostics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostics.d.ts","sourceRoot":"","sources":["../../src/providers/diagnostics.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,UAAU,EACV,aAAa,EACb,UAAU,EAEX,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AA+ClE;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,YAAY,GAAG,UAAU,EAAE,CA4CrE;AAED;;;;;;;;GAQG;AACH,wBAAgB,0BAA0B,CACxC,UAAU,EAAE,UAAU,EACtB,SAAS,EAAE,aAAa,CAAC,YAAY,CAAC,GACrC,IAAI,CAuBN"}
@@ -0,0 +1,143 @@
1
+ /**
2
+ * Diagnostics Provider
3
+ *
4
+ * Validates documents and publishes diagnostics (errors/warnings)
5
+ * to the LSP client for display in the IDE.
6
+ */
7
+ import { DiagnosticSeverity, } from 'vscode-languageserver';
8
+ import { findCoherentElements, createSourceFile } from '../analysis/coherent-analyzer.js';
9
+ import { validateAllAttributes } from '../analysis/element-validator.js';
10
+ import { validateAllNesting } from '../analysis/nesting-validator.js';
11
+ /**
12
+ * Debounce timeout for validation (ms).
13
+ * Prevents excessive validation during rapid typing.
14
+ */
15
+ const VALIDATION_DEBOUNCE_MS = 300;
16
+ /**
17
+ * Map of document URIs to debounce timers.
18
+ */
19
+ const validationTimers = new Map();
20
+ /**
21
+ * Convert an attribute validation error to an LSP diagnostic.
22
+ */
23
+ function attributeErrorToDiagnostic(error) {
24
+ return {
25
+ severity: error.severity === 'error' ? DiagnosticSeverity.Error : DiagnosticSeverity.Warning,
26
+ range: error.range,
27
+ message: error.message,
28
+ source: 'coherent',
29
+ code: error.code,
30
+ data: {
31
+ ...error.data,
32
+ suggestion: error.suggestion,
33
+ },
34
+ };
35
+ }
36
+ /**
37
+ * Convert a nesting validation error to an LSP diagnostic.
38
+ */
39
+ function nestingErrorToDiagnostic(error) {
40
+ return {
41
+ severity: error.severity === 'error' ? DiagnosticSeverity.Error : DiagnosticSeverity.Warning,
42
+ range: error.range,
43
+ message: error.message,
44
+ source: 'coherent',
45
+ code: error.code,
46
+ data: error.data,
47
+ };
48
+ }
49
+ /**
50
+ * Validate a single document and return diagnostics.
51
+ *
52
+ * @param document - Text document to validate
53
+ * @returns Array of diagnostics
54
+ */
55
+ export function validateDocument(document) {
56
+ const diagnostics = [];
57
+ try {
58
+ const content = document.getText();
59
+ const uri = document.uri;
60
+ // Determine file type for proper parsing
61
+ const isTypeScript = uri.endsWith('.ts') || uri.endsWith('.tsx');
62
+ const isJavaScript = uri.endsWith('.js') || uri.endsWith('.jsx') || uri.endsWith('.mjs');
63
+ // Skip non-JS/TS files
64
+ if (!isTypeScript && !isJavaScript) {
65
+ return diagnostics;
66
+ }
67
+ // Parse the document
68
+ const sourceFile = createSourceFile(content, uri);
69
+ // Find all Coherent elements
70
+ const elements = findCoherentElements(sourceFile);
71
+ if (elements.length === 0) {
72
+ // No Coherent elements found, nothing to validate
73
+ return diagnostics;
74
+ }
75
+ // Validate attributes
76
+ const attributeErrors = validateAllAttributes(elements);
77
+ for (const error of attributeErrors) {
78
+ diagnostics.push(attributeErrorToDiagnostic(error));
79
+ }
80
+ // Validate nesting
81
+ const nestingErrors = validateAllNesting(elements);
82
+ for (const error of nestingErrors) {
83
+ diagnostics.push(nestingErrorToDiagnostic(error));
84
+ }
85
+ }
86
+ catch (error) {
87
+ // Log error but don't crash - malformed documents are expected during editing
88
+ console.error('[coherent-lsp] Validation error:', error);
89
+ }
90
+ return diagnostics;
91
+ }
92
+ /**
93
+ * Register the diagnostics provider.
94
+ *
95
+ * Sets up document change listeners to trigger validation
96
+ * with debouncing.
97
+ *
98
+ * @param connection - LSP connection
99
+ * @param documents - Text document manager
100
+ */
101
+ export function registerDiagnosticProvider(connection, documents) {
102
+ // Validate on document open
103
+ documents.onDidOpen((event) => {
104
+ scheduleValidation(connection, event.document);
105
+ });
106
+ // Validate on document change (debounced)
107
+ documents.onDidChangeContent((event) => {
108
+ scheduleValidation(connection, event.document);
109
+ });
110
+ // Clear diagnostics when document closes
111
+ documents.onDidClose((event) => {
112
+ // Cancel any pending validation
113
+ const timer = validationTimers.get(event.document.uri);
114
+ if (timer) {
115
+ clearTimeout(timer);
116
+ validationTimers.delete(event.document.uri);
117
+ }
118
+ // Clear diagnostics
119
+ connection.sendDiagnostics({ uri: event.document.uri, diagnostics: [] });
120
+ });
121
+ }
122
+ /**
123
+ * Schedule document validation with debouncing.
124
+ *
125
+ * @param connection - LSP connection
126
+ * @param document - Document to validate
127
+ */
128
+ function scheduleValidation(connection, document) {
129
+ const uri = document.uri;
130
+ // Cancel existing timer
131
+ const existingTimer = validationTimers.get(uri);
132
+ if (existingTimer) {
133
+ clearTimeout(existingTimer);
134
+ }
135
+ // Schedule new validation
136
+ const timer = setTimeout(() => {
137
+ validationTimers.delete(uri);
138
+ const diagnostics = validateDocument(document);
139
+ connection.sendDiagnostics({ uri, diagnostics });
140
+ }, VALIDATION_DEBOUNCE_MS);
141
+ validationTimers.set(uri, timer);
142
+ }
143
+ //# 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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"}