packages feed

PyF 0.11.0.0 → 0.11.1.0

raw patch · 6 files changed

+47/−11 lines, 6 filesdep ~ghc-bootPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependency ranges changed: ghc-boot

API changes (from Hackage documentation)

- PyF.Internal.ParserEx: parseExpression :: RealSrcLoc -> String -> DynFlags -> ParseResult (Located (HsExpr GhcPs))
+ PyF.Internal.ParserEx: parseExpression :: RealSrcLoc -> String -> DynFlags -> ParseResult (LocatedA (HsExpr GhcPs))

Files

ChangeLog.md view
@@ -1,5 +1,10 @@ # Revision history for PyF +## 0.11.1.0 -- 2022-09-24++- Support for OverloadedRecordsDot syntax in Meta. Thank you @Profpatsch for the report.+- In some context, the error reporting for variable not found in the quasi quote expression was incorrectly reporting existing variables as not found. See https://github.com/guibou/PyF/issues/115 for details. This is now fixed by not abusing GHC api. Thank you @michaelpj for reporting this really weird problem.+ ## 0.11.0.0 -- 2022-08-10  - Support for GHC 9.4. (Written with a pre-release of GHC 9.4, hopefully it won't change too much before the release).
PyF.cabal view
@@ -1,6 +1,6 @@ cabal-version:       2.4 name:                PyF-version:             0.11.0.0+version:             0.11.1.0 synopsis:            Quasiquotations for a python like interpolated string formatter description:         Quasiquotations for a python like interpolated string formatter. license:             BSD-3-Clause@@ -27,15 +27,15 @@                   PyF.Internal.ParserEx                   PyF.Internal.Parser -  build-depends:       base >= 4.12 && < 4.17+  build-depends:       base >= 4.12 && < 4.18                      , bytestring >= 0.10.8 && < 0.12-                     , template-haskell >= 2.14.0 && < 2.19-                     , text >= 1.2.3 && <= 2.0+                     , template-haskell >= 2.14.0 && < 2.20+                     , text >= 1.2.3 && <= 2.1                      , time >= 1.8.0 && < 1.13                      , parsec >= 3.1.13 && < 3.2                      , mtl >= 2.2.2 && < 2.3-                     , ghc >= 8.6.1 && < 9.4-                     , ghc-boot >= 8.6.1 && < 9.4+                     , ghc >= 8.6.1 && < 9.6+                     , ghc-boot >= 8.6.1 && < 9.5   hs-source-dirs: src   ghc-options: -Wall -Wunused-packages -Wincomplete-uni-patterns   default-language:    Haskell2010
Readme.md view
@@ -373,3 +373,11 @@ - `nix run .\#run-ormolu`  Before submitting.++## Treesitter support++Have a look in the [./tree-sitter-pyf/](./tree-sitter-pyf) directory for a+parser of PyF which can be integrated in your treesitter compatible editor to+get syntax highlighting for PyF.++![](./tree-sitter-pyf/nvim_ts_highlight.png)
src/PyF/Internal/Meta.hs view
@@ -212,6 +212,13 @@ -- enabled thus match on Nothing toExp _ (HsOverLabel _ Nothing lbl) = TH.LabelE (unpackFS lbl) #endif+#if MIN_VERSION_ghc(9, 4, 0)+toExp dynFlags (HsGetField _ expr field) = TH.GetFieldE (toExp dynFlags (unLoc expr)) (unpackFS . unLoc . dfoLabel . unLoc $ field)+toExp _ (HsProjection _ fields) = TH.ProjectionE (fmap (unpackFS . unLoc . dfoLabel . unLoc) fields)+#elif MIN_VERSION_ghc(9, 2, 0)+toExp dynFlags (HsGetField _ expr field) = TH.GetFieldE (toExp dynFlags (unLoc expr)) (unpackFS . unLoc . hflLabel . unLoc $ field)+toExp _ (HsProjection _ fields) = TH.ProjectionE (fmap (unpackFS . unLoc . hflLabel . unLoc) fields)+#endif toExp dynFlags e = todo "toExp" (showSDoc dynFlags . ppr $ e)  todo :: (HasCallStack, Show e) => String -> e -> a
src/PyF/Internal/QQ.hs view
@@ -34,13 +34,14 @@ import Data.Maybe (catMaybes, fromMaybe) import Data.Proxy import Data.String (fromString)-import GHC (GenLocated (L))+import GHC (GenLocated (L), moduleNameString)  #if MIN_VERSION_ghc(9,0,0) import GHC.Tc.Utils.Monad (addErrAt) import GHC.Tc.Types (TcM)-import GHC.Tc.Gen.Splice (lookupThName_maybe)+import GHC.Types.Name (occNameString) #else+import OccName import TcRnTypes (TcM) import TcSplice (lookupThName_maybe) import TcRnMonad (addErrAt)@@ -106,6 +107,7 @@ import Text.Parsec.Pos (newPos, initialPos) import Text.ParserCombinators.Parsec.Error (Message (..)) import Unsafe.Coerce (unsafeCoerce)+import Data.Maybe (isJust)  -- | Configuration for the quasiquoter data Config = Config@@ -212,12 +214,20 @@     allVars = concat $ gmapQ f [item]     allNames = map (\(L l e) -> (l, e)) allVars +lookupName :: RdrName -> Q Bool+lookupName n = case n of+  (Unqual o) -> isJust <$> lookupValueName (occNameString o)+  (Qual m o) -> isJust <$> lookupValueName (moduleNameString m <> "." <> occNameString o)+  -- No idea how to lookup for theses names, so consider that they exists+  (Orig _m _o) -> pure True+  (Exact _) -> pure True+ doesExists :: (b, RdrName) -> Q (Maybe (String, b)) doesExists (loc, name) = do-  res <- unsafeRunTcM $ lookupThName_maybe (toName name)+  res <- lookupName name   case res of-    Nothing -> pure (Just ("Variable not in scope: " <> show (toName name), loc))-    Just _ -> pure Nothing+    False -> pure (Just ("Variable not in scope: " <> show (toName name), loc))+    True -> pure Nothing  -- | Check that all variables used in 'Item' exists, otherwise, fail. checkVariables :: [Item] -> Q (Maybe (SrcSpan, String))@@ -230,6 +240,9 @@  -- Stolen from: https://www.tweag.io/blog/2021-01-07-haskell-dark-arts-part-i/ -- This allows to hack inside the the GHC api and use function not exported by template haskell.+-- This may not be always safe, see https://github.com/guibou/PyF/issues/115,+-- hence keep that for "failing path" (i.e. error reporting), but not on+-- codepath which are executed otherwise. unsafeRunTcM :: TcM a -> Q a unsafeRunTcM m = Q (unsafeCoerce m) 
test/Spec.hs view
@@ -35,6 +35,7 @@ import SpecCustomDelimiters import SpecUtils import Test.Hspec+import qualified Data.Text as Text  {-    - Normal tests are done using the recommanded API: [fmt|.....|]@@ -546,3 +547,5 @@       let padding = 10       let precision = 3       [fmt|pi = {pi:{padding}.{precision}}|] `shouldBe` "pi =      3.142"+    it "an expression with module.variable" $ do+      [fmt|{Text.intercalate " " ["a" :: Text.Text, "b" :: Text.Text]}|] `shouldBe` "a b"