svelte-language-server
Version:
A language server for Svelte
138 lines • 4.91 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Document = void 0;
const utils_1 = require("../../utils");
const DocumentBase_1 = require("./DocumentBase");
const utils_2 = require("./utils");
const parseHtml_1 = require("./parseHtml");
const configLoader_1 = require("./configLoader");
const importPackage_1 = require("../../importPackage");
/**
* Represents a text document contains a svelte component.
*/
class Document extends DocumentBase_1.WritableDocument {
get compiler() {
return this.getCompiler();
}
get isSvelte5() {
return this.getSvelteVersion()[0] > 4;
}
constructor(url, content) {
super();
this.url = url;
this.content = content;
this.languageId = 'svelte';
this.scriptInfo = null;
this.moduleScriptInfo = null;
this.styleInfo = null;
this.templateInfo = null;
this.openedByClient = false;
/**
* Compute and cache directly because of performance reasons
* and it will be called anyway.
*/
this.path = (0, utils_1.urlToPath)(this.url);
this.configPromise = configLoader_1.configLoader.awaitConfig(this.getFilePath() || '');
this.updateDocInfo();
}
getCompiler() {
if (!this._compiler) {
this._compiler = (0, importPackage_1.importSvelte)(this.getFilePath() || '');
}
return this._compiler;
}
updateDocInfo() {
this.html = (0, parseHtml_1.parseHtml)(this.content);
const update = (config) => {
const scriptTags = (0, utils_2.extractScriptTags)(this.content, this.html);
this.config = config;
this.scriptInfo = this.addDefaultLanguage(config, scriptTags?.script || null, 'script');
this.moduleScriptInfo = this.addDefaultLanguage(config, scriptTags?.moduleScript || null, 'script');
this.styleInfo = this.addDefaultLanguage(config, (0, utils_2.extractStyleTag)(this.content, this.html), 'style');
this.templateInfo = this.addDefaultLanguage(config, (0, utils_2.extractTemplateTag)(this.content, this.html), 'markup');
};
const config = configLoader_1.configLoader.getConfig(this.getFilePath() || '');
if (config && !config.loadConfigError) {
update(config);
}
else {
update(undefined);
this.configPromise.then((c) => update(c));
}
}
getSvelteVersion() {
if (!this.svelteVersion) {
const [major, minor] = this.compiler.VERSION.split('.');
this.svelteVersion = [Number(major), Number(minor)];
}
return this.svelteVersion;
}
/**
* Get text content
*/
getText(range) {
if (range) {
return this.content.substring(this.offsetAt(range.start), this.offsetAt(range.end));
}
return this.content;
}
/**
* Set text content and increase the document version
*/
setText(text) {
this.content = text;
this.version++;
this.lineOffsets = undefined;
this.updateDocInfo();
}
/**
* Returns the file path if the url scheme is file
*/
getFilePath() {
return this.path;
}
/**
* Get URL file path.
*/
getURL() {
return this.url;
}
/**
* Returns the language associated to script, style or template.
* Returns an empty string if there's nothing set.
*/
getLanguageAttribute(tag) {
const attrs = (tag === 'style'
? this.styleInfo?.attributes
: tag === 'script'
? this.scriptInfo?.attributes || this.moduleScriptInfo?.attributes
: this.templateInfo?.attributes) || {};
const lang = attrs.lang || attrs.type || '';
return lang.replace(/^text\//, '');
}
/**
* Returns true if there's `lang="X"` on script or style or template.
*/
hasLanguageAttribute() {
return (!!this.getLanguageAttribute('script') ||
!!this.getLanguageAttribute('style') ||
!!this.getLanguageAttribute('template'));
}
/**
* @deprecated This no longer exists in svelte-preprocess v5, we leave it in in case someone is using this with v4
*/
addDefaultLanguage(config, tagInfo, tag) {
if (!tagInfo || !config) {
return tagInfo;
}
const defaultLang = Array.isArray(config.preprocess)
? config.preprocess.find((group) => group.defaultLanguages?.[tag])?.defaultLanguages?.[tag]
: config.preprocess?.defaultLanguages?.[tag];
if (!tagInfo.attributes.lang && !tagInfo.attributes.type && defaultLang) {
tagInfo.attributes.lang = defaultLang;
}
return tagInfo;
}
}
exports.Document = Document;
//# sourceMappingURL=Document.js.map