33namespace FSharp.Compiler.DependencyManager
44
55open System
6+ open System.Collections .Generic
67open System.IO
78open System.Reflection
89open System.Runtime .InteropServices
@@ -152,14 +153,27 @@ type ReflectionDependencyManagerProvider
152153 resolveDepsExWithScriptInfoAndTimeout: MethodInfo option,
153154 clearResultCache: MethodInfo option,
154155 outputDir: string option,
155- useResultsCache: bool
156+ useResultsCache: bool,
157+ sdkDirOverride: string option
156158 ) =
157159
158160 let instance =
159- if not ( isNull ( theType.GetConstructor([| typeof< string option>; typeof< bool> |]))) then
160- Activator.CreateInstance( theType, [| outputDir :> objnull; useResultsCache :> objnull |])
161- else
162- Activator.CreateInstance( theType, [| outputDir :> objnull |])
161+ let arguments : ( Type * objnull ) array =
162+ [|
163+ typeof< string option>, outputDir
164+ typeof< bool>, useResultsCache
165+ typeof< IDictionary< string, obj>>, dict [ " sdkDirOverride" , sdkDirOverride :> obj ]
166+ |]
167+
168+ let n = arguments.Length
169+
170+ // Searches for the most suitable constructor,
171+ // starting from the latest version (with more parameters) and falling back to earlier ones.
172+ seq { for i in n - 1 .. - 1 .. 0 -> arguments[ 0 .. i] }
173+ |> Seq.map Array.unzip
174+ |> Seq.tryFind ( fun ( types , _ ) -> isNotNull ( theType.GetConstructor( types)))
175+ |> Option.map ( fun ( _ , values ) -> Activator.CreateInstance( theType, values))
176+ |> Option.toObj
163177
164178 let nameProperty ( x : objnull ) = x |> nameProperty.GetValue |> string
165179 let keyProperty ( x : objnull ) = x |> keyProperty.GetValue |> string
@@ -171,7 +185,7 @@ type ReflectionDependencyManagerProvider
171185 | Some helpMessagesProperty -> x |> helpMessagesProperty.GetValue |> toStringArray
172186 | None -> [||]
173187
174- static member InstanceMaker ( theType : Type , outputDir : string option , useResultsCache : bool ) =
188+ static member InstanceMaker ( theType : Type , outputDir : string option , useResultsCache : bool , sdkDirOverride : string option ) =
175189 match
176190 getAttributeNamed theType dependencyManagerAttributeName,
177191 getInstanceProperty< string> theType namePropertyName,
@@ -246,7 +260,8 @@ type ReflectionDependencyManagerProvider
246260 resolveDepsExWithScriptInfoAndTimeout,
247261 clearResultsCacheMethod,
248262 outputDir,
249- useResultsCache
263+ useResultsCache,
264+ sdkDirOverride
250265 )
251266 :> IDependencyManagerProvider)
252267
@@ -315,7 +330,8 @@ type ReflectionDependencyManagerProvider
315330 resolveDepsExWithScriptInfoAndTimeout,
316331 clearResultsCacheMethod,
317332 outputDir,
318- useResultsCache
333+ useResultsCache,
334+ sdkDirOverride
319335 )
320336 :> IDependencyManagerProvider)
321337
@@ -510,7 +526,12 @@ type DependencyProvider
510526 let mutable registeredDependencyManagers : Map < string , IDependencyManagerProvider > option =
511527 None
512528
513- let RegisteredDependencyManagers ( compilerTools : seq < string >) ( outputDir : string option ) ( reportError : ResolvingErrorReport ) =
529+ let RegisteredDependencyManagers
530+ ( compilerTools : seq < string >)
531+ ( outputDir : string option )
532+ ( sdkDirOverride : string option )
533+ ( reportError : ResolvingErrorReport )
534+ =
514535 match registeredDependencyManagers with
515536 | Some managers -> managers
516537 | None ->
@@ -520,7 +541,8 @@ type DependencyProvider
520541 let loadedProviders =
521542 enumerateDependencyManagerAssemblies compilerTools reportError
522543 |> Seq.collect ( fun a -> a.GetTypes())
523- |> Seq.choose ( fun t -> ReflectionDependencyManagerProvider.InstanceMaker( t, outputDir, useResultsCache))
544+ |> Seq.choose ( fun t ->
545+ ReflectionDependencyManagerProvider.InstanceMaker( t, outputDir, useResultsCache, sdkDirOverride))
524546 |> Seq.map ( fun maker -> maker ())
525547
526548 defaultProviders
@@ -547,32 +569,37 @@ type DependencyProvider
547569 new () = new DependencyProvider( None, None, true )
548570
549571 /// Returns a formatted help messages for registered dependencymanagers for the host to present
550- member _.GetRegisteredDependencyManagerHelpText ( compilerTools , outputDir : string | null , errorReport ) =
572+ member _.GetRegisteredDependencyManagerHelpText ( compilerTools , outputDir : string | null , sdkDirOverride : string option , errorReport ) =
551573 [|
552574 let managers =
553- RegisteredDependencyManagers compilerTools ( Option.ofString outputDir) errorReport
575+ RegisteredDependencyManagers compilerTools ( Option.ofString outputDir) sdkDirOverride errorReport
554576
555577 for kvp in managers do
556578 let dm = kvp.Value
557579 yield ! dm.HelpMessages
558580 |]
559581
560582 /// Clear the DependencyManager results caches
561- member _.ClearResultsCache ( compilerTools , outputDir : string | null , errorReport ) =
583+ member _.ClearResultsCache ( compilerTools , outputDir : string | null , sdkDirOverride : string option , errorReport ) =
562584 let managers =
563- RegisteredDependencyManagers compilerTools ( Option.ofString outputDir) errorReport
585+ RegisteredDependencyManagers compilerTools ( Option.ofString outputDir) sdkDirOverride errorReport
564586
565587 for kvp in managers do
566588 kvp.Value.ClearResultsCache()
567589
568590 /// Returns a formatted error message for the host to present
569591 member _.CreatePackageManagerUnknownError
570- ( compilerTools : seq < string >, outputDir : string , packageManagerKey : string , reportError : ResolvingErrorReport )
571- =
592+ (
593+ compilerTools : seq < string >,
594+ outputDir : string ,
595+ sdkDirOverride : string option ,
596+ packageManagerKey : string ,
597+ reportError : ResolvingErrorReport
598+ ) =
572599 let registeredKeys =
573600 String.Join(
574601 " , " ,
575- RegisteredDependencyManagers compilerTools ( Option.ofString outputDir) reportError
602+ RegisteredDependencyManagers compilerTools ( Option.ofString outputDir) sdkDirOverride reportError
576603 |> Seq.map ( fun kv -> kv.Value.Key)
577604 )
578605
@@ -581,17 +608,17 @@ type DependencyProvider
581608
582609 /// Fetch a dependencymanager that supports a specific key
583610 member this.TryFindDependencyManagerInPath
584- ( compilerTools : seq < string >, outputDir : string , reportError : ResolvingErrorReport , path : string )
611+ ( compilerTools : seq < string >, outputDir : string , sdkDirOverride : string option , reportError : ResolvingErrorReport , path : string )
585612 : string | null * IDependencyManagerProvider | null =
586613 try
587614 if path.Contains " :" && not ( Path.IsPathRooted path) then
588615 let managers =
589- RegisteredDependencyManagers compilerTools ( Option.ofString outputDir) reportError
616+ RegisteredDependencyManagers compilerTools ( Option.ofString outputDir) sdkDirOverride reportError
590617
591618 match managers |> Seq.tryFind ( fun kv -> path.StartsWithOrdinal( kv.Value.Key + " :" )) with
592619 | None ->
593620 let err , msg =
594- this.CreatePackageManagerUnknownError( compilerTools, outputDir, path.Split( ':' ).[ 0 ], reportError)
621+ this.CreatePackageManagerUnknownError( compilerTools, outputDir, sdkDirOverride , path.Split( ':' ).[ 0 ], reportError)
595622
596623 reportError.Invoke( ErrorReportType.Error, err, msg)
597624 null , null
@@ -607,10 +634,10 @@ type DependencyProvider
607634
608635 /// Fetch a dependencymanager that supports a specific key
609636 member _.TryFindDependencyManagerByKey
610- ( compilerTools : seq < string >, outputDir : string , reportError : ResolvingErrorReport , key : string )
637+ ( compilerTools : seq < string >, outputDir : string , sdkDirOverride : string option , reportError : ResolvingErrorReport , key : string )
611638 : IDependencyManagerProvider | null =
612639 try
613- RegisteredDependencyManagers compilerTools ( Option.ofString outputDir) reportError
640+ RegisteredDependencyManagers compilerTools ( Option.ofString outputDir) sdkDirOverride reportError
614641 |> Map.tryFind key
615642 |> Option.toObj
616643
0 commit comments