@@ -2247,104 +2247,93 @@ and [<Sealed>] TcImports
22472247 phase2
22482248
22492249 // NOTE: When used in the Language Service this can cause the transitive checking of projects. Hence it must be cancellable.
2250- member tcImports.TryRegisterAndPrepareToImportReferencedDll
2251- ( ctok , r : AssemblyResolution )
2252- : Async <( _ * ( unit -> AvailableImportedAssembly list )) option > =
2253- async {
2254- CheckDisposed()
2255- let m = r.originalReference.Range
2256- let fileName = r.resolvedPath
2250+ member tcImports.RegisterAndImportReferencedAssemblies ( ctok , nms : AssemblyResolution list ) =
2251+ let tryGetAssemblyData ( r : AssemblyResolution ) =
2252+ async {
2253+ CheckDisposed()
2254+ let m = r.originalReference.Range
2255+ let fileName = r.resolvedPath
22572256
2258- let! contentsOpt =
2259- async {
2260- match r.ProjectReference with
2261- | Some ilb -> return ! ilb.EvaluateRawContents()
2262- | None -> return ProjectAssemblyDataResult.Unavailable true
2263- }
2257+ try
22642258
2265- // If we have a project reference but did not get any valid contents,
2266- // just return None and do not attempt to read elsewhere.
2267- match contentsOpt with
2268- | ProjectAssemblyDataResult.Unavailable false -> return None
2269- | _ ->
2259+ let! contentsOpt =
2260+ async {
2261+ match r.ProjectReference with
2262+ | Some ilb -> return ! ilb.EvaluateRawContents()
2263+ | None -> return ProjectAssemblyDataResult.Unavailable true
2264+ }
22702265
2271- let assemblyData =
2266+ // If we have a project reference but did not get any valid contents,
2267+ // just return None and do not attempt to read elsewhere.
22722268 match contentsOpt with
2273- | ProjectAssemblyDataResult.Available ilb -> ilb
2274- | ProjectAssemblyDataResult.Unavailable _ ->
2275- let ilModule , ilAssemblyRefs = tcImports.OpenILBinaryModule( ctok, fileName, m)
2276- RawFSharpAssemblyDataBackedByFileOnDisk( ilModule, ilAssemblyRefs) :> IRawFSharpAssemblyData
2269+ | ProjectAssemblyDataResult.Unavailable false -> return None
2270+ | _ ->
2271+
2272+ match contentsOpt with
2273+ | ProjectAssemblyDataResult.Available ilb -> return Some( r, ilb)
2274+ | ProjectAssemblyDataResult.Unavailable _ ->
2275+ let ilModule , ilAssemblyRefs = tcImports.OpenILBinaryModule( ctok, fileName, m)
2276+ return Some( r, RawFSharpAssemblyDataBackedByFileOnDisk( ilModule, ilAssemblyRefs))
2277+
2278+ with e ->
2279+ errorR ( Error( FSComp.SR.buildProblemReadingAssembly ( fileName, e.Message), m))
2280+ return None
2281+ }
22772282
2278- let ilShortAssemName = assemblyData.ShortAssemblyName
2279- let ilScopeRef = assemblyData.ILScopeRef
2283+ let registerDll ( r : AssemblyResolution , assemblyData : IRawFSharpAssemblyData ) =
2284+ let m = r.originalReference.Range
2285+ let fileName = r.resolvedPath
2286+ let ilShortAssemName = assemblyData.ShortAssemblyName
2287+ let ilScopeRef = assemblyData.ILScopeRef
22802288
2281- if tcImports.IsAlreadyRegistered ilShortAssemName then
2282- let dllinfo = tcImports.FindDllInfo( ctok, m, ilShortAssemName)
2289+ if tcImports.IsAlreadyRegistered ilShortAssemName then
22832290
2284- let phase2 () =
2285- [ tcImports.FindCcuInfo( ctok, m, ilShortAssemName, lookupOnly = true ) ]
2291+ let phase2 () =
2292+ [ tcImports.FindCcuInfo( ctok, m, ilShortAssemName, lookupOnly = true ) ]
22862293
2287- return Some ( dllinfo , phase2)
2288- else
2289- let dllinfo =
2290- {
2291- RawMetadata = assemblyData
2292- FileName = fileName
2294+ phase2
2295+ else
2296+ let dllinfo =
2297+ {
2298+ RawMetadata = assemblyData
2299+ FileName = fileName
22932300#if ! NO_ TYPEPROVIDERS
2294- ProviderGeneratedAssembly = None
2295- IsProviderGenerated = false
2296- ProviderGeneratedStaticLinkMap = None
2301+ ProviderGeneratedAssembly = None
2302+ IsProviderGenerated = false
2303+ ProviderGeneratedStaticLinkMap = None
22972304#endif
2298- ILScopeRef = ilScopeRef
2299- ILAssemblyRefs = assemblyData.ILAssemblyRefs
2300- }
2305+ ILScopeRef = ilScopeRef
2306+ ILAssemblyRefs = assemblyData.ILAssemblyRefs
2307+ }
23012308
2302- tcImports.RegisterDll dllinfo
2309+ tcImports.RegisterDll dllinfo
23032310
2304- let phase2 =
2305- if assemblyData.HasAnyFSharpSignatureDataAttribute then
2306- if not assemblyData.HasMatchingFSharpSignatureDataAttribute then
2307- errorR ( Error( FSComp.SR.buildDifferentVersionMustRecompile fileName, m))
2308- tcImports.PrepareToImportReferencedILAssembly( ctok, m, fileName, dllinfo)
2309- else
2310- try
2311- tcImports.PrepareToImportReferencedFSharpAssembly( ctok, m, fileName, dllinfo)
2312- with e ->
2313- error ( Error( FSComp.SR.buildErrorOpeningBinaryFile ( fileName, e.Message), m))
2314- else
2311+ let phase2 =
2312+ if assemblyData.HasAnyFSharpSignatureDataAttribute then
2313+ if not assemblyData.HasMatchingFSharpSignatureDataAttribute then
2314+ errorR ( Error( FSComp.SR.buildDifferentVersionMustRecompile fileName, m))
23152315 tcImports.PrepareToImportReferencedILAssembly( ctok, m, fileName, dllinfo)
2316+ else
2317+ try
2318+ tcImports.PrepareToImportReferencedFSharpAssembly( ctok, m, fileName, dllinfo)
2319+ with e ->
2320+ error ( Error( FSComp.SR.buildErrorOpeningBinaryFile ( fileName, e.Message), m))
2321+ else
2322+ tcImports.PrepareToImportReferencedILAssembly( ctok, m, fileName, dllinfo)
23162323
2317- return Some( dllinfo, phase2)
2318- }
2324+ phase2
23192325
2320- // NOTE: When used in the Language Service this can cause the transitive checking of projects. Hence it must be cancellable.
2321- member tcImports.RegisterAndImportReferencedAssemblies ( ctok , nms : AssemblyResolution list ) =
23222326 async {
23232327 CheckDisposed()
23242328
2325- let tcConfig = tcConfigP.Get ctok
2329+ let! assemblyData = nms |> List.map tryGetAssemblyData |> MultipleDiagnosticsLoggers.Parallel
23262330
2327- let runMethod =
2328- match tcConfig.parallelReferenceResolution with
2329- | ParallelReferenceResolution.On -> MultipleDiagnosticsLoggers.Parallel
2330- | ParallelReferenceResolution.Off -> MultipleDiagnosticsLoggers.Sequential
2331+ // Preserve determinicstic order of references, because types from later assemblies may shadow earlier ones.
2332+ let phase2s = assemblyData |> Seq.choose id |> Seq.map registerDll |> List.ofSeq
23312333
2332- let! results =
2333- nms
2334- |> List.map ( fun nm ->
2335- async {
2336- try
2337- use _ = new CompilationGlobalsScope()
2338- return ! tcImports.TryRegisterAndPrepareToImportReferencedDll( ctok, nm)
2339- with e ->
2340- errorR ( Error( FSComp.SR.buildProblemReadingAssembly ( nm.resolvedPath, e.Message), nm.originalReference.Range))
2341- return None
2342- })
2343- |> runMethod
2344-
2345- let _dllinfos , phase2s = results |> Array.choose id |> List.ofArray |> List.unzip
23462334 fixupOrphanCcus ()
2347- let ccuinfos = List.collect ( fun phase2 -> phase2 ()) phase2s
2335+
2336+ let ccuinfos = phase2s |> List.collect ( fun phase2 -> phase2 ())
23482337
23492338 if importsBase.IsSome then
23502339 importsBase.Value.CcuTable.Values |> Seq.iter addConstraintSources
0 commit comments