coffeelint
Version:
Lint your CoffeeScript
62 lines (49 loc) • 2.29 kB
text/coffeescript
regexes =
trailingSemicolon: /;\r?$/
module.exports = class NoTrailingSemicolons
rule:
name: 'no_trailing_semicolons'
level : 'error'
message : 'Line contains a trailing semicolon'
description: """
This rule prohibits trailing semicolons, since they are needless
cruft in CoffeeScript.
<pre>
<code># This semicolon is meaningful.
x = '1234'; console.log(x)
# This semicolon is redundant.
alert('end of line');
</code>
</pre>
Trailing semicolons are forbidden by default.
"""
lintLine: (line, lineApi) ->
# The TERMINATOR token is extended through to the next token. As a
# result a line with a comment DOES have a token: the TERMINATOR from
# the last line of code.
lineTokens = lineApi.getLineTokens()
tokenLen = lineTokens.length
stopTokens = ['TERMINATOR', 'HERECOMMENT']
if tokenLen is 1 and lineTokens[0][0] in stopTokens
return
newLine = line
if tokenLen > 1 and lineTokens[tokenLen - 1][0] is 'TERMINATOR'
# `startPos` contains the end pos of the last non-TERMINATOR token
# `endPos` contains the start position of the TERMINATOR token
# if startPos and endPos arent equal, that probably means a comment
# was sliced out of the tokenizer
startPos = lineTokens[tokenLen - 2][2].last_column + 1
endPos = lineTokens[tokenLen - 1][2].first_column
if (startPos isnt endPos)
startCounter = startPos
while line[startCounter] isnt '#' and startCounter < line.length
startCounter++
newLine = line.substring(0, startCounter).replace(/\s*$/, '')
hasSemicolon = regexes.trailingSemicolon.test(newLine)
[first..., last] = lineTokens
hasNewLine = last and last.newLine?
# Don't throw errors when the contents of multiline strings,
# regexes and the like end in ";"
if hasSemicolon and not hasNewLine and lineApi.lineHasToken() and
not (last[0] in ['STRING', 'IDENTIFIER', 'STRING_END'])
return true