Compare commits

...

2 Commits

Author SHA1 Message Date
Jeroen Engels
b1700c6f41 2.14.1 2024-10-08 21:58:37 +02:00
Jeroen Engels
55bc0d723f Fix source code extraction when dealing with Unicode characters 2024-10-08 17:39:17 +02:00
5 changed files with 75 additions and 20 deletions

View File

@ -2,6 +2,10 @@
## [Unreleased]
## [2.14.1] - 2024-10-08
- Fixed an issue where extracting code using `Review.Rule.withSourceCodeExtractor` would not get the correct source code when source contains Unicode characters.
## [2.14.0] - 2024-06-14
Support new visitors that visit "extra files".
@ -179,7 +183,8 @@ Help would be appreciated to fill the blanks!
[`Review.Rule.errorFixFailure`]: https://package.elm-lang.org/packages/jfmengels/elm-review/latest/Review-Rule#errorFixFailure
[`Review.Test.ignoredFilesImpactResults`]: https://package.elm-lang.org/packages/jfmengels/elm-review/latest/Review-Rule-Test#ignoredFilesImpactResults
[Unreleased]: https://github.com/jfmengels/elm-review/compare/v2.14.0...HEAD
[Unreleased]: https://github.com/jfmengels/elm-review/compare/v2.14.1...HEAD
[2.14.1]: https://github.com/jfmengels/elm-review/releases/tag/2.14.1
[2.14.0]: https://github.com/jfmengels/elm-review/releases/tag/2.14.0
[2.13.2]: https://github.com/jfmengels/elm-review/releases/tag/2.13.2
[2.13.1]: https://github.com/jfmengels/elm-review/releases/tag/2.13.1

View File

@ -116,7 +116,7 @@ Before you start adding rules or an unfamiliar existing configuration, I suggest
## Write your own rule
You can write your own rule using this package's API and [`elm-syntax`](https://package.elm-lang.org/packages/stil4m/elm-syntax/7.2.1/).
Check out the [`Review.Rule`](https://package.elm-lang.org/packages/jfmengels/elm-review/2.14.0/Review-Rule/) documentation for how to get started.
Check out the [`Review.Rule`](https://package.elm-lang.org/packages/jfmengels/elm-review/2.14.1/Review-Rule/) documentation for how to get started.
**NOTE**: If you want to **create a package** containing `elm-review` rules, I highly recommend using the
[CLI's](https://github.com/jfmengels/node-elm-review/) `elm-review new-package` subcommand. This will create a new package that will help you use the best practices and give you helpful tools like easy auto-publishing. More information is available in the maintenance file generated along with it.
@ -236,7 +236,7 @@ It does provide 2 systems that I think are better alternatives for the health of
### Configuring exceptions
You can [configure exceptions](https://package.elm-lang.org/packages/jfmengels/elm-review/2.14.0/Review-Rule/#configuring-exceptions),
You can [configure exceptions](https://package.elm-lang.org/packages/jfmengels/elm-review/2.14.1/Review-Rule/#configuring-exceptions),
which consists of marking specific directories or files as not relevant to a rule or set of rules, preventing errors to be reported for those.
It is a good fit if you wish for `elm-review` to not report errors in vendored or generated code,
@ -282,7 +282,7 @@ the codebase. You can use this to gain insight into your codebase, or provide in
powerful integrations.
To make use of this feature, run `elm-review --extract --report=json` with a configuration containing a rule that uses
[`Rule.withDataExtractor`](https://package.elm-lang.org/packages/jfmengels/elm-review/2.14.0/Review-Rule/#withDataExtractor).
[`Rule.withDataExtractor`](https://package.elm-lang.org/packages/jfmengels/elm-review/2.14.1/Review-Rule/#withDataExtractor).
The result for a rule will be stored under `<json>.extracts.<YourRuleName>`. To access it, you can then pipe the result
into either a `Node.js` script, a tool that expects JSON, or [`jq`](https://stedolan.github.io/jq/) as in the example below.

View File

@ -3,7 +3,7 @@
"name": "jfmengels/elm-review",
"summary": "Analyzes Elm projects, to help find mistakes before your users find them.",
"license": "BSD-3-Clause",
"version": "2.14.0",
"version": "2.14.1",
"exposed-modules": [
"Review.Rule",
"Review.ModuleNameLookupTable",

View File

@ -344,6 +344,7 @@ import Review.Project.InvalidProjectError as InvalidProjectError
import Review.Project.ProjectModule as ProjectModule exposing (OpaqueProjectModule)
import Review.Project.Valid as ValidProject exposing (ValidProject)
import Review.RequestedData as RequestedData exposing (RequestedData(..))
import Unicode
import Vendor.Graph as Graph exposing (Graph)
import Vendor.IntDict as IntDict
import Vendor.Zipper as Zipper exposing (Zipper)
@ -5958,23 +5959,48 @@ visitCaseBranch caseBlockWithRange (( _, caseExpression ) as caseBranch) rules =
extractSourceCode : List String -> Range -> String
extractSourceCode lines range =
lines
|> List.drop (range.start.row - 1)
|> List.take (range.end.row - range.start.row + 1)
|> mapLast (String.slice 0 (range.end.column - 1))
|> String.join "\n"
|> String.dropLeft (range.start.column - 1)
mapLast : (a -> a) -> List a -> List a
mapLast mapper lines =
case List.reverse lines of
extractSourceCode lines { start, end } =
case List.drop (start.row - 1) lines of
[] ->
lines
""
first :: rest ->
List.reverse (mapper first :: rest)
firstLine :: rest ->
if start.row == end.row then
Unicode.slice
(start.column - 1)
(end.column - 1)
firstLine
else
let
{ linesTaken, lastLine } =
takeNLines (end.row - start.row - 1) rest ""
in
Unicode.dropLeft (start.column - 1) firstLine
++ linesTaken
++ (case lastLine of
Just lastLine_ ->
"\n" ++ Unicode.left (end.column - 1) lastLine_
Nothing ->
""
)
takeNLines : Int -> List String -> String -> { linesTaken : String, lastLine : Maybe String }
takeNLines n lines linesTaken =
if n <= 0 then
{ linesTaken = linesTaken, lastLine = List.head lines }
else
case lines of
[] ->
{ linesTaken = linesTaken, lastLine = Nothing }
line :: rest ->
takeNLines (n - 1)
rest
(linesTaken ++ "\n" ++ line)
type RuleProjectVisitor

View File

@ -53,6 +53,30 @@ a =
2
else
1
"""
]
, test "should correctly extract sources containing 2-part UTF-16 characters" <|
\() ->
"""module A exposing (..)
a =
if not condition then
"first🔧"
else
"second🌐"
"""
|> Review.Test.run rule
|> Review.Test.expectErrors
[ Review.Test.error
{ message = "Don't use if expressions with negated conditions"
, details = [ "We at fruits.com think that if expressions are more readable when the condition is not negated." ]
, under = "not"
}
|> Review.Test.whenFixed """module A exposing (..)
a =
if condition then
"second🌐"
else
"first🔧"
"""
]
]