Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request #1231 from rollup/gh-1140
[WIP] [BREAKING] add this.warn method to plugin contexts
  • Loading branch information
Rich-Harris committed Jan 6, 2017
2 parents 79d1ecf + be7c90f commit e955ea7
Show file tree
Hide file tree
Showing 14 changed files with 172 additions and 98 deletions.
41 changes: 17 additions & 24 deletions bin/src/logging.js
Expand Up @@ -8,40 +8,33 @@ const errorSymbol = process.stderr.isTTY ? `🚨 ` : `Error: `;
// log to stderr to keep `rollup main.js > bundle.js` from breaking
export const stderr = console.error.bind( console ); // eslint-disable-line no-console

export function handleWarning ( warning ) {
stderr( `${warnSymbol}${chalk.bold( warning.message )}` );
function log ( object, symbol ) {
const message = object.plugin ? `(${object.plugin} plugin) ${object.message}` : object.message;

stderr( `${symbol}${chalk.bold( message )}` );

if ( warning.url ) {
stderr( chalk.cyan( warning.url ) );
if ( object.url ) {
stderr( chalk.cyan( object.url ) );
}

if ( warning.loc ) {
stderr( `${relativeId( warning.loc.file )} (${warning.loc.line}:${warning.loc.column})` );
if ( object.loc ) {
stderr( `${relativeId( object.loc.file )} (${object.loc.line}:${object.loc.column})` );
} else if ( object.id ) {
stderr( relativeId( object.id ) );
}

if ( warning.frame ) {
stderr( chalk.dim( warning.frame ) );
if ( object.frame ) {
stderr( chalk.dim( object.frame ) );
}

stderr( '' );
}

export function handleError ( err, recover ) {
stderr( `${errorSymbol}${chalk.bold( err.message )}` );

if ( err.url ) {
stderr( chalk.cyan( err.url ) );
}

if ( err.loc ) {
stderr( `${relativeId( err.loc.file )} (${err.loc.line}:${err.loc.column})` );
}

if ( err.frame ) {
stderr( chalk.dim( err.frame ) );
}

stderr( '' );
export function handleWarning ( warning ) {
log( warning, warnSymbol );
}

export function handleError ( err, recover ) {
log( err, errorSymbol );
if ( !recover ) process.exit( 1 );
}
12 changes: 7 additions & 5 deletions src/Bundle.js
Expand Up @@ -293,7 +293,7 @@ export default class Bundle {
return this.cachedModules.get( id );
}

return transform( source, id, this.plugins );
return transform( this, source, id, this.plugins );
})
.then( source => {
const { code, originalCode, originalSourceMap, ast, sourceMapChain, resolvedIds } = source;
Expand Down Expand Up @@ -619,11 +619,13 @@ export default class Bundle {

warn ( warning ) {
warning.toString = () => {
if ( warning.loc ) {
return `${relativeId( warning.loc.file )} (${warning.loc.line}:${warning.loc.column}) ${warning.message}`;
}
let str = '';

if ( warning.plugin ) str += `(${warning.plugin} plugin) `;
if ( warning.loc ) str += `${relativeId( warning.loc.file )} (${warning.loc.line}:${warning.loc.column}) `;
str += warning.message;

return warning.message;
return str;
};

this.onwarn( warning );
Expand Down
115 changes: 76 additions & 39 deletions src/utils/transform.js
@@ -1,8 +1,9 @@
import { decode } from 'sourcemap-codec';
import { locate } from 'locate-character';
import error from './error.js';
import relativeId from './relativeId.js';
import getCodeFrame from './getCodeFrame.js';

export default function transform ( source, id, plugins ) {
export default function transform ( bundle, source, id, plugins ) {
const sourceMapChain = [];

const originalSourceMap = typeof source.map === 'string' ? JSON.parse( source.map ) : source.map;
Expand All @@ -13,52 +14,88 @@ export default function transform ( source, id, plugins ) {

const originalCode = source.code;
let ast = source.ast;
let errored = false;

return plugins.reduce( ( promise, plugin ) => {
return promise.then( previous => {
if ( !plugin.transform ) return previous;
let promise = Promise.resolve( source.code );

return Promise.resolve( plugin.transform( previous, id ) ).then( result => {
if ( result == null ) return previous;
plugins.forEach( plugin => {
if ( !plugin.transform ) return;

if ( typeof result === 'string' ) {
result = {
code: result,
ast: null,
map: null
};
promise = promise.then( previous => {
function augment ( object, pos, code ) {
if ( typeof object === 'string' ) {
object = { message: object };
}
// `result.map` can only be a string if `result` isn't
else if ( typeof result.map === 'string' ) {
result.map = JSON.parse( result.map );

if ( !object.code ) object.code = code;

if ( pos !== undefined ) {
object.pos = pos;
const { line, column } = locate( previous, pos, { offsetLine: 1 });
object.loc = { file: id, line, column };
object.frame = getCodeFrame( previous, line, column );
}

if ( result.map && typeof result.map.mappings === 'string' ) {
result.map.mappings = decode( result.map.mappings );
return object;
}

let err;

const context = {
warn: ( warning, pos ) => {
warning = augment( warning, pos, 'PLUGIN_WARNING' );
warning.plugin = plugin.name;
warning.id = id;
bundle.warn( warning );
},

error ( e, pos ) {
err = augment( e, pos, 'PLUGIN_ERROR' );
}
};

let transformed;

sourceMapChain.push( result.map || { missing: true, plugin: plugin.name }); // lil' bit hacky but it works
ast = result.ast;
try {
transformed = plugin.transform.call( context, previous, id );
} catch ( err ) {
context.error( err );
}

return result.code;
});
}).catch( err => {
// TODO this all seems a bit hacky
if ( errored ) throw err;
errored = true;
return Promise.resolve( transformed )
.then( result => {
if ( err ) throw err;

err.plugin = plugin.name;
throw err;
if ( result == null ) return previous;

if ( typeof result === 'string' ) {
result = {
code: result,
ast: null,
map: null
};
}

// `result.map` can only be a string if `result` isn't
else if ( typeof result.map === 'string' ) {
result.map = JSON.parse( result.map );
}

if ( result.map && typeof result.map.mappings === 'string' ) {
result.map.mappings = decode( result.map.mappings );
}

sourceMapChain.push( result.map || { missing: true, plugin: plugin.name }); // lil' bit hacky but it works
ast = result.ast;

return result.code;
})
.catch( err => {
err.plugin = plugin.name;
err.id = id;
error( err );
});
});
}, Promise.resolve( source.code ) )
.catch( err => {
error({
code: 'BAD_TRANSFORMER',
message: `Error transforming ${relativeId( id )}${err.plugin ? ` with '${err.plugin}' plugin` : ''}: ${err.message}`,
plugin: err.plugin,
id
});
})
.then( code => ({ code, originalCode, originalSourceMap, ast, sourceMapChain }) );
});

return promise.then( code => ({ code, originalCode, originalSourceMap, ast, sourceMapChain }) );
}
Expand Up @@ -20,8 +20,8 @@ module.exports = {
]
},
error: {
code: 'BAD_TRANSFORMER',
message: `Error transforming main.js with 'plugin1' plugin: Something happened 1`,
code: 'PLUGIN_ERROR',
message: `Something happened 1`,
plugin: 'plugin1',
id: path.resolve( __dirname, 'main.js' )
}
Expand Down
29 changes: 29 additions & 0 deletions test/function/plugin-error/_config.js
@@ -0,0 +1,29 @@
const path = require( 'path' );

module.exports = {
description: 'plugin transform hooks can use `this.error({...}, char)` (#1140)',
options: {
plugins: [{
name: 'test',
transform ( code, id ) {
this.error( 'nope', 22 );
}
}]
},
error: {
code: 'PLUGIN_ERROR',
plugin: 'test',
message: 'nope',
id: path.resolve( __dirname, 'main.js' ),
pos: 22,
loc: {
file: path.resolve( __dirname, 'main.js' ),
line: 1,
column: 22
},
frame: `
1: assert.equal( 21 * 2, TK );
^
`
}
};
1 change: 1 addition & 0 deletions test/function/plugin-error/main.js
@@ -0,0 +1 @@
assert.equal( 21 * 2, TK );
39 changes: 39 additions & 0 deletions test/function/plugin-warn/_config.js
@@ -0,0 +1,39 @@
const path = require( 'path' );

module.exports = {
description: 'plugin transform hooks can use `this.warn({...}, char)` (#1140)',
options: {
plugins: [{
name: 'test',
transform ( code, id ) {
this.warn({ message: 'foo' });
this.warn( 'bar', 22 );
return 'assert.equal( 21 * 2, 42 );';
}
}]
},
warnings: [
{
code: 'PLUGIN_WARNING',
id: path.resolve( __dirname, 'main.js' ),
plugin: 'test',
message: 'foo'
},
{
code: 'PLUGIN_WARNING',
id: path.resolve( __dirname, 'main.js' ),
plugin: 'test',
message: 'bar',
pos: 22,
loc: {
file: path.resolve( __dirname, 'main.js' ),
line: 1,
column: 22
},
frame: `
1: assert.equal( 21 * 2, TK );
^
`
}
]
};
1 change: 1 addition & 0 deletions test/function/plugin-warn/main.js
@@ -0,0 +1 @@
assert.equal( 21 * 2, TK );
22 changes: 0 additions & 22 deletions test/function/report-transform-error-file/_config.js

This file was deleted.

3 changes: 0 additions & 3 deletions test/function/report-transform-error-file/foo.js

This file was deleted.

3 changes: 0 additions & 3 deletions test/function/report-transform-error-file/main.js

This file was deleted.

0 comments on commit e955ea7

Please sign in to comment.