From ea6744c06042dd7e0cc375c7481a6a7d76cb437d Mon Sep 17 00:00:00 2001 From: Simon Holthausen Date: Sun, 23 Aug 2020 19:49:24 +0200 Subject: [PATCH 1/3] (feat) possibility to ignore compiler warnings/treat them as errors --- packages/language-server/src/index.ts | 2 +- packages/language-server/src/ls-config.ts | 63 ++++++++++++++- .../src/plugins/svelte/SveltePlugin.ts | 6 +- .../plugins/svelte/features/getDiagnostics.ts | 10 ++- packages/language-server/src/server.ts | 6 +- packages/language-server/src/svelte-check.ts | 17 +++- .../svelte/features/getDiagnostics.test.ts | 80 ++++++++++++++++++- packages/svelte-check/README.md | 4 + packages/svelte-check/src/index.ts | 41 +++++++--- packages/svelte-vscode/README.md | 8 ++ packages/svelte-vscode/package.json | 12 +++ 11 files changed, 224 insertions(+), 25 deletions(-) diff --git a/packages/language-server/src/index.ts b/packages/language-server/src/index.ts index 9ee2cc5b8..a44da6bc6 100644 --- a/packages/language-server/src/index.ts +++ b/packages/language-server/src/index.ts @@ -1,3 +1,3 @@ export * from './server'; export { offsetAt } from './lib/documents'; -export { SvelteCheck } from './svelte-check'; +export { SvelteCheck, SvelteCheckOptions } from './svelte-check'; diff --git a/packages/language-server/src/ls-config.ts b/packages/language-server/src/ls-config.ts index 22d0e9d47..b448c1a28 100644 --- a/packages/language-server/src/ls-config.ts +++ b/packages/language-server/src/ls-config.ts @@ -32,6 +32,8 @@ const defaultLSConfig: LSConfig = { }, svelte: { enable: true, + ignoredCompilerWarnings: [], + compilerWarningsAsErrors: [], diagnostics: { enable: true }, format: { enable: true }, completions: { enable: true }, @@ -116,6 +118,8 @@ export interface LSHTMLConfig { export interface LSSvelteConfig { enable: boolean; + ignoredCompilerWarnings: string[]; + compilerWarningsAsErrors: string[]; diagnostics: { enable: boolean; }; @@ -133,17 +137,31 @@ export interface LSSvelteConfig { }; } +type DeepPartial = T extends any[] + ? T + : { + [P in keyof T]?: DeepPartial; + }; + export class LSConfigManager { private config: LSConfig = defaultLSConfig; /** * Updates config. */ - update(config: LSConfig): void { + update(config: DeepPartial): void { // Ideally we shouldn't need the merge here because all updates should be valid and complete configs. // But since those configs come from the client they might be out of synch with the valid config: // We might at some point in the future forget to synch config settings in all packages after updating the config. this.config = merge({}, defaultLSConfig, this.config, config); + // Merge will keep arrays if the new one is empty/has less entries, + // therefore we need some extra checks if there are new settings + if (config.svelte?.ignoredCompilerWarnings) { + this.config.svelte.ignoredCompilerWarnings = config.svelte.ignoredCompilerWarnings; + } + if (config.svelte?.compilerWarningsAsErrors) { + this.config.svelte.compilerWarningsAsErrors = config.svelte.compilerWarningsAsErrors; + } } /** @@ -151,8 +169,49 @@ export class LSConfigManager { * @param key a string which is a path. Example: 'svelte.diagnostics.enable'. */ enabled(key: string): boolean { - return !!get(this.config, key); + return !!this.get(key); + } + + /** + * Get specific config + * @param key a string which is a path. Example: 'svelte.diagnostics.enable'. + */ + get(key: string): T { + return get(this.config, key); + } + + /** + * Get the whole config + */ + getConfig(): Readonly { + return this.config; } } export const lsConfig = new LSConfigManager(); + +/** + * Parses a raw incoming config. + * Some options may come in a raw form (string with commas instead of string array) + * and need to be transformed accordingly. + */ +export function parseRawConfig(config: any): LSConfig { + return { + ...config, + svelte: { + ...config?.svelte, + ignoredCompilerWarnings: stringToArray(config?.svelte?.ignoredCompilerWarnings), + compilerWarningsAsErrors: stringToArray(config?.svelte?.compilerWarningsAsErrors), + }, + }; + + function stringToArray(str: string | string[] = ''): string[] { + if (Array.isArray(str)) { + return str; + } + return str + .split(',') + .map((s) => s.trim()) + .filter((s) => !!s); + } +} diff --git a/packages/language-server/src/plugins/svelte/SveltePlugin.ts b/packages/language-server/src/plugins/svelte/SveltePlugin.ts index c8dde414b..aa6b77056 100644 --- a/packages/language-server/src/plugins/svelte/SveltePlugin.ts +++ b/packages/language-server/src/plugins/svelte/SveltePlugin.ts @@ -46,7 +46,11 @@ export class SveltePlugin return []; } - return getDiagnostics(document, await this.getSvelteDoc(document)); + return getDiagnostics( + document, + await this.getSvelteDoc(document), + this.configManager.getConfig().svelte, + ); } async getCompiledResult(document: Document): Promise { diff --git a/packages/language-server/src/plugins/svelte/features/getDiagnostics.ts b/packages/language-server/src/plugins/svelte/features/getDiagnostics.ts index ba785e726..2c251fa78 100644 --- a/packages/language-server/src/plugins/svelte/features/getDiagnostics.ts +++ b/packages/language-server/src/plugins/svelte/features/getDiagnostics.ts @@ -3,6 +3,7 @@ import { Diagnostic, DiagnosticSeverity, Position, Range } from 'vscode-language import { Document, isInTag, mapDiagnosticToOriginal } from '../../../lib/documents'; import { Logger } from '../../../logger'; import { SvelteDocument, TranspileErrorSource } from '../SvelteDocument'; +import { LSSvelteConfig } from '../../../ls-config'; /** * Returns diagnostics from the svelte compiler. @@ -11,13 +12,14 @@ import { SvelteDocument, TranspileErrorSource } from '../SvelteDocument'; export async function getDiagnostics( document: Document, svelteDoc: SvelteDocument, + settings: Pick, ): Promise { if (svelteDoc.config.loadConfigError) { return getConfigLoadErrorDiagnostics(svelteDoc.config.loadConfigError); } try { - return await tryGetDiagnostics(document, svelteDoc); + return await tryGetDiagnostics(document, svelteDoc, settings); } catch (error) { return getPreprocessErrorDiagnostics(document, error); } @@ -29,19 +31,23 @@ export async function getDiagnostics( async function tryGetDiagnostics( document: Document, svelteDoc: SvelteDocument, + settings: Pick, ): Promise { const transpiled = await svelteDoc.getTranspiled(); try { const res = await svelteDoc.getCompiled(); return (((res.stats as any).warnings || res.warnings || []) as Warning[]) + .filter((warning) => !settings.ignoredCompilerWarnings.includes(warning.code)) .map((warning) => { const start = warning.start || { line: 1, column: 0 }; const end = warning.end || start; return { range: Range.create(start.line - 1, start.column, end.line - 1, end.column), message: warning.message, - severity: DiagnosticSeverity.Warning, + severity: settings.compilerWarningsAsErrors.includes(warning.code) + ? DiagnosticSeverity.Error + : DiagnosticSeverity.Warning, source: 'svelte', code: warning.code, }; diff --git a/packages/language-server/src/server.ts b/packages/language-server/src/server.ts index 00b394375..e8ce9c502 100644 --- a/packages/language-server/src/server.ts +++ b/packages/language-server/src/server.ts @@ -20,7 +20,7 @@ import { import { DiagnosticsManager } from './lib/DiagnosticsManager'; import { Document, DocumentManager } from './lib/documents'; import { Logger } from './logger'; -import { LSConfigManager } from './ls-config'; +import { LSConfigManager, parseRawConfig } from './ls-config'; import { AppCompletionItem, CSSPlugin, @@ -93,7 +93,7 @@ export function startServer(options?: LSOptions) { } pluginHost.initialize(!!evt.initializationOptions?.dontFilterIncompleteCompletions); - pluginHost.updateConfig(evt.initializationOptions?.config); + pluginHost.updateConfig(parseRawConfig(evt.initializationOptions?.config)); pluginHost.register( (sveltePlugin = new SveltePlugin( configManager, @@ -188,7 +188,7 @@ export function startServer(options?: LSOptions) { connection.onPrepareRename((req) => pluginHost.prepareRename(req.textDocument, req.position)); connection.onDidChangeConfiguration(({ settings }) => { - pluginHost.updateConfig(settings.svelte?.plugin); + pluginHost.updateConfig(parseRawConfig(settings.svelte?.plugin)); }); connection.onDidOpenTextDocument((evt) => { diff --git a/packages/language-server/src/svelte-check.ts b/packages/language-server/src/svelte-check.ts index 366e3681b..cfa5a8762 100644 --- a/packages/language-server/src/svelte-check.ts +++ b/packages/language-server/src/svelte-check.ts @@ -5,6 +5,11 @@ import { Diagnostic } from 'vscode-languageserver'; import { Logger } from './logger'; import { urlToPath } from './utils'; +export interface SvelteCheckOptions { + ignoredCompilerWarnings?: string[]; + compilerWarningsAsErrors?: string[]; +} + /** * Small wrapper around PluginHost's Diagnostic Capabilities * for svelte-check, without the overhead of the lsp. @@ -16,12 +21,18 @@ export class SvelteCheck { private configManager = new LSConfigManager(); private pluginHost = new PluginHost(this.docManager, this.configManager); - constructor(workspacePath: string) { + constructor(workspacePath: string, options: SvelteCheckOptions = {}) { Logger.setLogErrorsOnly(true); - this.initialize(workspacePath); + this.initialize(workspacePath, options); } - private initialize(workspacePath: string) { + private initialize(workspacePath: string, options: SvelteCheckOptions) { + this.configManager.update({ + svelte: { + ignoredCompilerWarnings: options.ignoredCompilerWarnings, + compilerWarningsAsErrors: options.compilerWarningsAsErrors, + }, + }); this.pluginHost.register(new SveltePlugin(this.configManager, {})); this.pluginHost.register(new HTMLPlugin(this.docManager, this.configManager)); this.pluginHost.register(new CSSPlugin(this.docManager, this.configManager)); diff --git a/packages/language-server/test/plugins/svelte/features/getDiagnostics.test.ts b/packages/language-server/test/plugins/svelte/features/getDiagnostics.test.ts index 8b82a1053..e196acfe1 100644 --- a/packages/language-server/test/plugins/svelte/features/getDiagnostics.test.ts +++ b/packages/language-server/test/plugins/svelte/features/getDiagnostics.test.ts @@ -7,16 +7,21 @@ import { TranspileErrorSource, } from '../../../../src/plugins/svelte/SvelteDocument'; import { SvelteConfig } from '../../../../src/lib/documents/configLoader'; +import { LSSvelteConfig } from '../../../../src/ls-config'; describe('SveltePlugin#getDiagnostics', () => { async function expectDiagnosticsFor( getTranspiled: any, getCompiled: any, config: Partial, + settings: Pick = { + compilerWarningsAsErrors: [], + ignoredCompilerWarnings: [], + }, ) { const document = new Document('', '\n'); const svelteDoc: SvelteDocument = { getTranspiled, getCompiled, config }; - const result = await getDiagnostics(document, svelteDoc); + const result = await getDiagnostics(document, svelteDoc, settings); return { toEqual: (expected: Diagnostic[]) => assert.deepStrictEqual(result, expected), }; @@ -259,4 +264,77 @@ describe('SveltePlugin#getDiagnostics', () => { }, ]); }); + + it('filter out warnings', async () => { + ( + await expectDiagnosticsFor( + () => ({ + getOriginalPosition: (pos: Position) => { + pos.line - 1; + return pos; + }, + }), + () => + Promise.resolve({ + stats: { + warnings: [ + { + start: { line: 1, column: 0 }, + end: { line: 1, column: 0 }, + message: 'warning', + code: '123', + }, + ], + }, + }), + {}, + { compilerWarningsAsErrors: [], ignoredCompilerWarnings: ['123'] }, + ) + ).toEqual([]); + }); + + it('treat warnings as error', async () => { + ( + await expectDiagnosticsFor( + () => ({ + getOriginalPosition: (pos: Position) => { + pos.line - 1; + return pos; + }, + }), + () => + Promise.resolve({ + stats: { + warnings: [ + { + start: { line: 1, column: 0 }, + end: { line: 1, column: 0 }, + message: 'warning', + code: '123', + }, + ], + }, + }), + {}, + { compilerWarningsAsErrors: ['123'], ignoredCompilerWarnings: [] }, + ) + ).toEqual([ + { + code: '123', + message: 'warning', + range: { + start: { + character: 0, + line: 0, + }, + end: { + character: 0, + line: 0, + }, + }, + severity: DiagnosticSeverity.Error, + source: 'svelte', + }, + ]); + }); }); diff --git a/packages/svelte-check/README.md b/packages/svelte-check/README.md index 50ea1e54b..6a3bc513e 100644 --- a/packages/svelte-check/README.md +++ b/packages/svelte-check/README.md @@ -60,6 +60,10 @@ Usage: `--fail-on-warnings` Will also exit with error code when there are warnings +`--ignored-compiler-warnings ` Svelte compiler warning codes to ignore, comma-separated, inside quotes. Example: --ignored-compiler-warnings "css-unused-selector,unused-export-let" + +`--compiler-warnings-as-errors ` Svelte compiler warning codes wich should be treated as errors, comma-separated, inside quotes. Example: --compiler-warnings-as-errors "css-unused-selector,unused-export-let" + ### More docs, preprocessor setup and troubleshooting [See here](/docs/README.md). diff --git a/packages/svelte-check/src/index.ts b/packages/svelte-check/src/index.ts index 657c04d2c..db911a01d 100644 --- a/packages/svelte-check/src/index.ts +++ b/packages/svelte-check/src/index.ts @@ -6,7 +6,7 @@ import * as fs from 'fs'; import * as glob from 'glob'; import * as argv from 'minimist'; import * as path from 'path'; -import { SvelteCheck } from 'svelte-language-server'; +import { SvelteCheck, SvelteCheckOptions } from 'svelte-language-server'; import { Diagnostic, DiagnosticSeverity } from 'vscode-languageserver-protocol'; import { URI } from 'vscode-uri'; import { HumanFriendlyWriter, MachineFriendlyWriter, Writer } from './writers'; @@ -122,6 +122,32 @@ class DiagnosticsWatcher { } } +function instantiateWriter(myArgs: argv.ParsedArgs): Writer { + const outputFormat: OutputFormat = outputFormats.includes(myArgs['output']) + ? myArgs['output'] + : 'human-verbose'; + + if (outputFormat === 'human-verbose' || outputFormat === 'human') { + return new HumanFriendlyWriter(process.stdout, outputFormat === 'human-verbose'); + } else { + return new MachineFriendlyWriter(process.stdout); + } +} + +function getOptions(myArgs: argv.ParsedArgs): SvelteCheckOptions { + return { + ignoredCompilerWarnings: stringToArray(myArgs['ignored-compiler-warnings']), + compilerWarningsAsErrors: stringToArray(myArgs['compiler-warnings-as-errors']), + }; + + function stringToArray(str = ''): string[] { + return str + .split(',') + .map((s) => s.trim()) + .filter((s) => !!s); + } +} + (async () => { const myArgs = argv(process.argv.slice(1)); let workspaceUri; @@ -136,18 +162,9 @@ class DiagnosticsWatcher { workspaceUri = URI.file(process.cwd()); } - const outputFormat: OutputFormat = outputFormats.includes(myArgs['output']) - ? myArgs['output'] - : 'human-verbose'; - let writer: Writer; - - if (outputFormat === 'human-verbose' || outputFormat === 'human') { - writer = new HumanFriendlyWriter(process.stdout, outputFormat === 'human-verbose'); - } else { - writer = new MachineFriendlyWriter(process.stdout); - } + const writer = instantiateWriter(myArgs); - const svelteCheck = new SvelteCheck(workspaceUri.fsPath); + const svelteCheck = new SvelteCheck(workspaceUri.fsPath, getOptions(myArgs)); const filePathsToIgnore = myArgs['ignore']?.split(',') || []; if (myArgs['watch']) { diff --git a/packages/svelte-vscode/README.md b/packages/svelte-vscode/README.md index dca4a348e..2dc2f4f2b 100644 --- a/packages/svelte-vscode/README.md +++ b/packages/svelte-vscode/README.md @@ -148,6 +148,14 @@ Enable the Svelte plugin. _Default_: `true` Enable diagnostic messages for Svelte. _Default_: `true` +##### `svelte.plugin.svelte.ignoredCompilerWarnings` + +Svelte compiler warning codes to ignore, comma-separated. Example: `css-unused-selector,unused-export-let`. + +##### `svelte.plugin.svelte.compilerWarningsAsErrors` + +Svelte compiler warning codes wich should be treated as errors, comma-separated. Example: `css-unused-selector,unused-export-let` + ##### `svelte.plugin.svelte.format.enable` Enable formatting for Svelte (includes css & js). _Default_: `true` diff --git a/packages/svelte-vscode/package.json b/packages/svelte-vscode/package.json index 28c053093..2a0c232da 100644 --- a/packages/svelte-vscode/package.json +++ b/packages/svelte-vscode/package.json @@ -188,6 +188,18 @@ "title": "Svelte: Diagnostics", "description": "Enable diagnostic messages for Svelte" }, + "svelte.plugin.svelte.ignoredCompilerWarnings": { + "type": "string", + "default": "", + "title": "Svelte: Ignored Compiler Warnings", + "description": "Svelte compiler warning codes to ignore, comma-separated. Example: `css-unused-selector,unused-export-let`" + }, + "svelte.plugin.svelte.compilerWarningsAsErrors": { + "type": "string", + "default": "", + "title": "Svelte: Compiler Warnings to treat as Errors", + "description": "Svelte compiler warning codes wich should be treated as errors, comma-separated. Example: `css-unused-selector,unused-export-let`" + }, "svelte.plugin.svelte.format.enable": { "type": "boolean", "default": true, From ab26a8be4a37dccc2227d118606cf3343e1cecce Mon Sep 17 00:00:00 2001 From: Simon Holthausen Date: Tue, 25 Aug 2020 08:28:22 +0200 Subject: [PATCH 2/3] (refactor) merge array to one object compilerWarnings More flexible for enhancement, better settings UI for VSCode --- packages/language-server/src/ls-config.ts | 19 +++++++-------- .../src/plugins/svelte/SveltePlugin.ts | 7 +----- .../plugins/svelte/features/getDiagnostics.ts | 15 ++++++------ packages/language-server/src/svelte-check.ts | 6 ++--- .../svelte/features/getDiagnostics.test.ts | 11 ++++----- packages/svelte-check/README.md | 4 +--- packages/svelte-check/src/index.ts | 14 +++++++---- packages/svelte-vscode/README.md | 8 ++----- packages/svelte-vscode/package.json | 23 ++++++++++--------- 9 files changed, 48 insertions(+), 59 deletions(-) diff --git a/packages/language-server/src/ls-config.ts b/packages/language-server/src/ls-config.ts index b448c1a28..19adca4db 100644 --- a/packages/language-server/src/ls-config.ts +++ b/packages/language-server/src/ls-config.ts @@ -32,8 +32,7 @@ const defaultLSConfig: LSConfig = { }, svelte: { enable: true, - ignoredCompilerWarnings: [], - compilerWarningsAsErrors: [], + compilerWarnings: {}, diagnostics: { enable: true }, format: { enable: true }, completions: { enable: true }, @@ -116,10 +115,11 @@ export interface LSHTMLConfig { }; } +export type CompilerWarningsSettings = Record; + export interface LSSvelteConfig { enable: boolean; - ignoredCompilerWarnings: string[]; - compilerWarningsAsErrors: string[]; + compilerWarnings: CompilerWarningsSettings; diagnostics: { enable: boolean; }; @@ -137,7 +137,7 @@ export interface LSSvelteConfig { }; } -type DeepPartial = T extends any[] +type DeepPartial = T extends CompilerWarningsSettings ? T : { [P in keyof T]?: DeepPartial; @@ -154,13 +154,10 @@ export class LSConfigManager { // But since those configs come from the client they might be out of synch with the valid config: // We might at some point in the future forget to synch config settings in all packages after updating the config. this.config = merge({}, defaultLSConfig, this.config, config); - // Merge will keep arrays if the new one is empty/has less entries, + // Merge will keep arrays/objects if the new one is empty/has less entries, // therefore we need some extra checks if there are new settings - if (config.svelte?.ignoredCompilerWarnings) { - this.config.svelte.ignoredCompilerWarnings = config.svelte.ignoredCompilerWarnings; - } - if (config.svelte?.compilerWarningsAsErrors) { - this.config.svelte.compilerWarningsAsErrors = config.svelte.compilerWarningsAsErrors; + if (config.svelte?.compilerWarnings) { + this.config.svelte.compilerWarnings = config.svelte.compilerWarnings; } } diff --git a/packages/language-server/src/plugins/svelte/SveltePlugin.ts b/packages/language-server/src/plugins/svelte/SveltePlugin.ts index aa6b77056..3725767d5 100644 --- a/packages/language-server/src/plugins/svelte/SveltePlugin.ts +++ b/packages/language-server/src/plugins/svelte/SveltePlugin.ts @@ -1,4 +1,3 @@ -import { cosmiconfig } from 'cosmiconfig'; import { CodeAction, CodeActionContext, @@ -34,10 +33,6 @@ export class SveltePlugin HoverProvider, CodeActionsProvider { private docManager = new Map(); - private cosmiConfigExplorer = cosmiconfig('svelte', { - packageProp: 'svelte-ls', - cache: true, - }); constructor(private configManager: LSConfigManager, private prettierConfig: any) {} @@ -49,7 +44,7 @@ export class SveltePlugin return getDiagnostics( document, await this.getSvelteDoc(document), - this.configManager.getConfig().svelte, + this.configManager.getConfig().svelte.compilerWarnings, ); } diff --git a/packages/language-server/src/plugins/svelte/features/getDiagnostics.ts b/packages/language-server/src/plugins/svelte/features/getDiagnostics.ts index 2c251fa78..8ce626424 100644 --- a/packages/language-server/src/plugins/svelte/features/getDiagnostics.ts +++ b/packages/language-server/src/plugins/svelte/features/getDiagnostics.ts @@ -3,7 +3,7 @@ import { Diagnostic, DiagnosticSeverity, Position, Range } from 'vscode-language import { Document, isInTag, mapDiagnosticToOriginal } from '../../../lib/documents'; import { Logger } from '../../../logger'; import { SvelteDocument, TranspileErrorSource } from '../SvelteDocument'; -import { LSSvelteConfig } from '../../../ls-config'; +import { CompilerWarningsSettings } from '../../../ls-config'; /** * Returns diagnostics from the svelte compiler. @@ -12,7 +12,7 @@ import { LSSvelteConfig } from '../../../ls-config'; export async function getDiagnostics( document: Document, svelteDoc: SvelteDocument, - settings: Pick, + settings: CompilerWarningsSettings, ): Promise { if (svelteDoc.config.loadConfigError) { return getConfigLoadErrorDiagnostics(svelteDoc.config.loadConfigError); @@ -31,23 +31,24 @@ export async function getDiagnostics( async function tryGetDiagnostics( document: Document, svelteDoc: SvelteDocument, - settings: Pick, + settings: CompilerWarningsSettings, ): Promise { const transpiled = await svelteDoc.getTranspiled(); try { const res = await svelteDoc.getCompiled(); return (((res.stats as any).warnings || res.warnings || []) as Warning[]) - .filter((warning) => !settings.ignoredCompilerWarnings.includes(warning.code)) + .filter((warning) => settings[warning.code] !== 'ignore') .map((warning) => { const start = warning.start || { line: 1, column: 0 }; const end = warning.end || start; return { range: Range.create(start.line - 1, start.column, end.line - 1, end.column), message: warning.message, - severity: settings.compilerWarningsAsErrors.includes(warning.code) - ? DiagnosticSeverity.Error - : DiagnosticSeverity.Warning, + severity: + settings[warning.code] === 'error' + ? DiagnosticSeverity.Error + : DiagnosticSeverity.Warning, source: 'svelte', code: warning.code, }; diff --git a/packages/language-server/src/svelte-check.ts b/packages/language-server/src/svelte-check.ts index cfa5a8762..2e05e4f76 100644 --- a/packages/language-server/src/svelte-check.ts +++ b/packages/language-server/src/svelte-check.ts @@ -6,8 +6,7 @@ import { Logger } from './logger'; import { urlToPath } from './utils'; export interface SvelteCheckOptions { - ignoredCompilerWarnings?: string[]; - compilerWarningsAsErrors?: string[]; + compilerWarnings?: Record; } /** @@ -29,8 +28,7 @@ export class SvelteCheck { private initialize(workspacePath: string, options: SvelteCheckOptions) { this.configManager.update({ svelte: { - ignoredCompilerWarnings: options.ignoredCompilerWarnings, - compilerWarningsAsErrors: options.compilerWarningsAsErrors, + compilerWarnings: options.compilerWarnings, }, }); this.pluginHost.register(new SveltePlugin(this.configManager, {})); diff --git a/packages/language-server/test/plugins/svelte/features/getDiagnostics.test.ts b/packages/language-server/test/plugins/svelte/features/getDiagnostics.test.ts index e196acfe1..efd5db04b 100644 --- a/packages/language-server/test/plugins/svelte/features/getDiagnostics.test.ts +++ b/packages/language-server/test/plugins/svelte/features/getDiagnostics.test.ts @@ -7,17 +7,14 @@ import { TranspileErrorSource, } from '../../../../src/plugins/svelte/SvelteDocument'; import { SvelteConfig } from '../../../../src/lib/documents/configLoader'; -import { LSSvelteConfig } from '../../../../src/ls-config'; +import { CompilerWarningsSettings } from '../../../../src/ls-config'; describe('SveltePlugin#getDiagnostics', () => { async function expectDiagnosticsFor( getTranspiled: any, getCompiled: any, config: Partial, - settings: Pick = { - compilerWarningsAsErrors: [], - ignoredCompilerWarnings: [], - }, + settings: CompilerWarningsSettings = {}, ) { const document = new Document('', '\n'); const svelteDoc: SvelteDocument = { getTranspiled, getCompiled, config }; @@ -288,7 +285,7 @@ describe('SveltePlugin#getDiagnostics', () => { }, }), {}, - { compilerWarningsAsErrors: [], ignoredCompilerWarnings: ['123'] }, + { '123': 'ignore' }, ) ).toEqual([]); }); @@ -316,7 +313,7 @@ describe('SveltePlugin#getDiagnostics', () => { }, }), {}, - { compilerWarningsAsErrors: ['123'], ignoredCompilerWarnings: [] }, + { '123': 'error' }, ) ).toEqual([ { diff --git a/packages/svelte-check/README.md b/packages/svelte-check/README.md index 6a3bc513e..4efbb9f37 100644 --- a/packages/svelte-check/README.md +++ b/packages/svelte-check/README.md @@ -60,9 +60,7 @@ Usage: `--fail-on-warnings` Will also exit with error code when there are warnings -`--ignored-compiler-warnings ` Svelte compiler warning codes to ignore, comma-separated, inside quotes. Example: --ignored-compiler-warnings "css-unused-selector,unused-export-let" - -`--compiler-warnings-as-errors ` Svelte compiler warning codes wich should be treated as errors, comma-separated, inside quotes. Example: --compiler-warnings-as-errors "css-unused-selector,unused-export-let" +`--compiler-warnings ` A list of Svelte compiler warning codes. Each entry defines whether that warning should be ignored or treated as an error. Warnings are comma-separated, between warning code and error level is a colon; all inside quotes. Example: --compiler-warnings "css-unused-selector:ignore,unused-export-let:error" ### More docs, preprocessor setup and troubleshooting diff --git a/packages/svelte-check/src/index.ts b/packages/svelte-check/src/index.ts index db911a01d..c8fad7e77 100644 --- a/packages/svelte-check/src/index.ts +++ b/packages/svelte-check/src/index.ts @@ -136,15 +136,21 @@ function instantiateWriter(myArgs: argv.ParsedArgs): Writer { function getOptions(myArgs: argv.ParsedArgs): SvelteCheckOptions { return { - ignoredCompilerWarnings: stringToArray(myArgs['ignored-compiler-warnings']), - compilerWarningsAsErrors: stringToArray(myArgs['compiler-warnings-as-errors']), + compilerWarnings: stringToObj(myArgs['compiler-warnings']), }; - function stringToArray(str = ''): string[] { + function stringToObj(str = '') { return str .split(',') .map((s) => s.trim()) - .filter((s) => !!s); + .filter((s) => !!s) + .reduce((settings, setting) => { + const [name, val] = setting.split(':'); + if (val === 'error' || val === 'ignore') { + settings[name] = val; + } + return settings; + }, >{}); } } diff --git a/packages/svelte-vscode/README.md b/packages/svelte-vscode/README.md index 2dc2f4f2b..5821aaaba 100644 --- a/packages/svelte-vscode/README.md +++ b/packages/svelte-vscode/README.md @@ -148,13 +148,9 @@ Enable the Svelte plugin. _Default_: `true` Enable diagnostic messages for Svelte. _Default_: `true` -##### `svelte.plugin.svelte.ignoredCompilerWarnings` +##### `svelte.plugin.svelte.compilerWarnings` -Svelte compiler warning codes to ignore, comma-separated. Example: `css-unused-selector,unused-export-let`. - -##### `svelte.plugin.svelte.compilerWarningsAsErrors` - -Svelte compiler warning codes wich should be treated as errors, comma-separated. Example: `css-unused-selector,unused-export-let` +Svelte compiler warning codes to ignore or to treat as errors. Example: { 'css-unused-selector': 'ignore', 'unused-export-let': 'error'} ##### `svelte.plugin.svelte.format.enable` diff --git a/packages/svelte-vscode/package.json b/packages/svelte-vscode/package.json index 2a0c232da..6c7082e90 100644 --- a/packages/svelte-vscode/package.json +++ b/packages/svelte-vscode/package.json @@ -188,17 +188,18 @@ "title": "Svelte: Diagnostics", "description": "Enable diagnostic messages for Svelte" }, - "svelte.plugin.svelte.ignoredCompilerWarnings": { - "type": "string", - "default": "", - "title": "Svelte: Ignored Compiler Warnings", - "description": "Svelte compiler warning codes to ignore, comma-separated. Example: `css-unused-selector,unused-export-let`" - }, - "svelte.plugin.svelte.compilerWarningsAsErrors": { - "type": "string", - "default": "", - "title": "Svelte: Compiler Warnings to treat as Errors", - "description": "Svelte compiler warning codes wich should be treated as errors, comma-separated. Example: `css-unused-selector,unused-export-let`" + "svelte.plugin.svelte.compilerWarnings": { + "type": "object", + "additionalProperties": { + "type": "string", + "enum": [ + "ignore", + "error" + ] + }, + "default": {}, + "title": "Svelte: Compiler Warnings Settings", + "description": "Svelte compiler warning codes to ignore or to treat as errors. Example: { 'css-unused-selector': 'ignore', 'unused-export-let': 'error'}" }, "svelte.plugin.svelte.format.enable": { "type": "boolean", From 25d086845bac479fce6f94e46dfcec6657acc7fd Mon Sep 17 00:00:00 2001 From: Simon Holthausen Date: Tue, 25 Aug 2020 18:28:28 +0200 Subject: [PATCH 3/3] remove obsolete mapping function --- packages/language-server/src/ls-config.ts | 26 ----------------------- packages/language-server/src/server.ts | 6 +++--- 2 files changed, 3 insertions(+), 29 deletions(-) diff --git a/packages/language-server/src/ls-config.ts b/packages/language-server/src/ls-config.ts index 19adca4db..b08cdc9ec 100644 --- a/packages/language-server/src/ls-config.ts +++ b/packages/language-server/src/ls-config.ts @@ -186,29 +186,3 @@ export class LSConfigManager { } export const lsConfig = new LSConfigManager(); - -/** - * Parses a raw incoming config. - * Some options may come in a raw form (string with commas instead of string array) - * and need to be transformed accordingly. - */ -export function parseRawConfig(config: any): LSConfig { - return { - ...config, - svelte: { - ...config?.svelte, - ignoredCompilerWarnings: stringToArray(config?.svelte?.ignoredCompilerWarnings), - compilerWarningsAsErrors: stringToArray(config?.svelte?.compilerWarningsAsErrors), - }, - }; - - function stringToArray(str: string | string[] = ''): string[] { - if (Array.isArray(str)) { - return str; - } - return str - .split(',') - .map((s) => s.trim()) - .filter((s) => !!s); - } -} diff --git a/packages/language-server/src/server.ts b/packages/language-server/src/server.ts index e8ce9c502..00b394375 100644 --- a/packages/language-server/src/server.ts +++ b/packages/language-server/src/server.ts @@ -20,7 +20,7 @@ import { import { DiagnosticsManager } from './lib/DiagnosticsManager'; import { Document, DocumentManager } from './lib/documents'; import { Logger } from './logger'; -import { LSConfigManager, parseRawConfig } from './ls-config'; +import { LSConfigManager } from './ls-config'; import { AppCompletionItem, CSSPlugin, @@ -93,7 +93,7 @@ export function startServer(options?: LSOptions) { } pluginHost.initialize(!!evt.initializationOptions?.dontFilterIncompleteCompletions); - pluginHost.updateConfig(parseRawConfig(evt.initializationOptions?.config)); + pluginHost.updateConfig(evt.initializationOptions?.config); pluginHost.register( (sveltePlugin = new SveltePlugin( configManager, @@ -188,7 +188,7 @@ export function startServer(options?: LSOptions) { connection.onPrepareRename((req) => pluginHost.prepareRename(req.textDocument, req.position)); connection.onDidChangeConfiguration(({ settings }) => { - pluginHost.updateConfig(parseRawConfig(settings.svelte?.plugin)); + pluginHost.updateConfig(settings.svelte?.plugin); }); connection.onDidOpenTextDocument((evt) => {