Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
implement this.error
  • Loading branch information
Rich-Harris committed Jan 6, 2017
1 parent 6d41868 commit 7831164
Show file tree
Hide file tree
Showing 10 changed files with 99 additions and 84 deletions.
121 changes: 67 additions & 54 deletions src/utils/transform.js
@@ -1,7 +1,6 @@
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 ( bundle, source, id, plugins ) {
Expand All @@ -15,73 +14,87 @@ export default function transform ( bundle, 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 );

const context = {
warn: ( warning, pos ) => {
if ( typeof warning === 'string' ) {
warning = { message: warning };
}
plugins.forEach( plugin => {
if ( !plugin.transform ) return;

warning.plugin = plugin.name;
if ( !warning.code ) warning.code = 'PLUGIN_WARNING';
promise = promise.then( previous => {
function augment ( object, pos, code ) {
if ( typeof object === 'string' ) {
object = { message: object };
}

if ( pos !== undefined ) {
warning.pos = pos;
const { line, column } = locate( previous, pos, { offsetLine: 1 });
warning.loc = { file: id, line, column };
warning.frame = getCodeFrame( previous, line, column );
}
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 );
}

return object;
}

let err;

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

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

return Promise.resolve( plugin.transform.call( context, previous, id ) ).then( result => {
if ( result == null ) return previous;
let transformed;

if ( typeof result === 'string' ) {
result = {
code: result,
ast: null,
map: null
};
}
try {
transformed = plugin.transform.call( context, previous, id );
} catch ( err ) {
context.error( err );
}

// `result.map` can only be a string if `result` isn't
else if ( typeof result.map === 'string' ) {
result.map = JSON.parse( result.map );
}
return Promise.resolve( transformed )
.then( result => {
if ( err ) throw err;

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

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

return result.code;
});
}).catch( err => {
// TODO this all seems a bit hacky
if ( errored ) throw err;
errored = true;
// `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 );
}

err.plugin = plugin.name;
throw err;
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 );
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 7831164

Please sign in to comment.