<commit_before>'use strict';

import { Interface } from './interface';

import { defaultAbiCoder, formatSignature, parseSignature } from '../utils/abi-coder';
import { getAddress, getContractAddress } from '../utils/address';
import { ConstantZero } from '../utils/bignumber';
import { hexDataLength, hexDataSlice, isHexString } from '../utils/bytes';
import { defineReadOnly, jsonCopy, shallowCopy } from '../utils/properties';
import { poll } from '../utils/web';

import {
    Signer,
    MinimalProvider,

    BigNumber,

    ContractFunction,
    EventDescription,
    EventFilter,
    ParamType,

    Listener,
    Log,
    TransactionRequest,
    TransactionResponse
} from '../utils/types';

import * as errors from '../utils/errors';

var allowedTransactionKeys: { [ key: string ]: boolean } = {
    data: true, from: true, gasLimit: true, gasPrice:true, nonce: true, to: true, value: true
}

// Recursively replaces ENS names with promises to resolve the name and
// stalls until all promises have returned
// @TODO: Expand this to resolve any promises too
function resolveAddresses(provider: MinimalProvider, value: any, paramType: ParamType | Array<ParamType>): Promise<any> {
    if (Array.isArray(paramType)) {
        var promises: Array<Promise<string>> = [];
        paramType.forEach((paramType, index) => {
            var v = null;
            if (Array.isArray(value)) {
                v = value[index];
            } else {
                v = value[paramType.name];
            }
            promises.push(resolveAddresses(provider, v, paramType));
        });
        return Promise.all(promises);
    }

    if (paramType.type === 'address') {
        return provider.resolveName(value);
    }

    if (paramType.components) {
        return resolveAddresses(provider, value, paramType.components);
    }

    return Promise.resolve(value);
}

type RunFunction = (...params: Array<any>) => Promise<any>;

function runMethod(contract: Contract, functionName: string, estimateOnly: boolean): RunFunction {
    let method = contract.interface.functions[functionName];
    return function(...params): Promise<any> {
        var tx: any = {}
<commit_msg>Fixed recursive promise filling for contract calls.<commit_after>'use strict';

import { Interface } from './interface';

import { defaultAbiCoder, formatSignature, parseSignature } from '../utils/abi-coder';
import { getAddress, getContractAddress } from '../utils/address';
import { ConstantZero } from '../utils/bignumber';
import { hexDataLength, hexDataSlice, isHexString } from '../utils/bytes';
import { defineReadOnly, jsonCopy, shallowCopy } from '../utils/properties';
import { poll } from '../utils/web';

import {
    Signer,
    MinimalProvider,

    BigNumber,

    ContractFunction,
    EventDescription,
    EventFilter,
    ParamType,

    Listener,
    Log,
    TransactionRequest,
    TransactionResponse
} from '../utils/types';

import * as errors from '../utils/errors';

var allowedTransactionKeys: { [ key: string ]: boolean } = {
    data: true, from: true, gasLimit: true, gasPrice:true, nonce: true, to: true, value: true
}

// Recursively replaces ENS names with promises to resolve the name and
// stalls until all promises have returned
// @TODO: Expand this to resolve any promises too
function resolveAddresses(provider: MinimalProvider, value: any, paramType: ParamType | Array<ParamType>): Promise<any> {
    if (Array.isArray(paramType)) {
        var promises: Array<Promise<any>> = [];
        paramType.forEach((paramType, index) => {
            var v = null;
            if (Array.isArray(value)) {
                v = value[index];
            } else {
                v = value[paramType.name];
            }
            promises.push(resolveAddresses(provider, v, paramType));
        });
        return Promise.all(promises);
    }

    if (paramType.type === 'address') {
        return provider.resolveName(value);
    }

    if (paramType.type === 'tuple') {
        return resolveAddresses(provider, value, paramType.components);
    }

    // Strips one level of array indexing off the end to recuse into
    let isArrayMatch = paramType.type.match(/(.*)(\[[0-9]*\]$)/);
    if (isArrayMatch) {
        if (!Array.isArray(value)) { throw new Error('invalid value for array'); }
        var promises: Array<Promise<any>> = [];
        var subParamType = {
            components: paramType.components,
            type: isArrayMatch[1],
        };
        value.forEach((v) => {
            promises.push(resolveAddresses(provider, v, subParamType));
        });
        return Promise.all(promises);
    }

    return Promise.resolve(value);
}

type RunFunction = (...params: Array<any>) => Promise<any>;

function runMethod(contract: Contract, functionName: string, estimateOnly: boolean): RunFunction {
    let method = contract.interface.functions[functionName];
    return function(...params): Promise<any> {
        var tx: any = {}

{'fraction_non_alphanumeric': 0.1301894397420395, 'fraction_numerical': 0.0006045949214026602, 'mean_word_length': 2.99597423510467, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 24, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2734362', 'n_tokens_mistral': 1374, 'n_tokens_neox': 1358, 'n_words': 377}