You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
116 lines
4.0 KiB
116 lines
4.0 KiB
'use strict'
|
|
import { AstWalker } from '@remix-project/remix-astwalker'
|
|
|
|
/**
|
|
* return all contract definitions of the given @astList
|
|
*
|
|
* @param {Object} sourcesList - sources list (containing root AST node)
|
|
* @return {Object} - returns a mapping from AST node ids to AST nodes for the contracts
|
|
*/
|
|
export function extractContractDefinitions (sourcesList) {
|
|
const ret = {
|
|
contractsById: {},
|
|
contractsByName: {},
|
|
sourcesByContract: {}
|
|
}
|
|
const walker = new AstWalker()
|
|
for (const k in sourcesList) {
|
|
walker.walkFull(sourcesList[k].ast, (node) => {
|
|
if (node.nodeType === 'ContractDefinition') {
|
|
ret.contractsById[node.id] = node
|
|
ret.sourcesByContract[node.id] = k
|
|
ret.contractsByName[k + ':' + node.name] = node
|
|
}
|
|
})
|
|
}
|
|
return ret
|
|
}
|
|
|
|
/**
|
|
* return nodes from an ast @arg sourcesList that are declared outside of a ContractDefinition @astList
|
|
*
|
|
* @param {Object} sourcesList - sources list (containing root AST node)
|
|
* @return {Object} - returns a list of node
|
|
*/
|
|
export function extractOrphanDefinitions (sourcesList) {
|
|
const ret = []
|
|
for (const k in sourcesList) {
|
|
const ast = sourcesList[k].ast
|
|
if (ast.nodes && ast.nodes.length) {
|
|
for (const node of ast.nodes) {
|
|
if (node.nodeType !== 'ContractDefinition') {
|
|
ret.push(node)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return ret
|
|
}
|
|
|
|
/**
|
|
* returns the linearized base contracts of the contract @arg id
|
|
*
|
|
* @param {Int} id - contract id to resolve
|
|
* @param {Map} contracts - all contracts defined in the current context
|
|
* @return {Array} - array of base contracts in derived to base order as AST nodes.
|
|
*/
|
|
export function getLinearizedBaseContracts (id, contractsById) {
|
|
return contractsById[id].linearizedBaseContracts.map(function (id) { return contractsById[id] })
|
|
}
|
|
|
|
/**
|
|
* return state var and type definition of the given contract
|
|
*
|
|
* @param {String} contractName - contract for which state var should be resolved
|
|
* @param {Object} sourcesList - sources list (containing root AST node)
|
|
* @param {Object} [contracts] - map of contract definitions (contains contractsById, contractsByName)
|
|
* @return {Object} - return an object containing: stateItems - list of all the children node of the @arg contractName
|
|
* stateVariables - list of all the variable declaration of the @arg contractName
|
|
*/
|
|
export function extractStateDefinitions (contractName, sourcesList, contracts) {
|
|
if (!contracts) {
|
|
contracts = extractContractDefinitions(sourcesList)
|
|
}
|
|
const node = contracts.contractsByName[contractName]
|
|
if (!node) {
|
|
return null
|
|
}
|
|
const stateItems = extractOrphanDefinitions(sourcesList)
|
|
const stateVar = []
|
|
const baseContracts = getLinearizedBaseContracts(node.id, contracts.contractsById)
|
|
baseContracts.reverse()
|
|
for (const k in baseContracts) {
|
|
const ctr = baseContracts[k]
|
|
for (const i in ctr.nodes) {
|
|
const item = ctr.nodes[i]
|
|
stateItems.push(item)
|
|
if (item.nodeType === 'VariableDeclaration') {
|
|
stateVar.push(item)
|
|
}
|
|
}
|
|
}
|
|
return { stateDefinitions: stateItems, stateVariables: stateVar }
|
|
}
|
|
|
|
/**
|
|
* return state var and type definition of all the contracts from the given @args sourcesList
|
|
*
|
|
* @param {Object} sourcesList - sources list (containing root AST node)
|
|
* @param {Object} [contracts] - map of contract definitions (contains contractsById, contractsByName)
|
|
* @return {Object} - returns a mapping between contract name and contract state
|
|
*/
|
|
export function extractStatesDefinitions (sourcesList, contracts) {
|
|
if (!contracts) {
|
|
contracts = extractContractDefinitions(sourcesList)
|
|
}
|
|
const ret = {}
|
|
for (const contract in contracts.contractsById) {
|
|
const name = contracts.contractsById[contract].name
|
|
const source = contracts.sourcesByContract[contract]
|
|
const fullName = source + ':' + name
|
|
const state = extractStateDefinitions(fullName, sourcesList, contracts)
|
|
ret[fullName] = state
|
|
ret[name] = state // solc < 0.4.9
|
|
}
|
|
return ret
|
|
}
|
|
|