Skip to content

feat: add ability to ignore warnings through compiler option #12296

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Jul 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/little-seals-reflect.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'svelte': patch
---

feat: add ability to ignore warnings through `warningFilter` compiler option
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { warnings, ignore_stack, ignore_map } from './state.js';
import { warnings, ignore_stack, ignore_map, warning_filter } from './state.js';
import { CompileDiagnostic } from './utils/compile_diagnostic.js';

/** @typedef {{ start?: number, end?: number }} NodeLike */
Expand Down Expand Up @@ -28,13 +28,15 @@ function w(node, code, message) {
}
if (stack && stack.at(-1)?.has(code)) return;

warnings.push(
new InternalCompileWarning(
code,
message,
node && node.start !== undefined ? [node.start, node.end ?? node.start] : undefined
)
const warning = new InternalCompileWarning(
code,
message,
node && node.start !== undefined ? [node.start, node.end ?? node.start] : undefined
);

if (!warning_filter(warning)) return;

warnings.push(warning);
}

export const codes = CODES;
Expand Down
3 changes: 3 additions & 0 deletions packages/svelte/src/compiler/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export { default as preprocess } from './preprocess/index.js';
* @returns {CompileResult}
*/
export function compile(source, options) {
state.reset_warning_filter(options.warningFilter);
const validated = validate_component_options(options, '');
state.reset(source, validated);

Expand Down Expand Up @@ -58,6 +59,7 @@ export function compile(source, options) {
* @returns {CompileResult}
*/
export function compileModule(source, options) {
state.reset_warning_filter(options.warningFilter);
const validated = validate_module_options(options, '');
state.reset(source, validated);

Expand Down Expand Up @@ -103,6 +105,7 @@ export function compileModule(source, options) {
* @returns {Root | LegacyRoot}
*/
export function parse(source, { filename, rootDir, modern } = {}) {
state.reset_warning_filter(() => false);
state.reset(source, { filename, rootDir }); // TODO it's weird to require filename/rootDir here. reconsider the API

const ast = _parse(source);
Expand Down
3 changes: 2 additions & 1 deletion packages/svelte/src/compiler/migrate/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { parse } from '../phases/1-parse/index.js';
import { analyze_component } from '../phases/2-analyze/index.js';
import { validate_component_options } from '../validate-options.js';
import { get_rune } from '../phases/scope.js';
import { reset } from '../state.js';
import { reset, reset_warning_filter } from '../state.js';
import { extract_identifiers } from '../utils/ast.js';
import { regex_is_valid_identifier } from '../phases/patterns.js';
import { migrate_svelte_ignore } from '../utils/extract_svelte_ignore.js';
Expand All @@ -24,6 +24,7 @@ import { migrate_svelte_ignore } from '../utils/extract_svelte_ignore.js';
*/
export function migrate(source) {
try {
reset_warning_filter(() => false);
reset(source, { filename: 'migrate.svelte' });

let parsed = parse(source);
Expand Down
13 changes: 12 additions & 1 deletion packages/svelte/src/compiler/state.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/** @import { SvelteNode } from './types' */
/** @import { CompileOptions, SvelteNode } from './types' */
/** @import { Warning } from '#compiler' */
import { getLocator } from 'locate-character';

Expand All @@ -22,6 +22,9 @@ export let source;

export let locator = getLocator('', { offsetLine: 1 });

/** @type {NonNullable<CompileOptions['warningFilter']>} */
export let warning_filter;

/**
* The current stack of ignored warnings
* @type {Set<string>[]}
Expand All @@ -48,6 +51,14 @@ export function pop_ignore() {
ignore_stack.pop();
}

/**
*
* @param {(warning: Warning) => boolean} fn
*/
export function reset_warning_filter(fn = () => true) {
warning_filter = fn;
}

/**
* @param {string} _source
* @param {{ filename?: string, rootDir?: string }} options
Expand Down
6 changes: 5 additions & 1 deletion packages/svelte/src/compiler/types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,12 +203,16 @@ export interface ModuleCompileOptions {
* Used for debugging hints and sourcemaps. Your bundler plugin will set it automatically.
*/
filename?: string;

/**
* Used for ensuring filenames don't leak filesystem information. Your bundler plugin will set it automatically.
* @default process.cwd() on node-like environments, undefined elsewhere
*/
rootDir?: string;
/**
* A function that gets a `Warning` as an argument and returns a boolean.
* Use this to filter out warnings. Return `true` to keep the warning, `false` to discard it.
*/
warningFilter?: (warning: Warning) => boolean;
}

// The following two somewhat scary looking types ensure that certain types are required but can be undefined still
Expand Down
16 changes: 16 additions & 0 deletions packages/svelte/src/compiler/validate-options.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ export const validate_component_options =

hmr: boolean(false),

warningFilter: fun(() => true),

sourcemap: validator(undefined, (input) => {
// Source maps can take on a variety of values, including string, JSON, map objects from magic-string and source-map,
// so there's no good way to check type validity here
Expand Down Expand Up @@ -259,6 +261,20 @@ function string(fallback, allow_empty = true) {
});
}

/**
* @param {string[]} fallback
* @returns {Validator}
*/
function string_array(fallback) {
return validator(fallback, (input, keypath) => {
if (input && !Array.isArray(input)) {
throw_error(`${keypath} should be a string array, if specified`);
}

return input;
});
}

/**
* @param {boolean | undefined} fallback
* @returns {Validator}
Expand Down
14 changes: 12 additions & 2 deletions packages/svelte/src/compiler/warnings.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
/* This file is generated by scripts/process-messages/index.js. Do not edit! */

import { warnings, ignore_stack, ignore_map } from './state.js';
import {
warnings,
ignore_stack,
ignore_map,
warning_filter
} from './state.js';

import { CompileDiagnostic } from './utils/compile_diagnostic.js';

/** @typedef {{ start?: number, end?: number }} NodeLike */
Expand Down Expand Up @@ -30,7 +36,11 @@ function w(node, code, message) {
}

if (stack && stack.at(-1)?.has(code)) return;
warnings.push(new InternalCompileWarning(code, message, node && node.start !== undefined ? [node.start, node.end ?? node.start] : undefined));

const warning = new InternalCompileWarning(code, message, node && node.start !== undefined ? [node.start, node.end ?? node.start] : undefined);

if (!warning_filter(warning)) return;
warnings.push(warning);
}

export const codes = [
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { test } from '../../test';

export default test({
compileOptions: {
warningFilter: (warning) =>
!['a11y_missing_attribute', 'a11y_misplaced_scope'].includes(warning.code)
}
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<div>
<img src="this-is-fine.jpg" />
<marquee>but this is still discouraged</marquee>
</div>

<div scope></div>

<img src="potato.jpg" />
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[
{
"code": "a11y_distracting_elements",
"end": {
"column": 49,
"line": 3
},
"message": "Avoid `<marquee>` elements",
"start": {
"column": 1,
"line": 3
}
}
]
12 changes: 10 additions & 2 deletions packages/svelte/types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -864,12 +864,16 @@ declare module 'svelte/compiler' {
* Used for debugging hints and sourcemaps. Your bundler plugin will set it automatically.
*/
filename?: string;

/**
* Used for ensuring filenames don't leak filesystem information. Your bundler plugin will set it automatically.
* @default process.cwd() on node-like environments, undefined elsewhere
*/
rootDir?: string;
/**
* A function that gets a `Warning` as an argument and returns a boolean.
* Use this to filter out warnings. Return `true` to keep the warning, `false` to discard it.
*/
warningFilter?: (warning: Warning) => boolean;
}

type DeclarationKind =
Expand Down Expand Up @@ -2672,12 +2676,16 @@ declare module 'svelte/types/compiler/interfaces' {
* Used for debugging hints and sourcemaps. Your bundler plugin will set it automatically.
*/
filename?: string;

/**
* Used for ensuring filenames don't leak filesystem information. Your bundler plugin will set it automatically.
* @default process.cwd() on node-like environments, undefined elsewhere
*/
rootDir?: string;
/**
* A function that gets a `Warning` as an argument and returns a boolean.
* Use this to filter out warnings. Return `true` to keep the warning, `false` to discard it.
*/
warningFilter?: (warning: Warning_1) => boolean;
}
/**
* - `html` — the default, for e.g. `<div>` or `<span>`
Expand Down
Loading