Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"Go to Definition" sometimes leads to declaration instead of definition #167

Open
3 tasks done
ZedOud opened this issue Sep 16, 2023 · 4 comments
Open
3 tasks done
Labels
type: imperfection Perceived defect in any part of project

Comments

@ZedOud
Copy link

ZedOud commented Sep 16, 2023

Describe the problem

In the context menu that opens when you right-click on an Arduino IDE editor view, we have two references to "Definitions":

  • Go to Definition
  • Peek > Peek Definition

However, these options, respectively, bring you to the subject's declaration in the relevant header file or shows a preview of its declaration in the relevant header.

Rarely, though, a "declaration that is also a definition" might be seen in the header (to loosely quote [this reference])(https://learn.microsoft.com/en-us/cpp/cpp/declarations-and-definitions-cpp?view=msvc-170#definitions). Though, except for one-liners, this is rare in the header. We can safely state that this feature only, at least functionally, results in declarations.

I thought I was doing something incorrectly: something wrong with my board packages, or with my libraries. However this occurs many boards I tried, even with the Arduino Uno, and it occurs for the default libraries and other widely used libraries.

I figured I must be operating the feature incorrectly, as I assumed I should be able to reach the Definition.

After a few hours investigating this, and looking through the Issues, I can only conclude that this is a typo, as either:

  • The intended result is to reach the declaration instead of the definition, or
  • There exists some developmental intention in the future for this to indeed reach the definition, but that functionality is not yet possible, or
  • Some mistake has been made.

Thank you for your time. I hope this minor bug can be resolved.

To reproduce

  1. Right-click a symbol, especially a function.
    A context menu will open.
  2. Select "Go to Definition" from the menu.

🐛 You are taken to the declaration of the symbol; not the definition as promised.

Expected behavior

I would expect to see a definition, not just a declaration, which would take me to a .cpp file instead of a .h file.

Arduino IDE version

2.2.2-nightly-20230916

Operating system

macOS

Operating system version

13.5.2

Additional context

Additional reports

Issue checklist

  • I searched for previous reports in the issue tracker
  • I verified the problem still occurs when using the latest nightly build
  • My report contains all necessary details
@ZedOud ZedOud added the type: imperfection Perceived defect in any part of project label Sep 16, 2023
@per1234 per1234 self-assigned this Sep 17, 2023
@per1234
Copy link
Contributor

per1234 commented Sep 17, 2023

Hi @ZedOud. Please add a comment here that provides detailed instructions I can follow to reproduce the problem.


Here is an example of the sort of instructions I need:

  1. Create the following sketch:
    void setup() {
      pinMode(LED_BUILTIN, OUTPUT);
    }
    void loop() {}
  2. Select Tools > Board > Arduino AVR Boards > Arduino Uno from the Arduino IDE menus.
  3. Wait for the sketch processing to finish, as indicated by the disappearance of the messages from the left side of the status bar.
  4. Right click on the pinMode call at line 2.
    A context menu will open.
  5. Select "Go to Definition" from the context menu.

If I follow the above instructions, I am taken to the definition of pinMode in wiring_digital.c, not to the declaration in Arduino.h. So everything is working as expected for me with that procedure.


Something to note is that the clangd C++ language server that provides the "context aware" features like "Go to Definition" for Arduino IDE falls back to the declaration when the definition is not available:

https://github.com/llvm/llvm-project/blob/llvmorg-14.0.0/clang-tools-extra/clangd/ClangdLSPServer.cpp#L1111

An example of when the definition would not be available is when the implementation is in a precompiled object file. This is done in some cores and libraries in order to reduce the initial compilation time which might be quite considerable in the case of the very significant quantities of code that are present in some of the more advanced cores (e.g., Arduino Mbed OS boards) and libraries (e.g., Arduino_TensorFlowLite).


There is also a "toggle" implemented that causes it to switch between the definition and declaration:

https://github.com/llvm/llvm-project/blob/llvmorg-14.0.0/clang-tools-extra/clangd/ClangdLSPServer.cpp#L1079-L1097

I'm actually not experiencing that toggling behavior when following the steps I describe above. I consistently get the definition even when I trigger a "Go to Definition" repeatedly on the pinMode call. I do remember encountering it at some point in the past.

@per1234 per1234 added the status: waiting for information More information must be provided before work can proceed label Sep 17, 2023
@ZedOud ZedOud closed this as completed Sep 19, 2023
@ZedOud
Copy link
Author

ZedOud commented Sep 19, 2023

Hi @per1234
This is fascinating. There is too much variation and not enough signals for me to understand the pattern of failure. I had tested many examples, but none of the included/default ones like pinMode.
I attempted a few more examples:
library -> object -> destination

  • Arduino global namespace -> pinMode -> goes to wiring_digital.c
  • Servo -> Servo.write -> Servo.h
  • Adafruit NeoPixel -> Adafruit_NeoPixel.begin -> Adafruit_NeoPixel.h
  • Ponoor PowerSTEP01 Library -> powerSTEP.setPWMFreq -> Ponoor_PowerSTEP01Library.h
  • Simple FOC -> BLDCMotor.move -> BLDCMotor.h

These were tested with the Uno selected.
It seems like only a very limited number of lookups go to the definition.
Each of the libraries I tested have their .h and .cpp or .c files included, I didn't see any of them include the mentioned precombiled binary files, unless they are not stored with the rest of the library's files?

P.S. accidentally misclicked it as "closed"

@ZedOud ZedOud reopened this Sep 19, 2023
@ZedOud
Copy link
Author

ZedOud commented Sep 21, 2023

I don't know if I can provide any more information. It seems evident that most libraries, and all of those I've tried, move to the declaration.

The only exception seems to be for the global namespace, which I'm not sure if that is what it is precisely called in Arduino C++, but I mean keywords like pinMode.

@per1234 per1234 changed the title Typo: Mix-up between "Definition" and "Declaration" "Go to Definition" sometimes leads to declaration instead of definition Sep 21, 2023
@per1234 per1234 removed the status: waiting for information More information must be provided before work can proceed label Sep 21, 2023
@per1234 per1234 transferred this issue from arduino/arduino-ide Sep 21, 2023
@per1234
Copy link
Contributor

per1234 commented Sep 21, 2023

The problem seems to be specific to libraries. Here is a minimal reproduction:

Sketch:

#include <Foo.h>
void setup() {
  foo();
}
void loop() {}

Library:

Foo.h:

void foo();

Foo.cpp:

void foo() {}

Trigger a "Go to Definition" (textDocument/definition) on the foo call in the sketch and you are taken to the foo declaration in Foo.h.

But if you move Foo.h and Foo.cpp to the sketch folder and adjust the #include directive in the sketch accordingly (#include "Foo.h") then the same operation takes you to the definition of foo in Foo.cpp as expected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: imperfection Perceived defect in any part of project
Projects
None yet
Development

No branches or pull requests

2 participants