UNPKG

node-mirror

Version:

node.js + CodeMirror = Great IDE and Admin Tool

1,421 lines (1,272 loc) 724 kB
!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.formatter=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ /** * Returns the lines from a file with comments removed. Will report erroneous * trailing tokens in multiline comments if an error reporter is provided. * * @param {JsFile} file * @param {Errors} [errors=null] errors * @returns {Array} */ exports.getLinesWithCommentsRemoved = function(file, errors) { var lines = file.getLines().concat(); file.getComments().reverse().forEach(function(comment) { var startLine = comment.loc.start.line; var startCol = comment.loc.start.column; var endLine = comment.loc.end.line; var endCol = comment.loc.end.column; var i = startLine - 1; if (startLine === endLine) { lines[i] = lines[i].substring(0, startCol) + lines[i].substring(endCol); } else { lines[i] = lines[i].substring(0, startCol); for (var x = i + 1; x < endLine - 1; x++) { lines[x] = ''; } lines[x] = lines[x].substring(endCol + 1); if (errors && lines[x] !== '') { errors.add( 'Multiline comments should not have tokens on its ending line', x + 1, endCol ); } } }); return lines; }; },{}],2:[function(require,module,exports){ var assert = require('assert'); var path = require('path'); var minimatch = require('minimatch'); var BUILTIN_OPTIONS = { plugins: true, preset: true, excludeFiles: true, additionalRules: true, fileExtensions: true, maxErrors: true, configPath: true, esnext: true, esprima: true, errorFilter: true }; /** * JSCS Configuration. * Browser/Rhino-compatible. * * @name Configuration */ function Configuration() { this._presets = {}; this._rules = {}; this._configuredRules = []; this._configuredFormattingRules = []; this._unsupportedRuleNames = []; this._fileExtensions = ['.js']; this._excludedFileMasks = []; this._excludedFileMatchers = []; this._ruleSettings = {}; this._maxErrors = null; this._basePath = '.'; this._overrides = {}; this._presetName = null; this._esnextEnabled = false; this._esprima = null; this._errorFilter = null; } /** * Load settings from a configuration. * * @param {Object} config */ Configuration.prototype.load = function(config) { this._throwNonCamelCaseErrorIfNeeded(config); var overrides = this._overrides; var currentConfig = {}; copyConfiguration(config, currentConfig); copyConfiguration(overrides, currentConfig); var ruleSettings = this._processConfig(currentConfig); var processedSettings = {}; Object.keys(ruleSettings).forEach(function(optionName) { var rule = this._rules[optionName]; if (rule) { var optionValue = ruleSettings[optionName]; if (optionValue !== null) { rule.configure(ruleSettings[optionName]); this._configuredRules.push(rule); if (rule.format) { this._configuredFormattingRules.push(rule); } processedSettings[optionName] = ruleSettings[optionName]; } } else { this._unsupportedRuleNames.push(optionName); } }, this); this._ruleSettings = processedSettings; }; /** * Returns resulting configuration after preset is applied and options are processed. * * @return {Object} */ Configuration.prototype.getProcessedConfig = function() { var result = {}; Object.keys(this._ruleSettings).forEach(function(key) { result[key] = this._ruleSettings[key]; }, this); result.excludeFiles = this._excludedFileMasks; result.fileExtensions = this._fileExtensions; result.maxErrors = this._maxErrors; result.preset = this._presetName; result.esnext = this._esnextEnabled; result.esprima = this._esprima; result.errorFilter = this._errorFilter; return result; }; /** * Returns list of configured formatting rules. * * @returns {Rule[]} */ Configuration.prototype.getConfiguredFormattingRules = function() { return this._configuredFormattingRules; }; /** * Returns list of configured rules. * * @returns {Rule[]} */ Configuration.prototype.getConfiguredRules = function() { return this._configuredRules; }; /** * Returns the list of unsupported rule names. * * @return {String[]} */ Configuration.prototype.getUnsupportedRuleNames = function() { return this._unsupportedRuleNames; }; /** * Returns excluded file mask list. * * @returns {String[]} */ Configuration.prototype.getExcludedFileMasks = function() { return this._excludedFileMasks; }; /** * Returns `true` if specified file path is excluded. * * @param {String} filePath * @returns {Boolean} */ Configuration.prototype.isFileExcluded = function(filePath) { filePath = path.resolve(filePath); return this._excludedFileMatchers.some(function(matcher) { return matcher.match(filePath); }); }; /** * Returns file extension list. * * @returns {String[]} */ Configuration.prototype.getFileExtensions = function() { return this._fileExtensions; }; /** * Returns maximal error count. * * @returns {Number|undefined} */ Configuration.prototype.getMaxErrors = function() { return this._maxErrors; }; /** * Returns `true` if `esnext` option is enabled. * * @returns {Boolean} */ Configuration.prototype.isESNextEnabled = function() { return this._esnextEnabled; }; /** * Returns `true` if `esprima` option is not null. * * @returns {Boolean} */ Configuration.prototype.hasCustomEsprima = function() { return !!this._esprima; }; /** * Returns the custom esprima parser. * * @returns {Object|null} */ Configuration.prototype.getCustomEsprima = function() { return this._esprima; }; /** * Returns the loaded error filter. * * @returns {Function|null} */ Configuration.prototype.getErrorFilter = function() { return this._errorFilter; }; /** * Returns base path. * * @returns {String} */ Configuration.prototype.getBasePath = function() { return this._basePath; }; /** * Overrides specified settings. * * @param {String} overrides */ Configuration.prototype.override = function(overrides) { Object.keys(overrides).forEach(function(key) { this._overrides[key] = overrides[key]; }, this); }; /** * Processes configuration and returns config options. * * @param {Object} config * @returns {Object} */ Configuration.prototype._processConfig = function(config) { var ruleSettings = {}; // Base path if (config.configPath) { assert( typeof config.configPath === 'string', '`configPath` option requires string value' ); this._basePath = path.dirname(config.configPath); } // Load plugins if (config.plugins) { assert(Array.isArray(config.plugins), '`plugins` option requires array value'); config.plugins.forEach(this._loadPlugin, this); } // Apply presets var presetName = config.preset; if (presetName) { this._presetName = presetName; assert(typeof presetName === 'string', '`preset` option requires string value'); var presetData = this._presets[presetName]; assert(Boolean(presetData), 'Preset "' + presetName + '" does not exist'); var presetResult = this._processConfig(presetData); Object.keys(presetResult).forEach(function(key) { ruleSettings[key] = presetResult[key]; }); } // File extensions if (config.fileExtensions) { assert( typeof config.fileExtensions === 'string' || Array.isArray(config.fileExtensions), '`fileExtensions` option requires string or array value' ); this._fileExtensions = [].concat(config.fileExtensions).map(function(ext) { return ext.toLowerCase(); }); } // File excludes if (config.excludeFiles) { assert(Array.isArray(config.excludeFiles), '`excludeFiles` option requires array value'); this._excludedFileMasks = config.excludeFiles; this._excludedFileMatchers = this._excludedFileMasks.map(function(fileMask) { return new minimatch.Minimatch(path.resolve(this._basePath, fileMask), { dot: true }); }, this); } // Additional rules if (config.additionalRules) { assert(Array.isArray(config.additionalRules), '`additionalRules` option requires array value'); config.additionalRules.forEach(this._loadAdditionalRule, this); } if (config.hasOwnProperty('maxErrors')) { var maxErrors = config.maxErrors === null ? null : Number(config.maxErrors); assert( maxErrors > 0 || isNaN(maxErrors) || maxErrors === null, '`maxErrors` option requires number or null value' ); this._maxErrors = maxErrors; } if (config.hasOwnProperty('esnext')) { assert( typeof config.esnext === 'boolean' || config.esnext === null, '`esnext` option requires boolean or null value' ); this._esnextEnabled = Boolean(config.esnext); } if (config.hasOwnProperty('esprima')) { this._loadEsprima(config.esprima); } if (config.hasOwnProperty('errorFilter')) { this._loadErrorFilter(config.errorFilter); } // Apply config options Object.keys(config).forEach(function(key) { if (!BUILTIN_OPTIONS[key]) { ruleSettings[key] = config[key]; } }); return ruleSettings; }; /** * Loads plugin data. * * @param {function(Configuration)} plugin * @protected */ Configuration.prototype._loadPlugin = function(plugin) { assert(typeof plugin === 'function', '`plugin` should be a function'); plugin(this); }; /** * Loads an error filter. * * @param {Function|null} errorFilter * @protected */ Configuration.prototype._loadErrorFilter = function(errorFilter) { assert( typeof errorFilter === 'function' || errorFilter === null, '`errorFilter` option requires a function or null value' ); this._errorFilter = errorFilter; }; /** * Loads a custom esprima. * * @param {Object|null} esprima * @protected */ Configuration.prototype._loadEsprima = function(esprima) { assert( (esprima && typeof esprima.parse === 'function') || esprima === null, '`esprima` option requires a null value or an object with a parse function' ); this._esprima = esprima; }; /** * Includes plugin in the configuration environment. * * @param {function(Configuration)|*} plugin */ Configuration.prototype.usePlugin = function(plugin) { this._loadPlugin(plugin); }; /** * Loads additional rule. * * @param {Rule} additionalRule * @protected */ Configuration.prototype._loadAdditionalRule = function(additionalRule) { assert(typeof additionalRule === 'object', '`additionalRule` should be an object'); this.registerRule(additionalRule); }; /** * Throws error for non camel-case options. * * @param {Object} ruleSettings * @protected */ Configuration.prototype._throwNonCamelCaseErrorIfNeeded = function(ruleSettings) { function symbolToUpperCase(s, symbol) { return symbol.toUpperCase(); } function fixSettings(originalSettings) { var result = {}; Object.keys(originalSettings).forEach(function(key) { var camelCaseName = key.replace(/_([a-zA-Z])/g, symbolToUpperCase); var value = originalSettings[key]; if (typeof value === 'object' && value !== null && !Array.isArray(value)) { value = fixSettings(value); } result[camelCaseName] = value; }); return result; } Object.keys(ruleSettings).forEach(function(key) { if (key.indexOf('_') !== -1) { throw new Error( 'JSCS now accepts configuration options in camel case. Sorry for inconvenience. ' + 'On the bright side, we tried to convert your jscs config to camel case.\n' + '----------------------------------------\n' + JSON.stringify(fixSettings(ruleSettings), null, 4) + '\n----------------------------------------\n' ); } }); }; /** * Adds rule to the collection. * * @param {Rule|function} rule Rule instance or rule class. */ Configuration.prototype.registerRule = function(rule) { if (typeof rule === 'function') { var RuleClass = rule; rule = new RuleClass(); } var optionName = rule.getOptionName(); assert(!this._rules.hasOwnProperty(optionName), 'Rule "' + optionName + '" is already registered'); this._rules[optionName] = rule; }; /** * Returns list of registered rules. * * @returns {Rule[]} */ Configuration.prototype.getRegisteredRules = function() { var rules = this._rules; return Object.keys(rules).map(function(ruleOptionName) { return rules[ruleOptionName]; }); }; /** * Adds preset to the collection. * * @param {String} presetName * @param {Object} presetConfig */ Configuration.prototype.registerPreset = function(presetName, presetConfig) { this._presets[presetName] = presetConfig; }; /** * Returns registered presets object (key - preset name, value - preset content). * * @returns {Object} */ Configuration.prototype.getRegisteredPresets = function() { return this._presets; }; /** * Returns `true` if preset with specified name exists. * * @param {String} presetName * @return {Boolean} */ Configuration.prototype.hasPreset = function(presetName) { return this._presets.hasOwnProperty(presetName); }; /** * Registers built-in Code Style cheking rules. */ Configuration.prototype.registerDefaultRules = function() { /* Important! These rules are linked explicitly to keep browser-version supported. */ this.registerRule(require('../rules/require-curly-braces')); this.registerRule(require('../rules/require-multiple-var-decl')); this.registerRule(require('../rules/disallow-multiple-var-decl')); this.registerRule(require('../rules/disallow-empty-blocks')); this.registerRule(require('../rules/require-space-after-keywords')); this.registerRule(require('../rules/require-space-before-keywords')); this.registerRule(require('../rules/disallow-space-after-keywords')); this.registerRule(require('../rules/disallow-space-before-keywords')); this.registerRule(require('../rules/require-parentheses-around-iife')); /* deprecated rules */ this.registerRule(require('../rules/require-left-sticked-operators')); this.registerRule(require('../rules/disallow-left-sticked-operators')); this.registerRule(require('../rules/require-right-sticked-operators')); this.registerRule(require('../rules/disallow-right-sticked-operators')); this.registerRule(require('../rules/validate-jsdoc')); /* deprecated rules (end) */ this.registerRule(require('../rules/require-operator-before-line-break')); this.registerRule(require('../rules/disallow-operator-before-line-break')); this.registerRule(require('../rules/disallow-implicit-type-conversion')); this.registerRule(require('../rules/require-camelcase-or-uppercase-identifiers')); this.registerRule(require('../rules/disallow-keywords')); this.registerRule(require('../rules/disallow-multiple-line-breaks')); this.registerRule(require('../rules/disallow-multiple-line-strings')); this.registerRule(require('../rules/validate-line-breaks')); this.registerRule(require('../rules/validate-quote-marks')); this.registerRule(require('../rules/validate-indentation')); this.registerRule(require('../rules/disallow-trailing-whitespace')); this.registerRule(require('../rules/disallow-mixed-spaces-and-tabs')); this.registerRule(require('../rules/require-keywords-on-new-line')); this.registerRule(require('../rules/disallow-keywords-on-new-line')); this.registerRule(require('../rules/require-line-feed-at-file-end')); this.registerRule(require('../rules/maximum-line-length')); this.registerRule(require('../rules/require-yoda-conditions')); this.registerRule(require('../rules/disallow-yoda-conditions')); this.registerRule(require('../rules/require-spaces-inside-object-brackets')); this.registerRule(require('../rules/require-spaces-inside-array-brackets')); this.registerRule(require('../rules/require-spaces-inside-parentheses')); this.registerRule(require('../rules/disallow-spaces-inside-object-brackets')); this.registerRule(require('../rules/disallow-spaces-inside-array-brackets')); this.registerRule(require('../rules/disallow-spaces-inside-parentheses')); this.registerRule(require('../rules/require-blocks-on-newline')); this.registerRule(require('../rules/require-space-after-object-keys')); this.registerRule(require('../rules/require-space-before-object-values')); this.registerRule(require('../rules/disallow-space-after-object-keys')); this.registerRule(require('../rules/disallow-space-before-object-values')); this.registerRule(require('../rules/disallow-quoted-keys-in-objects')); this.registerRule(require('../rules/disallow-dangling-underscores')); this.registerRule(require('../rules/require-aligned-object-values')); this.registerRule(require('../rules/disallow-padding-newlines-in-blocks')); this.registerRule(require('../rules/require-padding-newlines-in-blocks')); this.registerRule(require('../rules/require-padding-newlines-in-objects')); this.registerRule(require('../rules/disallow-padding-newlines-in-objects')); this.registerRule(require('../rules/require-newline-before-block-statements')); this.registerRule(require('../rules/disallow-newline-before-block-statements')); this.registerRule(require('../rules/require-padding-newlines-before-keywords')); this.registerRule(require('../rules/disallow-padding-newlines-before-keywords')); this.registerRule(require('../rules/disallow-trailing-comma')); this.registerRule(require('../rules/require-trailing-comma')); this.registerRule(require('../rules/disallow-comma-before-line-break')); this.registerRule(require('../rules/require-comma-before-line-break')); this.registerRule(require('../rules/disallow-space-before-block-statements.js')); this.registerRule(require('../rules/require-space-before-block-statements.js')); this.registerRule(require('../rules/disallow-space-before-postfix-unary-operators.js')); this.registerRule(require('../rules/require-space-before-postfix-unary-operators.js')); this.registerRule(require('../rules/disallow-space-after-prefix-unary-operators.js')); this.registerRule(require('../rules/require-space-after-prefix-unary-operators.js')); this.registerRule(require('../rules/disallow-space-before-binary-operators')); this.registerRule(require('../rules/require-space-before-binary-operators')); this.registerRule(require('../rules/disallow-space-after-binary-operators')); this.registerRule(require('../rules/require-space-after-binary-operators')); this.registerRule(require('../rules/require-spaces-in-conditional-expression')); this.registerRule(require('../rules/disallow-spaces-in-conditional-expression')); this.registerRule(require('../rules/require-spaces-in-function')); this.registerRule(require('../rules/disallow-spaces-in-function')); this.registerRule(require('../rules/require-spaces-in-function-expression')); this.registerRule(require('../rules/disallow-spaces-in-function-expression')); this.registerRule(require('../rules/require-spaces-in-anonymous-function-expression')); this.registerRule(require('../rules/disallow-spaces-in-anonymous-function-expression')); this.registerRule(require('../rules/require-spaces-in-named-function-expression')); this.registerRule(require('../rules/disallow-spaces-in-named-function-expression')); this.registerRule(require('../rules/require-spaces-in-function-declaration')); this.registerRule(require('../rules/disallow-spaces-in-function-declaration')); this.registerRule(require('../rules/require-spaces-in-call-expression')); this.registerRule(require('../rules/disallow-spaces-in-call-expression')); this.registerRule(require('../rules/validate-parameter-separator')); this.registerRule(require('../rules/require-space-between-arguments')); this.registerRule(require('../rules/disallow-space-between-arguments')); this.registerRule(require('../rules/require-capitalized-constructors')); this.registerRule(require('../rules/safe-context-keyword')); this.registerRule(require('../rules/require-dot-notation')); this.registerRule(require('../rules/require-space-after-line-comment')); this.registerRule(require('../rules/disallow-space-after-line-comment')); this.registerRule(require('../rules/require-anonymous-functions')); this.registerRule(require('../rules/disallow-anonymous-functions')); this.registerRule(require('../rules/require-function-declarations')); this.registerRule(require('../rules/disallow-function-declarations')); this.registerRule(require('../rules/require-capitalized-comments')); this.registerRule(require('../rules/disallow-capitalized-comments')); this.registerRule(require('../rules/require-line-break-after-variable-assignment')); this.registerRule(require('../rules/disallow-semicolons')); this.registerRule(require('../rules/require-spaces-in-for-statement')); this.registerRule(require('../rules/require-spaces-in-computed-memberExpression')); this.registerRule(require('../rules/validate-object-indentation')); }; /** * Registers built-in Code Style cheking presets. */ Configuration.prototype.registerDefaultPresets = function() { // https://github.com/airbnb/javascript this.registerPreset('airbnb', require('../../presets/airbnb.json')); // http://javascript.crockford.com/code.html this.registerPreset('crockford', require('../../presets/crockford.json')); // https://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml this.registerPreset('google', require('../../presets/google.json')); // http://gruntjs.com/contributing#syntax this.registerPreset('grunt', require('../../presets/grunt.json')); // https://contribute.jquery.org/style-guide/js/ this.registerPreset('jquery', require('../../presets/jquery.json')); // https://github.com/mrdoob/three.js/wiki/Mr.doob's-Code-Style%E2%84%A2 this.registerPreset('mdcs', require('../../presets/mdcs.json')); // https://www.mediawiki.org/wiki/Manual:Coding_conventions/JavaScript this.registerPreset('wikimedia', require('../../presets/wikimedia.json')); // https://github.com/yandex/codestyle/blob/master/js.md this.registerPreset('yandex', require('../../presets/yandex.json')); }; module.exports = Configuration; function copyConfiguration(source, dest) { Object.keys(source).forEach(function(key) { dest[key] = source[key]; }); if (source.configPath) { dest.configPath = source.configPath; } } },{"../../presets/airbnb.json":134,"../../presets/crockford.json":135,"../../presets/google.json":136,"../../presets/grunt.json":137,"../../presets/jquery.json":138,"../../presets/mdcs.json":139,"../../presets/wikimedia.json":140,"../../presets/yandex.json":141,"../rules/disallow-anonymous-functions":5,"../rules/disallow-capitalized-comments":6,"../rules/disallow-comma-before-line-break":7,"../rules/disallow-dangling-underscores":8,"../rules/disallow-empty-blocks":9,"../rules/disallow-function-declarations":10,"../rules/disallow-implicit-type-conversion":11,"../rules/disallow-keywords":13,"../rules/disallow-keywords-on-new-line":12,"../rules/disallow-left-sticked-operators":14,"../rules/disallow-mixed-spaces-and-tabs":15,"../rules/disallow-multiple-line-breaks":16,"../rules/disallow-multiple-line-strings":17,"../rules/disallow-multiple-var-decl":18,"../rules/disallow-newline-before-block-statements":19,"../rules/disallow-operator-before-line-break":20,"../rules/disallow-padding-newlines-before-keywords":21,"../rules/disallow-padding-newlines-in-blocks":22,"../rules/disallow-padding-newlines-in-objects":23,"../rules/disallow-quoted-keys-in-objects":24,"../rules/disallow-right-sticked-operators":25,"../rules/disallow-semicolons":26,"../rules/disallow-space-after-binary-operators":27,"../rules/disallow-space-after-keywords":28,"../rules/disallow-space-after-line-comment":29,"../rules/disallow-space-after-object-keys":30,"../rules/disallow-space-after-prefix-unary-operators.js":31,"../rules/disallow-space-before-binary-operators":32,"../rules/disallow-space-before-block-statements.js":33,"../rules/disallow-space-before-keywords":34,"../rules/disallow-space-before-object-values":35,"../rules/disallow-space-before-postfix-unary-operators.js":36,"../rules/disallow-space-between-arguments":37,"../rules/disallow-spaces-in-anonymous-function-expression":38,"../rules/disallow-spaces-in-call-expression":39,"../rules/disallow-spaces-in-conditional-expression":40,"../rules/disallow-spaces-in-function":43,"../rules/disallow-spaces-in-function-declaration":41,"../rules/disallow-spaces-in-function-expression":42,"../rules/disallow-spaces-in-named-function-expression":44,"../rules/disallow-spaces-inside-array-brackets":45,"../rules/disallow-spaces-inside-object-brackets":46,"../rules/disallow-spaces-inside-parentheses":47,"../rules/disallow-trailing-comma":48,"../rules/disallow-trailing-whitespace":49,"../rules/disallow-yoda-conditions":50,"../rules/maximum-line-length":51,"../rules/require-aligned-object-values":52,"../rules/require-anonymous-functions":53,"../rules/require-blocks-on-newline":54,"../rules/require-camelcase-or-uppercase-identifiers":55,"../rules/require-capitalized-comments":56,"../rules/require-capitalized-constructors":57,"../rules/require-comma-before-line-break":58,"../rules/require-curly-braces":59,"../rules/require-dot-notation":60,"../rules/require-function-declarations":61,"../rules/require-keywords-on-new-line":62,"../rules/require-left-sticked-operators":63,"../rules/require-line-break-after-variable-assignment":64,"../rules/require-line-feed-at-file-end":65,"../rules/require-multiple-var-decl":66,"../rules/require-newline-before-block-statements":67,"../rules/require-operator-before-line-break":68,"../rules/require-padding-newlines-before-keywords":69,"../rules/require-padding-newlines-in-blocks":70,"../rules/require-padding-newlines-in-objects":71,"../rules/require-parentheses-around-iife":72,"../rules/require-right-sticked-operators":73,"../rules/require-space-after-binary-operators":74,"../rules/require-space-after-keywords":75,"../rules/require-space-after-line-comment":76,"../rules/require-space-after-object-keys":77,"../rules/require-space-after-prefix-unary-operators.js":78,"../rules/require-space-before-binary-operators":79,"../rules/require-space-before-block-statements.js":80,"../rules/require-space-before-keywords":81,"../rules/require-space-before-object-values":82,"../rules/require-space-before-postfix-unary-operators.js":83,"../rules/require-space-between-arguments":84,"../rules/require-spaces-in-anonymous-function-expression":85,"../rules/require-spaces-in-call-expression":86,"../rules/require-spaces-in-computed-memberExpression":87,"../rules/require-spaces-in-conditional-expression":88,"../rules/require-spaces-in-for-statement":89,"../rules/require-spaces-in-function":92,"../rules/require-spaces-in-function-declaration":90,"../rules/require-spaces-in-function-expression":91,"../rules/require-spaces-in-named-function-expression":93,"../rules/require-spaces-inside-array-brackets":94,"../rules/require-spaces-inside-object-brackets":95,"../rules/require-spaces-inside-parentheses":96,"../rules/require-trailing-comma":97,"../rules/require-yoda-conditions":98,"../rules/safe-context-keyword":99,"../rules/validate-indentation":100,"../rules/validate-jsdoc":101,"../rules/validate-line-breaks":102,"../rules/validate-object-indentation":103,"../rules/validate-parameter-separator":104,"../rules/validate-quote-marks":105,"assert":143,"minimatch":125,"path":146}],3:[function(require,module,exports){ var assert = require('assert'); var colors = require('colors'); var TokenAssert = require('./token-assert'); /** * Set of errors for specified file. * * @name Errors * @param {JsFile} file * @param {Boolean} verbose */ var Errors = function(file, verbose) { this._errorList = []; this._file = file; this._currentRule = ''; this._verbose = verbose || false; /** * @type {TokenAssert} * @public */ this.assert = new TokenAssert(file); this.assert.on('error', this._addError.bind(this)); }; Errors.prototype = { /** * Adds style error to the list * * @param {String} message * @param {Number|Object} line * @param {Number} [column] optional if line is an object */ add: function(message, line, column) { if (typeof line === 'object') { column = line.column; line = line.line; } // line and column numbers should be explicit assert(typeof line === 'number' && line > 0, 'Unable to add an error, `line` should be a number greater than 0 but ' + line + ' given'); assert(typeof column === 'number' && column >= 0, 'Unable to add an error, `column` should be a positive number but ' + column + ' given'); this._addError({ message: message, line: line, column: column }); }, /** * Adds error to error list. * * @param {Object} errorInfo * @private */ _addError: function(errorInfo) { if (!this._file.isEnabledRule(this._currentRule, errorInfo.line)) { return; } this._errorList.push({ filename: this._file.getFilename(), rule: this._currentRule, message: this._verbose ? this._currentRule + ': ' + errorInfo.message : errorInfo.message, line: errorInfo.line, column: errorInfo.column }); }, /** * Returns style error list. * * @returns {Object[]} */ getErrorList: function() { return this._errorList; }, /** * Returns filename of file this error list is for. * * @returns {String} */ getFilename: function() { return this._file.getFilename(); }, /** * Returns true if no errors are added. * * @returns {Boolean} */ isEmpty: function() { return this._errorList.length === 0; }, /** * Returns amount of errors added by the rules. * * @returns {Number} */ getErrorCount: function() { return this._errorList.length; }, /** * Strips error list to the specified length. * * @param {Number} length */ stripErrorList: function(length) { this._errorList.splice(length); }, /** * Filters out errors based on the supplied filter function * * @param {Function} filter */ filter: function(filter) { this._errorList = this._errorList.filter(filter); }, /** * Formats error for further output. * * @param {Object} error * @param {Boolean} colorize * @returns {String} */ explainError: function(error, colorize) { var lineNumber = error.line - 1; var lines = this._file.getLines(); var result = [ renderLine(lineNumber, lines[lineNumber], colorize), renderPointer(error.column, colorize) ]; var i = lineNumber - 1; var linesAround = 2; while (i >= 0 && i >= (lineNumber - linesAround)) { result.unshift(renderLine(i, lines[i], colorize)); i--; } i = lineNumber + 1; while (i < lines.length && i <= (lineNumber + linesAround)) { result.push(renderLine(i, lines[i], colorize)); i++; } result.unshift(formatErrorMessage(error.message, this.getFilename(), colorize)); return result.join('\n'); }, /** * Sets the current rule so that errors are aware * of which rule triggered them. * * @param {String} rule */ setCurrentRule: function(rule) { this._currentRule = rule; } }; /** * Formats error message header. * * @param {String} message * @param {String} filename * @param {Boolean} colorize * @returns {String} */ function formatErrorMessage(message, filename, colorize) { return (colorize ? colors.bold(message) : message) + ' at ' + (colorize ? colors.green(filename) : filename) + ' :'; } /** * Simple util for prepending spaces to the string until it fits specified size. * * @param {String} s * @param {Number} len * @returns {String} */ function prependSpaces(s, len) { while (s.length < len) { s = ' ' + s; } return s; } /** * Renders single line of code in style error formatted output. * * @param {Number} n line number * @param {String} line * @param {Boolean} colorize * @returns {String} */ function renderLine(n, line, colorize) { // Convert tabs to spaces, so errors in code lines with tabs as indention symbol // could be correctly rendered, plus it will provide less verbose output line = line.replace(/\t/g, ' '); // "n + 1" to print lines in human way (counted from 1) var lineNumber = prependSpaces((n + 1).toString(), 5) + ' |'; return ' ' + (colorize ? colors.grey(lineNumber) : lineNumber) + line; } /** * Renders pointer: * ---------------^ * * @param {Number} column * @param {Boolean} colorize * @returns {String} */ function renderPointer(column, colorize) { var res = (new Array(column + 9)).join('-') + '^'; return colorize ? colors.grey(res) : res; } module.exports = Errors; },{"./token-assert":107,"assert":143,"colors":115}],4:[function(require,module,exports){ var treeIterator = require('./tree-iterator'); /** * Operator list which are represented as keywords in token list. */ var KEYWORD_OPERATORS = { 'instanceof': true, 'in': true }; /** * File representation for JSCS. * * @name JsFile */ var JsFile = function(filename, source, tree) { this._filename = filename; this._source = source; this._changes = []; this._tree = tree || {tokens: []}; this._lines = source.split(/\r\n|\r|\n/); this._tokenRangeStartIndex = null; this._tokenRangeEndIndex = null; var index = this._index = {}; var _this = this; this._buildTokenIndex(); this.iterate(function(node, parentNode, parentCollection) { var type = node.type; node.parentNode = parentNode; node.parentCollection = parentCollection; (index[type] || (index[type] = [])).push(node); // Temporary fix (i hope) for esprima tokenizer // (https://code.google.com/p/esprima/issues/detail?id=481) // Fixes #83, #180 switch (type) { case 'Property': convertKeywordToIdentifierIfRequired(node.key); break; case 'MemberExpression': convertKeywordToIdentifierIfRequired(node.property); break; } }); this._buildDisabledRuleIndex(); // Part of temporary esprima fix. function convertKeywordToIdentifierIfRequired(node) { var tokenPos = _this.getTokenPosByRangeStart(node.range[0]); var token = _this._tree.tokens[tokenPos]; if (token.type === 'Keyword') { token.type = 'Identifier'; } } }; JsFile.prototype = { /** * Builds an index of disabled rules by starting line for error suppression. */ _buildDisabledRuleIndex: function() { this._disabledRuleIndex = []; var comments = this.getComments() || []; var commentRe = /(jscs\s*:\s*(en|dis)able)(.*)/; comments.forEach(function(comment) { var enabled; var parsed = commentRe.exec(comment.value.trim()); if (!parsed || parsed.index !== 0) { return; } enabled = parsed[2] === 'en'; this._addToDisabledRuleIndex(enabled, parsed[3], comment.loc.start.line); }, this); }, /** * Returns whether a specific rule is disabled on the given line. * * @param {String} ruleName the rule name being tested * @param {Number} line the line number being tested * @returns {Boolean} true if the rule is enabled */ isEnabledRule: function(ruleName, line) { var enabled = true; this._disabledRuleIndex.some(function(region) { // once the comment we're inspecting occurs after the location of the error, // no longer check for whether the state is enabled or disable if (region.line > line) { return true; } if (region.rule === ruleName || region.rule === '*') { enabled = region.enabled; } }, this); return enabled; }, /** * Adds rules to the disabled index given a string containing rules (or '' for all). * * @param {Boolean} enabled whether the rule is disabled or enabled on this line * @param {String} rulesStr the string containing specific rules to en/disable * @param {Number} line the line the comment appears on */ _addToDisabledRuleIndex: function(enabled, rulesStr, line) { rulesStr = rulesStr || '*'; rulesStr.split(',').forEach(function(rule) { rule = rule.trim(); if (!rule) { return; } this._disabledRuleIndex.push({ rule: rule, enabled: enabled, line: line }); }, this); }, /** * Builds token index by starting pos for futher navigation. */ _buildTokenIndex: function() { var tokens = this._tree.tokens; var tokenRangeStartIndex = {}; var tokenRangeEndIndex = {}; for (var i = 0, l = tokens.length; i < l; i++) { tokenRangeStartIndex[tokens[i].range[0]] = i; tokenRangeEndIndex[tokens[i].range[1]] = i; tokens[i]._tokenIndex = i; } this._tokenRangeStartIndex = tokenRangeStartIndex; this._tokenRangeEndIndex = tokenRangeEndIndex; }, /** * Returns token position using range start from the index. * * @returns {Object} */ getTokenPosByRangeStart: function(start) { return this._tokenRangeStartIndex[start]; }, /** * Returns token using range start from the index. * * @returns {Object|undefined} */ getTokenByRangeStart: function(start) { var tokenIndex = this._tokenRangeStartIndex[start]; return tokenIndex === undefined ? undefined : this._tree.tokens[tokenIndex]; }, /** * Returns token using range end from the index. * * @returns {Object|undefined} */ getTokenByRangeEnd: function(end) { var tokenIndex = this._tokenRangeEndIndex[end]; return tokenIndex === undefined ? undefined : this._tree.tokens[tokenIndex]; }, /** * Returns the first token for the node from the AST. * * @param {Object} node * @returns {Object} */ getFirstNodeToken: function(node) { return this.getTokenByRangeStart(node.range[0]); }, /** * Returns the last token for the node from the AST. * * @param {Object} node * @returns {Object} */ getLastNodeToken: function(node) { return this.getTokenByRangeEnd(node.range[1]); }, /** * Returns the first token before the given. * * @param {Object} token * @returns {Object|undefined} */ getPrevToken: function(token) { var index = token._tokenIndex - 1; return index >= 0 ? this._tree.tokens[index] : undefined; }, /** * Returns the first token after the given. * * @param {Object} token * @returns {Object|undefined} */ getNextToken: function(token) { var index = token._tokenIndex + 1; return index < this._tree.tokens.length ? this._tree.tokens[index] : undefined; }, /** * Returns the first token before the given which matches type (and value). * * @param {Object} token * @param {String} type * @param {String} [value] * @returns {Object|undefined} */ findPrevToken: function(token, type, value) { var prevToken = this.getPrevToken(token); while (prevToken) { if (prevToken.type === type && (value === undefined || prevToken.value === value)) { return prevToken; } prevToken = this.getPrevToken(prevToken); } return prevToken; }, /** * Returns the first token after the given which matches type (and value). * * @param {Object} token * @param {String} type * @param {String} [value] * @returns {Object|undefined} */ findNextToken: function(token, type, value) { var nextToken = this.getNextToken(token); while (nextToken) { if (nextToken.type === type && (value === undefined || nextToken.value === value)) { return nextToken; } nextToken = this.getNextToken(nextToken); } return nextToken; }, /** * Returns the first token before the given which matches type (and value). * * @param {Object} token * @param {String} value * @returns {Object|undefined} */ findPrevOperatorToken: function(token, value) { return this.findPrevToken(token, value in KEYWORD_OPERATORS ? 'Keyword' : 'Punctuator', value); }, /** * Returns the first token after the given which matches type (and value). * * @param {Object} token * @param {String} value * @returns {Object|undefined} */ findNextOperatorToken: function(token, value) { return this.findNextToken(token, value in KEYWORD_OPERATORS ? 'Keyword' : 'Punctuator', value); }, /** * Iterates through the token tree using tree iterator. * Calls passed function for every token. * * @param {Function} cb * @param {Object} [tree] */ iterate: function(cb, tree) { return treeIterator.iterate(tree || this._tree, cb); }, /** * Returns node by its range position * * @returns {Object} */ getNodeByRange: function(number) { var result = {}; this.iterate(function(node) { if (number > node.range[0] && number < node.range[1]) { result = node; } if (number < node.range[0]) { return false; } }); return result; }, /** * Returns nodes by type(s) from earlier built index. * * @param {String|String[]} type * @returns {Object[]} */ getNodesByType: function(type) { if (typeof type === 'string') { return this._index[type] || []; } else { var result = []; for (var i = 0, l = type.length; i < l; i++) { var nodes = this._index[type[i]]; if (nodes) { result = result.concat(nodes); } } return result; } }, /** * Iterates nodes by type(s) from earlier built index. * Calls passed function for every matched node. * * @param {String|String[]} type * @param {Function} cb */ iterateNodesByType: function(type, cb) { return this.getNodesByType(type).forEach(cb); }, /** * Iterates tokens by type(s) from the token array. * Calls passed function for every matched token. * * @param {String|String[]} type * @param {Function} cb */ iterateTokensByType: function(type, cb) { var types = (typeof type === 'string') ? [type] : type; var typeIndex = {}; types.forEach(function(type) { typeIndex[type] = true; }); this.getTokens().forEach(function(token, index, tokens) { if (typeIndex[token.type]) { cb(token, index, tokens); } }); }, /** * Iterates token by value from the token array. * Calls passed function for every matched token. * * @param {String|String[]} name * @param {Function} cb */ iterateTokenByValue: function(name, cb) { var names = (typeof name === 'string') ? [name] : name; var nameIndex = {}; names.forEach(function(type) { nameIndex[type] = true; }); this.getTokens().forEach(function(token, index, tokens) { if (nameIndex.hasOwnProperty(token.value)) { cb(token, index, tokens); } }); }, /** * Returns string representing contents of the file. * * @returns {String} */ getSource: function() { return this._source; }, /** * Returns token tree, built using esprima. * * @returns {Object} */ getTree: function() { return this._tree; }, /** * Returns token list, built using esprima. * * @returns {Object[]} */ getTokens: function() { return this._tree.tokens; }, /** * Returns comment token list, built using esprima. */ getComments: function() { return this._tree.comments; }, /** * Returns source filename for this object representation. * * @returns {String} */ getFilename: function() { return this._filename; }, /** * Returns array of source lines for the file. * * @returns {String[]} */ getLines: function() { return this._lines; }, splice: function(startIndex, removeCharCount, charsToAdd) { this._changes.push({startIndex: startIndex, removeCharCount: removeCharCount, charsToAdd: charsToAdd}); }, applyChanges: function() { var result = ''; var startIndex = 0; var source = this._source; this._changes.sort(function(a, b) { return a.startIndex - b.startIndex; }); this._changes.forEach(function(change) { result = result + source.substring(startIndex, change.startIndex) + change.charsToAdd; startIndex = change.startIndex + change.removeCharCount; }); if (startIndex < source.length) { result = result + source.substring(startIndex, source.length); } return result; }, getPosByLineAndColumn: function(line, column) { var pos = 0; var source = this._source; for (var i = 0;i < line - 1;i++) { pos += this._lines[i].length + 1; if (source[pos - 1] === '\r' && source[pos] === '\n') { pos += 1; } } return pos + column; } }; module.exports = JsFile; },{"./tree-iterator":109}],5:[function(require,module,exports){ var assert = require('assert'); module.exports = function() {}; module.exports.prototype = { configure: function(disallowAnonymousFunctions) { assert( disallowAnonymousFunctions === true, 'disallowAnonymousFunctions option requires true value or should be removed' ); }, getOptionName: function() { return 'disallowAnonymousFunctions'; }, check: function(file, errors) { file.iterateNodesByType(['FunctionExpression', 'FunctionDeclaration'], function(node) { if (node.id === null) { errors.add('Anonymous functions needs to be named', node.loc.start); } }); } }; },{"assert":143}],6:[function(require,module,exports){ var assert = require('assert'); var Lu = require('unicode-6.3.0/categories/Lu/regex'); var Ll = require('unicode-6.3.0/categories/Ll/regex'); var Lt = require('unicode-6.3.0/categories/Lt/regex'); var Lm = require('unicode-6.3.0/categories/Lm/regex'); var Lo = require('unicode-6.3.0/categories/Lo/regex'); function letterPattern(char) { return Lu.test(char) || Ll.test(char) || Lt.test(char) || Lm.test(char) || Lo.test(char); } function lowerCasePattern(char) { return Ll.test(char); } module.exports = function() {}; module.exports.prototype = { configure: function(disallowCapitalizedComments) { assert( disallowCapitalizedComments === true, 'disallowCapitalizedComments option requ