
# AST Arama

Greph AST modu, PHP kaynak kodunu metne göre değil, yapısına göre arar. Desenler, `$VARIABLE` ve `$$$VARIADIC` üst değişkenleri içeren sıradan PHP kodu olarak yazılır. Desen, aradığı kaynakla aynı AST yapısına ayrıştırılır; bunu [nikic/php-parser](https://github.com/nikic/PHP-Parser) yapar. Ardından düğümler tek tek eşleştirilir.

Bu, [ast-grep](https://ast-grep.github.io/) ile aynı modeldir ve `sg` uyumluluk sarmalayıcısı aynı altyapının üzerinde ast-grep'ün CLI arayüzünü sunar.

## Hızlı örnekler

```bash
# Find every constructor call
./vendor/bin/greph -p 'new $CLASS()' src

# Find every method call with any number of arguments
./vendor/bin/greph -p '$obj->$method($$$ARGS)' src

# Find old-style array() calls
./vendor/bin/greph -p 'array($$$ITEMS)' src

# Find void-returning functions
./vendor/bin/greph -p 'function $name($$$PARAMS): void {}' src

# Find isset ternaries that should be ??
./vendor/bin/greph -p 'isset($x) ? $x : $default' src
```

## Desen söz dizimi

Bir desen, geçerli bir PHP kaynak kodudur. Gerçek bir ifade veya deyimin yer alabileceği her yerde, o düğümü yakalamak için yerine bir üst değişken koyabilirsiniz.

| Söz dizimi | Eşleşen | Örnek |
|---|---|---|
| `$VAR` | `VAR` olarak yakalanan herhangi bir AST düğümü | `$x + $y`, `foo() + bar` ile eşleşir |
| `$_` | Yakalanmayan herhangi bir AST düğümü | `$_->method()` herhangi bir alıcıyla eşleşir |
| `$$$ARGS` | `ARGS` olarak yakalanan sıfır veya daha fazla düğüm (değişken sayıda) | `func($$$ARGS)`, `func()`, `func(1)`, `func(1, 2, 3)` ile eşleşir |
| `$VAR` (tekrarlanan) | Aynı `$VAR` her iki yerde de aynı yapıyla eşleşmelidir | `$x == $x`, `a == a` ile eşleşir, `a == b` ile eşleşmez |

Üst değişken adı geleneksel olarak büyük harfle yazılır, ancak böyle olması gerekmez. `$_` yakalama yapmayan bir joker karakterdir.

`$$$VARIADIC`, PHP düğüm listesine izin verdiği her yerde kullanılabilir: işlev bağımsız değişkenlerinde, dizi öğelerinde, parametre listelerinde ve deyim gövdelerinde. Yakalama, eşleşen dizinin tamamını (sıfır öğe olsa bile) saklar.

## Tanımlayıcı üst değişkenleri

Sınıf, işlev, arayüz, trait ve enum adları ifade değil, tanımlayıcıdır; bu nedenle PHP normalde `class` sonrasında `$Name` kabul etmez. Greph ayrıştırmadan önce bu desenleri yeniden yazar; böylece üst değişken çalışmaya devam eder:

```bash
./vendor/bin/greph -p 'class $NAME extends BaseController {}' src
./vendor/bin/greph -p 'function $NAME(): void {}' src
./vendor/bin/greph -p 'interface $NAME {}' src
```

Aynı yeniden yazma `class`, `interface`, `trait`, `enum` ve `function` için de yapılır.

## Yinelenen üst değişkenler

Aynı desen içinde bir üst değişkeni yeniden kullanmak, her iki kullanımın da yapısal olarak aynı düğümle eşleşmesi gerektiğini belirtir. Bu, gereksiz kodu saptamak için kullanışlıdır:

```bash
# Tautological comparisons
./vendor/bin/greph -p '$X == $X' src

# Redundant ternaries
./vendor/bin/greph -p '$X ? $X : null' src
```

Aynı kural `$$$VARIADIC` için de geçerlidir: `$$$ARGS` değişkeninin iki kullanımı da aynı diziyle eşleşmelidir.

## Dosyaları filtreleme

AST modu, dosya ağacını metin moduyla aynı geziciyle tarar ve varsayılan olarak `php` dosya türü filtresini kullanır. `--type`, `--type-not`, `--glob`, `--no-ignore` ve `--hidden` ile değiştirin. Gezici, `.gitignore` ve `.grephignore` kurallarına uymaya devam eder ve ikili dosyaları atlar.

```bash
./vendor/bin/greph -p 'new $CLASS()' --glob 'src/**/*.php' .
./vendor/bin/greph -p 'new $CLASS()' --type-not phpt src
```

## Çıktı

Varsayılan çıktı, metin moduyla aynı `file:line:content` biçimini kullanır; eşleşen kod tek satıra indirgenir:

```text
src/Greph.php:38:return (new FileWalker())->walk($paths, $options);
src/Greph.php:49:$searcher = new TextSearcher();
```

Yapılandırılmış eşleşmeler üretmek için `--json` iletin:

```json
[
  {
    "file": "src/Greph.php",
    "start_line": 38,
    "end_line": 38,
    "start_file_pos": 1234,
    "end_file_pos": 1252,
    "code": "new FileWalker()"
  }
]
```

## Ayrıştırma hataları

Varsayılan olarak Greph, ayrıştırılamayan dosyaları sessizce atlar. Deneysel veya oluşturulmuş PHP içeren büyük bir kod tabanında çalışırken doğru davranış budur. Bunun yerine ayrıştırma hatasını yükseltmek için `--strict-parse` kullanın (`greph-index ast-index search` ve `greph-index ast-cache search` üzerinde) ya da cepheyi doğrudan kullanırken `AstSearchOptions` üzerinde `skipParseErrors: false` ayarlayın.

## Programatik kullanım

```php
use Greph\Greph;
use Greph\Ast\AstSearchOptions;

$matches = Greph::searchAst(
    '$obj->$method($$$ARGS)',
    'src',
    new AstSearchOptions(jobs: 4),
);

foreach ($matches as $match) {
    echo "{$match->file}:{$match->startLine}\n";
    echo $match->code . "\n";

    foreach ($match->captures as $name => $node) {
        echo "  {$name} = " . get_debug_type($node) . "\n";
    }
}
```

`$match->node` yakalanan `PhpParser\Node` değeridir (bu nedenle PHP-Parser'in `NodeVisitor` özelliğiyle gezebilirsiniz); `$match->captures` ise her üst değişken adını yakalanan düğüm veya düğüm listesiyle eşleştirir.

## Nasıl çalışır

İşlem hattı şöyledir:

1. **Desen ayrıştırma**: `Greph\Ast\PatternParser`, tanımlayıcı üst değişkenlerini yeniden yazar ve ardından deseni PHP-Parser ile ayrıştırır.
2. **Kaynak ayrıştırma**: Her aday dosya bir kez ayrıştırılır. `ast-cache` modunda bu adımın yerini önbellek deposundan serileştirilmiş veriyi okuma alır.
3. **Aday filtreleme**: `Greph\Ast\AstPatternPrefilter`, desenden kaba bir imza (çağrı adı, sınıf adı, deyim türü) çıkarır ve eşleşme içermesi açıkça mümkün olmayan dosyaları atlamak için bunu kullanır. `ast-index` modunda bu adım, önceden hesaplanmış bir olgu deposunu sorgular.
4. **Eşleştirme**: `Greph\Ast\PatternMatcher` kaynak AST'sini tarar ve desen AST'siyle karşılaştırır; bu sırada üst değişkenleri bağlar ve yinelenen değişkenlerin tutarlı olmasını sağlar.
5. **Sonuç üretimi**: Eşleşen düğümler, satır ve bayt konumlarıyla özgün kaynak dilimini içeren `AstMatch` nesnelerine dönüştürülür.

Tekrarlanan iş yüklerinde [dizinli AST araması](https://greph.inline0.dev/tr/docs/indexed/ast) ve [önbelleğe alınmış AST araması](https://greph.inline0.dev/tr/docs/indexed/cache), 2. ve 3. adımların çoğunu atlar.
