Skip to content

Instantly share code, notes, and snippets.

@banyudu
Last active August 20, 2020 01:36
Show Gist options
  • Select an option

  • Save banyudu/63818b4ae22f0cd35a4e2aa24a2fdac6 to your computer and use it in GitHub Desktop.

Select an option

Save banyudu/63818b4ae22f0cd35a4e2aa24a2fdac6 to your computer and use it in GitHub Desktop.
change lib/ast.ts file, convert defnode function calls to class definitations
import {Project, SyntaxKind, ts, Node} from "ts-morph";
const trim = (str: string) => str.substr(1, str.length - 2)
// const printChildren = (node: Node<ts.Node>) => {
// for (const item of node.getChildren()) {
// console.log('kind: ', item.getKindName())
// console.log('text: ', item.getText())
// console.log('>'.repeat(50))
// }
// }
const getMethodStr = (node: Node<ts.Node>, isStatic = false) => {
let name
let body
let result = ''
if (node.getKind() === SyntaxKind.MethodDeclaration) {
// 函数声明
name = node.getChildAtIndex(0).getText()
const params = node.getChildAtIndex(2).getText()
const functionBlock = node.getChildAtIndex(4).getText()
body = '(' + params + ') => ' + functionBlock
} else if (node.getKind() === SyntaxKind.PropertyAssignment) {
// 赋值
name = node.getChildAtIndex(0).getText()
body = node.getChildAtIndex(2).getText()
}
if (name && body) {
result = `${name} = ${body}`
if (isStatic) {
result = 'static ' + result
}
}
return result
}
const output = ({name, extendSentence, methodArr, staticMethodArr}) => {
console.log(`
class ${name} ${extendSentence} {
${staticMethodArr.join('\n ')}
${methodArr.join('\n ')}
}
`)
}
const filename = process.argv[2]
const project = new Project();
const sourceFile = project.addSourceFileAtPath(filename);
const declarations = sourceFile.getVariableDeclarations()
for (const item of declarations) {
const children = item.getChildren()
const nameNode = children[0]
const bodyNode = children.find(item => item.getKind() === SyntaxKind.CallExpression)
const varName = nameNode.getText()
if (!varName.startsWith('AST_')) {
continue
}
// AST_ 开头的变量定义
const defNodeChildren = bodyNode.getChildren()
const funcName = defNodeChildren[0].getText()
if (funcName !== 'DEFNODE') {
continue
}
const defNodeParams = defNodeChildren.find(item => item.getKind() === SyntaxKind.SyntaxList)
const paramsList = defNodeParams.getChildren()
const className = 'AST_' + trim(paramsList[0].getText())
const paramProps = paramsList[2]
const paramMethods = paramsList[4]
const paramStaticMethods = paramsList[6]
const paramBaseClass = paramsList[8]
const extendSentence = paramBaseClass.getKind() === SyntaxKind.NullKeyword ? '' : `extends ${paramBaseClass.getText()}`
const methodArr = paramMethods.getChildren()[1].getChildren().map(method => getMethodStr(method))
const staticMethodArr = paramStaticMethods.getChildren()[1].getChildren().map(method => getMethodStr(method, true))
output({
name: className,
extendSentence,
methodArr,
staticMethodArr
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment