From 3dbbd170027a909f77edea1eaa2fefb5557902a1 Mon Sep 17 00:00:00 2001 From: Orlando Rincon Date: Mon, 30 Nov 2015 17:15:01 -0600 Subject: [PATCH] Adding code base to support .jshintignore for JSHint linter. --- .../ternjs/node_modules/tern-jshint/jshint.js | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/core/ternjs/node_modules/tern-jshint/jshint.js b/core/ternjs/node_modules/tern-jshint/jshint.js index 7844fc173..328e424d5 100644 --- a/core/ternjs/node_modules/tern-jshint/jshint.js +++ b/core/ternjs/node_modules/tern-jshint/jshint.js @@ -17,6 +17,14 @@ "Unmatched ", " and instead saw", " is not defined", "Unclosed string", "Stopping, unable to continue" ]; + var slashAtEndRegEx = /\/$/; + + var pathLastSegmentIsolationRegEx = /([^\/]*)\/*$/; + + var fileNameRegEx = /([^\\]+)\.[^\\]+$/; + + var doubleAsteriskAtEndRegEx = /\*\*$/; + function cleanup(error) { // All problems are warnings by default fixWith(error, warnings, "warning", true); @@ -106,6 +114,64 @@ }); function validate(server, query, file, messages) { + function isIgnored(file) { + // JSHint ignore is potentially in a .jshintignore config file. + var jshintignoreFileName = ".jshintignore"; + var fs = require("fs"); + var filepath = normPath(jshintignoreFileName); + if (!fs.existsSync(filepath)) { + // If .jshintignore does not exist, then simply + // ask cli.gather if filename should be excluded + var gather = cli.gather({ + args: [file.name] + }); + return gather.indexOf(file.name) < 0; + } + + // We reach here if .jshintignore actually exists, but it needs special handling because + // there is a problem that is caused when a directory wants to be excluded entirely and + // you only know a single filename (as this case). + // For that scenario, the ignore path needs to be explicitly specified as + // "folder/**" in .jshintignore instead just "folder/" or "folder", and given + // tern makes individual file calls, we need to provide a workaround here + // for tern.java + + // Re-parse .jshintignore file + var shjs = require("shelljs"); + var ignorePatterns = shjs.cat(filepath).split("\n"); + // Remove empty entries + ignorePatterns = ignorePatterns.filter(function(line) { + return !!line.trim(); + }).map (function(line) { + if (slashAtEndRegEx.test (line)) { + // This is a directory name (it ends with a slash), so help the + // pattern adding the double asterisk at the end + return line += "**"; + } else { + // Get only the last segment for this path + var lastSegment = line.match(pathLastSegmentIsolationRegEx)[1]; + // If this is a directory (which we identify by reviewing + // it's not a filename (i.e it has no extension), neither + // the expresion ends with ** then help improving the + // ignore expression by adding a /** to the pattern + if (lastSegment && !fileNameRegEx.test (lastSegment) + && !doubleAsteriskAtEndRegEx.test (lastSegment)) { + return line += "/**"; + } + } + + // Otherwise, just pass the line with no modification + // This should be the case for explicit filenames + return line; + }); + + var gather = cli.gather({ + args: [file.name], + ignores : ignorePatterns + }); + + return gather.indexOf(file.name) < 0; + } function getSeverity(error) { switch(error.severity) { @@ -195,6 +261,11 @@ } } } + + if (isIgnored(file)) { + // Just skip, this file does not need to be linted + return; + } var text = file.text, jshintCfg = server.mod.jshint.config; // Update jshint config if needed.