• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1.. _showcase-sense-tutorial-intel:
2
3================================
44. Explore C++ code intelligence
5================================
6Sense's integration with :ref:`module-pw_ide` enables fast and accurate
7code navigation, autocompletion based on a deep understanding of the
8code structure, and instant compiler warnings and errors. Try intelligent
9code navigation features now:
10
11.. _showcase-sense-tutorial-intel-nav:
12
13-------------------------------
14Navigate the code intelligently
15-------------------------------
16Imagine this hypothetical development scenario. Suppose that you need
17to modify how your app logs messages. Your first task is to understand
18how logging currently works on the Pico 1. You know that your app uses
19:ref:`module-pw_log` and that ``pw_log`` uses a special type of API called
20a :ref:`facade <docs-facades>` where the implementation can be changed during
21compilation. The plan is to use the intelligent code navigation features of
22``pw_ide`` to determine the true, final implementation of the logging functions
23used in your project.
24
25.. _Command Palette: https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette
26
27.. tab-set::
28
29   .. tab-item:: VS Code
30      :sync: vsc
31
32      #. Press :kbd:`Control+Shift+P` (:kbd:`Command+Shift+P` on macOS) to open
33         the `Command Palette`_.
34
35      #. Start typing ``Pigweed: Select Code Analysis Target`` and press
36         :kbd:`Enter` to start executing that command.
37
38         .. figure:: https://storage.googleapis.com/pigweed-media/sense/20240802/target.png
39
40         .. tip::
41
42            You can also select code analysis targets from the bottom-left
43            of your VS Code GUI, in the status bar. In the next image,
44            the mouse cursor (bottom-left of image) is hovering over the GUI element
45            for selecting code analysis targets.
46
47            .. figure:: https://storage.googleapis.com/pigweed-media/sense/20240802/select_target_status_bar.png
48
49      #. Select the ``rp2040`` option.
50
51         The code intelligence is now set up to help you with physical Pico 1
52         programming. The RP2040 is the microprocessor that powers the Pico 1.
53         If you had selected the other option, ``host_simulator``,
54         the code intelligence would be set up to help with programming the
55         simulated app that you will run on your development host later.
56         Code intelligence for the Pico 2 (``rp2350``) isn't supported yet.
57         ``rp2040`` represents one platform, ``host_simulator`` another.
58
59         We will verify the platform-specific code intelligence now by making sure
60         that :ref:`module-pw_log` invocations resolve to different backends. This
61         will make more sense after you do the hands-on demonstration.
62
63      #. Open ``//apps/blinky/main.cc``.
64
65         .. figure:: https://storage.googleapis.com/pigweed-media/sense/blinky_main_v1.png
66
67      #. Right-click the ``PW_LOG_INFO()`` invocation and select
68         **Go to Definition**.
69
70         .. figure:: https://storage.googleapis.com/pigweed-media/sense/20240802/go_to_definition.png
71            :alt: Selecting "Go to Definition" after right-clicking PW_LOG_INFO()
72
73         This should take you to a file called ``log.h`` Your cursor should be
74         on the line that defines ``PW_LOG_INFO``:
75
76         .. code-block:: c++
77            :emphasize-lines: 2
78
79            #ifndef PW_LOG_INFO
80            #define PW_LOG_INFO(...) \  // Your cursor should be on this line.
81              PW_LOG(PW_LOG_LEVEL_INFO, PW_LOG_MODULE_NAME, PW_LOG_FLAGS, __VA_ARGS__)
82            #endif  // PW_LOG_INFO
83
84      #. Right-click the ``PW_LOG()`` invocation (on the line below your cursor)
85         and select **Go to Definition** again.
86
87         Your cursor should jump to the line that defines ``PW_LOG``:
88
89         .. code-block:: c++
90            :emphasize-lines: 2
91
92            // Your cursor should be on the next line.
93            #define PW_LOG(                                                            \
94                level, verbosity, module, flags, /* format string and arguments */...) \
95              do {                                                                     \
96                if (PW_LOG_ENABLE_IF(level, verbosity, module, flags)) {               \
97                  PW_HANDLE_LOG(level, module, flags, __VA_ARGS__);                    \
98                }                                                                      \
99              } while (0)
100
101      #. Finally, right-click the ``PW_HANDLE_LOG()`` invocation
102         and select **Go to Definition** one last time. You should jump to
103         a :ref:`module-pw_log_tokenized` backend header. You can hover
104         over the filename in the tab (``log_backend.h``) to see the full
105         path to the header.
106
107         .. code-block: c++
108
109            #define PW_HANDLE_LOG PW_LOG_TOKENIZED_TO_GLOBAL_HANDLER_WITH_PAYLOAD
110
111      #. Open the Command Palette, switch your target to ``host_simulator``,
112         and then repeat this workflow again, starting from the ``PW_LOG_INFO``
113         invocation in ``//apps/blinky/main.cc``. You should see the definitions finally
114         resolve to a :ref:`module-pw_log_string` backend header.
115
116   .. tab-item:: CLI
117      :sync: cli
118
119      This feature is only supported in VS Code.
120
121.. _showcase-sense-tutorial-intel-explanation:
122
123-----------
124Explanation
125-----------
126When you set your platform to ``rp2040`` and followed the call to
127``PW_LOG_INFO()`` in ``//apps/blinky/main.cc`` back to its source,
128you ended on a header within ``pw_log_tokenized``. When you repeated
129the process a second time with the ``host_simulator`` platform you
130ended on a header in a different module, ``pw_log_string``. This proves
131that intelligent code navigation is working. The ``pw_log`` API is a
132:ref:`facade <docs-facades>`. It's implementation is swapped out during
133compilation depending on what platform you're building for. The ``rp2040``
134platform has been set up to use the ``pw_log_tokenized`` implementation, whereas
135the ``host_simulator`` platform uses the ``pw_log_string`` implementation.
136
137Here's a diagram summary of how the intelligent code navigation resolved to
138different files depending on the code analysis target you selected:
139
140.. mermaid::
141
142   flowchart LR
143
144     a["main.cc"] --> b["log.h"]
145     b["log.h"] -. rp2040 .-> c["pw_log_tokenized/.../log_backend.h"]
146     b["log.h"] -. host_simulator .-> d["pw_log_string/.../log_backend.h"]
147
148.. _showcase-sense-tutorial-intel-summary:
149
150-------
151Summary
152-------
153Portable, hardware-agnostic software abstractions such as :ref:`module-pw_log`
154make it easier to reuse code across projects and hardware platforms. But they
155also make it more difficult to correctly navigate references in your codebase.
156The Pigweed extension for VS Code can solve this problem; you just need to
157tell it what hardware platform within your codebase to focus on.
158
159Next, head over to :ref:`showcase-sense-tutorial-hosttests` to learn how to run
160unit tests on your development host.
161