packages feed

dhscanner-kbgen 1.0.34 → 1.0.35

raw patch · 4 files changed

+168/−4 lines, 4 filesdep +QuickCheckdep +attoparsecdep +dhscanner-kbgenPVP ok

version bump matches the API change (PVP)

Dependencies added: QuickCheck, attoparsec, dhscanner-kbgen, hspec, text

API changes (from Hackage documentation)

+ Kbgen: locationify :: Location -> String
+ Kbgen: restoreloc :: String -> Maybe Location

Files

dhscanner-kbgen.cabal view
@@ -33,7 +33,7 @@         * explain in plain English your query's purpose
         * et voilà !
 
-version:            1.0.34
+version:            1.0.35
 license:            GPL-3.0-only
 license-file:       LICENSE
 author:             OrenGitHub
@@ -57,14 +57,43 @@ 
     build-depends:
         aeson < 2.3,
+        attoparsec,
         filepath,
         base >= 4.18 && < 4.21,
         containers < 0.7,
+        text,
         dhscanner-ast >= 1.1.5,
         dhscanner-bitcode >= 1.0.16
 
     hs-source-dirs:
         src
+
+    default-language:
+        Haskell2010
+
+test-suite restoreloc
+
+    import:
+        ghc_options
+
+    type:
+        exitcode-stdio-1.0
+
+    hs-source-dirs:
+        test
+
+    main-is:
+        Test.hs
+
+    other-modules:
+        SmokeTests
+
+    build-depends:
+        base >= 4.18 && < 4.21,
+        dhscanner-kbgen,
+        dhscanner-ast >= 1.1.5,
+        hspec,
+        QuickCheck
 
     default-language:
         Haskell2010
src/Kbgen.hs view
@@ -98,7 +98,9 @@     SuperDefinedInFile(..),
     SuperQualifiedName(..),
     ConstStr(..),
-    Fact(..)
+    Fact(..),
+    locationify,
+    restoreloc
 )
 
 where
@@ -106,8 +108,11 @@ -- general imports
 import Data.Aeson
 import Text.Printf
-import GHC.Generics
+import GHC.Generics (Generic)
 import System.FilePath (takeDirectory)
+import Data.Attoparsec.Text (Parser, char, decimal, parseOnly, string, takeText)
+import Data.Text (Text)
+import qualified Data.Text as T
 
 -- general qualified imports
 import qualified Data.List as List
@@ -1074,4 +1079,51 @@     z = Location.lineEnd l
     w = Location.colEnd l
     f = normalize (Location.filename l)
-    in printf "startloc_%u_%u_endloc_%u_%u_%s" x y z w f+    in printf "startloc_%u_%u_endloc_%u_%u_%s" x y z w f
+
+restoreloc :: String -> Maybe Location
+restoreloc s = case parseOnly locationParser (T.pack s) of { Right l -> Just l; _ -> Nothing; }
+
+locationParser :: Parser Location
+locationParser = do {
+
+    _ <- string "startloc_"; x <- decimal; _ <- char '_'; y <- decimal;
+    _ <- string "_endloc_" ; z <- decimal; _ <- char '_'; w <- decimal;
+    _ <- char '_'; fname <- takeText;
+
+    pure Location {
+        filename  = restoreFilename (T.unpack fname),
+        lineStart = x,
+        colStart = y,
+        lineEnd = z,
+        colEnd = w
+    }
+}
+
+data Rule = Rule { from :: Text, to :: Text }
+
+rules :: [ Rule ]
+rules =
+    [ Rule { from = "_slash_",  to = "/" }
+    , Rule { from = "_dot_",    to = "." }
+    , Rule { from = "_dash_",   to = "-" }
+    , Rule { from = "_lbrack_", to = "[" }
+    , Rule { from = "_rbrack_", to = "]" }
+    , Rule { from = "_lparen_", to = "(" }
+    , Rule { from = "_rparen_", to = ")" }
+    ]
+
+applyRule :: Rule -> Text -> Text
+applyRule Rule { from = f, to = t } = T.replace f t
+
+applyRuleStep :: Text -> Rule -> Text
+applyRuleStep acc r = applyRule r acc
+
+restore :: Text -> Text
+restore txt = List.foldl' applyRuleStep txt rules
+
+textToStringAdapter :: (Text -> Text) -> String -> String
+textToStringAdapter f = T.unpack . f . T.pack
+
+restoreFilename :: String -> String
+restoreFilename = textToStringAdapter restore
+ test/SmokeTests.hs view
@@ -0,0 +1,48 @@+module SmokeTests (runSmokeTests) where++import Kbgen (restoreloc)+import Test.Hspec (Spec, hspec, it, shouldBe)++it' :: IO () -> String -> Spec+it' testBody label = it label testBody++completelyInvalidLocationString :: String+completelyInvalidLocationString = "Blahhh"++testCompletelyInvalidLocationString :: IO ()+testCompletelyInvalidLocationString = restoreloc completelyInvalidLocationString `shouldBe` Nothing++locationStringWithoutProperPrefix :: String+locationStringWithoutProperPrefix = "____startloc_1_2_endloc_3_4_foo_dot_c"++testLocationStringWithoutProperPrefix :: IO ()+testLocationStringWithoutProperPrefix = restoreloc locationStringWithoutProperPrefix `shouldBe` Nothing++locationStringWithoutProperFormatExample1 :: String+locationStringWithoutProperFormatExample1 = "startloc_1_2_end_3_4_foo_dot_c"++testLocationStringWithoutProperFormatExample1 :: IO ()+testLocationStringWithoutProperFormatExample1 = restoreloc locationStringWithoutProperFormatExample1 `shouldBe` Nothing++locationStringWithoutProperFormatExample2 :: String+locationStringWithoutProperFormatExample2 = "startloc_1_2_endloc____3_4_foo_dot_c"++testLocationStringWithoutProperFormatExample2 :: IO ()+testLocationStringWithoutProperFormatExample2 = restoreloc locationStringWithoutProperFormatExample2 `shouldBe` Nothing++locationStringWithoutProperFormatExample3 :: String+locationStringWithoutProperFormatExample3 = "startloc_1_2_endloc_3______4_foo_dot_c"++testLocationStringWithoutProperFormatExample3 :: IO ()+testLocationStringWithoutProperFormatExample3 = restoreloc locationStringWithoutProperFormatExample3 `shouldBe` Nothing++tests :: Spec+tests = do+    it' testCompletelyInvalidLocationString "completelyInvalidLocationString should return Nothing"+    it' testLocationStringWithoutProperPrefix "locationStringWithoutProperPrefix should return Nothing"+    it' testLocationStringWithoutProperFormatExample1 "locationStringWithoutProperFormatExample1 should return Nothing"+    it' testLocationStringWithoutProperFormatExample2 "locationStringWithoutProperFormatExample2 should return Nothing"+    it' testLocationStringWithoutProperFormatExample3 "locationStringWithoutProperFormatExample3 should return Nothing"++runSmokeTests :: IO ()+runSmokeTests = hspec tests
+ test/Test.hs view
@@ -0,0 +1,35 @@+module Main (main) where++import Kbgen (locationify, restoreloc)+import Location (Location (..))+import SmokeTests (runSmokeTests)+import Test.QuickCheck (Arbitrary (arbitrary), Gen, Property, forAll, quickCheck, suchThat)++genLocation :: Gen Location+genLocation = do+    arbitraryLineStart <- arbitrary+    arbitraryLineEnd <- arbitrary `suchThat` (>= arbitraryLineStart)+    arbitraryColStart <- arbitrary+    arbitraryColEnd <- arbitrary+    arbitraryFilename <- arbitrary+    pure+        Location+            { lineStart = arbitraryLineStart+            , colStart = arbitraryColStart+            , lineEnd = arbitraryLineEnd+            , colEnd = arbitraryColEnd+            , filename = arbitraryFilename+            }++prop_restoreloc_locationify_roundtrip :: Property+prop_restoreloc_locationify_roundtrip =+    forAll genLocation prop_restoreloc_locationify_roundtrip_for++prop_restoreloc_locationify_roundtrip_for :: Location -> Bool+prop_restoreloc_locationify_roundtrip_for loc =+    restoreloc (locationify loc) == Just loc++main :: IO ()+main = do+    runSmokeTests+    quickCheck prop_restoreloc_locationify_roundtrip