Skip to content

Commit f52dfc7

Browse files
type fix
1 parent a6e4092 commit f52dfc7

File tree

2 files changed

+164
-87
lines changed

2 files changed

+164
-87
lines changed

packages/web/src/features/search/ir.ts

Lines changed: 162 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,99 @@
11
import { Q as QueryIR } from '@/proto/zoekt/webserver/v1/Q';
2+
import { RawConfig } from '@/proto/zoekt/webserver/v1/RawConfig';
3+
import { Regexp } from '@/proto/zoekt/webserver/v1/Regexp';
4+
import { Symbol } from '@/proto/zoekt/webserver/v1/Symbol';
5+
import { Language } from '@/proto/zoekt/webserver/v1/Language';
6+
import { Repo } from '@/proto/zoekt/webserver/v1/Repo';
7+
import { RepoRegexp } from '@/proto/zoekt/webserver/v1/RepoRegexp';
8+
import { BranchesRepos } from '@/proto/zoekt/webserver/v1/BranchesRepos';
9+
import { RepoIds } from '@/proto/zoekt/webserver/v1/RepoIds';
10+
import { RepoSet } from '@/proto/zoekt/webserver/v1/RepoSet';
11+
import { FileNameSet } from '@/proto/zoekt/webserver/v1/FileNameSet';
12+
import { Type } from '@/proto/zoekt/webserver/v1/Type';
13+
import { Substring } from '@/proto/zoekt/webserver/v1/Substring';
14+
import { And } from '@/proto/zoekt/webserver/v1/And';
15+
import { Or } from '@/proto/zoekt/webserver/v1/Or';
16+
import { Not } from '@/proto/zoekt/webserver/v1/Not';
17+
import { Branch } from '@/proto/zoekt/webserver/v1/Branch';
18+
import { Boost } from '@/proto/zoekt/webserver/v1/Boost';
219

320
export type {
421
QueryIR,
522
}
623

24+
// Type guards for each query node type
25+
export function isRawConfigQuery(query: QueryIR): query is QueryIR & { raw_config: RawConfig } {
26+
return query.raw_config != null;
27+
}
28+
29+
export function isRegexpQuery(query: QueryIR): query is QueryIR & { regexp: Regexp } {
30+
return query.regexp != null;
31+
}
32+
33+
export function isSymbolQuery(query: QueryIR): query is QueryIR & { symbol: Symbol } {
34+
return query.symbol != null;
35+
}
36+
37+
export function isLanguageQuery(query: QueryIR): query is QueryIR & { language: Language } {
38+
return query.language != null;
39+
}
40+
41+
export function isConstQuery(query: QueryIR): query is QueryIR & { const: boolean } {
42+
return query.const != null;
43+
}
44+
45+
export function isRepoQuery(query: QueryIR): query is QueryIR & { repo: Repo } {
46+
return query.repo != null;
47+
}
48+
49+
export function isRepoRegexpQuery(query: QueryIR): query is QueryIR & { repo_regexp: RepoRegexp } {
50+
return query.repo_regexp != null;
51+
}
52+
53+
export function isBranchesReposQuery(query: QueryIR): query is QueryIR & { branches_repos: BranchesRepos } {
54+
return query.branches_repos != null;
55+
}
56+
57+
export function isRepoIdsQuery(query: QueryIR): query is QueryIR & { repo_ids: RepoIds } {
58+
return query.repo_ids != null;
59+
}
60+
61+
export function isRepoSetQuery(query: QueryIR): query is QueryIR & { repo_set: RepoSet } {
62+
return query.repo_set != null;
63+
}
64+
65+
export function isFileNameSetQuery(query: QueryIR): query is QueryIR & { file_name_set: FileNameSet } {
66+
return query.file_name_set != null;
67+
}
68+
69+
export function isTypeQuery(query: QueryIR): query is QueryIR & { type: Type } {
70+
return query.type != null;
71+
}
72+
73+
export function isSubstringQuery(query: QueryIR): query is QueryIR & { substring: Substring } {
74+
return query.substring != null;
75+
}
76+
77+
export function isAndQuery(query: QueryIR): query is QueryIR & { and: And } {
78+
return query.and != null;
79+
}
80+
81+
export function isOrQuery(query: QueryIR): query is QueryIR & { or: Or } {
82+
return query.or != null;
83+
}
84+
85+
export function isNotQuery(query: QueryIR): query is QueryIR & { not: Not } {
86+
return query.not != null;
87+
}
88+
89+
export function isBranchQuery(query: QueryIR): query is QueryIR & { branch: Branch } {
90+
return query.branch != null;
91+
}
92+
93+
export function isBoostQuery(query: QueryIR): query is QueryIR & { boost: Boost } {
94+
return query.boost != null;
95+
}
96+
797
/**
898
* Visitor pattern for traversing a QueryIR tree.
999
* Return false from any method to stop traversal early.
@@ -39,97 +129,84 @@ export function traverseQueryIR(
39129
query: QueryIR,
40130
visitor: QueryVisitor
41131
): boolean {
42-
if (!query.query) {
43-
return true;
44-
}
45-
46-
// Call the appropriate visitor method
47132
let shouldContinue: boolean | void = true;
48133

49-
switch (query.query) {
50-
case 'raw_config':
51-
shouldContinue = visitor.onRawConfig?.(query);
52-
break;
53-
case 'regexp':
54-
shouldContinue = visitor.onRegexp?.(query);
55-
if (shouldContinue !== false && query.regexp) {
56-
// Symbol expressions contain nested queries
57-
if (query.regexp) {
58-
shouldContinue = true;
59-
}
60-
}
61-
break;
62-
case 'symbol':
63-
shouldContinue = visitor.onSymbol?.(query);
64-
if (shouldContinue !== false && query.symbol?.expr) {
65-
shouldContinue = traverseQueryIR(query.symbol.expr, visitor);
66-
}
67-
break;
68-
case 'language':
69-
shouldContinue = visitor.onLanguage?.(query);
70-
break;
71-
case 'const':
72-
shouldContinue = visitor.onConst?.(query);
73-
break;
74-
case 'repo':
75-
shouldContinue = visitor.onRepo?.(query);
76-
break;
77-
case 'repo_regexp':
78-
shouldContinue = visitor.onRepoRegexp?.(query);
79-
break;
80-
case 'branches_repos':
81-
shouldContinue = visitor.onBranchesRepos?.(query);
82-
break;
83-
case 'repo_ids':
84-
shouldContinue = visitor.onRepoIds?.(query);
85-
break;
86-
case 'repo_set':
87-
shouldContinue = visitor.onRepoSet?.(query);
88-
break;
89-
case 'file_name_set':
90-
shouldContinue = visitor.onFileNameSet?.(query);
91-
break;
92-
case 'type':
93-
shouldContinue = visitor.onType?.(query);
94-
break;
95-
case 'substring':
96-
shouldContinue = visitor.onSubstring?.(query);
97-
break;
98-
case 'and':
99-
shouldContinue = visitor.onAnd?.(query);
100-
if (shouldContinue !== false && query.and?.children) {
101-
for (const child of query.and.children) {
102-
if (!traverseQueryIR(child, visitor)) {
103-
return false;
104-
}
134+
if (isRawConfigQuery(query)) {
135+
shouldContinue = visitor.onRawConfig?.(query);
136+
137+
} else if (isRegexpQuery(query)) {
138+
shouldContinue = visitor.onRegexp?.(query);
139+
140+
} else if (isSymbolQuery(query)) {
141+
shouldContinue = visitor.onSymbol?.(query);
142+
if (shouldContinue !== false && query.symbol.expr) {
143+
shouldContinue = traverseQueryIR(query.symbol.expr, visitor);
144+
}
145+
146+
} else if (isLanguageQuery(query)) {
147+
shouldContinue = visitor.onLanguage?.(query);
148+
149+
} else if (isConstQuery(query)) {
150+
shouldContinue = visitor.onConst?.(query);
151+
152+
} else if (isRepoQuery(query)) {
153+
shouldContinue = visitor.onRepo?.(query);
154+
155+
} else if (isRepoRegexpQuery(query)) {
156+
shouldContinue = visitor.onRepoRegexp?.(query);
157+
158+
} else if (isBranchesReposQuery(query)) {
159+
shouldContinue = visitor.onBranchesRepos?.(query);
160+
161+
} else if (isRepoIdsQuery(query)) {
162+
shouldContinue = visitor.onRepoIds?.(query);
163+
164+
} else if (isRepoSetQuery(query)) {
165+
shouldContinue = visitor.onRepoSet?.(query);
166+
167+
} else if (isFileNameSetQuery(query)) {
168+
shouldContinue = visitor.onFileNameSet?.(query);
169+
170+
} else if (isTypeQuery(query)) {
171+
shouldContinue = visitor.onType?.(query);
172+
173+
} else if (isSubstringQuery(query)) {
174+
shouldContinue = visitor.onSubstring?.(query);
175+
176+
} else if (isAndQuery(query)) {
177+
shouldContinue = visitor.onAnd?.(query);
178+
if (shouldContinue !== false && query.and.children) {
179+
for (const child of query.and.children) {
180+
if (!traverseQueryIR(child, visitor)) {
181+
return false;
105182
}
106183
}
107-
break;
108-
case 'or':
109-
shouldContinue = visitor.onOr?.(query);
110-
if (shouldContinue !== false && query.or?.children) {
111-
for (const child of query.or.children) {
112-
if (!traverseQueryIR(child, visitor)) {
113-
return false;
114-
}
184+
}
185+
186+
} else if (isOrQuery(query)) {
187+
shouldContinue = visitor.onOr?.(query);
188+
if (shouldContinue !== false && query.or.children) {
189+
for (const child of query.or.children) {
190+
if (!traverseQueryIR(child, visitor)) {
191+
return false;
115192
}
116193
}
117-
break;
118-
case 'not':
119-
shouldContinue = visitor.onNot?.(query);
120-
if (shouldContinue !== false && query.not?.child) {
121-
shouldContinue = traverseQueryIR(query.not.child, visitor);
122-
}
123-
break;
124-
case 'branch':
125-
shouldContinue = visitor.onBranch?.(query);
126-
break;
127-
case 'boost':
128-
shouldContinue = visitor.onBoost?.(query);
129-
if (shouldContinue !== false && query.boost?.child) {
130-
shouldContinue = traverseQueryIR(query.boost.child, visitor);
131-
}
132-
break;
194+
}
195+
196+
} else if (isNotQuery(query)) {
197+
shouldContinue = visitor.onNot?.(query);
198+
if (shouldContinue !== false && query.not.child) {
199+
shouldContinue = traverseQueryIR(query.not.child, visitor);
200+
}
201+
202+
} else if (isBranchQuery(query)) {
203+
shouldContinue = visitor.onBranch?.(query);
204+
205+
} else if (isBoostQuery(query)) {
206+
shouldContinue = visitor.onBoost?.(query);
207+
if (shouldContinue !== false && query.boost.child) {
208+
shouldContinue = traverseQueryIR(query.boost.child, visitor);
209+
}
133210
}
134211

135212
return shouldContinue !== false;

packages/web/src/features/search/zoektSearcher.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import * as Sentry from '@sentry/nextjs';
1515
import { PrismaClient, Repo } from "@sourcebot/db";
1616
import { createLogger, env } from "@sourcebot/shared";
1717
import path from 'path';
18-
import { QueryIR, someInQueryIR } from './ir';
18+
import { isBranchQuery, QueryIR, someInQueryIR } from './ir';
1919
import { RepositoryInfo, SearchResponse, SearchResultFile, SearchStats, SourceRange, StreamedSearchErrorResponse, StreamedSearchResponse } from "./types";
2020

2121
const logger = createLogger("zoekt-searcher");
@@ -38,7 +38,7 @@ export const createZoektSearchRequest = async ({
3838
repoSearchScope?: string[];
3939
}) => {
4040
// Find if there are any `rev:` filters in the query.
41-
const containsRevExpression = someInQueryIR(query, (q) => q.query === 'branch');
41+
const containsRevExpression = someInQueryIR(query, (q) => isBranchQuery(q));
4242

4343
const zoektSearchRequest: ZoektGrpcSearchRequest = {
4444
query: {

0 commit comments

Comments
 (0)