(node: SyntaxNode)
| 149 | onExpandSearchContext: (contextName: string) => Promise<string[]>; |
| 150 | }): Promise<QueryIR> => { |
| 151 | const transformNode = async (node: SyntaxNode): Promise<QueryIR> => { |
| 152 | switch (node.type.id) { |
| 153 | case Program: { |
| 154 | // Program wraps the actual query - transform its child |
| 155 | const child = node.firstChild; |
| 156 | if (!child) { |
| 157 | // Empty query - match nothing |
| 158 | return { const: false, query: "const" }; |
| 159 | } |
| 160 | return transformNode(child); |
| 161 | } |
| 162 | case AndExpr: |
| 163 | return { |
| 164 | and: { |
| 165 | children: await Promise.all(getChildren(node).map(c => transformNode(c))) |
| 166 | }, |
| 167 | query: "and" |
| 168 | } |
| 169 | |
| 170 | case OrExpr: |
| 171 | return { |
| 172 | or: { |
| 173 | children: await Promise.all(getChildren(node).map(c => transformNode(c))) |
| 174 | }, |
| 175 | query: "or" |
| 176 | }; |
| 177 | |
| 178 | case NegateExpr: { |
| 179 | // Find the child after the negate token |
| 180 | const negateChild = node.getChild("PrefixExpr") || node.getChild("ParenExpr"); |
| 181 | if (!negateChild) { |
| 182 | throw new Error("NegateExpr missing child"); |
| 183 | } |
| 184 | return { |
| 185 | not: { |
| 186 | child: await transformNode(negateChild) |
| 187 | }, |
| 188 | query: "not" |
| 189 | }; |
| 190 | } |
| 191 | case ParenExpr: { |
| 192 | // Parentheses just group - transform the inner query |
| 193 | const innerQuery = node.getChild("query") || node.firstChild; |
| 194 | if (!innerQuery) { |
| 195 | return { const: false, query: "const" }; |
| 196 | } |
| 197 | return transformNode(innerQuery); |
| 198 | } |
| 199 | case PrefixExpr: |
| 200 | // PrefixExpr contains specific prefix types |
| 201 | return transformPrefixExpr(node); |
| 202 | |
| 203 | case QuotedTerm: |
| 204 | case Term: { |
| 205 | const fullText = input.substring(node.from, node.to); |
| 206 | // If the term is quoted, then we remove the quotes as they are |
| 207 | // not interpreted. |
| 208 | const termText = node.type.id === QuotedTerm ? fullText.replace(/^"|"$/g, '') : fullText; |
no test coverage detected