Ich kann nicht genau sagen, welche Algorithmen von einer bestimmten Implementierung verwendet werden, aber ich kann einige fundierte Vermutungen anstellen. Ein Trie ist eine sehr nützliche Datenstruktur für dieses Problem: Die IDE kann einen großen Trie im Speicher aller Symbole in Ihrem Projekt mit einigen zusätzlichen Metadaten an jedem Knoten verwalten.
Wenn Sie ein Zeichen eingeben, geht es einen Pfad in der Trie entlang. Alle Nachkommen eines bestimmten Trie-Knotens sind mögliche Vervollständigungen. Die IDE muss dann nur diejenigen herausfiltern, die im aktuellen Kontext sinnvoll sind, aber sie muss nur so viele berechnen, wie im Popup-Fenster zum Ausfüllen der Registerkarten angezeigt werden können.
Eine erweiterte Tab-Vervollständigung erfordert einen komplizierteren Versuch. Beispielsweise verfügt Visual Assist X über eine Funktion, mit der Sie nur die Großbuchstaben von CamelCase-Symbolen eingeben müssen. Wenn Sie beispielsweise SFN eingeben, wird das Symbol SomeFunctionName
in seinem Fenster zum Ausfüllen der Registerkarten angezeigt.
Für die Berechnung des Versuchs (oder anderer Datenstrukturen) muss der gesamte Code analysiert werden, um eine Liste aller Symbole in Ihrem Projekt zu erhalten. Visual Studio speichert dies in seiner IntelliSense-Datenbank, einer .ncb
Datei, die neben Ihrem Projekt gespeichert ist, sodass nicht jedes Mal, wenn Sie Ihr Projekt schließen und erneut öffnen, alles neu analysiert werden muss. Wenn Sie zum ersten Mal ein großes Projekt öffnen (z. B. eines, das Sie gerade mit der Quellcodeverwaltung synchronisiert haben), nimmt sich VS die Zeit, um alles zu analysieren und die Datenbank zu generieren.
Ich weiß nicht, wie es mit inkrementellen Änderungen umgeht. Wie Sie sagten, wenn Sie Code schreiben, ist die Syntax in 90% der Fälle ungültig. Wenn Sie alles im Leerlauf reparieren, wird Ihre CPU mit einem sehr geringen Nutzen belastet, insbesondere wenn Sie eine von enthaltene Header-Datei ändern eine große Anzahl von Quelldateien.
Ich vermute, dass es entweder (a) nur dann repariert wird, wenn Sie Ihr Projekt tatsächlich erstellen (oder möglicherweise, wenn Sie es schließen / öffnen), oder (b) es eine Art lokales Parsen durchführt, bei dem der Code nur dort analysiert wird, wo Sie gerade sind in begrenzter Weise bearbeitet, nur um die Namen der relevanten Symbole zu erhalten. Da C ++ eine so außergewöhnlich komplizierte Grammatik hat, kann es sich in den dunklen Ecken merkwürdig verhalten, wenn Sie eine starke Metaprogrammierung für Vorlagen und dergleichen verwenden.