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

Variable definition from C++ header #115

Open
JayPBe opened this issue Jun 7, 2019 · 7 comments
Open

Variable definition from C++ header #115

JayPBe opened this issue Jun 7, 2019 · 7 comments

Comments

@JayPBe
Copy link

JayPBe commented Jun 7, 2019

Hello,
I am currently using the Geany editor to work on a large fortran project and wanted to try out the fortran language server in conjunction with VS Code as an alternative.

I have everything set up now, but I am having problems due to our specific project structure. Most subroutines have statements of the type
#include declarations.h
or
#include common_constants.h
i.e. C++ header files with type declarations or global variables are included.

Firstly, VS Code is unable to jump to these .h files via "go to definition" or "strg+left click" from these #include statements within a .f90 file. It further shows a "No such file or directory" message under the problems tabs in VS Code. (Although the .h files are all within the workspace folder).
I imagine this is because the language server is not parsing non-fortran files? Is there any way to still obtain the desired behavior?

Secondly, inside these header files data types are defined. They follow the pattern _<FortranType>4us_, i.e. we could have a line
#define _real4us_ real*8
in the .h header file and a definition
_real4us_ :: x,y
in a f90 fortran source file. In this case jumping to the definition or getting information from hovering over x and y will not be possible. I imagine retrieving the definitions from the ".h" files would be very complicated. Alternatively, it would help me a great deal if I could manually add all necessary _<FortranType>4us_ types and enable the definition feature for them.

I hope that the above issues are actually related to the language server and not VS Code or the modern fortran extension. If not, please refer me to the correct location to post my questions.

Thanks in advance.

@JayPBe JayPBe changed the title Variable definition from C header Variable definition from C++ header Jun 7, 2019
@hansec
Copy link
Owner

hansec commented Jun 7, 2019

Currently, #include statements are not supported. This is probably my next big project to add, but I haven't had the time yet. This will certainly prevent objects defined in those files from being found. I am not sure about the "No such file or directory" messages, but I will look in to that while adding support for #include statements. Although, I have no reason to think it should work for *.h files now.

As for the preprocessor definitions, you can define these globally as you would in compile commands. So if they are the same for the entire project that should be a decent work around in the interim. For example to define the case you gave above you would add the following to your .fortls file for that project.

"pp_defs": {"_real4us_": "real*8"}

@JayPBe
Copy link
Author

JayPBe commented Jun 7, 2019

Currently, #include statements are not supported. This is probably my next big project to add, but I haven't had the time yet. This will certainly prevent objects defined in those files from being found. I am not sure about the "No such file or directory" messages, but I will look in to that while adding support for #include statements. Although, I have no reason to think it should work for *.h files now.

Perfect. Thank you!
I'm not really reliant on that, since geany couldn't do that either. Just a nice feature to have.

As for the preprocessor definitions, you can define these globally as you would in compile commands. So if they are the same for the entire project that should be a decent work around in the interim. For example to define the case you gave above you would add the following to your .fortls file for that project.

"pp_defs": {"_real4us_": "real*8"}

I have tested that, if I were to rename all the files in our project from .f90 to .F90, this would be a perfect workaround for now. I would, however, rather not do the renaming. Is there any specific reason for the restriction to all caps file endings? Or is there any way for me to include .f90 files in the preprocessing?

@hansec
Copy link
Owner

hansec commented Jun 7, 2019

Ah, I see. Yes, that was chosen because by default this is how most compilers handle preprocessing for Fortran files (ex. gcc). I will also add an option to allow you to specify any suffix for preprocessing.

hansec added a commit that referenced this issue Jun 13, 2019
- Limited to preprocessing only (no Fortran objects)
- Update README formatting
@hansec
Copy link
Owner

hansec commented Jun 13, 2019

I just pushed some changes up to the next version branch (see above) to work towards adding this functionality. The v1.10 branch should now support all preprocessing elements of header files, but declaration of fortran objects in header files is not yet supported (ie. statements like real(8) :: header_defined_var). When you get a chance take a look and let me know if this improves the functionality for you and if you notice any issues. Thanks!

@JayPBe
Copy link
Author

JayPBe commented Jun 18, 2019

Thanks a lot for the fast changes!

I checked the commit 7a8ccd9 and the problem due to non-caps file names is solved. I can now jump to definitions or get information on hovering for variable types which I added via "pp_defs" in the .fortls file.

I didn't have the time yet to take a look at the changes in 7697fcd though.

@mscfd
Copy link

mscfd commented Jun 28, 2019

@JayPBe: Just an additional note, which might or might not helpful. We have a very similar naming scheme, and I simply maintain a oneline patch, so that fortls thinks that real4us is a type. This has the advantage that the editor really shows real4us and not real(8). (We have several real4xyz macros, and I want to see the type name, not the kind number.)

Here is an example oneline patch (copy from git diff output):

modified   fortls/parse_fortran.py
@@ -59,7 +59,7 @@ GEN_ASSIGN_REGEX = re.compile(r'(ASSIGNMENT|OPERATOR)\(', re.I)
 END_TYPED_WORD = r'TYPE'
 ENUM_DEF_REGEX = re.compile(r'[ ]*ENUM[, ]+', re.I)
 END_ENUMD_WORD = r'ENUM'
-NAT_VAR_REGEX = re.compile(r'[ ]*(INTEGER|REAL|DOUBLE[ ]*PRECISION|COMPLEX'
+NAT_VAR_REGEX = re.compile(r'[ ]*(_integer4us_|_real4us_|_real4them_|INTEGER|REAL|DOUBLE[ ]*PRECISION|COMPLEX'
                            r'|DOUBLE[ ]*COMPLEX|CHARACTER|LOGICAL|PROCEDURE'
                            r'|EXTERNAL|CLASS|TYPE)', re.I)
 KIND_SPEC_REGEX = re.compile(r'([ ]*\([ ]*[a-z0-9_*:]|\*[0-9:]*)', re.I)

@JayPBe
Copy link
Author

JayPBe commented Jun 28, 2019

@JayPBe: Just an additional note, which might or might not helpful. We have a very similar naming scheme, and I simply maintain a oneline patch, so that fortls thinks that real4us is a type. This has the advantage that the editor really shows real4us and not real(8). (We have several real4xyz macros, and I want to see the type name, not the kind number.)

Here is an example oneline patch (copy from git diff output):

modified   fortls/parse_fortran.py
@@ -59,7 +59,7 @@ GEN_ASSIGN_REGEX = re.compile(r'(ASSIGNMENT|OPERATOR)\(', re.I)
 END_TYPED_WORD = r'TYPE'
 ENUM_DEF_REGEX = re.compile(r'[ ]*ENUM[, ]+', re.I)
 END_ENUMD_WORD = r'ENUM'
-NAT_VAR_REGEX = re.compile(r'[ ]*(INTEGER|REAL|DOUBLE[ ]*PRECISION|COMPLEX'
+NAT_VAR_REGEX = re.compile(r'[ ]*(_integer4us_|_real4us_|_real4them_|INTEGER|REAL|DOUBLE[ ]*PRECISION|COMPLEX'
                            r'|DOUBLE[ ]*COMPLEX|CHARACTER|LOGICAL|PROCEDURE'
                            r'|EXTERNAL|CLASS|TYPE)', re.I)
 KIND_SPEC_REGEX = re.compile(r'([ ]*\([ ]*[a-z0-9_*:]|\*[0-9:]*)', re.I)

Thank you for this great suggestion. Works like a charm and I think I even prefer this over the previous workaround!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants