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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Migrate from `Paket` to `Directory.Packages.props` #722 [@xperiandri]
- Migrate to .NET `9.0.201` and FCS `43.9.201` #722 [@xperiandri]
- Write test logs to test context output #722 [@xperiandri]
- Use string interpolation instead of `+` concatenation #724 [@xperiandri]

## [0.24.2] - 2024-02-29

Expand Down
4 changes: 2 additions & 2 deletions build.fsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ let authors = "Matthew Mcveigh"

let gitOwner = "fsprojects"
let gitName = "FSharpLint"
let gitHome = "https://github.com/" + gitOwner
let gitUrl = gitHome + "/" + gitName
let gitHome = $"https://github.com/{gitOwner}"
let gitUrl = $"{gitHome}/{gitName}"

// --------------------------------------------------------------------------------------
// Helpers
Expand Down
20 changes: 10 additions & 10 deletions docs/generators/apiref.fsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,10 @@ let generateType ctx (page: ApiPageInfo<Type>) =
div [Class "api-page"] [
h2 [] [!! t.Name]
b [] [!! "Namespace: "]
a [Href (sprintf "%s.html" page.NamespaceUrlName) ] [!! page.NamespaceName]
a [Href ($"%s{page.NamespaceUrlName}.html")] [!! page.NamespaceName]
br []
b [] [!! "Parent: "]
a [Href (sprintf "%s.html" page.ParentUrlName)] [!! page.ParentName]
a [Href ($"%s{page.ParentUrlName}.html")] [!! page.ParentName]
span [] [!! (getComment t.Comment)]
br []
if not (String.IsNullOrWhiteSpace t.Category) then
Expand Down Expand Up @@ -127,10 +127,10 @@ let generateModule ctx (page: ApiPageInfo<Module>) =
div [Class "api-page"] [
h2 [] [!!m.Name]
b [] [!! "Namespace: "]
a [Href (sprintf "%s.html" page.NamespaceUrlName) ] [!! page.NamespaceName]
a [Href ($"%s{page.NamespaceUrlName}.html")] [!! page.NamespaceName]
br []
b [] [!! "Parent: "]
a [Href (sprintf "%s.html" page.ParentUrlName)] [!! page.ParentName]
a [Href ($"%s{page.ParentUrlName}.html")] [!! page.ParentName]
span [] [!! (getComment m.Comment)]
br []
if not (String.IsNullOrWhiteSpace m.Category) then
Expand All @@ -147,7 +147,7 @@ let generateModule ctx (page: ApiPageInfo<Module>) =
]
for t in m.NestedTypes do
tr [] [
td [] [a [Href (sprintf "%s.html" t.UrlName )] [!! t.Name ]]
td [] [a [Href ($"%s{t.UrlName}.html")] [!! t.Name ]]
td [] [!! (getComment t.Comment)]
]
]
Expand All @@ -162,7 +162,7 @@ let generateModule ctx (page: ApiPageInfo<Module>) =
]
for t in m.NestedModules do
tr [] [
td [] [a [Href (sprintf "%s.html" t.UrlName )] [!! t.Name ]]
td [] [a [Href ($"%s{t.UrlName}.html")] [!! t.Name ]]
td [] [!! (getComment t.Comment)]
]
]
Expand Down Expand Up @@ -206,7 +206,7 @@ let generateNamespace ctx (n: Namespace) =
]
for t in n.Types do
tr [] [
td [] [a [Href (sprintf "%s.html" t.UrlName )] [!! t.Name ]]
td [] [a [Href ($"%s{t.UrlName}.html")] [!! t.Name ]]
td [] [!!(getComment t.Comment)]
]
]
Expand All @@ -222,7 +222,7 @@ let generateNamespace ctx (n: Namespace) =
]
for t in n.Modules do
tr [] [
td [] [a [Href (sprintf "%s.html" t.UrlName )] [!! t.Name ]]
td [] [a [Href ($"%s{t.UrlName}.html")] [!! t.Name ]]
td [] [!! (getComment t.Comment)]
]
]
Expand Down Expand Up @@ -257,12 +257,12 @@ let generate' (ctx : SiteContents) =
b [] [!! "Declared namespaces"]
br []
for (n, _) in namespaces do
a [Href (sprintf "%s.html" n)] [!!n]
a [Href ($"%s{n}.html")] [!!n]
br []
] n.Label

[("index" , ref); yield! namespaces; yield! modules; yield! types]
|> List.map (fun (x, y) -> (sprintf "%s/%s" n.Label x), y)
|> List.map (fun (x, y) -> $"%s{n.Label}/%s{x}", y)
)


Expand Down
14 changes: 6 additions & 8 deletions docs/generators/lunr.fsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ let generate (ctx : SiteContents) (projectRoot: string) (page: string) =

let gen =
let ctn =
sprintf "%s \n %s" generatorOutput.AssemblyGroup.Name (generatorOutput.AssemblyGroup.Namespaces |> Seq.map (fun n -> n.Name) |> String.concat " ")
{uri = (rootUrl + sprintf "/reference/%s/index.html" n.Label ); title = sprintf "%s - API Reference" n.Label; content = ctn }
$"%s{generatorOutput.AssemblyGroup.Name} \n %s{(generatorOutput.AssemblyGroup.Namespaces |> Seq.map (fun n -> n.Name) |> String.concat " ")}"
Copy link
Contributor

Choose a reason for hiding this comment

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

The compiler doesn't seem to like the nested quotes in the String.concat " " here?

image

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Fixed in a fix up commit later

{uri = $"{rootUrl}/reference/%s{n.Label}/index.html"; title = $"%s{n.Label} - API Reference"; content = ctn }

let mdlsGen =
allModules
Expand All @@ -59,21 +59,19 @@ let generate (ctx : SiteContents) (projectRoot: string) (page: string) =
(m.TypeExtensions |> List.map (fun m -> m.Name + " " + m.Comment.FullText ) |> String.concat " ")


{uri = rootUrl + sprintf "/reference/%s/%s.html" n.Label m.UrlName ; title = m.Name; content = cnt }
{uri = $"{rootUrl}/reference/%s{n.Label}/%s{m.UrlName}.html"; title = m.Name; content = cnt }
)

let tsGen =
allTypes
|> Seq.map (fun m ->
let m = m.Info
let cnt =
sprintf "%s \n %s \n %s"
m.Name
m.Comment.FullText
(m.AllMembers |> List.map (fun m -> m.Name + " " + m.Comment.FullText ) |> String.concat " ")
let allMembers = m.AllMembers |> List.map (fun m -> $"{m.Name} {m.Comment.FullText}" ) |> String.concat " "
$"%s{m.Name} \n %s{m.Comment.FullText} \n %s{allMembers}"


{uri = rootUrl + sprintf "/reference/%s/%s.html" n.Label m.UrlName ; title = m.Name; content = cnt }
{uri = $"{rootUrl}/reference/%s{n.Label}/%s{m.UrlName}.html"; title = m.Name; content = cnt }
)
[yield! entries; gen; yield! mdlsGen; yield! tsGen]
)
Expand Down
2 changes: 1 addition & 1 deletion docs/generators/partials/header.fsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,6 @@ let header (ctx : SiteContents) page =
link [Rel "stylesheet"; Href (rootUrl + "/static/css/custom.css")]
link [Rel "stylesheet"; Href "//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.0.0/styles/atom-one-dark.min.css"]
if siteInfo.theme_variant.IsSome then
link [Rel "stylesheet"; Href (rootUrl + (sprintf "/static/css/theme-%s.css" siteInfo.theme_variant.Value))]
link [Rel "stylesheet"; Href (rootUrl + ($"/static/css/theme-%s{siteInfo.theme_variant.Value}.css"))]
script [Src (rootUrl + "/static/js/jquery-3.3.1.min.js")] []
]
2 changes: 1 addition & 1 deletion docs/generators/partials/menu.fsx
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ let menu (ctx : SiteContents) (page: string) =
]
script [Type "text/javascript"; Src (rootUrl + "/static/js/lunr.min.js")] []
script [Type "text/javascript"; Src (rootUrl + "/static/js/auto-complete.js")] []
script [Type "text/javascript";] [!! (sprintf "var baseurl ='%s'" rootUrl)]
script [Type "text/javascript";] [!! ($"var baseurl ='%s{rootUrl}'")]
script [Type "text/javascript"; Src (rootUrl + "/static/js/search.js")] []
]
div [Class "highlightable"] [
Expand Down
15 changes: 8 additions & 7 deletions src/FSharpLint.Console/Output.fs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ type StandardOutput () =
errorLine
|> Seq.mapi (fun i _ -> if i = range.StartColumn then "^" else " ")
|> Seq.reduce (+)
getErrorMessage range + Environment.NewLine + errorLine + Environment.NewLine + highlightColumnLine
$"{getErrorMessage range}{Environment.NewLine}{errorLine}{Environment.NewLine}{highlightColumnLine}"

let writeLine (str:string) (color:ConsoleColor) (writer:IO.TextWriter) =
let originalColour = Console.ForegroundColor
Expand All @@ -34,29 +34,30 @@ type StandardOutput () =
Console.ForegroundColor <- originalColour

interface IOutput with

member _.WriteInfo (info:string) = writeLine info ConsoleColor.White Console.Out
member this.WriteWarning (warning:Suggestion.LintWarning) =
let highlightedErrorText = highlightErrorText warning.Details.Range warning.ErrorText
let ruleUrlHint = sprintf "See https://fsprojects.github.io/FSharpLint/how-tos/rules/%s.html" warning.RuleIdentifier
let str = warning.Details.Message + Environment.NewLine + highlightedErrorText
+ Environment.NewLine + ruleUrlHint
let ruleUrlHint = $"See https://fsprojects.github.io/FSharpLint/how-tos/rules/%s{warning.RuleIdentifier}.html"
let str = $"{warning.Details.Message}{Environment.NewLine}{highlightedErrorText}{Environment.NewLine}{ruleUrlHint}"
writeLine str ConsoleColor.Yellow Console.Out
String.replicate 80 "-" |> (this :> IOutput).WriteInfo
member _.WriteError (error:string) = writeLine error ConsoleColor.Red Console.Error

type MSBuildOutput () =

interface IOutput with

member _.WriteInfo (info:string) = Console.Out.WriteLine info
member _.WriteWarning (warning:Suggestion.LintWarning) =
sprintf "%s(%d,%d,%d,%d):FSharpLint warning %s: %s"
fprintf Console.Out "%s(%d,%d,%d,%d):FSharpLint warning %s: %s"
Copy link
Contributor

Choose a reason for hiding this comment

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

@xperiandri Should this be fprintfn as it used to do Out.WriteLine?

(ref #740 (comment))

<| warning.FilePath
<| warning.Details.Range.StartLine
<| warning.Details.Range.StartColumn
<| warning.Details.Range.EndLine
<| warning.Details.Range.EndColumn
<| warning.RuleIdentifier
<| warning.Details.Message
|> Console.Out.WriteLine
member _.WriteError (error:string) =
sprintf "FSharpLint error: %s" error
$"FSharpLint error: {error}"
|> Console.Error.WriteLine
15 changes: 6 additions & 9 deletions src/FSharpLint.Console/Program.fs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ type private FileType =
type private ToolArgs =
| [<AltCommandLine("-f")>] Format of OutputFormat
| [<CliPrefix(CliPrefix.None)>] Lint of ParseResults<LintArgs>
| Version
| Version
with
interface IArgParserTemplate with
member this.Usage =
Expand Down Expand Up @@ -56,10 +56,7 @@ let private parserProgress (output:Output.IOutput) = function
String.Format(Resources.GetString("ConsoleFinishedFile"), List.length warnings) |> output.WriteInfo
| Failed (file, parseException) ->
String.Format(Resources.GetString("ConsoleFailedToParseFile"), file) |> output.WriteError
"Exception Message:" + Environment.NewLine +
parseException.Message + Environment.NewLine +
"Exception Stack Trace:" + Environment.NewLine +
parseException.StackTrace + Environment.NewLine
$"Exception Message:{Environment.NewLine}{parseException.Message}{Environment.NewLine}Exception Stack Trace:{Environment.NewLine}{parseException.StackTrace}{Environment.NewLine}"
|> output.WriteError

/// Infers the file type of the target based on its file extension.
Expand All @@ -84,10 +81,10 @@ let private start (arguments:ParseResults<ToolArgs>) (toolsPath:Ionide.ProjInfo.
| None -> Output.StandardOutput() :> Output.IOutput

if arguments.Contains ToolArgs.Version then
let version =
let version =
Assembly.GetExecutingAssembly().GetCustomAttributes false
|> Seq.pick (function | :? AssemblyInformationalVersionAttribute as aiva -> Some aiva.InformationalVersion | _ -> None)
sprintf "Current version: %s" version |> output.WriteInfo
$"Current version: {version}" |> output.WriteInfo
()

let handleError (str:string) =
Expand Down Expand Up @@ -134,12 +131,12 @@ let private start (arguments:ParseResults<ToolArgs>) (toolsPath:Ionide.ProjInfo.
with
| e ->
let target = if fileType = FileType.Source then "source" else target
sprintf "Lint failed while analysing %s.\nFailed with: %s\nStack trace: %s" target e.Message e.StackTrace
$"Lint failed while analysing %s{target}.{Environment.NewLine}Failed with: %s{e.Message}{Environment.NewLine}Stack trace: {e.StackTrace}"
|> handleError
| _ -> ()

exitCode

/// Must be called only once per process.
/// We're calling it globally so we can call main multiple times from our tests.
let toolsPath = Ionide.ProjInfo.Init.init (DirectoryInfo <| Directory.GetCurrentDirectory()) None
Expand Down
6 changes: 3 additions & 3 deletions src/FSharpLint.Core/Application/Configuration.fs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ module IgnoreFiles =
let parseIgnorePath (path:string) =
let globToRegex glob =
Regex(
"^" + Regex.Escape(glob).Replace(@"\*", ".*").Replace(@"\?", ".") + "$",
$"""^{Regex.Escape(glob).Replace(@"\*", ".*").Replace(@"\?", ".")}$""",
RegexOptions.IgnoreCase ||| RegexOptions.Singleline)

let isDirectory = path.EndsWith("/")
Expand Down Expand Up @@ -584,7 +584,7 @@ let parseConfig (configText:string) =
try
JsonConvert.DeserializeObject<Configuration>(configText, FSharpJsonConverter.serializerSettings)
with
| ex -> raise <| ConfigurationException(sprintf "Couldn't parse config, error=%s" ex.Message)
| ex -> raise <| ConfigurationException $"Couldn't parse config, error=%s{ex.Message}"

/// Tries to parse the config file at the provided path.
let loadConfig (configPath:string) =
Expand Down Expand Up @@ -628,7 +628,7 @@ let private parseHints (hints:string []) =
match FParsec.CharParsers.run HintParser.phint hint with
| FParsec.CharParsers.Success(hint, _, _) -> hint
| FParsec.CharParsers.Failure(error, _, _) ->
raise <| ConfigurationException("Failed to parse hint: " + hint + "\n" + error)
raise <| ConfigurationException $"Failed to parse hint: {hint}{Environment.NewLine}{error}"

hints
|> Array.filter (System.String.IsNullOrWhiteSpace >> not)
Expand Down
6 changes: 3 additions & 3 deletions src/FSharpLint.Core/Application/Lint.fs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ module Lint =
let getParseFailureReason = function
| ParseFile.FailedToParseFile failures ->
let getFailureReason (x:FSharpDiagnostic) =
sprintf "failed to parse file %s, message: %s" x.FileName x.Message
$"failed to parse file {x.FileName}, message: {x.Message}"

String.Join(", ", failures |> Array.map getFailureReason)
| ParseFile.AbortedTypeCheck -> "Type check failed. You might want to build your solution/project first and try again."
Expand All @@ -78,10 +78,10 @@ module Lint =
| RunTimeConfigError error ->
String.Format(Resources.GetString("ConsoleRunTimeConfigError"), error)
| FailedToParseFile failure ->
"Lint failed to parse a file. Failed with: " + getParseFailureReason failure
$"Lint failed to parse a file. Failed with: {getParseFailureReason failure}"
| FailedToParseFilesInProject failures ->
let failureReasons = String.Join("\n", failures |> List.map getParseFailureReason)
"Lint failed to parse files. Failed with: " + failureReasons
$"Lint failed to parse files. Failed with: {failureReasons}"

[<NoComparison>]
type Result<'T> =
Expand Down
14 changes: 7 additions & 7 deletions src/FSharpLint.Core/Framework/AbstractSyntaxArray.fs
Original file line number Diff line number Diff line change
Expand Up @@ -131,18 +131,18 @@ module AbstractSyntaxArray =
| TypeRepresentation(_)
| File(_)
| LambdaArg(_)
| LambdaBody(_)
| Else(_)
| LambdaBody(_)
| Else(_)
| ComponentInfo(_) -> SyntaxNode.Other
| EnumCase(_) -> SyntaxNode.EnumCase
| UnionCase(_) -> SyntaxNode.UnionCase

[<Struct; NoEquality; NoComparison; DebuggerDisplay("{DebuggerDisplay,nq}")>]
type TempNode(hashcode: int, actual: AstNode) =
member _.Hashcode = hashcode
member _.Actual = actual
member private _.DebuggerDisplay = "AstNode: " + string actual

member private _.DebuggerDisplay = $"AstNode: {string actual}"

[<NoEquality; NoComparison>]
type Node =
Expand Down Expand Up @@ -248,7 +248,7 @@ module AbstractSyntaxArray =
let depth = stackedNode.Depth

tryAddPossibleSkips depth

// Strip out "extra info".
let node =
let extractExtraInfo actual extraInfoNode =
Expand Down Expand Up @@ -279,7 +279,7 @@ module AbstractSyntaxArray =
let skip = skips.[i]
let node = nodes.[skip.Index]

result.[skip.Index] <-
result.[skip.Index] <-
{ Hashcode = node.Hashcode
Actual = node.Actual
NumberOfChildren = skip.NumberOfChildren
Expand Down
4 changes: 2 additions & 2 deletions src/FSharpLint.Core/Framework/HintParser.fs
Original file line number Diff line number Diff line change
Expand Up @@ -428,7 +428,7 @@ module HintParser =

let isKeyword = List.exists ((=) identStr) FSharpKeywords.KeywordNames

if isKeyword then fail (sprintf "Unexpected keyword %s" identStr)
if isKeyword then fail $"Unexpected keyword %s{identStr}"
else preturn ident

let private pident: (CharStream<unit> -> Reply<char list>) =
Expand Down Expand Up @@ -1034,7 +1034,7 @@ module HintParser =
match operator with
| "|" -> Pattern.Or(patLhs, patRhs)
| "::" -> Pattern.Cons(patLhs, patRhs)
| _ -> failwith ("Unexpected operator " + operator + " in pattern."))
| _ -> failwith ($"Unexpected operator '{operator}' in pattern."))
opp.AddOperator(op)

do
Expand Down
4 changes: 2 additions & 2 deletions src/FSharpLint.Core/Framework/Utilities.fs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ module ExpressionUtilities =
PrettyNaming.ConvertValLogicalNameToDisplayNameCore ident.idText
else ident.idText

let identAsCompiledOpName (identName: string) =
let identAsCompiledOpName (identName: string) =
if PrettyNaming.IsOperatorDisplayName identName then
PrettyNaming.CompileOpName identName
else
Expand Down Expand Up @@ -106,7 +106,7 @@ module ExpressionUtilities =
let synTypeToString (text:string) = function
| SynType.Tuple _ as synType ->
tryFindTextOfRange synType.Range text
|> Option.map (fun x -> "(" + x + ")")
|> Option.map (fun x -> $"({x})")
| other ->
tryFindTextOfRange other.Range text

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ let private checkForNamedPatternEqualsConstant (args:AstNodeRuleParams) pattern

ExpressionUtilities.tryFindTextOfRange constRange args.FileContent
|> Option.bind (fun constText ->
lazy (Some { FromText = text; FromRange = fromRange; ToText = constText + " as " + ident.idText})

lazy (Some { FromText = text; FromRange = fromRange; ToText = $"{constText} as {ident.idText}"})
|> Some
)

Expand Down
Loading
Loading