eslint-plugin-no-use-extend-native
eslint-plugin-no-use-extend-native copied to clipboard
Investigate plugin blowing up
https://github.com/sindresorhus/xo/issues/61
Potentially not JS file types? I'd assume ESLint wouldn't emit the right Node types for this plugin to even get hit, but worth looking into.
I am unfamiliar with writing eslint plugins but did some digging.
When this error occurs:
node.object.type === 'NewExpression'
Which results in:
proto = node.object.callee.name;
While the callee
object exists, the name property does not. This results in undefined
and isJsType
throwing.
Node {
type: 'MemberExpression',
start: 37170,
end: 37209,
loc:
SourceLocation {
start: Position { line: 902, column: 9 },
end: Position { line: 902, column: 48 } },
object:
Node {
type: 'NewExpression',
start: 37170,
end: 37203,
loc: SourceLocation { start: [Object], end: [Object] },
callee:
Node {
type: 'MemberExpression',
start: 37174,
end: 37187,
loc: [Object],
object: [Object],
property: [Object],
computed: false,
range: [Object],
_babelType: 'MemberExpression' },
arguments: [ [Object], [Object] ],
range: [ 37170, 37203 ],
_babelType: 'NewExpression' },
property:
Node {
type: 'Identifier',
start: 37204,
end: 37209,
loc: SourceLocation { start: [Object], end: [Object] },
name: 'parse',
range: [ 37204, 37209 ],
_babelType: 'Identifier' },
computed: false,
range: [ 37170, 37209 ],
_babelType: 'MemberExpression',
parent:
Node {
type: 'CallExpression',
start: 37170,
end: 37211,
loc: SourceLocation { start: [Object], end: [Object] },
callee: [Circular],
arguments: [],
range: [ 37170, 37211 ],
_babelType: 'CallExpression',
parent:
Node {
type: 'ReturnStatement',
start: 37163,
end: 37212,
loc: [Object],
argument: [Circular],
range: [Object],
_babelType: 'ReturnStatement',
parent: [Object] } } }
Catching this unknown case and returning as if isJsType
had returned false allows the plugin to succeed as expected:
try{
if(!isJsType(proto))
return;
} catch(e){
return;
}
Through process of elimination the culprit module is acorn.
To reproduce:
mkdir demo
cd demo
npm init -y
xo --init
mkdir sub
cd sub
npm init -y
npm install acorn
cd ../
xo
Alternatively if not using xo, just make sure the plugin is run over the resulting directory from npm install acorn
node_modules/acorn
Update:
I've attached the individual file that is causing the throw. It is the built / distribution version of acorn generated on install. Because of this, it's probably not worth trying to figure out why it's blowing up since it isn't user code and eslint shouldn't be run against it to begin with.
I'd propose adding one of the following as a safe-guard:
try{
if(!isJsType(proto))
return;
} catch(e){
return;
}
or
if(typeof proto !== 'string' || !isJsType(proto))
return;
or
update is-js-type
to take an optional second parameter not to throw and return false
instead.
//is-js-type/src/index.js
module.exports = function isJsType(type, throw) {
if (typeof type !== 'string') {
if(throw === false)
return false;
throw new TypeError('Expected type to be a string');
}
return lowerCaseTypes.indexOf(type.toLowerCase()) > -1;
};
//eslint-plugin-no-use-extend-native/rules/no-use-extend-native.js
if(!isJsType(proto, false))
return;
Let me know what you think. I'd be glad to send a PR.
Thank you for all of the information! It's greatly appreciated.
Leaning towards your second solution.
I'd like to find the bit of code that causes this, so there is an appropriate test. I should have some time in the next couple of days to do some digging.
Thanks again for the info.
Almost 10 years later, I'm just going to close this 😃