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
81 changes: 49 additions & 32 deletions src/fsharp/CompileOps.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2141,6 +2141,7 @@ type TcConfigBuilder =

/// When false FSI will lock referenced assemblies requiring process restart, false = disable Shadow Copy false (*default*)
mutable shadowCopyReferences: bool
mutable useSdkRefs: bool

/// A function to call to try to get an object that acts as a snapshot of the metadata section of a .NET binary,
/// and from which we can read the metadata. Only used when metadataOnly=true.
Expand Down Expand Up @@ -2280,6 +2281,7 @@ type TcConfigBuilder =
exename = None
copyFSharpCore = CopyFSharpCoreFlag.No
shadowCopyReferences = false
useSdkRefs = true
tryGetMetadataSnapshot = (fun _ -> None)
internalTestSpanStackReferring = false
noConditionalErasure = false
Expand Down Expand Up @@ -2747,6 +2749,7 @@ type TcConfig private (data: TcConfigBuilder, validate: bool) =
member x.emitDebugInfoInQuotations = data.emitDebugInfoInQuotations
member x.copyFSharpCore = data.copyFSharpCore
member x.shadowCopyReferences = data.shadowCopyReferences
member x.useSdkRefs = data.useSdkRefs
member x.tryGetMetadataSnapshot = data.tryGetMetadataSnapshot
member x.internalTestSpanStackReferring = data.internalTestSpanStackReferring
member x.noConditionalErasure = data.noConditionalErasure
Expand Down Expand Up @@ -2795,6 +2798,11 @@ type TcConfig private (data: TcConfigBuilder, validate: bool) =
if Directory.Exists runtimeRootWPF then
yield runtimeRootWPF // PresentationCore.dll is in C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF

match getFrameworkRefsPackDirectory with
| Some path when Directory.Exists(path) ->
yield path
| _ -> ()

| ResolutionEnvironment.EditingOrCompilation _ ->
#if ENABLE_MONO_SUPPORT
if runningOnMono then
Expand Down Expand Up @@ -2857,13 +2865,14 @@ type TcConfig private (data: TcConfigBuilder, validate: bool) =
///
/// Returning true may mean that the file is locked and/or placed into the
/// 'framework' reference set that is potentially shared across multiple compilations.
member tcConfig.IsSystemAssembly (filename: string) =
try
FileSystem.SafeExists filename &&
member tcConfig.IsSystemAssembly (filename: string) =
try
FileSystem.SafeExists filename &&
((tcConfig.GetTargetFrameworkDirectories() |> List.exists (fun clrRoot -> clrRoot = Path.GetDirectoryName filename)) ||
(systemAssemblies.Contains(fileNameWithoutExtension filename)))
(systemAssemblies.Contains (fileNameWithoutExtension filename)) ||
isInReferenceAssemblyPackDirectory filename)
with _ ->
false
false

// This is not the complete set of search paths, it is just the set
// that is special to F# (as compared to MSBuild resolution)
Expand Down Expand Up @@ -3506,18 +3515,16 @@ type TcAssemblyResolutions(tcConfig: TcConfig, results: AssemblyResolution list,
TcConfig.TryResolveLibsUsingMSBuildRules (tcConfig, assemblyList, rangeStartup, ResolveAssemblyReferenceMode.ReportErrors)
TcAssemblyResolutions(tcConfig, resolved, unresolved @ knownUnresolved)


static member GetAllDllReferences (tcConfig: TcConfig) =
[
static member GetAllDllReferences (tcConfig: TcConfig) = [
let primaryReference = tcConfig.PrimaryAssemblyDllReference()
yield primaryReference
//yield primaryReference

if not tcConfig.compilingFslib then
yield tcConfig.CoreLibraryDllReference()

let assumeDotNetFramework = primaryReference.SimpleAssemblyNameIs("mscorlib")
if tcConfig.framework then
for s in defaultReferencesForScriptsAndOutOfProjectSources assumeDotNetFramework do
if tcConfig.framework then
for s in defaultReferencesForScriptsAndOutOfProjectSources assumeDotNetFramework tcConfig.useSdkRefs do
yield AssemblyReference(rangeStartup, (if s.EndsWith(".dll", StringComparison.OrdinalIgnoreCase) then s else s+".dll"), None)

if tcConfig.useFsiAuxLib then
Expand Down Expand Up @@ -4552,8 +4559,14 @@ type TcImports(tcConfigP: TcConfigProvider, initialResolutions: TcAssemblyResolu

// Note: TcImports are disposable - the caller owns this object and must dispose
let frameworkTcImports = new TcImports(tcConfigP, tcResolutions, None, None)

let primaryAssemblyReference = tcConfig.PrimaryAssemblyDllReference()

// Fetch the primaryAssembly from the referenced assemblies otherwise
let primaryAssemblyReference =
let path = frameworkDLLs |> List.tryFind(fun dll -> String.Compare(Path.GetFileNameWithoutExtension(dll.resolvedPath), tcConfig.primaryAssembly.Name, StringComparison.OrdinalIgnoreCase) = 0)
match path with
| Some p -> AssemblyReference(range0, p.resolvedPath, None)
| None -> tcConfig.PrimaryAssemblyDllReference()

let primaryAssemblyResolution = frameworkTcImports.ResolveAssemblyReference(ctok, primaryAssemblyReference, ResolveAssemblyReferenceMode.ReportErrors)
let! primaryAssem = frameworkTcImports.RegisterAndImportReferencedAssemblies(ctok, primaryAssemblyResolution)
let primaryScopeRef =
Expand All @@ -4568,7 +4581,7 @@ type TcImports(tcConfigP: TcConfigProvider, initialResolutions: TcAssemblyResolu
let! _assemblies = frameworkTcImports.RegisterAndImportReferencedAssemblies (ctok, tcResolutions.GetAssemblyResolutions())

// These are the DLLs we can search for well-known types
let sysCcus =
let sysCcus =
[| for ccu in frameworkTcImports.GetCcusInDeclOrder() do
//printfn "found sys ccu %s" ccu.AssemblyName
yield ccu |]
Expand Down Expand Up @@ -4913,8 +4926,8 @@ module private ScriptPreprocessClosure =
filename: string, codeContext,
useSimpleResolution, useFsiAuxLib,
basicReferences, applyCommandLineArgs,
assumeDotNetFramework, tryGetMetadataSnapshot,
reduceMemoryUsage) =
assumeDotNetFramework, useSdkRefs,
tryGetMetadataSnapshot, reduceMemoryUsage) =

let projectDir = Path.GetDirectoryName filename
let isInteractive = (codeContext = CodeContext.CompilationAndEvaluation)
Expand All @@ -4929,7 +4942,7 @@ module private ScriptPreprocessClosure =
applyCommandLineArgs tcConfigB

match basicReferences with
| None -> (basicReferencesForScriptLoadClosure useFsiAuxLib assumeDotNetFramework) |> List.iter(fun f->tcConfigB.AddReferencedAssemblyByPath(range0, f)) // Add script references
| None -> (basicReferencesForScriptLoadClosure useFsiAuxLib useSdkRefs assumeDotNetFramework) |> List.iter(fun f->tcConfigB.AddReferencedAssemblyByPath(range0, f)) // Add script references
| Some rs -> for m, r in rs do tcConfigB.AddReferencedAssemblyByPath(m, r)

tcConfigB.resolutionEnvironment <-
Expand All @@ -4942,8 +4955,10 @@ module private ScriptPreprocessClosure =
// Indicates that there are some references not in basicReferencesForScriptLoadClosure which should
// be added conditionally once the relevant version of mscorlib.dll has been detected.
tcConfigB.implicitlyResolveAssemblies <- false
tcConfigB.useSdkRefs <- useSdkRefs

TcConfig.Create(tcConfigB, validate=true)

let ClosureSourceOfFilename(filename, m, inputCodePage, parseRequired) =
try
let filename = FileSystem.GetFullPathShim filename
Expand Down Expand Up @@ -5111,12 +5126,13 @@ module private ScriptPreprocessClosure =

/// Given source text, find the full load closure. Used from service.fs, when editing a script file
let GetFullClosureOfScriptText
(ctok, legacyReferenceResolver, defaultFSharpBinariesDir,
filename, sourceText,
codeContext, useSimpleResolution, useFsiAuxLib,
lexResourceManager: Lexhelp.LexResourceManager,
(ctok, legacyReferenceResolver, defaultFSharpBinariesDir,
filename, sourceText, codeContext,
useSimpleResolution, useFsiAuxLib, useSdkRefs,
lexResourceManager: Lexhelp.LexResourceManager,
applyCommmandLineArgs, assumeDotNetFramework,
tryGetMetadataSnapshot, reduceMemoryUsage) =
tryGetMetadataSnapshot, reduceMemoryUsage) =

// Resolve the basic references such as FSharp.Core.dll first, before processing any #I directives in the script
//
// This is tries to mimic the action of running the script in F# Interactive - the initial context for scripting is created
Expand All @@ -5126,7 +5142,7 @@ module private ScriptPreprocessClosure =
CreateScriptTextTcConfig(legacyReferenceResolver, defaultFSharpBinariesDir,
filename, codeContext, useSimpleResolution,
useFsiAuxLib, None, applyCommmandLineArgs, assumeDotNetFramework,
tryGetMetadataSnapshot, reduceMemoryUsage)
useSdkRefs, tryGetMetadataSnapshot, reduceMemoryUsage)

let resolutions0, _unresolvedReferences = GetAssemblyResolutionInformation(ctok, tcConfig)
let references0 = resolutions0 |> List.map (fun r->r.originalReference.Range, r.resolvedPath) |> Seq.distinct |> List.ofSeq
Expand All @@ -5135,7 +5151,8 @@ module private ScriptPreprocessClosure =
let tcConfig =
CreateScriptTextTcConfig(legacyReferenceResolver, defaultFSharpBinariesDir, filename,
codeContext, useSimpleResolution, useFsiAuxLib, Some references0,
applyCommmandLineArgs, assumeDotNetFramework, tryGetMetadataSnapshot, reduceMemoryUsage)
applyCommmandLineArgs, assumeDotNetFramework, useSdkRefs,
tryGetMetadataSnapshot, reduceMemoryUsage)

let closureSources = [ClosureSource(filename, range0, sourceText, true)]
let closureFiles, tcConfig = FindClosureFiles(closureSources, tcConfig, codeContext, lexResourceManager)
Expand All @@ -5161,15 +5178,15 @@ type LoadClosure with
/// A temporary TcConfig is created along the way, is why this routine takes so many arguments. We want to be sure to use exactly the
/// same arguments as the rest of the application.
static member ComputeClosureOfScriptText
(ctok, legacyReferenceResolver, defaultFSharpBinariesDir,
filename: string, sourceText:ISourceText, codeContext, useSimpleResolution: bool,
useFsiAuxLib, lexResourceManager: Lexhelp.LexResourceManager,
applyCommmandLineArgs, assumeDotNetFramework, tryGetMetadataSnapshot, reduceMemoryUsage): LoadClosure =
(ctok, legacyReferenceResolver, defaultFSharpBinariesDir,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lots of trailing whitespace

filename: string, sourceText: ISourceText, codeContext, useSimpleResolution: bool,
useFsiAuxLib, useSdkRefs, lexResourceManager: Lexhelp.LexResourceManager,
applyCommmandLineArgs, assumeDotNetFramework, tryGetMetadataSnapshot, reduceMemoryUsage) =

use unwindBuildPhase = PushThreadBuildPhaseUntilUnwind BuildPhase.Parse
ScriptPreprocessClosure.GetFullClosureOfScriptText
(ctok, legacyReferenceResolver, defaultFSharpBinariesDir, filename, sourceText,
codeContext, useSimpleResolution, useFsiAuxLib, lexResourceManager,
(ctok, legacyReferenceResolver, defaultFSharpBinariesDir, filename, sourceText,
codeContext, useSimpleResolution, useFsiAuxLib, useSdkRefs, lexResourceManager,
applyCommmandLineArgs, assumeDotNetFramework, tryGetMetadataSnapshot, reduceMemoryUsage)

/// Analyze a set of script files and find the closure of their references.
Expand Down Expand Up @@ -5479,4 +5496,4 @@ let TypeCheckClosedInputSet (ctok, checkForErrors, tcConfig, tcImports, tcGlobal

// Existing public APIs delegate to newer implementations
let GetFSharpCoreLibraryName () = getFSharpCoreLibraryName
let DefaultReferencesForScriptsAndOutOfProjectSources assumeDotNetFramework = defaultReferencesForScriptsAndOutOfProjectSources assumeDotNetFramework
let DefaultReferencesForScriptsAndOutOfProjectSources assumeDotNetFramework = defaultReferencesForScriptsAndOutOfProjectSources assumeDotNetFramework false
10 changes: 6 additions & 4 deletions src/fsharp/CompileOps.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,7 @@ type TcConfigBuilder =
mutable exename: string option
mutable copyFSharpCore: CopyFSharpCoreFlag
mutable shadowCopyReferences: bool
mutable useSdkRefs: bool

/// A function to call to try to get an object that acts as a snapshot of the metadata section of a .NET binary,
/// and from which we can read the metadata. Only used when metadataOnly=true.
Expand All @@ -371,6 +372,7 @@ type TcConfigBuilder =

/// Prevent erasure of conditional attributes and methods so tooling is able analyse them.
mutable noConditionalErasure: bool

}

static member Initial: TcConfigBuilder
Expand All @@ -394,11 +396,9 @@ type TcConfigBuilder =
member RemoveReferencedAssemblyByPath: range * string -> unit
member AddEmbeddedSourceFile: string -> unit
member AddEmbeddedResource: string -> unit

static member SplitCommandLineResourceInfo: string -> string * string * ILResourceAccess

static member SplitCommandLineResourceInfo: string -> string * string * ILResourceAccess


[<Sealed>]
// Immutable TcConfig
type TcConfig =
Expand Down Expand Up @@ -531,6 +531,8 @@ type TcConfig =

member copyFSharpCore: CopyFSharpCoreFlag
member shadowCopyReferences: bool
member useSdkRefs: bool

static member Create: TcConfigBuilder * validate: bool -> TcConfig

/// Represents a computation to return a TcConfig. Normally this is just a constant immutable TcConfig,
Expand Down Expand Up @@ -801,7 +803,7 @@ type LoadClosure =
//
/// A temporary TcConfig is created along the way, is why this routine takes so many arguments. We want to be sure to use exactly the
/// same arguments as the rest of the application.
static member ComputeClosureOfScriptText: CompilationThreadToken * legacyReferenceResolver: ReferenceResolver.Resolver * defaultFSharpBinariesDir: string * filename: string * sourceText: ISourceText * implicitDefines:CodeContext * useSimpleResolution: bool * useFsiAuxLib: bool * lexResourceManager: Lexhelp.LexResourceManager * applyCompilerOptions: (TcConfigBuilder -> unit) * assumeDotNetFramework: bool * tryGetMetadataSnapshot: ILReaderTryGetMetadataSnapshot * reduceMemoryUsage: ReduceMemoryFlag -> LoadClosure
static member ComputeClosureOfScriptText: CompilationThreadToken * legacyReferenceResolver: ReferenceResolver.Resolver * defaultFSharpBinariesDir: string * filename: string * sourceText: ISourceText * implicitDefines:CodeContext * useSimpleResolution: bool * useFsiAuxLib: bool * useSdkRefs: bool * lexResourceManager: Lexhelp.LexResourceManager * applyCompilerOptions: (TcConfigBuilder -> unit) * assumeDotNetFramework: bool * tryGetMetadataSnapshot: ILReaderTryGetMetadataSnapshot * reduceMemoryUsage: ReduceMemoryFlag -> LoadClosure

/// Analyze a set of script files and find the closure of their references. The resulting references are then added to the given TcConfig.
/// Used from fsi.fs and fsc.fs, for #load and command line.
Expand Down
36 changes: 19 additions & 17 deletions src/fsharp/CompileOptions.fs
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,9 @@ let subSystemVersionSwitch (tcConfigB: TcConfigBuilder) (text: string) =
| _ -> fail()
| _ -> fail()

let SetUseSdkSwitch (tcConfigB: TcConfigBuilder) switch =
tcConfigB.useSdkRefs <- (switch = OptionSwitch.On)

let (++) x s = x @ [s]

let SetTarget (tcConfigB: TcConfigBuilder)(s: string) =
Expand Down Expand Up @@ -544,18 +547,21 @@ let PrintOptionInfo (tcConfigB:TcConfigBuilder) =
// OptionBlock: Input files
//-------------------------

let inputFileFlagsBoth (tcConfigB : TcConfigBuilder) =
[ CompilerOption("reference", tagFile, OptionString (fun s -> tcConfigB.AddReferencedAssemblyByPath (rangeStartup, s)), None,
Some (FSComp.SR.optsReference()) )
let inputFileFlagsBoth (tcConfigB: TcConfigBuilder) =
[ CompilerOption("reference", tagFile, OptionString (fun s -> tcConfigB.AddReferencedAssemblyByPath (rangeStartup, s)), None, Some (FSComp.SR.optsReference()))
]

let referenceFlagAbbrev (tcConfigB: TcConfigBuilder) =
CompilerOption("r", tagFile, OptionString (fun s -> tcConfigB.AddReferencedAssemblyByPath (rangeStartup, s)), None,
Some(FSComp.SR.optsShortFormOf("--reference")) )

let inputFileFlagsFsi tcConfigB = inputFileFlagsBoth tcConfigB
let inputFileFlagsFsc tcConfigB = inputFileFlagsBoth tcConfigB
let inputFileFlagsFsc tcConfigB = inputFileFlagsBoth tcConfigB

let inputFileFlagsFsiBase (_tcConfigB: TcConfigBuilder) =
#if NETSTANDARD
[ CompilerOption("usesdkrefs", tagNone, OptionSwitch (SetUseSdkSwitch _tcConfigB), None, Some (FSComp.SR.useSdkRefs())) ]
#else
List.empty<CompilerOption>
#endif

let inputFileFlagsFsi (tcConfigB: TcConfigBuilder) =
List.concat [ inputFileFlagsBoth tcConfigB; inputFileFlagsFsiBase tcConfigB]

// OptionBlock: Errors and warnings
//---------------------------------
Expand Down Expand Up @@ -825,12 +831,6 @@ let libFlag (tcConfigB: TcConfigBuilder) =
OptionStringList (fun s -> tcConfigB.AddIncludePath (rangeStartup, s, tcConfigB.implicitIncludeDir)), None,
Some (FSComp.SR.optsLib()))

let libFlagAbbrev (tcConfigB: TcConfigBuilder) =
CompilerOption
("I", tagDirList,
OptionStringList (fun s -> tcConfigB.AddIncludePath (rangeStartup, s, tcConfigB.implicitIncludeDir)), None,
Some (FSComp.SR.optsShortFormOf("--lib")))

let codePageFlag (tcConfigB: TcConfigBuilder) =
CompilerOption
("codepage", tagInt,
Expand Down Expand Up @@ -1395,8 +1395,10 @@ let abbreviatedFlagsBoth tcConfigB =
CompilerOption("O", tagNone, OptionSwitch (SetOptimizeSwitch tcConfigB), None, Some(FSComp.SR.optsShortFormOf("--optimize[+|-]")))
CompilerOption("g", tagNone, OptionSwitch (SetDebugSwitch tcConfigB None), None, Some(FSComp.SR.optsShortFormOf("--debug")))
CompilerOption("i", tagString, OptionUnit (fun () -> tcConfigB.printSignature <- true), None, Some(FSComp.SR.optsShortFormOf("--sig")))
referenceFlagAbbrev tcConfigB (* -r <dll> *)
libFlagAbbrev tcConfigB (* -I <dir> *)
CompilerOption("r", tagFile, OptionString (fun s -> tcConfigB.AddReferencedAssemblyByPath (rangeStartup, s)),
None, Some(FSComp.SR.optsShortFormOf("--reference")))
CompilerOption("I", tagDirList, OptionStringList (fun s -> tcConfigB.AddIncludePath (rangeStartup, s, tcConfigB.implicitIncludeDir)),
None, Some (FSComp.SR.optsShortFormOf("--lib")))
]

let abbreviatedFlagsFsi tcConfigB = abbreviatedFlagsBoth tcConfigB
Expand Down
Loading