194 lines
5.3 KiB
JavaScript
194 lines
5.3 KiB
JavaScript
"use strict"
|
|
|
|
const assert = require("assert")
|
|
const acorn = require("acorn")
|
|
const Parser = acorn.Parser.extend(require(".."))
|
|
|
|
function test(text, expectedResult, additionalOptions) {
|
|
it(text, function () {
|
|
const result = Parser.parse(text, Object.assign({ ecmaVersion: 9 }, additionalOptions))
|
|
assert.deepStrictEqual(result.body[0], expectedResult)
|
|
})
|
|
}
|
|
function testFail(text, expectedError, additionalOptions) {
|
|
it(text, function () {
|
|
let failed = false
|
|
try {
|
|
Parser.parse(text, Object.assign({ ecmaVersion: 9 }, additionalOptions))
|
|
} catch (e) {
|
|
assert.strictEqual(e.message, expectedError)
|
|
failed = true
|
|
}
|
|
assert(failed)
|
|
})
|
|
}
|
|
|
|
const newNode = (start, props) => Object.assign(new acorn.Node({options: {}}, start), props)
|
|
const newBigIntLiteral = (start, stringValue) => newNode(start, {
|
|
type: "Literal",
|
|
end: start + stringValue.length + 1,
|
|
value: typeof BigInt !== "undefined" ? BigInt(stringValue) : null,
|
|
raw: `${stringValue}n`,
|
|
bigint: `${stringValue}n`
|
|
})
|
|
|
|
describe("acorn-bigint", function () {
|
|
const digits = [
|
|
{d: "0", ast: start => newBigIntLiteral(start, "0")},
|
|
{d: "2", ast: start => newBigIntLiteral(start, "2")},
|
|
{d: "0x2", ast: start => newBigIntLiteral(start, "0x2")},
|
|
{d: "0o2", ast: start => newBigIntLiteral(start, "0o2")},
|
|
{d: "0b10", ast: start => newBigIntLiteral(start, "0b10")},
|
|
{d: "-0xbf2ed51ff75d380fd3be813ec6185780", ast: start => newNode(start, {
|
|
type: "UnaryExpression",
|
|
end: start + 36,
|
|
operator: "-",
|
|
prefix: true,
|
|
argument: newBigIntLiteral(start + 1, "0xbf2ed51ff75d380fd3be813ec6185780")
|
|
})},
|
|
{d: "02", error: start => `Identifier directly after number (1:${start + 2})`},
|
|
{d: "2e2", error: start => `Identifier directly after number (1:${start + 3})`},
|
|
{d: "2.4", error: start => `Identifier directly after number (1:${start + 3})`},
|
|
{d: ".4", error: start => `Identifier directly after number (1:${start + 2})`},
|
|
]
|
|
const statements = [
|
|
{s: "let i = %s", ast: content => newNode(0, {
|
|
type: "VariableDeclaration",
|
|
end: content.end,
|
|
kind: "let",
|
|
declarations: [newNode(4, {
|
|
type: "VariableDeclarator",
|
|
end: content.end,
|
|
id: newNode(4, {
|
|
type: "Identifier",
|
|
end: 5,
|
|
name: "i"
|
|
}),
|
|
init: content
|
|
})]
|
|
})},
|
|
|
|
{s: "i = %s", ast: content => newNode(0, {
|
|
type: "ExpressionStatement",
|
|
end: content.end,
|
|
expression: newNode(0, {
|
|
type: "AssignmentExpression",
|
|
end: content.end,
|
|
operator: "=",
|
|
left: newNode(0, {
|
|
type: "Identifier",
|
|
end: 1,
|
|
name: "i"
|
|
}),
|
|
right: content
|
|
})
|
|
})},
|
|
|
|
{s: "((i = %s) => {})", ast: content => newNode(0, {
|
|
type: "ExpressionStatement",
|
|
end: content.end + 8,
|
|
expression: newNode(1, {
|
|
type: "ArrowFunctionExpression",
|
|
end: content.end + 7,
|
|
id: null,
|
|
generator: false,
|
|
expression: false,
|
|
async: false,
|
|
params: [
|
|
newNode(2, {
|
|
type: "AssignmentPattern",
|
|
end: content.end,
|
|
left: newNode(2, {
|
|
type: "Identifier",
|
|
end: 3,
|
|
name: "i"
|
|
}),
|
|
right: content
|
|
})
|
|
],
|
|
body: newNode(content.end + 5, {
|
|
type: "BlockStatement",
|
|
end: content.end + 7,
|
|
body: []
|
|
})
|
|
})
|
|
})},
|
|
|
|
{s: "for (let i = 0n; i < %s;++i) {}", ast: content => newNode(0, {
|
|
type: "ForStatement",
|
|
end: content.end + 8,
|
|
init: newNode(5, {
|
|
type: "VariableDeclaration",
|
|
end: 15,
|
|
declarations: [
|
|
newNode(9, {
|
|
type: "VariableDeclarator",
|
|
end: 15,
|
|
id: newNode(9, {
|
|
type: "Identifier",
|
|
end: 10,
|
|
name: "i"
|
|
}),
|
|
init: newBigIntLiteral(13, "0")
|
|
})
|
|
],
|
|
kind: "let"
|
|
}),
|
|
test: newNode(17, {
|
|
type: "BinaryExpression",
|
|
end: content.end,
|
|
left: newNode(17, {
|
|
type: "Identifier",
|
|
start: 17,
|
|
end: 18,
|
|
name: "i"
|
|
}),
|
|
operator: "<",
|
|
right: content
|
|
}),
|
|
update: newNode(content.end + 1, {
|
|
type: "UpdateExpression",
|
|
end: content.end + 4,
|
|
operator: "++",
|
|
prefix: true,
|
|
argument: newNode(content.end + 3, {
|
|
type: "Identifier",
|
|
end: content.end + 4,
|
|
name: "i"
|
|
})
|
|
}),
|
|
body: newNode(content.end + 6, {
|
|
type: "BlockStatement",
|
|
end: content.end + 8,
|
|
body: []
|
|
})
|
|
})},
|
|
|
|
{s: "i + %s", ast: content => newNode(0, {
|
|
type: "ExpressionStatement",
|
|
end: content.end,
|
|
expression: newNode(0, {
|
|
type: "BinaryExpression",
|
|
end: content.end,
|
|
left: newNode(0, {
|
|
type: "Identifier",
|
|
start: 0,
|
|
end: 1,
|
|
name: "i"
|
|
}),
|
|
operator: "+",
|
|
right: content
|
|
})
|
|
})}
|
|
]
|
|
statements.forEach(statement => {
|
|
const start = statement.s.indexOf("%s")
|
|
digits.forEach(d => {
|
|
(d.error ? testFail : test)(
|
|
statement.s.replace("%s", `${d.d}n`),
|
|
d.error ? d.error(start) : statement.ast(d.ast(start))
|
|
)
|
|
})
|
|
})
|
|
})
|