-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #71 from ConsenSys/pretty-printing
Pretty printing
- Loading branch information
Showing
5 changed files
with
251 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
export * from "./location"; | ||
export * from "./utils"; | ||
export * from "./struct_equality"; | ||
export * from "./node"; | ||
export * from "./pretty_printing"; | ||
export * from "./struct_equality"; | ||
export * from "./utils"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
import { ASTNode } from "../ast/ast_node"; | ||
|
||
export interface PPAble { | ||
pp(): string; | ||
} | ||
|
||
export type PPIsh = | ||
| PPAble | ||
| ASTNode | ||
| string | ||
| number | ||
| boolean | ||
| bigint | ||
| null | ||
| undefined | ||
| PPIsh[] | ||
| Set<PPIsh> | ||
| Map<PPIsh, PPIsh> | ||
| Iterable<PPIsh>; | ||
|
||
export function isPPAble(value: any): value is PPAble { | ||
return value ? typeof value.pp === "function" : false; | ||
} | ||
|
||
export function pp(value: PPIsh): string { | ||
if (value instanceof ASTNode) { | ||
return value.type + " #" + value.id; | ||
} | ||
|
||
if (value === undefined) { | ||
return "<undefined>"; | ||
} | ||
|
||
if ( | ||
value === null || | ||
typeof value === "string" || | ||
typeof value === "number" || | ||
typeof value === "boolean" || | ||
typeof value === "bigint" | ||
) { | ||
return String(value); | ||
} | ||
|
||
if (isPPAble(value)) { | ||
return value.pp(); | ||
} | ||
|
||
if (value instanceof Array) { | ||
return ppArr(value); | ||
} | ||
|
||
if (value instanceof Set) { | ||
return ppSet(value); | ||
} | ||
|
||
if (value instanceof Map) { | ||
return ppMap(value); | ||
} | ||
|
||
if (typeof value[Symbol.iterator] === "function") { | ||
return ppIter(value); | ||
} | ||
|
||
throw new Error("Unhandled value in pp(): " + String(value)); | ||
} | ||
|
||
export function ppArr(array: PPIsh[], separator = ",", start = "[", end = "]"): string { | ||
return start + array.map(pp).join(separator) + end; | ||
} | ||
|
||
export function ppIter(iter: Iterable<PPIsh>, separator = ",", start = "[", end = "]"): string { | ||
const parts: string[] = []; | ||
|
||
for (const part of iter) { | ||
parts.push(pp(part)); | ||
} | ||
|
||
return start + parts.join(separator) + end; | ||
} | ||
|
||
export function ppSet(set: Set<PPIsh>, separator = ",", start = "{", end = "}"): string { | ||
return ppIter(set, separator, start, end); | ||
} | ||
|
||
export function ppMap( | ||
map: Map<PPIsh, PPIsh>, | ||
separator = ",", | ||
keyValueSeparator = ":", | ||
start = "{", | ||
end = "}" | ||
): string { | ||
const parts: string[] = []; | ||
|
||
for (const [name, val] of map.entries()) { | ||
parts.push(pp(name) + keyValueSeparator + pp(val)); | ||
} | ||
|
||
return start + parts.join(separator) + end; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
import expect from "expect"; | ||
import { ElementaryTypeName, isPPAble, pp, ppArr, ppIter, ppMap, ppSet } from "../../../src"; | ||
|
||
describe("Utility formatting routines", () => { | ||
describe("isPPAble()", () => { | ||
const cases: Array<[any, boolean]> = [ | ||
[{}, false], | ||
[[], false], | ||
[ | ||
{ | ||
name: "test", | ||
pp: () => "PPAble object" | ||
}, | ||
true | ||
] | ||
]; | ||
|
||
for (const [value, result] of cases) { | ||
it(`${JSON.stringify(value)} results ${result}`, () => { | ||
expect(isPPAble(value)).toEqual(result); | ||
}); | ||
} | ||
}); | ||
|
||
describe("pp()", () => { | ||
const cases: Array<[any, string]> = [ | ||
[1, "1"], | ||
[BigInt(1), "1"], | ||
["abc", "abc"], | ||
[true, "true"], | ||
[false, "false"], | ||
[null, "null"], | ||
[undefined, "<undefined>"], | ||
[ | ||
{ | ||
name: "test", | ||
pp: () => "PPAble object" | ||
}, | ||
"PPAble object" | ||
], | ||
[ | ||
new ElementaryTypeName(1, "0:0:0", "ElementaryTypeName", "uint8", "uint8"), | ||
"ElementaryTypeName #1" | ||
], | ||
[["x", 1, true, null], "[x,1,true,null]"], | ||
[new Set(["a", 2, false, null]), "{a,2,false,null}"], | ||
[ | ||
new Map<string, boolean | number>([ | ||
["x", true], | ||
["y", 100], | ||
["z", false] | ||
]), | ||
"{x:true,y:100,z:false}" | ||
], | ||
[ | ||
(function* gen() { | ||
yield 10; | ||
yield 20; | ||
yield 30; | ||
})(), | ||
"[10,20,30]" | ||
] | ||
]; | ||
|
||
for (const [value, result] of cases) { | ||
it(`${value} results ${result}`, () => { | ||
expect(pp(value)).toEqual(result); | ||
}); | ||
} | ||
}); | ||
|
||
describe("ppArr()", () => { | ||
const cases: Array<[any[], Array<string | undefined>, string]> = [ | ||
[[1, 2, 3], [], "[1,2,3]"], | ||
[["x", "y", "z"], ["/", "<", ">"], "<x/y/z>"] | ||
]; | ||
|
||
for (const [value, options, result] of cases) { | ||
it(`${value} with options ${JSON.stringify(options)} results ${result}`, () => { | ||
expect(ppArr(value, ...options)).toEqual(result); | ||
}); | ||
} | ||
}); | ||
|
||
describe("ppIter()", () => { | ||
function makeIterable<T>(...array: T[]): Iterable<T> { | ||
return { | ||
*[Symbol.iterator]() { | ||
for (const element of array) { | ||
yield element; | ||
} | ||
} | ||
}; | ||
} | ||
|
||
const cases: Array<[Iterable<any>, Array<string | undefined>, string]> = [ | ||
[[1, 2, 3], [], "[1,2,3]"], | ||
[new Set(["x", "y", "z"]), ["/", "<", ">"], "<x/y/z>"], | ||
[makeIterable<any>("1x", 2, "y3"), [], "[1x,2,y3]"] | ||
]; | ||
|
||
for (const [value, options, result] of cases) { | ||
const array = Array.from(value); | ||
|
||
it(`Iterable ${JSON.stringify(array)} with options ${JSON.stringify( | ||
options | ||
)} results ${result}`, () => { | ||
expect(ppIter(value, ...options)).toEqual(result); | ||
}); | ||
} | ||
}); | ||
|
||
describe("ppSet()", () => { | ||
const cases: Array<[Set<any>, Array<string | undefined>, string]> = [ | ||
[new Set([1, 2, 3]), [], "{1,2,3}"], | ||
[new Set(["x", "y", "z"]), ["/", "<", ">"], "<x/y/z>"] | ||
]; | ||
|
||
for (const [value, options, result] of cases) { | ||
it(`${value} with options ${JSON.stringify(options)} results ${result}`, () => { | ||
expect(ppSet(value, ...options)).toEqual(result); | ||
}); | ||
} | ||
}); | ||
|
||
describe("ppMap()", () => { | ||
const map = new Map<string, number>([ | ||
["a", 0], | ||
["b", 3], | ||
["c", 1] | ||
]); | ||
|
||
const cases: Array<[Map<any, any>, Array<string | undefined>, string]> = [ | ||
[map, [], "{a:0,b:3,c:1}"], | ||
[map, ["/", " => ", "<", ">"], "<a => 0/b => 3/c => 1>"] | ||
]; | ||
|
||
for (const [value, options, result] of cases) { | ||
it(`${value} with options ${JSON.stringify(options)} results ${result}`, () => { | ||
expect(ppMap(value, ...options)).toEqual(result); | ||
}); | ||
} | ||
}); | ||
}); |