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

ReferencedProjects empty OtherOptions #326

Closed
ghost opened this issue Jan 17, 2019 · 3 comments
Closed

ReferencedProjects empty OtherOptions #326

ghost opened this issue Jan 17, 2019 · 3 comments

Comments

@ghost
Copy link

ghost commented Jan 17, 2019

Moving from ionide/ionide-vscode-fsharp#924 (comment) to make it easier to troubleshoot:

Finally time to debug this a bit (holidays). I set up a debug version of FsAutoComplete and printed the project options in full for a working version of my code, and then a non working version, and diffed the output.

When the issue occurs, it appears that the FSharpProjectOptions that FsAutoComplete provides is not populating the 'OtherOptions' field.

On a working project this field should contain the framework references and some other info for FSC:

ReferencedProjects =
     [|("/home/user/projects/res/backend/src/Analysis/Model/bin/Debug/netstandard2.0/Analysis.Model.dll",
        {ProjectFileName =
          "/home/user/projects/res/backend/src/Analysis/Model/Analysis.Model.fsproj";
         ProjectId =
          Some
            "/home/user/projects/res/backend/src/Analysis/Model/Analysis.Model.fsproj";
         SourceFiles = [||];
         OtherOptions =
          [|"-o:/home/user/projects/res/backend/src/Analysis/Model/obj/Debug/netstandard2.0/Analysis.Model.dll";
            "-g"; "--debug:portable"; "--noframework"; "--define:TRACE";
            "--define:DEBUG"; "--define:NETSTANDARD"; "--define:NETSTANDARD2_0";
            "--optimize-"; "--tailcalls-";
            "-r:/home/user/.nuget/packages/fsharp.core/4.5.4/lib/netstandard1.6/FSharp.Core.dll";
            "-r:/home/user/.nuget/packages/netstandard.library/2.0.3/build/netstandard2.0/ref/Microsoft.Win32.Primitives.dll";
            "-r:/home/user/.nuget/packages/netstandard.library/2.0.3/build/netstandard2.0/ref/mscorlib.dll";
            "-r:/home/user/.nuget/packages/netstandard.library/2.0.3/build/netstandard2.0/ref/netstandard.dll";
...

On a project that causes the error on this issue, we get this instead:

 ReferencedProjects =
     [|("/home/user/projects/res/backend/src/Analysis/Model/bin/Debug/netstandard2.0/Analysis.Model.dll",
        {ProjectFileName =
          "/home/user/projects/res/backend/src/Analysis/Model/Analysis.Model.fsproj";
         ProjectId =
          Some
            "/home/user/projects/res/backend/src/Analysis/Model/Analysis.Model.fsproj";
         SourceFiles = [||];
         OtherOptions = [||];
         ReferencedProjects = [||];
         IsIncompleteTypeCheckEnvironment = false;
         UseScriptResolutionRules = false;
         LoadTime = 1/16/19 8:22:34 PM;
         UnresolvedReferences = None;
         OriginalLoadReferences = [];

I think commands should recompile projects on the fly (then cache them) that have missing references, something like this:

                let! checkOptions =
                    match state.GetCheckerOptions(file, lines) with
                    | Some c when Array.isEmpty c.ReferencedProjects -> 
                        do printfn "checker options for %s already existed %A" file c
                        async.Return c
                    // sometimes we get a cached referenceProject that does not have
                    // the correct 'OtherOptions' framework details
                    | Some c -> 
                        if not(Array.isEmpty c.ReferencedProjects) then 
                            let missingOpts = 
                                c.ReferencedProjects 
                                |> Array.filter (fun (_,x) -> Array.isEmpty x.OtherOptions) 
                            if Array.isEmpty missingOpts then
                                do printfn "checker options for %s already existed %A" file c
                                async.Return c
                            else
                                for _,prj in missingOpts do 
                                    do printfn "Missing opts! %A" prj.ProjectFileName
                                    let sts = x.Compile prj.ProjectFileName |> Async.RunSynchronously 
                                    printfn "Compiled project %A" sts

                                async {
                                    let! checkOptions = checker.GetProjectOptionsFromScript(file, text)
                                    state.AddFileTextAndCheckerOptions(file, lines, normalizeOptions checkOptions)
                                    return checkOptions
                                }
                        else
                            do printfn "checker options for %s already existed %A" file c
                            async.Return c
                    | None -> 
                        do printfn "No checker options returned, adding"
                        async {
                            let! checkOptions = checker.GetProjectOptionsFromScript(file, text)
                            state.AddFileTextAndCheckerOptions(file, lines, normalizeOptions checkOptions)
                            return checkOptions
                        }

It also seems that this might need updating to use dotnet msbuild instead of msbuild:

...
            let msbuildPath =
            #if NETCOREAPP || NETSTANDARD 
                Dotnet.ProjInfo.Inspect.MSBuildExePath.DotnetMsbuild "dotnet"
            #else
                Dotnet.ProjInfo.Inspect.MSBuildExePath.Path "msbuild"
            #endif
...

@enricosada am I on the right track here, I am trying to use:
Dotnet.ProjInfo.Inspect.getProjectInfo with the above msbuildPath, but it returns a strange error that suggests something with path concatenation is going odd:

Request cancelled (exn was System.IO.DirectoryNotFoundException: Could not find a part of the path '/tmp/tmpHYk1pa.tmp/obj/EnvironmentInfo.proj.proj-info.targets'

I will keep trying to debug this soon. My next step is to update the version of dotnet-proj-info that is used in FsAutoComplete (currently its 0.11.0 I think).

@enricosada
Copy link
Contributor

if the OtherOptions of a ReferenceProject are empty, i think the project loading failed.

It also seems that this might need updating to use dotnet msbuild instead of msbuild:

if we run FSAC in .NET, than .NET is installed, so is safe to use it.

Probably is better to use the real path found by FSAC euristic, not just msbuild (so using the one in PATH). ref #325 (comment)

Dotnet.ProjInfo.Inspect.getProjectInfo with the above msbuildPath, but it returns a strange error that suggests something with path concatenation is going odd:

yes, seems the load of the project failed. so should fail in FSAC too. like this is a false positive

@Krzysztof-Cieslak
Copy link
Member

@enricosada any idea what’s happening here? Is that a problem in dotnet-proj-info?

@enricosada
Copy link
Contributor

Closing.

the msbuild used now is always the latest, not the one in PATH and will work if is not in PATH

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

No branches or pull requests

2 participants