From ce7348904697feb497e9ddfb74f14c1924e7c016 Mon Sep 17 00:00:00 2001 From: filip mertens Date: Thu, 7 Jul 2022 10:59:00 +0200 Subject: [PATCH] types --- .../src/app/plugins/parser/code-parser.tsx | 63 +- .../services/code-parser-antlr-service.ts | 71 +- .../parser/services/code-parser-compiler.ts | 4 +- .../services/code-parser-gas-service.ts | 2 +- .../app/plugins/parser/types/antlr-types.ts | 732 ++++++++++++++++++ .../src/app/plugins/parser/types/index.ts | 1 + 6 files changed, 802 insertions(+), 71 deletions(-) create mode 100644 apps/remix-ide/src/app/plugins/parser/types/antlr-types.ts create mode 100644 apps/remix-ide/src/app/plugins/parser/types/index.ts diff --git a/apps/remix-ide/src/app/plugins/parser/code-parser.tsx b/apps/remix-ide/src/app/plugins/parser/code-parser.tsx index 2f87ce1f1c..020ff68d34 100644 --- a/apps/remix-ide/src/app/plugins/parser/code-parser.tsx +++ b/apps/remix-ide/src/app/plugins/parser/code-parser.tsx @@ -14,10 +14,9 @@ import React from 'react' import { fileDecoration, fileDecorationType } from '@remix-ui/file-decorators' 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 = { name: 'codeParser', @@ -26,7 +25,7 @@ const profile: Profile = { version: '0.0.1' } -export function isNodeDefinition(node: any) { +export function isNodeDefinition(node: AstNode) { return node.nodeType === 'ContractDefinition' || node.nodeType === 'FunctionDefinition' || node.nodeType === 'ModifierDefinition' || @@ -37,10 +36,10 @@ export function isNodeDefinition(node: any) { 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 - currentFile: any + compilerAbstract: CompilerAbstract + currentFile: string _index: any astWalker: any errorState: boolean = false @@ -52,7 +51,7 @@ export class CodeParser extends Plugin { antlrService: CodeParserAntlrService nodeHelper: CodeParserNodeHelper - parseSolidity: (text: string) => Promise + parseSolidity: (text: string) => Promise getLastNodeInLine: (ast: string) => Promise listAstNodes: () => Promise getBlockAtPosition: (position: any, text?: string) => Promise @@ -117,7 +116,7 @@ export class CodeParser extends Plugin { * @returns */ async getLastCompilationResult() { - return this.lastCompilationResult + return this.compilerAbstract } @@ -129,9 +128,9 @@ export class CodeParser extends Plugin { * @param compilationResult * @param source */ - _buildIndex(compilationResult, source) { + _buildIndex(compilationResult: CompilationResult, source) { if (compilationResult && compilationResult.sources) { - const callback = (node) => { + const callback = (node: AstNode) => { if (node && node.referencedDeclaration) { if (!this._index.Declarations[node.referencedDeclaration]) { this._index.Declarations[node.referencedDeclaration] = [] @@ -150,7 +149,7 @@ export class CodeParser extends Plugin { // NODE HELPERS - _getInputParams(node) { + _getInputParams(node: FunctionDefinitionAstNode) { const params = [] const target = node.parameters 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 callback = (node) => { node.gasEstimate = this._getContractGasEstimate(node, contractName, fileName, compilatioResult) @@ -176,14 +175,14 @@ export class CodeParser extends Plugin { return index } - _extractFileNodes(fileName: string, compilatioResult: any) { - if (compilatioResult && compilatioResult.data.sources && compilatioResult.data.sources[fileName]) { - const source = compilatioResult.data.sources[fileName] + _extractFileNodes(fileName: string, compilationResult: lastCompilationResult) { + if (compilationResult && compilationResult.data.sources && compilationResult.data.sources[fileName]) { + const source = compilationResult.data.sources[fileName] const nodesByContract = [] this.astWalker.walkFull(source.ast, (node) => { if (node.nodeType === 'ContractDefinition') { - const flatNodes = this._flatNodeList(node, node.name, fileName, compilatioResult) - node.gasEstimate = this._getContractGasEstimate(node, node.name, fileName, compilatioResult) + const flatNodes = this._flatNodeList(node, node.name, fileName, compilationResult) + node.gasEstimate = this._getContractGasEstimate(node, node.name, fileName, compilationResult) 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] for (const name in contracts) { @@ -237,7 +236,7 @@ export class CodeParser extends Plugin { * @returns */ async nodesAtPosition(position: number, type = '') { - const lastCompilationResult = this.lastCompilationResult + const lastCompilationResult = this.compilerAbstract if (!lastCompilationResult) return false const urlFromPath = await this.call('fileManager', 'getUrlFromPath', this.currentFile) console.log('URL FROM PATH', urlFromPath) @@ -253,7 +252,7 @@ export class CodeParser extends Plugin { * @param id * @returns */ - async getNodeById(id: any) { + async getNodeById(id: number) { for (const key in this._index.FlatReferences) { if (this._index.FlatReferences[key].id === id) { return this._index.FlatReferences[key] @@ -266,7 +265,7 @@ export class CodeParser extends Plugin { * @param id * @returns */ - async getDeclaration(id: any) { + async getDeclaration(id: number) { if (this._index.Declarations && this._index.Declarations[id]) return this._index.Declarations[id] } @@ -372,7 +371,7 @@ export class CodeParser extends Plugin { * @param node * @returns */ - async positionOfDefinition(node: any): Promise { + async positionOfDefinition(node: AstNode): Promise { if (node) { if (node.src) { const position = sourceMappingDecoder.decode(node.src) @@ -390,7 +389,7 @@ export class CodeParser extends Plugin { * @param imported * @returns */ - async resolveImports(node, imported = {}) { + async resolveImports(node: AstNode, imported = {}) { if (node.nodeType === 'ImportDirective' && !imported[node.sourceUnit]) { const importNode = await this.getNodeById(node.sourceUnit) imported[importNode.id] = importNode @@ -410,7 +409,7 @@ export class CodeParser extends Plugin { * @param node * @returns */ - referencesOf(node: any) { + referencesOf(node: AstNode) { const results = [] const highlights = (id) => { if (this._index.Declarations && this._index.Declarations[id]) { @@ -461,11 +460,11 @@ export class CodeParser extends Plugin { * @param node * @returns */ - async getNodeLink(node: any) { + async getNodeLink(node: AstNode) { const lineColumn = await this.getLineColumnOfNode(node) const position = await this.positionOfDefinition(node) - if (this.lastCompilationResult && this.lastCompilationResult.sources) { - const fileName = this.lastCompilationResult.getSourceName(position.file) + if (this.compilerAbstract && this.compilerAbstract.source) { + const fileName = this.compilerAbstract.getSourceName(position.file) return lineColumn ? `${fileName} ${lineColumn.start.line}:${lineColumn.start.column}` : null } return '' @@ -484,8 +483,8 @@ export class CodeParser extends Plugin { */ async getLineColumnOfPosition(position: any) { if (position) { - const fileName = this.lastCompilationResult.getSourceName(position.file) - const lineBreaks = sourceMappingDecoder.getLinebreakPositions(this.lastCompilationResult.source.sources[fileName].content) + const fileName = this.compilerAbstract.getSourceName(position.file) + const lineBreaks = sourceMappingDecoder.getLinebreakPositions(this.compilerAbstract.source.sources[fileName].content) const lineColumn = sourceMappingDecoder.convertOffsetToLineColumn(position, lineBreaks) return lineColumn } @@ -496,7 +495,7 @@ export class CodeParser extends Plugin { * @param node * @returns */ - async getNodeDocumentation(node: any) { + async getNodeDocumentation(node: AstNode) { if (node.documentation && node.documentation.text) { let text = '' node.documentation.text.split('\n').forEach(line => { diff --git a/apps/remix-ide/src/app/plugins/parser/services/code-parser-antlr-service.ts b/apps/remix-ide/src/app/plugins/parser/services/code-parser-antlr-service.ts index 51c19a4dd9..abf55e4735 100644 --- a/apps/remix-ide/src/app/plugins/parser/services/code-parser-antlr-service.ts +++ b/apps/remix-ide/src/app/plugins/parser/services/code-parser-antlr-service.ts @@ -1,6 +1,8 @@ 'use strict' +import { AstNode } from "@remix-project/remix-solidity-ts" import { CodeParser } from "../code-parser" +import { antlr } from '../types' const SolidityParser = (window as any).SolidityParser = (window as any).SolidityParser || [] @@ -15,10 +17,7 @@ export default class CodeParserAntlrService { */ async parseSolidity(text: string) { - const t0 = performance.now(); - 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.`); + const ast: antlr.ParseResult = (SolidityParser as any).parse(text, { loc: true, range: true, tolerant: true }) console.log('AST PARSE SUCCESS', ast) return ast } @@ -31,16 +30,16 @@ export default class CodeParserAntlrService { */ async getCurrentFileAST(text: string | null = null) { 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 const fileContent = text || await this.plugin.call('fileManager', 'readFile', this.plugin.currentFile) try { const ast = await this.parseSolidity(fileContent) - this.plugin.currentFileAST = ast + this.plugin.antlrParserResult = ast } catch (e) { console.log(e) } - return this.plugin.currentFileAST + return this.plugin.antlrParserResult } } @@ -51,47 +50,47 @@ export default class CodeParserAntlrService { */ async listAstNodes() { await this.getCurrentFileAST(); - const nodes: any = []; - (SolidityParser as any).visit(this.plugin.currentFileAST, { - StateVariableDeclaration: (node) => { + const nodes: AstNode[] = []; + (SolidityParser as any).visit(this.plugin.antlrParserResult, { + StateVariableDeclaration: (node: antlr.StateVariableDeclaration) => { if (node.variables) { for (const variable of node.variables) { - nodes.push({ ...variable, nodeType: 'VariableDeclaration' }) + nodes.push({ ...variable, nodeType: 'VariableDeclaration', id: null, src: null }) } } }, - VariableDeclaration: (node) => { - nodes.push({ ...node, nodeType: node.type }) + VariableDeclaration: (node: antlr.VariableDeclaration) => { + nodes.push({ ...node, nodeType: node.type, id: null, src: null }) }, - UserDefinedTypeName: (node) => { - nodes.push({ ...node, nodeType: node.type }) + UserDefinedTypeName: (node: antlr.UserDefinedTypeName) => { + nodes.push({ ...node, nodeType: node.type, id: null, src: null }) }, - FunctionDefinition: (node) => { - nodes.push({ ...node, nodeType: node.type }) + FunctionDefinition: (node: antlr.FunctionDefinition) => { + nodes.push({ ...node, nodeType: node.type, id: null, src: null }) }, - ContractDefinition: (node) => { - nodes.push({ ...node, nodeType: node.type }) + ContractDefinition: (node: antlr.ContractDefinition) => { + nodes.push({ ...node, nodeType: node.type, id: null, src: null }) }, - MemberAccess: function (node) { - nodes.push({ ...node, nodeType: node.type }) + MemberAccess: function (node: antlr.MemberAccess) { + nodes.push({ ...node, nodeType: node.type, id: null, src: null }) }, - Identifier: function (node) { - nodes.push({ ...node, nodeType: node.type }) + Identifier: function (node: antlr.Identifier) { + nodes.push({ ...node, nodeType: node.type, id: null, src: null }) }, - EventDefinition: function (node) { - nodes.push({ ...node, nodeType: node.type }) + EventDefinition: function (node: antlr.EventDefinition) { + nodes.push({ ...node, nodeType: node.type, id: null, src: null }) }, - ModifierDefinition: function (node) { - nodes.push({ ...node, nodeType: node.type }) + ModifierDefinition: function (node: antlr.ModifierDefinition) { + nodes.push({ ...node, nodeType: node.type, id: null, src: null }) }, - InvalidNode: function (node) { - nodes.push({ ...node, nodeType: node.type }) + InvalidNode: function (node: antlr.InvalidNode) { + nodes.push({ ...node, nodeType: node.type, id: null, src: null }) }, - EnumDefinition: function (node) { - nodes.push({ ...node, nodeType: node.type }) + EnumDefinition: function (node: antlr.EnumDefinition) { + nodes.push({ ...node, nodeType: node.type, id: null, src: null }) }, - StructDefinition: function (node) { - nodes.push({ ...node, nodeType: node.type }) + StructDefinition: function (node: antlr.StructDefinition) { + nodes.push({ ...node, nodeType: node.type, id: null, src: null }) } }) @@ -118,7 +117,7 @@ export default class CodeParserAntlrService { } (SolidityParser as any).visit(ast, { - MemberAccess: function (node) { + MemberAccess: function (node: any) { checkLastNode(node) }, Identifier: function (node) { @@ -160,8 +159,8 @@ export default class CodeParserAntlrService { } return null } - if (!this.plugin.currentFileAST) return - return walkAst(this.plugin.currentFileAST) + if (!this.plugin.antlrParserResult) return + return walkAst(this.plugin.antlrParserResult) } } \ No newline at end of file diff --git a/apps/remix-ide/src/app/plugins/parser/services/code-parser-compiler.ts b/apps/remix-ide/src/app/plugins/parser/services/code-parser-compiler.ts index de04ed54bd..cc8d20db38 100644 --- a/apps/remix-ide/src/app/plugins/parser/services/code-parser-compiler.ts +++ b/apps/remix-ide/src/app/plugins/parser/services/code-parser-compiler.ts @@ -62,8 +62,8 @@ export default class CodeParserCompiler { if (!data.sources) 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.plugin._index = { Declarations: {}, diff --git a/apps/remix-ide/src/app/plugins/parser/services/code-parser-gas-service.ts b/apps/remix-ide/src/app/plugins/parser/services/code-parser-gas-service.ts index 404a27ae87..5baf69b828 100644 --- a/apps/remix-ide/src/app/plugins/parser/services/code-parser-gas-service.ts +++ b/apps/remix-ide/src/app/plugins/parser/services/code-parser-gas-service.ts @@ -34,7 +34,7 @@ export default class CodeParserGasService { async showGasEstimates() { 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) console.log('all estimates', gasEstimates) diff --git a/apps/remix-ide/src/app/plugins/parser/types/antlr-types.ts b/apps/remix-ide/src/app/plugins/parser/types/antlr-types.ts new file mode 100644 index 0000000000..ebe8a8ea7d --- /dev/null +++ b/apps/remix-ide/src/app/plugins/parser/types/antlr-types.ts @@ -0,0 +1,732 @@ +// Base on the original type definitions for solidity-parser-antlr 0.2 +// by Leonid Logvinov +// Alex Browne +// Xiao Liang + +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 + 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 + 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 = { [K in ASTNodeTypeString]: U extends { type: K } ? U : never } +type ASTTypeMap = ASTMap + + +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] + + + + + + diff --git a/apps/remix-ide/src/app/plugins/parser/types/index.ts b/apps/remix-ide/src/app/plugins/parser/types/index.ts new file mode 100644 index 0000000000..1c252cc882 --- /dev/null +++ b/apps/remix-ide/src/app/plugins/parser/types/index.ts @@ -0,0 +1 @@ +export * as antlr from './antlr-types' \ No newline at end of file