Back to Coffeescript

helpers.coffee

docs/v1/annotated-source/helpers.html

2.7.07.5 KB
Original Source

browser.coffeecake.coffeecoffee-script.coffeecommand.coffeegrammar.coffeehelpers.coffeeindex.coffeelexer.coffeenodes.coffeeoptparse.coffeeregister.coffeerepl.coffeerewriter.coffeescope.litcoffeesourcemap.litcoffee

helpers.coffee

This file contains the common helper functions that we’d like to share among the Lexer , Rewriter , and the Nodes. Merge objects, flatten arrays, count characters, that sort of thing.

Peek at the beginning of a given string to see if it matches a sequence.

exports.starts =(string, literal, start) -\>literalisstring.substr start, literal.length

Peek at the end of a given string to see if it matches a sequence.

exports.ends =(string, literal, back) -\>len = literal.length
  literalisstring.substr string.length - len - (backor0), len

Repeat a string n times.

exports.repeat = repeat =(str, n) -\>

Use clever algorithm to have O(log(n)) string concatenation operations.

res =''whilen >0res += strifn &1n >>>=1str += str
  res

Trim out all falsy values from an array.

exports.compact =(array) -\>itemforiteminarraywhenitem

Count the number of occurrences of a string in a string.

exports.count =(string, substr) -\>num = pos =0return1/0unlesssubstr.length
  num++whilepos =1+ string.indexOf substr, pos
  num

Merge objects, returning a fresh copy with attributes from both sides. Used every time Base#compile is called, to allow properties in the options hash to propagate down the tree without polluting other branches.

exports.merge =(options, overrides) -\>extend (extend {}, options), overrides

Extend a source object with the properties of another object (shallow copy).

extend = exports.extend =(object, properties) -\>forkey, valofproperties
    object[key] = val
  object

Return a flattened version of an array. Handy for getting a list of children from the nodes.

exports.flatten = flatten =(array) -\>flattened = []forelementinarrayif'[object Array]'isObject::toString.call element
      flattened = flattened.concat flatten elementelseflattened.push element
  flattened

Delete a key from an object, returning the value. Useful when a node is looking for a particular method in an options hash.

exports.del =(obj, key) -\>val = obj[key]deleteobj[key]
  val

Typical Array::some

exports.some = Array::some ? (fn) ->returntrueforeinthiswhenfn efalse

Simple function for inverting Literate CoffeeScript code by putting the documentation in comments, producing a string of CoffeeScript code that can be compiled “normally”.

exports.invertLiterate =(code) -\>maybe_code =truelines =forlineincode.split('\n')ifmaybe_codeand/^([]{4}|[]{0,3}\t)/.test line
      lineelseifmaybe_code =/^\s\*$/.test line
      lineelse'# '+ line
  lines.join'\n'

Merge two jison-style location data objects together. If last is not provided, this will simply return first.

buildLocationData = (first, last) -\>ifnotlast
    firstelsefirst_line: first.first_line
    first_column: first.first_column
    last_line: last.last_line
    last_column: last.last_column

This returns a function which takes an object as a parameter, and if that object is an AST node, updates that object’s locationData. The object is returned either way.

exports.addLocationDataFn =(first, last) -\>(obj) ->if((typeofobj)is'object')and(!!obj['updateLocationDataIfMissing'])
      obj.updateLocationDataIfMissing buildLocationData(first, last)returnobj

Convert jison location data to a string. obj can be a token, or a locationData.

exports.locationDataToString =(obj) -\>if("2"ofobj)and("first\_line"ofobj[2])thenlocationData = obj[2]elseif"first\_line"ofobjthenlocationData = objiflocationData"#{locationData.first\_line + 1}:#{locationData.first\_column + 1}-"+"#{locationData.last\_line + 1}:#{locationData.last\_column + 1}"else"No location data"

A .coffee.md compatible version of basename, that returns the file sans-extension.

exports.baseFileName =(file, stripExt = no, useWinPathSep = no) -\>pathSep =ifuseWinPathSepthen/\\|\//else/\//parts = file.split(pathSep)
  file = parts[parts.length -1]returnfileunlessstripExtandfile.indexOf('.') >=0parts = file.split('.')
  parts.pop()
  parts.pop()ifparts[parts.length -1]is'coffee'andparts.length >1parts.join('.')

Determine if a filename represents a CoffeeScript file.

exports.isCoffee =(file) -\>/\.((lit)?coffee|coffee\.md)$/.test file

Determine if a filename represents a Literate CoffeeScript file.

exports.isLiterate =(file) -\>/\.(litcoffee|coffee\.md)$/.test file

Throws a SyntaxError from a given location. The error’s toString will return an error message following the “standard” format <filename>:<line>:<col>: <message> plus the line with the error and a marker showing where the error is.

exports.throwSyntaxError =(message, location) -\>error =newSyntaxError message
  error.location = location
  error.toString = syntaxErrorToString

Instead of showing the compiler’s stacktrace, show our custom error message (this is useful when the error bubbles up in Node.js applications that compile CoffeeScript for example).

error.stack = error.toString()throwerror

Update a compiler SyntaxError with source code information if it didn’t have it already.

exports.updateSyntaxError =(error, code, filename) -\>

Avoid screwing up the stack property of other errors (i.e. possible bugs).

iferror.toStringissyntaxErrorToString
    error.codeor= code
    error.filenameor= filename
    error.stack = error.toString()
  error syntaxErrorToString = -\>returnError::toString.call @unless@codeand@location

  {first_line, first_column, last_line, last_column} = @location
  last_line ?= first_line
  last_column ?= first_column

  filename = @filenameor'[stdin]'codeLine = @code.split('\n')[first_line]
  start = first_column

Show only the first line on multi-line errors.

end =iffirst_lineislast_linethenlast_column +1elsecodeLine.length
  marker = codeLine[...start].replace(/[^\s]/g,' ') + repeat('^', end - start)

Check to see if we’re running on a color-enabled TTY.

ifprocess?
    colorsEnabled = process.stdout?.isTTYandnotprocess.env?.NODE_DISABLE_COLORSif@colorful ? colorsEnabledcolorize = (str) -\>"\x1B[1;31m#{str}\x1B[0m"codeLine = codeLine[...start] + colorize(codeLine[start...end]) + codeLine[end..]
    marker = colorize marker""" #{filename}:#{first\_line + 1}:#{first\_column + 1}: error: #{@message} #{codeLine} #{marker} """exports.nameWhitespaceCharacter =(string) -\>switchstringwhen' 'then'space'when'\n'then'newline'when'\r'then'carriage return'when'\t'then'tab'elsestring