@coffeelint/cli
Version:
Lint your CoffeeScript
105 lines (90 loc) • 3.21 kB
JavaScript
(function() {
var NoUnnecessaryDoubleQuotes;
module.exports = NoUnnecessaryDoubleQuotes = (function() {
class NoUnnecessaryDoubleQuotes {
constructor() {
this.regexps = [];
this.interpolationLevel = 0;
this.inJSX = false;
this.JSXCallLevel = 0;
}
lintToken(token, tokenApi) {
var hasLegalConstructs, isSingleBlock, isSingleQuote, ref, tokenValue, type;
[type, tokenValue] = token;
if (type === 'STRING_START' || type === 'STRING_END') {
return this.trackInterpolation(...arguments);
}
if (type === 'JSX_TAG' || type === 'CALL_START' || type === 'CALL_END') {
return this.trackJSX(...arguments);
}
isSingleQuote = tokenValue.quote === "'";
isSingleBlock = tokenValue.quote === "'''";
if (isSingleQuote || isSingleBlock) { // no double quotes, all OK
return false;
}
// When CoffeeScript generates calls to RegExp it double quotes the 2nd
// parameter. Using peek(2) becuase the peek(1) would be a CALL_END
if (((ref = tokenApi.peek(2)) != null ? ref[0] : void 0) === 'REGEX_END') {
return false;
}
hasLegalConstructs = this.inJSX || this.isInInterpolation() || this.hasSingleQuote(tokenValue);
if (!hasLegalConstructs) {
return {token};
}
}
isInInterpolation() {
return this.interpolationLevel > 0;
}
trackInterpolation(token, tokenApi) {
if (token[0] === 'STRING_START') {
this.interpolationLevel += 1;
} else if (token[0] === 'STRING_END') {
this.interpolationLevel -= 1;
}
// We're not linting, just tracking interpolations.
return null;
}
trackJSX(token, tokenApi) {
if (token[0] === 'JSX_TAG') {
this.inJSX = true;
} else if (token[0] === 'CALL_START') {
if (this.inJSX) {
this.JSXCallLevel += 1;
}
} else if (token[0] === 'CALL_END') {
if (this.inJSX) {
this.JSXCallLevel -= 1;
if (this.JSXCallLevel === 0) {
this.inJSX = false;
}
}
}
// We're not linting, just tracking interpolations.
return null;
}
hasSingleQuote(tokenValue) {
return tokenValue.indexOf("'") !== -1;
}
};
NoUnnecessaryDoubleQuotes.prototype.rule = {
type: 'style',
name: 'no_unnecessary_double_quotes',
level: 'ignore',
message: 'Unnecessary double quotes are forbidden',
description: `This rule prohibits double quotes unless string interpolation is
used or the string contains single quotes.
<pre>
<code># Double quotes are discouraged:
foo = "bar"
# Unless string interpolation is used:
foo = "#{bar}baz"
# Or they prevent cumbersome escaping:
foo = "I'm just following the 'rules'"
</code>
</pre>
Double quotes are permitted by default.`
};
NoUnnecessaryDoubleQuotes.prototype.tokens = ['STRING', 'STRING_START', 'STRING_END', 'JSX_TAG', 'CALL_START', 'CALL_END'];
return NoUnnecessaryDoubleQuotes;
}).call(this);
}).call(this);