mirror of
https://github.com/jfmengels/elm-review.git
synced 2024-09-11 16:16:09 +03:00
Backport elm-review-unused
This commit is contained in:
parent
63819d3fb7
commit
4669fe3960
@ -22,6 +22,7 @@ import Elm.Syntax.Pattern as Pattern exposing (Pattern)
|
||||
import Elm.Syntax.Range exposing (Range)
|
||||
import Elm.Syntax.Type as Type
|
||||
import Elm.Syntax.TypeAnnotation as TypeAnnotation exposing (TypeAnnotation)
|
||||
import NoUnused.RangeDict as RangeDict exposing (RangeDict)
|
||||
import Review.ModuleNameLookupTable as ModuleNameLookupTable exposing (ModuleNameLookupTable)
|
||||
import Review.Rule as Rule exposing (Error, Rule)
|
||||
import Set exposing (Set)
|
||||
@ -187,7 +188,7 @@ type alias ModuleContext =
|
||||
, declaredTypesWithConstructors : Dict CustomTypeName (Dict ConstructorName (Node ConstructorName))
|
||||
, usedFunctionsOrValues : Dict ModuleNameAsString (Set ConstructorName)
|
||||
, phantomVariables : Dict ModuleName (List ( CustomTypeName, Int ))
|
||||
, ignoreBlocks : List (Dict RangeAsString (Set ( ModuleName, String )))
|
||||
, ignoreBlocks : List (RangeDict (Set ( ModuleName, String )))
|
||||
, constructorsToIgnore : List (Set ( ModuleName, String ))
|
||||
, wasUsedInLocationThatNeedsItself : Set ( ModuleNameAsString, ConstructorName )
|
||||
, wasUsedInComparisons : Set ( ModuleNameAsString, ConstructorName )
|
||||
@ -195,10 +196,6 @@ type alias ModuleContext =
|
||||
}
|
||||
|
||||
|
||||
type alias RangeAsString =
|
||||
String
|
||||
|
||||
|
||||
initialProjectContext : List { moduleName : String, typeName : String, index : Int } -> ProjectContext
|
||||
initialProjectContext phantomTypes =
|
||||
{ exposedModules = Set.empty
|
||||
@ -532,7 +529,7 @@ expressionVisitor node moduleContext =
|
||||
newModuleContext =
|
||||
case List.head moduleContext.ignoreBlocks of
|
||||
Just expressionsWhereToIgnoreCases ->
|
||||
case Dict.get (rangeAsString (Node.range node)) expressionsWhereToIgnoreCases of
|
||||
case RangeDict.get (Node.range node) expressionsWhereToIgnoreCases of
|
||||
Just constructorsToIgnore ->
|
||||
{ moduleContext | constructorsToIgnore = constructorsToIgnore :: moduleContext.constructorsToIgnore }
|
||||
|
||||
@ -559,7 +556,7 @@ expressionExitVisitor node moduleContext =
|
||||
in
|
||||
case List.head newModuleContext.ignoreBlocks of
|
||||
Just rangesWhereToIgnoreConstructors ->
|
||||
if Dict.member (rangeAsString (Node.range node)) rangesWhereToIgnoreConstructors then
|
||||
if RangeDict.member (Node.range node) rangesWhereToIgnoreConstructors then
|
||||
( []
|
||||
, { newModuleContext | constructorsToIgnore = List.drop 1 newModuleContext.constructorsToIgnore }
|
||||
)
|
||||
@ -611,11 +608,11 @@ expressionVisitorHelp node moduleContext =
|
||||
|
||||
Expression.CaseExpression { cases } ->
|
||||
let
|
||||
newCases : Dict RangeAsString (Set ( ModuleName, String ))
|
||||
newCases : RangeDict (Set ( ModuleName, String ))
|
||||
newCases =
|
||||
cases
|
||||
|> List.map (\( pattern, body ) -> ( rangeAsString (Node.range body), constructorsInPattern moduleContext.lookupTable pattern ))
|
||||
|> Dict.fromList
|
||||
|> List.map (\( pattern, body ) -> ( Node.range body, constructorsInPattern moduleContext.lookupTable pattern ))
|
||||
|> RangeDict.fromList
|
||||
in
|
||||
( []
|
||||
, { moduleContext | ignoreBlocks = newCases :: moduleContext.ignoreBlocks }
|
||||
@ -945,14 +942,3 @@ listAtIndex index list =
|
||||
|
||||
( n, _ :: rest ) ->
|
||||
listAtIndex (n - 1) rest
|
||||
|
||||
|
||||
rangeAsString : Range -> RangeAsString
|
||||
rangeAsString range =
|
||||
[ range.start.row
|
||||
, range.start.column
|
||||
, range.end.row
|
||||
, range.end.column
|
||||
]
|
||||
|> List.map String.fromInt
|
||||
|> String.join "_"
|
||||
|
@ -16,6 +16,7 @@ import Elm.Syntax.Pattern as Pattern exposing (Pattern)
|
||||
import Elm.Syntax.Range as Range exposing (Range)
|
||||
import Elm.Writer as Writer
|
||||
import NoUnused.Patterns.NameVisitor as NameVisitor
|
||||
import NoUnused.RangeDict as RangeDict exposing (RangeDict)
|
||||
import Review.Fix as Fix exposing (Fix)
|
||||
import Review.Rule as Rule exposing (Rule)
|
||||
import Set exposing (Set)
|
||||
@ -70,14 +71,97 @@ rule =
|
||||
|> Rule.fromModuleRuleSchema
|
||||
|
||||
|
||||
expressionEnterVisitor : Node Expression -> Context -> ( List (Rule.Error {}), Context )
|
||||
type alias Context =
|
||||
{ scopes : List Scope
|
||||
, scopesToCreate : RangeDict (List FoundPattern)
|
||||
}
|
||||
|
||||
|
||||
type alias Scope =
|
||||
{ declared : List FoundPattern
|
||||
, used : Set String
|
||||
}
|
||||
|
||||
|
||||
type FoundPattern
|
||||
= SingleValue
|
||||
{ name : String
|
||||
, range : Range
|
||||
, message : String
|
||||
, details : List String
|
||||
, fix : List Fix
|
||||
}
|
||||
| RecordPattern
|
||||
{ fields : List (Node String)
|
||||
, recordRange : Range
|
||||
}
|
||||
| SimplifiablePattern (Rule.Error {})
|
||||
|
||||
|
||||
initialContext : Context
|
||||
initialContext =
|
||||
{ scopes = []
|
||||
, scopesToCreate = RangeDict.empty
|
||||
}
|
||||
|
||||
|
||||
|
||||
-- EXPRESSION ENTER VISITOR
|
||||
|
||||
|
||||
expressionEnterVisitor : Node Expression -> Context -> ( List nothing, Context )
|
||||
expressionEnterVisitor node context =
|
||||
let
|
||||
newContext : Context
|
||||
newContext =
|
||||
case RangeDict.get (Node.range node) context.scopesToCreate of
|
||||
Just declared ->
|
||||
{ context | scopes = { declared = declared, used = Set.empty } :: context.scopes }
|
||||
|
||||
Nothing ->
|
||||
context
|
||||
in
|
||||
expressionEnterVisitorHelp node newContext
|
||||
|
||||
|
||||
expressionEnterVisitorHelp : Node Expression -> Context -> ( List nothing, Context )
|
||||
expressionEnterVisitorHelp node context =
|
||||
case Node.value node of
|
||||
Expression.LetExpression { declarations } ->
|
||||
( [], rememberLetDeclarationList declarations context )
|
||||
let
|
||||
findPatternsInLetDeclaration : Node Expression.LetDeclaration -> List FoundPattern
|
||||
findPatternsInLetDeclaration letDeclaration =
|
||||
case Node.value letDeclaration of
|
||||
Expression.LetFunction _ ->
|
||||
[]
|
||||
|
||||
Expression.LetDestructuring pattern _ ->
|
||||
findPatterns Destructuring pattern
|
||||
in
|
||||
( []
|
||||
, { context
|
||||
| scopes =
|
||||
{ declared = List.concatMap findPatternsInLetDeclaration declarations
|
||||
, used = Set.empty
|
||||
}
|
||||
:: context.scopes
|
||||
|
||||
-- Will only be used to remove on exit, we are already adding the declared patterns to the scope above
|
||||
, scopesToCreate = RangeDict.insert (Node.range node) [] context.scopesToCreate
|
||||
}
|
||||
)
|
||||
|
||||
Expression.CaseExpression { cases } ->
|
||||
( [], rememberCaseList cases context )
|
||||
( []
|
||||
, { context
|
||||
| scopes = { declared = [], used = Set.empty } :: context.scopes
|
||||
, scopesToCreate =
|
||||
List.foldl
|
||||
(\( pattern, expr ) scopesToCreate -> RangeDict.insert (Node.range expr) (findPatterns Matching pattern) scopesToCreate)
|
||||
context.scopesToCreate
|
||||
cases
|
||||
}
|
||||
)
|
||||
|
||||
_ ->
|
||||
( [], context )
|
||||
@ -85,17 +169,136 @@ expressionEnterVisitor node context =
|
||||
|
||||
expressionExitVisitor : Node Expression -> Context -> ( List (Rule.Error {}), Context )
|
||||
expressionExitVisitor node context =
|
||||
case Node.value node of
|
||||
Expression.LetExpression { declarations } ->
|
||||
errorsForLetDeclarationList declarations context
|
||||
case RangeDict.get (Node.range node) context.scopesToCreate of
|
||||
Just _ ->
|
||||
report context
|
||||
|
||||
Expression.CaseExpression { cases } ->
|
||||
errorsForCaseList cases context
|
||||
Nothing ->
|
||||
( [], context )
|
||||
|
||||
|
||||
report : Context -> ( List (Rule.Error {}), Context )
|
||||
report context =
|
||||
case context.scopes of
|
||||
headScope :: restOfScopes ->
|
||||
let
|
||||
{ singles, records, simplifiablePatterns } =
|
||||
findDeclaredPatterns headScope
|
||||
|
||||
allDeclared : List String
|
||||
allDeclared =
|
||||
List.concat
|
||||
[ List.map .name singles
|
||||
, List.concatMap (.fields >> List.map Node.value) records
|
||||
]
|
||||
|
||||
nonUsedVars : Set String
|
||||
nonUsedVars =
|
||||
allDeclared
|
||||
|> Set.fromList
|
||||
|> Set.diff headScope.used
|
||||
|
||||
errors : List (Rule.Error {})
|
||||
errors =
|
||||
List.concat
|
||||
[ singleErrors
|
||||
, recordErrors
|
||||
, simplifiablePatterns
|
||||
]
|
||||
|
||||
singleErrors : List (Rule.Error {})
|
||||
singleErrors =
|
||||
List.filter (\{ name } -> not <| Set.member name headScope.used) singles
|
||||
|> List.map
|
||||
(\pattern ->
|
||||
Rule.errorWithFix
|
||||
{ message = pattern.message
|
||||
, details = pattern.details
|
||||
}
|
||||
pattern.range
|
||||
pattern.fix
|
||||
)
|
||||
|
||||
recordErrors : List (Rule.Error {})
|
||||
recordErrors =
|
||||
records
|
||||
|> List.concatMap
|
||||
(\{ fields, recordRange } ->
|
||||
let
|
||||
( unused, used ) =
|
||||
List.partition (isNodeInContext context) fields
|
||||
in
|
||||
case unused of
|
||||
[] ->
|
||||
[]
|
||||
|
||||
firstNode :: restNodes ->
|
||||
let
|
||||
first : String
|
||||
first =
|
||||
Node.value firstNode
|
||||
|
||||
rest : List String
|
||||
rest =
|
||||
List.map Node.value restNodes
|
||||
|
||||
( errorRange, fix ) =
|
||||
case used of
|
||||
[] ->
|
||||
( recordRange, Fix.replaceRangeBy recordRange "_" )
|
||||
|
||||
_ ->
|
||||
( Range.combine (List.map Node.range unused)
|
||||
, Node Range.emptyRange (Pattern.RecordPattern used)
|
||||
|> Writer.writePattern
|
||||
|> Writer.write
|
||||
|> Fix.replaceRangeBy recordRange
|
||||
)
|
||||
in
|
||||
[ Rule.errorWithFix
|
||||
{ message = listToMessage first rest
|
||||
, details = listToDetails first rest
|
||||
}
|
||||
errorRange
|
||||
[ fix ]
|
||||
]
|
||||
)
|
||||
in
|
||||
( errors
|
||||
, List.foldl
|
||||
useValue
|
||||
{ context | scopes = restOfScopes }
|
||||
(Set.toList nonUsedVars)
|
||||
)
|
||||
|
||||
_ ->
|
||||
( [], context )
|
||||
|
||||
|
||||
findDeclaredPatterns :
|
||||
Scope
|
||||
->
|
||||
{ singles : List { name : String, range : Range, message : String, details : List String, fix : List Fix }
|
||||
, records : List { fields : List (Node String), recordRange : Range }
|
||||
, simplifiablePatterns : List (Rule.Error {})
|
||||
}
|
||||
findDeclaredPatterns scope =
|
||||
List.foldl
|
||||
(\foundPattern acc ->
|
||||
case foundPattern of
|
||||
SingleValue v ->
|
||||
{ acc | singles = v :: acc.singles }
|
||||
|
||||
RecordPattern v ->
|
||||
{ acc | records = v :: acc.records }
|
||||
|
||||
SimplifiablePattern simplifiablePatternError ->
|
||||
{ acc | simplifiablePatterns = simplifiablePatternError :: acc.simplifiablePatterns }
|
||||
)
|
||||
{ singles = [], records = [], simplifiablePatterns = [] }
|
||||
scope.declared
|
||||
|
||||
|
||||
valueVisitor : Node ( ModuleName, String ) -> Context -> ( List (Rule.Error {}), Context )
|
||||
valueVisitor (Node _ ( moduleName, value )) context =
|
||||
case moduleName of
|
||||
@ -110,96 +313,109 @@ valueVisitor (Node _ ( moduleName, value )) context =
|
||||
--- ON ENTER
|
||||
|
||||
|
||||
rememberCaseList : List Expression.Case -> Context -> Context
|
||||
rememberCaseList list context =
|
||||
List.foldl rememberCase context list
|
||||
|
||||
|
||||
rememberCase : Expression.Case -> Context -> Context
|
||||
rememberCase ( pattern, _ ) context =
|
||||
rememberPattern pattern context
|
||||
|
||||
|
||||
rememberLetDeclarationList : List (Node Expression.LetDeclaration) -> Context -> Context
|
||||
rememberLetDeclarationList list context =
|
||||
List.foldl rememberLetDeclaration context list
|
||||
|
||||
|
||||
rememberLetDeclaration : Node Expression.LetDeclaration -> Context -> Context
|
||||
rememberLetDeclaration (Node _ letDeclaration) context =
|
||||
case letDeclaration of
|
||||
Expression.LetFunction _ ->
|
||||
context
|
||||
|
||||
Expression.LetDestructuring pattern _ ->
|
||||
rememberPattern pattern context
|
||||
|
||||
|
||||
rememberPatternList : List (Node Pattern) -> Context -> Context
|
||||
rememberPatternList list context =
|
||||
List.foldl rememberPattern context list
|
||||
|
||||
|
||||
rememberPattern : Node Pattern -> Context -> Context
|
||||
rememberPattern (Node _ pattern) context =
|
||||
findPatterns : PatternUse -> Node Pattern -> List FoundPattern
|
||||
findPatterns use (Node range pattern) =
|
||||
case pattern of
|
||||
Pattern.AllPattern ->
|
||||
context
|
||||
Pattern.VarPattern name ->
|
||||
[ SingleValue
|
||||
{ name = name
|
||||
, message = "Value `" ++ name ++ "` is not used."
|
||||
, details = singularReplaceDetails
|
||||
, range = range
|
||||
, fix = [ Fix.replaceRangeBy range "_" ]
|
||||
}
|
||||
]
|
||||
|
||||
Pattern.VarPattern value ->
|
||||
rememberValue value context
|
||||
Pattern.TuplePattern [ Node _ Pattern.AllPattern, Node _ Pattern.AllPattern ] ->
|
||||
[ SimplifiablePattern
|
||||
(Rule.errorWithFix
|
||||
{ message = "Tuple pattern is not needed."
|
||||
, details = redundantDetails
|
||||
}
|
||||
range
|
||||
[ Fix.replaceRangeBy range "_" ]
|
||||
)
|
||||
]
|
||||
|
||||
Pattern.TuplePattern [ Node _ Pattern.AllPattern, Node _ Pattern.AllPattern, Node _ Pattern.AllPattern ] ->
|
||||
[ SimplifiablePattern
|
||||
(Rule.errorWithFix
|
||||
{ message = "Tuple pattern is not needed."
|
||||
, details = redundantDetails
|
||||
}
|
||||
range
|
||||
[ Fix.replaceRangeBy range "_" ]
|
||||
)
|
||||
]
|
||||
|
||||
Pattern.TuplePattern patterns ->
|
||||
rememberPatternList patterns context
|
||||
List.concatMap (findPatterns use) patterns
|
||||
|
||||
Pattern.RecordPattern values ->
|
||||
rememberValueList values context
|
||||
Pattern.RecordPattern fields ->
|
||||
[ RecordPattern
|
||||
{ fields = fields
|
||||
, recordRange = range
|
||||
}
|
||||
]
|
||||
|
||||
Pattern.UnConsPattern first second ->
|
||||
context
|
||||
|> rememberPattern first
|
||||
|> rememberPattern second
|
||||
findPatterns use first ++ findPatterns use second
|
||||
|
||||
Pattern.ListPattern patterns ->
|
||||
rememberPatternList patterns context
|
||||
List.concatMap (findPatterns use) patterns
|
||||
|
||||
Pattern.NamedPattern _ patterns ->
|
||||
rememberPatternList patterns context
|
||||
if use == Destructuring && List.all isAllPattern patterns then
|
||||
[ SimplifiablePattern
|
||||
(Rule.errorWithFix
|
||||
{ message = "Named pattern is not needed."
|
||||
, details = redundantDetails
|
||||
}
|
||||
range
|
||||
[ Fix.replaceRangeBy range "_" ]
|
||||
)
|
||||
]
|
||||
|
||||
else
|
||||
List.concatMap (findPatterns use) patterns
|
||||
|
||||
Pattern.AsPattern inner name ->
|
||||
context
|
||||
|> rememberPattern inner
|
||||
|> rememberValue (Node.value name)
|
||||
findPatternForAsPattern range inner name :: findPatterns use inner
|
||||
|
||||
Pattern.ParenthesizedPattern inner ->
|
||||
rememberPattern inner context
|
||||
findPatterns use inner
|
||||
|
||||
_ ->
|
||||
context
|
||||
|
||||
|
||||
rememberValueList : List (Node String) -> Context -> Context
|
||||
rememberValueList list context =
|
||||
List.foldl (Node.value >> rememberValue) context list
|
||||
[]
|
||||
|
||||
|
||||
|
||||
--- ON EXIT
|
||||
|
||||
|
||||
singularDetails : List String
|
||||
singularDetails =
|
||||
[ "You should either use this value somewhere, or remove it at the location I pointed at." ]
|
||||
singularRemoveDetails : List String
|
||||
singularRemoveDetails =
|
||||
[ "You should either use this value somewhere or remove it." ]
|
||||
|
||||
|
||||
singularReplaceDetails : List String
|
||||
singularReplaceDetails =
|
||||
[ "You should either use this value somewhere or replace it with '_'." ]
|
||||
|
||||
|
||||
pluralDetails : List String
|
||||
pluralDetails =
|
||||
[ "You should either use these values somewhere, or remove them at the location I pointed at." ]
|
||||
[ "You should either use these values somewhere or remove them." ]
|
||||
|
||||
|
||||
redundantDetails : List String
|
||||
redundantDetails =
|
||||
[ "This pattern is redundant and should be replaced with '_'." ]
|
||||
|
||||
|
||||
removeDetails : List String
|
||||
removeDetails =
|
||||
[ "You should remove it at the location I pointed at." ]
|
||||
[ "This pattern is redundant and should be removed." ]
|
||||
|
||||
|
||||
andThen :
|
||||
@ -215,31 +431,6 @@ andThen function value ( errors, context ) =
|
||||
( newErrors ++ errors, newContext )
|
||||
|
||||
|
||||
errorsForCaseList : List Expression.Case -> Context -> ( List (Rule.Error {}), Context )
|
||||
errorsForCaseList list context =
|
||||
List.foldl (andThen errorsForCase) ( [], context ) list
|
||||
|
||||
|
||||
errorsForCase : Expression.Case -> Context -> ( List (Rule.Error {}), Context )
|
||||
errorsForCase ( pattern, _ ) context =
|
||||
errorsForPattern Matching pattern context
|
||||
|
||||
|
||||
errorsForLetDeclarationList : List (Node Expression.LetDeclaration) -> Context -> ( List (Rule.Error {}), Context )
|
||||
errorsForLetDeclarationList list context =
|
||||
List.foldl (andThen errorsForLetDeclaration) ( [], context ) list
|
||||
|
||||
|
||||
errorsForLetDeclaration : Node Expression.LetDeclaration -> Context -> ( List (Rule.Error {}), Context )
|
||||
errorsForLetDeclaration (Node _ letDeclaration) context =
|
||||
case letDeclaration of
|
||||
Expression.LetFunction _ ->
|
||||
( [], context )
|
||||
|
||||
Expression.LetDestructuring pattern _ ->
|
||||
errorsForPattern Destructuring pattern context
|
||||
|
||||
|
||||
type PatternUse
|
||||
= Destructuring
|
||||
| Matching
|
||||
@ -300,7 +491,7 @@ errorsForUselessNamePattern : Range -> Context -> ( List (Rule.Error {}), Contex
|
||||
errorsForUselessNamePattern range context =
|
||||
( [ Rule.errorWithFix
|
||||
{ message = "Named pattern is not needed."
|
||||
, details = removeDetails
|
||||
, details = redundantDetails
|
||||
}
|
||||
range
|
||||
[ Fix.replaceRangeBy range "_" ]
|
||||
@ -313,7 +504,7 @@ errorsForUselessTuple : Range -> Context -> ( List (Rule.Error {}), Context )
|
||||
errorsForUselessTuple range context =
|
||||
( [ Rule.errorWithFix
|
||||
{ message = "Tuple pattern is not needed."
|
||||
, details = removeDetails
|
||||
, details = redundantDetails
|
||||
}
|
||||
range
|
||||
[ Fix.replaceRangeBy range "_" ]
|
||||
@ -366,11 +557,6 @@ errorsForRecordValueList recordRange list context =
|
||||
)
|
||||
|
||||
|
||||
isNodeInContext : Context -> Node String -> Bool
|
||||
isNodeInContext context (Node _ value) =
|
||||
Set.member value context
|
||||
|
||||
|
||||
listToMessage : String -> List String -> String
|
||||
listToMessage first rest =
|
||||
case List.reverse rest of
|
||||
@ -385,7 +571,7 @@ listToDetails : String -> List String -> List String
|
||||
listToDetails _ rest =
|
||||
case rest of
|
||||
[] ->
|
||||
singularDetails
|
||||
singularRemoveDetails
|
||||
|
||||
_ ->
|
||||
pluralDetails
|
||||
@ -393,7 +579,7 @@ listToDetails _ rest =
|
||||
|
||||
errorsForAsPattern : Range -> Node Pattern -> Node String -> Context -> ( List (Rule.Error {}), Context )
|
||||
errorsForAsPattern patternRange inner (Node range name) context =
|
||||
if Set.member name context then
|
||||
if isUnused name context then
|
||||
let
|
||||
fix : List Fix
|
||||
fix =
|
||||
@ -405,12 +591,12 @@ errorsForAsPattern patternRange inner (Node range name) context =
|
||||
in
|
||||
( [ Rule.errorWithFix
|
||||
{ message = "Pattern alias `" ++ name ++ "` is not used."
|
||||
, details = singularDetails
|
||||
, details = singularRemoveDetails
|
||||
}
|
||||
range
|
||||
fix
|
||||
]
|
||||
, Set.remove name context
|
||||
, useValue name context
|
||||
)
|
||||
|
||||
else if isAllPattern inner then
|
||||
@ -421,13 +607,44 @@ errorsForAsPattern patternRange inner (Node range name) context =
|
||||
(Node.range inner)
|
||||
[ Fix.replaceRangeBy patternRange name ]
|
||||
]
|
||||
, Set.remove name context
|
||||
, useValue name context
|
||||
)
|
||||
|
||||
else
|
||||
( [], context )
|
||||
|
||||
|
||||
findPatternForAsPattern : Range -> Node Pattern -> Node String -> FoundPattern
|
||||
findPatternForAsPattern patternRange inner (Node range name) =
|
||||
if isAllPattern inner then
|
||||
SimplifiablePattern
|
||||
(Rule.errorWithFix
|
||||
{ message = "Pattern `_` is not needed."
|
||||
, details = removeDetails
|
||||
}
|
||||
(Node.range inner)
|
||||
[ Fix.replaceRangeBy patternRange name ]
|
||||
)
|
||||
|
||||
else
|
||||
let
|
||||
fix : List Fix
|
||||
fix =
|
||||
[ inner
|
||||
|> Writer.writePattern
|
||||
|> Writer.write
|
||||
|> Fix.replaceRangeBy patternRange
|
||||
]
|
||||
in
|
||||
SingleValue
|
||||
{ name = name
|
||||
, message = "Pattern alias `" ++ name ++ "` is not used."
|
||||
, details = singularRemoveDetails
|
||||
, range = range
|
||||
, fix = fix
|
||||
}
|
||||
|
||||
|
||||
isAllPattern : Node Pattern -> Bool
|
||||
isAllPattern (Node _ pattern) =
|
||||
case pattern of
|
||||
@ -440,44 +657,46 @@ isAllPattern (Node _ pattern) =
|
||||
|
||||
forgetNode : Node String -> Context -> Context
|
||||
forgetNode (Node _ value) context =
|
||||
Set.remove value context
|
||||
|
||||
|
||||
|
||||
--- CONTEXT
|
||||
|
||||
|
||||
type alias Context =
|
||||
Set String
|
||||
|
||||
|
||||
initialContext : Context
|
||||
initialContext =
|
||||
Set.empty
|
||||
useValue value context
|
||||
|
||||
|
||||
errorsForValue : String -> Range -> Context -> ( List (Rule.Error {}), Context )
|
||||
errorsForValue value range context =
|
||||
if Set.member value context then
|
||||
errorsForValue name range context =
|
||||
if isUnused name context then
|
||||
( [ Rule.errorWithFix
|
||||
{ message = "Value `" ++ value ++ "` is not used."
|
||||
, details = singularDetails
|
||||
{ message = "Value `" ++ name ++ "` is not used."
|
||||
, details = singularReplaceDetails
|
||||
}
|
||||
range
|
||||
[ Fix.replaceRangeBy range "_" ]
|
||||
]
|
||||
, Set.remove value context
|
||||
, useValue name context
|
||||
)
|
||||
|
||||
else
|
||||
( [], context )
|
||||
|
||||
|
||||
rememberValue : String -> Context -> Context
|
||||
rememberValue value context =
|
||||
Set.insert value context
|
||||
|
||||
|
||||
useValue : String -> Context -> Context
|
||||
useValue value context =
|
||||
Set.remove value context
|
||||
useValue name context =
|
||||
case context.scopes of
|
||||
[] ->
|
||||
context
|
||||
|
||||
headScope :: restOfScopes ->
|
||||
{ context | scopes = { headScope | used = Set.insert name headScope.used } :: restOfScopes }
|
||||
|
||||
|
||||
isNodeInContext : Context -> Node String -> Bool
|
||||
isNodeInContext context (Node _ value) =
|
||||
isUnused value context
|
||||
|
||||
|
||||
isUnused : String -> Context -> Bool
|
||||
isUnused name context =
|
||||
case context.scopes of
|
||||
[] ->
|
||||
False
|
||||
|
||||
headScope :: _ ->
|
||||
not <| Set.member name headScope.used
|
||||
|
@ -5,9 +5,21 @@ import Review.Test
|
||||
import Test exposing (Test, describe, test)
|
||||
|
||||
|
||||
details : List String
|
||||
details =
|
||||
[ "You should either use this value somewhere, or remove it at the location I pointed at."
|
||||
useOrRemoveDetails : List String
|
||||
useOrRemoveDetails =
|
||||
[ "You should either use this value somewhere or remove it."
|
||||
]
|
||||
|
||||
|
||||
useOrReplaceDetails : List String
|
||||
useOrReplaceDetails =
|
||||
[ "You should either use this value somewhere or replace it with '_'."
|
||||
]
|
||||
|
||||
|
||||
redundantReplaceDetails : List String
|
||||
redundantReplaceDetails =
|
||||
[ "This pattern is redundant and should be replaced with '_'."
|
||||
]
|
||||
|
||||
|
||||
@ -49,7 +61,7 @@ foo =
|
||||
|> Review.Test.expectErrors
|
||||
[ Review.Test.error
|
||||
{ message = "Value `bish` is not used."
|
||||
, details = details
|
||||
, details = useOrReplaceDetails
|
||||
, under = "bish"
|
||||
}
|
||||
|> Review.Test.whenFixed
|
||||
@ -64,7 +76,7 @@ foo =
|
||||
"""
|
||||
, Review.Test.error
|
||||
{ message = "Value `bash` is not used."
|
||||
, details = details
|
||||
, details = useOrReplaceDetails
|
||||
, under = "bash"
|
||||
}
|
||||
|> Review.Test.whenFixed
|
||||
@ -93,7 +105,7 @@ foo =
|
||||
|> Review.Test.expectErrors
|
||||
[ Review.Test.error
|
||||
{ message = "Value `one` is not used."
|
||||
, details = details
|
||||
, details = useOrReplaceDetails
|
||||
, under = "one"
|
||||
}
|
||||
|> Review.Test.whenFixed
|
||||
@ -108,7 +120,7 @@ foo =
|
||||
"""
|
||||
, Review.Test.error
|
||||
{ message = "Value `first` is not used."
|
||||
, details = details
|
||||
, details = useOrReplaceDetails
|
||||
, under = "first"
|
||||
}
|
||||
|> Review.Test.whenFixed
|
||||
@ -123,7 +135,7 @@ foo =
|
||||
"""
|
||||
, Review.Test.error
|
||||
{ message = "Value `two` is not used."
|
||||
, details = details
|
||||
, details = useOrReplaceDetails
|
||||
, under = "two"
|
||||
}
|
||||
|> Review.Test.whenFixed
|
||||
@ -138,7 +150,7 @@ foo =
|
||||
"""
|
||||
, Review.Test.error
|
||||
{ message = "Value `more` is not used."
|
||||
, details = details
|
||||
, details = useOrReplaceDetails
|
||||
, under = "more"
|
||||
}
|
||||
|> Review.Test.whenFixed
|
||||
@ -167,7 +179,7 @@ foo =
|
||||
|> Review.Test.expectErrors
|
||||
[ Review.Test.error
|
||||
{ message = "Value `one` is not used."
|
||||
, details = details
|
||||
, details = useOrReplaceDetails
|
||||
, under = "one"
|
||||
}
|
||||
|> Review.Test.whenFixed
|
||||
@ -182,7 +194,7 @@ foo =
|
||||
"""
|
||||
, Review.Test.error
|
||||
{ message = "Value `first` is not used."
|
||||
, details = details
|
||||
, details = useOrReplaceDetails
|
||||
, under = "first"
|
||||
}
|
||||
|> Review.Test.whenFixed
|
||||
@ -197,7 +209,7 @@ foo =
|
||||
"""
|
||||
, Review.Test.error
|
||||
{ message = "Value `two` is not used."
|
||||
, details = details
|
||||
, details = useOrReplaceDetails
|
||||
, under = "two"
|
||||
}
|
||||
|> Review.Test.whenFixed
|
||||
@ -212,7 +224,7 @@ foo =
|
||||
"""
|
||||
, Review.Test.error
|
||||
{ message = "Value `more` is not used."
|
||||
, details = details
|
||||
, details = useOrReplaceDetails
|
||||
, under = "more"
|
||||
}
|
||||
|> Review.Test.whenFixed
|
||||
@ -224,6 +236,70 @@ foo =
|
||||
one :: [] -> 1
|
||||
first :: two :: [] -> 2
|
||||
_ :: _ :: _ -> 3
|
||||
"""
|
||||
]
|
||||
, test "report unused values with the same name as found in other branches" <|
|
||||
\() ->
|
||||
"""
|
||||
module A exposing (..)
|
||||
foo =
|
||||
case value of
|
||||
Thing foo ->
|
||||
Just foo
|
||||
OtherThing foo ->
|
||||
Nothing
|
||||
"""
|
||||
|> Review.Test.run rule
|
||||
|> Review.Test.expectErrors
|
||||
[ Review.Test.error
|
||||
{ message = "Value `foo` is not used."
|
||||
, details = useOrReplaceDetails
|
||||
, under = "foo"
|
||||
}
|
||||
|> Review.Test.atExactly { start = { row = 7, column = 20 }, end = { row = 7, column = 23 } }
|
||||
|> Review.Test.whenFixed
|
||||
"""
|
||||
module A exposing (..)
|
||||
foo =
|
||||
case value of
|
||||
Thing foo ->
|
||||
Just foo
|
||||
OtherThing _ ->
|
||||
Nothing
|
||||
"""
|
||||
]
|
||||
, test "report unused values with the same name as found in different functions" <|
|
||||
\() ->
|
||||
"""
|
||||
module A exposing (..)
|
||||
foo =
|
||||
case bar of
|
||||
bish ->
|
||||
bish
|
||||
bar =
|
||||
case bar of
|
||||
bish ->
|
||||
Nothing
|
||||
"""
|
||||
|> Review.Test.run rule
|
||||
|> Review.Test.expectErrors
|
||||
[ Review.Test.error
|
||||
{ message = "Value `bish` is not used."
|
||||
, details = useOrReplaceDetails
|
||||
, under = "bish"
|
||||
}
|
||||
|> Review.Test.atExactly { start = { row = 9, column = 9 }, end = { row = 9, column = 13 } }
|
||||
|> Review.Test.whenFixed
|
||||
"""
|
||||
module A exposing (..)
|
||||
foo =
|
||||
case bar of
|
||||
bish ->
|
||||
bish
|
||||
bar =
|
||||
case bar of
|
||||
_ ->
|
||||
Nothing
|
||||
"""
|
||||
]
|
||||
]
|
||||
@ -275,7 +351,7 @@ foo =
|
||||
|> Review.Test.expectErrors
|
||||
[ Review.Test.error
|
||||
{ message = "Value `right` is not used."
|
||||
, details = details
|
||||
, details = useOrReplaceDetails
|
||||
, under = "right"
|
||||
}
|
||||
|> Review.Test.whenFixed
|
||||
@ -303,7 +379,7 @@ foo =
|
||||
|> Review.Test.expectErrors
|
||||
[ Review.Test.error
|
||||
{ message = "Pattern `_` is not needed."
|
||||
, details = [ "You should remove it at the location I pointed at." ]
|
||||
, details = [ "This pattern is redundant and should be removed." ]
|
||||
, under = "_"
|
||||
}
|
||||
|> Review.Test.whenFixed
|
||||
@ -314,6 +390,52 @@ foo =
|
||||
(bar) = 1
|
||||
in
|
||||
bar
|
||||
"""
|
||||
]
|
||||
, test "should report unused values even if the same name is used in different scopes" <|
|
||||
\() ->
|
||||
"""
|
||||
module A exposing (..)
|
||||
foo =
|
||||
case a of
|
||||
A ->
|
||||
let
|
||||
( left, right ) =
|
||||
tupleValue
|
||||
in
|
||||
left + right
|
||||
B ->
|
||||
let
|
||||
( left, right ) =
|
||||
tupleValue
|
||||
in
|
||||
left
|
||||
"""
|
||||
|> Review.Test.run rule
|
||||
|> Review.Test.expectErrors
|
||||
[ Review.Test.error
|
||||
{ message = "Value `right` is not used."
|
||||
, details = useOrReplaceDetails
|
||||
, under = "right"
|
||||
}
|
||||
|> Review.Test.atExactly { start = { row = 13, column = 21 }, end = { row = 13, column = 26 } }
|
||||
|> Review.Test.whenFixed
|
||||
"""
|
||||
module A exposing (..)
|
||||
foo =
|
||||
case a of
|
||||
A ->
|
||||
let
|
||||
( left, right ) =
|
||||
tupleValue
|
||||
in
|
||||
left + right
|
||||
B ->
|
||||
let
|
||||
( left, _ ) =
|
||||
tupleValue
|
||||
in
|
||||
left
|
||||
"""
|
||||
]
|
||||
]
|
||||
@ -371,7 +493,7 @@ foo =
|
||||
|> Review.Test.expectErrors
|
||||
[ Review.Test.error
|
||||
{ message = "Pattern alias `bosh` is not used."
|
||||
, details = details
|
||||
, details = useOrRemoveDetails
|
||||
, under = "bosh"
|
||||
}
|
||||
|> Review.Test.whenFixed
|
||||
@ -396,7 +518,7 @@ foo =
|
||||
|> Review.Test.expectErrors
|
||||
[ Review.Test.error
|
||||
{ message = "Value `bash` is not used."
|
||||
, details = details
|
||||
, details = useOrRemoveDetails
|
||||
, under = "bash"
|
||||
}
|
||||
|> Review.Test.whenFixed
|
||||
@ -421,7 +543,7 @@ foo =
|
||||
|> Review.Test.expectErrors
|
||||
[ Review.Test.error
|
||||
{ message = "Value `bash` is not used."
|
||||
, details = details
|
||||
, details = useOrRemoveDetails
|
||||
, under = "bash"
|
||||
}
|
||||
|> Review.Test.whenFixed
|
||||
@ -434,7 +556,7 @@ foo =
|
||||
"""
|
||||
, Review.Test.error
|
||||
{ message = "Pattern alias `bosh` is not used."
|
||||
, details = details
|
||||
, details = useOrRemoveDetails
|
||||
, under = "bosh"
|
||||
}
|
||||
|> Review.Test.whenFixed
|
||||
@ -458,7 +580,7 @@ foo =
|
||||
|> Review.Test.expectErrors
|
||||
[ Review.Test.error
|
||||
{ message = "Pattern `_` is not needed."
|
||||
, details = [ "You should remove it at the location I pointed at." ]
|
||||
, details = [ "This pattern is redundant and should be removed." ]
|
||||
, under = "_"
|
||||
}
|
||||
|> Review.Test.whenFixed
|
||||
@ -484,7 +606,7 @@ foo =
|
||||
|> Review.Test.expectErrors
|
||||
[ Review.Test.error
|
||||
{ message = "Pattern alias `bish` is not used."
|
||||
, details = details
|
||||
, details = useOrRemoveDetails
|
||||
, under = "bish"
|
||||
}
|
||||
|> Review.Test.whenFixed
|
||||
@ -516,7 +638,7 @@ foo =
|
||||
|> Review.Test.expectErrors
|
||||
[ Review.Test.error
|
||||
{ message = "Value `first` is not used."
|
||||
, details = details
|
||||
, details = useOrReplaceDetails
|
||||
, under = "first"
|
||||
}
|
||||
|> Review.Test.whenFixed
|
||||
@ -529,7 +651,7 @@ foo =
|
||||
"""
|
||||
, Review.Test.error
|
||||
{ message = "Value `second` is not used."
|
||||
, details = details
|
||||
, details = useOrReplaceDetails
|
||||
, under = "second"
|
||||
}
|
||||
|> Review.Test.whenFixed
|
||||
@ -561,7 +683,7 @@ foo =
|
||||
|> Review.Test.expectErrors
|
||||
[ Review.Test.error
|
||||
{ message = "Value `bish` is not used."
|
||||
, details = details
|
||||
, details = useOrReplaceDetails
|
||||
, under = "bish"
|
||||
}
|
||||
|> Review.Test.whenFixed
|
||||
@ -590,7 +712,7 @@ foo =
|
||||
|> Review.Test.expectErrors
|
||||
[ Review.Test.error
|
||||
{ message = "Value `bish` is not used."
|
||||
, details = details
|
||||
, details = useOrReplaceDetails
|
||||
, under = "bish"
|
||||
}
|
||||
|> Review.Test.whenFixed
|
||||
@ -634,7 +756,7 @@ foo =
|
||||
|> Review.Test.expectErrors
|
||||
[ Review.Test.error
|
||||
{ message = "Named pattern is not needed."
|
||||
, details = [ "You should remove it at the location I pointed at." ]
|
||||
, details = redundantReplaceDetails
|
||||
, under = "Singular _"
|
||||
}
|
||||
|> Review.Test.whenFixed
|
||||
@ -649,7 +771,7 @@ foo =
|
||||
"""
|
||||
, Review.Test.error
|
||||
{ message = "Named pattern is not needed."
|
||||
, details = [ "You should remove it at the location I pointed at." ]
|
||||
, details = redundantReplaceDetails
|
||||
, under = "Pair _ _"
|
||||
}
|
||||
|> Review.Test.whenFixed
|
||||
@ -677,7 +799,7 @@ foo =
|
||||
|> Review.Test.expectErrors
|
||||
[ Review.Test.error
|
||||
{ message = "Named pattern is not needed."
|
||||
, details = [ "You should remove it at the location I pointed at." ]
|
||||
, details = redundantReplaceDetails
|
||||
, under = "Singular _"
|
||||
}
|
||||
|> Review.Test.whenFixed
|
||||
@ -691,7 +813,7 @@ foo =
|
||||
"""
|
||||
, Review.Test.error
|
||||
{ message = "Named pattern is not needed."
|
||||
, details = [ "You should remove it at the location I pointed at." ]
|
||||
, details = redundantReplaceDetails
|
||||
, under = "Pair _ _"
|
||||
}
|
||||
|> Review.Test.whenFixed
|
||||
@ -724,7 +846,7 @@ foo =
|
||||
|> Review.Test.expectErrors
|
||||
[ Review.Test.error
|
||||
{ message = "Values `bish` and `bash` are not used."
|
||||
, details = [ "You should either use these values somewhere, or remove them at the location I pointed at." ]
|
||||
, details = [ "You should either use these values somewhere or remove them." ]
|
||||
, under = "{ bish, bash }"
|
||||
}
|
||||
|> Review.Test.whenFixed
|
||||
@ -753,7 +875,7 @@ foo =
|
||||
|> Review.Test.expectErrors
|
||||
[ Review.Test.error
|
||||
{ message = "Values `bish` and `bosh` are not used."
|
||||
, details = [ "You should either use these values somewhere, or remove them at the location I pointed at." ]
|
||||
, details = [ "You should either use these values somewhere or remove them." ]
|
||||
, under = "bish, bash, bosh"
|
||||
}
|
||||
|> Review.Test.whenFixed
|
||||
@ -782,7 +904,7 @@ foo =
|
||||
|> Review.Test.expectErrors
|
||||
[ Review.Test.error
|
||||
{ message = "Values `bash` and `bosh` are not used."
|
||||
, details = [ "You should either use these values somewhere, or remove them at the location I pointed at." ]
|
||||
, details = [ "You should either use these values somewhere or remove them." ]
|
||||
, under = "bash, bosh"
|
||||
}
|
||||
|> Review.Test.whenFixed
|
||||
@ -816,7 +938,7 @@ foo =
|
||||
|> Review.Test.expectErrors
|
||||
[ Review.Test.error
|
||||
{ message = "Value `bish` is not used."
|
||||
, details = details
|
||||
, details = useOrReplaceDetails
|
||||
, under = "bish"
|
||||
}
|
||||
|> Review.Test.whenFixed
|
||||
@ -831,7 +953,7 @@ foo =
|
||||
"""
|
||||
, Review.Test.error
|
||||
{ message = "Value `bosh` is not used."
|
||||
, details = details
|
||||
, details = useOrReplaceDetails
|
||||
, under = "bosh"
|
||||
}
|
||||
|> Review.Test.whenFixed
|
||||
@ -860,7 +982,7 @@ foo =
|
||||
|> Review.Test.expectErrors
|
||||
[ Review.Test.error
|
||||
{ message = "Tuple pattern is not needed."
|
||||
, details = [ "You should remove it at the location I pointed at." ]
|
||||
, details = redundantReplaceDetails
|
||||
, under = "( _, _ )"
|
||||
}
|
||||
|> Review.Test.whenFixed
|
||||
@ -889,7 +1011,7 @@ foo =
|
||||
|> Review.Test.expectErrors
|
||||
[ Review.Test.error
|
||||
{ message = "Tuple pattern is not needed."
|
||||
, details = [ "You should remove it at the location I pointed at." ]
|
||||
, details = redundantReplaceDetails
|
||||
, under = "( _, _, _ )"
|
||||
}
|
||||
|> Review.Test.whenFixed
|
||||
@ -932,7 +1054,7 @@ foo =
|
||||
|> Review.Test.expectErrors
|
||||
[ Review.Test.error
|
||||
{ message = "Value `first` is not used."
|
||||
, details = details
|
||||
, details = useOrReplaceDetails
|
||||
, under = "first"
|
||||
}
|
||||
|> Review.Test.whenFixed
|
||||
@ -945,7 +1067,7 @@ foo =
|
||||
"""
|
||||
, Review.Test.error
|
||||
{ message = "Value `rest` is not used."
|
||||
, details = details
|
||||
, details = useOrReplaceDetails
|
||||
, under = "rest"
|
||||
}
|
||||
|> Review.Test.whenFixed
|
||||
|
46
tests/NoUnused/RangeDict.elm
Normal file
46
tests/NoUnused/RangeDict.elm
Normal file
@ -0,0 +1,46 @@
|
||||
module NoUnused.RangeDict exposing (RangeDict, empty, fromList, get, insert, member)
|
||||
|
||||
import Dict exposing (Dict)
|
||||
import Elm.Syntax.Range exposing (Range)
|
||||
|
||||
|
||||
type alias RangeDict v =
|
||||
Dict String v
|
||||
|
||||
|
||||
empty : RangeDict v
|
||||
empty =
|
||||
Dict.empty
|
||||
|
||||
|
||||
insert : Range -> v -> RangeDict v -> RangeDict v
|
||||
insert range =
|
||||
Dict.insert (rangeAsString range)
|
||||
|
||||
|
||||
fromList : List ( Range, v ) -> RangeDict v
|
||||
fromList values =
|
||||
values
|
||||
|> List.map (Tuple.mapFirst rangeAsString)
|
||||
|> Dict.fromList
|
||||
|
||||
|
||||
get : Range -> RangeDict v -> Maybe v
|
||||
get range =
|
||||
Dict.get (rangeAsString range)
|
||||
|
||||
|
||||
member : Range -> RangeDict v -> Bool
|
||||
member range =
|
||||
Dict.member (rangeAsString range)
|
||||
|
||||
|
||||
rangeAsString : Range -> String
|
||||
rangeAsString range =
|
||||
[ range.start.row
|
||||
, range.start.column
|
||||
, range.end.row
|
||||
, range.end.column
|
||||
]
|
||||
|> List.map String.fromInt
|
||||
|> String.join "_"
|
@ -22,6 +22,7 @@ import Elm.Syntax.Pattern as Pattern exposing (Pattern)
|
||||
import Elm.Syntax.Range exposing (Range)
|
||||
import Elm.Syntax.TypeAnnotation as TypeAnnotation exposing (TypeAnnotation)
|
||||
import NoUnused.NonemptyList as NonemptyList exposing (Nonempty)
|
||||
import NoUnused.RangeDict as RangeDict exposing (RangeDict)
|
||||
import Review.Fix as Fix exposing (Fix)
|
||||
import Review.ModuleNameLookupTable as ModuleNameLookupTable exposing (ModuleNameLookupTable)
|
||||
import Review.Project.Dependency as Dependency exposing (Dependency)
|
||||
@ -101,7 +102,7 @@ type alias ModuleContext =
|
||||
{ lookupTable : ModuleNameLookupTable
|
||||
, scopes : Nonempty Scope
|
||||
, inTheDeclarationOf : List String
|
||||
, declarations : Dict RangeAsString String
|
||||
, declarations : RangeDict String
|
||||
, exposesEverything : Bool
|
||||
, isApplication : Bool
|
||||
, constructorNameToTypeName : Dict String String
|
||||
@ -143,10 +144,6 @@ type alias ModuleThatExposesEverything =
|
||||
}
|
||||
|
||||
|
||||
type alias RangeAsString =
|
||||
String
|
||||
|
||||
|
||||
type DeclaredModuleType
|
||||
= ImportedModule
|
||||
| ModuleAlias { originalNameOfTheImport : String, exposesSomething : Bool }
|
||||
@ -571,7 +568,7 @@ expressionEnterVisitor node context =
|
||||
let
|
||||
newContext : ModuleContext
|
||||
newContext =
|
||||
case Dict.get (rangeAsString (Node.range node)) context.declarations of
|
||||
case RangeDict.get (Node.range node) context.declarations of
|
||||
Just functionName ->
|
||||
{ context | inTheDeclarationOf = functionName :: context.inTheDeclarationOf }
|
||||
|
||||
@ -643,11 +640,12 @@ expressionEnterVisitorHelp (Node range value) context =
|
||||
|> List.map (getUsedVariablesFromPattern context)
|
||||
|> foldUsedTypesAndModules
|
||||
|
||||
markAsInTheDeclarationOf : a -> { b | declarations : RangeDict a } -> { b | declarations : RangeDict a }
|
||||
markAsInTheDeclarationOf name ctx =
|
||||
{ ctx
|
||||
| declarations =
|
||||
Dict.insert
|
||||
(function.declaration |> Node.value |> .expression |> Node.range |> rangeAsString)
|
||||
RangeDict.insert
|
||||
(function.declaration |> Node.value |> .expression |> Node.range)
|
||||
name
|
||||
ctx.declarations
|
||||
}
|
||||
@ -720,7 +718,7 @@ expressionExitVisitor node context =
|
||||
let
|
||||
newContext : ModuleContext
|
||||
newContext =
|
||||
if Dict.member (rangeAsString (Node.range node)) context.declarations then
|
||||
if RangeDict.member (Node.range node) context.declarations then
|
||||
{ context | inTheDeclarationOf = List.drop 1 context.inTheDeclarationOf }
|
||||
|
||||
else
|
||||
@ -1615,14 +1613,3 @@ comparePosition a b =
|
||||
|
||||
_ ->
|
||||
order
|
||||
|
||||
|
||||
rangeAsString : Range -> RangeAsString
|
||||
rangeAsString range =
|
||||
[ range.start.row
|
||||
, range.start.column
|
||||
, range.end.row
|
||||
, range.end.column
|
||||
]
|
||||
|> List.map String.fromInt
|
||||
|> String.join "_"
|
||||
|
Loading…
Reference in New Issue
Block a user