Skip to content

Commit

Permalink
source-code-utils: added getComments()
Browse files Browse the repository at this point in the history
  • Loading branch information
duaraghav8 committed Apr 7, 2019
1 parent 572f7f6 commit 8ff8ad4
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 14 deletions.
9 changes: 7 additions & 2 deletions docs/developer-guide.rst
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ Your rule should expose an object that contains 2 attributes - ``meta`` object w
``create()``

This function is responsible for actual processing of the contract code, determining whether something is wrong or not, reporting an issue and suggesting fixes.
create() must return an object whose Key is an AST node type, and value is the function to execute on that node. So, for example, ``IfStatement`` is the type of the AST node representing an ``if`` clause and block in solidity.
create() must return an object whose Key is an AST node type, and value is the function to execute on that node (i.e., the *handler function*). So, for example, ``IfStatement`` is the type of the AST node representing an ``if`` clause and block in solidity.

.. note::
To know which node type you need to capture, install `solparse <https://github.com/duaraghav8/solparse>`_, parse some sample code into AST, then examine the particular node of interest for its ``type`` field. Specify that type as your return object key. You can see `any rule implementation <https://github.com/duaraghav8/Solium/tree/master/lib/rules>`_ to understand what create()'s return object looks like.
Expand Down Expand Up @@ -248,14 +248,19 @@ The functions exposed by SourceCode object are as follows:

10. ``getNextChars (node, charCount)`` - get charCount no. of characters after the code of specified node

11. ``getPrevChars (node, charCount)`` - get charCount no. of characters befre the code of specified node
11. ``getPrevChars (node, charCount)`` - get charCount no. of characters before the code of specified node

12. ``isASTNode (arg)`` - Returns true if the given argument is a valid (Spider-Monkey compliant) AST Node

13. ``getStringBetweenNodes (prevNode, nextNode)`` - get the complete code between 2 specified nodes. (The code ranges from prevNode.end (inclusive) to nextNode.start (exclusive) )

14. ``getLines ()`` - get the source code split into lines

15. ``getComments()`` - get the list of AST nodes representing comments in the code. Call ``getSourceCode()`` inside your *handler function* if you wish to use this method.

.. note::
The recommended way to use the ``getSourceCode()`` method is inside the *handler function* in which you will be calling the functions the SourceCode object provides. If you call ``getSourceCode()`` inside the main ``create()`` function, some functions will return empty results because the data hasn't been populated yet. This is by design. If you see some rule implementations calling the function outside of their handler functions, it means that the SourceCode object functions they use are unaffected by whether you call them inside or outside the handler functions.

- ``context.report()`` - Lastly, the context object provides you with a clean interface to report lint issues:

.. code-block:: javascript
Expand Down
13 changes: 9 additions & 4 deletions lib/solium.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,16 @@ const solidityParser = require("solparse"),
module.exports = (function() {

let Solium = Object.create(new EventEmitter()),
messages = [], sourceCodeText = "", currentConfig = null, commentDirectiveParser;
commentObjects = [], messages = [],
sourceCodeText = "", currentConfig = null, commentDirectiveParser;

/**
* Initialize all global variables: ensure nothing from the previous lint() gets carried to the next lint()
* @returns {void}
*/
Solium.reset = function reset() {
Solium.removeAllListeners();
commentObjects = [];
messages = [];
sourceCodeText = "";
currentConfig = {};
Expand All @@ -53,6 +55,7 @@ module.exports = (function() {
* Function called for linting the code by external application(s) using the Solium object
* @param {(String|Buffer)} sourceCode The Source Code to lint
* @param {Object} config An object that specifies the rules to use and path of file containing custom rule definitions
* @param {boolean} noReset Specifies whether Solium.reset() should be called or not
* @returns {Array} errorObjects Array of objects, each containing lint error messages and supporting info, empty if no errors
*/
Solium.lint = function lint(sourceCode, config, noReset) {
Expand Down Expand Up @@ -158,7 +161,8 @@ module.exports = (function() {
throw(e);
}

commentDirectiveParser = new CommentDirectiveParser(AST.comments, AST);
commentObjects = AST.comments;
commentDirectiveParser = new CommentDirectiveParser(commentObjects, AST);

/**
* Perform depth-first traversal of the AST and notify rules upon entering & leaving nodes
Expand Down Expand Up @@ -203,7 +207,8 @@ module.exports = (function() {
* Lints, then applies fixes specified by rules and returns fixed code.
* @param {(String|Buffer)} sourceCode The Source Code to lint.
* @param {Object} config An object that specifies the rules to use and path of file containing custom rule definitions.
* @returns {Object} result Returns lint errors, errors that were fixed and final fixed code.
* @param {boolean} noReset Specifies whether Solium.reset() should be called or not
* @returns {Object} result Returns lint errors, errors that were fixed and final fixed code.
*/
Solium.lintAndFix = function lintAndFix(sourceCode, config, noReset) {
if (typeof sourceCode === "object" && sourceCode.constructor.name === "Buffer") {
Expand Down Expand Up @@ -299,7 +304,7 @@ module.exports = (function() {
* @returns {Object} sourceCodeObject The SourceCode Object that provides source text & functionality
*/
Solium.getSourceCode = function getSourceCode() {
return new SourceCode(sourceCodeText);
return new SourceCode(sourceCodeText, commentObjects);
};

/**
Expand Down
6 changes: 3 additions & 3 deletions lib/utils/ast-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ function throwIfInvalidNode(node, functionName) {

/**
* Initialization method - provide all the necessary information astUtils functions could require in order to work
* @param {String} sourceCodeText The source code being linted
* @param {String} sourceCode The source code being linted
*/
exports.init = function(sourceCode) {
sourceCodeText = sourceCode;
Expand All @@ -37,7 +37,7 @@ exports.isASTNode = nodeSchemaValidator.compile(astNodeSchema);

/**
* @param {Object} node The node to check
* @param {String} type The type of the node
* @param {String} name The type of the node
* @returns {Boolean} true if the given node is the right type
*/
function isNodeType(node, name) {
Expand Down Expand Up @@ -157,7 +157,7 @@ exports.getColumn = function(node) {
/**
* Retrieve the line number on which the code for provided node ENDS
* @param {Object} node The AST Node to retrieve the line number of
* @returns {Integer} lineNumber Line number of code ending of the specified node. (LINES BEGIN FROM 1)
* @returns {int} lineNumber Line number of code ending of the specified node. (LINES BEGIN FROM 1)
*/
exports.getEndingLine = function(node) {
throwIfInvalidNode(node, "getEndingLine");
Expand Down
20 changes: 15 additions & 5 deletions lib/utils/source-code-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,11 @@ const INHERITABLE_METHODS = [
/**
* SourceCode object constructor - provides the source code text along with functions to operate on the code easily
* @param {String} sourceCodeText source code being linted
* @param {ASTNode[]} comments List of objects representing comments throughout the source code
*/
function SourceCode(sourceCodeText) {
function SourceCode(sourceCodeText, comments) {
this.text = sourceCodeText;
this.commentObjects = comments;
}

SourceCode.prototype = {
Expand All @@ -39,8 +41,8 @@ SourceCode.prototype = {
/**
* Function to retrieve the source code text being linted. Returns the complete source code if no node specified
* @param {Object} node The AST node whose source code (specifically) is needed
* @param {Integer} beforeCount Include beforeCount number of characters prior to the node's code
* @param {Integer} afterCount Include afterCount number of characters following the node's code
* @param {int} beforeCount Include beforeCount number of characters prior to the node's code
* @param {int} afterCount Include afterCount number of characters following the node's code
* @returns {String} sourceCodeText source code of the specified node plus extra characters specified by beforeCount & afterCount
*/
getText: function(node, beforeCount, afterCount) {
Expand Down Expand Up @@ -137,7 +139,7 @@ SourceCode.prototype = {

/**
* Get the complete text on line lineNumber (excluding the EOL)
* @param {Integer} lineNumber Line number whose text to get
* @param {int} lineNumber Line number whose text to get
* @returns {String} code Source code text on the specified line
*/
getTextOnLine: function(lineNumber) {
Expand All @@ -152,7 +154,15 @@ SourceCode.prototype = {
return this.sourceCodeTextLines [lineNumber - 1];
}

throw new Error("Line number " + lineNumber + " invalid or out of bounds.");
throw new Error(`Line number ${lineNumber} invalid or out of bounds.`);
},

/**
* Get all AST Nodes representing comments
* @returns {ASTNode[]} List of comment nodes
*/
getComments() {
return this.commentObjects;
}

};
Expand Down

0 comments on commit 8ff8ad4

Please sign in to comment.