packages feed

hamlet 1.1.5 → 1.1.6

raw patch · 4 files changed

+72/−9 lines, 4 filesdep ~template-haskellPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: template-haskell

API changes (from Hackage documentation)

Files

Text/Hamlet.hs view
@@ -118,12 +118,46 @@ bindingPattern (BindConstr (Ident con) is) = do     (patterns, scopes) <- fmap unzip $ mapM bindingPattern is     return (ConP (mkName con) patterns, concat scopes)-bindingPattern (BindRecord (Ident con) fields) = do+bindingPattern (BindRecord (Ident con) fields wild) = do     let f (Ident field,b) =            do (p,s) <- bindingPattern b               return ((mkName field,p),s)     (patterns, scopes) <- fmap unzip $ mapM f fields-    return (RecP (mkName con) patterns, concat scopes)+    (patterns1, scopes1) <- if wild+       then bindWildFields con $ map fst fields+       else return ([],[])+    return (RecP (mkName con) (patterns++patterns1), concat scopes ++ scopes1)++-- Wildcards bind all of the unbound fields to variables whose name+-- matches the field name.+--+-- For example: data R = C { f1, f2 :: Int }+-- C {..}           is equivalent to   C {f1=f1, f2=f2}+-- C {f1 = a, ..}   is equivalent to   C {f1=a,  f2=f2}+-- C {f2 = a, ..}   is equivalent to   C {f1=f1, f2=a}+bindWildFields :: String -> [Ident] -> Q ([(Name, Pat)], [(Ident, Exp)])+bindWildFields conName fields = do+  fieldNames <- recordToFieldNames conName+  let available n     = nameBase n `notElem` map unIdent fields+  let remainingFields = filter available fieldNames+  let mkPat n = do+        e <- newName (nameBase n)+        return ((n,VarP e), (Ident (nameBase n), VarE e))+  fmap unzip $ mapM mkPat remainingFields++-- Important note! reify will fail if the record type is defined in the+-- same module as the reify is used. This means quasi-quoted Hamlet+-- literals will not be able to use wildcards to match record types+-- defined in the same module.+recordToFieldNames :: String -> Q [Name]+recordToFieldNames conStr = do+  -- use 'lookupValueName' instead of just using 'mkName' so we reify the+  -- data constructor and not the type constructor if their names match.+  Just conName                <- lookupValueName conStr+  DataConI _ _ typeName _     <- reify conName+  TyConI (DataD _ _ _ cons _) <- reify typeName+  [fields] <- return [fields | RecC name fields <- cons, name == conName]+  return [fieldName | (fieldName, _, _) <- fields]  docToExp :: Env -> HamletRules -> Scope -> Doc -> Q Exp docToExp env hr scope (DocForall list idents inside) = do
Text/Hamlet/Parse.hs view
@@ -319,6 +319,8 @@      white = skipMany $ char ' ' +    wildDots = string ".." >> white+     isVariable (Ident (x:_)) = not (isUpper x)     isVariable (Ident []) = error "isVariable: bad identifier" @@ -351,12 +353,21 @@                       guard (isConstructor c)                       return c         choice-          [ fmap (BindRecord c) (braces (recordField `sepBy` comma))+          [ record c           , fmap (BindConstr c) (guard allowArgs >> many apat)           , return (BindConstr c [])           ]        <?> "constructor" +      record c = braces $ do+        (fields, wild) <- option ([], False) $ go+        return (BindRecord c fields wild)+        where+        go = (wildDots >> return ([], True))+           <|> (do x         <- recordField+                   (xs,wild) <- option ([],False) (comma >> go)+                   return (x:xs,wild))+       recordField = do         field <- ident         p <- option (BindVar field) -- support punning@@ -644,7 +655,7 @@  data Binding = BindVar Ident | BindAs Ident Binding | BindConstr Ident [Binding]              | BindTuple [Binding] | BindList [Binding]-             | BindRecord Ident [(Ident, Binding)]+             | BindRecord Ident [(Ident, Binding)] Bool     deriving (Eq, Show, Read, Data, Typeable)  spaceTabs :: Parser String
hamlet.cabal view
@@ -1,5 +1,5 @@ name:            hamlet-version:         1.1.5+version:         1.1.6 license:         MIT license-file:    LICENSE author:          Michael Snoyman <michael@snoyman.com>
test/HamletTest.hs view
@@ -2,6 +2,8 @@ {-# LANGUAGE TemplateHaskell #-}
 module HamletTest (spec) where
 
+import HamletTestTypes (ARecord(..))
+
 import Test.HUnit hiding (Test)
 import Test.Hspec
 
@@ -76,6 +78,8 @@     it "hamlet tuple" caseTuple
     it "complex pattern" caseComplex
     it "record pattern" caseRecord
+    it "record wildcard pattern #1" caseRecordWildCard
+    it "record wildcard pattern #2" caseRecordWildCard1
 
 
 
@@ -945,13 +949,27 @@         #{a} #{b} #{c} #{e} #{f} #{g}
     |]
 
-data ARecord = ARecCon { field1 :: Int, field2 :: Bool }
-
 caseRecord :: Assertion
 caseRecord = do
-  let z = ARecCon 10 True
+  let z = ARecord 10 True
   helper "10" [hamlet|
-    $with ARecCon { field1, field2 = True } <- z
+    $with ARecord { field1, field2 = True } <- z
+        #{field1}
+    |]
+
+caseRecordWildCard :: Assertion
+caseRecordWildCard = do
+  let z = ARecord 10 True
+  helper "10 True" [hamlet|
+    $with ARecord {..} <- z
+        #{field1} #{field2}
+    |]
+
+caseRecordWildCard1 :: Assertion
+caseRecordWildCard1 = do
+  let z = ARecord 10 True
+  helper "10" [hamlet|
+    $with ARecord {field2 = True, ..} <- z
         #{field1}
     |]