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
158 changes: 72 additions & 86 deletions src/fsharp/CompileOps.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2787,7 +2787,7 @@ type TcConfig private (data : TcConfigBuilder,validate:bool) =
(sourceFiles |> List.mapi (fun i _ -> (i = n-1)), tcConfig.target.IsExe)

// This call can fail if no CLR is found (this is the path to mscorlib)
member tcConfig.ClrRoot =
member tcConfig.TargetFrameworkDirectories =
use unwindBuildPhase = PushThreadBuildPhaseUntilUnwind (BuildPhase.Parameter)
match tcConfig.clrRoot with
| Some x ->
Expand Down Expand Up @@ -2844,15 +2844,15 @@ type TcConfig private (data : TcConfigBuilder,validate:bool) =
member tcConfig.IsSystemAssembly (filename:string) =
try
FileSystem.SafeExists filename &&
((tcConfig.ClrRoot |> List.exists (fun clrRoot -> clrRoot = Path.GetDirectoryName filename)) ||
((tcConfig.TargetFrameworkDirectories |> List.exists (fun clrRoot -> clrRoot = Path.GetDirectoryName filename)) ||
(systemAssemblies |> List.exists (fun sysFile -> sysFile = fileNameWithoutExtension filename)))
with _ ->
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)
member tcConfig.SearchPathsForLibraryFiles =
[ yield! tcConfig.ClrRoot
[ yield! tcConfig.TargetFrameworkDirectories
yield! List.map (tcConfig.MakePathAbsolute) tcConfig.includes
yield tcConfig.implicitIncludeDir
yield tcConfig.fsharpBinariesDir ]
Expand Down Expand Up @@ -2977,13 +2977,16 @@ type TcConfig private (data : TcConfigBuilder,validate:bool) =
assemblyName, highestPosition, assemblyGroup)
|> Array.ofSeq

let logmessage showMessages =
let logMessage showMessages =
if showMessages && tcConfig.showReferenceResolutions then (fun (message:string)->dprintf "%s\n" message)
else ignore

let logwarning showMessages =
(fun code message->
let logErrorOrWarning showMessages =
(fun isError code message->
if showMessages && mode = ReportErrors then
if isError then
errorR(MSBuildReferenceResolutionError(code,message,errorAndWarningRange))
else
match code with
// These are warnings that mean 'not resolved' for some assembly.
// Note that we don't get to know the name of the assembly that couldn't be resolved.
Expand All @@ -2992,15 +2995,10 @@ type TcConfig private (data : TcConfigBuilder,validate:bool) =
| "MSB3106"
-> ()
| _ ->
(if code = "MSB3245" then errorR else warning)
(MSBuildReferenceResolutionWarning(code,message,errorAndWarningRange)))

let logerror showMessages =
(fun code message ->
if showMessages && mode = ReportErrors then
errorR(MSBuildReferenceResolutionError(code,message,errorAndWarningRange)))

let targetFrameworkVersion = tcConfig.targetFrameworkVersion
if code = "MSB3245" then
errorR(MSBuildReferenceResolutionWarning(code,message,errorAndWarningRange))
else
warning(MSBuildReferenceResolutionWarning(code,message,errorAndWarningRange)))

let targetProcessorArchitecture =
match tcConfig.platform with
Expand All @@ -3009,13 +3007,6 @@ type TcConfig private (data : TcConfigBuilder,validate:bool) =
| Some(AMD64) -> "amd64"
| Some(IA64) -> "ia64"

let outputDirectory =
match tcConfig.outputFile with
| Some(outputFile) -> tcConfig.MakePathAbsolute outputFile
| None -> tcConfig.implicitIncludeDir

let targetFrameworkDirectories = tcConfig.ClrRoot

// First, try to resolve everything as a file using simple resolution
let resolvedAsFile =
groupedReferences
Expand All @@ -3031,14 +3022,13 @@ type TcConfig private (data : TcConfigBuilder,validate:bool) =
tcConfig.referenceResolver.Resolve
(tcConfig.resolutionEnvironment,
references,
targetFrameworkVersion,
targetFrameworkDirectories,
tcConfig.targetFrameworkVersion,
tcConfig.TargetFrameworkDirectories,
targetProcessorArchitecture,
Path.GetDirectoryName(outputDirectory),
tcConfig.fsharpBinariesDir, // FSharp binaries directory
tcConfig.includes, // Explicit include directories
tcConfig.implicitIncludeDir, // Implicit include directory (likely the project directory)
logmessage showMessages, logwarning showMessages, logerror showMessages)
logMessage showMessages, logErrorOrWarning showMessages)
with
ReferenceResolver.ResolutionFailure -> error(Error(FSComp.SR.buildAssemblyResolutionFailed(),errorAndWarningRange))

Expand Down Expand Up @@ -4241,38 +4231,25 @@ type TcImports(tcConfigP:TcConfigProvider, initialResolutions:TcAssemblyResoluti
let invalidateCcu = new Event<_>()
#endif

// Adjust where the code for known F# libraries live relative to the installation of F#
let codeDir =
let dir = minfo.compileTimeWorkingDir
let knownLibraryLocation = @"src\fsharp\" // Help highlighting... "
let knownLibarySuffixes =
[ @"FSharp.Core"
@"FSharp.PowerPack"
@"FSharp.PowerPack.Linq"
@"FSharp.PowerPack.Metadata" ]
match knownLibarySuffixes |> List.tryFind (fun x -> dir.EndsWith(knownLibraryLocation + x,StringComparison.OrdinalIgnoreCase)) with
| None ->
dir
| Some libSuffix ->
// add "..\lib\FSharp.Core" to the F# binaries directory
Path.Combine(Path.Combine(tcConfig.fsharpBinariesDir,@"..\lib"),libSuffix)

let ccu =
CcuThunk.Create(ccuName, { ILScopeRef=ilScopeRef
Stamp = newStamp()
FileName = Some filename
QualifiedName= Some(ilScopeRef.QualifiedName)
SourceCodeDirectory = codeDir (* note: in some cases we fix up this information later *)
IsFSharp=true
Contents = mspec
let codeDir = minfo.compileTimeWorkingDir
let ccuData : CcuData =
{ ILScopeRef=ilScopeRef
Stamp = newStamp()
FileName = Some filename
QualifiedName= Some(ilScopeRef.QualifiedName)
SourceCodeDirectory = codeDir (* note: in some cases we fix up this information later *)
IsFSharp=true
Contents = mspec
#if EXTENSIONTYPING
InvalidateEvent=invalidateCcu.Publish
IsProviderGenerated = false
ImportProvidedType = (fun ty -> Import.ImportProvidedType (tcImports.GetImportMap()) m ty)
InvalidateEvent=invalidateCcu.Publish
IsProviderGenerated = false
ImportProvidedType = (fun ty -> Import.ImportProvidedType (tcImports.GetImportMap()) m ty)
#endif
UsesFSharp20PlusQuotations = minfo.usesQuotations
MemberSignatureEquality= (fun ty1 ty2 -> Tastops.typeEquivAux EraseAll (tcImports.GetTcGlobals()) ty1 ty2)
TypeForwarders = ImportILAssemblyTypeForwarders(tcImports.GetImportMap,m, ilModule.GetRawTypeForwarders()) })
UsesFSharp20PlusQuotations = minfo.usesQuotations
MemberSignatureEquality= (fun ty1 ty2 -> Tastops.typeEquivAux EraseAll (tcImports.GetTcGlobals()) ty1 ty2)
TypeForwarders = ImportILAssemblyTypeForwarders(tcImports.GetImportMap,m, ilModule.GetRawTypeForwarders()) }

let ccu = CcuThunk.Create(ccuName, ccuData)

let optdata =
lazy
Expand All @@ -4287,15 +4264,15 @@ type TcImports(tcConfigP:TcConfigProvider, initialResolutions:TcAssemblyResoluti
Some res)
let ilg = defaultArg ilGlobalsOpt EcmaILGlobals
let ccuinfo =
{ FSharpViewOfMetadata=ccu
AssemblyAutoOpenAttributes = ilModule.GetAutoOpenAttributes(ilg)
AssemblyInternalsVisibleToAttributes = ilModule.GetInternalsVisibleToAttributes(ilg)
FSharpOptimizationData=optdata
{ FSharpViewOfMetadata=ccu
AssemblyAutoOpenAttributes = ilModule.GetAutoOpenAttributes(ilg)
AssemblyInternalsVisibleToAttributes = ilModule.GetInternalsVisibleToAttributes(ilg)
FSharpOptimizationData=optdata
#if EXTENSIONTYPING
IsProviderGenerated = false
TypeProviders = []
IsProviderGenerated = false
TypeProviders = []
#endif
ILScopeRef = ilScopeRef }
ILScopeRef = ilScopeRef }
let phase2() =
#if EXTENSIONTYPING
match ilModule.TryGetRawILModule() with
Expand Down Expand Up @@ -4344,15 +4321,16 @@ type TcImports(tcConfigP:TcConfigProvider, initialResolutions:TcAssemblyResoluti
let phase2() = [tcImports.FindCcuInfo(m,ilShortAssemName,lookupOnly=true)]
dllinfo,phase2
else
let dllinfo = {RawMetadata=assemblyData
FileName=filename
let dllinfo =
{ RawMetadata=assemblyData
FileName=filename
#if EXTENSIONTYPING
ProviderGeneratedAssembly=None
IsProviderGenerated=false
ProviderGeneratedStaticLinkMap = None
ProviderGeneratedAssembly=None
IsProviderGenerated=false
ProviderGeneratedStaticLinkMap = None
#endif
ILScopeRef = ilScopeRef
ILAssemblyRefs = assemblyData.ILAssemblyRefs }
ILScopeRef = ilScopeRef
ILAssemblyRefs = assemblyData.ILAssemblyRefs }
tcImports.RegisterDll(dllinfo)
let ilg = defaultArg ilGlobalsOpt EcmaILGlobals
let phase2 =
Expand Down Expand Up @@ -5154,26 +5132,31 @@ type TcState =
tcsTcImplEnv = tcEnvAtEndOfLastInput }


/// Create the initial type checking state for compiling an assembly
let GetInitialTcState(m,ccuName,tcConfig:TcConfig,tcGlobals,tcImports:TcImports,niceNameGen,tcEnv0) =
ignore tcImports

// Create a ccu to hold all the results of compilation
let ccuType = NewCcuContents ILScopeRef.Local m ccuName (NewEmptyModuleOrNamespaceType Namespace)
let ccu =
CcuThunk.Create(ccuName,{IsFSharp=true
UsesFSharp20PlusQuotations=false

let ccuData : CcuData =
{ IsFSharp=true
UsesFSharp20PlusQuotations=false
#if EXTENSIONTYPING
InvalidateEvent=(new Event<_>()).Publish
IsProviderGenerated = false
ImportProvidedType = (fun ty -> Import.ImportProvidedType (tcImports.GetImportMap()) m ty)
InvalidateEvent=(new Event<_>()).Publish
IsProviderGenerated = false
ImportProvidedType = (fun ty -> Import.ImportProvidedType (tcImports.GetImportMap()) m ty)
#endif
FileName=None
Stamp = newStamp()
QualifiedName= None
SourceCodeDirectory = tcConfig.implicitIncludeDir
ILScopeRef=ILScopeRef.Local
Contents=ccuType
MemberSignatureEquality= (Tastops.typeEquivAux EraseAll tcGlobals)
TypeForwarders=Map.empty })
FileName=None
Stamp = newStamp()
QualifiedName= None
SourceCodeDirectory = tcConfig.implicitIncludeDir
ILScopeRef=ILScopeRef.Local
Contents=ccuType
MemberSignatureEquality= (Tastops.typeEquivAux EraseAll tcGlobals)
TypeForwarders=Map.empty }

let ccu = CcuThunk.Create(ccuName,ccuData)

// OK, is this is the FSharp.Core CCU then fix it up.
if tcConfig.compilingFslib then
Expand All @@ -5191,7 +5174,7 @@ let GetInitialTcState(m,ccuName,tcConfig:TcConfig,tcGlobals,tcImports:TcImports,
tcsRootSigsAndImpls = RootSigsAndImpls (rootSigs, rootImpls, allSigModulTyp, allImplementedSigModulTyp) }


/// Typecheck a single file or interactive entry into F# Interactive
/// Typecheck a single file (or interactive entry into F# Interactive)
let TypeCheckOneInputEventually
(checkForErrors , tcConfig:TcConfig, tcImports:TcImports,
tcGlobals, prefixPathOpt, tcSink, tcState: TcState, inp: ParsedInput) =
Expand Down Expand Up @@ -5302,12 +5285,14 @@ let TypeCheckOneInputEventually
return (tcState.TcEnvFromSignatures,EmptyTopAttrs,[]),tcState
}

/// Typecheck a single file (or interactive entry into F# Interactive)
let TypeCheckOneInput (checkForErrors, tcConfig, tcImports, tcGlobals, prefixPathOpt) tcState inp =
// 'use' ensures that the warning handler is restored at the end
use unwindEL = PushErrorLoggerPhaseUntilUnwind(fun oldLogger -> GetErrorLoggerFilteringByScopedPragmas(false,GetScopedPragmasForInput(inp),oldLogger) )
use unwindBP = PushThreadBuildPhaseUntilUnwind (BuildPhase.TypeCheck)
TypeCheckOneInputEventually (checkForErrors, tcConfig, tcImports, tcGlobals, prefixPathOpt, TcResultsSink.NoSink, tcState, inp) |> Eventually.force

/// Finish checking multiple files (or one interactive entry into F# Interactive)
let TypeCheckMultipleInputsFinish(results,tcState: TcState) =
let tcEnvsAtEndFile,topAttrs,mimpls = List.unzip3 results

Expand All @@ -5318,11 +5303,12 @@ let TypeCheckMultipleInputsFinish(results,tcState: TcState) =

(tcEnvAtEndOfLastFile,topAttrs,mimpls),tcState

/// Check multiple files (or one interactive entry into F# Interactive)
let TypeCheckMultipleInputs (checkForErrors, tcConfig: TcConfig, tcImports, tcGlobals, prefixPathOpt, tcState, inputs) =
let results,tcState = (tcState, inputs) ||> List.mapFold (TypeCheckOneInput (checkForErrors, tcConfig, tcImports, tcGlobals, prefixPathOpt))
TypeCheckMultipleInputsFinish(results,tcState)

let TypeCheckSingleInputAndFinishEventually(checkForErrors, tcConfig: TcConfig, tcImports, tcGlobals, prefixPathOpt, tcSink, tcState, input) =
let TypeCheckOneInputAndFinishEventually(checkForErrors, tcConfig: TcConfig, tcImports, tcGlobals, prefixPathOpt, tcSink, tcState, input) =
eventually {
let! results,tcState = TypeCheckOneInputEventually(checkForErrors, tcConfig, tcImports, tcGlobals, prefixPathOpt, tcSink, tcState, input)
return TypeCheckMultipleInputsFinish([results],tcState)
Expand Down
4 changes: 2 additions & 2 deletions src/fsharp/CompileOps.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -502,7 +502,7 @@ type TcConfig =


member ComputeLightSyntaxInitialStatus : string -> bool
member ClrRoot : string list
member TargetFrameworkDirectories : string list

/// Get the loaded sources that exist and issue a warning for the ones that don't
member GetAvailableLoadedSources : unit -> (range*string) list
Expand Down Expand Up @@ -724,7 +724,7 @@ val TypeCheckClosedInputSetFinish : TypedImplFile list * TcState -> TcState * Ty
val TypeCheckClosedInputSet :(unit -> bool) * TcConfig * TcImports * TcGlobals * Ast.LongIdent option * TcState * Ast.ParsedInput list -> TcState * TopAttribs * TypedImplFile list * TcEnv

/// Check a single input and finish the checking
val TypeCheckSingleInputAndFinishEventually :
val TypeCheckOneInputAndFinishEventually :
(unit -> bool) * TcConfig * TcImports * TcGlobals * Ast.LongIdent option * NameResolution.TcResultsSink * TcState * Ast.ParsedInput
-> Eventually<(TcEnv * TopAttribs * TypedImplFile list) * TcState>

Expand Down
Loading