editorcontextDummy
filip mertens 2 years ago
parent 632d6dc9e4
commit cccab12a76
  1. 63
      apps/remix-ide/src/app/plugins/parser/code-parser.tsx
  2. 71
      apps/remix-ide/src/app/plugins/parser/services/code-parser-antlr-service.ts
  3. 4
      apps/remix-ide/src/app/plugins/parser/services/code-parser-compiler.ts
  4. 2
      apps/remix-ide/src/app/plugins/parser/services/code-parser-gas-service.ts
  5. 732
      apps/remix-ide/src/app/plugins/parser/types/antlr-types.ts
  6. 1
      apps/remix-ide/src/app/plugins/parser/types/index.ts

@ -14,10 +14,9 @@ import React from 'react'
import { fileDecoration, fileDecorationType } from '@remix-ui/file-decorators' import { fileDecoration, fileDecorationType } from '@remix-ui/file-decorators'
import { Profile } from '@remixproject/plugin-utils' import { Profile } from '@remixproject/plugin-utils'
// eslint-disable-next-line import { ContractDefinitionAstNode, FunctionCallAstNode, FunctionDefinitionAstNode, ImportDirectiveAstNode, ModifierDefinitionAstNode, VariableDeclarationAstNode } from 'dist/libs/remix-analyzer/src/types'
import { lastCompilationResult } from '@remixproject/plugin-api'
import { antlr } from './types'
const profile: Profile = { const profile: Profile = {
name: 'codeParser', name: 'codeParser',
@ -26,7 +25,7 @@ const profile: Profile = {
version: '0.0.1' version: '0.0.1'
} }
export function isNodeDefinition(node: any) { export function isNodeDefinition(node: AstNode) {
return node.nodeType === 'ContractDefinition' || return node.nodeType === 'ContractDefinition' ||
node.nodeType === 'FunctionDefinition' || node.nodeType === 'FunctionDefinition' ||
node.nodeType === 'ModifierDefinition' || node.nodeType === 'ModifierDefinition' ||
@ -37,10 +36,10 @@ export function isNodeDefinition(node: any) {
export class CodeParser extends Plugin { export class CodeParser extends Plugin {
currentFileAST: any // contains the simple parsed AST for the current file antlrParserResult: antlr.ParseResult // contains the simple parsed AST for the current file
lastCompilationResult: any compilerAbstract: CompilerAbstract
currentFile: any currentFile: string
_index: any _index: any
astWalker: any astWalker: any
errorState: boolean = false errorState: boolean = false
@ -52,7 +51,7 @@ export class CodeParser extends Plugin {
antlrService: CodeParserAntlrService antlrService: CodeParserAntlrService
nodeHelper: CodeParserNodeHelper nodeHelper: CodeParserNodeHelper
parseSolidity: (text: string) => Promise<any> parseSolidity: (text: string) => Promise<antlr.ParseResult>
getLastNodeInLine: (ast: string) => Promise<any> getLastNodeInLine: (ast: string) => Promise<any>
listAstNodes: () => Promise<any> listAstNodes: () => Promise<any>
getBlockAtPosition: (position: any, text?: string) => Promise<any> getBlockAtPosition: (position: any, text?: string) => Promise<any>
@ -117,7 +116,7 @@ export class CodeParser extends Plugin {
* @returns * @returns
*/ */
async getLastCompilationResult() { async getLastCompilationResult() {
return this.lastCompilationResult return this.compilerAbstract
} }
@ -129,9 +128,9 @@ export class CodeParser extends Plugin {
* @param compilationResult * @param compilationResult
* @param source * @param source
*/ */
_buildIndex(compilationResult, source) { _buildIndex(compilationResult: CompilationResult, source) {
if (compilationResult && compilationResult.sources) { if (compilationResult && compilationResult.sources) {
const callback = (node) => { const callback = (node: AstNode) => {
if (node && node.referencedDeclaration) { if (node && node.referencedDeclaration) {
if (!this._index.Declarations[node.referencedDeclaration]) { if (!this._index.Declarations[node.referencedDeclaration]) {
this._index.Declarations[node.referencedDeclaration] = [] this._index.Declarations[node.referencedDeclaration] = []
@ -150,7 +149,7 @@ export class CodeParser extends Plugin {
// NODE HELPERS // NODE HELPERS
_getInputParams(node) { _getInputParams(node: FunctionDefinitionAstNode) {
const params = [] const params = []
const target = node.parameters const target = node.parameters
if (target) { if (target) {
@ -165,7 +164,7 @@ export class CodeParser extends Plugin {
} }
_flatNodeList(node: any, contractName: string, fileName: string, compilatioResult: any) { _flatNodeList(node: ContractDefinitionAstNode, contractName: string, fileName: string, compilatioResult: any) {
const index = {} const index = {}
const callback = (node) => { const callback = (node) => {
node.gasEstimate = this._getContractGasEstimate(node, contractName, fileName, compilatioResult) node.gasEstimate = this._getContractGasEstimate(node, contractName, fileName, compilatioResult)
@ -176,14 +175,14 @@ export class CodeParser extends Plugin {
return index return index
} }
_extractFileNodes(fileName: string, compilatioResult: any) { _extractFileNodes(fileName: string, compilationResult: lastCompilationResult) {
if (compilatioResult && compilatioResult.data.sources && compilatioResult.data.sources[fileName]) { if (compilationResult && compilationResult.data.sources && compilationResult.data.sources[fileName]) {
const source = compilatioResult.data.sources[fileName] const source = compilationResult.data.sources[fileName]
const nodesByContract = [] const nodesByContract = []
this.astWalker.walkFull(source.ast, (node) => { this.astWalker.walkFull(source.ast, (node) => {
if (node.nodeType === 'ContractDefinition') { if (node.nodeType === 'ContractDefinition') {
const flatNodes = this._flatNodeList(node, node.name, fileName, compilatioResult) const flatNodes = this._flatNodeList(node, node.name, fileName, compilationResult)
node.gasEstimate = this._getContractGasEstimate(node, node.name, fileName, compilatioResult) node.gasEstimate = this._getContractGasEstimate(node, node.name, fileName, compilationResult)
nodesByContract[node.name] = { contractDefinition: node, contractNodes: flatNodes } nodesByContract[node.name] = { contractDefinition: node, contractNodes: flatNodes }
} }
}) })
@ -191,7 +190,7 @@ export class CodeParser extends Plugin {
} }
} }
_getContractGasEstimate(node: any, contractName: string, fileName: string, compilationResult: any) { _getContractGasEstimate(node: ContractDefinitionAstNode | FunctionDefinitionAstNode, contractName: string, fileName: string, compilationResult: lastCompilationResult) {
const contracts = compilationResult.data.contracts && compilationResult.data.contracts[this.currentFile] const contracts = compilationResult.data.contracts && compilationResult.data.contracts[this.currentFile]
for (const name in contracts) { for (const name in contracts) {
@ -237,7 +236,7 @@ export class CodeParser extends Plugin {
* @returns * @returns
*/ */
async nodesAtPosition(position: number, type = '') { async nodesAtPosition(position: number, type = '') {
const lastCompilationResult = this.lastCompilationResult const lastCompilationResult = this.compilerAbstract
if (!lastCompilationResult) return false if (!lastCompilationResult) return false
const urlFromPath = await this.call('fileManager', 'getUrlFromPath', this.currentFile) const urlFromPath = await this.call('fileManager', 'getUrlFromPath', this.currentFile)
console.log('URL FROM PATH', urlFromPath) console.log('URL FROM PATH', urlFromPath)
@ -253,7 +252,7 @@ export class CodeParser extends Plugin {
* @param id * @param id
* @returns * @returns
*/ */
async getNodeById(id: any) { async getNodeById(id: number) {
for (const key in this._index.FlatReferences) { for (const key in this._index.FlatReferences) {
if (this._index.FlatReferences[key].id === id) { if (this._index.FlatReferences[key].id === id) {
return this._index.FlatReferences[key] return this._index.FlatReferences[key]
@ -266,7 +265,7 @@ export class CodeParser extends Plugin {
* @param id * @param id
* @returns * @returns
*/ */
async getDeclaration(id: any) { async getDeclaration(id: number) {
if (this._index.Declarations && this._index.Declarations[id]) return this._index.Declarations[id] if (this._index.Declarations && this._index.Declarations[id]) return this._index.Declarations[id]
} }
@ -372,7 +371,7 @@ export class CodeParser extends Plugin {
* @param node * @param node
* @returns * @returns
*/ */
async positionOfDefinition(node: any): Promise<any | null> { async positionOfDefinition(node: AstNode): Promise<any | null> {
if (node) { if (node) {
if (node.src) { if (node.src) {
const position = sourceMappingDecoder.decode(node.src) const position = sourceMappingDecoder.decode(node.src)
@ -390,7 +389,7 @@ export class CodeParser extends Plugin {
* @param imported * @param imported
* @returns * @returns
*/ */
async resolveImports(node, imported = {}) { async resolveImports(node: AstNode, imported = {}) {
if (node.nodeType === 'ImportDirective' && !imported[node.sourceUnit]) { if (node.nodeType === 'ImportDirective' && !imported[node.sourceUnit]) {
const importNode = await this.getNodeById(node.sourceUnit) const importNode = await this.getNodeById(node.sourceUnit)
imported[importNode.id] = importNode imported[importNode.id] = importNode
@ -410,7 +409,7 @@ export class CodeParser extends Plugin {
* @param node * @param node
* @returns * @returns
*/ */
referencesOf(node: any) { referencesOf(node: AstNode) {
const results = [] const results = []
const highlights = (id) => { const highlights = (id) => {
if (this._index.Declarations && this._index.Declarations[id]) { if (this._index.Declarations && this._index.Declarations[id]) {
@ -461,11 +460,11 @@ export class CodeParser extends Plugin {
* @param node * @param node
* @returns * @returns
*/ */
async getNodeLink(node: any) { async getNodeLink(node: AstNode) {
const lineColumn = await this.getLineColumnOfNode(node) const lineColumn = await this.getLineColumnOfNode(node)
const position = await this.positionOfDefinition(node) const position = await this.positionOfDefinition(node)
if (this.lastCompilationResult && this.lastCompilationResult.sources) { if (this.compilerAbstract && this.compilerAbstract.source) {
const fileName = this.lastCompilationResult.getSourceName(position.file) const fileName = this.compilerAbstract.getSourceName(position.file)
return lineColumn ? `${fileName} ${lineColumn.start.line}:${lineColumn.start.column}` : null return lineColumn ? `${fileName} ${lineColumn.start.line}:${lineColumn.start.column}` : null
} }
return '' return ''
@ -484,8 +483,8 @@ export class CodeParser extends Plugin {
*/ */
async getLineColumnOfPosition(position: any) { async getLineColumnOfPosition(position: any) {
if (position) { if (position) {
const fileName = this.lastCompilationResult.getSourceName(position.file) const fileName = this.compilerAbstract.getSourceName(position.file)
const lineBreaks = sourceMappingDecoder.getLinebreakPositions(this.lastCompilationResult.source.sources[fileName].content) const lineBreaks = sourceMappingDecoder.getLinebreakPositions(this.compilerAbstract.source.sources[fileName].content)
const lineColumn = sourceMappingDecoder.convertOffsetToLineColumn(position, lineBreaks) const lineColumn = sourceMappingDecoder.convertOffsetToLineColumn(position, lineBreaks)
return lineColumn return lineColumn
} }
@ -496,7 +495,7 @@ export class CodeParser extends Plugin {
* @param node * @param node
* @returns * @returns
*/ */
async getNodeDocumentation(node: any) { async getNodeDocumentation(node: AstNode) {
if (node.documentation && node.documentation.text) { if (node.documentation && node.documentation.text) {
let text = '' let text = ''
node.documentation.text.split('\n').forEach(line => { node.documentation.text.split('\n').forEach(line => {

@ -1,6 +1,8 @@
'use strict' 'use strict'
import { AstNode } from "@remix-project/remix-solidity-ts"
import { CodeParser } from "../code-parser" import { CodeParser } from "../code-parser"
import { antlr } from '../types'
const SolidityParser = (window as any).SolidityParser = (window as any).SolidityParser || [] const SolidityParser = (window as any).SolidityParser = (window as any).SolidityParser || []
@ -15,10 +17,7 @@ export default class CodeParserAntlrService {
*/ */
async parseSolidity(text: string) { async parseSolidity(text: string) {
const t0 = performance.now(); const ast: antlr.ParseResult = (SolidityParser as any).parse(text, { loc: true, range: true, tolerant: true })
const ast = (SolidityParser as any).parse(text, { loc: true, range: true, tolerant: true })
const t1 = performance.now();
console.log(`Call to doSomething took ${t1 - t0} milliseconds.`);
console.log('AST PARSE SUCCESS', ast) console.log('AST PARSE SUCCESS', ast)
return ast return ast
} }
@ -31,16 +30,16 @@ export default class CodeParserAntlrService {
*/ */
async getCurrentFileAST(text: string | null = null) { async getCurrentFileAST(text: string | null = null) {
this.plugin.currentFile = await this.plugin.call('fileManager', 'file') this.plugin.currentFile = await this.plugin.call('fileManager', 'file')
if(this.plugin.currentFile && this.plugin.currentFile.endsWith('.sol')) { if (this.plugin.currentFile && this.plugin.currentFile.endsWith('.sol')) {
if (!this.plugin.currentFile) return if (!this.plugin.currentFile) return
const fileContent = text || await this.plugin.call('fileManager', 'readFile', this.plugin.currentFile) const fileContent = text || await this.plugin.call('fileManager', 'readFile', this.plugin.currentFile)
try { try {
const ast = await this.parseSolidity(fileContent) const ast = await this.parseSolidity(fileContent)
this.plugin.currentFileAST = ast this.plugin.antlrParserResult = ast
} catch (e) { } catch (e) {
console.log(e) console.log(e)
} }
return this.plugin.currentFileAST return this.plugin.antlrParserResult
} }
} }
@ -51,47 +50,47 @@ export default class CodeParserAntlrService {
*/ */
async listAstNodes() { async listAstNodes() {
await this.getCurrentFileAST(); await this.getCurrentFileAST();
const nodes: any = []; const nodes: AstNode[] = [];
(SolidityParser as any).visit(this.plugin.currentFileAST, { (SolidityParser as any).visit(this.plugin.antlrParserResult, {
StateVariableDeclaration: (node) => { StateVariableDeclaration: (node: antlr.StateVariableDeclaration) => {
if (node.variables) { if (node.variables) {
for (const variable of node.variables) { for (const variable of node.variables) {
nodes.push({ ...variable, nodeType: 'VariableDeclaration' }) nodes.push({ ...variable, nodeType: 'VariableDeclaration', id: null, src: null })
} }
} }
}, },
VariableDeclaration: (node) => { VariableDeclaration: (node: antlr.VariableDeclaration) => {
nodes.push({ ...node, nodeType: node.type }) nodes.push({ ...node, nodeType: node.type, id: null, src: null })
}, },
UserDefinedTypeName: (node) => { UserDefinedTypeName: (node: antlr.UserDefinedTypeName) => {
nodes.push({ ...node, nodeType: node.type }) nodes.push({ ...node, nodeType: node.type, id: null, src: null })
}, },
FunctionDefinition: (node) => { FunctionDefinition: (node: antlr.FunctionDefinition) => {
nodes.push({ ...node, nodeType: node.type }) nodes.push({ ...node, nodeType: node.type, id: null, src: null })
}, },
ContractDefinition: (node) => { ContractDefinition: (node: antlr.ContractDefinition) => {
nodes.push({ ...node, nodeType: node.type }) nodes.push({ ...node, nodeType: node.type, id: null, src: null })
}, },
MemberAccess: function (node) { MemberAccess: function (node: antlr.MemberAccess) {
nodes.push({ ...node, nodeType: node.type }) nodes.push({ ...node, nodeType: node.type, id: null, src: null })
}, },
Identifier: function (node) { Identifier: function (node: antlr.Identifier) {
nodes.push({ ...node, nodeType: node.type }) nodes.push({ ...node, nodeType: node.type, id: null, src: null })
}, },
EventDefinition: function (node) { EventDefinition: function (node: antlr.EventDefinition) {
nodes.push({ ...node, nodeType: node.type }) nodes.push({ ...node, nodeType: node.type, id: null, src: null })
}, },
ModifierDefinition: function (node) { ModifierDefinition: function (node: antlr.ModifierDefinition) {
nodes.push({ ...node, nodeType: node.type }) nodes.push({ ...node, nodeType: node.type, id: null, src: null })
}, },
InvalidNode: function (node) { InvalidNode: function (node: antlr.InvalidNode) {
nodes.push({ ...node, nodeType: node.type }) nodes.push({ ...node, nodeType: node.type, id: null, src: null })
}, },
EnumDefinition: function (node) { EnumDefinition: function (node: antlr.EnumDefinition) {
nodes.push({ ...node, nodeType: node.type }) nodes.push({ ...node, nodeType: node.type, id: null, src: null })
}, },
StructDefinition: function (node) { StructDefinition: function (node: antlr.StructDefinition) {
nodes.push({ ...node, nodeType: node.type }) nodes.push({ ...node, nodeType: node.type, id: null, src: null })
} }
}) })
@ -118,7 +117,7 @@ export default class CodeParserAntlrService {
} }
(SolidityParser as any).visit(ast, { (SolidityParser as any).visit(ast, {
MemberAccess: function (node) { MemberAccess: function (node: any) {
checkLastNode(node) checkLastNode(node)
}, },
Identifier: function (node) { Identifier: function (node) {
@ -160,8 +159,8 @@ export default class CodeParserAntlrService {
} }
return null return null
} }
if (!this.plugin.currentFileAST) return if (!this.plugin.antlrParserResult) return
return walkAst(this.plugin.currentFileAST) return walkAst(this.plugin.antlrParserResult)
} }
} }

@ -62,8 +62,8 @@ export default class CodeParserCompiler {
if (!data.sources) return if (!data.sources) return
if (data.sources && Object.keys(data.sources).length === 0) return if (data.sources && Object.keys(data.sources).length === 0) return
this.plugin.lastCompilationResult = new CompilerAbstract('soljson', data, source, input) this.plugin.compilerAbstract = new CompilerAbstract('soljson', data, source, input)
console.log('ABSTRACT', this.plugin.compilerAbstract)
this.errorState = false this.errorState = false
this.plugin._index = { this.plugin._index = {
Declarations: {}, Declarations: {},

@ -34,7 +34,7 @@ export default class CodeParserGasService {
async showGasEstimates() { async showGasEstimates() {
this.plugin.currentFile = await this.plugin.call('fileManager', 'file') this.plugin.currentFile = await this.plugin.call('fileManager', 'file')
this.plugin._index.NodesPerFile[this.plugin.currentFile] = await this.plugin._extractFileNodes(this.plugin.currentFile, this.plugin.lastCompilationResult) this.plugin._index.NodesPerFile[this.plugin.currentFile] = await this.plugin._extractFileNodes(this.plugin.currentFile, this.plugin.compilerAbstract)
const gasEstimates = await this.getGasEstimates(this.plugin.currentFile) const gasEstimates = await this.getGasEstimates(this.plugin.currentFile)
console.log('all estimates', gasEstimates) console.log('all estimates', gasEstimates)

@ -0,0 +1,732 @@
// Base on the original type definitions for solidity-parser-antlr 0.2
// by Leonid Logvinov <https://github.com/LogvinovLeon>
// Alex Browne <https://github.com/albrow>
// Xiao Liang <https://github.com/yxliang01>
export type ParseResult = SourceUnit & {
errors?: any[]
tokens?: Token[]
}
interface Token {
type: string
value: string | undefined
range?: [number, number]
loc?: {
start: {
line: number
column: number
}
end: {
line: number
column: number
}
}
}
interface Location {
start: {
line: number
column: number
}
end: {
line: number
column: number
}
}
export interface BaseASTNode {
type: ASTNodeTypeString
range?: [number, number]
loc?: Location
}
export interface SourceUnit extends BaseASTNode {
type: 'SourceUnit'
children: ASTNode[]
}
export interface ContractDefinition extends BaseASTNode {
type: 'ContractDefinition'
name: string
baseContracts: InheritanceSpecifier[]
kind: string
subNodes: BaseASTNode[]
}
export interface InheritanceSpecifier extends BaseASTNode {
type: 'InheritanceSpecifier'
baseName: UserDefinedTypeName
arguments: Expression[]
}
export interface UserDefinedTypeName extends BaseASTNode {
type: 'UserDefinedTypeName'
namePath: string
}
export type ASTNodeTypeString = typeof astNodeTypes[number]
export interface InvalidNode extends BaseASTNode {
type: 'InvalidNode'
name?: string
value?: string
}
export interface PragmaDirective extends BaseASTNode {
type: 'PragmaDirective'
name: string
value: string
}
export interface ImportDirective extends BaseASTNode {
type: 'ImportDirective'
path: string
pathLiteral: StringLiteral
unitAlias: string | null
unitAliasIdentifier: Identifier | null
symbolAliases: Array<[string, string | null]> | null
symbolAliasesIdentifiers: Array<[Identifier, Identifier | null]> | null
}
export interface StateVariableDeclaration extends BaseASTNode {
type: 'StateVariableDeclaration'
variables: StateVariableDeclarationVariable[]
initialValue: Expression | null
}
export interface FileLevelConstant extends BaseASTNode {
type: 'FileLevelConstant'
typeName: TypeName
name: string
initialValue: Expression
isDeclaredConst: boolean
isImmutable: boolean
}
export interface UsingForDeclaration extends BaseASTNode {
type: 'UsingForDeclaration'
typeName: TypeName | null
functions: string[]
libraryName: string | null
isGlobal: boolean;
}
export interface StructDefinition extends BaseASTNode {
type: 'StructDefinition'
name: string
members: VariableDeclaration[]
}
export interface ModifierDefinition extends BaseASTNode {
type: 'ModifierDefinition'
name: string
parameters: null | VariableDeclaration[]
isVirtual: boolean
override: null | UserDefinedTypeName[]
body: Block | null
}
export interface ModifierInvocation extends BaseASTNode {
type: 'ModifierInvocation'
name: string
arguments: Expression[] | null
}
export interface FunctionDefinition extends BaseASTNode {
type: 'FunctionDefinition'
name: string | null
parameters: VariableDeclaration[]
modifiers: ModifierInvocation[]
stateMutability: 'pure' | 'constant' | 'payable' | 'view' | null
visibility: 'default' | 'external' | 'internal' | 'public' | 'private'
returnParameters: VariableDeclaration[] | null
body: Block | null
override: UserDefinedTypeName[] | null
isConstructor: boolean
isReceiveEther: boolean
isFallback: boolean
isVirtual: boolean
}
export interface CustomErrorDefinition extends BaseASTNode {
type: 'CustomErrorDefinition'
name: string
parameters: VariableDeclaration[]
}
export interface TypeDefinition extends BaseASTNode {
type: 'TypeDefinition'
name: string
definition: ElementaryTypeName
}
export interface RevertStatement extends BaseASTNode {
type: 'RevertStatement'
revertCall: FunctionCall
}
export interface EventDefinition extends BaseASTNode {
type: 'EventDefinition'
name: string
parameters: VariableDeclaration[]
isAnonymous: boolean
}
export interface EnumValue extends BaseASTNode {
type: 'EnumValue'
name: string
}
export interface EnumDefinition extends BaseASTNode {
type: 'EnumDefinition'
name: string
members: EnumValue[]
}
export interface VariableDeclaration extends BaseASTNode {
type: 'VariableDeclaration'
isIndexed: boolean
isStateVar: boolean
typeName: TypeName | null
name: string | null
identifier: Identifier | null
isDeclaredConst?: boolean
storageLocation: string | null
expression: Expression | null
visibility?: 'public' | 'private' | 'internal' | 'default'
}
export interface StateVariableDeclarationVariable extends VariableDeclaration {
override: null | UserDefinedTypeName[]
isImmutable: boolean
}
export interface ArrayTypeName extends BaseASTNode {
type: 'ArrayTypeName'
baseTypeName: TypeName
length: Expression | null
}
export interface Mapping extends BaseASTNode {
type: 'Mapping'
keyType: ElementaryTypeName | UserDefinedTypeName
valueType: TypeName
}
export interface FunctionTypeName extends BaseASTNode {
type: 'FunctionTypeName'
parameterTypes: VariableDeclaration[]
returnTypes: VariableDeclaration[]
visibility: string
stateMutability: string | null
}
export interface Block extends BaseASTNode {
type: 'Block'
statements: BaseASTNode[]
}
export interface ExpressionStatement extends BaseASTNode {
type: 'ExpressionStatement'
expression: Expression | null
}
export interface IfStatement extends BaseASTNode {
type: 'IfStatement'
condition: Expression
trueBody: Statement
falseBody: Statement | null
}
export interface UncheckedStatement extends BaseASTNode {
type: 'UncheckedStatement'
block: Block
}
export interface TryStatement extends BaseASTNode {
type: 'TryStatement'
expression: Expression
returnParameters: VariableDeclaration[] | null
body: Block
catchClauses: CatchClause[]
}
export interface CatchClause extends BaseASTNode {
type: 'CatchClause'
isReasonStringType: boolean
kind: string | null
parameters: VariableDeclaration[] | null
body: Block
}
export interface WhileStatement extends BaseASTNode {
type: 'WhileStatement'
condition: Expression
body: Statement
}
export interface ForStatement extends BaseASTNode {
type: 'ForStatement'
initExpression: SimpleStatement | null
conditionExpression?: Expression
loopExpression: ExpressionStatement
body: Statement
}
export interface InlineAssemblyStatement extends BaseASTNode {
type: 'InlineAssemblyStatement'
language: string | null
flags: string[]
body: AssemblyBlock
}
export interface DoWhileStatement extends BaseASTNode {
type: 'DoWhileStatement'
condition: Expression
body: Statement
}
export interface ContinueStatement extends BaseASTNode {
type: 'ContinueStatement'
}
export interface Break extends BaseASTNode {
type: 'Break'
}
export interface Continue extends BaseASTNode {
type: 'Continue'
}
export interface BreakStatement extends BaseASTNode {
type: 'BreakStatement'
}
export interface ReturnStatement extends BaseASTNode {
type: 'ReturnStatement'
expression: Expression | null
}
export interface EmitStatement extends BaseASTNode {
type: 'EmitStatement'
eventCall: FunctionCall
}
export interface ThrowStatement extends BaseASTNode {
type: 'ThrowStatement'
}
export interface VariableDeclarationStatement extends BaseASTNode {
type: 'VariableDeclarationStatement'
variables: Array<BaseASTNode | null>
initialValue: Expression | null
}
export interface ElementaryTypeName extends BaseASTNode {
type: 'ElementaryTypeName'
name: string
stateMutability: string | null
}
export interface FunctionCall extends BaseASTNode {
type: 'FunctionCall'
expression: Expression
arguments: Expression[]
names: string[]
identifiers: Identifier[]
}
export interface AssemblyBlock extends BaseASTNode {
type: 'AssemblyBlock'
operations: AssemblyItem[]
}
export interface AssemblyCall extends BaseASTNode {
type: 'AssemblyCall'
functionName: string
arguments: AssemblyExpression[]
}
export interface AssemblyLocalDefinition extends BaseASTNode {
type: 'AssemblyLocalDefinition'
names: Identifier[] | AssemblyMemberAccess[]
expression: AssemblyExpression | null
}
export interface AssemblyAssignment extends BaseASTNode {
type: 'AssemblyAssignment'
names: Identifier[] | AssemblyMemberAccess[]
expression: AssemblyExpression
}
export interface AssemblyStackAssignment extends BaseASTNode {
type: 'AssemblyStackAssignment'
name: string
expression: AssemblyExpression
}
export interface LabelDefinition extends BaseASTNode {
type: 'LabelDefinition'
name: string
}
export interface AssemblySwitch extends BaseASTNode {
type: 'AssemblySwitch'
expression: AssemblyExpression
cases: AssemblyCase[]
}
export interface AssemblyCase extends BaseASTNode {
type: 'AssemblyCase'
value: AssemblyLiteral | null
block: AssemblyBlock
default: boolean
}
export interface AssemblyFunctionDefinition extends BaseASTNode {
type: 'AssemblyFunctionDefinition'
name: string
arguments: Identifier[]
returnArguments: Identifier[]
body: AssemblyBlock
}
export interface AssemblyFunctionReturns extends BaseASTNode {
type: 'AssemblyFunctionReturns'
}
export interface AssemblyFor extends BaseASTNode {
type: 'AssemblyFor'
pre: AssemblyBlock | AssemblyExpression
condition: AssemblyExpression
post: AssemblyBlock | AssemblyExpression
body: AssemblyBlock
}
export interface AssemblyIf extends BaseASTNode {
type: 'AssemblyIf'
condition: AssemblyExpression
body: AssemblyBlock
}
export type AssemblyLiteral =
| StringLiteral
| DecimalNumber
| HexNumber
| HexLiteral
export interface SubAssembly extends BaseASTNode {
type: 'SubAssembly'
}
export interface AssemblyMemberAccess extends BaseASTNode {
type: 'AssemblyMemberAccess'
expression: Identifier
memberName: Identifier
}
export interface NewExpression extends BaseASTNode {
type: 'NewExpression'
typeName: TypeName
}
export interface TupleExpression extends BaseASTNode {
type: 'TupleExpression'
components: Array<BaseASTNode | null>
isArray: boolean
}
export interface NameValueExpression extends BaseASTNode {
type: 'NameValueExpression'
expression: Expression
arguments: NameValueList
}
export interface NumberLiteral extends BaseASTNode {
type: 'NumberLiteral'
number: string
subdenomination:
| null
| 'wei'
| 'szabo'
| 'finney'
| 'ether'
| 'seconds'
| 'minutes'
| 'hours'
| 'days'
| 'weeks'
| 'years'
}
export interface BooleanLiteral extends BaseASTNode {
type: 'BooleanLiteral'
value: boolean
}
export interface HexLiteral extends BaseASTNode {
type: 'HexLiteral'
value: string
parts: string[]
}
export interface StringLiteral extends BaseASTNode {
type: 'StringLiteral'
value: string
parts: string[]
isUnicode: boolean[]
}
export interface Identifier extends BaseASTNode {
type: 'Identifier'
name: string
}
export interface BinaryOperation extends BaseASTNode {
type: 'BinaryOperation'
left: Expression
right: Expression
operator: BinOp
}
export interface UnaryOperation extends BaseASTNode {
type: 'UnaryOperation'
operator: UnaryOp
subExpression: Expression
isPrefix: boolean
}
export interface Conditional extends BaseASTNode {
type: 'Conditional'
condition: Expression
trueExpression: Expression
falseExpression: Expression
}
export interface IndexAccess extends BaseASTNode {
type: 'IndexAccess'
base: Expression
index: Expression
}
export interface IndexRangeAccess extends BaseASTNode {
type: 'IndexRangeAccess'
base: Expression
indexStart?: Expression
indexEnd?: Expression
}
export interface MemberAccess extends BaseASTNode {
type: 'MemberAccess'
expression: Expression
memberName: string
}
export interface HexNumber extends BaseASTNode {
type: 'HexNumber'
value: string
}
export interface DecimalNumber extends BaseASTNode {
type: 'DecimalNumber'
value: string
}
export interface NameValueList extends BaseASTNode {
type: 'NameValueList'
names: string[]
identifiers: Identifier[]
arguments: Expression[]
}
export type ASTNode =
| SourceUnit
| PragmaDirective
| ImportDirective
| ContractDefinition
| InheritanceSpecifier
| StateVariableDeclaration
| UsingForDeclaration
| StructDefinition
| ModifierDefinition
| ModifierInvocation
| FunctionDefinition
| EventDefinition
| CustomErrorDefinition
| EnumValue
| EnumDefinition
| VariableDeclaration
| TypeName
| UserDefinedTypeName
| Mapping
| FunctionTypeName
| Block
| Statement
| ElementaryTypeName
| AssemblyBlock
| AssemblyCall
| AssemblyLocalDefinition
| AssemblyAssignment
| AssemblyStackAssignment
| LabelDefinition
| AssemblySwitch
| AssemblyCase
| AssemblyFunctionDefinition
| AssemblyFunctionReturns
| AssemblyFor
| AssemblyIf
| AssemblyLiteral
| SubAssembly
| TupleExpression
| BinaryOperation
| Conditional
| IndexAccess
| IndexRangeAccess
| AssemblyItem
| Expression
| NameValueList
| AssemblyMemberAccess
| CatchClause
| FileLevelConstant
| TypeDefinition
| InvalidNode
export type AssemblyItem =
| Identifier
| AssemblyBlock
| AssemblyExpression
| AssemblyLocalDefinition
| AssemblyAssignment
| AssemblyStackAssignment
| LabelDefinition
| AssemblySwitch
| AssemblyFunctionDefinition
| AssemblyFor
| AssemblyIf
| Break
| Continue
| SubAssembly
| NumberLiteral
| StringLiteral
| HexNumber
| HexLiteral
| DecimalNumber
export type AssemblyExpression = AssemblyCall | AssemblyLiteral
export type Expression =
| IndexAccess
| IndexRangeAccess
| TupleExpression
| BinaryOperation
| Conditional
| MemberAccess
| FunctionCall
| UnaryOperation
| NewExpression
| PrimaryExpression
| NameValueExpression
export type PrimaryExpression =
| BooleanLiteral
| HexLiteral
| StringLiteral
| NumberLiteral
| Identifier
| TupleExpression
| TypeName
export type SimpleStatement = VariableDeclarationStatement | ExpressionStatement
export type TypeName =
| ElementaryTypeName
| UserDefinedTypeName
| Mapping
| ArrayTypeName
| FunctionTypeName
export type Statement =
| IfStatement
| WhileStatement
| ForStatement
| Block
| InlineAssemblyStatement
| DoWhileStatement
| ContinueStatement
| BreakStatement
| ReturnStatement
| EmitStatement
| ThrowStatement
| SimpleStatement
| VariableDeclarationStatement
| UncheckedStatement
| TryStatement
| RevertStatement
type ASTMap<U> = { [K in ASTNodeTypeString]: U extends { type: K } ? U : never }
type ASTTypeMap = ASTMap<ASTNode>
export const astNodeTypes = [
'SourceUnit',
'PragmaDirective',
'ImportDirective',
'ContractDefinition',
'InheritanceSpecifier',
'StateVariableDeclaration',
'UsingForDeclaration',
'StructDefinition',
'ModifierDefinition',
'ModifierInvocation',
'FunctionDefinition',
'EventDefinition',
'CustomErrorDefinition',
'RevertStatement',
'EnumValue',
'EnumDefinition',
'VariableDeclaration',
'UserDefinedTypeName',
'Mapping',
'ArrayTypeName',
'FunctionTypeName',
'Block',
'ExpressionStatement',
'IfStatement',
'WhileStatement',
'ForStatement',
'InlineAssemblyStatement',
'DoWhileStatement',
'ContinueStatement',
'Break',
'Continue',
'BreakStatement',
'ReturnStatement',
'EmitStatement',
'ThrowStatement',
'VariableDeclarationStatement',
'ElementaryTypeName',
'FunctionCall',
'AssemblyBlock',
'AssemblyCall',
'AssemblyLocalDefinition',
'AssemblyAssignment',
'AssemblyStackAssignment',
'LabelDefinition',
'AssemblySwitch',
'AssemblyCase',
'AssemblyFunctionDefinition',
'AssemblyFunctionReturns',
'AssemblyFor',
'AssemblyIf',
'SubAssembly',
'TupleExpression',
'NameValueExpression',
'BooleanLiteral',
'NumberLiteral',
'Identifier',
'BinaryOperation',
'UnaryOperation',
'NewExpression',
'Conditional',
'StringLiteral',
'HexLiteral',
'HexNumber',
'DecimalNumber',
'MemberAccess',
'IndexAccess',
'IndexRangeAccess',
'NameValueList',
'UncheckedStatement',
'TryStatement',
'CatchClause',
'FileLevelConstant',
'AssemblyMemberAccess',
'TypeDefinition',
'InvalidNode'
] as const
export const binaryOpValues = [
'+',
'-',
'*',
'/',
'**',
'%',
'<<',
'>>',
'&&',
'||',
',,',
'&',
',',
'^',
'<',
'>',
'<=',
'>=',
'==',
'!=',
'=',
',=',
'^=',
'&=',
'<<=',
'>>=',
'+=',
'-=',
'*=',
'/=',
'%=',
'|',
'|=',
] as const
export type BinOp = typeof binaryOpValues[number]
export const unaryOpValues = [
'-',
'+',
'++',
'--',
'~',
'after',
'delete',
'!',
] as const
export type UnaryOp = typeof unaryOpValues[number]

@ -0,0 +1 @@
export * as antlr from './antlr-types'
Loading…
Cancel
Save