[fix] be able to silence more warnings

including css-unused-selector, unused-export-let, module-script-reactive-declaration
Fixes #5954
Related to #5281
pull/6504/head
Simon Holthausen 5 years ago
parent b662c7fd41
commit 39fab6ee8b

@ -36,6 +36,7 @@ import { DecodedSourceMap, RawSourceMap } from '@ampproject/remapping/dist/types
import { clone } from '../utils/clone';
import compiler_warnings from './compiler_warnings';
import compiler_errors from './compiler_errors';
import { extract_svelte_ignore_from_comments } from './utils/extract_svelte_ignore';
interface ComponentOptions {
namespace?: string;
@ -476,6 +477,14 @@ export default class Component {
}
extract_exports(node) {
const ignores = extract_svelte_ignore_from_comments(node);
if (ignores.length) this.push_ignores(ignores);
const result = this._extract_exports(node);
if (ignores.length) this.pop_ignores();
return result;
}
private _extract_exports(node) {
if (node.type === 'ExportDefaultDeclaration') {
this.error(node, compiler_errors.default_export);
}
@ -1169,6 +1178,9 @@ export default class Component {
}> = [];
this.ast.instance.content.body.forEach(node => {
const ignores = extract_svelte_ignore_from_comments(node);
if (ignores.length) this.push_ignores(ignores);
if (node.type === 'LabeledStatement' && node.label.name === '$') {
this.reactive_declaration_nodes.add(node);
@ -1246,6 +1258,8 @@ export default class Component {
declaration
});
}
if (ignores.length) this.pop_ignores();
});
const lookup = new Map();

@ -7,6 +7,7 @@ import Component from '../Component';
import { CssNode } from './interfaces';
import hash from '../utils/hash';
import compiler_warnings from '../compiler_warnings';
import { extract_svelte_ignore } from '../utils/extract_svelte_ignore';
function remove_css_prefix(name: string): string {
return name.replace(/^-((webkit)|(moz)|(o)|(ms))-/, '');
@ -447,10 +448,37 @@ export default class Stylesheet {
}
warn_on_unused_selectors(component: Component) {
const ignores = this.get_ignores();
if (ignores.length) component.push_ignores(ignores);
this.children.forEach(child => {
child.warn_on_unused_selector((selector: Selector) => {
component.warn(selector.node, compiler_warnings.css_unused_selector(this.source.slice(selector.node.start, selector.node.end)));
});
});
if (ignores.length) component.pop_ignores();
}
private get_ignores(): string[] {
const previous_node_idx = !this.ast.css ? -1 : this.ast.html.children.findIndex(child => child.end === this.ast.css.start);
if (previous_node_idx === -1) {
return [];
}
for (let i = previous_node_idx; i >= 0; i--) {
const node = this.ast.html.children[i];
if (node.type !== 'Comment' && node.type !== 'Text') {
return [];
}
if (node.type === 'Comment') {
const ignores = extract_svelte_ignore(node.data || '');
if (ignores.length) {
return ignores;
}
}
}
return [];
}
}

@ -1,10 +1,9 @@
import { TemplateNode } from '../../interfaces';
import Component from '../Component';
import { extract_svelte_ignore } from '../utils/extract_svelte_ignore';
import Node from './shared/Node';
import TemplateScope from './shared/TemplateScope';
const pattern = /^\s*svelte-ignore\s+([\s\S]+)\s*$/m;
export default class Comment extends Node {
type: 'Comment';
data: string;
@ -13,8 +12,6 @@ export default class Comment extends Node {
constructor(component: Component, parent: Node, scope: TemplateScope, info: TemplateNode) {
super(component, parent, scope, info);
this.data = info.data;
const match = pattern.exec(this.data);
this.ignores = match ? match[1].split(/[^\S]/).map(x => x.trim()).filter(Boolean) : [];
this.ignores = extract_svelte_ignore(this.data)
}
}

@ -10,6 +10,7 @@ import { ClassDeclaration, FunctionExpression, Node, Statement, ObjectExpression
import { apply_preprocessor_sourcemap } from '../../utils/mapped_code';
import { RawSourceMap, DecodedSourceMap } from '@ampproject/remapping/dist/types/types';
import { Node as PeriscopicNode } from 'periscopic';
import { flatten } from '../utils/flatten';
export default function dom(
component: Component,
@ -551,18 +552,5 @@ export default function dom(
body.push(declaration);
}
return { js: flatten(body, []), css };
}
function flatten(nodes: any[], target: any[]) {
for (let i = 0; i < nodes.length; i += 1) {
const node = nodes[i];
if (Array.isArray(node)) {
flatten(node, target);
} else {
target.push(node);
}
}
return target;
return { js: flatten(body), css };
}

@ -0,0 +1,12 @@
import { flatten } from "./flatten";
const pattern = /^\s*svelte-ignore\s+([\s\S]+)\s*$/m;
export function extract_svelte_ignore(text: string): string[] {
const match = pattern.exec(text);
return match ? match[1].split(/[^\S]/).map(x => x.trim()).filter(Boolean) : [];
}
export function extract_svelte_ignore_from_comments<Node extends { leadingComments?: Array<{value: string}> }>(node: Node): string[] {
return flatten((node.leadingComments || []).map(comment => extract_svelte_ignore(comment.value)));
}

@ -0,0 +1,14 @@
export function flatten<T>(nodes: T[][], target?: T[]): T[];
export function flatten<T>(nodes: T[], target?: T[]): T[];
export function flatten(nodes: any[], target: any[] = []): any[] {
for (let i = 0; i < nodes.length; i += 1) {
const node = nodes[i];
if (Array.isArray(node)) {
flatten(node, target);
} else {
target.push(node);
}
}
return target;
}

@ -0,0 +1,15 @@
<script context="module">
let foo;
</script>
<script>
// svelte-ignore unused-export-let
export let unused;
// svelte-ignore module-script-reactive-declaration
$: reactive = foo;
</script>
<!-- svelte-ignore css-unused-selector -->
<style>
.unused {}
</style>
Loading…
Cancel
Save