🎉 initiate project *astro_rewrite*
This commit is contained in:
		
							parent
							
								
									ffd4d5e86c
								
							
						
					
					
						commit
						2ba37bfbe3
					
				
					 8658 changed files with 2268794 additions and 2538 deletions
				
			
		
							
								
								
									
										17
									
								
								node_modules/@astrojs/language-server/dist/plugins/astro/features/CompletionsProvider.d.ts
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								node_modules/@astrojs/language-server/dist/plugins/astro/features/CompletionsProvider.d.ts
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,17 @@ | |||
| import { CompletionContext, Position } from 'vscode-languageserver'; | ||||
| import type { AstroDocument } from '../../../core/documents'; | ||||
| import type { AppCompletionList, CompletionsProvider } from '../../interfaces'; | ||||
| import type { LanguageServiceManager } from '../../typescript/LanguageServiceManager'; | ||||
| export declare class CompletionsProviderImpl implements CompletionsProvider { | ||||
|     private readonly languageServiceManager; | ||||
|     private readonly ts; | ||||
|     private lastCompletion; | ||||
|     directivesHTMLLang: import("vscode-html-languageservice").LanguageService; | ||||
|     constructor(languageServiceManager: LanguageServiceManager); | ||||
|     getCompletions(document: AstroDocument, position: Position, completionContext?: CompletionContext): Promise<AppCompletionList | null>; | ||||
|     private getComponentScriptCompletion; | ||||
|     private getPropCompletionsAndFilePath; | ||||
|     private getImportedSymbol; | ||||
|     private getPropType; | ||||
|     private getCompletionItemForProperty; | ||||
| } | ||||
							
								
								
									
										242
									
								
								node_modules/@astrojs/language-server/dist/plugins/astro/features/CompletionsProvider.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										242
									
								
								node_modules/@astrojs/language-server/dist/plugins/astro/features/CompletionsProvider.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,242 @@ | |||
| "use strict"; | ||||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||||
| exports.CompletionsProviderImpl = void 0; | ||||
| const vscode_html_languageservice_1 = require("vscode-html-languageservice"); | ||||
| const vscode_languageserver_1 = require("vscode-languageserver"); | ||||
| const utils_1 = require("../../../core/documents/utils"); | ||||
| const astro_attributes_1 = require("../../html/features/astro-attributes"); | ||||
| const utils_2 = require("../../html/utils"); | ||||
| const utils_3 = require("../../typescript/utils"); | ||||
| class CompletionsProviderImpl { | ||||
|     constructor(languageServiceManager) { | ||||
|         this.lastCompletion = null; | ||||
|         this.directivesHTMLLang = (0, vscode_html_languageservice_1.getLanguageService)({ | ||||
|             customDataProviders: [astro_attributes_1.astroDirectives], | ||||
|             useDefaultDataProvider: false, | ||||
|         }); | ||||
|         this.languageServiceManager = languageServiceManager; | ||||
|         this.ts = languageServiceManager.docContext.ts; | ||||
|     } | ||||
|     async getCompletions(document, position, completionContext) { | ||||
|         let items = []; | ||||
|         const html = document.html; | ||||
|         const offset = document.offsetAt(position); | ||||
|         const node = html.findNodeAt(offset); | ||||
|         const insideExpression = (0, utils_1.isInsideExpression)(document.getText(), node.start, offset); | ||||
|         if (completionContext?.triggerCharacter === '-' && node.parent === undefined && !insideExpression) { | ||||
|             const frontmatter = this.getComponentScriptCompletion(document, position); | ||||
|             if (frontmatter) | ||||
|                 items.push(frontmatter); | ||||
|         } | ||||
|         if ((0, utils_1.isInComponentStartTag)(html, offset) && !insideExpression) { | ||||
|             const { completions: props, componentFilePath } = await this.getPropCompletionsAndFilePath(document, position, completionContext); | ||||
|             if (props.length) { | ||||
|                 items.push(...props); | ||||
|             } | ||||
|             const isAstro = componentFilePath?.endsWith('.astro'); | ||||
|             if (!isAstro && node.tag !== 'Fragment') { | ||||
|                 const directives = (0, utils_2.removeDataAttrCompletion)(this.directivesHTMLLang.doComplete(document, position, html).items); | ||||
|                 items.push(...directives); | ||||
|             } | ||||
|         } | ||||
|         return vscode_languageserver_1.CompletionList.create(items, true); | ||||
|     } | ||||
|     getComponentScriptCompletion(document, position) { | ||||
|         const base = { | ||||
|             kind: vscode_languageserver_1.CompletionItemKind.Snippet, | ||||
|             label: '---', | ||||
|             sortText: '\0', | ||||
|             preselect: true, | ||||
|             detail: 'Create component script block', | ||||
|             insertTextFormat: vscode_languageserver_1.InsertTextFormat.Snippet, | ||||
|             commitCharacters: [], | ||||
|         }; | ||||
|         const prefix = document.getLineUntilOffset(document.offsetAt(position)); | ||||
|         if (document.astroMeta.frontmatter.state === null) { | ||||
|             return { | ||||
|                 ...base, | ||||
|                 insertText: '---\n$0\n---', | ||||
|                 textEdit: prefix.match(/^\s*\-+/) | ||||
|                     ? vscode_languageserver_1.TextEdit.replace({ start: { ...position, character: 0 }, end: position }, '---\n$0\n---') | ||||
|                     : undefined, | ||||
|             }; | ||||
|         } | ||||
|         if (document.astroMeta.frontmatter.state === 'open') { | ||||
|             let insertText = '---'; | ||||
|             // If the current line is a full component script starter/ender, the user expects a full frontmatter
 | ||||
|             // completion and not just a completion for "---"  on the same line (which result in, well, nothing)
 | ||||
|             if (prefix === '---') { | ||||
|                 insertText = '---\n$0\n---'; | ||||
|             } | ||||
|             return { | ||||
|                 ...base, | ||||
|                 insertText, | ||||
|                 detail: insertText === '---' ? 'Close component script block' : 'Create component script block', | ||||
|                 textEdit: prefix.match(/^\s*\-+/) | ||||
|                     ? vscode_languageserver_1.TextEdit.replace({ start: { ...position, character: 0 }, end: position }, insertText) | ||||
|                     : undefined, | ||||
|             }; | ||||
|         } | ||||
|         return null; | ||||
|     } | ||||
|     async getPropCompletionsAndFilePath(document, position, completionContext) { | ||||
|         const offset = document.offsetAt(position); | ||||
|         const html = document.html; | ||||
|         const node = html.findNodeAt(offset); | ||||
|         if (!(0, utils_1.isPossibleComponent)(node)) { | ||||
|             return { completions: [], componentFilePath: null }; | ||||
|         } | ||||
|         const inAttribute = node.start + node.tag.length < offset; | ||||
|         if (!inAttribute) { | ||||
|             return { completions: [], componentFilePath: null }; | ||||
|         } | ||||
|         if (completionContext?.triggerCharacter === '/' || completionContext?.triggerCharacter === '>') { | ||||
|             return { completions: [], componentFilePath: null }; | ||||
|         } | ||||
|         // If inside of attribute value, skip.
 | ||||
|         if (completionContext && | ||||
|             completionContext.triggerKind === vscode_languageserver_1.CompletionTriggerKind.TriggerCharacter && | ||||
|             completionContext.triggerCharacter === '"') { | ||||
|             return { completions: [], componentFilePath: null }; | ||||
|         } | ||||
|         const componentName = node.tag; | ||||
|         const { lang, tsDoc } = await this.languageServiceManager.getLSAndTSDoc(document); | ||||
|         // Get the source file
 | ||||
|         const tsFilePath = tsDoc.filePath; | ||||
|         const program = lang.getProgram(); | ||||
|         const sourceFile = program?.getSourceFile(tsFilePath); | ||||
|         const typeChecker = program?.getTypeChecker(); | ||||
|         if (!sourceFile || !typeChecker) { | ||||
|             return { completions: [], componentFilePath: null }; | ||||
|         } | ||||
|         // Get the import statement
 | ||||
|         const imp = this.getImportedSymbol(sourceFile, componentName); | ||||
|         const importType = imp && typeChecker.getTypeAtLocation(imp); | ||||
|         if (!importType) { | ||||
|             return { completions: [], componentFilePath: null }; | ||||
|         } | ||||
|         const symbol = importType.getSymbol(); | ||||
|         if (!symbol) { | ||||
|             return { completions: [], componentFilePath: null }; | ||||
|         } | ||||
|         const symbolDeclaration = symbol.declarations; | ||||
|         if (!symbolDeclaration) { | ||||
|             return { completions: [], componentFilePath: null }; | ||||
|         } | ||||
|         const filePath = symbolDeclaration[0].getSourceFile().fileName; | ||||
|         const componentSnapshot = await this.languageServiceManager.getSnapshot(filePath); | ||||
|         if (this.lastCompletion) { | ||||
|             if (this.lastCompletion.tag === componentName && | ||||
|                 this.lastCompletion.documentVersion == componentSnapshot.version) { | ||||
|                 return { completions: this.lastCompletion.completions, componentFilePath: filePath }; | ||||
|             } | ||||
|         } | ||||
|         // Get the component's props type
 | ||||
|         const componentType = this.getPropType(symbolDeclaration, typeChecker); | ||||
|         if (!componentType) { | ||||
|             return { completions: [], componentFilePath: null }; | ||||
|         } | ||||
|         let completionItems = []; | ||||
|         // Add completions for this component's props type properties
 | ||||
|         const properties = componentType.getProperties().filter((property) => property.name !== 'children') || []; | ||||
|         properties.forEach((property) => { | ||||
|             const type = typeChecker.getTypeOfSymbolAtLocation(property, imp); | ||||
|             let completionItem = this.getCompletionItemForProperty(property, typeChecker, type); | ||||
|             completionItems.push(completionItem); | ||||
|         }); | ||||
|         this.lastCompletion = { | ||||
|             tag: componentName, | ||||
|             documentVersion: componentSnapshot.version, | ||||
|             completions: completionItems, | ||||
|         }; | ||||
|         return { completions: completionItems, componentFilePath: filePath }; | ||||
|     } | ||||
|     getImportedSymbol(sourceFile, identifier) { | ||||
|         for (let list of sourceFile.getChildren()) { | ||||
|             for (let node of list.getChildren()) { | ||||
|                 if (this.ts.isImportDeclaration(node)) { | ||||
|                     let clauses = node.importClause; | ||||
|                     if (!clauses) | ||||
|                         continue; | ||||
|                     let namedImport = clauses.getChildAt(0); | ||||
|                     if (this.ts.isNamedImports(namedImport)) { | ||||
|                         for (let imp of namedImport.elements) { | ||||
|                             // Iterate the named imports
 | ||||
|                             if (imp.name.getText() === identifier) { | ||||
|                                 return imp; | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                     else if (this.ts.isIdentifier(namedImport)) { | ||||
|                         if (namedImport.getText() === identifier) { | ||||
|                             return namedImport; | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         return null; | ||||
|     } | ||||
|     getPropType(declarations, typeChecker) { | ||||
|         for (const decl of declarations) { | ||||
|             const fileName = (0, utils_3.toVirtualFilePath)(decl.getSourceFile().fileName); | ||||
|             if (fileName.endsWith('.tsx') || fileName.endsWith('.jsx') || fileName.endsWith('.d.ts')) { | ||||
|                 if (!this.ts.isFunctionDeclaration(decl) && !this.ts.isFunctionTypeNode(decl)) { | ||||
|                     console.error(`We only support functions declarations at the moment`); | ||||
|                     continue; | ||||
|                 } | ||||
|                 const fn = decl; | ||||
|                 if (!fn.parameters.length) | ||||
|                     continue; | ||||
|                 const param1 = fn.parameters[0]; | ||||
|                 const propType = typeChecker.getTypeAtLocation(param1); | ||||
|                 return propType; | ||||
|             } | ||||
|         } | ||||
|         return null; | ||||
|     } | ||||
|     getCompletionItemForProperty(mem, typeChecker, type) { | ||||
|         const typeString = typeChecker.typeToString(type); | ||||
|         let insertText = mem.name; | ||||
|         switch (typeString) { | ||||
|             case 'string': | ||||
|                 insertText = `${mem.name}="$1"`; | ||||
|                 break; | ||||
|             case 'boolean': | ||||
|                 insertText = mem.name; | ||||
|                 break; | ||||
|             default: | ||||
|                 insertText = `${mem.name}={$1}`; | ||||
|                 break; | ||||
|         } | ||||
|         let item = { | ||||
|             label: mem.name, | ||||
|             detail: typeString, | ||||
|             insertText: insertText, | ||||
|             insertTextFormat: vscode_languageserver_1.InsertTextFormat.Snippet, | ||||
|             commitCharacters: [], | ||||
|             // Ensure that props shows up first as a completion, despite this plugin being ran after the HTML one
 | ||||
|             sortText: '\0', | ||||
|         }; | ||||
|         if (mem.flags & this.ts.SymbolFlags.Optional) { | ||||
|             item.filterText = item.label; | ||||
|             item.label += '?'; | ||||
|             // Put optional props at a lower priority
 | ||||
|             item.sortText = '_'; | ||||
|         } | ||||
|         mem.getDocumentationComment(typeChecker); | ||||
|         let description = mem | ||||
|             .getDocumentationComment(typeChecker) | ||||
|             .map((val) => val.text) | ||||
|             .join('\n'); | ||||
|         if (description) { | ||||
|             let docs = { | ||||
|                 kind: vscode_languageserver_1.MarkupKind.Markdown, | ||||
|                 value: description, | ||||
|             }; | ||||
|             item.documentation = docs; | ||||
|         } | ||||
|         return item; | ||||
|     } | ||||
| } | ||||
| exports.CompletionsProviderImpl = CompletionsProviderImpl; | ||||
							
								
								
									
										10
									
								
								node_modules/@astrojs/language-server/dist/plugins/astro/features/DiagnosticsProvider.d.ts
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								node_modules/@astrojs/language-server/dist/plugins/astro/features/DiagnosticsProvider.d.ts
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,10 @@ | |||
| import { Diagnostic } from 'vscode-languageserver-types'; | ||||
| import { AstroDocument } from '../../../core/documents'; | ||||
| import { DiagnosticsProvider } from '../../interfaces'; | ||||
| import { LanguageServiceManager } from '../../typescript/LanguageServiceManager'; | ||||
| export declare class DiagnosticsProviderImpl implements DiagnosticsProvider { | ||||
|     private languageServiceManager; | ||||
|     constructor(languageServiceManager: LanguageServiceManager); | ||||
|     getDiagnostics(document: AstroDocument): Promise<Diagnostic[]>; | ||||
|     private compilerMessageToDiagnostic; | ||||
| } | ||||
							
								
								
									
										23
									
								
								node_modules/@astrojs/language-server/dist/plugins/astro/features/DiagnosticsProvider.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								node_modules/@astrojs/language-server/dist/plugins/astro/features/DiagnosticsProvider.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,23 @@ | |||
| "use strict"; | ||||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||||
| exports.DiagnosticsProviderImpl = void 0; | ||||
| const vscode_languageserver_types_1 = require("vscode-languageserver-types"); | ||||
| class DiagnosticsProviderImpl { | ||||
|     constructor(languageServiceManager) { | ||||
|         this.languageServiceManager = languageServiceManager; | ||||
|     } | ||||
|     async getDiagnostics(document) { | ||||
|         const { tsDoc } = (await this.languageServiceManager.getLSAndTSDoc(document)); | ||||
|         return tsDoc.compilerDiagnostics.map(this.compilerMessageToDiagnostic); | ||||
|     } | ||||
|     compilerMessageToDiagnostic(message) { | ||||
|         return { | ||||
|             message: message.text + '\n\n' + message.hint, | ||||
|             range: vscode_languageserver_types_1.Range.create(message.location.line - 1, message.location.column - 1, message.location.line, message.location.length), | ||||
|             code: message.code, | ||||
|             severity: message.severity, | ||||
|             source: 'astro', | ||||
|         }; | ||||
|     } | ||||
| } | ||||
| exports.DiagnosticsProviderImpl = DiagnosticsProviderImpl; | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue