Skip to content

Commit

Permalink
fix: use Expr for any A_Expr/FuncCall-accepting field
Browse files Browse the repository at this point in the history
Since the Expr type consists of a ton of variants, there won‘t exist enough test cases for inference to get us all the way there. If a field is known to possibly be (or include) an A_Expr or FuncCall node, we can be 95% sure it supports any Expr node.

Closes #13
  • Loading branch information
aleclarson committed Nov 6, 2024
1 parent 2c778ee commit af71884
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 253 deletions.
50 changes: 25 additions & 25 deletions scripts/generateTypes.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import fs from 'node:fs'
import type { NodeFieldMetadataByTag } from './inferFieldMetadata'
import { nullableFields, typeMappings } from './typeMappings'
import { expressionFields, nullableFields, typeMappings } from './typeMappings'

/** A record of node tag -> field name -> nullability */
const nodeFieldsByTag: NodeFieldMetadataByTag = JSON.parse(
Expand Down Expand Up @@ -209,8 +209,15 @@ async function main() {
const renderTagType = (tag: string) =>
tag === '{}' ? tag : `{ ${tag}: ${tag} }`

const renderTagTypes = (tags: string[]) =>
tags.sort().map(renderTagType).join(' | ')
const renderTagTypes = (tags: string[], fieldPath: string) => {
if (expressionFields.has(fieldPath)) {
if (tags.includes('{}')) {
return 'Expr | {}'
}
return 'Expr'
}
return tags.sort().map(renderTagType).join(' | ')
}

delete structsByModule['../backend/parser/gram']
delete structsByModule['../backend/parser/gramparse']
Expand Down Expand Up @@ -335,27 +342,24 @@ async function main() {
if (fieldType === 'any' || fieldType === 'Node') {
const inferredTags = fieldMetadata?.[fieldName]?.[1]
if (inferredTags) {
debugTags &&
console.log(
'Inferred tags for %s.%s:',
typeName,
fieldName,
inferredTags,
)
fieldType = '(' + renderTagTypes(inferredTags) + ')'
if (debugTags) {
console.log('Inferred tags for %s:', fieldPath, inferredTags)
}
fieldType = renderTagTypes(inferredTags, fieldPath)
}
} else if (fieldType === 'any[]') {
const inferredListTags = fieldMetadata?.[fieldName]?.[2]
if (inferredListTags) {
debugTags &&
if (debugTags) {
console.log(
'Inferred list tags for %s.%s:',
typeName,
fieldName,
'Inferred list tags for %s:',
fieldPath,
inferredListTags,
)
}

fieldType = 'List<' + renderTagTypes(inferredListTags) + '>'
fieldType =
'List<' + renderTagTypes(inferredListTags, fieldPath) + '>'

if (field.c_type === 'List*') {
fieldType += '[]'
Expand All @@ -364,15 +368,11 @@ async function main() {
if (fieldType === 'any[]' && field.c_type === 'List*') {
const inferredTags = fieldMetadata?.[fieldName]?.[1]
if (inferredTags) {
debugTags &&
console.log(
'Inferred tags for %s.%s:',
typeName,
fieldName,
inferredTags,
)

fieldType = '(' + renderTagTypes(inferredTags) + ')[]'
if (debugTags) {
console.log('Inferred tags for %s:', fieldPath, inferredTags)
}
fieldType =
'(' + renderTagTypes(inferredTags, fieldPath) + ')[]'
}
}
}
Expand Down
35 changes: 35 additions & 0 deletions scripts/typeMappings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,41 @@ export const typeMappings: Record<string, string> = {
'SelectStmt.valuesLists': 'List<Expr>[]',
}

/**
* If a field accepts an arbitrary expression, add it here.
*/
export const expressionFields = new Set([
'A_ArrayExpr.elements',
'A_Indirection.arg',
'AlterTableCmd.def',
'BoolExpr.args',
'CreatePolicyStmt.qual',
'DeleteStmt.whereClause',
'FuncCall.args',
'GroupingSet.content',
'IndexStmt.whereClause',
'JoinExpr.quals',
'MergeWhenClause.condition',
'MergeWhenClause.values',
'MergeStmt.joinCondition',
'MinMaxExpr.args',
'RangeFunction.functions',
'RangeTableSample.args',
'ResTarget.val',
'ReturnStmt.returnval',
'RowExpr.args',
'RuleStmt.whereClause',
'SelectStmt.groupClause',
'SelectStmt.havingClause',
'SelectStmt.whereClause',
'SelectStmt.limitCount',
'SelectStmt.limitOffset',
'SortBy.node',
'TypeCast.arg',
'UpdateStmt.whereClause',
'XmlExpr.args',
])

/**
* If a field's nullability is incorrectly inferred, add it here.
*/
Expand Down
Loading

0 comments on commit af71884

Please sign in to comment.