fix(client/codegen): fix rare crash when parsing default arguments

i have no idea why having .parent makes it crash but whatever lol.
This commit is contained in:
teidesu 2021-04-10 23:12:07 +03:00
parent 9edaa438fd
commit eb9b004b44

View file

@ -38,6 +38,8 @@ async function addSingleMethod(state, fileName) {
) )
const relPath = path.relative(targetDir, fileName).replace(/\\/g, '/') // replace path delim to unix const relPath = path.relative(targetDir, fileName).replace(/\\/g, '/') // replace path delim to unix
state.files[relPath] = fileFullText
function getLeadingComments(ast) { function getLeadingComments(ast) {
return (ts.getLeadingCommentRanges(fileFullText, ast.pos) || []) return (ts.getLeadingCommentRanges(fileFullText, ast.pos) || [])
.map((range) => fileFullText.substring(range.pos, range.end)) .map((range) => fileFullText.substring(range.pos, range.end))
@ -195,7 +197,7 @@ async function addSingleMethod(state, fileName) {
isPrivate, isPrivate,
func: stmt, func: stmt,
comment: getLeadingComments(stmt), comment: getLeadingComments(stmt),
aliases aliases,
}) })
const module = `./${relPath.replace(/\.ts$/, '')}` const module = `./${relPath.replace(/\.ts$/, '')}`
@ -255,6 +257,7 @@ async function main() {
list: [], list: [],
}, },
copy: [], copy: [],
files: {},
} }
for await (const file of getFiles(path.join(__dirname, '../src/methods'))) { for await (const file of getFiles(path.join(__dirname, '../src/methods'))) {
@ -296,7 +299,8 @@ async function main() {
const printer = ts.createPrinter() const printer = ts.createPrinter()
state.methods.list.forEach(({ name: origName, isPrivate, func, comment, aliases }) => { state.methods.list.forEach(
({ name: origName, isPrivate, func, comment, aliases }) => {
// create method that calls that function and passes `this` // create method that calls that function and passes `this`
// first let's determine the signature // first let's determine the signature
const returnType = func.type ? ': ' + func.type.getText() : '' const returnType = func.type ? ': ' + func.type.getText() : ''
@ -317,43 +321,70 @@ async function main() {
// no explicit type. // no explicit type.
// infer from initializer // infer from initializer
if ( if (
it.initializer.kind === ts.SyntaxKind.TrueKeyword || it.initializer.kind ===
it.initializer.kind === ts.SyntaxKind.FalseKeyword ts.SyntaxKind.TrueKeyword ||
it.initializer.kind ===
ts.SyntaxKind.FalseKeyword
) { ) {
it.type = { kind: ts.SyntaxKind.BooleanKeyword } it.type = { kind: ts.SyntaxKind.BooleanKeyword }
} else if ( } else if (
it.initializer.kind === ts.SyntaxKind.StringLiteral it.initializer.kind ===
ts.SyntaxKind.StringLiteral
) { ) {
it.type = { kind: ts.SyntaxKind.StringKeyword } it.type = { kind: ts.SyntaxKind.StringKeyword }
} else if ( } else if (
it.initializer.kind === it.initializer.kind ===
ts.SyntaxKind.NumericLiteral || ts.SyntaxKind.NumericLiteral ||
(it.initializer.kind === ts.SyntaxKind.Identifier && (it.initializer.kind ===
ts.SyntaxKind.Identifier &&
it.initializer.escapedText === 'NaN') it.initializer.escapedText === 'NaN')
) { ) {
it.type = { kind: ts.SyntaxKind.NumberKeyword } it.type = { kind: ts.SyntaxKind.NumberKeyword }
} else { } else {
throwError( throwError(
it, it,
state.methods.used[name], state.methods.used[origName],
'Cannot infer parameter type' 'Cannot infer parameter type'
) )
} }
} }
it.initializer = undefined it.initializer = undefined
const deleteParents = (obj) => {
if (Array.isArray(obj)) return obj.forEach((it) => deleteParents(it))
if (obj.parent) delete obj.parent
for (const k of Object.keys(obj)) {
if (obj[k] && typeof obj[k] === 'object') {
deleteParents(obj[k])
}
}
}
deleteParents(it)
it.questionToken = { kind: ts.SyntaxKind.QuestionToken } it.questionToken = { kind: ts.SyntaxKind.QuestionToken }
return printer.printNode(ts.EmitHint.Unspecified, it) return printer.printNode(
ts.EmitHint.Unspecified,
it,
// state.files[state.methods.used[origName]]
)
} }
return it.getFullText() return it.getFullText()
}).join(', ') })
.join(', ')
// remove @internal mark and set default values for parameters // remove @internal mark and set default values for parameters
comment = comment comment = comment
.replace(/^\s*\/\/+\s*@alias.*$/m, '') .replace(/^\s*\/\/+\s*@alias.*$/m, '')
.replace(/(\n^|\/\*)\s*\*\s*@internal.*/m, '') .replace(/(\n^|\/\*)\s*\*\s*@internal.*/m, '')
.replace(/((?:\n^|\/\*)\s*\*\s*@param )([^\s]+?)($|\s+)/gm, (_, pref, arg, post) => { .replace(
const param = rawParams.find(it => it.name.escapedText === arg) /((?:\n^|\/\*)\s*\*\s*@param )([^\s]+?)($|\s+)/gm,
(_, pref, arg, post) => {
const param = rawParams.find(
(it) => it.name.escapedText === arg
)
if (!param) return _ if (!param) return _
if (!param._savedDefault) return _ if (!param._savedDefault) return _
if (post) { if (post) {
@ -361,7 +392,8 @@ async function main() {
} else { } else {
return `${pref}${arg}\n* (default: \`${param._savedDefault.trim()}\`)` return `${pref}${arg}\n* (default: \`${param._savedDefault.trim()}\`)`
} }
}) }
)
for (const name of [origName, ...aliases]) { for (const name of [origName, ...aliases]) {
if (!comment.match(/\/\*\*?\s*\*\//)) if (!comment.match(/\/\*\*?\s*\*\//))
@ -380,7 +412,8 @@ return ${origName}.apply(this, arguments)
}` }`
) )
} }
}) }
)
output.untab() output.untab()
output.write('}') output.write('}')