From 336ff739964be7229fb3b39e20062b18142bec01 Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Thu, 11 Feb 2021 00:31:07 +0530 Subject: [PATCH] linting for astwalker done --- libs/remix-astwalker/.eslintrc | 3 +- libs/remix-astwalker/src/astWalker.ts | 207 ++++++++++----------- libs/remix-astwalker/src/sourceMappings.ts | 74 ++++---- libs/remix-astwalker/src/types.ts | 4 +- 4 files changed, 143 insertions(+), 145 deletions(-) diff --git a/libs/remix-astwalker/.eslintrc b/libs/remix-astwalker/.eslintrc index 35e3aeb511..592e8bc3e9 100644 --- a/libs/remix-astwalker/.eslintrc +++ b/libs/remix-astwalker/.eslintrc @@ -2,7 +2,8 @@ "extends": "../../.eslintrc", "rules": { "@typescript-eslint/no-explicit-any": "off", - "@typescript-eslint/prefer-namespace-keyword": "off" + "@typescript-eslint/prefer-namespace-keyword": "off", + "no-unused-vars": "off" }, "ignorePatterns": ["!**/*"] } diff --git a/libs/remix-astwalker/src/astWalker.ts b/libs/remix-astwalker/src/astWalker.ts index 82f19108fd..d784a6f378 100644 --- a/libs/remix-astwalker/src/astWalker.ts +++ b/libs/remix-astwalker/src/astWalker.ts @@ -1,15 +1,15 @@ -import { EventEmitter } from "events"; -import { Node, AstNode } from "./index"; +import { EventEmitter } from 'events' +import { Node, AstNode } from './index' export declare interface AstWalker { new(): EventEmitter; } -const isObject = function(obj: any): boolean { - return obj != null && obj.constructor.name === "Object" +const isObject = function (obj: any): boolean { + return obj != null && obj.constructor.name === 'Object' } -export function isAstNode(node: Record): boolean { +export function isAstNode (node: Record): boolean { return ( isObject(node) && 'id' in node && @@ -18,7 +18,7 @@ export function isAstNode(node: Record): boolean { ) } -export function isYulAstNode(node: Record): boolean { +export function isYulAstNode (node: Record): boolean { return ( isObject(node) && 'nodeType' in node && @@ -26,7 +26,6 @@ export function isYulAstNode(node: Record): boolean { ) } - /** * Crawl the given AST through the function walk(ast, callback) */ @@ -41,7 +40,7 @@ export function isYulAstNode(node: Record): boolean { * If no event for the current type, children are visited. */ export class AstWalker extends EventEmitter { - manageCallback( + manageCallback ( node: AstNode, callback: Record | Function // eslint-disable-line @typescript-eslint/ban-types ): any { @@ -51,178 +50,178 @@ export class AstWalker extends EventEmitter { // return that. if (node) { if ((node).name in callback) { - return callback[(node).name](node); + return callback[(node).name](node) } else { - return callback["*"](node); + return callback['*'](node) } } if (node) { if ((node).nodeType in callback) { /* istanbul ignore next */ - return callback[(node).nodeType](node); + return callback[(node).nodeType](node) } else { /* istanbul ignore next */ - return callback["*"](node); + return callback['*'](node) } } } - normalizeNodes(nodes: AstNode[]): AstNode[] { + normalizeNodes (nodes: AstNode[]): AstNode[] { // Remove null, undefined and empty elements if any nodes = nodes.filter(e => e) // If any element in nodes is array, extract its members const objNodes = [] - nodes.forEach(x => { + nodes.forEach(x => { if (Array.isArray(x)) objNodes.push(...x) else objNodes.push(x) - }); - + }) + // Filter duplicate nodes using id field const normalizedNodes = [] objNodes.forEach((element) => { const firstIndex = normalizedNodes.findIndex(e => e.id === element.id) - if(firstIndex == -1) normalizedNodes.push(element) + if (firstIndex === -1) normalizedNodes.push(element) }) return normalizedNodes } - getASTNodeChildren(ast: AstNode): AstNode[] { - - let nodes = ast.nodes // for ContractDefinition - || ast.body // for FunctionDefinition, ModifierDefinition, WhileStatement, DoWhileStatement, ForStatement - || ast.statements // for Block, YulBlock - || ast.members // for StructDefinition, EnumDefinition - || ast.overrides // for OverrideSpecifier - || ast.parameters // for ParameterList, EventDefinition - || ast.declarations // for VariableDeclarationStatement - || ast.expression // for Return, ExpressionStatement, FunctionCall, FunctionCallOptions, MemberAccess - || ast.components // for TupleExpression - || ast.subExpression // for UnaryOperation - || ast.eventCall // for EmitStatement - || [] - - // If 'nodes' is not an array, convert it into one, for example: ast.body - if(nodes && !Array.isArray(nodes)) { + getASTNodeChildren (ast: AstNode): AstNode[] { + let nodes = ast.nodes || // for ContractDefinition + ast.body || // for FunctionDefinition, ModifierDefinition, WhileStatement, DoWhileStatement, ForStatement + ast.statements || // for Block, YulBlock + ast.members || // for StructDefinition, EnumDefinition + ast.overrides || // for OverrideSpecifier + ast.parameters || // for ParameterList, EventDefinition + ast.declarations || // for VariableDeclarationStatement + ast.expression || // for Return, ExpressionStatement, FunctionCall, FunctionCallOptions, MemberAccess + ast.components || // for TupleExpression + ast.subExpression || // for UnaryOperation + ast.eventCall || // for EmitStatement + [] + + // If 'nodes' is not an array, convert it into one, for example: ast.body + if (nodes && !Array.isArray(nodes)) { const tempArr = [] tempArr.push(nodes) nodes = tempArr } - + // To break object referencing nodes = [...nodes] - if(ast.nodes && ast.baseContracts?.length) { // for ContractDefinition - nodes.push(...ast.baseContracts) + if (ast.nodes && ast.baseContracts?.length) { // for ContractDefinition + nodes.push(...ast.baseContracts) } else if (ast.body && ast.overrides && ast.parameters && ast.returnParameters && ast.modifiers) { // for FunctionDefinition - nodes.push(ast.overrides) - nodes.push(ast.parameters) - nodes.push(ast.returnParameters) - nodes.push(ast.modifiers) - } else if(ast.typeName) { // for VariableDeclaration, NewExpression, ElementaryTypeNameExpression - nodes.push(ast.typeName) + nodes.push(ast.overrides) + nodes.push(ast.parameters) + nodes.push(ast.returnParameters) + nodes.push(ast.modifiers) + } else if (ast.typeName) { // for VariableDeclaration, NewExpression, ElementaryTypeNameExpression + nodes.push(ast.typeName) } else if (ast.body && ast.overrides && ast.parameters) { // for ModifierDefinition - nodes.push(ast.overrides) - nodes.push(ast.parameters) + nodes.push(ast.overrides) + nodes.push(ast.parameters) } else if (ast.modifierName && ast.arguments) { // for ModifierInvocation - nodes.push(ast.modifierName) - nodes.push(ast.arguments) + nodes.push(ast.modifierName) + nodes.push(ast.arguments) } else if (ast.parameterTypes && ast.returnParameterTypes) { // for ModifierInvocation - nodes.push(ast.parameterTypes) - nodes.push(ast.returnParameterTypes) + nodes.push(ast.parameterTypes) + nodes.push(ast.returnParameterTypes) } else if (ast.keyType && ast.valueType) { // for Mapping - nodes.push(ast.keyType) - nodes.push(ast.valueType) + nodes.push(ast.keyType) + nodes.push(ast.valueType) } else if (ast.baseType && ast.length) { // for ArrayTypeName - nodes.push(ast.baseType) - nodes.push(ast.length) + nodes.push(ast.baseType) + nodes.push(ast.length) } else if (ast.AST) { // for InlineAssembly - nodes.push(ast.AST) + nodes.push(ast.AST) } else if (ast.condition && (ast.trueBody || ast.falseBody || ast.body)) { // for IfStatement, WhileStatement, DoWhileStatement - nodes.push(ast.condition) - nodes.push(ast.trueBody) - nodes.push(ast.falseBody) + nodes.push(ast.condition) + nodes.push(ast.trueBody) + nodes.push(ast.falseBody) } else if (ast.parameters && ast.block) { // for TryCatchClause - nodes.push(ast.block) + nodes.push(ast.block) } else if (ast.externalCall && ast.clauses) { // for TryStatement - nodes.push(ast.externalCall) - nodes.push(ast.clauses) + nodes.push(ast.externalCall) + nodes.push(ast.clauses) } else if (ast.body && ast.condition && ast.initializationExpression && ast.loopExpression) { // for ForStatement - nodes.push(ast.condition) - nodes.push(ast.initializationExpression) - nodes.push(ast.loopExpression) + nodes.push(ast.condition) + nodes.push(ast.initializationExpression) + nodes.push(ast.loopExpression) } else if (ast.declarations && ast.initialValue) { // for VariableDeclarationStatement - nodes.push(ast.initialValue) + nodes.push(ast.initialValue) } else if (ast.condition && (ast.trueExpression || ast.falseExpression)) { // for Conditional - nodes.push(ast.condition) - nodes.push(ast.trueExpression) - nodes.push(ast.falseExpression) + nodes.push(ast.condition) + nodes.push(ast.trueExpression) + nodes.push(ast.falseExpression) } else if (ast.leftHandSide && ast.rightHandSide) { // for Assignment - nodes.push(ast.leftHandSide) - nodes.push(ast.rightHandSide) + nodes.push(ast.leftHandSide) + nodes.push(ast.rightHandSide) } else if (ast.leftExpression && ast.rightExpression) { // for BinaryOperation - nodes.push(ast.leftExpression) - nodes.push(ast.rightExpression) + nodes.push(ast.leftExpression) + nodes.push(ast.rightExpression) } else if (ast.expression && (ast.arguments || ast.options)) { // for FunctionCall, FunctionCallOptions - nodes.push(ast.arguments ? ast.arguments : ast.options) + nodes.push(ast.arguments ? ast.arguments : ast.options) } else if (ast.baseExpression && (ast.indexExpression || (ast.startExpression && ast.endExpression))) { // for IndexAccess, IndexRangeAccess - nodes.push(ast.baseExpression) - if(ast.indexExpression) nodes.push(ast.indexExpression) - else { - nodes.push(ast.startExpression) - nodes.push(ast.endExpression) - } + nodes.push(ast.baseExpression) + if (ast.indexExpression) nodes.push(ast.indexExpression) + else { + nodes.push(ast.startExpression) + nodes.push(ast.endExpression) + } } return this.normalizeNodes(nodes) } - + // eslint-disable-next-line @typescript-eslint/ban-types, @typescript-eslint/explicit-module-boundary-types - walk(ast: AstNode, callback?: Function | Record) { + walk (ast: AstNode, callback?: Function | Record) { if (ast) { const children: AstNode[] = this.getASTNodeChildren(ast) if (callback) { if (callback instanceof Function) { - callback = Object({ "*": callback }); + callback = Object({ '*': callback }) } - if (!("*" in callback)) { - callback["*"] = function() { - return true; - }; + if (!('*' in callback)) { + callback['*'] = function () { + return true + } } if (this.manageCallback(ast, callback) && children?.length) { for (const k in children) { - const child = children[k]; - this.walk(child, callback); + const child = children[k] + this.walk(child, callback) } } - } else { - if (children?.length) { - for (const k in children) { - const child = children[k]; - this.emit("node", child); - this.walk(child); - } + } else { + if (children?.length) { + for (const k in children) { + const child = children[k] + this.emit('node', child) + this.walk(child) } } + } } } + // eslint-disable-next-line @typescript-eslint/ban-types, @typescript-eslint/explicit-module-boundary-types - walkFullInternal(ast: AstNode, callback: Function) { + walkFullInternal (ast: AstNode, callback: Function) { if (isAstNode(ast) || isYulAstNode(ast)) { // console.log(`XXX id ${ast.id}, nodeType: ${ast.nodeType}, src: ${ast.src}`); - callback(ast); + callback(ast) for (const k of Object.keys(ast)) { // Possible optimization: // if (k in ['id', 'src', 'nodeType']) continue; - const astItem = ast[k]; + const astItem = ast[k] if (Array.isArray(astItem)) { for (const child of astItem) { if (child) { - this.walkFullInternal(child, callback); + this.walkFullInternal(child, callback) } } } else { - this.walkFullInternal(astItem, callback); + this.walkFullInternal(astItem, callback) } } } @@ -230,19 +229,19 @@ export class AstWalker extends EventEmitter { // Normalizes parameter callback and calls walkFullInternal // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types - walkFull(ast: AstNode, callback: any) { - if (isAstNode(ast) || isYulAstNode(ast)) return this.walkFullInternal(ast, callback); + walkFull (ast: AstNode, callback: any) { + if (isAstNode(ast) || isYulAstNode(ast)) return this.walkFullInternal(ast, callback) } // eslint-disable-next-line @typescript-eslint/ban-types, @typescript-eslint/explicit-module-boundary-types - walkAstList(sourcesList: Node, cb?: Function) { + walkAstList (sourcesList: Node, cb?: Function) { if (cb) { if (sourcesList.ast) { - this.walk(sourcesList.ast, cb); + this.walk(sourcesList.ast, cb) } } else { if (sourcesList.ast) { - this.walk(sourcesList.ast); + this.walk(sourcesList.ast) } } } diff --git a/libs/remix-astwalker/src/sourceMappings.ts b/libs/remix-astwalker/src/sourceMappings.ts index b95f707ba2..275b90f394 100644 --- a/libs/remix-astwalker/src/sourceMappings.ts +++ b/libs/remix-astwalker/src/sourceMappings.ts @@ -1,6 +1,6 @@ -import { isAstNode, isYulAstNode, AstWalker } from './astWalker'; -import { AstNode, LineColPosition, LineColRange, Location } from "./types"; -import { util } from "@remix-project/remix-lib"; +import { isAstNode, isYulAstNode, AstWalker } from './astWalker' +import { AstNode, LineColPosition, LineColRange, Location } from './types' +import { util } from '@remix-project/remix-lib' export declare interface SourceMappings { // eslint-disable-next-line @typescript-eslint/no-misused-new @@ -12,12 +12,12 @@ export declare interface SourceMappings { * * @param offset The character offset to convert. */ -export function lineColPositionFromOffset(offset: number, lineBreaks: Array): LineColPosition { - let line: number = util.findLowerBound(offset, lineBreaks); +export function lineColPositionFromOffset (offset: number, lineBreaks: Array): LineColPosition { + let line: number = util.findLowerBound(offset, lineBreaks) if (lineBreaks[line] !== offset) { - line += 1; + line += 1 } - const beginColumn = line === 0 ? 0 : (lineBreaks[line - 1] + 1); + const beginColumn = line === 0 ? 0 : (lineBreaks[line - 1] + 1) return { line: line + 1, character: (offset - beginColumn) + 1 @@ -30,11 +30,11 @@ export function lineColPositionFromOffset(offset: number, lineBreaks: Array{ start: parseInt(split[0], 10), @@ -59,20 +59,19 @@ export function sourceLocationFromSrc(src: string): Location { * includng "src' information. */ export class SourceMappings { - readonly source: string; readonly lineBreaks: Array; - constructor(source: string) { - this.source = source; + constructor (source: string) { + this.source = source // Create a list of line offsets which will be used to map between // character offset and line/column positions. - const lineBreaks: Array = []; + const lineBreaks: Array = [] for (let pos = source.indexOf('\n'); pos >= 0; pos = source.indexOf('\n', pos + 1)) { lineBreaks.push(pos) } - this.lineBreaks = lineBreaks; + this.lineBreaks = lineBreaks }; /** @@ -81,23 +80,23 @@ export class SourceMappings { * @param astNodeType Type of node to return or null. * @param position Character offset where AST node should be located. */ - nodesAtPosition(astNodeType: string | null, position: Location, ast: AstNode): Array { + nodesAtPosition (astNodeType: string | null, position: Location, ast: AstNode): Array { const astWalker = new AstWalker() - const found: Array = []; + const found: Array = [] - const callback = function(node: AstNode): boolean { - const nodeLocation = sourceLocationFromAstNode(node); + const callback = function (node: AstNode): boolean { + const nodeLocation = sourceLocationFromAstNode(node) if (nodeLocation && - nodeLocation.start == position.start && - nodeLocation.length == position.length) { + nodeLocation.start === position.start && + nodeLocation.length === position.length) { if (!astNodeType || astNodeType === node.nodeType) { found.push(node) } } - return true; + return true } - astWalker.walkFull(ast, callback); - return found; + astWalker.walkFull(ast, callback) + return found } /** @@ -106,25 +105,25 @@ export class SourceMappings { * @param astNodeType nodeType that a found ASTNode must be. Use "null" if any ASTNode can match. * @param sourceLocation "src" location that the AST node must match. */ - findNodeAtSourceLocation(astNodeType: string | undefined, sourceLocation: Location, ast: AstNode | null): AstNode | null { + findNodeAtSourceLocation (astNodeType: string | undefined, sourceLocation: Location, ast: AstNode | null): AstNode | null { const astWalker = new AstWalker() - let found = null; + let found = null /* FIXME: Looking at AST walker code, I don't understand a need to return a boolean. */ - const callback = function(node: AstNode) { - const nodeLocation = sourceLocationFromAstNode(node); + const callback = function (node: AstNode) { + const nodeLocation = sourceLocationFromAstNode(node) if (nodeLocation && - nodeLocation.start == sourceLocation.start && - nodeLocation.length == sourceLocation.length) { - if (astNodeType == undefined || astNodeType === node.nodeType) { - found = node; + nodeLocation.start === sourceLocation.start && + nodeLocation.length === sourceLocation.length) { + if (astNodeType === undefined || astNodeType === node.nodeType) { + found = node } } - return true; + return true } - astWalker.walkFull(ast, callback); - return found; + astWalker.walkFull(ast, callback) + return found } /** @@ -132,8 +131,8 @@ export class SourceMappings { * * @param src Solc "src" object containing attributes {source} and {length}. */ - srcToLineColumnRange(src: string): LineColRange { - const sourceLocation = sourceLocationFromSrc(src); + srcToLineColumnRange (src: string): LineColRange { + const sourceLocation = sourceLocationFromSrc(src) if (sourceLocation.start >= 0 && sourceLocation.length >= 0) { return { start: lineColPositionFromOffset(sourceLocation.start, this.lineBreaks), @@ -146,5 +145,4 @@ export class SourceMappings { } } } - } diff --git a/libs/remix-astwalker/src/types.ts b/libs/remix-astwalker/src/types.ts index 7ffc364249..784323d221 100644 --- a/libs/remix-astwalker/src/types.ts +++ b/libs/remix-astwalker/src/types.ts @@ -3,7 +3,7 @@ export interface Location { start: number; length: number; - file: number; // Would it be clearer to call this a file index? + file: number; // Would it be clearer to call this a file index? } // This is intended to be compatibile with VScode's Position. @@ -31,7 +31,7 @@ export interface Node { export interface AstNode { /* The following fields are essential, and indicates an that object is an AST node. */ - id: number; // This is unique across all nodes in an AST tree + id: number; // This is unique across all nodes in an AST tree nodeType: string; src: string;