From 107018e6f32105faab89faa60999305e8e5b93db Mon Sep 17 00:00:00 2001 From: Kirill Andreev Date: Wed, 5 Aug 2020 20:31:54 +0400 Subject: [PATCH] Add basic code completion mechanism --- tools/lsp/squirrel/src/AST.hs | 9 ++-- tools/lsp/squirrel/src/AST/Completion.hs | 52 ++++++++++++++++++++++++ tools/lsp/squirrel/src/AST/Folding.hs | 3 ++ tools/lsp/squirrel/src/AST/Parser.hs | 3 +- tools/lsp/squirrel/src/AST/Scope.hs | 10 ++--- tools/lsp/squirrel/src/ParseTree.hs | 2 +- tools/lsp/squirrel/src/Parser.hs | 12 +++++- tools/lsp/squirrel/stack.yaml | 2 +- tools/lsp/squirrel/stack.yaml.lock | 6 +-- 9 files changed, 82 insertions(+), 17 deletions(-) create mode 100644 tools/lsp/squirrel/src/AST/Completion.hs create mode 100644 tools/lsp/squirrel/src/AST/Folding.hs diff --git a/tools/lsp/squirrel/src/AST.hs b/tools/lsp/squirrel/src/AST.hs index a019a7106..d221e316d 100644 --- a/tools/lsp/squirrel/src/AST.hs +++ b/tools/lsp/squirrel/src/AST.hs @@ -4,7 +4,8 @@ module AST (module M) where -import AST.Types as M -import AST.Parser as M -import AST.Scope as M -import AST.Find as M +import AST.Types as M +import AST.Parser as M +import AST.Scope as M +import AST.Find as M +import AST.Completion as M diff --git a/tools/lsp/squirrel/src/AST/Completion.hs b/tools/lsp/squirrel/src/AST/Completion.hs new file mode 100644 index 000000000..1e2353a36 --- /dev/null +++ b/tools/lsp/squirrel/src/AST/Completion.hs @@ -0,0 +1,52 @@ + +module AST.Completion where + +import Data.Text (Text) +import qualified Data.Text as Text +import Data.Maybe (listToMaybe) +import Data.List (isSubsequenceOf, nub) + +import Duplo.Tree +import Duplo.Lattice +import Duplo.Pretty + +import AST.Types +import AST.Scope +import AST.Parser +import Range +import Product + +import Debug.Trace + + +complete + :: ( Eq (Product xs) + , Modifies (Product xs) + , Contains Range xs + , Contains [ScopedDecl] xs + , Contains (Maybe Category) xs + ) + => Range + -> LIGO (Product xs) + -> Maybe [Text] +complete r tree = do + let l = spineTo (leq r . getElem) tree + word <- listToMaybe l + let scope = getElem (extract word) + let cat = getElem (extract word) + return + $ filter (isSubseqOf (ppToText word)) + $ nub + $ map (ppToText . _sdName) + $ filter (fits cat . catFromType) + $ scope + +isSubseqOf :: Text -> Text -> Bool +isSubseqOf l r = isSubsequenceOf (Text.unpack l) (Text.unpack r) + +fits :: Maybe Category -> Category -> Bool +fits Nothing _ = True +fits (Just c) c' = c == c' + +catFromType :: ScopedDecl -> Category +catFromType = maybe Variable (either (const Variable) (const Type)) . _sdType \ No newline at end of file diff --git a/tools/lsp/squirrel/src/AST/Folding.hs b/tools/lsp/squirrel/src/AST/Folding.hs new file mode 100644 index 000000000..dcc6afacd --- /dev/null +++ b/tools/lsp/squirrel/src/AST/Folding.hs @@ -0,0 +1,3 @@ + +module AST.Folding where + diff --git a/tools/lsp/squirrel/src/AST/Parser.hs b/tools/lsp/squirrel/src/AST/Parser.hs index 98076801d..6afa47658 100644 --- a/tools/lsp/squirrel/src/AST/Parser.hs +++ b/tools/lsp/squirrel/src/AST/Parser.hs @@ -45,7 +45,8 @@ import Debug.Trace -- example = "../../../src/test/contracts/blockless.ligo" -- example = "../../../src/test/contracts/bytes_arithmetic.ligo" -- example = "../../../src/test/contracts/chain_id.ligo" -example = "../../../src/test/contracts/closure-3.ligo" +-- example = "../../../src/test/contracts/closure-3.ligo" +example = "../../../src/test/contracts/coase.ligo" sample' :: FilePath -> IO (LIGO Info) sample' f diff --git a/tools/lsp/squirrel/src/AST/Scope.hs b/tools/lsp/squirrel/src/AST/Scope.hs index add1bf18e..75da0cde9 100644 --- a/tools/lsp/squirrel/src/AST/Scope.hs +++ b/tools/lsp/squirrel/src/AST/Scope.hs @@ -102,11 +102,11 @@ ofCategory _ _ = False type Info' = Product [[ScopedDecl], Maybe Category, [Text], Range, ShowRange] -instance Modifies (Product '[[ScopedDecl], Maybe Category, [Text], Range, a]) where - ascribe (ds :> _ :> _ :> r :> _) d = - color 3 (fsep (map (pp . _sdName) ds)) - $$ pp r - $$ d +-- instance Modifies (Product '[[ScopedDecl], Maybe Category, [Text], Range, a]) where +-- ascribe (ds :> _ :> _ :> r :> _) d = +-- color 3 (fsep (map (pp . _sdName) ds)) +-- $$ pp r +-- $$ d addLocalScopes :: forall xs diff --git a/tools/lsp/squirrel/src/ParseTree.hs b/tools/lsp/squirrel/src/ParseTree.hs index 1260e13b5..7cf6f912e 100644 --- a/tools/lsp/squirrel/src/ParseTree.hs +++ b/tools/lsp/squirrel/src/ParseTree.hs @@ -70,7 +70,7 @@ srcToBytestring = \case type RawTree = Tree '[ParseTree] RawInfo type RawInfo = Product [Range, Text] -instance Modifies RawInfo where +instance {-# OVERLAPS #-} Modifies RawInfo where ascribe (r :> n :> _) d = color 3 (pp n) <+> pp r `indent` pp d -- | The tree tree-sitter produces. diff --git a/tools/lsp/squirrel/src/Parser.hs b/tools/lsp/squirrel/src/Parser.hs index 26a7855fc..998eed330 100644 --- a/tools/lsp/squirrel/src/Parser.hs +++ b/tools/lsp/squirrel/src/Parser.hs @@ -111,8 +111,16 @@ instance Pretty ShowRange where type Info = Product [[Text], Range, ShowRange] type PreInfo = Product [Range, ShowRange] -instance Modifies Info where - ascribe (comms :> r :> pin :> _) = ascribeRange r pin . ascribeComms comms +instance + ( Contains Range xs + , Contains [Text] xs + , Contains ShowRange xs + ) + => Modifies (Product xs) + where + ascribe xs + = ascribeRange (getElem @Range xs) (getElem xs) + . ascribeComms (getElem xs) ascribeComms comms | null comms = id diff --git a/tools/lsp/squirrel/stack.yaml b/tools/lsp/squirrel/stack.yaml index e4767539c..66820a587 100644 --- a/tools/lsp/squirrel/stack.yaml +++ b/tools/lsp/squirrel/stack.yaml @@ -15,7 +15,7 @@ extra-deps: - semilattices-0.0.0.4@sha256:333707e460923711d1edbdd02ebe1c3957d4e0808eab9886747b52ee3e443639,1909 - fastsum-0.1.1.1 - git: https://github.com/serokell/duplo.git - commit: 0cc243e90bc497989ec48417a6b5a5ce6a01759f + commit: 60983e6e1fd21eba57af83da7d541fe555678cc8 nix: packages: [zlib] \ No newline at end of file diff --git a/tools/lsp/squirrel/stack.yaml.lock b/tools/lsp/squirrel/stack.yaml.lock index 9279ced6a..70c70fce8 100644 --- a/tools/lsp/squirrel/stack.yaml.lock +++ b/tools/lsp/squirrel/stack.yaml.lock @@ -45,11 +45,11 @@ packages: git: https://github.com/serokell/duplo.git pantry-tree: size: 557 - sha256: e8618a84baa4c24a1cabc47008cc12bbb7bd52b6fd8acaff6c4871201509c2ac - commit: 0cc243e90bc497989ec48417a6b5a5ce6a01759f + sha256: b00e0db1d2c3c0db58e90a69415f6cdc4d416ff6e50789f2de841fc60e2f2ffb + commit: 60983e6e1fd21eba57af83da7d541fe555678cc8 original: git: https://github.com/serokell/duplo.git - commit: 0cc243e90bc497989ec48417a6b5a5ce6a01759f + commit: 60983e6e1fd21eba57af83da7d541fe555678cc8 snapshots: - completed: size: 493124