mirror of
https://github.com/swc-project/swc.git
synced 2024-12-23 21:54:36 +03:00
211e208219
node/binding: - Fix visitor methods for array elements. (#1819, #1888) - Fix for const assertion. (#1625) - Verify object properties. (#906)
163 lines
4.0 KiB
JavaScript
163 lines
4.0 KiB
JavaScript
import swc from "../..";
|
|
import Visitor from "../../Visitor";
|
|
|
|
function assertAllObjectHasTypeFiled(obj, desc = '') {
|
|
if (Array.isArray(obj)) {
|
|
for (const item of obj) {
|
|
assertAllObjectHasTypeFiled(item, `${desc} -> array`);
|
|
}
|
|
return
|
|
}
|
|
|
|
if (!obj) {
|
|
return
|
|
}
|
|
|
|
if (typeof obj === 'object') {
|
|
if (typeof obj.start !== 'undefined' && typeof obj.end !== 'undefined') {
|
|
return;
|
|
}
|
|
if ("spread" in obj) {
|
|
return;
|
|
}
|
|
|
|
if ("params" in obj && "span" in obj && "body" in obj) {
|
|
return;
|
|
}
|
|
|
|
if (!obj.type) {
|
|
throw new Error(`${desc}: ${JSON.stringify(obj)} should have field 'type'`)
|
|
}
|
|
|
|
for (const key in obj) {
|
|
if (Object.hasOwnProperty.call(obj, key)) {
|
|
assertAllObjectHasTypeFiled(obj[key], `${desc} -> ${key}`)
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
class BaseVisitor extends Visitor.default {
|
|
visitExpression(n) {
|
|
const e = super.visitExpression(n);
|
|
assertAllObjectHasTypeFiled(e);
|
|
return e;
|
|
}
|
|
|
|
visitPattern(n) {
|
|
const e = super.visitPattern(n);
|
|
assertAllObjectHasTypeFiled(e);
|
|
return e;
|
|
}
|
|
|
|
visitStatement(n) {
|
|
const e = super.visitStatement(n);
|
|
assertAllObjectHasTypeFiled(e);
|
|
return e;
|
|
}
|
|
|
|
visitFunctionDeclaration(n) {
|
|
const e = super.visitFunctionDeclaration(n);
|
|
assertAllObjectHasTypeFiled(e);
|
|
return e;
|
|
}
|
|
|
|
visitClassMember(n) {
|
|
const e = super.visitClassMember(n);
|
|
assertAllObjectHasTypeFiled(e);
|
|
return e;
|
|
}
|
|
|
|
visitClassMethod(n) {
|
|
assertAllObjectHasTypeFiled(n, 'BEFORE');
|
|
const e = super.visitClassMethod(n);
|
|
assertAllObjectHasTypeFiled(e);
|
|
return e;
|
|
}
|
|
}
|
|
|
|
const testCodes = [
|
|
{
|
|
input: `const arr = [1, 2, 3]`,
|
|
output: `const arr = [1, 2, 3];`
|
|
},
|
|
{
|
|
input: `export default {
|
|
foo: 'foo',
|
|
} as const;`,
|
|
output: `export default {
|
|
foo: 'foo'
|
|
};`
|
|
},
|
|
|
|
{
|
|
input: `const obj = { a: 1, b: 2 };
|
|
const { a, b } = obj;`,
|
|
output: `const obj = { a: 1, b: 2 };
|
|
const { a, b } = obj;`
|
|
}
|
|
];
|
|
test.each(testCodes)(`code($s)`, async ({ input, output }) => {
|
|
const { code } = await swc.transform(input, {
|
|
jsc: {
|
|
parser: {
|
|
syntax: 'typescript',
|
|
},
|
|
target: 'es2021'
|
|
},
|
|
isModule: true,
|
|
plugin: (ast) => {
|
|
const visitor = new BaseVisitor();
|
|
const after = visitor.visitProgram(ast);
|
|
assertAllObjectHasTypeFiled(after);
|
|
return after
|
|
},
|
|
});
|
|
|
|
expect(code.replace(/[\n\t ]/g, '')).toEqual(output.replace(/[\n\t ]/g, ''))
|
|
})
|
|
|
|
|
|
// test.each(files)('test262(%s)', async (file) => {
|
|
// if (!file.endsWith('.js')) {
|
|
// console.log(`Ignoring ${file}`)
|
|
// return
|
|
// }
|
|
|
|
// console.log(`Validating $${file}`)
|
|
// let astNode;
|
|
// const { code } = await swc.transformFile(file, {
|
|
// jsc: {
|
|
// parser: {
|
|
// syntax: 'ecmascript',
|
|
// },
|
|
// target: 'es2021'
|
|
// },
|
|
// isModule: file.includes('module.'),
|
|
// plugin: (ast) => {
|
|
// // console.debug(ast);
|
|
// const visitor = new BaseVisitor();
|
|
// const after = visitor.visitProgram(ast);
|
|
|
|
// // console.debug(after);
|
|
// assertAllObjectHasTypeFiled(after);
|
|
// astNode = ast;
|
|
// return after
|
|
// },
|
|
// });
|
|
// const filename = path.basename(file);
|
|
|
|
// try {
|
|
// await swc.print(astNode);
|
|
// } catch (e) {
|
|
// throw new Error(`${e}: ${JSON.stringify(astNode, null, 4)}`)
|
|
// }
|
|
|
|
// const expected = await fs.promises.readFile(`./ecmascript/codegen/tests/references/${filename}`, { encoding: 'utf8' });
|
|
|
|
// expect(code.trim()).toEqual(expected.trim());
|
|
|
|
// })
|