5

Github Enable in-memory cross project referencing for C# -> F# projects by TI...

 3 years ago
source link: https://github.com/dotnet/fsharp/pull/11301
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client
Enable in-memory cross project referencing for C# -> F# projects by TIHan · Pull Request #11301 · dotnet/fsharp · GitHub

Copy link

Contributor

TIHan commented on Mar 24

edited

This allows cross project referencing of C#/IL projects to be supported directly in FCS. This means, making a change in a C# project will now be able to be reflected in a F# project that depends on it without having to compile the C# project on-disk.

In VS specifically, there are still a few quirks as semantic analysis doesn't get fired in a F# project when it's dependent C# project changes, but it will correct itself as soon as the user does something in the F# project or any of its dependent F# projects.

API Changes:

Remaining work:

@@ -82,6 +82,15 @@ type public FSharpProjectOptions =

/// Compute the project directory.

member internal ProjectDirectory: string

and [<NoComparison>] public FSharpReferencedProject =

internal

auduchinok on Mar 25

Contributor

Could you please make it public instead?

TIHan on Mar 25

Author

Contributor

I don't want the internal structure to be public. But, we should be able to create different kinds of FSharpReferencedProject instances.

and [<NoComparison>] public FSharpReferencedProject =

internal

| FSharp of projectFileName: string * options: FSharpProjectOptions

| IL of projectFileName: string * stamp: DateTime * lazyData: Lazy<byte []>

auduchinok on Mar 25

Contributor

Could you make it an interface? We can't use Roslyn compilation that produces a byte array but would be happy to use an implementation that looks at R# symbols.

TIHan on Mar 25

Author

Contributor

The use of the byte array isn't because of the Roslyn compilation, it's our metadata reader.

There are currently two functions for opening an ILModuleReader:

val internal OpenILModuleReader: string -> ILReaderOptions -> ILModuleReader

val internal OpenILModuleReaderFromBytes: fileName:string -> assemblyContents: byte[] -> options: ILReaderOptions -> ILModuleReader

I'm using the latter at the moment. Using the former is a little tricky as it tries to look at the last write time of a file which in this case, we can't because it's in-memory.

I think we need a new function to open an ILModuleReader that doesn't require a byte array and doesn't require the file to be on-disk.

auduchinok on Mar 26

edited

Contributor

What do you think about something like this?

type FSharpReferencedProject =
    | FSharp of projectFileName: string * options: FSharpProjectOptions
    | IL of projectFileName: string * metadata: IILMetadata

and IILMetadata =
    abstract Timestamp: DateTime
    abstract CreateReader: unit -> ILModuleReader // or `ILReaderOptions -> ILModuleReader`

TIHan on Apr 6

Author

Contributor

An IILMetadata would be better, though I am hesitant to create an ILModuleReader directly like that as a public API, even though ILModuleReader is public.

I need to investigate whether or not we could use System.Reflection.PortableExecutable.PEReader.

auduchinok 20 days ago

edited

Contributor

What makes me want to reuse this logic is changing the module reader directly via shim currently makes it impossible to distinguish module reads from projects and from scripts. Using FSharpReferencedProject would make it a better experience, but we only can provide a custom module reader, not a PEReader or a metadata stream. Could you consider an option allowing passing a custom reader, something like I've suggested above, please?

TIHan 20 days ago

Author

Contributor

To make sure I understand, you already have a module reader and you just want to pass it to a FSharpReferencedProject?

auduchinok 20 days ago

Contributor

Yes, I currently create it in IAssemblyReader.GetILModuleReader(filename: string, readerOptions: ILReaderOptions) implementation that is used in the assembly reader shim.

TIHan 20 days ago

Author

Contributor

Ok, then I think it makes sense to allow you to create a FSharpReferencedProject with an ILModuleReader. I will make another PR.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK