Je ne peux pas dire exactement quels algorithmes sont utilisés par une implémentation particulière, mais je peux faire des suppositions éclairées. Un trie est une structure de données très utile pour ce problème: l'EDI peut conserver un grand trie en mémoire de tous les symboles de votre projet, avec quelques métadonnées supplémentaires à chaque nœud.
Lorsque vous tapez un caractère, il emprunte un chemin dans le trie. Tous les descendants d'un nœud de trie particulier sont des complétions possibles. L'EDI a alors juste besoin de filtrer ceux qui ont du sens dans le contexte actuel, mais il a seulement besoin d'en calculer autant que possible dans la fenêtre contextuelle de complétion des onglets.
La complétion par tabulation plus avancée nécessite un tri plus compliqué. Par exemple, Visual Assist X a une fonction dans laquelle vous n'avez qu'à taper les lettres majuscules des symboles CamelCase - par exemple, si vous tapez SFN, il vous montre le symbole SomeFunctionName
dans sa fenêtre de complétion par tabulation.
Le calcul du trie (ou d'autres structures de données) nécessite l'analyse de tout votre code pour obtenir une liste de tous les symboles de votre projet. Visual Studio le stocke dans sa base de données IntelliSense, un .ncb
fichier stocké à côté de votre projet, afin qu'il n'ait pas à tout analyser à chaque fois que vous fermez et rouvrez votre projet. La première fois que vous ouvrez un grand projet (par exemple, celui que vous venez de synchroniser avec le contrôle de code source), VS prendra le temps de tout analyser et de générer la base de données.
Je ne sais pas comment il gère les changements incrémentiels. Comme vous l'avez dit, lorsque vous écrivez du code, sa syntaxe est invalide 90% du temps, et tout réanalyser chaque fois que vous êtes inactif imposerait une énorme taxe sur votre processeur pour très peu d'avantages, surtout si vous modifiez un fichier d'en-tête inclus par un grand nombre de fichiers source.
Je soupçonne que soit (a) il ne répète que chaque fois que vous construisez votre projet (ou peut-être lorsque vous le fermez / ouvrez), ou (b) il effectue une sorte d'analyse locale où il analyse uniquement le code là où vous venez de édité de manière limitée, juste pour obtenir les noms des symboles pertinents. Étant donné que C ++ a une grammaire extrêmement compliquée, il peut se comporter de manière étrange dans les coins sombres si vous utilisez une métaprogrammation de modèles lourds, etc.