Ein Flowistry-IDE-Plugin, das bei Rust dabei hilft, sich auf relevanten Code zu konzentrieren
(github.com/willcrichton)- Flowistry ist ein IDE-Plugin für die Rust-Sprache, das nur die Codeabschnitte anzeigt, die für den gerade fokussierten Code relevant sind
- Dieses Plugin analysiert den Informationsfluss im Rust-Code und hebt visuell nur den Code hervor, der direkt mit der aktuell ausgewählten Variablen oder dem aktuellen Ausdruck verknüpft ist
- Es lässt sich einfach als VSCode-Plugin installieren und markiert nur den Code, der auf die gewählte Variable einwirkt oder von ihr beeinflusst wird
- Mit Funktionen wie "Focus mode" und der "Mark"-Funktion verbessert es die Verständlichkeit großer Funktionen oder komplexen Codes erheblich
- Es hat jedoch Grenzen wie eine unvollständige Behandlung von Interior Mutability und einen eingeschränkten Analyseumfang, ist aber in Entwicklung und bleibt ein separates Werkzeug zu Rust Analyzer
Überblick und Bedeutung von Flowistry
Flowistry ist ein IDE-Plugin für Rust-Entwickler und hebt im Code die Teile hervor, die mit dem Bereich verbunden sind, auf den man sich gerade konzentrieren möchte. Es hilft dabei, in großen Funktionen oder komplexen Codeflüssen die relevanten Stellen schnell und klar zu identifizieren und bietet dadurch einen praktischen Mehrwert gegenüber anderen statischen Analysewerkzeugen. Die Kerntechnik ist die Informationsflussanalyse, ein Datenflussanalyse-Ansatz, der Pfade erkennt, über die ein Codeabschnitt auf anderen Code einwirken kann. Flowistry stellt diese Informationsflussanalyse für Rust bereit und berücksichtigt dabei die Spracheigenschaften sowie das Ownership-/Lebenszeit-Modell von Rust und basiert auf Rust MIR (Mid-level Intermediate Representation).
Hauptfunktionen und Funktionsweise
- Klickt man in Rust-Code eine bestimmte Variable oder einen Ausdruck an, wird der Code, der diese Stelle beeinflusst oder von ihr beeinflusst wird, hervorgehoben und der übrige Code ausgegraut
- Relevanter Code wird intuitiv hervorgehoben, wodurch unnötiges Lesen reduziert und der zentrale Codefluss schneller erfasst werden kann
- In großen Funktionen oder komplexen Codebereichen wie echten Funktionen im Rust-Compiler lässt sich auf einen Blick erkennen, welche Rolle ein bestimmter Parameter spielt
- Der zugrundeliegende Algorithmus basiert auf dem im PLDI 2022 veröffentlichten Paper "Modular Information Flow through Ownership"
Installation und Umgebungsunterstützung
IDE-Plugin-Installation
- Flowistry kann als VSCode-Plugin über Visual Studio Marketplace oder Open VSX Registry installiert werden
- Nach dem Öffnen eines Rust-Workspaces erfolgt die Installation und Initialisierung automatisch
- NixOS wird nicht unterstützt, und auf ARM-Plattformen (z. B. M1-Macs) muss aus dem Quellcode gebaut werden
Rustc-Plugin
- Die reine Informationsflussanalyse wird als eigenes Crate veröffentlicht und mit ausführlicher Dokumentation und eigener API bereitgestellt
Nutzung und detaillierte Funktionen
Erster Start
- Beim Start des Plugins in VSCode wird zunächst eine Typprüfung der gesamten Codebasis durchgeführt
- Das Ergebnis wird im Verzeichnis
target/flowistryzwischengespeichert
Fokusmodus aktivieren
- Mit dem Befehl „Toggle focus mode“ des Plugins (z. B. Ctrl+R Ctrl+A) lässt sich der Fokusmodus aktivieren
- Wenn der Cursor in einer Funktion platziert ist, wird innerhalb dieser Funktion automatisch die Informationsflussanalyse ausgeführt
- Sobald die Analyse abgeschlossen ist, werden nur die relevanten Codebereiche hervorgehoben (die Analyse kann bis zu etwa 15 Sekunden dauern)
Mark einrichten
- Mit dem Konzept „Mark“ kann ein bestimmter Fokusbereich fixiert werden, sodass man beim Durchsehen anderer Codeabschnitte den aktuellen Bereich beibehält
- Mit „Set mark“ (Ctrl+R Ctrl+S) und „Unset mark“ (Ctrl+R Ctrl+D) lässt sich die Markierung setzen und aufheben
Fokusbereich auswählen
- Der Befehl „Select focused region“ ermöglicht es, den gesamten hervorgehobenen Codeblock auf einmal auszuwählen, um ihn zu kopieren, zu kommentieren oder anderweitig zu bearbeiten
Einschränkungen und Hinweise
- Interior Mutability wird nicht vollständig unterstützt
- Beispiel: Bei Strukturen wie
ArcundMutexist aufgrund von Lebensdauerdifferenzen zwischen Referenzen keine vollständige Nachverfolgung möglich
- Beispiel: Bei Strukturen wie
- Der Fokusbereich kann gelegentlich breiter ausfallen als erwartet
- Das liegt daran, dass die interne Struktur aufgerufener Funktionen tatsächlich nicht vollständig analysiert werden kann
- Es gibt nicht auswählbaren Code
- Nicht jeder Code ist auswählbar, da es Mapping-Grenzen zwischen MIR-Ebene und Quellcode gibt
- Verschachtelte Funktionen, Closures und
asyncwerden nicht gemeinsam analysiert- Die Analyse findet immer nur auf der kleinsten Funktionseinheit statt, der Funktion, in der sich der Cursor befindet
FAQ und Sonstiges
- Falls die rustup-Installation fehlschlägt: rustup bitte manuell per Kommandozeile installieren und dann in VSCode fortfahren
- Warum es nicht in Rust Analyzer integriert ist: Rust Analyzer unterstützt keine MIR-Analyse und den Borrow Checker, daher handelt es sich um ein separates Plugin
- Bei Problemen mit dem Code-Highlighting siehe die Limits-Dokumentation; weitere Anfragen sind über GitHub-Issues, Discord oder Twitter möglich
Lizenz und Open-Source-Informationen
- Es ist als MIT-Lizenz offen verfügbar
- Die Hauptprogrammiersprachen sind Rust und TypeScript, zusätzlich Python, HTML, JavaScript usw.
- Stand September 2025: 2.6k Stars, 61 Forks, mit aktiver Weiterentwicklung und Pflege
Fazit
Flowistry ist ein Open-Source-Tool, das in der Rust-Entwicklungsumgebung einen echten Vorteil für das Verstehen von Kontexten in komplexem Code und die Verbesserung der Konzentration bietet. Insbesondere durch die Integration der Informationsflussanalyse in Echtzeit in die IDE liefert es ein anderes Erlebnis als klassische statische Analysewerkzeuge oder Rust Analyzer. Seine Nutzbarkeit und Effizienz ist in verschiedenen Situationen hoch, etwa beim Erlernen der Rust-Sprache, beim Refactoring und bei Code-Reviews.
1 Kommentare
Hacker-News-Kommentare
Das eigentliche Paper ist hier. Ich denke schon seit Langem über statisch geprüfte Back-References in Rust nach. Einer der Hauptgründe, warum C/C++-Nutzer mit Rust unzufrieden sind, ist, dass es schwierig ist, wenn A auf B verweist, von B aus wieder einen Pointer auf A zu haben. Deshalb werden oft unsichere Workarounds verwendet.
Mit Rc, RefCell, Weak, borrow(), borrow_mut(), upgrade(), downgrade() usw. lässt sich das in Rust sicher umsetzen, aber der Code wird ausführlich, es entsteht Runtime-Overhead, und bei doppeltem Borrow kann es zu Panics kommen. Dennoch ist die Ausdrucksstärke ausreichend. Ich habe Notizen zu der Arbeit zusammengestellt, an der ich gerade arbeite.
Schwierig an der statischen Prüfung ist festzustellen, ob sich geborgte Bereiche überschneiden. Wenn sich Lifetime-Scopes nicht überschneiden, gibt es keinen Konflikt. Bei Funktionsaufrufen oder Aufrufen generischer Funktionen wird die Scope-Prüfung kniffliger. Der Ansatz von Flowistry könnte dabei hilfreich sein.
Mich beschäftigt, dass Flowistry interior mutability (interne Mutierbarkeit wie mit RefCell usw.) nicht vollständig abdeckt.
In der Praxis ist der Kern, Einschränkungen zu finden, die Bedingungen erfüllen wie: 1) sound, 2) mit geringen Kosten zur Compile-Zeit prüfbar, 3) die von den meisten benötigten Back Pointer wie Verweise auf den Elternknoten eines Baums erlauben und 4) bei Problemen nützliche Diagnosemeldungen liefern.
Ich frage mich, ob es in anderen Sprachen Funktionen gibt, die etwas größere oder informellere Abhängigkeitsbeziehungen innerhalb von Funktionskörpern prüfen.
Wenn man zum Beispiel den Parameter oder die Variable foo hervorhebt, würde man dann nicht nur die direkte Verwendung von foo sehen, sondern gleichzeitig auch die Verwendung aller Variablen, die aus foo entstanden sind?
Rusts Borrow-Nutzung bildet diese Art von Nachverfolgung perfekt ab, aber so eine Visualisierung wäre auch für Code in anderen Sprachen sehr nützlich.
Ich denke, Flowistry wäre besonders wichtig für schwer wartbare Dateien in modernen Codebases wie Servos Flexbox-Layout-Code; diese Funktion ist übrigens mit über 400 Zeilen eine der unerquicklichsten Codedateien überhaupt.
(Ich kann mich irren, aber) üblicherweise nennt man so etwas „flow analysis“, und TypeScript führt das im Hintergrund aus, um Typen zu verfeinern.
Eine Visualisierungsfunktion gibt es aber nicht.
So etwas wird üblicherweise „program slicing“ genannt.
Ich halte das für ein sehr nützliches Tool, um Situationen auszugleichen, in denen nicht in einem Stil programmiert wird, der für Menschen leicht lesbar optimiert ist.
Der vorhandene Code ist nicht immer gut lesbar geschrieben, deshalb helfen solche Tools enorm.
Der Autor hat bei Rust East Coast ein Video eines Vortrags gezeigt, der das Plugin und die Forschung zu Routinen ausführlich behandelt.
Ich finde das eine wirklich coole Funktion, und Rust eignet sich dafür wegen seines Ownership-Systems, das Nebenwirkungen begrenzt.
Selbst wenn man so etwas an Python oder Ähnliches anhängt, kann dort zur Laufzeit jederzeit der Call Stack hinaufgestiegen und Speicher manipuliert werden, daher ist es nicht zu 100 % vertrauenswürdig.
Trotzdem ist es in den meisten Fällen korrekt, deshalb hoffe ich, dass solche Funktionen hinzugefügt werden.
Ich frage mich, ob es in TypeScript oder JavaScript ein ähnliches Tool gibt.
Sieht cool aus, aber statt es unbedingt „IDE“ zu nennen, wäre es vielleicht besser gewesen, es einfach ein VSCode-Plugin zu nennen.
Vermutlich weil „Visual Studio Code“ eine Marke von Microsoft ist; das Plugin läuft in allen Open-Source-basierten IDEs wie VSCodium, Cursor usw.
Auch in der Dokumentation wird es als IDE-Plugin bezeichnet.
Die Idee, den Fokus auf die wichtigen Teile des Codes zu lenken, scheint wirklich gut zu sein.
Ich frage mich, ob es etwas Ähnliches auch für JS/TS gibt.
Ich frage mich, wie es war, zur documentHighlight-LSP-Methode von rust-analyzer beizutragen.
Sie verhält sich ziemlich ähnlich zu dem, was im GIF gezeigt wird.
Für ein Plugin wirkt das wie eine zu spezifische Funktion.
Link zur betreffenden LSP-Spezifikation
Im README wird das erklärt; Details gibt es hier.
MIR (Mid-level Intermediate Representation) wird benötigt.
Ich habe mir so eine Funktion immer gewünscht und hätte gern auch gesehen, wie Datenpfade von außerhalb einer Funktion hereinkommen, also wer diese Funktion aufruft.
Ich denke, man könnte dabei vielleicht Daten des Compilers wiederverwenden.