eslint-plugin-no-use-extend-native icon indicating copy to clipboard operation
eslint-plugin-no-use-extend-native copied to clipboard

Investigate plugin blowing up

Open dustinspecker opened this issue 9 years ago • 5 comments

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.

dustinspecker avatar Dec 19 '15 19:12 dustinspecker

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] } } }

brandon93s avatar Dec 21 '15 00:12 brandon93s

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;
}

brandon93s avatar Dec 21 '15 00:12 brandon93s

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

brandon93s avatar Dec 21 '15 00:12 brandon93s

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.

acorn.zip

brandon93s avatar Dec 21 '15 02:12 brandon93s

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.

dustinspecker avatar Dec 22 '15 00:12 dustinspecker

Almost 10 years later, I'm just going to close this 😃

dustinspecker avatar May 22 '24 02:05 dustinspecker