Comparing version 0.1.8 to 0.1.9
/** | ||
* @fileoverview Ensure that string are quoted with double-quotes only | ||
* @fileoverview Ensure that strings are quoted with double-quotes only | ||
* @author Raghav Dua <duaraghav8@gmail.com> | ||
@@ -8,2 +8,18 @@ */ | ||
/** | ||
* Determine whether the provided literal is in Hex Notation | ||
* @param {String} literal The literal to test for Hex Notation | ||
* @returns {Boolean} | ||
*/ | ||
function isHex (literal) { | ||
var reg = /^[0-9a-f]+$/i; | ||
//test for '0x' separately because hex notation should not be a part of the standard RegExp | ||
if (literal.slice (0, 2) !== '0x') { | ||
return false; | ||
} | ||
return reg.test (literal.slice (2)); | ||
} | ||
module.exports = { | ||
@@ -17,15 +33,15 @@ | ||
context.on ('Literal', function (emitted) { | ||
var node = emitted.node; | ||
var node = emitted.node, nodeText = sourceCode.getText (node); | ||
if (emitted.exit) { | ||
if (emitted.exit || | ||
typeof node.value !== 'string' || | ||
(nodeText [0] !== '\'' && nodeText [0] !== '\"' && isHex (node.value)) | ||
) { | ||
return; | ||
} | ||
if ( | ||
typeof node.value === 'string' && | ||
!doubleQuotesLiteralRegExp.test (sourceCode.getText (node)) | ||
) { | ||
if (!doubleQuotesLiteralRegExp.test (nodeText)) { | ||
context.report ({ | ||
node: node, | ||
message: 'String Literals must be quoted with double quotes only.' | ||
message: '\'' + node.value + '\': String Literals must be quoted with \"double quotes\" only.' | ||
}); | ||
@@ -32,0 +48,0 @@ } |
@@ -46,3 +46,3 @@ /** | ||
programChild.type.replace ('Statement', '').toLowerCase () + | ||
' \'' + programChild.name + '\'' + | ||
( programChild.name ? (' \'' + programChild.name + '\'') : ' statement' ) + | ||
': ' + messageText | ||
@@ -157,4 +157,13 @@ ) | ||
//if the block item spans over multiple lines, make sure the ending line also follows the indent rule | ||
/** | ||
* If the block item spans over multiple lines, make sure the ending line also follows the indent rule | ||
* An exception to this is the if-else statements when they don't have BlockStatement as their body | ||
* eg- | ||
* if (a) | ||
* foo(); | ||
* else | ||
* bar(); | ||
*/ | ||
if ( | ||
blockItem.type !== 'IfStatement' && | ||
sourceCode.getLine (blockItem) !== endingLineNum && | ||
@@ -302,3 +311,5 @@ !endingLineRegExp.test (sourceCode.getTextOnLine (endingLineNum)) | ||
var MAX_PARAMS_ON_SINGLE_LINE = 3; | ||
var endingLineNum = sourceCode.getEndingLine (node), | ||
var startLine = sourceCode.getLine (node), | ||
lastArgLine = params.length ? sourceCode.getEndingLine (params.slice (-1) [0]) : startLine, | ||
functionDeclarationLineText, currentIndent, currentIndentLevel, paramIndent; | ||
@@ -321,3 +332,3 @@ | ||
if (sourceCode.getLine (node) === endingLineNum) { | ||
if (startLine === lastArgLine) { | ||
if (params.length > MAX_PARAMS_ON_SINGLE_LINE) { | ||
@@ -332,3 +343,3 @@ context.report ({ | ||
functionDeclarationLineText = sourceCode.getTextOnLine (sourceCode.getLine (node)); | ||
functionDeclarationLineText = sourceCode.getTextOnLine (startLine); | ||
@@ -335,0 +346,0 @@ currentIndent = functionDeclarationLineText.slice ( |
@@ -18,3 +18,5 @@ /** | ||
testConditionsCode = sourceCode.getText (node.test); | ||
var startingLine = sourceCode.getLine (node); | ||
var startingLine = sourceCode.getLine (node), | ||
consequentStartingLine = sourceCode.getLine (node.consequent), | ||
testEndingLine = sourceCode.getEndingLine (node.test); | ||
@@ -25,10 +27,40 @@ if (emitted.exit) { | ||
if (node.consequent.type !== 'BlockStatement') { | ||
if (node.consequent.type === 'EmptyStatement') { | ||
context.report ({ | ||
node: node.consequent, | ||
message: 'Clause is followed by an empty statement.' | ||
}); | ||
} | ||
//if this node is an alternate ('else if (..) {..}'), make sure its on its own line | ||
if ( | ||
node.parent.type === 'IfStatement' && | ||
startingLine !== sourceCode.getEndingLine (node.parent) + 1 | ||
) { | ||
context.report ({ | ||
node: node, | ||
message: 'Expected \'{\' after if clause' | ||
message: 'Clause must be on its own line immediately after the previous one.' | ||
}); | ||
} | ||
/** | ||
* If consequent is not block and its not the case that: | ||
* consequent is on the next line and only resides on a single line, then | ||
* report | ||
*/ | ||
if (node.consequent.type !== 'BlockStatement') { | ||
if ( | ||
!( | ||
consequentStartingLine === testEndingLine + 1 && | ||
consequentStartingLine === sourceCode.getEndingLine (node.consequent) | ||
) | ||
) { | ||
context.report ({ | ||
node: node, | ||
message: 'Expected \'{\' after if clause' | ||
}); | ||
} | ||
} else if ( | ||
startingLine === sourceCode.getEndingLine (node.test) && | ||
startingLine !== sourceCode.getLine (node.consequent) | ||
startingLine === testEndingLine && | ||
consequentStartingLine !== startingLine | ||
) { | ||
@@ -43,27 +75,46 @@ //'{' is not on the same line as the if statement AND the test isn't spread over multiple lines | ||
if (node.alternate) { | ||
if (node.alternate.type === 'BlockStatement') { | ||
//an else statement with {...} | ||
var prevChar = '', prevCount = 1; | ||
//enforse 'else' clause to be on its own line | ||
/*if (sourceCode.getLine (node.alternate) !== sourceCode.getEndingLine (node.consequent) + 1) { | ||
context.report ({ | ||
node: node.alternate, | ||
message: node.alternate.type + ' must be on its own line, immediately after the previous clause\'s body ends.' | ||
}); | ||
}*/ | ||
/** | ||
* Start going backward from '{' to find the ending 'e' of 'else' | ||
* If a \n is encountered beofore 'e', it means there's a lin gap between 'else' and '{' | ||
*/ | ||
while (prevChar !== 'e') { | ||
prevChar = sourceCode.getPrevChars (node.alternate, prevCount++) [0]; | ||
if (prevChar === '\n') { | ||
context.report ({ | ||
node: node, | ||
message: 'Opening brace must be on the same line as the else keyword.' | ||
}); | ||
prevChar = 'e'; //error has been found, now stop the loop | ||
} | ||
if (node.alternate.type === 'EmptyStatement') { | ||
context.report ({ | ||
node: node.alternate, | ||
message: 'Clause is followed by an empty statement.' | ||
}); | ||
} else if (node.alternate.type === 'BlockStatement') { | ||
//an else statement with block {...} | ||
var elseClauseRegExp = /^\s*else\s*{/, | ||
elseClauseText = sourceCode.getTextOnLine (sourceCode.getLine (node.alternate)); | ||
if (!elseClauseRegExp.test (elseClauseText)) { | ||
context.report ({ | ||
node: node.alternate, | ||
message: 'Opening brace must be on the same line as the else keyword and comments should only appear after all code.' | ||
}); | ||
} | ||
} else if (node.alternate.type !== 'IfStatement') { | ||
//node.alternate is neither an else {...}, nor an else if (..) {...} | ||
context.report ({ | ||
node: node, | ||
message: 'Expected \'{\' after else clause' | ||
}); | ||
var alternateClauseText = sourceCode.getTextOnLine (sourceCode.getLine (node.alternate) - 1); | ||
//finally, of ts not even a single-line alternative 'else <statement>;' | ||
if ( | ||
!/\s*else\s*/.test (alternateClauseText) || | ||
sourceCode.getLine (node.alternate) !== sourceCode.getEndingLine (node.alternate) | ||
) { | ||
context.report ({ | ||
node: node.alternate, | ||
message: 'Expected \'{\' after else clause' | ||
}); | ||
} | ||
} | ||
@@ -73,2 +124,3 @@ } | ||
context.on ('ForStatement', function (emitted) { | ||
@@ -108,2 +160,3 @@ var node = emitted.node, | ||
context.on ('WhileStatement', function (emitted) { | ||
@@ -137,2 +190,3 @@ var node = emitted.node, | ||
/** | ||
@@ -139,0 +193,0 @@ * Ideally with() shouldn't be be used in code and there's even a rule to disallow it. |
@@ -12,3 +12,3 @@ /** | ||
var mixedCaseRegEx = /^_?[a-z]+[a-zA-Z]*$/; | ||
var mixedCaseRegEx = /^_?[a-z][a-zA-Z0-9]*$/; | ||
var similarNodes = [ | ||
@@ -31,9 +31,14 @@ 'FunctionDeclaration', | ||
//a constructor (function with name same as it parent contract/library) is exception to mixedCase Rule | ||
/** | ||
* If node's parent is contract/library and | ||
* node is either a modifier (which means Inheritance), OR | ||
* node is a constructor of the contract/library, THEN | ||
* do not apply mixedcase | ||
*/ | ||
if ( | ||
emitted.exit || | ||
(node.parent.type === 'ContractStatement' || node.parent.type === 'LibraryStatement') && | ||
( | ||
node.type === 'FunctionDeclaration' && | ||
(node.parent.type === 'ContractStatement' || node.parent.type === 'LibraryStatement') && | ||
node.parent.name === node.name | ||
node.type === 'ModifierName' || | ||
(node.type === 'FunctionDeclaration' && node.parent.name === node.name) | ||
) | ||
@@ -40,0 +45,0 @@ ) { |
@@ -14,2 +14,30 @@ /** | ||
context.on ('BlockStatement', function (emitted) { | ||
var node = emitted.node, | ||
blockBody = node.body; | ||
//Function's body is an exception to this rule | ||
if (emitted.exit || node.parent.type === 'FunctionDeclaration') { | ||
return; | ||
} | ||
//if block has only 1 item, starts & ends on same line and doesn't have 1 space before & after item, report | ||
if (blockBody.length === 1 && sourceCode.getLine (node) === sourceCode.getEndingLine (node)) { | ||
if (sourceCode.getPrevChars (blockBody [0], 2) !== '{ ') { | ||
context.report ({ | ||
node: blockBody [0], | ||
message: blockBody [0].type + ': Item should be preceded by exactly 1 space.' | ||
}); | ||
} | ||
if (sourceCode.getNextChars (blockBody [0], 2) !== ' }') { | ||
context.report ({ | ||
node: blockBody [0], | ||
message: blockBody [0].type + ': Item should be followed by exactly 1 space.' | ||
}); | ||
} | ||
} | ||
}); | ||
context.on ('CallExpression', function (emitted) { | ||
@@ -16,0 +44,0 @@ var node = emitted.node, |
{ | ||
"name": "solium", | ||
"version": "0.1.8", | ||
"version": "0.1.9", | ||
"description": "A flexible, stand-alone linter for Ethereum Solidity", | ||
@@ -5,0 +5,0 @@ "main": "./lib/solium.js", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
112714
2789