How do I find cases of CoffeeScript 1.9.0 breaking

2019-05-07 07:05发布

问题:

TL;DR: Is there any way to identify violations to CoffeeScript's new 1.9.0 behavior for @foo parameter naming? It is now illegal, and does not cause a warning/error, to use the bare foo variable in the function.

In the 1.9.0 version of CoffeeScript is stated:

Changed strategy for the generation of internal compiler variable names. Note that this means that @example function parameters are no longer available as naked example variables within the function body.

This means

class Animal
  constructor: (@name) ->
    console.log name

.. will fail, silently. I.e the above will not print the new animal's name.

The new correct solution is:

class Animal
  constructor: (@name) ->
    console.log @name

CoffeeLint does not catch this. Is there any known stunt for finding the now illegal bare parameter use? Maybe a nifty script running on the generated javascript?

Here are 2 links about this:

  • https://groups.google.com/forum/?hl=en#!topic/coffeescript/SDRGFYXWBnQ
  • https://github.com/jashkenas/coffeescript/issues/3891

回答1:

The easiest thing would be to use older coffee version.

In case that is not possible, you can compile every source file and run that through eslint checking for no-undef rule. You can do that with following bash script:

#!/bin/bash

FILES=$@

# https://nodejs.org/api/globals.html
# Object.keys(global).concat(['__dirname', '__filename']).join(',')
DEFINED_GLOBALS='ArrayBuffer,Int8Array,Uint8Array,Uint8ClampedArray,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array,DataView,global,process,GLOBAL,root,Buffer,setTimeout,setInterval,clearTimeout,clearInterval,setImmediate,clearImmediate,console,module,require,__dirname,__filename'

function compile() {
  ./node_modules/.bin/coffee --print $1
}

function lint() {
  # checks only for undefined variables except DEFINED_GLOBALS
  ./node_modules/.bin/eslint\
    --stdin --no-color\
    --global $DEFINED_GLOBALS\
    --reset --rule 'no-undef: [true]'
}

function main() {
  for file in $FILES; do
    local problems=`compile $file | lint`
    if [[ $problems ]]; then
      echo -e "=== $file\n$problems\n\n"
    fi
  done
}

main

Save that as check.sh and run something along the following lines:

chmod u+x ./check.sh
npm install coffee-script eslint
find . -name "*.coffee" | xargs ./check.sh


回答2:

I’ve made a mod of the CoffeeScript compiler that console.errors each occurance where you are missing a @: https://github.com/lydell/coffee-script/tree/1.8-at-params-warn

To install it:

npm install lydell/coffee-script#1.8-at-params-warn

To check a file for missing @s, run for example:

./node_modules/.bin/coffee -p file-to-check.coffee >/dev/null

The above will log the file path, line number, column number and variable name for each variable that needs a @.