İçeriğe geç

Dizinlenmiş AST Araması

Dizinlenmiş AST araması, AST aramasının ısıtılmış önbellekli sürümüdür. İlk çağrı, düğüm düzeyindeki olguları (çağrı adları, örneklemeler, sınıf bildirimleri, yöntem bildirimleri) diskteki bir depoya çıkarır; sonraki çağrılar, yapısal eşleşme içermesi açıkça mümkün olmayan dosyaları atlamak için bu depoyu kullanır. Ardından eşleştirici, adayları kaynak kodla yeniden doğrular.

Olgu dizinine greph-index ast-index CLI alt komutundan ve Greph::buildAstIndex() / Greph::searchAstIndexed() arayüz yöntemlerinden erişilir. Ayrıca ısıtılmış çoklu dizin ve bildirim dosyası destekli küme iş akışlarına da katılır.

Dizini oluşturma

Kabuk
# Full build at the current directory
./vendor/bin/greph-index ast-index build .

# Full build at an explicit root
./vendor/bin/greph-index ast-index build path/to/repo

# Use a non-default index directory
./vendor/bin/greph-index ast-index build . --index-dir /tmp/greph-ast-index

# Build a mutable overlay that can refresh cheaply on demand
./vendor/bin/greph-index ast-index build . \
  --lifecycle opportunistic-refresh \
  --auto-refresh-max-files 32 \
  --auto-refresh-max-bytes 1048576

Olgu dizini varsayılan olarak <root>/.greph-ast-index/ konumunda saklanır.

Başarılı bir oluşturma işlemi tek satırlık bir özet yazdırır:

Text
Built AST index for 2547 files in .greph-ast-index (84931 fact rows, +2547 ~0 -0 =0)

Dört sayaç, son oluşturma işleminden bu yana eklenen, güncellenen, silinen ve değişmeden kalan dosyaları gösterir.

Dizini yenileme

Kabuk
./vendor/bin/greph-index ast-index refresh .

refresh dizinlenen kökü yeniden tarar, değişen dosyaları yeniden ayrıştırır ve yalnızca değişen olgu satırlarını yeniden yazar. Çıktıda metin diziniyle aynı dört sayaç kullanılır.

Yaşam döngüsü profilleri, ısıtılmış metin dizinleriyle aynı şekilde çalışır:

  • static: güncelliği hiçbir zaman denetleme veya otomatik olarak değiştirme
  • manual-refresh: eski durumu stats içinde bildir, ancak arama sırasında hiçbir zaman yenileme
  • opportunistic-refresh: yalnızca değişen küme hâlâ yeterince küçükse arama sırasında yenile
  • strict-stale-check: eski aramaları yenilemek yerine reddet

Dizinde sorgu yapma

Kabuk
./vendor/bin/greph-index ast-index search 'new $CLASS()' src
./vendor/bin/greph-index ast-index search '$obj->$method($$$ARGS)' src
./vendor/bin/greph-index ast-index search --json 'array($$$ITEMS)' src
./vendor/bin/greph-index ast-index search -l 'array($$$ITEMS)' src
./vendor/bin/greph-index ast-index search --trace-plan 'new $CLASS()' src

Metadeğişken sözdizimi, yerel AST aramasıyla aynıdır. Tüm dil bilgisi için Modlar / AST Araması bölümüne bakın.

Seçenekler

Seçenek Anlamı
--lang NAME AST dili. Varsayılan: php
-j N, --jobs N Paralel çalışan sayısı
-l, --files-with-matches Yalnızca eşleşen dosyaları listele
--glob GLOB Yalnızca yolları GLOB ile eşleşen dosyaları dahil et
--type NAME / --type-not NAME Dosya türü filtresi
--json JSON çıktısı üret
--no-ignore .gitignore ve .grephignore kurallarını yok say
--hidden Gizli dosyaları dahil et
--strict-parse Ayrıştırma hatalarını atlamak yerine hata ver
--fallback MODE Eksik dizin davranışı: fail (varsayılan) veya scan
--index-dir DIR Varsayılan olmayan bir dizin klasörü kullan
--trace-plan Isıtılmış AST planlayıcı tanılamalarını stderr konumuna yaz
--show-index-origin Çoklu dizin veya küme modunda çıktının başına eşleşen dizin etiketini ekle

Eksik dizin için yedek seçenek

Varsayılan olarak ast-index search, istenen konumda dizin yoksa hata verir. Bunun yerine yerel AST taramasına geçmek için --fallback scan seçeneğini iletin. Bu seçenek, dizin mevcut olduğunda dizinlenmiş arama kullanmak, henüz oluşturulmadığında da sonuç üretmeye devam etmek isteyen araçlar için uygundur.

Kabuk
./vendor/bin/greph-index ast-index search --fallback scan 'new $CLASS()' src

--index-dir seçeneğini tekrarlayarak tek bir komutla birden çok ısıtılmış AST dizininde arama yapabilirsiniz. Bu, WordPress çekirdeğiyle birlikte bir eklenti veya tema kullanmak gibi düzenlerde yararlıdır.

Kabuk
./vendor/bin/greph-index ast-index search \
  --index-dir ../wordpress/.greph-ast-index \
  --index-dir ./.greph-ast-index \
  --show-index-origin \
  'new $CLASS()' .

--show-index-origin etkin olduğunda çıktı, eşleşmenin hangi kökten geldiğini görebilmeniz için eşleşen ısıtılmış dizin girişinin adıyla başlar.

Bildirim dosyası destekli dizin kümeleri

Kararlı ısıtılmış düzenler için bir bildirim dosyası tanımlayın ve greph-index set komutunun gruplandırılmış dizinlerde çalışmasını sağlayın:

Kabuk
./vendor/bin/greph-index set build
./vendor/bin/greph-index set stats --mode ast-index --dry-refresh
./vendor/bin/greph-index set search --mode ast-index --show-index-origin 'new $CLASS()' .

Küme alt komutları, doğrudan ast-index kullanımındakiyle aynı yaşam döngüsü yönetimini, eskilik denetimlerini ve planlayıcı tanılamalarını paylaşır.

Planlayıcı tanılamaları

--trace-plan, tam eşleştirici çalışmadan önce Greph sorguyu nasıl daralttığını gösterir. ast-index için bu genellikle şunları içerir:

  • Örüntüden çıkarılan genel olgu imzası
  • Kaç ısıtılmış dizinde arama yapıldığı
  • Olgu filtresinin kaç dosyayı elediği
  • Tam yapısal doğrulama için kaç aday dosyanın yeniden ayrıştırıldığı

Dizinin sakladıkları

AST olgu çıkarıcısı, dizinlenen her dosyada “ilgi çekici” her düğüm için bir satır kaydeder. Olgu türleri, AST örüntülerinin en sık hedeflediği yapıları kapsar:

  • İşlev ve yöntem çağrıları (çağrılan ada göre)
  • Sınıf örneklemeleri (sınıf adına göre)
  • Sınıf, arayüz, özellik ve enum bildirimleri (ada göre)
  • İşlev bildirimleri (ada göre)
  • Yöntem bildirimleri (ada ve görünürlüğe göre)
  • Kullanım ifadeleri

Bir sorgu geldiğinde Greph\Ast\AstFactQuery, arama örüntüsünü genel bir olgu imzasına dönüştürür (örneğin, “herhangi bir sınıfa ait bir new içermeli”) ve olgu deposuyla kesişimini alır. Kesişimden geçen dosyalar yeniden ayrıştırılır ve tam örüntüyle eşleştirilir.

Bu, olgu dizininin tam eşleşme deposu değil, bir ön filtre olduğu anlamına gelir. Eşleştirme adımı kaynak kodu yine ayrıştırır; dolayısıyla yapısal doğruluk yerel AST aramasıyla aynıdır, yalnızca aday kümesi daha küçüktür.

Ne zaman kullanılır?

Dizinlenmiş AST modu şu durumlarda doğru araçtır:

  • Aynı yapısal sorguları aynı kod tabanında tekrar tekrar çalıştırıyorsanız.
  • Örüntüler, olgu çıkarıcının sakladığı tanımlanabilir şekilleri (çağrı adı, sınıf adı, bildirim türü) hedefliyorsa.
  • Her dosyayı yeniden ayrıştırmaktan daha düşük gecikme istiyorsanız.

Ayırt edici özelliği olgu kümesinde bulunmayan örüntülerde (örneğin, tanınabilir bir başlığı olmayan karmaşık iç içe ifadelerde), önbelleğe alınmış AST modu genellikle daha uygundur; genel bir imzaya bağlı kalmadan ayrıştırma adımını tamamen atlar.

Programatik kullanım

PHP
use Greph\Greph;
use Greph\Ast\AstSearchOptions;
use Greph\Index\IndexLifecycleProfile;

Greph::buildAstIndex('.', lifecycle: IndexLifecycleProfile::OpportunisticRefresh);

$matches = Greph::searchAstIndexed(
    'new $CLASS()',
    'src',
    new AstSearchOptions(jobs: 4, tracePlan: true),
);

searchAstIndexed, yerel AST aramasıyla aynı AstSearchOptions değerini kabul eder ve aynı list<AstMatch> yapısını döndürür. Çoklu dizin veya bildirim dosyası destekli iş akışları için searchAstIndexedMany(...) ve searchAstIndexedSet(...) kullanın.