ionide-vscode-fsharp icon indicating copy to clipboard operation
ionide-vscode-fsharp copied to clipboard

Source files autogenerated by tools during build are not scanned for definitions

Open Arshia001 opened this issue 3 years ago • 13 comments

Describe the bug**

Some libraries generate source files during the build process by using MSBuild targets. These generated files are not scanned for definitions, and any usage of types contained in those files is reported as an error.

Steps to reproduce

  1. Create a new project.
  2. Reference any library which generates code. The Grpc-FSharp.Tools package in Arshia001/FSharp.GrpcCodeGenerator is one such project. This problem was in fact first reported in Arshia001/FSharp.GrpcCodeGenerator#5.
  3. Use one of the generated types in a source file. Ionide reports an error saying The value, namespace, type or module 'XXXX' is not defined. F# Compiler(39)

Expected behaviour

The autogenerated files should be scanned and their types made available.

Machine info

  • OS: Windows 10, Ubuntu Desktop, Arch Linux
  • .NET SDK version: 5.0.203
  • Ionide version: 5.5.5

Additional context

There looks to be a problem with how Ionide interacts with MSBuild, since running the right MSBuild targets should generate such files and add them to Compile, which Ionide can then pick up.

(One could argue that code generation is not the best approach for F#, and that type providers should be used instead. While this is a perfectly valid argument, source code ported from C# takes much more effort to turn into a type provider.)

This issue can be worked around by referencing the generated source in the fsproj directly, but with a Condition that evaluates to true for Ionide and false for the build process. However, I know of no MSBuild properties that can be used for this purpose.

Arshia001 avatar May 18 '21 17:05 Arshia001

Hey @Arshia001 :wave:,

Thank you for opening an issue. We will get back to you as soon as we can. Also, check out our OpenCollective and consider backing us.

https://opencollective.com/ionide

PS.: We offer backer support for all backers. Don't forget to add backer label when you start backing us :smile:

We should be well equipped to handle this, as we do already do design-time builds during project cracking to ensure that we're as close to a 'real' compiler as possible. If possible, could you get a structured build log by setting the Ionide settings for build logs and uploading that result? NOTE: env variables are uploaded as part of this, so if you have secrets in your env variable then maybe don't do this and instead wait for someone to diagnose your project.

baronfel avatar May 18 '21 17:05 baronfel

Thanks for the quick response!

I'll recreate the problem in a minimal project and upload the binlog and the project itself ASAP.

Arshia001 avatar May 18 '21 18:05 Arshia001

@baronfel I uploaded a minimal reproduction here: https://github.com/Arshia001/Ionide-1535-repro.

The repository also contains an msbuild.binlog which I hope I generated correctly, and a debug log of an actual build in the build-log file. To find the targets the library adds, look for Grpc-FSharp.Tools.dll around line 2638.

I'm on a company laptop, so I had to create the logs inside a container to ensure isolation. I'm pretty sure that shouldn't make a difference since we've already seen this issue on all major platforms, but I thought I'd let you know in case it does make a difference.

Arshia001 avatar May 18 '21 20:05 Arshia001

So it's a bit hairy, but one different I notice between Ionide and the CLI build's binlog is that in the Ionide binlog, there's no Evaluation Phase at all. This is important because the Evaluation Phase is where your package's targets were imported, which brought them into the overall build graph. Another small difference is that Ionide does a design-time build of the CoreCompile target, not necessarily the Build target, since all we need is the input file list to the compiler and that happens via the CoreCompile target. From what I can see, this target-difference doesn't seem to be an issue really. It all seems to be evaluation....

Ionide build: image

CLI Build: image

baronfel avatar May 18 '21 21:05 baronfel

I'm not that familiar with MSBuild, and the build scripts in the package are almost entirely copied over from the official C# package. One thing I can say for certain is that the scripts work in VS.

Can I change something in the package to make it work with Ionide? I was under the impression that there's only one correct way to do build-time codegen, but it seems I was wrong.

Arshia001 avatar May 18 '21 21:05 Arshia001

Oh I was just dumping some initial investigations in the above comment. It looks to me like your package is doing the correct thing. I think the problem is more on the Ionide side (specifically the proj-info library we use for project cracking), because we don't seem to be doing build evaluation the same way the CLI does.

baronfel avatar May 18 '21 21:05 baronfel

I've has some limited success working on ionide's evaluation, and I can now successfully perform evaluation the way the CLI does. Still digging into why we can't retrieve the correct item list from the compiler args though.

baronfel avatar May 18 '21 23:05 baronfel

I have exactly the same problem. Ionide won't scan my autogenerated files and i have to manually insert some msbuild script to project file and remove it before every commit. I hope there be good news from ionide soon :)

hamidrezakp avatar May 24 '21 11:05 hamidrezakp

I'm happy to say that in 5.10.1 I can't reproduce these issues!

baronfel avatar Nov 20 '21 20:11 baronfel

@baronfel I'm still seeing the issue in version 5.10.1. Is there something I can do to pinpoint the problem?

Arshia001 avatar Nov 22 '21 08:11 Arshia001

Running into this issue in 5.10.2. @Arshia001 can you re open?

jwosty avatar Dec 13 '21 17:12 jwosty

@baronfel @Krzysztof-Cieslak Just letting you know that this issue still exists.

Arshia001 avatar Jul 17 '22 11:07 Arshia001