xref: /aosp_15_r20/external/pigweed/pw_ide/guide/vscode/code_intelligence.rst (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1.. _module-pw_ide-guide-vscode-code-intelligence:
2
3=================
4Code intelligence
5=================
6.. pigweed-module-subpage::
7   :name: pw_ide
8
9The Pigweed Visual Studio Code extension bridges Bazel and ``clangd`` to provide
10the smoothest possible C++ embedded development system. For background on the
11tools and approaches Pigweed uses, check out the :ref:`design docs<module-pw_ide-design-cpp>`.
12This doc is a user guide to the way those concepts are applied in Visual Studio
13Code.
14
15-------------------------
16Configuring target groups
17-------------------------
18In Bazel projects, :ref:`target groups<module-pw_ide-design-cpp-target-groups>`
19are defined in a top-level ``BUILD.bazel`` file with something like this:
20
21.. code-block::
22
23   refresh_compile_commands(
24     name = "refresh_compile_commands",
25     out_dir = ".compile_commands",
26     target_groups = {
27       "host_simulator": [
28         "//apps/blinky:simulator_blinky",
29         "//apps/production:simulator",
30         "//modules/blinky:blinky_test",
31         "//modules/buttons:manager_test",
32       ],
33       "test_only": "//tests/test:run_tests",
34       "dev_board": [
35          ["//apps/blinky:dev_board_blinky.elf", "--config=dev_board"],
36          ["//apps/factory:dev_board.elf", "--config=dev_board"],
37          ["//apps/production:dev_board.elf", "--config=dev_board"],
38       ],
39     },
40   )
41
42Each target group should contain one or more targets that are "related", in the
43sense that they are pertinent to the way code is compiled for a particular
44platform. For example, as in the example above, it's common to have at least two
45target groups, one for code running on target, and one for code running on host.
46
47As the example illustrates, each target group's value can be either:
48
49* A single string target name
50* A list/array of target names
51* A list/array of tuples, where the first value is the target name and the
52  second value contains build flags
53
54.. tip::
55
56   The name of the Bazel target that refreshes compile commands can be set to
57   whatever you want via the ``name`` attribute. Just make sure to update the
58   :ref:`corresponding editor setting<module-pw_ide-guide-vscode-settings-refresh-compile-commands-target>`
59   so that the Pigweed extension knows which target to run.
60
61.. warning::
62
63   The order of the targets in each target group matters, as it dictates the
64   ordering of the compile commands in the resulting compilation database.
65   ``clangd`` will use the *first* relevant compile command it encounters to
66   provide code intelligence for a particular file. So if a target group
67   contains two targets that build the same file in different ways, the way
68   the first listed target builds the file will dictate how ``clangd``
69   interprets the file.
70
71----------------------------------------------
72Selecting a target group for code intelligence
73----------------------------------------------
74The currently-selected code intelligence target group is displayed in the
75Visual Studio Code status bar:
76
77.. figure:: https://storage.googleapis.com/pigweed-media/vsc-status-bar-target.png
78   :alt: Visual Studio Code screenshot showing the target status bar item
79
80You can click the status bar item to select a new target group from a dropdown
81list at the top of the screen.
82
83.. figure:: https://storage.googleapis.com/pigweed-media/vsc-dropdown-select-target.png
84   :alt: Visual Studio Code screenshot showing the target selector
85
86------------------------------------
87Keeping code intelligence data fresh
88------------------------------------
89As you work on your project, the build graph will change, new compilation
90databases will need to be built, and ``clangd`` will need to be re-configured
91to provide accurate code intelligence.
92
93The Pigweed extension handles this for you automatically. Whenever you make a
94change that could alter the build graph, a background process is launched to
95regenerate fresh compile commands. You'll see the status bar icon change to
96look like this while the refresh process is running, and during that time, you
97can click on the status bar item to open the output window and monitor progress.
98
99.. figure:: https://storage.googleapis.com/pigweed-media/vsc-status-bar-refreshing.png
100   :alt: Visual Studio Code screenshot showing the target status bar item
101         refreshing
102
103When the refresh process is complete, the status bar item will look like this:
104
105.. figure:: https://storage.googleapis.com/pigweed-media/vsc-status-bar-finished.png
106   :alt: Visual Studio Code screenshot showing the target status bar item in the
107         finished state
108
109.. tip::
110
111   In most cases, you don't have to wait around for the refresh process to
112   finish to keep working. You can still switch between targets, and code
113   intelligence still works (though it may be a little stale for any files
114   affected by the change that triggered the refresh).
115
116No automatic process is perfect, and if an error occurs during the refresh
117process, that will be indicated with this icon in the status bar:
118
119.. figure:: https://storage.googleapis.com/pigweed-media/vsc-status-bar-fault.png
120   :alt: Visual Studio Code screenshot showing the target status bar item in an
121         error state
122
123You can click the status bar item to trigger a retry, or you can
124:ref:`open the output panel<module-pw_ide-guide-vscode-commands-open-output-panel>`
125to get more details about the error.
126
127.. note::
128
129   * You can always trigger a manual compilation database refresh by running
130     :ref:`Pigweed: Refresh Compile Commands<module-pw_ide-guide-vscode-commands-refresh-compile-commands>`.
131
132   * If you don't want to use the automatic refresh process, you can
133     :ref:`disable it<module-pw_ide-guide-vscode-settings-disable-compile-commands-file-watcher>`.
134
135----------------------------------
136Inactive and orphaned source files
137----------------------------------
138As discussed in the :ref:`design docs<module-pw_ide-design-cpp>`, some source
139files will be compiled in several different targets, possibly with different
140compiler and linker options. Likewise, some files may not be compiled as part
141of a particular selected target, perhaps because the file is not relevant to
142the target (for example, hardware support implementations for a host simulator
143target). Finally, some source files may not be compiled by *any* defined target
144group, either because those files have not yet been brought into the build
145graph, or because none of the defined target groups contain a target that builds
146that source file.
147
148We need to care about this because ``clangd`` tries to be helpful in a way that
149is very counterproductive in Pigweed projects: If it encounters a file but
150cannot find a corresponding compile command in the compilation database, it
151will *infer* a compile command for that file from other similar files that *are*
152in the compilation database.
153
154Since the compilation databases that Pigweed generates are specifically
155engineered to only include compile commands pertinent to the selected target
156group, the *inferred* code intelligence ``clangd`` provides for other files
157is invalid. So the Pigweed extension provides mechanisms to exclude those files
158from ``clangd`` and prevent misleading code intelligence information.
159
160.. glossary::
161
162   Active source file
163     A source file that is built in the currently-selected target group
164
165   Inactive source file
166     A source file that is *not* built in the currently-selected target group
167
168   Orphaned source file
169     A source file that is not built by *any* defined target groups
170
171Disabling ``clangd`` for inactive and orphaned files
172====================================================
173By default, Pigweed will disable ``clangd`` for inactive and orphaned files to
174prevent inaccurate and distracting information from appearing in the editor.
175You can see that ``clangd`` is disabled for those files when you see this icon
176in the status bar:
177
178.. figure:: https://storage.googleapis.com/pigweed-media/vsc-inactive-clangd-disabled.png
179   :alt: Visual Studio Code screenshot showing code intelligence disabled for
180         inactive files
181
182You can click the icon to *enable* ``clangd`` for all files, regardless of
183whether they are in the current target's build graph or not. That state will be
184indicated with this icon:
185
186.. figure:: https://storage.googleapis.com/pigweed-media/vsc-inactive-clangd-enabled.png
187   :alt: Visual Studio Code screenshot showing code intelligence enabled for
188         inactive files
189
190You can click it again to toggle it back to the default state.
191
192File status indicators
193======================
194The Visual Studio Code explorer (file tree) displays an indicator next to
195inactive and orphaned files to help you understand which files will not have
196code intelligence. These indicators will change as you change targets and as
197you change the build graph.
198
199.. figure:: https://storage.googleapis.com/pigweed-media/vsc-inactive-file-indicators.png
200   :alt: Visual Studio Code screenshot file indicators for inactive and
201         orphaned files
202   :figwidth: 250
203
204Inactive files are indicated like this:
205
206.. figure:: https://storage.googleapis.com/pigweed-media/vsc-inactive-file-indicators-inactive.png
207   :alt: Visual Studio Code screenshot file indicators for inactive files
208   :figwidth: 250
209
210Orphaned files are indicated like this:
211
212.. figure:: https://storage.googleapis.com/pigweed-media/vsc-inactive-file-indicators-orphaned.png
213   :alt: Visual Studio Code screenshot file indicators for orphaned files
214   :figwidth: 250
215
216Note that the colors may vary depending on your Visual Studio Code theme.
217
218.. tip::
219
220   By default, file status indicators will be shown even if ``clangd`` is
221   enabled for all files. You can change this behavior with
222   :ref:`this setting<module-pw_ide-guide-vscode-settings-hide-inactive-file-indicators>`.
223