@@ -110,6 +110,9 @@ module internal ParseAndCheck =
110
110
let tcConfig =
111
111
let tcConfigB =
112
112
TcConfigBuilder.CreateNew( SimulatedMSBuildReferenceResolver.getResolver(),
113
+ includewin32manifest= false ,
114
+ framework= false ,
115
+ portablePDB= false ,
113
116
defaultFSharpBinariesDir= FSharpCheckerResultsSettings.defaultFSharpBinariesDir,
114
117
reduceMemoryUsage= ReduceMemoryFlag.Yes,
115
118
implicitIncludeDir= Path.GetDirectoryName( projectOptions.ProjectFileName),
@@ -231,12 +234,23 @@ module internal ParseAndCheck =
231
234
loadClosure, implFile, sink.GetOpenDeclarations())
232
235
FSharpCheckFileResults ( fileName, errors, Some scope, parseResults.DependencyFiles, None, keepAssemblyContents)
233
236
234
- let TypeCheckClosedInputSet ( parseResults : FSharpParseFileResults [], tcState , compilerState ) =
237
+ let TypeCheckClosedInputSet ( parseResults : FSharpParseFileResults [], tcState , compilerState , subscriber ) =
235
238
let cachedTypeCheck ( tcState , moduleNamesDict ) ( parseRes : FSharpParseFileResults ) =
236
239
let checkCacheKey = parseRes.FileName
240
+
237
241
let typeCheckOneInput _fileName =
238
242
TypeCheckOneInputEntry ( parseRes, TcResultsSink.NoSink, tcState, moduleNamesDict, compilerState)
239
- compilerState.checkCache.GetOrAdd( checkCacheKey, typeCheckOneInput)
243
+
244
+ let ( result , errors ), ( tcState , moduleNamesDict ) = compilerState.checkCache.GetOrAdd( checkCacheKey, typeCheckOneInput)
245
+
246
+ let _ , _ , implFile , _ = result
247
+ match subscriber, implFile with
248
+ | Some subscriber, Some implFile ->
249
+ let cenv = SymbolEnv( compilerState.tcGlobals, tcState.Ccu, Some tcState.CcuSig, compilerState.tcImports)
250
+ FSharpImplementationFileContents( cenv, implFile) |> subscriber
251
+ | _ -> ()
252
+
253
+ ( result, errors), ( tcState, moduleNamesDict)
240
254
241
255
let results , ( tcState , moduleNamesDict ) =
242
256
(( tcState, Map.empty), parseResults) ||> Array.mapFold cachedTypeCheck
@@ -256,7 +270,6 @@ module internal ParseAndCheck =
256
270
errors |> Array.iter ( Array.sortInPlaceBy ( fun x -> x.StartLine, x.StartColumn))
257
271
errors |> Array.concat
258
272
259
-
260
273
type InteractiveChecker internal ( compilerStateCache ) =
261
274
262
275
static member Create ( projectOptions : FSharpProjectOptions ) =
@@ -269,32 +282,66 @@ type InteractiveChecker internal (compilerStateCache) =
269
282
compilerState.checkCache.Clear()
270
283
}
271
284
285
+ member _.GetImportedAssemblies () = async {
286
+ let! compilerState = compilerStateCache.Get()
287
+ let tcImports = compilerState.tcImports
288
+ let tcGlobals = compilerState.tcGlobals
289
+ return
290
+ tcImports.GetImportedAssemblies()
291
+ |> List.map ( fun x -> FSharpAssembly( tcGlobals, tcImports, x.FSharpViewOfMetadata))
292
+ }
293
+
294
+ /// Compile project to file. If project has already been type checked,
295
+ /// check results will be taken from the cache.
296
+ member _.Compile ( fileNames : string [], sourceReader : string -> int * Lazy < string >, outFile : string ) = async {
297
+ let! compilerState = compilerStateCache.Get()
298
+ let parsingOptions = FSharpParsingOptions.FromTcConfig( compilerState.tcConfig, fileNames, false )
299
+ let parseResults = fileNames |> Array.map ( fun fileName ->
300
+ let sourceHash , source = sourceReader fileName
301
+ ParseFile( fileName, sourceHash, source, parsingOptions, compilerState))
302
+
303
+ let ( tcState , topAttrs , tcImplFiles , _tcEnvAtEnd , _moduleNamesDict , _tcErrors ) =
304
+ TypeCheckClosedInputSet ( parseResults, compilerState.tcInitialState, compilerState, None)
305
+
306
+ let ctok = CompilationThreadToken()
307
+ let errors , errorLogger , _loggerProvider = CompileHelpers.mkCompilationErrorHandlers()
308
+ let exitCode =
309
+ CompileHelpers.tryCompile errorLogger ( fun exiter ->
310
+ compileOfTypedAst ( ctok, compilerState.tcGlobals, compilerState.tcImports, tcState.Ccu,
311
+ tcImplFiles, topAttrs, compilerState.tcConfig, outFile, errorLogger, exiter))
312
+
313
+ return errors.ToArray(), exitCode
314
+ }
315
+
272
316
/// Parses and checks the whole project, good for compilers (Fable etc.)
273
317
/// Does not retain name resolutions and symbol uses which are quite memory hungry (so no intellisense etc.).
274
318
/// Already parsed files will be cached so subsequent compilations will be faster.
275
- member _.ParseAndCheckProject ( projectFileName : string , fileNames : string [], sourceReader : string -> int * Lazy < string >, ?lastFile : string ) = async {
319
+ member _.ParseAndCheckProject ( projectFileName : string , fileNames : string [], sourceReader : string -> int * Lazy < string >,
320
+ ?lastFile : string , ?subscriber : FSharpImplementationFileContents -> unit ) = async {
276
321
let! compilerState = compilerStateCache.Get()
277
322
// parse files
278
323
let parsingOptions = FSharpParsingOptions.FromTcConfig( compilerState.tcConfig, fileNames, false )
279
- // We can paralellize this, but only in the first compilation because later it causes issues when invalidating the cache
280
- let parseResults = // measureTime <| fun _ ->
324
+ let parseResults =
281
325
let fileNames =
282
326
match lastFile with
283
327
| None -> fileNames
284
328
| Some fileName ->
285
329
let fileIndex = fileNames |> Array.findIndex ((=) fileName)
286
330
fileNames |> Array.take ( fileIndex + 1 )
287
331
288
- fileNames |> Array.map ( fun fileName ->
332
+ let parseFile fileName =
289
333
let sourceHash , source = sourceReader fileName
290
334
ParseFile( fileName, sourceHash, source, parsingOptions, compilerState)
291
- )
292
- // printfn "FCS: Parsing finished in %ims" ms
335
+
336
+ // Don't parallelize if we have cached files, as it would create issues with invalidation
337
+ if compilerState.parseCache.Count = 0 then
338
+ fileNames |> Array.Parallel.map parseFile
339
+ else
340
+ fileNames |> Array.map parseFile
293
341
294
342
// type check files
295
343
let ( tcState , topAttrs , tcImplFiles , _tcEnvAtEnd , _moduleNamesDict , tcErrors ) = // measureTime <| fun _ ->
296
- TypeCheckClosedInputSet ( parseResults, compilerState.tcInitialState, compilerState)
297
- // printfn "FCS: Checking finished in %ims" ms
344
+ TypeCheckClosedInputSet ( parseResults, compilerState.tcInitialState, compilerState, subscriber)
298
345
299
346
// make project results
300
347
let parseErrors = parseResults |> Array.collect ( fun p -> p.Diagnostics)
@@ -325,7 +372,7 @@ type InteractiveChecker internal (compilerStateCache) =
325
372
326
373
// type check files before file
327
374
let tcState , topAttrs , tcImplFiles , _tcEnvAtEnd , moduleNamesDict , tcErrors =
328
- TypeCheckClosedInputSet ( parseResults, compilerState.tcInitialState, compilerState)
375
+ TypeCheckClosedInputSet ( parseResults, compilerState.tcInitialState, compilerState, None )
329
376
330
377
// parse and type check file
331
378
let parseFileResults = parseFile fileName
0 commit comments