Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/Compiler/Driver/CompilerConfig.fs
Original file line number Diff line number Diff line change
Expand Up @@ -604,6 +604,8 @@ type TcConfigBuilder =
mutable captureIdentifiersWhenParsing: bool

mutable typeCheckingConfig: TypeCheckingConfig

mutable dumpSignatureData: bool
}

// Directories to start probing in
Expand Down Expand Up @@ -803,6 +805,7 @@ type TcConfigBuilder =
TypeCheckingMode.Sequential
DumpGraph = false
}
dumpSignatureData = false
}

member tcConfigB.FxResolver =
Expand Down Expand Up @@ -1343,6 +1346,7 @@ type TcConfig private (data: TcConfigBuilder, validate: bool) =
member _.parallelReferenceResolution = data.parallelReferenceResolution
member _.captureIdentifiersWhenParsing = data.captureIdentifiersWhenParsing
member _.typeCheckingConfig = data.typeCheckingConfig
member _.dumpSignatureData = data.dumpSignatureData

static member Create(builder, validate) =
use _ = UseBuildPhase BuildPhase.Parameter
Expand Down
4 changes: 4 additions & 0 deletions src/Compiler/Driver/CompilerConfig.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,8 @@ type TcConfigBuilder =
mutable captureIdentifiersWhenParsing: bool

mutable typeCheckingConfig: TypeCheckingConfig

mutable dumpSignatureData: bool
}

static member CreateNew:
Expand Down Expand Up @@ -884,6 +886,8 @@ type TcConfig =

member typeCheckingConfig: TypeCheckingConfig

member dumpSignatureData: bool

/// Represents a computation to return a TcConfig. Normally this is just a constant immutable TcConfig,
/// but for F# Interactive it may be based on an underlying mutable TcConfigBuilder.
[<Sealed>]
Expand Down
7 changes: 7 additions & 0 deletions src/Compiler/Driver/CompilerImports.fs
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,13 @@ let GetSignatureData (file, ilScopeRef, ilModule, byteReader) : PickledDataWithR
let WriteSignatureData (tcConfig: TcConfig, tcGlobals, exportRemapping, ccu: CcuThunk, fileName, inMem) : ILResource =
let mspec = ApplyExportRemappingToEntity tcGlobals exportRemapping ccu.Contents

if tcConfig.dumpSignatureData then
tcConfig.outputFile
|> Option.iter (fun outputFile ->
let outputFile = FileSystem.GetFullPathShim(outputFile)
let signatureDataFile = FileSystem.ChangeExtensionShim(outputFile, ".signature-data.json")
serializeEntity signatureDataFile mspec)

// For historical reasons, we use a different resource name for FSharp.Core, so older F# compilers
// don't complain when they see the resource.
let rName, compress =
Expand Down
1 change: 1 addition & 0 deletions src/Compiler/Driver/CompilerOptions.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1383,6 +1383,7 @@ let testFlag tcConfigB =
{ tcConfigB.typeCheckingConfig with
DumpGraph = true
}
| "DumpSignatureData" -> tcConfigB.dumpSignatureData <- true
#if DEBUG
| "ShowParserStackOnParseError" -> showParserStackOnParseError <- true
#endif
Expand Down
105 changes: 105 additions & 0 deletions src/Compiler/TypedTree/TypedTreeOps.fs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
/// Defines derived expression manipulation and construction functions.
module internal FSharp.Compiler.TypedTreeOps

open System.CodeDom.Compiler
open System.Collections.Generic
open System.Collections.Immutable
open Internal.Utilities
Expand All @@ -11,6 +12,7 @@ open Internal.Utilities.Library
open Internal.Utilities.Library.Extras
open Internal.Utilities.Rational

open FSharp.Compiler.IO
open FSharp.Compiler.AbstractIL.IL
open FSharp.Compiler.CompilerGlobalState
open FSharp.Compiler.DiagnosticsLogger
Expand Down Expand Up @@ -10481,3 +10483,106 @@ let tryAddExtensionAttributeIfNotAlreadyPresent
match tryFindExtensionAttributeIn tryFindExtensionAttribute with
| None -> entity
| Some extensionAttrib -> { entity with entity_attribs = extensionAttrib :: entity.Attribs }

type TypedTreeNode =
{
Kind: string
Name: string
Children: TypedTreeNode list
}

let rec visitEntity (entity: Entity) : TypedTreeNode =
let kind =
if entity.IsModule then
"module"
elif entity.IsNamespace then
"namespace"
else
"other"

let children =
if not entity.IsModuleOrNamespace then
Seq.empty
else
seq {
yield! Seq.map visitEntity entity.ModuleOrNamespaceType.AllEntities
yield! Seq.map visitVal entity.ModuleOrNamespaceType.AllValsAndMembers
}

{
Kind = kind
Name = entity.CompiledName
Children = Seq.toList children
}

and visitVal (v: Val) : TypedTreeNode =
let children =
seq {
match v.ValReprInfo with
| None -> ()
| Some reprInfo ->
yield!
reprInfo.ArgInfos
|> Seq.collect (fun argInfos ->
argInfos
|> Seq.map (fun argInfo -> {
Name = argInfo.Name |> Option.map (fun i -> i.idText) |> Option.defaultValue ""
Kind = "ArgInfo"
Children = []
})
)

yield!
v.Typars
|> Seq.map (fun typar -> {
Name = typar.Name
Kind = "Typar"
Children = []
})
}

{
Name = v.CompiledName None
Kind = "val"
Children = Seq.toList children
}

let rec serializeNode (writer: IndentedTextWriter) (addTrailingComma:bool) (node: TypedTreeNode) =
writer.WriteLine("{")
// Add indent after opening {
writer.Indent <- writer.Indent + 1

writer.WriteLine($"\"name\": \"{node.Name}\",")
writer.WriteLine($"\"kind\": \"{node.Kind}\",")

if node.Children.IsEmpty then
writer.WriteLine("\"children\": []")
else
writer.WriteLine("\"children\": [")

// Add indent after opening [
writer.Indent <- writer.Indent + 1

node.Children
|> List.iteri (fun idx -> serializeNode writer (idx + 1 < node.Children.Length))

// Remove indent before closing ]
writer.Indent <- writer.Indent - 1
writer.WriteLine("]")

// Remove indent before closing }
writer.Indent <- writer.Indent - 1
if addTrailingComma then
writer.WriteLine("},")
else
writer.WriteLine("}")

let rec serializeEntity path (entity: Entity) =
let root = visitEntity entity
use sw = new System.IO.StringWriter()
use writer = new IndentedTextWriter(sw)
serializeNode writer false root
writer.Flush()
let json = sw.ToString()
use out = FileSystem.OpenFileForWriteShim(path, fileMode = System.IO.FileMode.Create)
out.WriteAllText(json)
3 changes: 3 additions & 0 deletions src/Compiler/TypedTree/TypedTreeOps.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -2695,3 +2695,6 @@ val (|EmptyModuleOrNamespaces|_|):
/// Add an System.Runtime.CompilerServices.ExtensionAttribute to the Entity if found via predicate and not already present.
val tryAddExtensionAttributeIfNotAlreadyPresent:
tryFindExtensionAttributeIn: ((Attrib list -> Attrib option) -> Attrib option) -> entity: Entity -> Entity

/// Serialize an entity to a very basic json structure.
val serializeEntity: path: string -> entity: Entity -> unit