diff --git a/samples/OptionAnalyzer.Test/UnitTests.fs b/samples/OptionAnalyzer.Test/UnitTests.fs index 1546fe5..8f52132 100644 --- a/samples/OptionAnalyzer.Test/UnitTests.fs +++ b/samples/OptionAnalyzer.Test/UnitTests.fs @@ -4,7 +4,6 @@ module OptionAnalyzer.Test open FSharp.Compiler.CodeAnalysis open NUnit.Framework -open FSharp.Compiler.Text open FSharp.Analyzers.SDK open FSharp.Analyzers.SDK.Testing open FSharp.Analyzers.SDK diff --git a/samples/OptionAnalyzer/Library.fs b/samples/OptionAnalyzer/Library.fs index 8e0ff5a..8cbd4d5 100644 --- a/samples/OptionAnalyzer/Library.fs +++ b/samples/OptionAnalyzer/Library.fs @@ -3,7 +3,6 @@ open System open FSharp.Analyzers.SDK open FSharp.Analyzers.SDK.TASTCollecting -open FSharp.Compiler.Text let notUsed () = let option: Option = None @@ -11,7 +10,7 @@ let notUsed () = let handler typeTree = async { - let state = ResizeArray() + let state = ResizeArray() let walker = { new TypedTreeCollectorBase() with diff --git a/src/FSharp.Analyzers.SDK/FSharp.Analyzers.SDK.fs b/src/FSharp.Analyzers.SDK/FSharp.Analyzers.SDK.fs index e0400e8..a0c3c86 100644 --- a/src/FSharp.Analyzers.SDK/FSharp.Analyzers.SDK.fs +++ b/src/FSharp.Analyzers.SDK/FSharp.Analyzers.SDK.fs @@ -12,6 +12,49 @@ open System.Runtime.InteropServices open FSharp.Compiler.Text open FSharp.Compiler.SyntaxTrivia +[] +type Position = + { + Line: int + Column: int + } + + static member mkPos (line: int) (column: int) : Position = { Line = line; Column = column } + +[] +type Range = + { + FileName: string + Start: Position + End: Position + } + + member r.StartLine = r.Start.Line + member r.StartColumn = r.Start.Column + member r.EndLine = r.End.Line + member r.EndColumn = r.End.Column + + static member mkRange (fileName: string) (startPos: Position) (endPos: Position) : Range = + { + FileName = fileName + Start = startPos + End = endPos + } + +/// Helpers for converting FCS position/range types to SDK types. +/// Useful for analyzer authors who work with FCS types and need to produce SDK messages. +module RangeConversions = + /// Converts an FCS pos to an SDK Position. + let ofFcsPos (p: FSharp.Compiler.Text.pos) : Position = { Line = p.Line; Column = p.Column } + + /// Converts an FCS range to an SDK Range. + let ofFcsRange (r: FSharp.Compiler.Text.range) : Range = + { + FileName = r.FileName + Start = ofFcsPos r.Start + End = ofFcsPos r.End + } + [] type IgnoreComment = | CurrentLine of line: int * codes: string list @@ -362,7 +405,7 @@ type EditorContext = type Fix = { - FromRange: range + FromRange: Range FromText: string ToText: string } @@ -380,7 +423,7 @@ type Message = Message: string Code: string Severity: Severity - Range: range + Range: Range Fixes: Fix list } diff --git a/src/FSharp.Analyzers.SDK/FSharp.Analyzers.SDK.fsi b/src/FSharp.Analyzers.SDK/FSharp.Analyzers.SDK.fsi index fcdad39..a1eabed 100644 --- a/src/FSharp.Analyzers.SDK/FSharp.Analyzers.SDK.fsi +++ b/src/FSharp.Analyzers.SDK/FSharp.Analyzers.SDK.fsi @@ -8,6 +8,54 @@ open FSharp.Compiler.Symbols open FSharp.Compiler.EditorServices open FSharp.Compiler.Text +/// Represents a position (line and column) in a source file. +/// This type is independent of any compiler implementation. +[] +type Position = + { + /// 1-based line number. + Line: int + /// 0-based column number. + Column: int + } + + /// Creates a Position from a line and column. + static member mkPos: line: int -> column: int -> Position + +/// Represents a range (start and end position) in a source file. +/// This type is independent of any compiler implementation. +[] +type Range = + { + /// The file name this range belongs to. + FileName: string + /// Start position of the range. + Start: Position + /// End position of the range. + End: Position + } + + /// 1-based start line of the range. + member StartLine: int + /// 0-based start column of the range. + member StartColumn: int + /// 1-based end line of the range. + member EndLine: int + /// 0-based end column of the range. + member EndColumn: int + + /// Creates a Range from a file name and start/end positions. + static member mkRange: fileName: string -> startPos: Position -> endPos: Position -> Range + +/// Helpers for converting FCS position/range types to SDK types. +/// Useful for analyzer authors who work with FCS types and need to produce SDK messages. +module RangeConversions = + /// Converts an FCS pos to an SDK Position. + val ofFcsPos: p: FSharp.Compiler.Text.pos -> Position + + /// Converts an FCS range to an SDK Range. + val ofFcsRange: r: FSharp.Compiler.Text.range -> Range + type AnalyzerIgnoreRange = | File | Range of commentStart: int * commentEnd: int @@ -155,7 +203,7 @@ type EditorContext = type Fix = { - FromRange: range + FromRange: Range FromText: string ToText: string } @@ -173,7 +221,7 @@ type Message = Message: string Code: string Severity: Severity - Range: range + Range: Range Fixes: Fix list } diff --git a/src/FSharp.Analyzers.SDK/FSharp.Analyzers.SDK.fsproj b/src/FSharp.Analyzers.SDK/FSharp.Analyzers.SDK.fsproj index c03f91c..f3843ef 100644 --- a/src/FSharp.Analyzers.SDK/FSharp.Analyzers.SDK.fsproj +++ b/src/FSharp.Analyzers.SDK/FSharp.Analyzers.SDK.fsproj @@ -12,10 +12,10 @@ - - + + diff --git a/src/FSharp.Analyzers.SDK/TASTCollecting.fs b/src/FSharp.Analyzers.SDK/TASTCollecting.fs index 8e659fe..c69dbd1 100644 --- a/src/FSharp.Analyzers.SDK/TASTCollecting.fs +++ b/src/FSharp.Analyzers.SDK/TASTCollecting.fs @@ -29,7 +29,7 @@ module TASTCollecting = objExprTypeArgs: FSharpType list -> memberOrFuncTypeArgs: FSharpType list -> argExprs: FSharpExpr list -> - exprRange: range -> + exprRange: FSharp.Analyzers.SDK.Range -> unit default _.WalkCall _ _ _ _ _ _ = () @@ -118,7 +118,10 @@ module TASTCollecting = default _.WalkNewObject _ _ _ = () abstract WalkNewRecord: - recordType: FSharpType -> argExprs: FSharpExpr list -> exprRange: range -> unit + recordType: FSharpType -> + argExprs: FSharpExpr list -> + exprRange: FSharp.Analyzers.SDK.Range -> + unit default _.WalkNewRecord _ _ _ = () @@ -282,7 +285,7 @@ module TASTCollecting = objExprTypeArgs memberOrFuncTypeArgs argExprs - e.Range + (RangeConversions.ofFcsRange e.Range) visitObjArg handler objExprOpt visitExprs handler argExprs @@ -343,7 +346,7 @@ module TASTCollecting = handler.WalkNewObject objType typeArgs argExprs visitExprs handler argExprs | NewRecord(recordType, argExprs) -> - handler.WalkNewRecord recordType argExprs e.Range + handler.WalkNewRecord recordType argExprs (RangeConversions.ofFcsRange e.Range) visitExprs handler argExprs | NewTuple(tupleType, argExprs) -> handler.WalkNewTuple tupleType argExprs diff --git a/src/FSharp.Analyzers.SDK/TASTCollecting.fsi b/src/FSharp.Analyzers.SDK/TASTCollecting.fsi index fd8cdc6..b4d4c8c 100644 --- a/src/FSharp.Analyzers.SDK/TASTCollecting.fsi +++ b/src/FSharp.Analyzers.SDK/TASTCollecting.fsi @@ -3,7 +3,6 @@ namespace FSharp.Analyzers.SDK open Microsoft.Extensions.Logging open FSharp.Compiler.Symbols open FSharp.Compiler.Syntax -open FSharp.Compiler.Text module TASTCollecting = @@ -34,7 +33,7 @@ module TASTCollecting = objExprTypeArgs: FSharpType list -> memberOrFuncTypeArgs: FSharpType list -> argExprs: FSharpExpr list -> - exprRange: range -> + exprRange: Range -> unit default WalkCall: @@ -43,7 +42,7 @@ module TASTCollecting = objTypeArgs: FSharpType list -> memberOrFuncTypeArgs: FSharpType list -> argExprs: FSharpExpr list -> - exprRange: range -> + exprRange: Range -> unit /// Overwriting this member hooks up a custom operation for type coercion. @@ -177,10 +176,10 @@ module TASTCollecting = /// Overwriting this member hooks up a custom operation for the creation of a new record instance. abstract WalkNewRecord: - recordType: FSharpType -> argExprs: FSharpExpr list -> exprRange: range -> unit + recordType: FSharpType -> argExprs: FSharpExpr list -> exprRange: Range -> unit default WalkNewRecord: - recordType: FSharpType -> argExprs: FSharpExpr list -> exprRange: range -> unit + recordType: FSharpType -> argExprs: FSharpExpr list -> exprRange: Range -> unit /// Overwriting this member hooks up a custom operation for the creation of a new tuple instance. abstract WalkNewTuple: tupleType: FSharpType -> argExprs: FSharpExpr list -> unit