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
85 changes: 28 additions & 57 deletions src/Compiler/Symbols/FSharpDiagnostic.fs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ namespace FSharp.Compiler.Diagnostics

open System

open FSharp.Compiler.AttributeChecking
open FSharp.Compiler.CheckExpressions
open FSharp.Compiler.ConstraintSolver
open FSharp.Compiler.SignatureConformance
Expand All @@ -26,11 +25,10 @@ open FSharp.Compiler.CompilerDiagnostics
open FSharp.Compiler.Diagnostics
open FSharp.Compiler.DiagnosticsLogger
open FSharp.Compiler.Text
open FSharp.Compiler.Text.Position
open FSharp.Compiler.Text.Range

module ExtendedData =
[<RequireQualifiedAccess; Experimental("This FCS API is experimental and subject to change.")>]
[<RequireQualifiedAccess>]
type DiagnosticContextInfo =
| NoContext
| IfExpression
Expand All @@ -46,7 +44,7 @@ module ExtendedData =
| FollowingPatternMatchClause
| PatternMatchGuard
| SequenceExpression
with

static member From(contextInfo: ContextInfo) =
match contextInfo with
| ContextInfo.NoContext -> NoContext
Expand All @@ -64,110 +62,83 @@ module ExtendedData =
| ContextInfo.PatternMatchGuard _ -> PatternMatchGuard
| ContextInfo.SequenceExpression _ -> SequenceExpression

[<Interface; Experimental("This FCS API is experimental and subject to change.")>]
type IFSharpDiagnosticExtendedData = interface end
type IFSharpDiagnosticExtendedData =
interface end

/// Additional data for diagnostics about obsolete attributes.
[<Class; Experimental("This FCS API is experimental and subject to change.")>]
type ObsoleteDiagnosticExtendedData
internal (diagnosticId: string option, urlFormat: string option) =
type ObsoleteDiagnosticExtendedData internal (diagnosticId: string option, urlFormat: string option) =
interface IFSharpDiagnosticExtendedData
/// Represents the DiagnosticId of the diagnostic
member this.DiagnosticId: string option = diagnosticId

/// Represents the URL format of the diagnostic
member this.DiagnosticId: string option = diagnosticId
member this.UrlFormat: string option = urlFormat

/// Additional data for diagnostics about experimental attributes.
[<Class; Experimental("This FCS API is experimental and subject to change.")>]
type ExperimentalExtendedData
internal (diagnosticId: string option, urlFormat: string option) =
type ExperimentalExtendedData internal (diagnosticId: string option, urlFormat: string option) =
interface IFSharpDiagnosticExtendedData
/// Represents the DiagnosticId of the diagnostic
member this.DiagnosticId: string option = diagnosticId

/// Represents the URL format of the diagnostic
member this.DiagnosticId: string option = diagnosticId
member this.UrlFormat: string option = urlFormat

[<Experimental("This FCS API is experimental and subject to change.")>]
type TypeMismatchDiagnosticExtendedData
internal (symbolEnv: SymbolEnv, dispEnv: DisplayEnv, expectedType: TType, actualType: TType, context: DiagnosticContextInfo) =
type TypeMismatchDiagnosticExtendedData internal (symbolEnv: SymbolEnv, dispEnv: DisplayEnv, expectedType: TType, actualType: TType,
context: DiagnosticContextInfo) =
interface IFSharpDiagnosticExtendedData

member x.ExpectedType = FSharpType(symbolEnv, expectedType)
member x.ActualType = FSharpType(symbolEnv, actualType)
member x.ContextInfo = context
member x.DisplayContext = FSharpDisplayContext(fun _ -> dispEnv)

[<Experimental("This FCS API is experimental and subject to change.")>]
type ExpressionIsAFunctionExtendedData
internal (symbolEnv: SymbolEnv, actualType: TType) =
type ExpressionIsAFunctionExtendedData internal (symbolEnv: SymbolEnv, actualType: TType) =
interface IFSharpDiagnosticExtendedData

member x.ActualType = FSharpType(symbolEnv, actualType)

[<Experimental("This FCS API is experimental and subject to change.")>]
type FieldNotContainedDiagnosticExtendedData
internal (symbolEnv: SymbolEnv, implTycon: Tycon, sigTycon: Tycon, signatureField: RecdField, implementationField: RecdField) =
type FieldNotContainedDiagnosticExtendedData internal (symbolEnv: SymbolEnv, implTycon: Tycon, sigTycon: Tycon,
signatureField: RecdField, implementationField: RecdField) =
interface IFSharpDiagnosticExtendedData

member x.SignatureField = FSharpField(symbolEnv, RecdFieldRef.RecdFieldRef(mkLocalTyconRef sigTycon, signatureField.Id.idText))
member x.ImplementationField = FSharpField(symbolEnv, RecdFieldRef.RecdFieldRef(mkLocalTyconRef implTycon, implementationField.Id.idText))

[<Experimental("This FCS API is experimental and subject to change.")>]
type ValueNotContainedDiagnosticExtendedData
internal (symbolEnv: SymbolEnv, signatureValue: Val, implValue: Val) =
member x.ImplementationField =
FSharpField(symbolEnv, RecdFieldRef.RecdFieldRef(mkLocalTyconRef implTycon, implementationField.Id.idText))

type ValueNotContainedDiagnosticExtendedData internal (symbolEnv: SymbolEnv, signatureValue: Val, implValue: Val) =
interface IFSharpDiagnosticExtendedData

member x.SignatureValue = FSharpMemberOrFunctionOrValue(symbolEnv, mkLocalValRef signatureValue)
member x.ImplementationValue = FSharpMemberOrFunctionOrValue(symbolEnv, mkLocalValRef implValue)

[<Experimental("This FCS API is experimental and subject to change.")>]
type ArgumentsInSigAndImplMismatchExtendedData
internal(sigArg: Ident, implArg: Ident) =
type ArgumentsInSigAndImplMismatchExtendedData internal (sigArg: Ident, implArg: Ident) =
interface IFSharpDiagnosticExtendedData

member x.SignatureName = sigArg.idText
member x.ImplementationName = implArg.idText
member x.SignatureRange = sigArg.idRange
member x.ImplementationRange = implArg.idRange

[<Class; Experimental("This FCS API is experimental and subject to change.")>]
type DefinitionsInSigAndImplNotCompatibleAbbreviationsDifferExtendedData
internal(signatureType: Tycon, implementationType: Tycon) =
type DefinitionsInSigAndImplNotCompatibleAbbreviationsDifferExtendedData internal (signatureType: Tycon, implementationType: Tycon) =
interface IFSharpDiagnosticExtendedData
member x.SignatureRange: range = signatureType.Range
member x.ImplementationRange: range = implementationType.Range

member x.SignatureRange = signatureType.Range
member x.ImplementationRange = implementationType.Range

open ExtendedData

type FSharpDiagnostic(m: range, severity: FSharpDiagnosticSeverity, message: string, subcategory: string, errorNum: int, numberPrefix: string, extendedData: IFSharpDiagnosticExtendedData option) =
type FSharpDiagnostic(m: range, severity: FSharpDiagnosticSeverity, message: string, subcategory: string, errorNum: int,
numberPrefix: string, extendedData: IFSharpDiagnosticExtendedData option) =
member _.Range = m

member _.Severity = severity

member _.Message = message

member _.Subcategory = subcategory

member _.ErrorNumber = errorNum

member _.ErrorNumberPrefix = numberPrefix

member _.ErrorNumberText = numberPrefix + errorNum.ToString("0000")

member _.Start = m.Start

member _.End = m.End

member _.StartLine = m.Start.Line

member _.EndLine = m.End.Line

member _.StartColumn = m.Start.Column

member _.EndColumn = m.End.Column

member _.FileName = m.FileName

[<Experimental("This FCS API is experimental and subject to change.")>]
member _.ExtendedData = extendedData

member _.WithStart newStart =
Expand Down Expand Up @@ -305,7 +276,7 @@ type DiagnosticsScope(flatErrors: bool) =
| None -> err ""

/// A diagnostics logger that capture diagnostics, filtering them according to warning levels etc.
type internal CompilationDiagnosticLogger (debugName: string, options: FSharpDiagnosticOptions, ?preprocess: (PhasedDiagnostic -> PhasedDiagnostic)) =
type internal CompilationDiagnosticLogger(debugName: string, options: FSharpDiagnosticOptions, ?preprocess: (PhasedDiagnostic -> PhasedDiagnostic)) =
inherit DiagnosticsLogger("CompilationDiagnosticLogger("+debugName+")")

let mutable errorCount = 0
Expand Down
93 changes: 60 additions & 33 deletions src/Compiler/Symbols/FSharpDiagnostic.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -11,46 +11,58 @@ open FSharp.Compiler.Symbols
open FSharp.Compiler.Text
open FSharp.Compiler.DiagnosticsLogger

module public ExtendedData =
module ExtendedData =
/// Information about the context of a type equation in type-mismatch-like diagnostic
[<RequireQualifiedAccess; Experimental("This FCS API is experimental and subject to change.")>]
type public DiagnosticContextInfo =
[<RequireQualifiedAccess>]
type DiagnosticContextInfo =
/// No context was given
| NoContext

/// The type equation comes from an IF expression
| IfExpression

/// The type equation comes from an omitted else branch
| OmittedElseBranch

/// The type equation comes from a type check of the result of an else branch
| ElseBranchResult

/// The type equation comes from the verification of record fields
| RecordFields

/// The type equation comes from the verification of a tuple in record fields
| TupleInRecordFields

/// The type equation comes from a list or array constructor
| CollectionElement

/// The type equation comes from a return in a computation expression
| ReturnInComputationExpression

/// The type equation comes from a yield in a computation expression
| YieldInComputationExpression

/// The type equation comes from a runtime type test
| RuntimeTypeTest
/// The type equation comes from an downcast where a upcast could be used

/// The type equation comes from a downcast where an upcast could be used
| DowncastUsedInsteadOfUpcast
/// The type equation comes from a return type of a pattern match clause (not the first clause)

/// The type equation comes from the return type of a pattern match clause (not the first clause)
| FollowingPatternMatchClause

/// The type equation comes from a pattern match guard
| PatternMatchGuard

/// The type equation comes from a sequence expression
| SequenceExpression

/// Contextually-relevant data to each particular diagnostic
[<Interface; Experimental("This FCS API is experimental and subject to change.")>]
type public IFSharpDiagnosticExtendedData = interface end
type IFSharpDiagnosticExtendedData = interface end

/// Additional data for diagnostics about obsolete attributes.
[<Class; Experimental("This FCS API is experimental and subject to change.")>]
type public ObsoleteDiagnosticExtendedData =
[<Class>]
type ObsoleteDiagnosticExtendedData =
interface IFSharpDiagnosticExtendedData

/// Represents the DiagnosticId of the diagnostic
Expand All @@ -60,8 +72,8 @@ module public ExtendedData =
member UrlFormat: string option

/// Additional data for diagnostics about experimental attributes.
[<Class; Experimental("This FCS API is experimental and subject to change.")>]
type public ExperimentalExtendedData =
[<Class>]
type ExperimentalExtendedData =
interface IFSharpDiagnosticExtendedData

/// Represents the DiagnosticId of the diagnostic
Expand All @@ -71,69 +83,84 @@ module public ExtendedData =
member UrlFormat: string option

/// Additional data for type-mismatch-like (usually with ErrorNumber = 1) diagnostics
[<Class; Experimental("This FCS API is experimental and subject to change.")>]
type public TypeMismatchDiagnosticExtendedData =
[<Class>]
type TypeMismatchDiagnosticExtendedData =
interface IFSharpDiagnosticExtendedData
/// Represents F# type expected in the current context

/// Represents the expected F# type in the current context
member ExpectedType: FSharpType
/// Represents F# type type actual in the current context

/// Represents the actual F# type in the current context
member ActualType: FSharpType

/// The context in which the type mismatch was found
member ContextInfo: DiagnosticContextInfo

/// Represents the information needed to format types
member DisplayContext: FSharpDisplayContext

/// Additional data for 'This expression is a function value, i.e. is missing arguments' diagnostic
[<Class; Experimental("This FCS API is experimental and subject to change.")>]
type public ExpressionIsAFunctionExtendedData =
[<Class>]
type ExpressionIsAFunctionExtendedData =
interface IFSharpDiagnosticExtendedData

/// Represents F# type of the expression
member ActualType: FSharpType

/// Additional data for diagnostics about a field whose declarations differ in signature and implementation
[<Class; Experimental("This FCS API is experimental and subject to change.")>]
type public FieldNotContainedDiagnosticExtendedData =
[<Class>]
type FieldNotContainedDiagnosticExtendedData =
interface IFSharpDiagnosticExtendedData
/// Represents F# field in signature file

/// Represents F# field in the signature file
member SignatureField: FSharpField
/// Represents F# field in implementation file

/// Represents F# field in the implementation file
member ImplementationField: FSharpField

/// Additional data for diagnostics about a value whose declarations differ in signature and implementation
[<Class; Experimental("This FCS API is experimental and subject to change.")>]
type public ValueNotContainedDiagnosticExtendedData =
[<Class>]
type ValueNotContainedDiagnosticExtendedData =
interface IFSharpDiagnosticExtendedData

/// Represents F# value in signature file
member SignatureValue: FSharpMemberOrFunctionOrValue

/// Represents F# value in implementation file
member ImplementationValue: FSharpMemberOrFunctionOrValue

/// Additional data for 'argument names in the signature and implementation do not match' diagnostic
[<Class; Experimental("This FCS API is experimental and subject to change.")>]
[<Class>]
type ArgumentsInSigAndImplMismatchExtendedData =
interface IFSharpDiagnosticExtendedData
/// Argument name in signature file

/// Argument name in the signature file
member SignatureName: string
/// Argument name in implementation file

/// Argument name in the implementation file
member ImplementationName: string
/// Argument identifier range within signature file

/// Argument identifier range within the signature file
member SignatureRange: range
/// Argument identifier range within implementation file

/// Argument identifier range within the implementation file
member ImplementationRange: range

[<Class; Experimental("This FCS API is experimental and subject to change.")>]
[<Class>]
type DefinitionsInSigAndImplNotCompatibleAbbreviationsDifferExtendedData =
interface IFSharpDiagnosticExtendedData

/// Range of the signature type identifier.
member SignatureRange: range

/// Range of the implementation type identifier.
member ImplementationRange: range

open ExtendedData

/// Represents a diagnostic produced by the F# compiler
[<Class>]
type public FSharpDiagnostic =
type FSharpDiagnostic =

/// Gets the file name for the diagnostic
member FileName: string
Expand Down Expand Up @@ -165,7 +192,7 @@ type public FSharpDiagnostic =
/// Gets the message for the diagnostic
member Message: string

/// Gets the sub-category for the diagnostic
/// Gets the subcategory for the diagnostic
member Subcategory: string

/// Gets the number for the diagnostic
Expand All @@ -177,7 +204,7 @@ type public FSharpDiagnostic =
/// Gets the full error number text e.g "FS0031"
member ErrorNumberText: string

/// Gets the contextually-relevant data to each particular diagnostic for things like code fixes
/// Gets the contextually relevant data to each particular diagnostic for things like code fixes
[<Experimental("This FCS API is experimental and subject to change.")>]
member ExtendedData: IFSharpDiagnosticExtendedData option

Expand Down Expand Up @@ -222,7 +249,7 @@ type internal DiagnosticsScope =

static member Protect<'T> : range -> (unit -> 'T) -> (string -> 'T) -> 'T

/// An error logger that capture errors, filtering them according to warning levels etc.
/// An error logger that captures errors, filtering them according to warning levels etc.
type internal CompilationDiagnosticLogger =
inherit DiagnosticsLogger

Expand Down
Loading