@astrojs/language-server 0.9.3 → 0.12.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.
- package/CHANGELOG.md +22 -0
- package/bin/browserServer.js +3 -0
- package/bin/nodeServer.js +3 -0
- package/dist/browser.d.ts +1 -0
- package/dist/browser.js +8 -0
- package/dist/check.js +2 -5
- package/dist/core/DiagnosticsManager.d.ts +3 -3
- package/dist/core/DiagnosticsManager.js +2 -2
- package/dist/core/config/ConfigManager.d.ts +19 -164
- package/dist/core/config/ConfigManager.js +62 -101
- package/dist/core/config/index.d.ts +1 -0
- package/dist/core/config/index.js +6 -1
- package/dist/core/config/interfaces.d.ts +123 -0
- package/dist/core/config/interfaces.js +2 -0
- package/dist/core/documents/AstroDocument.d.ts +18 -0
- package/dist/core/documents/AstroDocument.js +37 -0
- package/dist/core/documents/DocumentBase.d.ts +10 -2
- package/dist/core/documents/DocumentBase.js +15 -50
- package/dist/core/documents/DocumentManager.d.ts +12 -16
- package/dist/core/documents/DocumentManager.js +32 -26
- package/dist/core/documents/DocumentMapper.js +3 -1
- package/dist/core/documents/index.d.ts +1 -1
- package/dist/core/documents/index.js +6 -2
- package/dist/core/documents/parseAstro.d.ts +2 -2
- package/dist/core/documents/parseHtml.d.ts +2 -2
- package/dist/core/documents/parseHtml.js +4 -1
- package/dist/core/documents/utils.d.ts +22 -26
- package/dist/core/documents/utils.js +96 -134
- package/dist/index.d.ts +0 -1
- package/dist/index.js +1 -3
- package/dist/node.d.ts +1 -0
- package/dist/node.js +29 -0
- package/dist/plugins/PluginHost.d.ts +10 -9
- package/dist/plugins/PluginHost.js +30 -36
- package/dist/plugins/astro/AstroPlugin.d.ts +11 -12
- package/dist/plugins/astro/AstroPlugin.js +17 -38
- package/dist/plugins/astro/features/{CompletionProvider.d.ts → CompletionsProvider.d.ts} +5 -5
- package/dist/plugins/astro/features/{CompletionProvider.js → CompletionsProvider.js} +33 -54
- package/dist/plugins/css/CSSDocument.d.ts +3 -3
- package/dist/plugins/css/CSSDocument.js +7 -16
- package/dist/plugins/css/CSSPlugin.d.ts +22 -12
- package/dist/plugins/css/CSSPlugin.js +112 -41
- package/dist/plugins/css/StyleAttributeDocument.d.ts +2 -2
- package/dist/plugins/css/StyleAttributeDocument.js +2 -2
- package/dist/plugins/css/features/astro-selectors.d.ts +2 -0
- package/dist/plugins/css/features/astro-selectors.js +16 -0
- package/dist/plugins/css/features/{getIdClassCompletion.d.ts → getIdClassCompletions.d.ts} +3 -3
- package/dist/plugins/css/features/{getIdClassCompletion.js → getIdClassCompletions.js} +10 -9
- package/dist/plugins/css/{service.d.ts → language-service.d.ts} +0 -0
- package/dist/plugins/css/{service.js → language-service.js} +2 -1
- package/dist/plugins/html/HTMLPlugin.d.ts +15 -17
- package/dist/plugins/html/HTMLPlugin.js +33 -41
- package/dist/plugins/index.d.ts +2 -2
- package/dist/plugins/index.js +7 -3
- package/dist/plugins/interfaces.d.ts +35 -48
- package/dist/plugins/typescript/LanguageServiceManager.d.ts +33 -14
- package/dist/plugins/typescript/LanguageServiceManager.js +57 -32
- package/dist/plugins/typescript/TypeScriptPlugin.d.ts +16 -23
- package/dist/plugins/typescript/TypeScriptPlugin.js +48 -56
- package/dist/plugins/typescript/astro-sys.d.ts +5 -3
- package/dist/plugins/typescript/astro-sys.js +24 -41
- package/dist/plugins/typescript/features/CompletionsProvider.d.ts +6 -6
- package/dist/plugins/typescript/features/CompletionsProvider.js +17 -33
- package/dist/plugins/typescript/features/DiagnosticsProvider.d.ts +4 -4
- package/dist/plugins/typescript/features/DiagnosticsProvider.js +22 -61
- package/dist/plugins/typescript/features/HoverProvider.d.ts +4 -5
- package/dist/plugins/typescript/features/HoverProvider.js +9 -10
- package/dist/plugins/typescript/features/SignatureHelpProvider.d.ts +4 -5
- package/dist/plugins/typescript/features/SignatureHelpProvider.js +15 -11
- package/dist/plugins/typescript/features/utils.d.ts +1 -12
- package/dist/plugins/typescript/features/utils.js +2 -22
- package/dist/plugins/typescript/language-service.d.ts +38 -0
- package/dist/plugins/typescript/language-service.js +222 -0
- package/dist/plugins/typescript/module-loader.d.ts +5 -8
- package/dist/plugins/typescript/module-loader.js +43 -23
- package/dist/plugins/typescript/{DocumentSnapshot.d.ts → snapshots/DocumentSnapshot.d.ts} +45 -42
- package/dist/plugins/typescript/snapshots/DocumentSnapshot.js +135 -0
- package/dist/plugins/typescript/snapshots/SnapshotManager.d.ts +42 -0
- package/dist/plugins/typescript/snapshots/SnapshotManager.js +197 -0
- package/dist/plugins/typescript/snapshots/utils.d.ts +28 -0
- package/dist/plugins/typescript/snapshots/utils.js +84 -0
- package/dist/plugins/typescript/utils.d.ts +10 -11
- package/dist/plugins/typescript/utils.js +122 -151
- package/dist/server.d.ts +2 -4
- package/dist/server.js +91 -54
- package/dist/utils.d.ts +16 -8
- package/dist/utils.js +29 -14
- package/package.json +19 -13
- package/bin/server.js +0 -7
- package/dist/core/documents/Document.d.ts +0 -51
- package/dist/core/documents/Document.js +0 -135
- package/dist/plugins/typescript/DocumentSnapshot.js +0 -202
- package/dist/plugins/typescript/SnapshotManager.d.ts +0 -24
- package/dist/plugins/typescript/SnapshotManager.js +0 -97
- package/dist/plugins/typescript/languageService.d.ts +0 -17
- package/dist/plugins/typescript/languageService.js +0 -169
- package/types/index.d.ts +0 -4
|
@@ -1,40 +1,22 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var
|
|
3
|
-
|
|
4
|
-
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
-
}) : (function(o, m, k, k2) {
|
|
6
|
-
if (k2 === undefined) k2 = k;
|
|
7
|
-
o[k2] = m[k];
|
|
8
|
-
}));
|
|
9
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
10
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
11
|
-
}) : function(o, v) {
|
|
12
|
-
o["default"] = v;
|
|
13
|
-
});
|
|
14
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
15
|
-
if (mod && mod.__esModule) return mod;
|
|
16
|
-
var result = {};
|
|
17
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
18
|
-
__setModuleDefault(result, mod);
|
|
19
|
-
return result;
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
20
4
|
};
|
|
21
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
6
|
exports.AstroPlugin = void 0;
|
|
7
|
+
const typescript_1 = __importDefault(require("typescript"));
|
|
23
8
|
const vscode_languageserver_1 = require("vscode-languageserver");
|
|
9
|
+
const documents_1 = require("../../core/documents");
|
|
24
10
|
const utils_1 = require("../../utils");
|
|
25
|
-
const utils_2 = require("../typescript/utils");
|
|
26
|
-
const utils_3 = require("../../core/documents/utils");
|
|
27
|
-
const ts = __importStar(require("typescript"));
|
|
28
11
|
const LanguageServiceManager_1 = require("../typescript/LanguageServiceManager");
|
|
29
|
-
const
|
|
30
|
-
const
|
|
31
|
-
const CompletionProvider_1 = require("./features/CompletionProvider");
|
|
12
|
+
const utils_2 = require("../typescript/utils");
|
|
13
|
+
const CompletionsProvider_1 = require("./features/CompletionsProvider");
|
|
32
14
|
class AstroPlugin {
|
|
33
15
|
constructor(docManager, configManager, workspaceUris) {
|
|
34
|
-
this.
|
|
16
|
+
this.__name = 'astro';
|
|
35
17
|
this.configManager = configManager;
|
|
36
|
-
this.
|
|
37
|
-
this.completionProvider = new
|
|
18
|
+
this.languageServiceManager = new LanguageServiceManager_1.LanguageServiceManager(docManager, workspaceUris, configManager);
|
|
19
|
+
this.completionProvider = new CompletionsProvider_1.CompletionsProviderImpl(docManager, this.languageServiceManager);
|
|
38
20
|
}
|
|
39
21
|
async getCompletions(document, position, completionContext) {
|
|
40
22
|
const completions = this.completionProvider.getCompletions(document, position, completionContext);
|
|
@@ -42,7 +24,7 @@ class AstroPlugin {
|
|
|
42
24
|
}
|
|
43
25
|
async getFoldingRanges(document) {
|
|
44
26
|
const foldingRanges = [];
|
|
45
|
-
const { frontmatter } = document.
|
|
27
|
+
const { frontmatter } = document.astroMeta;
|
|
46
28
|
// Currently editing frontmatter, don't fold
|
|
47
29
|
if (frontmatter.state !== 'closed')
|
|
48
30
|
return foldingRanges;
|
|
@@ -54,7 +36,7 @@ class AstroPlugin {
|
|
|
54
36
|
startCharacter: start.character,
|
|
55
37
|
endLine: end.line,
|
|
56
38
|
endCharacter: end.character,
|
|
57
|
-
kind:
|
|
39
|
+
kind: vscode_languageserver_1.FoldingRangeKind.Imports,
|
|
58
40
|
},
|
|
59
41
|
];
|
|
60
42
|
}
|
|
@@ -69,20 +51,20 @@ class AstroPlugin {
|
|
|
69
51
|
return [];
|
|
70
52
|
}
|
|
71
53
|
const [componentName] = node.tag.split(':');
|
|
72
|
-
const { lang } = await this.
|
|
54
|
+
const { lang, tsDoc } = await this.languageServiceManager.getLSAndTSDoc(document);
|
|
73
55
|
const defs = this.getDefinitionsForComponentName(document, lang, componentName);
|
|
74
56
|
if (!defs || !defs.length) {
|
|
75
57
|
return [];
|
|
76
58
|
}
|
|
77
59
|
const startRange = vscode_languageserver_1.Range.create(vscode_languageserver_1.Position.create(0, 0), vscode_languageserver_1.Position.create(0, 0));
|
|
78
60
|
const links = defs.map((def) => {
|
|
79
|
-
const defFilePath = (0,
|
|
61
|
+
const defFilePath = (0, utils_2.ensureRealFilePath)(def.fileName);
|
|
80
62
|
return vscode_languageserver_1.LocationLink.create((0, utils_1.pathToUrl)(defFilePath), startRange, startRange);
|
|
81
63
|
});
|
|
82
64
|
return links;
|
|
83
65
|
}
|
|
84
66
|
isInsideFrontmatter(document, position) {
|
|
85
|
-
return (0,
|
|
67
|
+
return (0, documents_1.isInsideFrontmatter)(document.getText(), document.offsetAt(position));
|
|
86
68
|
}
|
|
87
69
|
isComponentTag(node) {
|
|
88
70
|
if (!node.tag) {
|
|
@@ -111,15 +93,15 @@ class AstroPlugin {
|
|
|
111
93
|
}
|
|
112
94
|
getImportSpecifierForIdentifier(sourceFile, identifier) {
|
|
113
95
|
let importSpecifier = undefined;
|
|
114
|
-
|
|
115
|
-
if (
|
|
96
|
+
typescript_1.default.forEachChild(sourceFile, (tsNode) => {
|
|
97
|
+
if (typescript_1.default.isImportDeclaration(tsNode)) {
|
|
116
98
|
if (tsNode.importClause) {
|
|
117
99
|
const { name, namedBindings } = tsNode.importClause;
|
|
118
100
|
if (name && name.getText() === identifier) {
|
|
119
101
|
importSpecifier = tsNode.moduleSpecifier;
|
|
120
102
|
return true;
|
|
121
103
|
}
|
|
122
|
-
else if (namedBindings && namedBindings.kind ===
|
|
104
|
+
else if (namedBindings && namedBindings.kind === typescript_1.default.SyntaxKind.NamedImports) {
|
|
123
105
|
const elements = namedBindings.elements;
|
|
124
106
|
for (let elem of elements) {
|
|
125
107
|
if (elem.name.getText() === identifier) {
|
|
@@ -135,6 +117,3 @@ class AstroPlugin {
|
|
|
135
117
|
}
|
|
136
118
|
}
|
|
137
119
|
exports.AstroPlugin = AstroPlugin;
|
|
138
|
-
function isNodeExported(node) {
|
|
139
|
-
return (ts.getCombinedModifierFlags(node) & ts.ModifierFlags.Export) !== 0 || (!!node.parent && node.parent.kind === ts.SyntaxKind.SourceFile);
|
|
140
|
-
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import type { AppCompletionList } from '../../interfaces';
|
|
2
|
-
import type {
|
|
2
|
+
import type { AstroDocument, DocumentManager } from '../../../core/documents';
|
|
3
3
|
import { CompletionContext, Position } from 'vscode-languageserver';
|
|
4
4
|
import { LanguageServiceManager as TypeScriptLanguageServiceManager } from '../../typescript/LanguageServiceManager';
|
|
5
|
-
export declare class
|
|
5
|
+
export declare class CompletionsProviderImpl {
|
|
6
6
|
private readonly docManager;
|
|
7
|
-
private readonly
|
|
8
|
-
constructor(docManager: DocumentManager,
|
|
9
|
-
getCompletions(document:
|
|
7
|
+
private readonly languageServiceManager;
|
|
8
|
+
constructor(docManager: DocumentManager, languageServiceManager: TypeScriptLanguageServiceManager);
|
|
9
|
+
getCompletions(document: AstroDocument, position: Position, completionContext?: CompletionContext): Promise<AppCompletionList | null>;
|
|
10
10
|
private getClientHintCompletion;
|
|
11
11
|
private getComponentScriptCompletion;
|
|
12
12
|
private getPropCompletions;
|
|
@@ -1,34 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var
|
|
3
|
-
|
|
4
|
-
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
-
}) : (function(o, m, k, k2) {
|
|
6
|
-
if (k2 === undefined) k2 = k;
|
|
7
|
-
o[k2] = m[k];
|
|
8
|
-
}));
|
|
9
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
10
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
11
|
-
}) : function(o, v) {
|
|
12
|
-
o["default"] = v;
|
|
13
|
-
});
|
|
14
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
15
|
-
if (mod && mod.__esModule) return mod;
|
|
16
|
-
var result = {};
|
|
17
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
18
|
-
__setModuleDefault(result, mod);
|
|
19
|
-
return result;
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
20
4
|
};
|
|
21
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
-
exports.
|
|
6
|
+
exports.CompletionsProviderImpl = void 0;
|
|
23
7
|
const vscode_languageserver_1 = require("vscode-languageserver");
|
|
24
|
-
const
|
|
8
|
+
const typescript_1 = __importDefault(require("typescript"));
|
|
25
9
|
const utils_1 = require("../../../core/documents/utils");
|
|
26
10
|
const utils_2 = require("../../../utils");
|
|
27
11
|
const utils_3 = require("../../typescript/utils");
|
|
28
|
-
class
|
|
29
|
-
constructor(docManager,
|
|
12
|
+
class CompletionsProviderImpl {
|
|
13
|
+
constructor(docManager, languageServiceManager) {
|
|
30
14
|
this.docManager = docManager;
|
|
31
|
-
this.
|
|
15
|
+
this.languageServiceManager = languageServiceManager;
|
|
32
16
|
}
|
|
33
17
|
async getCompletions(document, position, completionContext) {
|
|
34
18
|
const doc = this.docManager.get(document.uri);
|
|
@@ -76,8 +60,8 @@ class CompletionProvider {
|
|
|
76
60
|
{
|
|
77
61
|
label: ':media',
|
|
78
62
|
insertText: 'media',
|
|
79
|
-
commitCharacters: ['m']
|
|
80
|
-
}
|
|
63
|
+
commitCharacters: ['m'],
|
|
64
|
+
},
|
|
81
65
|
];
|
|
82
66
|
}
|
|
83
67
|
getComponentScriptCompletion(document, position, completionContext) {
|
|
@@ -91,18 +75,22 @@ class CompletionProvider {
|
|
|
91
75
|
commitCharacters: ['-'],
|
|
92
76
|
};
|
|
93
77
|
const prefix = document.getLineUntilOffset(document.offsetAt(position));
|
|
94
|
-
if (document.
|
|
78
|
+
if (document.astroMeta.frontmatter.state === null) {
|
|
95
79
|
return {
|
|
96
80
|
...base,
|
|
97
81
|
insertText: '---\n$0\n---',
|
|
98
|
-
textEdit: prefix.match(/^\s*\-+/)
|
|
82
|
+
textEdit: prefix.match(/^\s*\-+/)
|
|
83
|
+
? vscode_languageserver_1.TextEdit.replace({ start: { ...position, character: 0 }, end: position }, '---\n$0\n---')
|
|
84
|
+
: undefined,
|
|
99
85
|
};
|
|
100
86
|
}
|
|
101
|
-
if (document.
|
|
87
|
+
if (document.astroMeta.frontmatter.state === 'open') {
|
|
102
88
|
return {
|
|
103
89
|
...base,
|
|
104
90
|
insertText: '---',
|
|
105
|
-
textEdit: prefix.match(/^\s*\-+/)
|
|
91
|
+
textEdit: prefix.match(/^\s*\-+/)
|
|
92
|
+
? vscode_languageserver_1.TextEdit.replace({ start: { ...position, character: 0 }, end: position }, '---')
|
|
93
|
+
: undefined,
|
|
106
94
|
};
|
|
107
95
|
}
|
|
108
96
|
return null;
|
|
@@ -123,15 +111,17 @@ class CompletionProvider {
|
|
|
123
111
|
return [];
|
|
124
112
|
}
|
|
125
113
|
// If inside of attribute value, skip.
|
|
126
|
-
if (completionContext &&
|
|
114
|
+
if (completionContext &&
|
|
115
|
+
completionContext.triggerKind === vscode_languageserver_1.CompletionTriggerKind.TriggerCharacter &&
|
|
116
|
+
completionContext.triggerCharacter === '"') {
|
|
127
117
|
return [];
|
|
128
118
|
}
|
|
129
119
|
const componentName = node.tag;
|
|
130
|
-
const { lang
|
|
120
|
+
const { lang, tsDoc } = await this.languageServiceManager.getLSAndTSDoc(document);
|
|
131
121
|
// Get the source file
|
|
132
122
|
const filePath = (0, utils_2.urlToPath)(document.uri);
|
|
133
123
|
const tsFilePath = (0, utils_3.toVirtualAstroFilePath)(filePath);
|
|
134
|
-
const program =
|
|
124
|
+
const program = lang.getProgram();
|
|
135
125
|
const sourceFile = program === null || program === void 0 ? void 0 : program.getSourceFile(tsFilePath);
|
|
136
126
|
const typeChecker = program === null || program === void 0 ? void 0 : program.getTypeChecker();
|
|
137
127
|
if (!sourceFile || !typeChecker) {
|
|
@@ -152,14 +142,14 @@ class CompletionProvider {
|
|
|
152
142
|
// Add completions for this types props
|
|
153
143
|
for (let baseType of componentType.getBaseTypes() || []) {
|
|
154
144
|
const members = ((_a = baseType.getSymbol()) === null || _a === void 0 ? void 0 : _a.members) || [];
|
|
155
|
-
members.forEach(mem => {
|
|
145
|
+
members.forEach((mem) => {
|
|
156
146
|
let completionItem = this.getCompletionItemForTypeMember(mem, typeChecker);
|
|
157
147
|
completionItems.push(completionItem);
|
|
158
148
|
});
|
|
159
149
|
}
|
|
160
150
|
// Add completions for this types base members
|
|
161
151
|
const members = ((_b = componentType.getSymbol()) === null || _b === void 0 ? void 0 : _b.members) || [];
|
|
162
|
-
members.forEach(mem => {
|
|
152
|
+
members.forEach((mem) => {
|
|
163
153
|
let completionItem = this.getCompletionItemForTypeMember(mem, typeChecker);
|
|
164
154
|
completionItems.push(completionItem);
|
|
165
155
|
});
|
|
@@ -168,19 +158,20 @@ class CompletionProvider {
|
|
|
168
158
|
getImportedSymbol(sourceFile, identifier) {
|
|
169
159
|
for (let list of sourceFile.getChildren()) {
|
|
170
160
|
for (let node of list.getChildren()) {
|
|
171
|
-
if (
|
|
161
|
+
if (typescript_1.default.isImportDeclaration(node)) {
|
|
172
162
|
let clauses = node.importClause;
|
|
173
163
|
if (!clauses)
|
|
174
164
|
return null;
|
|
175
165
|
let namedImport = clauses.getChildAt(0);
|
|
176
|
-
if (
|
|
177
|
-
for (let imp of namedImport.elements) {
|
|
166
|
+
if (typescript_1.default.isNamedImports(namedImport)) {
|
|
167
|
+
for (let imp of namedImport.elements) {
|
|
168
|
+
// Iterate the named imports
|
|
178
169
|
if (imp.name.getText() === identifier) {
|
|
179
170
|
return imp;
|
|
180
171
|
}
|
|
181
172
|
}
|
|
182
173
|
}
|
|
183
|
-
else if (
|
|
174
|
+
else if (typescript_1.default.isIdentifier(namedImport)) {
|
|
184
175
|
if (namedImport.getText() === identifier) {
|
|
185
176
|
return namedImport;
|
|
186
177
|
}
|
|
@@ -196,21 +187,9 @@ class CompletionProvider {
|
|
|
196
187
|
return null;
|
|
197
188
|
}
|
|
198
189
|
for (const decl of (sym === null || sym === void 0 ? void 0 : sym.getDeclarations()) || []) {
|
|
199
|
-
const fileName = decl.getSourceFile().fileName;
|
|
200
|
-
if ((
|
|
201
|
-
if (!
|
|
202
|
-
console.error(`Unexpected: .astro files should export a default function for the component definition.`);
|
|
203
|
-
continue;
|
|
204
|
-
}
|
|
205
|
-
const fn = decl;
|
|
206
|
-
if (!fn.parameters.length)
|
|
207
|
-
continue;
|
|
208
|
-
const param1 = fn.parameters[0];
|
|
209
|
-
const type = typeChecker.getTypeAtLocation(param1);
|
|
210
|
-
return type;
|
|
211
|
-
}
|
|
212
|
-
else if (fileName.endsWith('.tsx') || fileName.endsWith('.jsx')) {
|
|
213
|
-
if (!ts.isFunctionDeclaration(decl)) {
|
|
190
|
+
const fileName = (0, utils_3.toVirtualFilePath)(decl.getSourceFile().fileName);
|
|
191
|
+
if (fileName.endsWith('.tsx') || fileName.endsWith('.jsx')) {
|
|
192
|
+
if (!typescript_1.default.isFunctionDeclaration(decl)) {
|
|
214
193
|
console.error(`We only support function components for tsx/jsx at the moment.`);
|
|
215
194
|
continue;
|
|
216
195
|
}
|
|
@@ -255,4 +234,4 @@ class CompletionProvider {
|
|
|
255
234
|
return (0, utils_1.isInsideFrontmatter)(document.getText(), document.offsetAt(position));
|
|
256
235
|
}
|
|
257
236
|
}
|
|
258
|
-
exports.
|
|
237
|
+
exports.CompletionsProviderImpl = CompletionsProviderImpl;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Stylesheet, TextDocument } from 'vscode-css-languageservice';
|
|
2
2
|
import { Position } from 'vscode-languageserver';
|
|
3
|
-
import {
|
|
3
|
+
import { AstroDocument, DocumentMapper, ReadableDocument, TagInformation } from '../../core/documents';
|
|
4
4
|
export interface CSSDocumentBase extends DocumentMapper, TextDocument {
|
|
5
5
|
languageId: string;
|
|
6
6
|
stylesheet: Stylesheet;
|
|
@@ -11,7 +11,7 @@ export declare class CSSDocument extends ReadableDocument implements DocumentMap
|
|
|
11
11
|
readonly version: number;
|
|
12
12
|
stylesheet: Stylesheet;
|
|
13
13
|
languageId: string;
|
|
14
|
-
constructor(parent:
|
|
14
|
+
constructor(parent: AstroDocument, styleInfo: Pick<TagInformation, 'attributes' | 'start' | 'end'>);
|
|
15
15
|
/**
|
|
16
16
|
* Get the fragment position relative to the parent
|
|
17
17
|
* @param pos Position in fragment
|
|
@@ -32,7 +32,7 @@ export declare class CSSDocument extends ReadableDocument implements DocumentMap
|
|
|
32
32
|
*/
|
|
33
33
|
getText(): string;
|
|
34
34
|
/**
|
|
35
|
-
* Returns the length of the fragment as calculated from the start and end
|
|
35
|
+
* Returns the length of the fragment as calculated from the start and end position
|
|
36
36
|
*/
|
|
37
37
|
getTextLength(): number;
|
|
38
38
|
/**
|
|
@@ -1,25 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.CSSDocument = void 0;
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
class CSSDocument extends
|
|
7
|
-
constructor(parent) {
|
|
4
|
+
const language_service_1 = require("./language-service");
|
|
5
|
+
const documents_1 = require("../../core/documents");
|
|
6
|
+
class CSSDocument extends documents_1.ReadableDocument {
|
|
7
|
+
constructor(parent, styleInfo) {
|
|
8
8
|
super();
|
|
9
9
|
this.parent = parent;
|
|
10
|
+
this.styleInfo = styleInfo;
|
|
10
11
|
this.version = this.parent.version;
|
|
11
|
-
if (this.parent.styleInfo) {
|
|
12
|
-
this.styleInfo = this.parent.styleInfo;
|
|
13
|
-
}
|
|
14
|
-
else {
|
|
15
|
-
this.styleInfo = {
|
|
16
|
-
attributes: {},
|
|
17
|
-
start: -1,
|
|
18
|
-
end: -1,
|
|
19
|
-
};
|
|
20
|
-
}
|
|
21
12
|
this.languageId = this.language;
|
|
22
|
-
this.stylesheet = (0,
|
|
13
|
+
this.stylesheet = (0, language_service_1.getLanguageService)(this.language).parseStylesheet(this);
|
|
23
14
|
}
|
|
24
15
|
/**
|
|
25
16
|
* Get the fragment position relative to the parent
|
|
@@ -52,7 +43,7 @@ class CSSDocument extends index_1.ReadableDocument {
|
|
|
52
43
|
return this.parent.getText().slice(this.styleInfo.start, this.styleInfo.end);
|
|
53
44
|
}
|
|
54
45
|
/**
|
|
55
|
-
* Returns the length of the fragment as calculated from the start and end
|
|
46
|
+
* Returns the length of the fragment as calculated from the start and end position
|
|
56
47
|
*/
|
|
57
48
|
getTextLength() {
|
|
58
49
|
return this.styleInfo.end - this.styleInfo.start;
|
|
@@ -1,17 +1,27 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
5
|
-
export declare class CSSPlugin implements
|
|
6
|
-
|
|
1
|
+
import { Color, ColorInformation, ColorPresentation, CompletionContext, CompletionList, Position, Range } from 'vscode-languageserver';
|
|
2
|
+
import { ConfigManager } from '../../core/config/ConfigManager';
|
|
3
|
+
import { AstroDocument } from '../../core/documents';
|
|
4
|
+
import type { Plugin } from '../interfaces';
|
|
5
|
+
export declare class CSSPlugin implements Plugin {
|
|
6
|
+
__name: string;
|
|
7
7
|
private configManager;
|
|
8
|
-
private
|
|
8
|
+
private cssDocuments;
|
|
9
9
|
private triggerCharacters;
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
getCompletions(document: Document, position: Position, completionContext?: CompletionContext): CompletionList | null;
|
|
10
|
+
constructor(configManager: ConfigManager);
|
|
11
|
+
getCompletions(document: AstroDocument, position: Position, completionContext?: CompletionContext): CompletionList | null;
|
|
13
12
|
private getCompletionsInternal;
|
|
13
|
+
getDocumentColors(document: AstroDocument): ColorInformation[];
|
|
14
|
+
getColorPresentations(document: AstroDocument, range: Range, color: Color): ColorPresentation[];
|
|
14
15
|
private inStyleAttributeWithoutInterpolation;
|
|
15
|
-
|
|
16
|
-
|
|
16
|
+
/**
|
|
17
|
+
* Get the associated CSS Document for a style tag
|
|
18
|
+
*/
|
|
19
|
+
private getCSSDocumentForStyleTag;
|
|
20
|
+
private getCSSDocumentsForDocument;
|
|
21
|
+
private getStylesheetsForDocument;
|
|
22
|
+
/**
|
|
23
|
+
* Get style tag at position for a document
|
|
24
|
+
*/
|
|
25
|
+
private getStyleTagForPosition;
|
|
26
|
+
private featureEnabled;
|
|
17
27
|
}
|
|
@@ -1,85 +1,156 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.CSSPlugin = void 0;
|
|
4
|
-
const emmet_helper_1 = require("@vscode/emmet-helper");
|
|
5
4
|
const vscode_languageserver_1 = require("vscode-languageserver");
|
|
6
|
-
const utils_1 = require("../../core/documents/utils");
|
|
7
|
-
const CSSDocument_1 = require("./CSSDocument");
|
|
8
|
-
const service_1 = require("./service");
|
|
9
|
-
const StyleAttributeDocument_1 = require("./StyleAttributeDocument");
|
|
10
5
|
const documents_1 = require("../../core/documents");
|
|
6
|
+
const emmet_helper_1 = require("@vscode/emmet-helper");
|
|
7
|
+
const CSSDocument_1 = require("./CSSDocument");
|
|
8
|
+
const language_service_1 = require("./language-service");
|
|
11
9
|
const parseHtml_1 = require("../../core/documents/parseHtml");
|
|
12
|
-
const
|
|
10
|
+
const StyleAttributeDocument_1 = require("./StyleAttributeDocument");
|
|
11
|
+
const getIdClassCompletions_1 = require("./features/getIdClassCompletions");
|
|
12
|
+
const lodash_1 = require("lodash");
|
|
13
13
|
class CSSPlugin {
|
|
14
|
-
constructor(
|
|
15
|
-
this.
|
|
14
|
+
constructor(configManager) {
|
|
15
|
+
this.__name = 'css';
|
|
16
|
+
this.cssDocuments = new WeakMap();
|
|
16
17
|
this.triggerCharacters = new Set(['.', ':', '-', '/']);
|
|
17
|
-
this.pluginName = 'CSS';
|
|
18
|
-
this.docManager = docManager;
|
|
19
18
|
this.configManager = configManager;
|
|
20
|
-
this.docManager.on('documentChange', (document) => {
|
|
21
|
-
this.documents.set(document, new CSSDocument_1.CSSDocument(document));
|
|
22
|
-
});
|
|
23
19
|
}
|
|
24
20
|
getCompletions(document, position, completionContext) {
|
|
21
|
+
if (!this.featureEnabled('completions')) {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
if ((0, documents_1.isInsideFrontmatter)(document.getText(), document.offsetAt(position))) {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
25
27
|
const triggerCharacter = completionContext === null || completionContext === void 0 ? void 0 : completionContext.triggerCharacter;
|
|
26
28
|
const triggerKind = completionContext === null || completionContext === void 0 ? void 0 : completionContext.triggerKind;
|
|
27
29
|
const isCustomTriggerCharacter = triggerKind === vscode_languageserver_1.CompletionTriggerKind.TriggerCharacter;
|
|
28
30
|
if (isCustomTriggerCharacter && triggerCharacter && !this.triggerCharacters.has(triggerCharacter)) {
|
|
29
31
|
return null;
|
|
30
32
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
33
|
+
const styleTag = this.getStyleTagForPosition(document, position);
|
|
34
|
+
// If we don't have a style tag at this position, we might be in a style property instead, let's check
|
|
35
|
+
if (!styleTag) {
|
|
36
|
+
const attributeContext = (0, parseHtml_1.getAttributeContextAtPosition)(document, position);
|
|
37
|
+
if (!attributeContext) {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
if (this.inStyleAttributeWithoutInterpolation(attributeContext, document.getText())) {
|
|
41
|
+
const [start, end] = attributeContext.valueRange;
|
|
42
|
+
return this.getCompletionsInternal(document, position, new StyleAttributeDocument_1.StyleAttributeDocument(document, start, end));
|
|
43
|
+
}
|
|
44
|
+
// If we're not in a style attribute, instead give completions for ids and classes used in the current document
|
|
45
|
+
else if ((attributeContext.name == 'id' || attributeContext.name == 'class') && attributeContext.inValue) {
|
|
46
|
+
const stylesheets = this.getStylesheetsForDocument(document);
|
|
47
|
+
return (0, getIdClassCompletions_1.getIdClassCompletion)(stylesheets, attributeContext);
|
|
48
|
+
}
|
|
40
49
|
return null;
|
|
41
50
|
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
return this.getCompletionsInternal(document, position, new StyleAttributeDocument_1.StyleAttributeDocument(document, start, end));
|
|
45
|
-
}
|
|
46
|
-
else {
|
|
47
|
-
return (0, getIdClassCompletion_1.getIdClassCompletion)(cssDocument, attributeContext);
|
|
48
|
-
}
|
|
51
|
+
const cssDocument = this.getCSSDocumentForStyleTag(styleTag, document);
|
|
52
|
+
return this.getCompletionsInternal(document, position, cssDocument);
|
|
49
53
|
}
|
|
50
54
|
getCompletionsInternal(document, position, cssDocument) {
|
|
51
55
|
if (isSASS(cssDocument)) {
|
|
52
|
-
//
|
|
53
|
-
//
|
|
56
|
+
// The CSS language service does not support SASS (not to be confused with SCSS)
|
|
57
|
+
// however we can at least still at least provide Emmet completions in SASS blocks
|
|
54
58
|
return (0, emmet_helper_1.doComplete)(document, position, 'sass', this.configManager.getEmmetConfig()) || null;
|
|
55
59
|
}
|
|
56
|
-
const
|
|
57
|
-
const
|
|
60
|
+
const cssLang = extractLanguage(cssDocument);
|
|
61
|
+
const langService = (0, language_service_1.getLanguageService)(cssLang);
|
|
58
62
|
const emmetResults = {
|
|
59
63
|
isIncomplete: true,
|
|
60
64
|
items: [],
|
|
61
65
|
};
|
|
62
|
-
const results =
|
|
66
|
+
const results = langService.doComplete(cssDocument, cssDocument.getGeneratedPosition(position), cssDocument.stylesheet);
|
|
63
67
|
return vscode_languageserver_1.CompletionList.create([...(results ? results.items : []), ...emmetResults.items].map((completionItem) => (0, documents_1.mapCompletionItemToOriginal)(cssDocument, completionItem)),
|
|
64
68
|
// Emmet completions change on every keystroke, so they are never complete
|
|
65
69
|
emmetResults.items.length > 0);
|
|
66
70
|
}
|
|
71
|
+
getDocumentColors(document) {
|
|
72
|
+
if (!this.featureEnabled('documentColors')) {
|
|
73
|
+
return [];
|
|
74
|
+
}
|
|
75
|
+
const allColorInfo = this.getCSSDocumentsForDocument(document).map((cssDoc) => {
|
|
76
|
+
const cssLang = extractLanguage(cssDoc);
|
|
77
|
+
const langService = (0, language_service_1.getLanguageService)(cssLang);
|
|
78
|
+
if (shouldExcludeColor(cssLang)) {
|
|
79
|
+
return [];
|
|
80
|
+
}
|
|
81
|
+
return langService
|
|
82
|
+
.findDocumentColors(cssDoc, cssDoc.stylesheet)
|
|
83
|
+
.map((colorInfo) => (0, documents_1.mapObjWithRangeToOriginal)(cssDoc, colorInfo));
|
|
84
|
+
});
|
|
85
|
+
return (0, lodash_1.flatten)(allColorInfo);
|
|
86
|
+
}
|
|
87
|
+
getColorPresentations(document, range, color) {
|
|
88
|
+
if (!this.featureEnabled('colorPresentations')) {
|
|
89
|
+
return [];
|
|
90
|
+
}
|
|
91
|
+
const allColorPres = this.getCSSDocumentsForDocument(document).map((cssDoc) => {
|
|
92
|
+
const cssLang = extractLanguage(cssDoc);
|
|
93
|
+
const langService = (0, language_service_1.getLanguageService)(cssLang);
|
|
94
|
+
if ((!cssDoc.isInGenerated(range.start) && !cssDoc.isInGenerated(range.end)) || shouldExcludeColor(cssLang)) {
|
|
95
|
+
return [];
|
|
96
|
+
}
|
|
97
|
+
return langService
|
|
98
|
+
.getColorPresentations(cssDoc, cssDoc.stylesheet, color, (0, documents_1.mapRangeToGenerated)(cssDoc, range))
|
|
99
|
+
.map((colorPres) => (0, documents_1.mapColorPresentationToOriginal)(cssDoc, colorPres));
|
|
100
|
+
});
|
|
101
|
+
return (0, lodash_1.flatten)(allColorPres);
|
|
102
|
+
}
|
|
67
103
|
inStyleAttributeWithoutInterpolation(attrContext, text) {
|
|
68
|
-
return attrContext.name === 'style' &&
|
|
104
|
+
return (attrContext.name === 'style' &&
|
|
105
|
+
!!attrContext.valueRange &&
|
|
106
|
+
!text.substring(attrContext.valueRange[0], attrContext.valueRange[1]).includes('{'));
|
|
69
107
|
}
|
|
70
|
-
|
|
71
|
-
|
|
108
|
+
/**
|
|
109
|
+
* Get the associated CSS Document for a style tag
|
|
110
|
+
*/
|
|
111
|
+
getCSSDocumentForStyleTag(tag, document) {
|
|
112
|
+
let cssDoc = this.cssDocuments.get(tag);
|
|
72
113
|
if (!cssDoc || cssDoc.version < document.version) {
|
|
73
|
-
cssDoc = new CSSDocument_1.CSSDocument(document);
|
|
74
|
-
this.
|
|
114
|
+
cssDoc = new CSSDocument_1.CSSDocument(document, tag);
|
|
115
|
+
this.cssDocuments.set(tag, cssDoc);
|
|
75
116
|
}
|
|
76
117
|
return cssDoc;
|
|
77
118
|
}
|
|
78
|
-
|
|
79
|
-
return (
|
|
119
|
+
getCSSDocumentsForDocument(document) {
|
|
120
|
+
return document.styleTags.map((tag) => this.getCSSDocumentForStyleTag(tag, document));
|
|
121
|
+
}
|
|
122
|
+
getStylesheetsForDocument(document) {
|
|
123
|
+
return this.getCSSDocumentsForDocument(document).map((cssDoc) => cssDoc.stylesheet);
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Get style tag at position for a document
|
|
127
|
+
*/
|
|
128
|
+
getStyleTagForPosition(document, position) {
|
|
129
|
+
return document.styleTags.find((styleTag) => {
|
|
130
|
+
return (0, documents_1.isInTag)(position, styleTag);
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
featureEnabled(feature) {
|
|
134
|
+
return this.configManager.enabled('css.enabled') && this.configManager.enabled(`css.${feature}.enabled`);
|
|
80
135
|
}
|
|
81
136
|
}
|
|
82
137
|
exports.CSSPlugin = CSSPlugin;
|
|
138
|
+
/**
|
|
139
|
+
* Exclude certain language when getting colors
|
|
140
|
+
* The CSS language service only supports CSS, LESS and SCSS,
|
|
141
|
+
* which mean that we cannot support colors in other languages
|
|
142
|
+
*/
|
|
143
|
+
function shouldExcludeColor(document) {
|
|
144
|
+
const language = typeof document === 'string' ? document : extractLanguage(document);
|
|
145
|
+
switch (language) {
|
|
146
|
+
case 'sass':
|
|
147
|
+
case 'stylus':
|
|
148
|
+
case 'styl':
|
|
149
|
+
return true;
|
|
150
|
+
default:
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
83
154
|
function isSASS(document) {
|
|
84
155
|
switch (extractLanguage(document)) {
|
|
85
156
|
case 'sass':
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Stylesheet } from 'vscode-css-languageservice';
|
|
2
2
|
import { Position } from 'vscode-languageserver';
|
|
3
|
-
import {
|
|
3
|
+
import { AstroDocument, DocumentMapper, ReadableDocument } from '../../core/documents';
|
|
4
4
|
export declare class StyleAttributeDocument extends ReadableDocument implements DocumentMapper {
|
|
5
5
|
private readonly parent;
|
|
6
6
|
private readonly attrStart;
|
|
@@ -8,7 +8,7 @@ export declare class StyleAttributeDocument extends ReadableDocument implements
|
|
|
8
8
|
readonly version: number;
|
|
9
9
|
stylesheet: Stylesheet;
|
|
10
10
|
languageId: string;
|
|
11
|
-
constructor(parent:
|
|
11
|
+
constructor(parent: AstroDocument, attrStart: number, attrEnd: number);
|
|
12
12
|
/**
|
|
13
13
|
* Get the fragment position relative to the parent
|
|
14
14
|
* @param pos Position in fragment
|