hansec / fortran-language-server

Fortran Language Server for the Language Server Protocol
MIT License
294 stars 57 forks source link

Code in #ifdef not linted (preprocessor variable not defined) #225

Closed jphaupt closed 2 years ago

jphaupt commented 2 years ago

Hi, thanks for the very useful software. I am currently using it in conjunction with the Modern Fortran VS Code extension. Sorry if this is not correctly reported -- perhaps it should be in that repo.

However, I am running into the following problem: Say, I have code like the following:

#ifdef ENABLE_MPI
! some code goes here, gets ignored
#else 
! some code goes here, and gets linted
#endif

then the linter simply ignores everything in the guards. E.g. if I have a integer :: ierr declared outside, it will be detected as unused, or if I write complete nonsense it doesn't detect it as such (so it seems like there is no linting there -- there will be linting in the #else block though). Hence, it seems the variables are just not defined. I tried adding "pp_defs": {"ENABLE_MPI": "ON"} to the .fortls file, which I understood to be the solution based on the documentation (and this would be pretty close to the C/C++ extension's solution), but this doesn't solve the problem either.

This variable is defined through CMake in my case. Is there some way to make this work? The docs also mention "Preprocessor definitions are normally included via INCLUDE_DIRS" -- what would that look like for this?

Minimal example:

program example
    implicit none
#ifdef ENABLE_MPI
    I can write whatever I want here without consequence
#else
    ! this actually gets understood
    integer :: i
    i = 10
#endif
! this is no problem, but should be invalid if ENABLE_MPI defined
    print*, i
end program example
gnikit commented 2 years ago

Hi, you need to pass you preprocessor values to the linter, since you are using CMake you will have to pass in the extraAgs the "-DHAVE_MPI", the option you are looking for is "fortran.linter.extraArgs": ["-DENABLE_MPI"],

For future reference, the linter is from the Modern Fortran extension: https://github.com/fortran-lang/vscode-fortran-support not the language server. Also, and this is quite important, fortran-language-server is not supported in Modern Fortran, only fortls. We will update the links in the README for people to file things easier, but when in doubt ask your question in the VS Code extension repo as a Discussion Q&A and we will point you in the right direction.

gnikit commented 2 years ago

The docs also mention "Preprocessor definitions are normally included via INCLUDE_DIRS" -- what would that look like for this?

A lot of times programs define their preprocessor variables in a header file to keep track of what is enabled/disabled. This is very common with autotools and manually written Makefiles, however, not so common with CMake.

jphaupt commented 2 years ago

Thanks @gnikit, that's exactly what I was looking for. Sorry I had a hard time trying to find this option yesterday, but I suppose it really is that easy. Noted about the VS Code Q&A.