Skip to content

Commit 20573b7

Browse files
vasily-kirichenkodsyme
authored andcommitted
Add impl files to file check results (#3659)
* add LanguageServiceProfiling project to internals visible to list of FSharp.Compiler.Private project * add ImplementationFiles to FSharpCheckFileResults * make FSharpImplementationFileContents ctor internal * throw if ImplementationFiles is called having keepAssemblyContents flag set to false * add a test * spelling and cosmetics
1 parent 34e669c commit 20573b7

9 files changed

+78
-17
lines changed

src/assemblyinfo/assemblyinfo.FSharp.Compiler.Private.dll.fs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ open System.Runtime.InteropServices
4646
[<assembly:System.Runtime.CompilerServices.InternalsVisibleTo("Test, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")>]
4747
[<assembly:System.Runtime.CompilerServices.InternalsVisibleTo("FSharp.Compiler.Unittests, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")>]
4848
[<assembly:System.Runtime.CompilerServices.InternalsVisibleTo("fsc-proto, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")>]
49+
[<assembly:System.Runtime.CompilerServices.InternalsVisibleTo("LanguageServiceProfiling, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")>]
4950
#endif
5051
#if STRONG_NAME_FSHARP_COMPILER_WITH_TEST_KEY
5152
[<assembly:System.Runtime.CompilerServices.InternalsVisibleTo("fsc, PublicKey=002400000480000094000000060200000024000052534131000400000100010077d32e043d184cf8cebf177201ec6fad091581a3a639a0534f1c4ebb3ab847a6b6636990224a04cf4bd1aec51ecec44cf0c8922eb5bb2ee65ec3fb9baa87e141042c96ce414f98af33508c7e24dab5b068aa802f6693881537ee0efcb5d3f1c9aaf8215ac42e92ba9a5a02574d6890d07464cb2f338b043b1c4ffe98efe069ee")>]

src/fsharp/CompileOps.fs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2835,8 +2835,8 @@ type TcConfig private (data : TcConfigBuilder, validate:bool) =
28352835
member x.embedResources = data.embedResources
28362836
member x.globalWarnAsError = data.globalWarnAsError
28372837
member x.globalWarnLevel = data.globalWarnLevel
2838-
member x.specificWarnOff = data. specificWarnOff
2839-
member x.specificWarnOn = data. specificWarnOn
2838+
member x.specificWarnOff = data.specificWarnOff
2839+
member x.specificWarnOn = data.specificWarnOn
28402840
member x.specificWarnAsError = data.specificWarnAsError
28412841
member x.specificWarnAsWarn = data.specificWarnAsWarn
28422842
member x.mlCompatibility = data.mlCompatibility

src/fsharp/CompileOptions.fs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -380,9 +380,7 @@ let ParseCompilerOptions (collectOtherArgument : string -> unit, blocks: Compile
380380
let rest = attempt specs
381381
processArg rest
382382

383-
let result = processArg args
384-
result
385-
383+
processArg args
386384

387385
//----------------------------------------------------------------------------
388386
// Compiler options

src/fsharp/symbols/Exprs.fsi

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ and [<Class>] FSharpImplementationFileContents =
2828
#else
2929
and [<Class>] internal FSharpImplementationFileContents =
3030
#endif
31+
internal new : cenv: Impl.cenv * mimpl: TypedImplFile -> FSharpImplementationFileContents
3132

3233
/// The qualified name acts to fully-qualify module specifications and implementations
3334
member QualifiedName: string

src/fsharp/vs/IncrementalBuild.fs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1095,7 +1095,8 @@ type PartialCheckResults =
10951095
TcSymbolUses: TcSymbolUses list
10961096
TcDependencyFiles: string list
10971097
TopAttribs: TopAttribs option
1098-
TimeStamp: System.DateTime }
1098+
TimeStamp: System.DateTime
1099+
ImplementationFiles: TypedImplFile list }
10991100

11001101
static member Create (tcAcc: TypeCheckAccumulator, timestamp) =
11011102
{ TcState = tcAcc.tcState
@@ -1108,7 +1109,8 @@ type PartialCheckResults =
11081109
TcSymbolUses = tcAcc.tcSymbolUses
11091110
TcDependencyFiles = tcAcc.tcDependencyFiles
11101111
TopAttribs = tcAcc.topAttribs
1111-
TimeStamp = timestamp }
1112+
TimeStamp = timestamp
1113+
ImplementationFiles = tcAcc.typedImplFiles }
11121114

11131115

11141116
[<AutoOpen>]

src/fsharp/vs/IncrementalBuild.fsi

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,10 @@ type internal PartialCheckResults =
5959
/// Represents the collected attributes to apply to the module of assuembly generates
6060
TopAttribs: TypeChecker.TopAttribs option
6161

62-
TimeStamp: DateTime }
62+
TimeStamp: DateTime
63+
64+
/// Represents complete typechecked implementation files, including thier typechecked signatures if any.
65+
ImplementationFiles: TypedImplFile list }
6366

6467
/// Manages an incremental build graph for the build of an F# project
6568
[<Class>]

src/fsharp/vs/service.fs

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,8 @@ type TypeCheckInfo
163163
loadClosure : LoadClosure option,
164164
reactorOps : IReactorOperations,
165165
checkAlive : (unit -> bool),
166-
textSnapshotInfo:obj option) =
166+
textSnapshotInfo:obj option,
167+
implementationFiles: TypedImplFile list) =
167168

168169
let textSnapshotInfo = defaultArg textSnapshotInfo null
169170
let (|CNR|) (cnr:CapturedNameResolution) =
@@ -1356,6 +1357,8 @@ type TypeCheckInfo
13561357
/// The assembly being analyzed
13571358
member __.ThisCcu = thisCcu
13581359

1360+
member __.ImplementationFiles = implementationFiles
1361+
13591362
override __.ToString() = "TypeCheckInfo(" + mainInputFileName + ")"
13601363

13611364

@@ -1662,7 +1665,7 @@ module internal Parser =
16621665
let errors = errHandler.CollectedDiagnostics
16631666

16641667
match tcEnvAtEndOpt with
1665-
| Some (tcEnvAtEnd, _typedImplFiles, tcState) ->
1668+
| Some (tcEnvAtEnd, typedImplFiles, tcState) ->
16661669
let scope =
16671670
TypeCheckInfo(tcConfig, tcGlobals,
16681671
tcState.PartialAssemblySignature,
@@ -1678,7 +1681,8 @@ module internal Parser =
16781681
loadClosure,
16791682
reactorOps,
16801683
checkAlive,
1681-
textSnapshotInfo)
1684+
textSnapshotInfo,
1685+
typedImplFiles)
16821686
return errors, TypeCheckAborted.No scope
16831687
| None ->
16841688
return errors, TypeCheckAborted.Yes
@@ -1761,7 +1765,7 @@ type FSharpCheckProjectResults(projectFileName:string, keepAssemblyContents, err
17611765
FSharpAssemblySignature(tcGlobals, thisCcu, tcImports, topAttribs, ccuSig)
17621766

17631767
member info.AssemblyContents =
1764-
if not keepAssemblyContents then invalidOp "The 'keepAssemblyContents' flag must be set to tru on the FSharpChecker in order to access the checked contents of assemblies"
1768+
if not keepAssemblyContents then invalidOp "The 'keepAssemblyContents' flag must be set to true on the FSharpChecker in order to access the checked contents of assemblies"
17651769
let (tcGlobals, tcImports, thisCcu, _ccuSig, _tcSymbolUses, _topAttribs, _tcAssemblyData, _ilAssemRef, _ad, tcAssemblyExpr, _dependencyFiles) = getDetails()
17661770
let mimpls =
17671771
match tcAssemblyExpr with
@@ -1817,7 +1821,7 @@ type FSharpCheckProjectResults(projectFileName:string, keepAssemblyContents, err
18171821
//
18181822
// There is an important property of all the objects returned by the methods of this type: they do not require
18191823
// the corresponding background builder to be alive. That is, they are simply plain-old-data through pre-formatting of all result text.
1820-
type FSharpCheckFileResults(filename: string, errors: FSharpErrorInfo[], scopeOptX: TypeCheckInfo option, dependencyFiles: string list, builderX: IncrementalBuilder option, reactorOpsX:IReactorOperations) =
1824+
type FSharpCheckFileResults(filename: string, errors: FSharpErrorInfo[], scopeOptX: TypeCheckInfo option, dependencyFiles: string list, builderX: IncrementalBuilder option, reactorOpsX:IReactorOperations, keepAssemblyContents: bool) =
18211825

18221826
// This may be None initially, or may be set to None when the object is disposed or finalized
18231827
let mutable details = match scopeOptX with None -> None | Some scopeX -> Some (scopeX, builderX, reactorOpsX)
@@ -2002,6 +2006,12 @@ type FSharpCheckFileResults(filename: string, errors: FSharpErrorInfo[], scopeOp
20022006
RequireCompilationThread ctok
20032007
scope.IsRelativeNameResolvable(pos, plid, item))
20042008

2009+
member info.ImplementationFiles =
2010+
if not keepAssemblyContents then invalidOp "The 'keepAssemblyContents' flag must be set to true on the FSharpChecker in order to access the checked contents of assemblies"
2011+
scopeOptX
2012+
|> Option.map (fun scope ->
2013+
let cenv = Impl.cenv(scope.TcGlobals, scope.ThisCcu, scope.TcImports)
2014+
[ for mimpl in scope.ImplementationFiles -> FSharpImplementationFileContents(cenv, mimpl)])
20052015

20062016
override info.ToString() = "FSharpCheckFileResults(" + filename + ")"
20072017

@@ -2326,7 +2336,7 @@ type BackgroundCompiler(legacyReferenceResolver, projectCacheSize, keepAssemblyC
23262336
static let mutable foregroundTypeCheckCount = 0
23272337

23282338
let MakeCheckFileResultsEmpty(filename, creationErrors) =
2329-
FSharpCheckFileResults (filename, Array.ofList creationErrors, None, [], None, reactorOps)
2339+
FSharpCheckFileResults (filename, Array.ofList creationErrors, None, [], None, reactorOps, keepAssemblyContents)
23302340

23312341
let MakeCheckFileResults(filename, options:FSharpProjectOptions, builder, scope, dependencyFiles, creationErrors, parseErrors, tcErrors) =
23322342
let errors =
@@ -2337,7 +2347,7 @@ type BackgroundCompiler(legacyReferenceResolver, projectCacheSize, keepAssemblyC
23372347
else
23382348
yield! tcErrors |]
23392349

2340-
FSharpCheckFileResults (filename, errors, Some scope, dependencyFiles, Some builder, reactorOps)
2350+
FSharpCheckFileResults (filename, errors, Some scope, dependencyFiles, Some builder, reactorOps, keepAssemblyContents)
23412351

23422352
let MakeCheckFileAnswer(filename, tcFileResult, options:FSharpProjectOptions, builder, dependencyFiles, creationErrors, parseErrors, tcErrors) =
23432353
match tcFileResult with
@@ -2624,7 +2634,8 @@ type BackgroundCompiler(legacyReferenceResolver, projectCacheSize, keepAssemblyC
26242634
List.last tcProj.TcResolutions,
26252635
List.last tcProj.TcSymbolUses,
26262636
tcProj.TcEnvAtEnd.NameEnv,
2627-
loadClosure, reactorOps, (fun () -> builder.IsAlive), None)
2637+
loadClosure, reactorOps, (fun () -> builder.IsAlive), None,
2638+
tcProj.ImplementationFiles)
26282639
let typedResults = MakeCheckFileResults(filename, options, builder, scope, tcProj.TcDependencyFiles, creationErrors, parseResults.Errors, tcErrors)
26292640
return (parseResults, typedResults)
26302641
})
@@ -3144,7 +3155,7 @@ type FsiInteractiveChecker(legacyReferenceResolver, reactorOps: IReactorOperatio
31443155
match tcFileResult with
31453156
| Parser.TypeCheckAborted.No scope ->
31463157
let errors = [| yield! parseErrors; yield! tcErrors |]
3147-
let typeCheckResults = FSharpCheckFileResults (filename, errors, Some scope, dependencyFiles, None, reactorOps)
3158+
let typeCheckResults = FSharpCheckFileResults (filename, errors, Some scope, dependencyFiles, None, reactorOps, false)
31483159
let projectResults = FSharpCheckProjectResults (filename, keepAssemblyContents, errors, Some(tcGlobals, tcImports, scope.ThisCcu, scope.CcuSig, [scope.ScopeSymbolUses], None, None, mkSimpleAssRef "stdin", tcState.TcEnvFromImpls.AccessRights, None, dependencyFiles), reactorOps)
31493160
parseResults, typeCheckResults, projectResults
31503161
| _ ->

src/fsharp/vs/service.fsi

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,9 @@ type internal FSharpCheckFileResults =
262262
/// <param name="userOpName">An optional string used for tracing compiler operations associated with this request.</param>
263263
member internal IsRelativeNameResolvable: cursorPos : pos * plid : string list * item: Item * ?userOpName: string -> Async<bool>
264264

265+
/// Represents complete typechecked implementation files, including thier typechecked signatures if any.
266+
member ImplementationFiles: FSharpImplementationFileContents list option
267+
265268
/// A handle to the results of CheckFileInProject.
266269
[<Sealed>]
267270
#if COMPILER_PUBLIC_API

tests/service/ProjectAnalysisTests.fs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5174,3 +5174,45 @@ let ``Test line directives in foreground analysis`` () = // see https://github.c
51745174

51755175
[ for e in checkResults1.Errors -> e.StartLineAlternate, e.EndLineAlternate, e.FileName ] |> shouldEqual [(4, 4, ProjectLineDirectives.fileName1)]
51765176

5177+
//------------------------------------------------------
5178+
5179+
[<Test>]
5180+
let ``ParseAndCheckFileResults contains ImplFile list if FSharpChecker is created with keepAssemblyContent flag set to true``() =
5181+
5182+
let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs")
5183+
let base2 = Path.GetTempFileName()
5184+
let dllName = Path.ChangeExtension(base2, ".dll")
5185+
let projFileName = Path.ChangeExtension(base2, ".fsproj")
5186+
let fileSource1 = """
5187+
type A(i:int) =
5188+
member x.Value = i
5189+
"""
5190+
File.WriteAllText(fileName1, fileSource1)
5191+
5192+
let fileNames = [fileName1]
5193+
let args = mkProjectCommandLineArgs (dllName, fileNames)
5194+
let keepAssemblyContentsChecker = FSharpChecker.Create(keepAssemblyContents=true)
5195+
let options = keepAssemblyContentsChecker.GetProjectOptionsFromCommandLineArgs (projFileName, args)
5196+
5197+
let fileCheckResults =
5198+
keepAssemblyContentsChecker.ParseAndCheckFileInProject(fileName1, 0, fileSource1, options) |> Async.RunSynchronously
5199+
|> function
5200+
| _, FSharpCheckFileAnswer.Succeeded(res) -> res
5201+
| _ -> failwithf "Parsing aborted unexpectedly..."
5202+
5203+
let declarations =
5204+
match fileCheckResults.ImplementationFiles with
5205+
| Some (implFile :: _) ->
5206+
match implFile.Declarations |> List.tryHead with
5207+
| Some (FSharpImplementationFileDeclaration.Entity (_, subDecls)) -> subDecls
5208+
| _ -> failwith "unexpected declaration"
5209+
| Some [] | None -> failwith "File check results does not contain any `ImplementationFile`s"
5210+
5211+
match declarations |> List.tryHead with
5212+
| Some (FSharpImplementationFileDeclaration.Entity(entity, [])) ->
5213+
entity.DisplayName |> shouldEqual "A"
5214+
let memberNames = entity.MembersFunctionsAndValues |> Seq.map (fun x -> x.DisplayName) |> Set.ofSeq
5215+
Assert.That(memberNames, Contains.Item "Value")
5216+
5217+
| Some decl -> failwithf "unexpected declaration %A" decl
5218+
| None -> failwith "declaration list is empty"

0 commit comments

Comments
 (0)