linting for astwalker done

pull/861/head
aniket-engg 4 years ago
parent 0bdf821487
commit 336ff73996
  1. 3
      libs/remix-astwalker/.eslintrc
  2. 79
      libs/remix-astwalker/src/astWalker.ts
  3. 56
      libs/remix-astwalker/src/sourceMappings.ts

@ -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": ["!**/*"]
}

@ -1,12 +1,12 @@
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"
return obj != null && obj.constructor.name === 'Object'
}
export function isAstNode (node: Record<string, unknown>): boolean {
@ -26,7 +26,6 @@ export function isYulAstNode(node: Record<string, unknown>): boolean {
)
}
/**
* Crawl the given AST through the function walk(ast, callback)
*/
@ -51,18 +50,18 @@ 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 (<AstNode>node) {
if ((<AstNode>node).nodeType in callback) {
/* istanbul ignore next */
return callback[(<AstNode>node).nodeType](node);
return callback[(<AstNode>node).nodeType](node)
} else {
/* istanbul ignore next */
return callback["*"](node);
return callback['*'](node)
}
}
}
@ -76,31 +75,30 @@ export class AstWalker extends EventEmitter {
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
|| []
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)) {
@ -182,47 +180,48 @@ export class AstWalker extends EventEmitter {
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);
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) {
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)
}
}
}
@ -231,18 +230,18 @@ 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);
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) {
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)
}
}
}

@ -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
@ -13,11 +13,11 @@ export declare interface SourceMappings {
* @param offset The character offset to convert.
*/
export function lineColPositionFromOffset (offset: number, lineBreaks: Array<number>): LineColPosition {
let line: number = util.findLowerBound(offset, lineBreaks);
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 <LineColPosition>{
line: line + 1,
character: (offset - beginColumn) + 1
@ -34,7 +34,7 @@ export function sourceLocationFromAstNode(astNode: AstNode): Location | null {
if (isAstNode(astNode) && isYulAstNode(astNode) && astNode.src) {
return sourceLocationFromSrc(astNode.src)
}
return null;
return null
}
/**
@ -59,20 +59,19 @@ export function sourceLocationFromSrc(src: string): Location {
* includng "src' information.
*/
export class SourceMappings {
readonly source: string;
readonly lineBreaks: Array<number>;
constructor (source: string) {
this.source = source;
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<number> = [];
const lineBreaks: Array<number> = []
for (let pos = source.indexOf('\n'); pos >= 0; pos = source.indexOf('\n', pos + 1)) {
lineBreaks.push(pos)
}
this.lineBreaks = lineBreaks;
this.lineBreaks = lineBreaks
};
/**
@ -83,21 +82,21 @@ export class SourceMappings {
*/
nodesAtPosition (astNodeType: string | null, position: Location, ast: AstNode): Array<AstNode> {
const astWalker = new AstWalker()
const found: Array<AstNode> = [];
const found: Array<AstNode> = []
const callback = function (node: AstNode): boolean {
const nodeLocation = sourceLocationFromAstNode(node);
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
}
/**
@ -108,23 +107,23 @@ export class SourceMappings {
*/
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 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
}
/**
@ -133,7 +132,7 @@ export class SourceMappings {
* @param src Solc "src" object containing attributes {source} and {length}.
*/
srcToLineColumnRange (src: string): LineColRange {
const sourceLocation = sourceLocationFromSrc(src);
const sourceLocation = sourceLocationFromSrc(src)
if (sourceLocation.start >= 0 && sourceLocation.length >= 0) {
return <LineColRange>{
start: lineColPositionFromOffset(sourceLocation.start, this.lineBreaks),
@ -146,5 +145,4 @@ export class SourceMappings {
}
}
}
}

Loading…
Cancel
Save