From bebe36e4bd37872f9578d8d5e6fb860682041eb5 Mon Sep 17 00:00:00 2001
From: Nathan Gendron <nato@coderabbit.ai>
Date: Tue, 1 Apr 2025 13:38:55 -0400
Subject: [PATCH 1/5] =?UTF-8?q?=E2=9C=A8=20php?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 packages/php/README.md      | 24 +++++++++++++++++++
 packages/php/index.d.ts     | 10 ++++++++
 packages/php/index.js       |  9 +++++++
 packages/php/nursery.js     | 12 ++++++++++
 packages/php/package.json   | 47 +++++++++++++++++++++++++++++++++++++
 packages/php/postinstall.js |  4 ++++
 pnpm-lock.yaml              | 31 ++++++++++++++++++++++++
 7 files changed, 137 insertions(+)
 create mode 100644 packages/php/README.md
 create mode 100644 packages/php/index.d.ts
 create mode 100644 packages/php/index.js
 create mode 100644 packages/php/nursery.js
 create mode 100644 packages/php/package.json
 create mode 100644 packages/php/postinstall.js

diff --git a/packages/php/README.md b/packages/php/README.md
new file mode 100644
index 0000000..bd56beb
--- /dev/null
+++ b/packages/php/README.md
@@ -0,0 +1,24 @@
+# ast-grep napi language for php
+
+## Installation
+
+In a pnpm project, run:
+
+```bash
+pnpm install @ast-grep/lang-php
+pnpm install @ast-grep/napi
+# install the tree-sitter-cli if no prebuild is available
+pnpm install @tree-sitter/cli --save-dev
+```
+
+## Usage
+
+```js
+import php from '@ast-grep/lang-php'
+import { registerDynamicLanguage, parse } from '@ast-grep/napi'
+
+registerDynamicLanguage({ php })
+
+const sg = parse('php', `your code`)
+sg.root().kind()
+```
diff --git a/packages/php/index.d.ts b/packages/php/index.d.ts
new file mode 100644
index 0000000..11140a6
--- /dev/null
+++ b/packages/php/index.d.ts
@@ -0,0 +1,10 @@
+type LanguageRegistration = {
+  libraryPath: string
+  extensions: string[]
+  languageSymbol?: string
+  metaVarChar?: string
+  expandoChar?: string
+}
+
+declare const registration: LanguageRegistration
+export default registration
diff --git a/packages/php/index.js b/packages/php/index.js
new file mode 100644
index 0000000..e64d7c0
--- /dev/null
+++ b/packages/php/index.js
@@ -0,0 +1,9 @@
+const path = require('node:path')
+const libPath = path.join(__dirname, 'parser.so')
+
+module.exports = {
+  libraryPath: libPath,
+  extensions: ['php'],
+  languageSymbol: 'tree_sitter_php',
+  expandoChar: '$',
+}
diff --git a/packages/php/nursery.js b/packages/php/nursery.js
new file mode 100644
index 0000000..b1c8ce8
--- /dev/null
+++ b/packages/php/nursery.js
@@ -0,0 +1,12 @@
+const { setup } = require('@ast-grep/nursery')
+const languageRegistration = require('./index')
+
+setup({
+  dirname: __dirname,
+  name: 'php',
+  treeSitterPackage: 'tree-sitter-php',
+  languageRegistration,
+  testRunner: parse => {
+    // add test here
+  },
+})
diff --git a/packages/php/package.json b/packages/php/package.json
new file mode 100644
index 0000000..a7a693e
--- /dev/null
+++ b/packages/php/package.json
@@ -0,0 +1,47 @@
+{
+  "name": "@ast-grep/lang-php",
+  "version": "0.0.1",
+  "description": "",
+  "main": "index.js",
+  "scripts": {
+    "build": "tree-sitter build -o parser.so",
+    "source": "node nursery.js source",
+    "prepublishOnly": "node nursery.js source",
+    "postinstall": "node postinstall.js",
+    "test": "node nursery.js test"
+  },
+  "files": [
+    "index.js",
+    "index.d.ts",
+    "type.d.ts",
+    "postinstall.js",
+    "src",
+    "prebuilds"
+  ],
+  "keywords": ["ast-grep"],
+  "author": "",
+  "license": "ISC",
+  "dependencies": {
+    "@ast-grep/setup-lang": "0.0.3"
+  },
+  "peerDependencies": {
+    "tree-sitter-cli": "0.24.6"
+  },
+  "peerDependenciesMeta": {
+    "tree-sitter-cli": {
+      "optional": true
+    }
+  },
+  "devDependencies": {
+    "@ast-grep/nursery": "0.0.2",
+    "tree-sitter-cli": "0.24.6",
+    "tree-sitter-php": "0.23.12"
+  },
+  "publishConfig": {
+    "access": "public",
+    "registry": "https://registry.npmjs.org/"
+  },
+  "pnpm": {
+    "onlyBuiltDependencies": ["@ast-grep/lang-php", "tree-sitter-cli"]
+  }
+}
diff --git a/packages/php/postinstall.js b/packages/php/postinstall.js
new file mode 100644
index 0000000..b9141ff
--- /dev/null
+++ b/packages/php/postinstall.js
@@ -0,0 +1,4 @@
+const { postinstall } = require('@ast-grep/setup-lang')
+postinstall({
+  dirname: __dirname,
+})
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 2db243b..da6b032 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -274,6 +274,22 @@ importers:
         specifier: 2.1.3
         version: 2.1.3
 
+  packages/php:
+    dependencies:
+      '@ast-grep/setup-lang':
+        specifier: 0.0.3
+        version: 0.0.3
+    devDependencies:
+      '@ast-grep/nursery':
+        specifier: 0.0.2
+        version: 0.0.2
+      tree-sitter-cli:
+        specifier: 0.24.6
+        version: 0.24.6
+      tree-sitter-php:
+        specifier: 0.23.12
+        version: 0.23.12(tree-sitter@0.21.1)
+
   packages/python:
     dependencies:
       '@ast-grep/setup-lang':
@@ -1159,6 +1175,14 @@ packages:
   tree-sitter-lua@2.1.3:
     resolution: {integrity: sha512-BmRSRI0Y4J47cE2cODyXsPiueDSAnIrFLJqOP/gKIJhGa4HoGpvEccmNuhAEVGtCrgaHGhaIkWeqiMGCgQ0cfw==}
 
+  tree-sitter-php@0.23.12:
+    resolution: {integrity: sha512-VwkBVOahhC2NYXK/Fuqq30NxuL/6c2hmbxEF4jrB7AyR5rLc7nT27mzF3qoi+pqx9Gy2AbXnGezF7h4MeM6YRA==}
+    peerDependencies:
+      tree-sitter: ^0.21.1
+    peerDependenciesMeta:
+      tree-sitter:
+        optional: true
+
   tree-sitter-python@0.23.6:
     resolution: {integrity: sha512-yIM9z0oxKIxT7bAtPOhgoVl6gTXlmlIhue7liFT4oBPF/lha7Ha4dQBS82Av6hMMRZoVnFJI8M6mL+SwWoLD3A==}
     peerDependencies:
@@ -1908,6 +1932,13 @@ snapshots:
     dependencies:
       nan: 2.22.2
 
+  tree-sitter-php@0.23.12(tree-sitter@0.21.1):
+    dependencies:
+      node-addon-api: 8.3.1
+      node-gyp-build: 4.8.4
+    optionalDependencies:
+      tree-sitter: 0.21.1
+
   tree-sitter-python@0.23.6:
     dependencies:
       node-addon-api: 8.3.0

From 7a1de1d75d693c3140ac4e54f94c155db8872c45 Mon Sep 17 00:00:00 2001
From: Nathan Gendron <nato@coderabbit.ai>
Date: Thu, 3 Apr 2025 16:20:33 -0400
Subject: [PATCH 2/5] =?UTF-8?q?=E2=9C=A8=20Add=20a=20`src`=20parameter=20t?=
 =?UTF-8?q?o=20`SetupConfig`?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 scripts/nursery/index.ts | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/scripts/nursery/index.ts b/scripts/nursery/index.ts
index de7ab89..1255b86 100644
--- a/scripts/nursery/index.ts
+++ b/scripts/nursery/index.ts
@@ -22,6 +22,10 @@ interface SetupConfig {
   treeSitterPackage: string
   /** Test cases running in CI */
   testRunner: (parse: (c: string) => SgRoot) => void
+  /** Path of the `src` directory inside the `tree-sitter-*` package. Useful for
+   * `tree-sitter-php`, `tree-sitter-typescript` and `tree-sitter-yaml`.
+   * @default "src" */
+  src?: string
 }
 
 function test(setupConfig: SetupConfig) {
@@ -44,13 +48,15 @@ export function setup(setupConfig: SetupConfig) {
 function copySrcIfNeeded(config: SetupConfig) {
   const { dirname, treeSitterPackage } = config
   const existing = path.join(dirname, 'src')
-  const src = path.join(dirname, 'node_modules', treeSitterPackage, 'src')
+  const src = config.src || 'src'
+  const source = path.join(dirname, 'node_modules', treeSitterPackage, src)
   if (fs.existsSync(existing)) {
     log('src exists, skipping copy')
     return
   }
+
   log('copying tree-sitter src')
-  fs.cpSync(src, 'src', { recursive: true })
+  fs.cpSync(source, 'src', { recursive: true })
 }
 
 interface NodeBasicInfo {

From a7f14d638002d08b7198fdc99152b4114880be85 Mon Sep 17 00:00:00 2001
From: Nathan Gendron <nato@coderabbit.ai>
Date: Thu, 3 Apr 2025 16:22:19 -0400
Subject: [PATCH 3/5] =?UTF-8?q?=F0=9F=9A=A7=20Use=20the=20new=20`src`=20co?=
 =?UTF-8?q?nfig?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 packages/php/nursery.js   | 2 ++
 packages/php/package.json | 4 ++--
 pnpm-lock.yaml            | 4 ++--
 3 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/packages/php/nursery.js b/packages/php/nursery.js
index b1c8ce8..8d11ed1 100644
--- a/packages/php/nursery.js
+++ b/packages/php/nursery.js
@@ -1,10 +1,12 @@
 const { setup } = require('@ast-grep/nursery')
 const languageRegistration = require('./index')
+const path = require('node:path')
 
 setup({
   dirname: __dirname,
   name: 'php',
   treeSitterPackage: 'tree-sitter-php',
+  src: path.join('php', 'src'),
   languageRegistration,
   testRunner: parse => {
     // add test here
diff --git a/packages/php/package.json b/packages/php/package.json
index a7a693e..a9a5333 100644
--- a/packages/php/package.json
+++ b/packages/php/package.json
@@ -4,7 +4,7 @@
   "description": "",
   "main": "index.js",
   "scripts": {
-    "build": "tree-sitter build -o parser.so",
+    "build": "tree-sitter build -o parser.so ./node_modules/tree-sitter-php/php",
     "source": "node nursery.js source",
     "prepublishOnly": "node nursery.js source",
     "postinstall": "node postinstall.js",
@@ -33,7 +33,7 @@
     }
   },
   "devDependencies": {
-    "@ast-grep/nursery": "0.0.2",
+    "@ast-grep/nursery": "workspace:*",
     "tree-sitter-cli": "0.24.6",
     "tree-sitter-php": "0.23.12"
   },
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index da6b032..ecbe981 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -281,8 +281,8 @@ importers:
         version: 0.0.3
     devDependencies:
       '@ast-grep/nursery':
-        specifier: 0.0.2
-        version: 0.0.2
+        specifier: workspace:*
+        version: link:../../scripts/nursery
       tree-sitter-cli:
         specifier: 0.24.6
         version: 0.24.6

From b16c11022674c0948c1f3ca2cf3dd52a21b6ece5 Mon Sep 17 00:00:00 2001
From: Nathan Gendron <nato@coderabbit.ai>
Date: Thu, 3 Apr 2025 16:22:59 -0400
Subject: [PATCH 4/5] =?UTF-8?q?=E2=9C=85=20Add=20a=20test=20for=20PHP?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 packages/php/nursery.js | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/packages/php/nursery.js b/packages/php/nursery.js
index 8d11ed1..ecee25a 100644
--- a/packages/php/nursery.js
+++ b/packages/php/nursery.js
@@ -1,4 +1,5 @@
 const { setup } = require('@ast-grep/nursery')
+const assert = require('node:assert')
 const languageRegistration = require('./index')
 const path = require('node:path')
 
@@ -9,6 +10,9 @@ setup({
   src: path.join('php', 'src'),
   languageRegistration,
   testRunner: parse => {
-    // add test here
+    const sg = parse('123')
+    const root = sg.root()
+    const node = root.find('123')
+    assert.equal(node.kind(), 'text')
   },
 })

From c06191e48d115937f5c105cc40fce880d9203453 Mon Sep 17 00:00:00 2001
From: Nathan Gendron <nato@coderabbit.ai>
Date: Fri, 4 Apr 2025 15:31:26 -0400
Subject: [PATCH 5/5] =?UTF-8?q?=F0=9F=93=9D=20Add=20changeset?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .changeset/wet-nights-cover.md | 6 ++++++
 1 file changed, 6 insertions(+)
 create mode 100644 .changeset/wet-nights-cover.md

diff --git a/.changeset/wet-nights-cover.md b/.changeset/wet-nights-cover.md
new file mode 100644
index 0000000..e067ca9
--- /dev/null
+++ b/.changeset/wet-nights-cover.md
@@ -0,0 +1,6 @@
+---
+"@ast-grep/nursery": patch
+"@ast-grep/lang-php": patch
+---
+
+Add @ast-grep/lang-php