diff --git a/src/compile/Component.ts b/src/compile/Component.ts index 3e76bf71b2..647068fdf1 100644 --- a/src/compile/Component.ts +++ b/src/compile/Component.ts @@ -164,7 +164,7 @@ export default class Component { this.fragment = new Fragment(this, ast.html); if (!options.customElement) this.stylesheet.reify(); - this.stylesheet.warnOnUnusedSelectors(options.onwarn); + this.stylesheet.warnOnUnusedSelectors(stats); if (!this.instance_script) { const props = [...this.template_references]; @@ -229,6 +229,7 @@ export default class Component { format, name, options, + this.stats, banner, options.sveltePath, importedHelpers, diff --git a/src/compile/css/Stylesheet.ts b/src/compile/css/Stylesheet.ts index 96e959c99d..2a22782a5a 100644 --- a/src/compile/css/Stylesheet.ts +++ b/src/compile/css/Stylesheet.ts @@ -8,6 +8,7 @@ import removeCSSPrefix from '../../utils/removeCSSPrefix'; import Element from '../nodes/Element'; import { Node, Ast, Warning } from '../../interfaces'; import Component from '../Component'; +import Stats from '../../Stats'; const isKeyframesNode = (node: Node) => removeCSSPrefix(node.name) === 'keyframes' @@ -391,7 +392,7 @@ export default class Stylesheet { }); } - warnOnUnusedSelectors(onwarn: (warning: Warning) => void) { + warnOnUnusedSelectors(stats: Stats) { let locator; const handler = (selector: Selector) => { @@ -404,7 +405,7 @@ export default class Stylesheet { const frame = getCodeFrame(this.source, start.line - 1, start.column); const message = `Unused CSS selector`; - onwarn({ + stats.warn({ code: `css-unused-selector`, message, frame, diff --git a/src/compile/index.ts b/src/compile/index.ts index 4037a6def7..8557bcdc75 100644 --- a/src/compile/index.ts +++ b/src/compile/index.ts @@ -6,17 +6,6 @@ import renderSSR from './render-ssr/index'; import { CompileOptions, Warning, Ast } from '../interfaces'; import Component from './Component'; -function normalize_options(options: CompileOptions): CompileOptions { - let normalized = assign({ generate: 'dom', dev: false }, options); - const { onwarn } = normalized; - - normalized.onwarn = onwarn - ? (warning: Warning) => onwarn(warning, default_onwarn) - : default_onwarn; - - return normalized; -} - function default_onwarn({ start, message }: Warning) { if (start) { console.warn(`(${start.line}:${start.column}) – ${message}`); @@ -45,10 +34,12 @@ function validate_options(options: CompileOptions, stats: Stats) { } export default function compile(source: string, options: CompileOptions = {}) { - options = normalize_options(options); + options = assign({ generate: 'dom', dev: false }, options); const stats = new Stats({ onwarn: options.onwarn + ? (warning: Warning) => options.onwarn(warning, default_onwarn) + : default_onwarn }); let ast: Ast; diff --git a/src/compile/wrapModule.ts b/src/compile/wrapModule.ts index 76dbe020bc..d4f8198bc0 100644 --- a/src/compile/wrapModule.ts +++ b/src/compile/wrapModule.ts @@ -1,6 +1,7 @@ import deindent from '../utils/deindent'; import list from '../utils/list'; import { CompileOptions, ModuleFormat, Node } from '../interfaces'; +import Stats from '../Stats'; interface Dependency { name: string; @@ -20,6 +21,7 @@ export default function wrapModule( format: ModuleFormat, name: string, options: CompileOptions, + stats: Stats, banner: string, sveltePath = 'svelte', helpers: { name: string, alias: string }[], @@ -34,7 +36,7 @@ export default function wrapModule( } if (format === 'cjs') return cjs(code, name, banner, sveltePath, internalPath, helpers, imports, module_exports); - if (format === 'eval') return expr(code, name, options, banner, imports); + if (format === 'eval') return expr(code, name, options, stats, banner, imports); throw new Error(`options.format is invalid (must be ${list(Object.keys(wrappers))})`); } @@ -142,6 +144,7 @@ function expr( code: string, name: string, options: CompileOptions, + stats: Stats, banner: string, imports: Node[] ) { @@ -182,7 +185,7 @@ function expr( return { name, statements, source: declaration.source.value }; }); - const globals = getGlobals(dependencies, options); + const globals = getGlobals(dependencies, options, stats); return deindent` (function (${paramString(dependencies)}) { "use strict"; @@ -212,8 +215,8 @@ function getCompatibilityStatements(dependencies: Dependency[]) { return statements.join('\n'); } -function getGlobals(dependencies: Dependency[], options: CompileOptions) { - const { globals, onwarn } = options; +function getGlobals(dependencies: Dependency[], options: CompileOptions, stats: Stats) { + const { globals } = options; const globalFn = getGlobalFn(globals); return dependencies.map(d => { @@ -225,12 +228,10 @@ function getGlobals(dependencies: Dependency[], options: CompileOptions) { `Could not determine name for imported module '${d.source}' – use options.globals` ); } else { - const warning = { + stats.warn({ code: `options-missing-globals`, message: `No name was supplied for imported module '${d.source}'. Guessing '${d.name}', but you should use options.globals`, - }; - - onwarn(warning); + }); } name = d.name; diff --git a/src/interfaces.ts b/src/interfaces.ts index c358ca20ed..ab2fcb1944 100644 --- a/src/interfaces.ts +++ b/src/interfaces.ts @@ -60,7 +60,7 @@ export interface CompileOptions { preserveComments?: boolean | false; - onwarn?: (warning: Warning) => void; + onwarn?: (warning: Warning, default_onwarn?: (warning: Warning) => void) => void; } export interface Visitor { diff --git a/test/css/index.js b/test/css/index.js index 237721daf1..224af150bd 100644 --- a/test/css/index.js +++ b/test/css/index.js @@ -69,6 +69,8 @@ describe('css', () => { }) ); + assert.deepEqual(dom.stats.warnings, domWarnings); + const ssr = svelte.compile( input, Object.assign(config, { @@ -81,6 +83,8 @@ describe('css', () => { }) ); + assert.deepEqual(dom.stats.warnings, domWarnings); + assert.equal(dom.css.code, ssr.css.code); assert.deepEqual( diff --git a/test/validator/index.js b/test/validator/index.js index 6a1b446617..9ca3fc57d1 100644 --- a/test/validator/index.js +++ b/test/validator/index.js @@ -83,43 +83,26 @@ describe("validate", () => { }); it("warns if options.name is not capitalised", () => { - const warnings = []; - svelte.compile("
", { + const { stats } = svelte.compile("", { name: "lowercase", - onwarn(warning) { - warnings.push({ - code: warning.code, - message: warning.message, - pos: warning.pos, - start: warning.start - }); - }, generate: false }); - assert.deepEqual(warnings, [ - { - code: `options-lowercase-name`, - message: "options.name should be capitalised", - pos: undefined, - start: undefined - } - ]); + + assert.deepEqual(stats.warnings.map(w => ({ + code: w.code, + message: w.message + })), [{ + code: `options-lowercase-name`, + message: "options.name should be capitalised" + }]); }); it("does not warn if options.name begins with non-alphabetic character", () => { - const warnings = []; - svelte.compile("", { + const { stats } = svelte.compile("", { name: "_", - onwarn(warning) { - warnings.push({ - code: warning.code, - message: warning.message, - pos: warning.pos, - start: warning.start - }); - }, generate: false }); - assert.deepEqual(warnings, []); + + assert.deepEqual(stats.warnings, []); }); });