@solidity-parser/parser
Advanced tools
Comparing version 0.17.0 to 0.18.0
@@ -1,13 +0,18 @@ | ||
interface Location { | ||
start: { | ||
line: number; | ||
column: number; | ||
}; | ||
end: { | ||
line: number; | ||
column: number; | ||
}; | ||
export interface Position { | ||
line: number; | ||
column: number; | ||
} | ||
export interface Location { | ||
start: Position; | ||
end: Position; | ||
} | ||
export interface Comment { | ||
type: 'BlockComment' | 'LineComment'; | ||
value: string; | ||
range?: [number, number]; | ||
loc?: Location; | ||
} | ||
export interface BaseASTNode { | ||
type: ASTNodeTypeString; | ||
comments?: Comment[]; | ||
range?: [number, number]; | ||
@@ -367,3 +372,3 @@ loc?: Location; | ||
} | ||
export declare const binaryOpValues: readonly ["+", "-", "*", "/", "**", "%", "<<", ">>", "&&", "||", ",,", "&", ",", "^", "<", ">", "<=", ">=", "==", "!=", "=", ",=", "^=", "&=", "<<=", ">>=", "+=", "-=", "*=", "/=", "%=", "|", "|="]; | ||
export declare const binaryOpValues: readonly ["+", "-", "*", "/", "**", "%", "<<", ">>", "&&", "||", "&", "^", "<", ">", "<=", ">=", "==", "!=", "=", "^=", "&=", "<<=", ">>=", "+=", "-=", "*=", "/=", "%=", "|", "|="]; | ||
export type BinOp = (typeof binaryOpValues)[number]; | ||
@@ -370,0 +375,0 @@ export declare const unaryOpValues: readonly ["-", "+", "++", "--", "~", "after", "delete", "!"]; |
import { Token as AntlrToken } from 'antlr4'; | ||
import { Token, TokenizeOptions } from './types'; | ||
import type { Comment } from './ast-types'; | ||
export declare function buildTokenList(tokensArg: AntlrToken[], options: TokenizeOptions): Token[]; | ||
export declare function buildCommentList(tokensArg: AntlrToken[], commentsChannelId: number, options: TokenizeOptions): Comment[]; |
@@ -9,2 +9,3 @@ export interface Node { | ||
export interface ParseOptions extends TokenizeOptions { | ||
comments?: boolean; | ||
tokens?: boolean; | ||
@@ -11,0 +12,0 @@ tolerant?: boolean; |
{ | ||
"name": "@solidity-parser/parser", | ||
"version": "0.17.0", | ||
"version": "0.18.0", | ||
"description": "A Solidity parser built from a robust ANTLR 4 grammar", | ||
"main": "dist/index.cjs.js", | ||
"browser": { | ||
"fs": false, | ||
"path": false | ||
}, | ||
"main": "./dist/index.cjs.js", | ||
"browser": "./dist/index.umd.js", | ||
"unpkg": "./dist/index.umd.js", | ||
"files": [ | ||
@@ -48,8 +46,8 @@ "dist/**/*", | ||
"@types/mocha": "^10.0.6", | ||
"@types/node": "^20.10.5", | ||
"@typescript-eslint/eslint-plugin": "^6.15.0", | ||
"@typescript-eslint/parser": "^6.15.0", | ||
"@types/node": "^20.11.5", | ||
"@typescript-eslint/eslint-plugin": "^6.19.0", | ||
"@typescript-eslint/parser": "^6.19.0", | ||
"antlr4": "^4.13.1-patch-1", | ||
"assert": "^2.1.0", | ||
"chai": "^4.3.10", | ||
"chai": "^4.4.1", | ||
"esbuild": "^0.11.13", | ||
@@ -66,4 +64,4 @@ "eslint": "^8.56.0", | ||
"nyc": "^15.1.0", | ||
"prettier": "^3.1.1", | ||
"puppeteer": "^21.6.1", | ||
"prettier": "^3.2.4", | ||
"puppeteer": "^21.7.0", | ||
"ts-node": "^10.9.2", | ||
@@ -70,0 +68,0 @@ "typescript": "^5.3.3", |
@@ -87,3 +87,3 @@ # Solidity Parser for JavaScript | ||
A browser-friendly version is available in `dist/index.iife.js` (along with its sourcemaps file) in the published version. | ||
A browser-friendly version is available in `dist/index.umd.js` (along with its sourcemaps file) in the published version. | ||
@@ -90,0 +90,0 @@ If you are using webpack, keep in mind that minimizing your bundle will mangle function names, breaking the parser. To fix this you can just set `optimization.minimize` to `false`. |
@@ -6,15 +6,22 @@ // Base on the original type definitions for solidity-parser-antlr 0.2 | ||
interface Location { | ||
start: { | ||
line: number | ||
column: number | ||
} | ||
end: { | ||
line: number | ||
column: number | ||
} | ||
export interface Position { | ||
line: number | ||
column: number | ||
} | ||
export interface Location { | ||
start: Position | ||
end: Position | ||
} | ||
export interface Comment { | ||
type: 'BlockComment' | 'LineComment' | ||
value: string | ||
range?: [number, number] | ||
loc?: Location | ||
} | ||
export interface BaseASTNode { | ||
type: ASTNodeTypeString | ||
comments?: Comment[] | ||
range?: [number, number] | ||
@@ -488,5 +495,3 @@ loc?: Location | ||
'||', | ||
',,', | ||
'&', | ||
',', | ||
'^', | ||
@@ -500,3 +505,2 @@ '<', | ||
'=', | ||
',=', | ||
'^=', | ||
@@ -503,0 +507,0 @@ '&=', |
@@ -7,13 +7,2 @@ import { ParserRuleContext, ParseTreeVisitor, ParseTree } from 'antlr4' | ||
interface SourceLocation { | ||
start: { | ||
line: number | ||
column: number | ||
} | ||
end: { | ||
line: number | ||
column: number | ||
} | ||
} | ||
interface WithMeta { | ||
@@ -486,15 +475,15 @@ __withMeta: never | ||
if (ctx.elementaryTypeName()) { | ||
return this.visitElementaryTypeName(ctx.elementaryTypeName()!) | ||
return this.visitElementaryTypeName(ctx.elementaryTypeName()) | ||
} | ||
if (ctx.userDefinedTypeName()) { | ||
return this.visitUserDefinedTypeName(ctx.userDefinedTypeName()!) | ||
return this.visitUserDefinedTypeName(ctx.userDefinedTypeName()) | ||
} | ||
if (ctx.mapping()) { | ||
return this.visitMapping(ctx.mapping()!) | ||
return this.visitMapping(ctx.mapping()) | ||
} | ||
if (ctx.functionTypeName()) { | ||
return this.visitFunctionTypeName(ctx.functionTypeName()!) | ||
return this.visitFunctionTypeName(ctx.functionTypeName()) | ||
} | ||
@@ -678,3 +667,3 @@ | ||
if (ctx.storageLocation()) { | ||
storageLocation = this._toText(ctx.storageLocation()!) | ||
storageLocation = this._toText(ctx.storageLocation()) | ||
} | ||
@@ -889,3 +878,3 @@ | ||
if (ctx.parameterList()) { | ||
parameters = this.visitParameterList(ctx.parameterList()!) | ||
parameters = this.visitParameterList(ctx.parameterList()) | ||
} | ||
@@ -895,4 +884,4 @@ | ||
ctx.identifier() && | ||
this._toText(ctx.identifier()!) !== 'Error' && | ||
this._toText(ctx.identifier()!) !== 'Panic' | ||
this._toText(ctx.identifier()) !== 'Error' && | ||
this._toText(ctx.identifier()) !== 'Panic' | ||
) { | ||
@@ -957,5 +946,5 @@ throw new Error('Expected "Error" or "Panic" identifier in catch clause') | ||
if (ctx.elementaryTypeName()) { | ||
return this.visitElementaryTypeName(ctx.elementaryTypeName()!) | ||
return this.visitElementaryTypeName(ctx.elementaryTypeName()) | ||
} else if (ctx.userDefinedTypeName()) { | ||
return this.visitUserDefinedTypeName(ctx.userDefinedTypeName()!) | ||
return this.visitUserDefinedTypeName(ctx.userDefinedTypeName()) | ||
} else { | ||
@@ -993,3 +982,3 @@ throw new Error( | ||
if (ctx.parameterList()) { | ||
parameters = this.visitParameterList(ctx.parameterList()!) | ||
parameters = this.visitParameterList(ctx.parameterList()) | ||
} | ||
@@ -1065,3 +1054,3 @@ | ||
type: 'NewExpression', | ||
typeName: this.visitTypeName(ctx.typeName()!), | ||
typeName: this.visitTypeName(ctx.typeName()), | ||
} | ||
@@ -1117,3 +1106,3 @@ return this._addMeta(node, ctx) | ||
expression: this.visitExpression(ctx.expression(0)), | ||
memberName: this._toText(ctx.identifier()!), | ||
memberName: this._toText(ctx.identifier()), | ||
} | ||
@@ -1144,10 +1133,10 @@ return this._addMeta(node, ctx) | ||
const ctxArgs = ctx.functionCallArguments()! | ||
const ctxArgs = ctx.functionCallArguments() | ||
if (ctxArgs.expressionList()) { | ||
args = ctxArgs | ||
.expressionList()! | ||
.expressionList() | ||
.expression_list() | ||
.map((exprCtx) => this.visitExpression(exprCtx)) | ||
} else if (ctxArgs.nameValueList()) { | ||
for (const nameValue of ctxArgs.nameValueList()!.nameValue_list()) { | ||
for (const nameValue of ctxArgs.nameValueList().nameValue_list()) { | ||
args.push(this.visitExpression(nameValue.expression())) | ||
@@ -1201,3 +1190,3 @@ names.push(this._toText(nameValue.identifier())) | ||
expression: this.visitExpression(ctx.expression(0)), | ||
arguments: this.visitNameValueList(ctx.nameValueList()!), | ||
arguments: this.visitNameValueList(ctx.nameValueList()), | ||
} | ||
@@ -1319,3 +1308,3 @@ | ||
let conditionExpression: any = this.visitExpressionStatement( | ||
ctx.expressionStatement()! | ||
ctx.expressionStatement() | ||
) | ||
@@ -1328,3 +1317,3 @@ if (conditionExpression) { | ||
initExpression: ctx.simpleStatement() | ||
? this.visitSimpleStatement(ctx.simpleStatement()!) | ||
? this.visitSimpleStatement(ctx.simpleStatement()) | ||
: null, | ||
@@ -1335,3 +1324,3 @@ conditionExpression, | ||
expression: ctx.expression() | ||
? this.visitExpression(ctx.expression()!) | ||
? this.visitExpression(ctx.expression()) | ||
: null, | ||
@@ -1366,3 +1355,3 @@ }, | ||
type: 'BooleanLiteral', | ||
value: this._toText(ctx.BooleanLiteral()!) === 'true', | ||
value: this._toText(ctx.BooleanLiteral()) === 'true', | ||
} | ||
@@ -1374,3 +1363,3 @@ | ||
if (ctx.hexLiteral()) { | ||
return this.visitHexLiteral(ctx.hexLiteral()!) | ||
return this.visitHexLiteral(ctx.hexLiteral()) | ||
} | ||
@@ -1380,6 +1369,6 @@ | ||
const fragments = ctx | ||
.stringLiteral()! | ||
.stringLiteral() | ||
.StringLiteralFragment_list() | ||
.map((stringLiteralFragmentCtx) => { | ||
let text = this._toText(stringLiteralFragmentCtx)! | ||
let text = this._toText(stringLiteralFragmentCtx) | ||
@@ -1412,3 +1401,3 @@ const isUnicode = text.slice(0, 7) === 'unicode' | ||
if (ctx.numberLiteral()) { | ||
return this.visitNumberLiteral(ctx.numberLiteral()!) | ||
return this.visitNumberLiteral(ctx.numberLiteral()) | ||
} | ||
@@ -1426,3 +1415,3 @@ | ||
if (ctx.typeName()) { | ||
return this.visitTypeName(ctx.typeName()!) | ||
return this.visitTypeName(ctx.typeName()) | ||
} | ||
@@ -1500,3 +1489,3 @@ | ||
if (decl.storageLocation()) { | ||
storageLocation = this._toText(decl.storageLocation()!) | ||
storageLocation = this._toText(decl.storageLocation()) | ||
} | ||
@@ -1620,3 +1609,3 @@ | ||
if (ctx.StringLiteralFragment()) { | ||
language = this._toText(ctx.StringLiteralFragment()!)! | ||
language = this._toText(ctx.StringLiteralFragment())! | ||
language = language.substring(1, language.length - 1) | ||
@@ -1663,7 +1652,7 @@ } | ||
if (ctx.hexLiteral()) { | ||
return this.visitHexLiteral(ctx.hexLiteral()!) | ||
return this.visitHexLiteral(ctx.hexLiteral()) | ||
} | ||
if (ctx.stringLiteral()) { | ||
text = this._toText(ctx.stringLiteral()!)! | ||
text = this._toText(ctx.stringLiteral())! | ||
const value = text.substring(1, text.length - 1) | ||
@@ -1739,3 +1728,3 @@ const node: AST.StringLiteral = { | ||
type: 'BooleanLiteral', | ||
value: this._toText(ctx.BooleanLiteral()!) === 'true', | ||
value: this._toText(ctx.BooleanLiteral()) === 'true', | ||
} | ||
@@ -1765,3 +1754,3 @@ | ||
if (ctx.hexLiteral()) { | ||
return this.visitHexLiteral(ctx.hexLiteral()!) | ||
return this.visitHexLiteral(ctx.hexLiteral()) | ||
} | ||
@@ -1787,3 +1776,3 @@ | ||
if (this._toText(ctx.getChild(0)) === 'case') { | ||
value = this.visitAssemblyLiteral(ctx.assemblyLiteral()!) | ||
value = this.visitAssemblyLiteral(ctx.assemblyLiteral()) | ||
} | ||
@@ -1807,11 +1796,11 @@ | ||
if (ctxAssemblyIdentifierOrList.identifier()) { | ||
names = [this.visitIdentifier(ctxAssemblyIdentifierOrList.identifier()!)] | ||
names = [this.visitIdentifier(ctxAssemblyIdentifierOrList.identifier())] | ||
} else if (ctxAssemblyIdentifierOrList.assemblyMember()) { | ||
names = [ | ||
this.visitAssemblyMember(ctxAssemblyIdentifierOrList.assemblyMember()!), | ||
this.visitAssemblyMember(ctxAssemblyIdentifierOrList.assemblyMember()), | ||
] | ||
} else { | ||
names = ctxAssemblyIdentifierOrList | ||
.assemblyIdentifierList()! | ||
.identifier_list()! | ||
.assemblyIdentifierList() | ||
.identifier_list() | ||
.map((x) => this.visitIdentifier(x)) | ||
@@ -1822,3 +1811,3 @@ } | ||
if (ctx.assemblyExpression()) { | ||
expression = this.visitAssemblyExpression(ctx.assemblyExpression()!) | ||
expression = this.visitAssemblyExpression(ctx.assemblyExpression()) | ||
} | ||
@@ -1848,3 +1837,3 @@ | ||
? ctxAssemblyFunctionReturns | ||
.assemblyIdentifierList()! | ||
.assemblyIdentifierList() | ||
.identifier_list() | ||
@@ -1869,10 +1858,10 @@ .map((x) => this.visitIdentifier(x)) | ||
if (ctxAssemblyIdentifierOrList.identifier()) { | ||
names = [this.visitIdentifier(ctxAssemblyIdentifierOrList.identifier()!)] | ||
names = [this.visitIdentifier(ctxAssemblyIdentifierOrList.identifier())] | ||
} else if (ctxAssemblyIdentifierOrList.assemblyMember()) { | ||
names = [ | ||
this.visitAssemblyMember(ctxAssemblyIdentifierOrList.assemblyMember()!), | ||
this.visitAssemblyMember(ctxAssemblyIdentifierOrList.assemblyMember()), | ||
] | ||
} else { | ||
names = ctxAssemblyIdentifierOrList | ||
.assemblyIdentifierList()! | ||
.assemblyIdentifierList() | ||
.identifier_list() | ||
@@ -1998,4 +1987,4 @@ .map((x) => this.visitIdentifier(x)) | ||
private _loc(ctx: ParserRuleContext): SourceLocation { | ||
const sourceLocation: SourceLocation = { | ||
private _loc(ctx: ParserRuleContext): AST.Location { | ||
const sourceLocation: AST.Location = { | ||
start: { | ||
@@ -2002,0 +1991,0 @@ line: ctx.start.line, |
@@ -14,3 +14,3 @@ import { CharStream, CommonTokenStream } from 'antlr4' | ||
import ErrorListener from './ErrorListener' | ||
import { buildTokenList } from './tokens' | ||
import { buildCommentList, buildTokenList } from './tokens' | ||
import { ParseOptions, Token, TokenizeOptions } from './types' | ||
@@ -73,3 +73,3 @@ | ||
const ast: ParseResult | null = astBuilder.result as any | ||
const ast: ParseResult | null = astBuilder.result | ||
@@ -80,16 +80,20 @@ if (ast === null) { | ||
let tokenList: Token[] = [] | ||
if (options.tokens === true) { | ||
tokenList = buildTokenList(tokenStream.tokens, options) | ||
ast.tokens = buildTokenList(tokenStream.tokens, options) | ||
} | ||
if (options.tolerant !== true && listener.hasErrors()) { | ||
throw new ParserError({ errors: listener.getErrors() }) | ||
if (options.comments === true) { | ||
ast.comments = buildCommentList( | ||
tokenStream.tokens, | ||
lexer.channelNames.indexOf('HIDDEN'), | ||
options | ||
) | ||
} | ||
if (options.tolerant === true && listener.hasErrors()) { | ||
if (listener.hasErrors()) { | ||
if (options.tolerant !== true) { | ||
throw new ParserError({ errors: listener.getErrors() }) | ||
} | ||
ast.errors = listener.getErrors() | ||
} | ||
if (options.tokens === true) { | ||
ast.tokens = tokenList | ||
} | ||
@@ -96,0 +100,0 @@ return ast |
import { Token as AntlrToken } from 'antlr4' | ||
import { Token, TokenizeOptions } from './types' | ||
import { tokens } from './antlr/solidity-tokens' | ||
import type { Comment, Location } from './ast-types' | ||
@@ -43,2 +44,21 @@ const TYPE_TOKENS = [ | ||
function range(token: AntlrToken): [number, number] { | ||
return [token.start, token.stop + 1] | ||
} | ||
function loc(token: AntlrToken): Location { | ||
const tokenText = token.text ?? '' | ||
const textInLines = tokenText.split(/\r?\n/) | ||
const numberOfNewLines = textInLines.length - 1 | ||
return { | ||
start: { line: token.line, column: token.column }, | ||
end: { | ||
line: token.line + numberOfNewLines, | ||
column: | ||
textInLines[numberOfNewLines].length + | ||
(numberOfNewLines === 0 ? token.column : 0), | ||
}, | ||
} | ||
} | ||
export function buildTokenList( | ||
@@ -48,21 +68,34 @@ tokensArg: AntlrToken[], | ||
): Token[] { | ||
const result = tokensArg.map((token) => { | ||
return tokensArg.map((token) => { | ||
const type = getTokenType(tokens[token.type.toString()]) | ||
const node: Token = { type, value: token.text } | ||
if (options.range === true) { | ||
node.range = [token.start, token.stop + 1] | ||
node.range = range(token) | ||
} | ||
if (options.loc === true) { | ||
node.loc = { | ||
start: { line: token.line, column: token.column }, | ||
end: { | ||
line: token.line, | ||
column: token.column + (token.text?.length ?? 0), | ||
}, | ||
} | ||
node.loc = loc(token) | ||
} | ||
return node | ||
}) | ||
} | ||
return result | ||
export function buildCommentList( | ||
tokensArg: AntlrToken[], | ||
commentsChannelId: number, | ||
options: TokenizeOptions | ||
): Comment[] { | ||
return tokensArg | ||
.filter((token) => token.channel === commentsChannelId) | ||
.map((token) => { | ||
const comment: Comment = token.text.startsWith('//') | ||
? { type: 'LineComment', value: token.text.slice(2) } | ||
: { type: 'BlockComment', value: token.text.slice(2, -2) } | ||
if (options.range === true) { | ||
comment.range = range(token) | ||
} | ||
if (options.loc === true) { | ||
comment.loc = loc(token) | ||
} | ||
return comment | ||
}) | ||
} |
@@ -11,2 +11,3 @@ export interface Node { | ||
export interface ParseOptions extends TokenizeOptions { | ||
comments?: boolean | ||
tokens?: boolean | ||
@@ -13,0 +14,0 @@ tolerant?: boolean |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
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
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
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
5208857
39
97535
1