特定の実装でどのアルゴリズムが使用されているかは正確にはわかりませんが、ある程度の推測はできます。トライは、この問題に非常に役立つデータ構造です。IDE は、プロジェクト内のすべてのシンボルのメモリに大きなトライを保持し、各ノードに追加のメタデータを追加できます。
文字を入力すると、トライのパスをたどります。特定のトライ ノードのすべての子孫は、可能な補完です。その後、IDE は、現在のコンテキストで意味のあるものによってそれらを除外する必要がありますが、タブ補完ポップアップ ウィンドウに表示できる数だけ計算する必要があります。
より高度なタブ補完には、より複雑な試行が必要です。たとえば、Visual Assist Xには、キャメルケース記号の大文字のみを入力する必要があるという機能があります。たとえば、SFN と入力するとSomeFunctionName
、タブ補完ウィンドウに記号が表示されます。
トライ (または他のデータ構造) を計算するには、すべてのコードを解析して、プロジェクト内のすべてのシンボルのリストを取得する必要があります。Visual Studio はこれを、.ncb
プロジェクトと共に保存されるファイルである IntelliSense データベースに保存するため、プロジェクトを閉じて再度開くたびにすべてを再解析する必要はありません。大規模なプロジェクト (たとえば、ソース管理から同期したばかりのプロジェクト) を初めて開くと、VS はすべてを解析してデータベースを生成するのに時間がかかります。
増分変更をどのように処理するかわかりません。あなたが言ったように、コードを書いているときは、90% の確率で無効な構文であり、アイドル状態になるたびにすべてを再解析すると、CPU に莫大な負担がかかり、ほとんどメリットがありません。大量のソース ファイル。
(a) プロジェクトを実際にビルドするとき (または、プロジェクトを閉じたり開いたりするとき) にのみ再解析するか、(b) ローカル解析のようなものを実行して、その周辺のコードのみを解析するかのいずれかであると思われます。関連するシンボルの名前を取得するためだけに、いくつかの限られた方法で編集されました。C++ は非常に複雑な文法を持っているため、大量のテンプレート メタプログラミングなどを使用している場合、隅々までおかしな動作をする可能性があります。