Μετάβαση στο περιεχόμενο

Αναζήτηση AST με ευρετήριο

Η αναζήτηση AST με ευρετήριο είναι η έκδοση με προθερμασμένη προσωρινή μνήμη της αναζήτησης AST. Κατά την πρώτη κλήση, εξάγονται δεδομένα σε επίπεδο κόμβου (ονόματα κλήσεων, στιγμιότυπα, δηλώσεις κλάσεων και δηλώσεις μεθόδων) και αποθηκεύονται σε αποθηκευτικό μέσο στον δίσκο. Οι επόμενες κλήσεις χρησιμοποιούν αυτό το αποθηκευτικό μέσο για να παραλείπουν αρχεία που προφανώς δεν μπορούν να περιέχουν δομική αντιστοίχιση. Στη συνέχεια, ο μηχανισμός αντιστοίχισης επαληθεύει ξανά τα υποψήφια αρχεία με βάση τον πηγαίο κώδικα.

Το ευρετήριο δεδομένων είναι διαθέσιμο μέσω της υποεντολής greph-index ast-index CLI και των μεθόδων πρόσοψης Greph::buildAstIndex() / Greph::searchAstIndexed(). Συμμετέχει επίσης σε ροές εργασίας με πολλά προθερμασμένα ευρετήρια και σε σύνολα που βασίζονται σε δηλωτικό αρχείο.

Δημιουργία του ευρετηρίου

Κέλυφος
# 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

Από προεπιλογή, το ευρετήριο δεδομένων αποθηκεύεται στο <root>/.greph-ast-index/.

Μια επιτυχής δημιουργία εκτυπώνει μια σύνοψη μίας γραμμής:

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

Οι τέσσερις μετρητές αντιστοιχούν στα αρχεία που προστέθηκαν, ενημερώθηκαν, διαγράφηκαν και παρέμειναν αμετάβλητα από την τελευταία δημιουργία.

Ανανέωση του ευρετηρίου

Κέλυφος
./vendor/bin/greph-index ast-index refresh .

Το refresh περιηγείται ξανά στη ρίζα του ευρετηρίου, αναλύει εκ νέου τα αρχεία που άλλαξαν και ξαναγράφει μόνο τις γραμμές δεδομένων που μεταβλήθηκαν. Η έξοδος χρησιμοποιεί τους ίδιους τέσσερις μετρητές με το ευρετήριο κειμένου.

Τα προφίλ κύκλου ζωής λειτουργούν όπως και στα προθερμασμένα ευρετήρια κειμένου:

  • static: μην ελέγχετε ποτέ αυτόματα την επικαιρότητα ούτε να κάνετε αυτόματες αλλαγές
  • manual-refresh: αναφέρετε την παρωχημένη κατάσταση στο stats, αλλά μην ανανεώνετε ποτέ κατά την αναζήτηση
  • opportunistic-refresh: ανανεώνετε κατά την αναζήτηση μόνο όταν το σύνολο των αλλαγών παραμένει αρκετά μικρό
  • strict-stale-check: απορρίψτε τις παρωχημένες αναζητήσεις αντί να τις ανανεώσετε

Εκτέλεση ερωτημάτων στο ευρετήριο

Κέλυφος
./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

Η σύνταξη μεταβλητών μετα-επιπέδου είναι ίδια με εκείνη της εγγενούς αναζήτησης AST. Δείτε τις Λειτουργίες / Αναζήτηση AST για την πλήρη γραμματική.

Επιλογές

Σημαία Σημασία
--lang NAME Γλώσσα AST. Προεπιλογή: php
-j N, --jobs N Αριθμός παράλληλων εργαζομένων
-l, --files-with-matches Εμφάνιση μόνο των αρχείων που αντιστοιχούν
--glob GLOB Συμπερίληψη μόνο αρχείων των οποίων οι διαδρομές αντιστοιχούν στο GLOB
--type NAME / --type-not NAME Φίλτρο τύπου αρχείου
--json Εξαγωγή εξόδου JSON
--no-ignore Αγνόηση των .gitignore και .grephignore
--hidden Συμπερίληψη κρυφών αρχείων
--strict-parse Αποτυχία σε σφάλματα ανάλυσης αντί παράλειψής τους
--fallback MODE Συμπεριφορά όταν λείπει το ευρετήριο: fail (προεπιλογή) ή scan
--index-dir DIR Χρήση μη προεπιλεγμένου καταλόγου ευρετηρίου
--trace-plan Εξαγωγή διαγνωστικών σχεδιασμού AST με προθερμασμένο ευρετήριο στο stderr
--show-index-origin Πρόθεμα στην έξοδο με την ετικέτα του ευρετηρίου που αντιστοιχεί, σε λειτουργία πολλών ευρετηρίων ή συνόλου

Εναλλακτική λειτουργία όταν λείπει το ευρετήριο

Από προεπιλογή, το ast-index search εμφανίζει σφάλμα όταν δεν υπάρχει ευρετήριο στην καθορισμένη θέση. Περάστε το --fallback scan για να γίνει εγγενής σάρωση AST. Αυτή είναι η κατάλληλη ρύθμιση για εργαλεία που προτιμούν αναζήτηση με ευρετήριο όταν αυτό είναι διαθέσιμο, αλλά πρέπει να εμφανίζουν αποτελέσματα ακόμη και αν δεν έχει δημιουργηθεί ευρετήριο.

Κέλυφος
./vendor/bin/greph-index ast-index search --fallback scan 'new $CLASS()' src

Μπορείτε να κάνετε αναζήτηση σε πολλά προθερμασμένα ευρετήρια AST με μία εντολή, επαναλαμβάνοντας το --index-dir. Αυτό είναι χρήσιμο σε διατάξεις όπως ο βασικός κώδικας WordPress μαζί με ένα πρόσθετο ή ένα θέμα.

Κέλυφος
./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, στην αρχή της εξόδου εμφανίζεται το όνομα της αντίστοιχης καταχώρισης προθερμασμένου ευρετηρίου, ώστε να γνωρίζετε από ποια ρίζα προέρχεται το αποτέλεσμα.

Σύνολα ευρετηρίων βάσει δηλωτικού αρχείου

Για σταθερές διατάξεις προθερμασμένων ευρετηρίων, ορίστε ένα δηλωτικό αρχείο και αφήστε το greph-index set να λειτουργήσει πάνω στα ομαδοποιημένα ευρετήρια:

Κέλυφος
./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()' .

Οι υποεντολές συνόλων χρησιμοποιούν τον ίδιο χειρισμό κύκλου ζωής, τους ίδιους ελέγχους παρωχημένης κατάστασης και τα ίδια διαγνωστικά σχεδιασμού με την άμεση χρήση του ast-index.

Διαγνωστικά σχεδιασμού

Το --trace-plan δείχνει πώς το Greph περιόρισε το ερώτημα πριν ξεκινήσει ο πλήρης μηχανισμός αντιστοίχισης. Για το ast-index, αυτό συνήθως περιλαμβάνει:

  • την ευρεία υπογραφή δεδομένων που εξήχθη από το μοτίβο
  • πόσα προθερμασμένα ευρετήρια αναζητήθηκαν
  • πόσα αρχεία απορρίφθηκαν από το φίλτρο δεδομένων
  • πόσα υποψήφια αρχεία αναλύθηκαν ξανά για ακριβή δομική επαλήθευση

Τι αποθηκεύει το ευρετήριο

Για κάθε αρχείο στο ευρετήριο, ο εξαγωγέας δεδομένων AST καταγράφει μία γραμμή για κάθε «ενδιαφέροντα» κόμβο. Τα είδη δεδομένων καλύπτουν τις δομές που στοχεύουν συχνότερα τα μοτίβα AST:

  • Κλήσεις συναρτήσεων και μεθόδων (με βάση το όνομα που καλείται)
  • Δημιουργία στιγμιότυπων κλάσεων (με βάση το όνομα της κλάσης)
  • Δηλώσεις κλάσεων, διεπαφών, traits και enums (με βάση το όνομα)
  • Δηλώσεις συναρτήσεων (με βάση το όνομα)
  • Δηλώσεις μεθόδων (με βάση το όνομα και την ορατότητα)
  • Δηλώσεις use

Όταν λαμβάνεται ένα ερώτημα, το Greph\Ast\AstFactQuery μετατρέπει το μοτίβο αναζήτησης σε μια ευρεία υπογραφή δεδομένων (για παράδειγμα, «πρέπει να περιέχει ένα new οποιασδήποτε κλάσης») και κάνει τομή με το αποθηκευμένο σύνολο δεδομένων. Τα αρχεία που περνούν αυτό το στάδιο αναλύονται ξανά και αντιστοιχίζονται με βάση ολόκληρο το μοτίβο.

Αυτό σημαίνει ότι το ευρετήριο δεδομένων λειτουργεί ως προφίλτρο και όχι ως αποθήκη πλήρων αντιστοιχίσεων. Το στάδιο αντιστοίχισης εξακολουθεί να αναλύει τον πηγαίο κώδικα, επομένως η δομική ορθότητα είναι ίδια με εκείνη της εγγενούς αναζήτησης AST· απλώς το σύνολο υποψηφίων είναι μικρότερο.

Πότε να το χρησιμοποιήσετε

Η λειτουργία AST με ευρετήριο είναι κατάλληλη όταν:

  • Εκτελείτε επανειλημμένα τα ίδια δομικά ερωτήματα στην ίδια βάση κώδικα.
  • Τα μοτίβα στοχεύουν αναγνωρίσιμα σχήματα (όνομα κλήσης, όνομα κλάσης, είδος δήλωσης) που αποθηκεύει ο εξαγωγέας δεδομένων.
  • Θέλετε μικρότερη καθυστέρηση από την εκ νέου ανάλυση κάθε αρχείου.

Για μοτίβα των οποίων το διακριτικό χαρακτηριστικό δεν περιλαμβάνεται στο σύνολο δεδομένων (για παράδειγμα, σύνθετες εμφωλευμένες εκφράσεις χωρίς αναγνωρίσιμη κεφαλή), η λειτουργία AST με προσωρινή μνήμη συνήθως ταιριάζει καλύτερα, επειδή παραλείπει εντελώς το στάδιο ανάλυσης χωρίς να βασίζεται σε ευρεία υπογραφή.

Προγραμματιστική χρήση

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 δέχεται τα ίδια AstSearchOptions με την εγγενή αναζήτηση AST και επιστρέφει το ίδιο σχήμα list<AstMatch>. Για ροές εργασίας με πολλά ευρετήρια ή δηλωτικό αρχείο, χρησιμοποιήστε τα searchAstIndexedMany(...) και searchAstIndexedSet(...).