diff --git a/tests/samples/codefiles/elm.elm b/tests/samples/codefiles/elm.elm new file mode 100644 index 0000000..554bc6f --- /dev/null +++ b/tests/samples/codefiles/elm.elm @@ -0,0 +1,21 @@ +module Index exposing (..) -- where + +import Color exposing (Color, darkGrey) +import Dict +import TempFontAwesome as FA +import Html exposing (..) +import Html.Attributes exposing (..) +import Markdown +import String + + +-- MAIN + + +main = + Html.programWithFlags + { init = init + , view = view + , update = update + , subscriptions = subscriptions + } diff --git a/tests/samples/codefiles/haskell.hs b/tests/samples/codefiles/haskell.hs new file mode 100644 index 0000000..045b53a --- /dev/null +++ b/tests/samples/codefiles/haskell.hs @@ -0,0 +1,20 @@ +{-# OPTIONS_GHC -Wall #-} +{-# LANGUAGE OverloadedStrings #-} +module Socket (watchFile) where + +import Control.Concurrent (forkIO, threadDelay) +import Control.Exception (SomeException, catch) +import qualified Data.ByteString.Char8 as BS +import qualified Network.WebSockets as WS +import qualified System.FSNotify.Devel as Notify +import qualified System.FSNotify as Notify + + +watchFile :: FilePath -> WS.PendingConnection -> IO () +watchFile watchedFile pendingConnection = + do connection <- WS.acceptRequest pendingConnection + + Notify.withManager $ \mgmt -> + do stop <- Notify.treeExtAny mgmt "." ".elm" print + tend connection + stop diff --git a/tests/test_dependencies.py b/tests/test_dependencies.py index f6cb1e4..c7b71d6 100644 --- a/tests/test_dependencies.py +++ b/tests/test_dependencies.py @@ -476,3 +476,31 @@ class DependenciesTestCase(TestCase): expected_lines=18, entity='haxe.hx', ) + + def test_haskell_dependencies_detected(self): + self.shared( + expected_dependencies=[ + 'Control', + 'Data', + 'Network', + 'System', + ], + expected_language='Haskell', + expected_lines=20, + entity='haskell.hs', + ) + + def test_elm_dependencies_detected(self): + self.shared( + expected_dependencies=[ + 'Color', + 'Dict', + 'TempFontAwesome', + 'Html', + 'Markdown', + 'String', + ], + expected_language='Elm', + expected_lines=21, + entity='elm.elm', + ) diff --git a/wakatime/dependencies/elm.py b/wakatime/dependencies/elm.py new file mode 100644 index 0000000..86db024 --- /dev/null +++ b/wakatime/dependencies/elm.py @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -*- +""" + wakatime.dependencies.elm + ~~~~~~~~~~~~~~~~~~~~~~~~~ + + Parse dependencies from Elm code. + + :copyright: (c) 2018 Alan Hamlett. + :license: BSD, see LICENSE for more details. +""" + +from . import TokenParser + + +class ElmParser(TokenParser): + state = None + + def parse(self): + for index, token, content in self.tokens: + self._process_token(token, content) + return self.dependencies + + def _process_token(self, token, content): + if self.partial(token) == 'Namespace': + self._process_namespace(token, content) + elif self.partial(token) == 'Text': + self._process_text(token, content) + elif self.partial(token) == 'Class': + self._process_class(token, content) + else: + self._process_other(token, content) + + def _process_namespace(self, token, content): + self.state = content.strip() + + def _process_class(self, token, content): + if self.state == 'import': + self.append(self._format(content)) + + def _process_text(self, token, content): + pass + + def _process_other(self, token, content): + self.state = None + + def _format(self, content): + return content.strip().split('.')[0].strip() diff --git a/wakatime/dependencies/haskell.py b/wakatime/dependencies/haskell.py new file mode 100644 index 0000000..6e39381 --- /dev/null +++ b/wakatime/dependencies/haskell.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +""" + wakatime.dependencies.haskell + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Parse dependencies from Haskell code. + + :copyright: (c) 2018 Alan Hamlett. + :license: BSD, see LICENSE for more details. +""" + +from . import TokenParser + + +class HaskellParser(TokenParser): + state = None + + def parse(self): + for index, token, content in self.tokens: + self._process_token(token, content) + return self.dependencies + + def _process_token(self, token, content): + if self.partial(token) == 'Reserved': + self._process_reserved(token, content) + elif self.partial(token) == 'Namespace': + self._process_namespace(token, content) + elif self.partial(token) == 'Keyword': + self._process_keyword(token, content) + elif self.partial(token) == 'Text': + self._process_text(token, content) + else: + self._process_other(token, content) + + def _process_reserved(self, token, content): + self.state = content.strip() + + def _process_namespace(self, token, content): + if self.state == 'import': + self.append(self._format(content)) + + def _process_keyword(self, token, content): + if self.state != 'import' or content.strip() != 'qualified': + self.state = None + + def _process_text(self, token, content): + pass + + def _process_other(self, token, content): + self.state = None + + def _format(self, content): + return content.strip().split('.')[0].strip()