Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 32 additions & 12 deletions src/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,9 @@ export function nodeToPlainText(node: SgNode) {
function toText(one: SgNode) {
const children = one.children()
if (!children.length) {
out.push(one.text())
if (!one.is('comment')) {
out.push(one.text())
}
} else {
children.forEach((child) => toText(child))
}
Expand Down Expand Up @@ -205,19 +207,37 @@ export function nodeToPlainText(node: SgNode) {
* validatorArgs.forEach(arg => console.log('Validator argument:', arg.text()))
*/
export function inspectMethodArguments(node: SgNode, methodCalls: string[]): SgNode[] {
const matchingExpressions = node.findAll({
rule: {
any: methodCalls.map((methodCall) => {
return {
pattern: {
context: `${methodCall}($$$ARGUMENTS)`,
selector: 'call_expression',
},
}
}),
},
const exactMethodCalls = new Set<string>()
const receiverMethodCalls: string[] = []

methodCalls.forEach((methodCall) => {
const separator = methodCall.indexOf('.')
if (methodCall.startsWith('$') && separator !== -1) {
receiverMethodCalls.push(methodCall.slice(separator + 1))
} else {
exactMethodCalls.add(methodCall)
}
})

const matchingExpressions = node
.findAll({ rule: { kind: 'call_expression' } })
.filter((expression) => {
const functionNode = expression.field('function')
if (!functionNode) {
return false
}
const functionName = nodeToPlainText(functionNode)

return (
exactMethodCalls.has(functionName) ||
receiverMethodCalls.some((methodCall) => {
return (
functionName.endsWith(`.${methodCall}`) && !functionName.endsWith(`?.${methodCall}`)
)
})
)
})

return matchingExpressions.flatMap((matchingExpression) => {
return matchingExpression.findAll({ rule: { kind: 'arguments' } })
})
Expand Down
34 changes: 34 additions & 0 deletions tests/helpers/inspect_method_arguments.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,36 @@ test.group('Inspect method arguments', () => {
}`,
output: ['createCarValidator', 'createVehicleValidator'],
},
{
input: `class UsersController {
async store(ctx: HttpContext) {
await ctx.request.tryValidateUsing(admin.createUserValidator)
await this.ctx.request.validateUsing(createUserValidator)
}
}`,
output: ['admin.createUserValidator', 'createUserValidator'],
},
{
input: `class UsersController {
async store() {
await request /* request comment */ . validateUsing(
factory(createUserValidator)
)
await vine.tryValidate(user.createUserValidator)
}
}`,
output: ['factory', 'createUserValidator', 'user.createUserValidator'],
},
{
input: `class UsersController {
async store(ctx: HttpContext) {
await request?.validateUsing(optionalValidator)
await ctx?.request.validateUsing(optionalContextValidator)
await validator.validate(request.all())
}
}`,
output: [],
},
])
.run(({ assert }, { input, output }) => {
const root = parse(Lang.TypeScript, input).root()
Expand All @@ -87,7 +117,11 @@ test.group('Inspect method arguments', () => {

const validatorArguments = inspectMethodArguments(storeMethod, [
'request.validateUsing',
'request.tryValidateUsing',
'$CTX.request.validateUsing',
'$CTX.request.tryValidateUsing',
'vine.validate',
'vine.tryValidate',
]).map((node) => {
return nodeToPlainText(
node.find({ rule: { any: [{ kind: 'identifier' }, { kind: 'member_expression' }] } })!
Expand Down
Loading