Skip to content

Commit c893453

Browse files
committed
revert api change
1 parent d20447a commit c893453

8 files changed

Lines changed: 104 additions & 27 deletions

File tree

docs/src/content/docs/reference/scripts/ast-grep.mdx

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,13 @@ The first argument is the language, the second argument is the file globs, and t
2424

2525
```ts
2626
// matches is an array of AST (immutable) nodes
27-
const { matches } = await sg.search("src/*.ts", "console.log($META)")
27+
const { matches } = await sg.search("ts", "src/*.ts", "console.log($META)")
2828
```
2929

3030
- find all TypeScript functions without comments. This example uses the [rule syntax](https://ast-grep.github.io/reference/rule.html).
3131

3232
```ts
33-
const { matches } = await sg.search("src/fib.ts", {
33+
const { matches } = await sg.search("ts", "src/fib.ts", {
3434
rule: {
3535
kind: "function_declaration",
3636
not: {
@@ -74,7 +74,7 @@ that do not intersect with the `to` files of the diff.
7474

7575
```ts "{ diff }" wrap
7676
const diff = await git.diff({ base: "main" })
77-
const { matches } = await sg.search("src/fib.ts", {...}, { diff })
77+
const { matches } = await sg.search("ts", "src/fib.ts", {...}, { diff })
7878
```
7979

8080
## Changesets
@@ -155,19 +155,28 @@ If your language is not supported, go to [ast-grep langs](https://github.com/ast
155155
156156
:::
157157
158+
### Filename extension mapping
159+
160+
The following file extensions are mapped to the corresponding languages:
161+
162+
- HTML: `html`, `htm`
163+
- JavaScript: `cjs`, `mjs`, `js`
164+
- TypeScript: `cts`, `mts`, `ts`
165+
- TSX: `tsx`
166+
- CSS: `css`
167+
- c: `c`
168+
- cpp: `cpp`, `cxx`, `h`, `hpp`, `hxx`
169+
- python: `py`
170+
- C#: `cs`
171+
- sql: `sql`
172+
158173
### Overriding the language selection
159174
160175
GenAIScript has default mappings from well-known file extensions to languages.
161176
However, you can override this by passing the `lang` option to the `search` method.
162177
163178
```ts "{ lang: "ts" }"
164-
const { matches } = await sg.search("src/fib.ts", {...}, { lang: "ts" })
165-
```
166-
167-
or if you want to search multiple languages, by providing a `extension` to `lang` mapping.
168-
169-
```ts 'lang: { "ttts": "ts", "jjjs":"js" }'
170-
const { matches } = await sg.search("src/*", {...}, { lang: { "ttts": "ts", "jjjs":"js" } })
179+
const { matches } = await sg.search("ts", "src/fib.ts", {...}, { lang: "ts" })
171180
```
172181
173182
## Learning ast-grep

packages/core/src/astgrep.test.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { beforeEach, describe, test } from "node:test"
22
import assert from "node:assert/strict"
33
import { astGrepFindFiles, astGrepParse } from "./astgrep"
44
import { TestHost } from "./testhost"
5+
import { dedent } from "./indent"
56

67
describe("astgrep", () => {
78
beforeEach(() => {
@@ -11,6 +12,7 @@ describe("astgrep", () => {
1112
test("finds matches in files", async () => {
1213
console.log("Hello, world!")
1314
const result = await astGrepFindFiles(
15+
"ts",
1416
"src/astgrep.test.ts",
1517
"console.log($GREETING)"
1618
)
@@ -34,4 +36,44 @@ describe("astgrep", () => {
3436
const result = await astGrepParse(file, { lang: "js" })
3537
assert.equal(result, undefined)
3638
})
39+
40+
test("parse C++ file", async () => {
41+
const file: WorkspaceFile = {
42+
filename: "test.cpp",
43+
content: dedent`
44+
#include <iostream>
45+
46+
int main() {
47+
std::cout << 'Hello, world!' << std::endl;
48+
return 0;
49+
}
50+
`,
51+
}
52+
const result = await astGrepParse(file)
53+
assert(result)
54+
})
55+
test("parse TypeScript file", async () => {
56+
const file: WorkspaceFile = {
57+
filename: "test.ts",
58+
content: "const x: number = 1;",
59+
}
60+
const result = await astGrepParse(file)
61+
assert(result)
62+
})
63+
test("parse python file", async () => {
64+
const file: WorkspaceFile = {
65+
filename: "test.py",
66+
content: "x = 1",
67+
}
68+
const result = await astGrepParse(file)
69+
assert(result)
70+
})
71+
test("parse C file", async () => {
72+
const file: WorkspaceFile = {
73+
filename: "test.c",
74+
content: "#include <stdio.h>",
75+
}
76+
const result = await astGrepParse(file)
77+
assert(result)
78+
})
3779
})

packages/core/src/astgrep.ts

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,12 @@ export function astGrepCreateChangeSet(): SgChangeSet {
8181
* @throws An error if `glob` or `matcher` is not provided.
8282
*/
8383
export async function astGrepFindFiles(
84+
lang: SgLang,
8485
glob: ElementOrArray<string>,
8586
matcher: string | SgMatcher,
8687
options?: SgSearchOptions & CancellationOptions
8788
): ReturnType<Sg["search"]> {
88-
const { cancellationToken, diff, lang } = options || {}
89+
const { cancellationToken, diff } = options || {}
8990
if (!glob) {
9091
throw new Error("glob is required")
9192
}
@@ -248,7 +249,6 @@ export async function astGrepParse(
248249
dbg(`parsing file: ${filename}`)
249250
const { parseAsync } = await import("@ast-grep/napi")
250251
const lang = await resolveLang(options?.lang, filename)
251-
dbg(`resolving language for file: ${filename}`)
252252
if (!lang) {
253253
return undefined
254254
}
@@ -292,6 +292,8 @@ async function resolveLang(
292292
sql: "sql",
293293
}
294294

295+
const forbidden = ["bin", "exe", "dll"]
296+
295297
// user provided a string
296298
if (typeof lang === "string") {
297299
lang = norm(lang)
@@ -301,26 +303,30 @@ async function resolveLang(
301303
else return await loadDynamicLanguage(lang)
302304
}
303305

306+
if (!filename) {
307+
dbgLang(`filename not provided`)
308+
throw new Error("filename is required to resolve language")
309+
}
310+
304311
if (filename) {
305-
const ext = norm(path.extname(filename))
312+
const ext = norm(extname(filename))
306313
dbgLang(`resolving language for ${ext}`)
307314

308-
if (typeof lang === "object") {
309-
const l = lang[ext]
310-
if (l) return await loadDynamicLanguage(l)
311-
}
312-
315+
// known builtins
313316
const builtin = builtins[ext]
314317
if (builtin) return builtin
315318

316319
// known dynamics
317320
const dynamic = dynamics[ext]
318321
if (dynamic) return await loadDynamicLanguage(dynamic)
319322

323+
if (forbidden.includes(ext)) return undefined
324+
320325
// try our luck
321326
return await loadDynamicLanguage(ext)
322327
}
323328

329+
dbgLang(`language not resolved`, { lang, filename })
324330
throw new Error("language not resolved")
325331
}
326332

packages/core/src/promptcontext.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -343,8 +343,8 @@ export async function createPromptContext(
343343
astGrep: async () =>
344344
Object.freeze<Sg>({
345345
changeset: astGrepCreateChangeSet,
346-
search: (glob, matcher, sgOptions) =>
347-
astGrepFindFiles(glob, matcher, {
346+
search: (lang, glob, matcher, sgOptions) =>
347+
astGrepFindFiles(lang, glob, matcher, {
348348
...(sgOptions || {}),
349349
cancellationToken,
350350
}),

packages/core/src/types/prompt_template.d.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4340,11 +4340,6 @@ interface SgChangeSet {
43404340
}
43414341

43424342
interface SgSearchOptions extends Omit<FindFilesOptions, "readText"> {
4343-
/**
4344-
* The language, or a mapping of languages, of the source code
4345-
*/
4346-
lang?: SgLang | Record<string, SgLang>
4347-
43484343
/**
43494344
* Restrict matches that are part of the diff.
43504345
*/
@@ -4358,6 +4353,7 @@ interface Sg {
43584353
changeset(): SgChangeSet
43594354
parse(file: WorkspaceFile, options: { lang?: SgLang }): Promise<SgRoot>
43604355
search(
4356+
lang: SgLang,
43614357
glob: ElementOrArray<string>,
43624358
matcher: string | SgMatcher,
43634359
options?: SgSearchOptions

packages/sample/genaisrc/astgrep.genai.mjs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@ script({
55
tests: {},
66
})
77
const sg = await host.astGrep()
8-
const { matches } = await sg.search("src/*.ts", "console.log($META)")
8+
const { matches } = await sg.search("ts", "src/*.ts", "console.log($META)")
99
if (matches.length < 2) throw new Error("No matches src/*.ts found")
1010
for (const match of matches) {
1111
const t = match.text()
1212
console.log(match.getRoot().filename() + " " + match.text())
1313
if (!t.includes("console.log")) throw new Error("console.log found")
1414
}
1515

16-
const { matches: matches2 } = await sg.search("src/fib.ts", {
16+
const { matches: matches2 } = await sg.search("ts", "src/fib.ts", {
1717
rule: {
1818
kind: "function_declaration",
1919
not: {

packages/sample/package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919
"@agentic/core": "v7.5.3",
2020
"@agentic/weather": "v7.5.3",
2121
"@ast-grep/lang-c": "^0.0.1",
22+
"@ast-grep/lang-cpp": "^0.0.1",
23+
"@ast-grep/lang-csharp": "^0.0.1",
24+
"@ast-grep/lang-python": "^0.0.1",
2225
"@azure/identity": "^4.8.0",
2326
"@azure/storage-blob": "^12.27.0",
2427
"@huggingface/transformers": "^3.4.0",

yarn.lock

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,27 @@
8282
dependencies:
8383
"@ast-grep/setup-lang" "0.0.3"
8484

85+
"@ast-grep/lang-cpp@^0.0.1":
86+
version "0.0.1"
87+
resolved "https://registry.yarnpkg.com/@ast-grep/lang-cpp/-/lang-cpp-0.0.1.tgz#8964ad2d635f11bc6183a0660b6e581db35a2ef2"
88+
integrity sha512-mtjdHPKtyIuPza6Shh7ZDfYHGUhjJMhwy3mD1aDZyimZJe3H/ODb8FJg/n5wquqjDa3K+OyHDHHS+dgcMqCj0g==
89+
dependencies:
90+
"@ast-grep/setup-lang" "0.0.3"
91+
92+
"@ast-grep/lang-csharp@^0.0.1":
93+
version "0.0.1"
94+
resolved "https://registry.yarnpkg.com/@ast-grep/lang-csharp/-/lang-csharp-0.0.1.tgz#7f7ebc493c52fb59fb99b9caeed4f0b8150290df"
95+
integrity sha512-hqRnrHkBYTMFo7cV6L6QqWGvdwahZLpo2MI33cMa2i6UFO+6xTUPB0wJx5xELvMz457tKjO8ljKwSh3a/kiryA==
96+
dependencies:
97+
"@ast-grep/setup-lang" "0.0.3"
98+
99+
"@ast-grep/lang-python@^0.0.1":
100+
version "0.0.1"
101+
resolved "https://registry.yarnpkg.com/@ast-grep/lang-python/-/lang-python-0.0.1.tgz#e00ece849f67850ad73097dc3048678ebbd1bfd8"
102+
integrity sha512-RUtQKM5msT2Jdwu6q9rW5qVh2S5X3iBAGj6Zoct1CAHEGHIpkOFa+jLvJpVeLxVOqq0U9jRX+7G1keuqgn7daQ==
103+
dependencies:
104+
"@ast-grep/setup-lang" "0.0.3"
105+
85106
"@ast-grep/napi-darwin-arm64@0.36.2":
86107
version "0.36.2"
87108
resolved "https://registry.yarnpkg.com/@ast-grep/napi-darwin-arm64/-/napi-darwin-arm64-0.36.2.tgz#4d0344c05852824f047785b19f6a49fd005b7c63"

0 commit comments

Comments
 (0)