Skip to content
Closed
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
11 changes: 0 additions & 11 deletions FSharp.sln
Original file line number Diff line number Diff line change
Expand Up @@ -196,16 +196,6 @@ Global
{4239EFEA-E746-446A-BF7A-51FCBAB13946}.Release|Any CPU.Build.0 = Release|Any CPU
{4239EFEA-E746-446A-BF7A-51FCBAB13946}.Release|x86.ActiveCfg = Release|Any CPU
{4239EFEA-E746-446A-BF7A-51FCBAB13946}.Release|x86.Build.0 = Release|Any CPU
{BF5C6D92-D053-4216-9C42-B62F5F5C5E91}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BF5C6D92-D053-4216-9C42-B62F5F5C5E91}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BF5C6D92-D053-4216-9C42-B62F5F5C5E91}.Debug|x86.ActiveCfg = Debug|Any CPU
{BF5C6D92-D053-4216-9C42-B62F5F5C5E91}.Debug|x86.Build.0 = Debug|Any CPU
{BF5C6D92-D053-4216-9C42-B62F5F5C5E91}.Proto|Any CPU.ActiveCfg = Release|Any CPU
{BF5C6D92-D053-4216-9C42-B62F5F5C5E91}.Proto|x86.ActiveCfg = Release|Any CPU
{BF5C6D92-D053-4216-9C42-B62F5F5C5E91}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BF5C6D92-D053-4216-9C42-B62F5F5C5E91}.Release|Any CPU.Build.0 = Release|Any CPU
{BF5C6D92-D053-4216-9C42-B62F5F5C5E91}.Release|x86.ActiveCfg = Release|Any CPU
{BF5C6D92-D053-4216-9C42-B62F5F5C5E91}.Release|x86.Build.0 = Release|Any CPU
{2E60864A-E3FF-4BCC-810F-DC7C34E6B236}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2E60864A-E3FF-4BCC-810F-DC7C34E6B236}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2E60864A-E3FF-4BCC-810F-DC7C34E6B236}.Debug|x86.ActiveCfg = Debug|Any CPU
Expand Down Expand Up @@ -245,7 +235,6 @@ Global
{A8D9641A-9170-4CF4-8FE0-6DB8C134E1B5} = {CFE3259A-2D30-4EB0-80D5-E8B5F3D01449}
{88E2D422-6852-46E3-A740-83E391DC7973} = {CFE3259A-2D30-4EB0-80D5-E8B5F3D01449}
{4239EFEA-E746-446A-BF7A-51FCBAB13946} = {CFE3259A-2D30-4EB0-80D5-E8B5F3D01449}
{BF5C6D92-D053-4216-9C42-B62F5F5C5E91} = {CFE3259A-2D30-4EB0-80D5-E8B5F3D01449}
{2E60864A-E3FF-4BCC-810F-DC7C34E6B236} = {CFE3259A-2D30-4EB0-80D5-E8B5F3D01449}
{BDA4D411-6AD9-4B3E-A3B3-07BAD6BEF1ED} = {CFE3259A-2D30-4EB0-80D5-E8B5F3D01449}
EndGlobalSection
Expand Down
192 changes: 90 additions & 102 deletions src/fsharp/CompileOps.fs

Large diffs are not rendered by default.

57 changes: 35 additions & 22 deletions src/fsharp/CompileOps.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -86,36 +86,41 @@ val SplitRelatedErrors : PhasedError -> PhasedError * PhasedError list
val OutputPhasedError : ErrorLogger.ErrorStyle -> StringBuilder -> PhasedError -> bool -> unit

/// Output an error or warning to a buffer
val OutputErrorOrWarning : implicitIncludeDir:string * showFullPaths: bool * flattenErrors: bool * errorStyle: ErrorStyle * warning:bool -> StringBuilder -> PhasedError -> unit
val OutputDiagnostic : implicitIncludeDir:string * showFullPaths: bool * flattenErrors: bool * errorStyle: ErrorStyle * warning:bool -> StringBuilder -> PhasedError -> unit

/// Output extra context information for an error or warning to a buffer
val OutputErrorOrWarningContext : prefix:string -> fileLineFunction:(string -> int -> string) -> StringBuilder -> PhasedError -> unit
val OutputDiagnosticContext : prefix:string -> fileLineFunction:(string -> int -> string) -> StringBuilder -> PhasedError -> unit

/// Part of LegacyHostedCompilerForTesting
[<RequireQualifiedAccess>]
type ErrorLocation =
type DiagnosticLocation =
{ Range : range
File : string
TextRepresentation : string
IsEmpty : bool }

/// Part of LegacyHostedCompilerForTesting
[<RequireQualifiedAccess>]
type CanonicalInformation =
type DiagnosticCanonicalInformation =
{ ErrorNumber : int
Subcategory : string
TextRepresentation : string }

/// Part of LegacyHostedCompilerForTesting
[<RequireQualifiedAccess>]
type DetailedIssueInfo =
{ Location : ErrorLocation option
Canonical : CanonicalInformation
type DiagnosticDetailedInfo =
{ Location : DiagnosticLocation option
Canonical : DiagnosticCanonicalInformation
Message : string }

/// Part of LegacyHostedCompilerForTesting
[<RequireQualifiedAccess>]
type ErrorOrWarning =
type Diagnostic =
| Short of bool * string
| Long of bool * DetailedIssueInfo
| Long of bool * DiagnosticDetailedInfo

val CollectErrorOrWarning : implicitIncludeDir:string * showFullPaths: bool * flattenErrors: bool * errorStyle: ErrorStyle * warning:bool * PhasedError -> seq<ErrorOrWarning>
/// Part of LegacyHostedCompilerForTesting
val CollectDiagnostic : implicitIncludeDir:string * showFullPaths: bool * flattenErrors: bool * errorStyle: ErrorStyle * warning:bool * PhasedError -> seq<Diagnostic>

//----------------------------------------------------------------------------
// Resolve assembly references
Expand Down Expand Up @@ -732,6 +737,14 @@ type CodeContext =
| Compilation
| Editing

[<RequireQualifiedAccess>]
type LoadClosureInput =
{ FileName: string
SyntaxTree: ParsedInput option
ParseDiagnostics: (PhasedError * bool) list
MetaCommandDiagnostics: (PhasedError * bool) list }


[<RequireQualifiedAccess>]
type LoadClosure =
{ /// The source files along with the ranges of the #load positions in each file.
Expand All @@ -740,26 +753,26 @@ type LoadClosure =
/// The resolved references along with the ranges of the #r positions in each file.
References: (string * AssemblyResolution list) list

/// The list of references that were not resolved during load closure. These may still be extension references.
/// The list of references that were not resolved during load closure.
UnresolvedReferences : UnresolvedAssemblyReference list

/// The list of all sources in the closure with inputs when available
Inputs: (string * ParsedInput option * PhasedError list * PhasedError list) list
/// The list of all sources in the closure with inputs when available, with associated parse errors and warnings
Inputs: LoadClosureInput list

/// The original #load references, including those that didn't resolve
OriginalLoadReferences: (range * string) list

/// The #nowarns
NoWarns: (string * range list) list

/// Errors seen while processing resolutions
ResolutionErrors : PhasedError list

/// Warnings seen while processing resolutions
ResolutionWarnings : PhasedError list
/// Diagnostics seen while processing resolutions
ResolutionDiagnostics : (PhasedError * bool) list

/// *Parse* errors seen while parsing root of closure
RootErrors : PhasedError list
/// Diagnostics to show for root of closure (used by fsc.fs)
AllRootFileDiagnostics : (PhasedError * bool) list

/// *Parse* warnings seen while parsing root of closure
RootWarnings : PhasedError list }
/// Diagnostics seen while processing the compiler options implied root of closure
LoadClosureRootFileDiagnostics : (PhasedError * bool) list }

// Used from service.fs, when editing a script file
static member ComputeClosureOfSourceText : referenceResolver: ReferenceResolver.Resolver * filename: string * source: string * implicitDefines:CodeContext * useSimpleResolution: bool * useFsiAuxLib: bool * lexResourceManager: Lexhelp.LexResourceManager * applyCompilerOptions: (TcConfigBuilder -> unit) * assumeDotNetFramework : bool -> LoadClosure
Expand Down
4 changes: 2 additions & 2 deletions src/fsharp/CompileOptions.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1342,7 +1342,7 @@ let GetGeneratedILModuleName (t:CompilerTarget) (s:string) =

let ignoreFailureOnMono1_1_16 f = try f() with _ -> ()

let DoWithErrorColor isWarn f =
let DoWithErrorColor isError f =
if not enableConsoleColoring then
f()
else
Expand All @@ -1359,7 +1359,7 @@ let DoWithErrorColor isWarn f =
try
let warnColor = if Console.BackgroundColor = ConsoleColor.White then ConsoleColor.DarkBlue else ConsoleColor.Cyan
let errorColor = ConsoleColor.Red
ignoreFailureOnMono1_1_16 (fun () -> Console.ForegroundColor <- (if isWarn then warnColor else errorColor))
ignoreFailureOnMono1_1_16 (fun () -> Console.ForegroundColor <- (if isError then errorColor else warnColor))
f()
finally
ignoreFailureOnMono1_1_16 (fun () -> Console.ForegroundColor <- c)
2 changes: 1 addition & 1 deletion src/fsharp/CompileOptions.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ val NormalizeAssemblyRefs : TcImports -> (AbstractIL.IL.ILScopeRef -> AbstractIL
// Miscellany
val ignoreFailureOnMono1_1_16 : (unit -> unit) -> unit
val mutable enableConsoleColoring : bool
val DoWithErrorColor : bool -> (unit -> 'a) -> 'a
val DoWithErrorColor : isError:bool -> (unit -> 'a) -> 'a
val ReportTime : TcConfig -> string -> unit
val GetAbbrevFlagSet : TcConfigBuilder -> bool -> Set<string>
val PostProcessCompilerArgs : string Set -> string [] -> string list
Expand Down
70 changes: 31 additions & 39 deletions src/fsharp/ErrorLogger.fs
Original file line number Diff line number Diff line change
Expand Up @@ -248,39 +248,33 @@ type ErrorLogger(nameForDebugging:string) =
abstract ErrorCount: int
// The 'Impl' factoring enables a developer to place a breakpoint at the non-Impl
// code just below and get a breakpoint for all error logger implementations.
abstract WarnSinkImpl: PhasedError -> unit
abstract ErrorSinkImpl: PhasedError -> unit
member this.WarnSink err =
this.WarnSinkImpl err
member this.ErrorSink err =
this.ErrorSinkImpl err
abstract DiagnosticSink: phasedError: PhasedError * isError: bool -> unit
member this.DebugDisplay() = sprintf "ErrorLogger(%s)" nameForDebugging
// Record the reported error/warning numbers for SQM purpose
abstract ErrorNumbers : int list
abstract WarningNumbers : int list
default this.ErrorNumbers = []
default this.WarningNumbers = []

let DiscardErrorsLogger =
{ new ErrorLogger("DiscardErrorsLogger") with
member x.WarnSinkImpl(e) =
()
member x.ErrorSinkImpl(e) =
()
member x.ErrorCount =
0 }
member x.DiagnosticSink(phasedError,isError) = ()
member x.ErrorCount = 0 }

let AssertFalseErrorLogger =
{ new ErrorLogger("AssertFalseErrorLogger") with
member x.WarnSinkImpl(e) =
assert false; ()
member x.ErrorSinkImpl(e) =
assert false; ()
member x.ErrorCount =
assert false; 0 }
member x.DiagnosticSink(phasedError,isError) = assert false; ()
member x.ErrorCount = assert false; 0 }

type CapturingErrorLogger(nm) =
inherit ErrorLogger(nm)
let mutable errorCount = 0
let diagnostics = ResizeArray()
override x.DiagnosticSink(phasedError, isError) =
if isError then errorCount <- errorCount + 1
diagnostics.Add (phasedError, isError)
override x.ErrorCount = errorCount
member x.Diagnostics = diagnostics |> Seq.toList
member x.CommitDelayedDiagnostics(errorLogger:ErrorLogger) =
// Eagerly grab all the errors and warnings from the mutable collection
let errors = diagnostics.ToArray()
errors |> Array.iter errorLogger.DiagnosticSink

/// When no errorLogger is installed (on the thread) use this one.
let uninitializedErrorLoggerFallback = ref AssertFalseErrorLogger

/// Type holds thread-static globals for use by the compile.
type internal CompileThreadStatic =
Expand All @@ -301,7 +295,7 @@ type internal CompileThreadStatic =
static member ErrorLogger
with get() =
match box CompileThreadStatic.errorLogger with
| null -> !uninitializedErrorLoggerFallback
| null -> AssertFalseErrorLogger
| _ -> CompileThreadStatic.errorLogger
and set v = CompileThreadStatic.errorLogger <- v

Expand Down Expand Up @@ -343,15 +337,15 @@ module ErrorLoggerExtensions =
#endif

type ErrorLogger with
member x.ErrorR exn = match exn with StopProcessing | ReportedError _ -> raise exn | _ -> x.ErrorSink(PhasedError.Create(exn,CompileThreadStatic.BuildPhase))
member x.Warning exn = match exn with StopProcessing | ReportedError _ -> raise exn | _ -> x.WarnSink(PhasedError.Create(exn,CompileThreadStatic.BuildPhase))
member x.ErrorR exn = match exn with StopProcessing | ReportedError _ -> raise exn | _ -> x.DiagnosticSink(PhasedError.Create(exn,CompileThreadStatic.BuildPhase), true)
member x.Warning exn = match exn with StopProcessing | ReportedError _ -> raise exn | _ -> x.DiagnosticSink(PhasedError.Create(exn,CompileThreadStatic.BuildPhase), false)
member x.Error exn = x.ErrorR exn; raise (ReportedError (Some exn))
member x.PhasedError (ph:PhasedError) =
x.ErrorSink ph
x.DiagnosticSink (ph, true)
raise (ReportedError (Some ph.Exception))
member x.ErrorRecovery (exn:exn) (m:range) =
// Never throws ReportedError.
// Throws StopProcessing and exceptions raised by the ErrorSink(exn) handler.
// Throws StopProcessing and exceptions raised by the DiagnosticSink(exn) handler.
match exn with
(* Don't send ThreadAbortException down the error channel *)
#if FX_REDUCED_EXCEPTIONS
Expand All @@ -370,13 +364,13 @@ module ErrorLoggerExtensions =
// Do standard error recovery.
// Additionally ignore/catch StopProcessing. [This is the only catch handler for StopProcessing].
// Additionally ignore/catch ReportedError.
// Can throw other exceptions raised by the ErrorSink(exn) handler.
// Can throw other exceptions raised by the DiagnosticSink(exn) handler.
match exn with
| StopProcessing | WrappedError(StopProcessing,_) -> () // suppress, so skip error recovery.
| _ ->
try x.ErrorRecovery exn m
with
| StopProcessing | WrappedError(StopProcessing,_) -> () // catch, e.g. raised by ErrorSink.
| StopProcessing | WrappedError(StopProcessing,_) -> () // catch, e.g. raised by DiagnosticSink.
| ReportedError _ | WrappedError(ReportedError _,_) -> () // catch, but not expected unless ErrorRecovery is changed.
member x.ErrorRecoveryNoRange (exn:exn) =
x.ErrorRecovery exn range0
Expand All @@ -395,8 +389,7 @@ let PushErrorLoggerPhaseUntilUnwind(errorLoggerTransformer : ErrorLogger -> #Err
let newInstalled = ref true
let newIsInstalled() = if !newInstalled then () else (assert false; (); (*failwith "error logger used after unwind"*)) // REVIEW: ok to throw?
let chkErrorLogger = { new ErrorLogger("PushErrorLoggerPhaseUntilUnwind") with
member x.WarnSinkImpl(e) = newIsInstalled(); newErrorLogger.WarnSink(e)
member x.ErrorSinkImpl(e) = newIsInstalled(); newErrorLogger.ErrorSink(e)
member x.DiagnosticSink(phasedError, isError) = newIsInstalled(); newErrorLogger.DiagnosticSink(phasedError, isError)
member x.ErrorCount = newIsInstalled(); newErrorLogger.ErrorCount }
CompileThreadStatic.ErrorLogger <- chkErrorLogger
{ new System.IDisposable with
Expand All @@ -406,7 +399,6 @@ let PushErrorLoggerPhaseUntilUnwind(errorLoggerTransformer : ErrorLogger -> #Err

let SetThreadBuildPhaseNoUnwind(phase:BuildPhase) = CompileThreadStatic.BuildPhase <- phase
let SetThreadErrorLoggerNoUnwind(errorLogger) = CompileThreadStatic.ErrorLogger <- errorLogger
let SetUninitializedErrorLoggerFallback errLogger = uninitializedErrorLoggerFallback := errLogger

// Global functions are still used by parser and TAST ops.
let errorR exn = CompileThreadStatic.ErrorLogger.ErrorR exn
Expand All @@ -415,8 +407,9 @@ let error exn = CompileThreadStatic.ErrorLogger.Error exn
// for test only
let phasedError (p : PhasedError) = CompileThreadStatic.ErrorLogger.PhasedError p

let errorSink pe = CompileThreadStatic.ErrorLogger.ErrorSink pe
let warnSink pe = CompileThreadStatic.ErrorLogger.WarnSink pe
let diagnosticSink (phasedError, isError) = CompileThreadStatic.ErrorLogger.DiagnosticSink (phasedError, isError)
let errorSink pe = diagnosticSink (pe, true)
let warnSink pe = diagnosticSink (pe, false)
let errorRecovery exn m = CompileThreadStatic.ErrorLogger.ErrorRecovery exn m
let stopProcessingRecovery exn m = CompileThreadStatic.ErrorLogger.StopProcessingRecovery exn m
let errorRecoveryNoRange exn = CompileThreadStatic.ErrorLogger.ErrorRecoveryNoRange exn
Expand All @@ -439,8 +432,7 @@ let suppressErrorReporting f =
try
let errorLogger =
{ new ErrorLogger("suppressErrorReporting") with
member x.WarnSinkImpl(_exn) = ()
member x.ErrorSinkImpl(_exn) = ()
member x.DiagnosticSink(_phasedError,_isError) = ()
member x.ErrorCount = 0 }
SetThreadErrorLoggerNoUnwind(errorLogger)
f()
Expand Down
3 changes: 1 addition & 2 deletions src/fsharp/FSharp.Compiler.Unittests/HashIfExpression.fs
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,7 @@ type HashIfExpression() =
let errorLogger =
{
new ErrorLogger("TestErrorLogger") with
member x.WarnSinkImpl(e) = warnings.Add e
member x.ErrorSinkImpl(e) = errors.Add e
member x.DiagnosticSink(e, isError) = if isError then errors.Add e else warnings.Add e
member x.ErrorCount = errors.Count
}

Expand Down
11 changes: 6 additions & 5 deletions src/fsharp/LegacyHostedCompilerForTesting.fs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ open System
open System.IO
open System.Text
open System.Text.RegularExpressions
open Microsoft.FSharp.Compiler
open Microsoft.FSharp.Compiler.Driver
open Microsoft.FSharp.Compiler.ErrorLogger
open Microsoft.FSharp.Compiler.CompileOps
Expand Down Expand Up @@ -48,8 +49,8 @@ type internal CompilationResult =

[<RequireQualifiedAccess>]
type internal CompilationOutput =
{ Errors : ErrorOrWarning[]
Warnings : ErrorOrWarning[] }
{ Errors : Diagnostic[]
Warnings : Diagnostic[] }

type internal InProcCompiler(referenceResolver) =
member this.Compile(argv) =
Expand All @@ -72,7 +73,7 @@ type internal InProcCompiler(referenceResolver) =

/// in-proc version of fsc.exe
type internal FscCompiler() =
let referenceResolver = Microsoft.FSharp.Compiler.MSBuildReferenceResolver.Resolver
let referenceResolver = MSBuildReferenceResolver.Resolver
let compiler = InProcCompiler(referenceResolver)

let emptyLocation =
Expand All @@ -86,7 +87,7 @@ type internal FscCompiler() =
/// converts short and long issue types to the same CompilationIssue reprsentation
let convert issue : CompilationIssue =
match issue with
| Microsoft.FSharp.Compiler.CompileOps.ErrorOrWarning.Short(isError, text) ->
| Diagnostic.Short(isError, text) ->
{
Location = emptyLocation
Code = ""
Expand All @@ -95,7 +96,7 @@ type internal FscCompiler() =
Text = text
Type = if isError then CompilationIssueType.Error else CompilationIssueType.Warning
}
| Microsoft.FSharp.Compiler.CompileOps.ErrorOrWarning.Long(isError, details) ->
| Diagnostic.Long(isError, details) ->
let loc, file =
match details.Location with
| Some l when not l.IsEmpty ->
Expand Down
Loading