Specifying fortran 77 vs fortran 90 in vscode fortran server

Dear all,
I’m new with VS code.

I’m using it for a large project where the source is written in modern fortran inside *.F files, pre-processed with a FPP (fortran pre-processor) to generate *.f90 files, and then compiled with a FC (fortran compiler)

When opening the source *.F files with VScode and the Modern Fortran extension enabled, these are detected as fortran 77 sources and both the markup and the suggestions are all wrong.
I can easily change the file association to fix the murk-up, but still the suggestions (problems section inside vscode are all wrong). If I open instead the pre-processed output, which in this case is almost identical to the original file, it is all correct.

See image below. The .F file gets 130 nonsense error suggestions, while the .f90 just 1, which is indeed correct.

image

My understanding is that the association works only for the editor, and not for the fortran language server which generates the “problems”

Is there a way to specify that the .F file needs to be considered as a Fortran 90 source and not as a Fortran 77 source also to the fortran language server?

The one warning in PROBLEMS shown here contains diagnostics generated by the linter, probably GFortran, in your case, not the language server.

As you said changing the vscode association for .F from FixedForm (F77) → FreeForm (F90+) will fix a few of the errors. I would guess that the rest of your problems are related to the linter (GFortran) not being configured with the right preprocessor options. You’ll have to pass your options as to the linter as extra args (see Modern Fortran VS Code settings).

P.S. tha language server does not have an option to specify fixed or free form depending on the file extension. That’s because it can detect if a source file is fixed or free by parsing its syntax.

Ok, clear.

This is my settings.json file

{
    "files.associations": {
        "*.F": "FortranFreeForm",
        "*.f90": "FortranFreeForm"
    },
    "[FortranFreeForm]": {

    },
    "fortran.linter": "gfortran",
    "fortran.linter.executablePath": "/usr/local/bin/gfortran",
    "fortran.linter.includePaths": [ "${workspaceFolder}/**" ],
    "fortran.linter.extraArgs": ["-Wall", "-Wextra", "-pedantic", "-std=f2008"],
    "fortran.fortls.preprocessor.suffixes": [ ".F"]
}

As you can see I’m using fgortran. Is there a way to specify there that .F files need to be considered as Fortran 90 sources and not Fortran 77 sources ?

I don’t think this is your issue.

What options do you pass to fpp? That’s the stuff that needs to go into GFortran as part of the linting (otherwise it will generate wrong diagnostics).

A MWE of your preprocessed code would help.

Ok. I see you suggest to somehow explain to the linter the whole procedure my makefile is following. It might be a bit involved, this is why I was just hoping to tell the linter that *.F file are Fortran 90 sources.

This is my preprocessor
gfortran -E -P -cpp -D_HDF5_LIB -D_HDF5_IO -D_PAR_IO -D_MPI -D_FFTW -D_SLEPC -D_SCALAPACK -D_OPENMP -D_TIMING
How do I put this in my settings.json ?

Linters are just static analysis tools. In the case of Modern Fortran, they are actual compilers, so they need to know about your compile options. The setting you are looking for is fortran.linter.extraArgs. In that you should add your preproc args (["-D_HDF5_LIB", "-D_HDF5_IO", ...].

    "fortran.linter.extraArgs": [
        "-D_HDF5_LIB",
        "-D_HDF5_IO"
    ]

You should do the same with this option fortran.fortls.preprocessor.definitions, it would look like this:

    "fortran.fortls.preprocessor.definitions": {
        "_HDF5_LI": "",
        "_HDF5_IO": ""
    }

Make sure you have installed the Pre-Release of the Modern Fortran extension.

Ok, this is something I’m already in part using, and it would not change the fact that my .F file are treated as Fortran 70 sources by the linter.

See the errors below

As you can see there is nothing related to the preproc flags. It is even giving error because it does not recognize the definition
subroutine DIPOLE_shifted_grids(Xen,Xk,Dip)

I tried switching to the pre-release version. With it I do not get any “problem” even when they are there.

I switched back to the release version.
It is frustrating because that works just fine if I rename my .F files as .f90
I’d really just need to explain to the linters how to behave with my .F files, but I’m not able.

You should keep using the pre-release. Enable the Debug level logging. Your settings should look something like this, (adjust with your includes etc.)

{
    "fortran.fortls.preprocessor.definitions": {
        "_HDF5_LI": "",
        "_HDF5_IO": ""
    },
    "fortran.linter.extraArgs": [
        "-D_HDF5_LIB",
        "-D_HDF5_IO"
    ],
    "fortran.logging.level": "Debug",
    "files.associations": {
        "*.F": "FortranFreeForm",
    },

}

And post the Modern Fortran logs from the OUTPUT pane, mine look like this for a demo case.

[DEBUG - 13:50:34] [lint] arguments:
[
  "-ffree-line-length-none",
  "-ffixed-line-length-none",
  "-D_HDF5_LIB",
  "-D_HDF5_IO"
]
[DEBUG - 13:50:34] [lint] moduleOutput: -J /Users/gn/Library/Application Support/Code - Insiders/User/workspaceStorage/3a58b2bf4fff16e78874adb0590a6c39/fortran-lang.linter-gfortran/include
[DEBUG - 13:50:34] [lint] glob paths:
[]
[DEBUG - 13:50:34] [lint] resolved paths:
[]
[DEBUG - 13:50:34] [build.single] compiler: "gfortran" located in: "/opt/homebrew/bin/gfortran"
[INFO - 13:50:34] [build.single] Compiler query command line: /opt/homebrew/bin/gfortran -fsyntax-only -cpp -fdiagnostics-plain-output -ffree-line-length-none -ffixed-line-length-none -D_HDF5_LIB -D_HDF5_IO -J /Users/gn/Library/Application Support/Code - Insiders/User/workspaceStorage/3a58b2bf4fff16e78874adb0590a6c39/fortran-lang.linter-gfortran/include -ffree-form -o /Users/gn/Code/fortran-lang/fortls/demo.F.o /Users/gn/Code/fortran-lang/fortls/demo.F
[DEBUG - 13:50:34] [build.single] Compiler output:

[DEBUG - 13:50:34] [lint] No linting diagnostics to show

If looking at the log output does not help you trace the error with the user settings, you will have to provide a Minimal Working Example that reproduces the problem.

Ok, I’m trying again with the pre-release.

The issue with the pre-release might be this. Every time there is a symbolic link, I get the following error:

[DEBUG - 1:12:22 AM] [build.single] Compiler output:

f951: Fatal Error: '/home/sangalli/data/Codes/yambo/yambo-mine/features/shifted-grid/include/system/xc_version.h' is not a directory

compilation terminated.

Here xc_version.h is a link to the actual file, which is located somewhere else

Just to complete and close this thread. If I specify manually all the include folders it works. Instead if I use the syntax ${workspace}/**, if any of the folders inside ${workspace} contains a symbolic link the above mentioned error appears.

From what I understand, this is a bug of the plugin which excludes standard files but not symbolic links from the list of folder generated and passed to the linter. Specifying manually all the folder is a workaround for such bug.