diff --git a/packages/language-server/src/core/astro2tsx.ts b/packages/language-server/src/core/astro2tsx.ts index 5dff9853..7caaf284 100644 --- a/packages/language-server/src/core/astro2tsx.ts +++ b/packages/language-server/src/core/astro2tsx.ts @@ -3,7 +3,8 @@ import type { ConvertToTSXOptions, TSXResult } from '@astrojs/compiler/types'; import { decode } from '@jridgewell/sourcemap-codec'; import type { CodeInformation, CodeMapping, VirtualCode } from '@volar/language-core'; import { Range } from '@volar/language-server'; -import { HTMLDocument, TextDocument } from 'vscode-html-languageservice'; +import type { HTMLDocument } from 'vscode-html-languageservice'; +import { TextDocument } from 'vscode-languageserver-textdocument'; import { patchTSX } from './utils.js'; export interface LSPTSXRanges { diff --git a/packages/language-server/src/core/index.ts b/packages/language-server/src/core/index.ts index beb83808..76a36048 100644 --- a/packages/language-server/src/core/index.ts +++ b/packages/language-server/src/core/index.ts @@ -9,6 +9,7 @@ import { import type { TypeScriptExtraServiceScript } from '@volar/typescript'; import type ts from 'typescript'; import type { HTMLDocument } from 'vscode-html-languageservice'; +import { TextDocument } from 'vscode-languageserver-textdocument'; import type { URI } from 'vscode-uri'; import { type AstroInstall, getLanguageServerTypesDir } from '../utils.js'; import { astro2tsx } from './astro2tsx'; @@ -161,6 +162,13 @@ export class AstroVirtualCode implements VirtualCode { ]; this.compilerDiagnostics = []; + const astroDocument = TextDocument.create( + fileName + '.astro', + 'astro', + 0, + snapshot.getText(0, snapshot.getLength()) + ); + const astroMetadata = getAstroMetadata( this.fileName, this.snapshot.getText(0, this.snapshot.getLength()) @@ -178,13 +186,17 @@ export class AstroVirtualCode implements VirtualCode { ); this.htmlDocument = htmlDocument; - const scriptTags = extractScriptTags(this.snapshot, htmlDocument, astroMetadata.ast); + const scriptTags = extractScriptTags( + this.snapshot, + astroDocument, + htmlDocument, + astroMetadata.ast + ); this.scriptCodeIds = scriptTags.map((scriptTag) => scriptTag.id); - htmlVirtualCode.embeddedCodes = []; htmlVirtualCode.embeddedCodes.push( - ...extractStylesheets(this.snapshot, htmlDocument, astroMetadata.ast), + ...extractStylesheets(this.snapshot, astroDocument, htmlDocument, astroMetadata.ast), ...scriptTags ); diff --git a/packages/language-server/src/core/parseCSS.ts b/packages/language-server/src/core/parseCSS.ts index fabb1fbc..e2238d53 100644 --- a/packages/language-server/src/core/parseCSS.ts +++ b/packages/language-server/src/core/parseCSS.ts @@ -3,12 +3,13 @@ import { is } from '@astrojs/compiler/utils'; import type { CodeInformation, VirtualCode } from '@volar/language-core'; import { Segment, toString } from 'muggle-string'; import type ts from 'typescript'; -import type { HTMLDocument, Node } from 'vscode-html-languageservice'; +import type { HTMLDocument, Node, TextDocument } from 'vscode-html-languageservice'; import { buildMappings } from '../buildMappings.js'; -import type { AttributeNodeWithPosition } from './compilerUtils.js'; +import { type AttributeNodeWithPosition, PointToPosition } from './compilerUtils.js'; export function extractStylesheets( snapshot: ts.IScriptSnapshot, + astroDocument: TextDocument, htmlDocument: HTMLDocument, ast: ParseResult['ast'] ): VirtualCode[] { @@ -22,7 +23,7 @@ export function extractStylesheets( codes.push([ inlineStyle.value, undefined, - inlineStyle.position.start.offset + 'style="'.length, + astroDocument.offsetAt(PointToPosition(inlineStyle.position.start)) + 'style="'.length, { completion: true, verification: false, diff --git a/packages/language-server/src/core/parseJS.ts b/packages/language-server/src/core/parseJS.ts index f4a6e4c9..4f690898 100644 --- a/packages/language-server/src/core/parseJS.ts +++ b/packages/language-server/src/core/parseJS.ts @@ -3,11 +3,13 @@ import { is } from '@astrojs/compiler/utils'; import type { CodeInformation, VirtualCode } from '@volar/language-core'; import { Segment, toString } from 'muggle-string'; import type ts from 'typescript'; -import type { HTMLDocument, Node } from 'vscode-html-languageservice'; +import type { HTMLDocument, Node, TextDocument } from 'vscode-html-languageservice'; import { buildMappings } from '../buildMappings'; +import { PointToPosition } from './compilerUtils.js'; export function extractScriptTags( snapshot: ts.IScriptSnapshot, + astroDocument: TextDocument, htmlDocument: HTMLDocument, ast: ParseResult['ast'] ): VirtualCode[] { @@ -15,7 +17,7 @@ export function extractScriptTags( const javascriptContexts = [ ...findClassicScripts(htmlDocument, snapshot), - ...findEventAttributes(ast), + ...findEventAttributes(ast, astroDocument), ].sort((a, b) => a.startOffset - b.startOffset); if (javascriptContexts.length > 0) { @@ -153,7 +155,10 @@ function isJSON(type: string | null | undefined): boolean { return JSON_TYPES.includes(type.slice(1, -1)); } -function findEventAttributes(ast: ParseResult['ast']): JavaScriptContext[] { +function findEventAttributes( + ast: ParseResult['ast'], + astroDocument: TextDocument +): JavaScriptContext[] { const eventAttrs: JavaScriptContext[] = []; // `@astrojs/compiler`'s `walk` method is async, so we can't use it here. Arf @@ -172,7 +177,9 @@ function findEventAttributes(ast: ParseResult['ast']): JavaScriptContext[] { // This is not perfect, but it's better than nothing // See: https://github.com/microsoft/vscode/blob/e8e04769ec817a3374c3eaa26a08d3ae491820d5/extensions/html-language-features/server/src/modes/embeddedSupport.ts#L192 content: eventAttribute.value + ';', - startOffset: eventAttribute.position.start.offset + `${eventAttribute.name}="`.length, + startOffset: + astroDocument.offsetAt(PointToPosition(eventAttribute.position.start)) + + `${eventAttribute.name}="`.length, }); } }