UNPKG

coffeelint

Version:
88 lines (71 loc) 2.82 kB
BaseLinter = require './base_linter.coffee' node_children = Class: ['variable', 'parent', 'body'] Code: ['params', 'body'] For: ['body', 'source', 'guard', 'step'] If: ['condition', 'body', 'elseBody'] Obj: ['properties'] Op: ['first', 'second'] Switch: ['subject', 'cases', 'otherwise'] Try: ['attempt', 'recovery', 'ensure'] Value: ['base', 'properties'] While: ['condition', 'guard', 'body'] hasChildren = (node, children) -> node?.children?.length is children.length and node?.children.every (elem, i) -> elem is children[i] class ASTApi constructor: (@config) -> getNodeName: (node) -> name = node?.constructor?.name if node_children[name] return name else for own name, children of node_children if hasChildren(node, children) return name # A class that performs static analysis of the abstract # syntax tree. module.exports = class ASTLinter extends BaseLinter constructor : (source, config, rules, @CoffeeScript) -> super source, config, rules @astApi = new ASTApi @config # This uses lintAST instead of lintNode because I think it makes it a bit # more clear that the rule needs to walk the AST on its own. acceptRule: (rule) -> return typeof rule.lintAST is 'function' lint : () -> errors = [] try @node = @CoffeeScript.nodes(@source) catch coffeeError # If for some reason you shut off the 'coffeescript_error' rule err # will be null and should NOT be added to errors err = @_parseCoffeeScriptError(coffeeError) errors.push err if err? return errors for rule in @rules @astApi.createError = (attrs = {}) => @createError rule.rule.name, attrs # HACK: Push the local errors object into the plugin. This is a # temporary solution until I have a way for it to really return # multiple errors. rule.errors = errors v = @normalizeResult rule, rule.lintAST(@node, @astApi) return v if v? errors _parseCoffeeScriptError : (coffeeError) -> rule = @config['coffeescript_error'] message = coffeeError.toString() # Parse the line number lineNumber = -1 if coffeeError.location? lineNumber = coffeeError.location.first_line + 1 else match = /line (\d+)/.exec message lineNumber = parseInt match[1], 10 if match?.length > 1 attrs = { message: message level: rule.level lineNumber: lineNumber } return @createError 'coffeescript_error', attrs