Add unused binding detection to LSP

This commit is contained in:
Chris Penner 2024-07-05 12:09:00 -07:00
parent a74d4e8cb9
commit b9f4bfe198
3 changed files with 37 additions and 1 deletions

View File

@ -35,6 +35,7 @@ import Unison.KindInference.Error qualified as KindInference
import Unison.LSP.Conversions
import Unison.LSP.Conversions qualified as Cv
import Unison.LSP.Diagnostics (DiagnosticSeverity (..), mkDiagnostic, reportDiagnostics)
import Unison.LSP.FileAnalysis.UnusedBindings qualified as UnusedBindings
import Unison.LSP.Orphans ()
import Unison.LSP.Types
import Unison.LSP.VFS qualified as VFS
@ -111,12 +112,14 @@ checkFile doc = runMaybeT do
& toRangeMap
let typeSignatureHints = fromMaybe mempty (mkTypeSignatureHints <$> parsedFile <*> typecheckedFile)
let fileSummary = FileSummary.mkFileSummary parsedFile typecheckedFile
let unusedBindingDiagnostics = fileSummary ^.. _Just . to termsBySymbol . folded . _3 . folding (UnusedBindings.analyseTerm fileUri)
Debug.debugM Debug.Temp "Unused binding diagnostics" unusedBindingDiagnostics
let tokenMap = getTokenMap tokens
conflictWarningDiagnostics <-
fold <$> for fileSummary \fs ->
lift $ computeConflictWarningDiagnostics fileUri fs
let diagnosticRanges =
(errDiagnostics <> conflictWarningDiagnostics)
(errDiagnostics <> conflictWarningDiagnostics <> unusedBindingDiagnostics)
& fmap (\d -> (d ^. range, d))
& toRangeMap
let fileAnalysis = FileAnalysis {diagnostics = diagnosticRanges, codeActions = codeActionRanges, fileSummary, typeSignatureHints, ..}

View File

@ -0,0 +1,32 @@
module Unison.LSP.FileAnalysis.UnusedBindings (analyseTerm) where
import Data.Foldable qualified as Foldable
import Data.Map qualified as Map
import Data.Set qualified as Set
import Language.LSP.Protocol.Types (Diagnostic)
import Language.LSP.Protocol.Types qualified as Lsp
import U.Core.ABT (ABT (..))
import U.Core.ABT qualified as ABT
import Unison.LSP.Conversions qualified as Cv
import Unison.LSP.Diagnostics qualified as Diagnostic
import Unison.Parser.Ann (Ann)
import Unison.Prelude
import Unison.Symbol (Symbol)
import Unison.Term (Term)
analyseTerm :: Lsp.Uri -> Term Symbol Ann -> [Diagnostic]
analyseTerm fileUri tm =
let (unusedVars, _) = ABT.cata alg tm
in Map.toList unusedVars & mapMaybe \(v, ann) -> do
range <- Cv.annToRange ann
pure $ Diagnostic.mkDiagnostic fileUri range Diagnostic.DiagnosticSeverity_Warning ("Unused binding " <> tShow v) []
where
alg :: (Foldable f, Ord v) => Ann -> ABT f v (Map v Ann, Set v) -> (Map v Ann, Set v)
alg ann abt = case abt of
Var v -> (mempty, Set.singleton v)
Cycle x -> x
Abs v (unusedBindings, usedVars) ->
if v `Set.member` usedVars
then (unusedBindings, Set.delete v usedVars)
else (Map.insert v ann unusedBindings, usedVars)
Tm fx -> Foldable.fold fx

View File

@ -128,6 +128,7 @@ library
Unison.LSP.Conversions
Unison.LSP.Diagnostics
Unison.LSP.FileAnalysis
Unison.LSP.FileAnalysis.UnusedBindings
Unison.LSP.FoldingRange
Unison.LSP.Formatting
Unison.LSP.HandlerUtils