Skip to content

Commit

Permalink
Added string spell-checking to library and fixed discovered typos.
Browse files Browse the repository at this point in the history
  • Loading branch information
ricmoo committed Apr 22, 2020
1 parent 2aeb4e9 commit 71d03c6
Show file tree
Hide file tree
Showing 26 changed files with 250 additions and 32 deletions.
213 changes: 213 additions & 0 deletions admin/cmds/spell-check.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
"use strict";

const { resolve } = require("path");
const fs = require("fs");

const Words = fs.readFileSync("/usr/share/dict/words").toString().split("\n").reduce((accum, word) => {
accum[word.toLowerCase()] = true;
return accum;
}, { });

`
// Words missing from the dictionary
addresses aligned autofill called cancelled censored compiled
computed configured consumed creating decoded
decoding decrypt decrypted decrypting deployed deploying deprecated
discontinued earliest email enabled encoded encoding encrypt
encrypted encrypting entries euro exceeded existing expected expired
failed fetches formatted formatting funding generated
has ignoring implemented implementer imported including instantiate
keyword labelled larger lookup matches mined modified modifies multi
named nested neutered numeric offline optimizer owned packed padded parsed parsing
passed placeholder processing reached recommended recovered redacted remaining replaced
required serializes shared signed signing stored supported
tagging targetted transactions uninstall unsubscribe using verifies website
// Overly Specific Words
BIP BIP39 BIP44 crypto eip hashes hmac icap
keccak namehash ripemd RLP scrypt secp sha
blockhash
bitcoin ethereum finney gwei kwei mwei satoshi szabo wei weth
crowdsale hexlify hd hdnode underpriced
boolean int struct tuple uint
nonpayable
jumpdest mstore shr shl xor
// Classes
ABIEncoder testcase numberish Wordlist
// Common Code Strings
abi addr api app arg arrayify asm basex
bigint bn byte bytecode callback
calldata checksum ciphertext cli codepoint
config contenthash ctr ctrl debug dklen eexist encseed
eof ethaddr ethseed ethers eval exec filename func
gz hid http https hw iv info init ipc
json kdf kdfparams labelhash lang lib
multihash nfc nfkc
nfd nfkd nodehash oob opcode pbkdf pc plugin
pragma pre prf repl rpc sighash topichash solc
stdin stdout subclasses subnode timeout todo txt
ufixed utc utf util url uuid
vm vs websocket wikipedia wx xe zlib
// AbiV2
abiv
// Query parameters
apikey asc endblock startblock
Cloudflare Etherscan INFURA IPFS Nodesmith Trezor ledgerhq
axic bitcoinjs browserify easyseed ethereumjs
goerli homestead kotti kovan mainnet morden mordor rinkeby ropsten testnet
// Demo words
args foo eth foo foobar ll localhost passwd ricmoo tx xxx yna
// nameprep tags
ALCat BiDi LCat nameprep
// Lanauge Codes (and short binary data)
cn cz en es fr it ja tw zh zh_cn zh_tw
OYAa IJBEJqXZJ
`.split("\n").filter((l) => (l.substring(0, 2) != "/\/")).join("\n").split(/\s+/g,).forEach((word) => {
word = word.trim();
if (word === "") { return; }
Words[word.toLowerCase()] = true;
});

const ts = require("typescript");

function getStrings(source) {
const sourceFile = ts.createSourceFile("filename.ts", source);

const result = [ ];

function add(value, pos) {
const lineNo = sourceFile.getLineAndCharacterOfPosition(pos).line + 1;
result.push({ value, lineNo });
}

let lastClass = null, lastEnum = null;
function visit(node, depth) {
switch (node.kind) {
//case ts.SyntaxKind.TemplateExpression:
// if (node.head) { visit(node.head); }
// console.dir(node, { depth: null });
// break;
case ts.SyntaxKind.TemplateHead:
case ts.SyntaxKind.TemplateMiddle:
case ts.SyntaxKind.TemplateTail:
case ts.SyntaxKind.StringLiteral:
case ts.SyntaxKind.NoSubstitutionTemplateLiteral:
add(node.text, node.pos);
break;
}

ts.forEachChild(node, (node) => { return visit(node, depth + 1); });
}

visit(sourceFile, 0);

return result;
}

const Include = new RegExp("packages/.*/src.ts/.*\.ts$");
const Exclude = new RegExp("/node_modules/|src.ts/.*browser.*");

function getAllStrings(path) {
const Root = resolve(__dirname, path);

const readdir = function(path) {
if (path.match(Exclude)) { return [ ]; }

const stat = fs.statSync(path);
if (stat.isDirectory()) {
return fs.readdirSync(path).reduce((result, filename) => {
readdir(resolve(path, filename)).forEach((file) => {
result.push(file);
});
return result;
}, [ ]);
}

if (path.match(Include)) {
const source = fs.readFileSync(path).toString();
return [ { filename: path.substring(Root.length), values: getStrings(source) } ]
}

return [ ];
}

return readdir(Root);
}

function checkWord(word) {
word = word.toLowerCase();

// A word
if (Words[word]) { return true; }

// Simple Plural
if (word.match(/.*s$/) && Words[word.substring(0, word.length - 1)]) { return true; }

// Hex string
if (word.match(/^(0x)?[0-9a-f]*$/i)) { return true; }
}

function starts(text, prefix) {
return (text.substring(0, prefix.length) === prefix);
}

(async function() {
let count = 0;
getAllStrings(resolve(__dirname, "../../packages")).forEach((file) => {
if (starts(file.filename, "/testcases/src.ts/generation-scripts")) { return; }
if (starts(file.filename, "/asm/src.ts/opcodes.ts")) { return; }

file.values.forEach((entry) => {
function problem(word) {
count++;
console.log({
filename: file.filename,
word: JSON.stringify(word),
sentence: JSON.stringify(entry.value.substring(0, 80)),
line: entry.lineNo
});
}

const value = entry.value.trim();

// Emptry space
if (value === "") { return; }

// Prolly a require
if (value.match(/^@ethersproject\/[a-z0-9-]+$/)) { return; }
if (value.substring(0, 2) === "./") { return; }

// Prolly encoded binary data
if (value.indexOf(" ") === -1 && value.length > 20) { return; }

if (checkWord(value)) { return; }

value.replace(/([a-z+])([A-Z])/g, (all, first, secondLetter) => {
return first + " " + secondLetter;
}).replace(/((?:0x)?[A-Za-z]+)/gi, (all, word) => {
if (checkWord(word)) { return; }
problem(word);
return "";
});;
});
});
if (count) {
console.log(`Found ${ count } typos.`);
process.exit(1)
}
process.exit(0)
})();

File renamed without changes.
File renamed without changes.
File renamed without changes.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,9 @@
"lock-versions": "node ./admin/cmds/lock-versions",
"build-docs": "flatworm docs.wrm docs",
"upload-docs": " node ./admin/cmds/upload-docs.js",
"spell-check": "node admin/cmds/spell-check.js",
"_admin_prepare": "npm run clean && npm run bootstrap && npm run build && node ./admin/cmds/update-exports.js",
"update-versions": "npm run _admin_prepare && node ./admin/cmds/update-versions",
"update-versions": "npm run spell-check && npm run _admin_prepare && node ./admin/cmds/update-versions",
"publish-all": "node ./admin/cmds/publish",
"sync-github": "node ./admin/cmds/cache-github"
},
Expand Down
4 changes: 2 additions & 2 deletions packages/abi/src.ts/fragments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -566,7 +566,7 @@ function parseGas(value: string, params: any): string {
logger.throwArgumentError("invalid human-readable ABI signature", "value", value);
}
if (!comps[1].match(/^[0-9]+$/)) {
logger.throwArgumentError("invalid human-readable aBI signature gas", "value", value);
logger.throwArgumentError("invalid human-readable ABI signature gas", "value", value);
}
params.gas = BigNumber.from(comps[1]);
return comps[0];
Expand Down Expand Up @@ -938,7 +938,7 @@ function splitNesting(value: string): Array<any> {
} else if (c === ")") {
depth--;
if (depth === -1) {
logger.throwArgumentError("unbalanced parenthsis", "value", value);
logger.throwArgumentError("unbalanced parenthesis", "value", value);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion packages/abi/src.ts/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ export class Interface {
format(format?: string): string | Array<string> {
if (!format) { format = FormatTypes.full; }
if (format === FormatTypes.sighash) {
logger.throwArgumentError("interface does not support formating sighash", "format", format);
logger.throwArgumentError("interface does not support formatting sighash", "format", format);
}

const abi = this.fragments.map((fragment) => fragment.format(format));
Expand Down
2 changes: 1 addition & 1 deletion packages/asm/src.ts/assembler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ export abstract class Node {
};

const factory = Factories[options.type];
if (!factory) { throwError("uknown type: " + options.type, options.loc); }
if (!factory) { throwError("unknown type: " + options.type, options.loc); }
return factory.from(options);
}
}
Expand Down
2 changes: 1 addition & 1 deletion packages/bignumber/src.ts/bignumber.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export class BigNumber implements Hexable {
logger.checkNew(new.target, BigNumber);

if (constructorGuard !== _constructorGuard) {
logger.throwError("cannot call consturtor directly; use BigNumber.from", Logger.errors.UNSUPPORTED_OPERATION, {
logger.throwError("cannot call constructor directly; use BigNumber.from", Logger.errors.UNSUPPORTED_OPERATION, {
operation: "new (BigNumber)"
});
}
Expand Down
2 changes: 1 addition & 1 deletion packages/bignumber/src.ts/fixednumber.ts
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ export class FixedNumber {
round(decimals?: number): FixedNumber {
if (decimals == null) { decimals = 0; }
if (decimals < 0 || decimals > 80 || (decimals % 1)) {
logger.throwArgumentError("invalid decimal cound", "decimals", decimals);
logger.throwArgumentError("invalid decimal count", "decimals", decimals);
}

// If we are already in range, we're done
Expand Down
4 changes: 2 additions & 2 deletions packages/cli/src.ts/bin/ethers-ens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ abstract class AccountPlugin extends EnsPlugin {
nodehash: string;
static getHelp(): Help {
return logger.throwError("subclasses must implemetn this", ethers.errors.UNSUPPORTED_OPERATION, {
return logger.throwError("subclasses must implement this", ethers.errors.UNSUPPORTED_OPERATION, {
operation: "getHelp"
});
}
Expand Down Expand Up @@ -841,7 +841,7 @@ class ReclaimPlugin extends AddressAccountPlugin {
try {
ownerOf = await registrar.ownerOf(ethers.utils.id(comps[0]));
} catch (error) {
this.throwError("Name not present in Permantent Registrar");
this.throwError("Name not present in Permanent Registrar");
}

if (account !== ownerOf) {
Expand Down
8 changes: 4 additions & 4 deletions packages/cli/src.ts/bin/ethers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,7 @@ class SendPlugin extends Plugin {
await super.prepareOptions(argParser);

if (this.accounts.length !== 1) {
this.throwUsageError("send requires exacly one account");
this.throwUsageError("send requires exactly one account");
}

this.data = ethers.utils.hexlify(argParser.consumeOption("data") || "0x");
Expand Down Expand Up @@ -464,7 +464,7 @@ class SweepPlugin extends Plugin {
await super.prepareOptions(argParser);

if (this.accounts.length !== 1) {
this.throwUsageError("sweep requires exacly one account");
this.throwUsageError("sweep requires exactly one account");
}
}

Expand Down Expand Up @@ -529,7 +529,7 @@ class SignMessagePlugin extends Plugin {
async prepareOptions(argParser: ArgParser): Promise<void> {
await super.prepareOptions(argParser);
if (this.accounts.length !== 1) {
this.throwError("sign-message requires exacly one account");
this.throwError("sign-message requires exactly one account");
}
this.hex = argParser.consumeFlag("hex");
}
Expand Down Expand Up @@ -741,7 +741,7 @@ class UnwrapEtherPlugin extends Plugin {
let address = await this.accounts[0].getAddress();
this.dump("Withdrawing Wrapped Ether", {
"To": address,
"Valiue": ethers.utils.formatEther(this.value)
"Value": ethers.utils.formatEther(this.value)
});

let contract = new ethers.Contract(WethAddress, WethAbi, this.accounts[0]);
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src.ts/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -878,7 +878,7 @@ export class CLI {
console.log(" --gasPrice GWEI Default gas price for transactions(in wei)");
console.log(" --gasLimit GAS Default gas limit for transactions");
console.log(" --nonce NONCE Initial nonce for the first transaction");
console.log(" --yes Always accept Siging and Sending");
console.log(" --yes Always accept Signing and Sending");
console.log("");
}

Expand Down
2 changes: 1 addition & 1 deletion packages/contracts/src.ts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ function runMethod(contract: Contract, functionName: string, options: RunOptions
// Check for unexpected keys (e.g. using "gas" instead of "gasLimit")
for (let key in tx) {
if (!allowedTransactionKeys[key]) {
logger.throwError(("unknown transaxction override - " + key), "overrides", tx);
logger.throwError(("unknown transaction override - " + key), "overrides", tx);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion packages/errors/src.ts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ let LogLevel = LogLevels["default"];
export function setLogLevel(logLevel: string): void {
let level = LogLevels[logLevel];
if (level == null) {
warn("invliad log level - " + logLevel);
warn("invalid log level - " + logLevel);
return;
}
LogLevel = level;
Expand Down
8 changes: 6 additions & 2 deletions packages/ethers/src.ts/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import { defaultPath, entropyToMnemonic, HDNode, isValidMnemonic, mnemonicToEntr
import { getJsonWalletAddress } from "@ethersproject/json-wallets";
import { keccak256 } from "@ethersproject/keccak256";
import { Logger } from "@ethersproject/logger";
import { sha256 } from "@ethersproject/sha2";
import { computeHmac, ripemd160, sha256, sha512 } from "@ethersproject/sha2";
import { keccak256 as solidityKeccak256, pack as solidityPack, sha256 as soliditySha256 } from "@ethersproject/solidity";
import { randomBytes } from "@ethersproject/random";
import { randomBytes, shuffled } from "@ethersproject/random";
import { checkProperties, deepCopy, defineReadOnly, getStatic, resolveProperties, shallowCopy } from "@ethersproject/properties";
import * as RLP from "@ethersproject/rlp";
import { computePublicKey, recoverPublicKey, SigningKey } from "@ethersproject/signing-key";
Expand Down Expand Up @@ -119,10 +119,14 @@ export {

commify,

computeHmac,
keccak256,
ripemd160,
sha256,
sha512,

randomBytes,
shuffled,

solidityPack,
solidityKeccak256,
Expand Down
2 changes: 1 addition & 1 deletion packages/experimental/src.ts/eip1193-bridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ export class _Eip1193Bridge extends EventEmitter {
}
case "estimateGas": {
if (params[1] && params[1] !== "latest") {
throwUnsupported("estimateGas does not supprot blockTag");
throwUnsupported("estimateGas does not support blockTag");
}

const req = ethers.providers.JsonRpcProvider.hexlifyTransaction(params[0]);
Expand Down
Loading

0 comments on commit 71d03c6

Please sign in to comment.