Eine Funktion verstehen, bevor man sie liest
Was du davon hast
Dein Agent sieht zuerst, was eine Funktion tut, wie sie aufgebaut ist und wer sie aufruft. brief liefert das in einem Aufruf, read-smart zeigt die Gestalt einer langen Funktion mit einer Zeile pro tiefem Block. Den Block, den er wirklich braucht, holt der Agent danach mit expand. 200 Zeilen Quelltext muss er dafür nicht lesen.
Vorher und nachher
Die Frage an serde: Was macht deserialize_map im Derive-Makro, wie ist es aufgebaut, und wer ruft es auf?
Ohne greppy
Der Agent sucht den Namen, liest die ganze Funktion und ordnet die Aufrufstelle ihrer Funktion zu.
$ grep -rnw deserialize_map serde_derive/src
serde_derive/src/de/struct_.rs:97: let visit_map = Stmts(deserialize_map(
serde_derive/src/de/struct_.rs:115: _serde::Deserializer::deserialize_map(__deserializer, self)
serde_derive/src/de/struct_.rs:141: _serde::Deserializer::deserialize_map(__deserializer, #visitor_expr)
serde_derive/src/de/struct_.rs:199:fn deserialize_map(
$ sed -n '199,/^}/p' serde_derive/src/de/struct_.rs
fn deserialize_map(
struct_path: &TokenStream,
…
}
$ grep -n '^pub.*fn \|^fn ' serde_derive/src/de/struct_.rs
17:pub(super) fn deserialize(
199:fn deserialize_map(
…
Die Zeilen 115 und 141 sind Token im erzeugten Code, keine Aufrufe. Der echte Aufruf liegt in deserialize (Zeile 97).
Mit greppy
$ greppy brief serde_derive/src/de/struct_.rs::deserialize_map
Generates deserialization code for struct fields.
serde_derive/src/de/struct_.rs:199-205
fn deserialize_map(
…
) -> Fragment {
210 field_i — creates an Ident for a field named after the index
…
317 expr_is_missing — generates code for missing-field validation
…
}
called by deserialize
expand 986e0689aced6bf4 — the call tree below deserialize_map sketched, 7 functions, 59 lines
$ greppy read-smart serde_derive/src/de/struct_.rs::deserialize_map
serde_derive/src/de/struct_.rs:199-419 deserialize_map
…
// Match arms to extract a value for a field.
let value_arms = fields_names
.iter()
.filter(|&&(field, _)| !field.attrs.skip_deserializing() && !field.attrs.flatten())
… 240-274 Generates deserialization code for a struct field. — greppy expand c53ffb0c7b71d241
…
brief skizziert den Ablauf in 19 Zeilen, read-smart zeigt die 221 Zeilen als 72 Zeilen Gestalt. Jeder gefaltete Block trägt seine expand-ID: greppy expand c53ffb0c7b71d241 liefert genau die Zeilen 240 bis 274, selbst wieder mit gefalteten Unterblöcken.
| ohne greppy | mit greppy | |
|---|---|---|
| Aufrufe | 3 | 2 |
| Zeichen Ausgabe | 8.419 | 3.699 |
| Token | 1.917 | 1.011 |
So funktioniert es
brief verbindet Graph, Quelltext und lokales Modell: Es druckt den Zweck der Funktion in einem Satz, ihre Signatur wörtlich und danach eine Zeile pro Aufrufstelle oder Verzweigung mit dem echten Symbol und dessen Kurzbeschreibung. Die Aufrufer kommen aus dem Symbolgraph. Structs, Enums und Traits haben keinen Ablauf, brief zeigt ihre ganze Definition. read-smart lässt die äußeren Ebenen einer Funktion wörtlich stehen und faltet jeden tieferen Block in eine Zeile mit Zeilenbereich, Beschreibung und expand-ID; --depth N wählt die Ebene. Die Beschreibungen schreibt das lokale Modell aus dem Quelltext. Große Ergebnisse liegen hinter einer expand-ID bereit, greppy expand ID druckt sie in einem Aufruf.
Die Befehle
| Befehl | was er tut |
|---|---|
greppy brief S |
Zweck in einem Satz, Signatur, Ablauf mit einer Zeile pro Aufruf oder Verzweigung, dann die Aufrufer |
greppy read-smart S |
die Definition mit gefalteten Blöcken, je Block eine Zeile mit Zeilenbereich, Beschreibung und expand-ID |
greppy expand ID |
das vorbereitete Ergebnis einer früheren Abfrage, vollständig in einem Aufruf |
Mehr in der Doku
- Den Graph navigieren:
briefmit Beispielen - Quelltext lesen:
read-smartund--depth - Suchen:
expandund die Evidenzpakete