mirror of https://github.com/sveltejs/svelte
parent
0a61385aa9
commit
f3b399f9b1
@ -1,188 +0,0 @@
|
||||
/** @import { Context, Visitors } from 'zimmerframe' */
|
||||
/** @import { FunctionExpression, FunctionDeclaration } from 'estree' */
|
||||
import { walk } from 'zimmerframe';
|
||||
import * as b from '#compiler/builders';
|
||||
import * as e from '../../errors.js';
|
||||
|
||||
/**
|
||||
* @param {FunctionExpression | FunctionDeclaration} node
|
||||
* @param {Context<any, any>} context
|
||||
*/
|
||||
function remove_this_param(node, context) {
|
||||
if (node.params[0]?.type === 'Identifier' && node.params[0].name === 'this') {
|
||||
node.params.shift();
|
||||
}
|
||||
return context.next();
|
||||
}
|
||||
|
||||
/** @type {Visitors<any, null>} */
|
||||
const visitors = {
|
||||
_(node, context) {
|
||||
const n = context.next() ?? node;
|
||||
|
||||
// TODO there may come a time when we decide to preserve type annotations.
|
||||
// until that day comes, we just delete them so they don't confuse esrap
|
||||
delete n.typeAnnotation;
|
||||
delete n.typeParameters;
|
||||
delete n.typeArguments;
|
||||
delete n.returnType;
|
||||
delete n.accessibility;
|
||||
delete n.readonly;
|
||||
delete n.definite;
|
||||
delete n.override;
|
||||
|
||||
// `optional` is reused by JS optional chaining (`a?.b`, `a?.()`), so only
|
||||
// strip the TypeScript optional marker (`x?: T`, `m?(): T`, `x?: T` fields)
|
||||
if (n.type !== 'MemberExpression' && n.type !== 'CallExpression') {
|
||||
delete n.optional;
|
||||
}
|
||||
},
|
||||
Decorator(node) {
|
||||
e.typescript_invalid_feature(node, 'decorators (related TSC proposal is not stage 4 yet)');
|
||||
},
|
||||
ImportDeclaration(node) {
|
||||
if (node.importKind === 'type') return b.empty;
|
||||
|
||||
if (node.specifiers?.length > 0) {
|
||||
const specifiers = node.specifiers.filter((/** @type {any} */ s) => s.importKind !== 'type');
|
||||
if (specifiers.length === 0) return b.empty;
|
||||
|
||||
return { ...node, specifiers };
|
||||
}
|
||||
|
||||
return node;
|
||||
},
|
||||
ExportNamedDeclaration(node, context) {
|
||||
if (node.exportKind === 'type') return b.empty;
|
||||
|
||||
if (node.declaration) {
|
||||
const result = context.next();
|
||||
if (result?.declaration?.type === 'EmptyStatement') {
|
||||
return b.empty;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
if (node.specifiers) {
|
||||
const specifiers = node.specifiers.filter((/** @type {any} */ s) => s.exportKind !== 'type');
|
||||
if (specifiers.length === 0) return b.empty;
|
||||
|
||||
return { ...node, specifiers };
|
||||
}
|
||||
|
||||
return node;
|
||||
},
|
||||
ExportDefaultDeclaration(node) {
|
||||
if (node.exportKind === 'type') return b.empty;
|
||||
return node;
|
||||
},
|
||||
ExportAllDeclaration(node) {
|
||||
if (node.exportKind === 'type') return b.empty;
|
||||
return node;
|
||||
},
|
||||
PropertyDefinition(node, { next }) {
|
||||
if (node.accessor) {
|
||||
e.typescript_invalid_feature(
|
||||
node,
|
||||
'accessor fields (related TSC proposal is not stage 4 yet)'
|
||||
);
|
||||
}
|
||||
return next();
|
||||
},
|
||||
TSAsExpression(node, context) {
|
||||
return context.visit(node.expression);
|
||||
},
|
||||
TSSatisfiesExpression(node, context) {
|
||||
return context.visit(node.expression);
|
||||
},
|
||||
TSNonNullExpression(node, context) {
|
||||
return context.visit(node.expression);
|
||||
},
|
||||
TSInterfaceDeclaration() {
|
||||
return b.empty;
|
||||
},
|
||||
TSTypeAliasDeclaration() {
|
||||
return b.empty;
|
||||
},
|
||||
TSTypeAssertion(node, context) {
|
||||
return context.visit(node.expression);
|
||||
},
|
||||
TSEnumDeclaration(node) {
|
||||
e.typescript_invalid_feature(node, 'enums');
|
||||
},
|
||||
TSParameterProperty(node, context) {
|
||||
if ((node.readonly || node.accessibility) && context.path.at(-2)?.kind === 'constructor') {
|
||||
e.typescript_invalid_feature(node, 'accessibility modifiers on constructor parameters');
|
||||
}
|
||||
return context.visit(node.parameter);
|
||||
},
|
||||
TSInstantiationExpression(node, context) {
|
||||
return context.visit(node.expression);
|
||||
},
|
||||
FunctionExpression: remove_this_param,
|
||||
FunctionDeclaration: remove_this_param,
|
||||
TSDeclareFunction() {
|
||||
return b.empty;
|
||||
},
|
||||
ClassBody(node, context) {
|
||||
const body = [];
|
||||
for (const _child of node.body) {
|
||||
const child = context.visit(_child);
|
||||
if (child.type !== 'PropertyDefinition' || !child.declare) {
|
||||
body.push(child);
|
||||
}
|
||||
}
|
||||
return {
|
||||
...node,
|
||||
body
|
||||
};
|
||||
},
|
||||
ClassDeclaration(node, context) {
|
||||
if (node.declare) {
|
||||
return b.empty;
|
||||
}
|
||||
delete node.abstract;
|
||||
delete node.implements;
|
||||
delete node.superTypeArguments;
|
||||
delete node.superTypeParameters;
|
||||
return context.next();
|
||||
},
|
||||
ClassExpression(node, context) {
|
||||
delete node.implements;
|
||||
delete node.superTypeArguments;
|
||||
delete node.superTypeParameters;
|
||||
return context.next();
|
||||
},
|
||||
MethodDefinition(node, context) {
|
||||
if (node.abstract) {
|
||||
return b.empty;
|
||||
}
|
||||
return context.next();
|
||||
},
|
||||
VariableDeclaration(node, context) {
|
||||
if (node.declare) {
|
||||
return b.empty;
|
||||
}
|
||||
return context.next();
|
||||
},
|
||||
TSModuleDeclaration(node, context) {
|
||||
if (!node.body) return b.empty;
|
||||
|
||||
// namespaces can contain non-type nodes
|
||||
const cleaned = /** @type {any[]} */ (node.body.body).map((entry) => context.visit(entry));
|
||||
if (cleaned.some((entry) => entry !== b.empty)) {
|
||||
e.typescript_invalid_feature(node, 'namespaces with non-type nodes');
|
||||
}
|
||||
|
||||
return b.empty;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @template T
|
||||
* @param {T} ast
|
||||
* @returns {T}
|
||||
*/
|
||||
export function remove_typescript_nodes(ast) {
|
||||
return walk(ast, null, visitors);
|
||||
}
|
||||
Loading…
Reference in new issue