fay 0.18.1 → 0.18.1.1
raw patch · 16 files changed
+277/−19 lines, 16 files
Files
- CHANGELOG.md +159/−0
- README.md +7/−0
- fay.cabal +5/−2
- src/Fay.hs +5/−5
- src/Fay/Compiler/Desugar.hs +34/−4
- src/Fay/Compiler/Exp.hs +9/−5
- src/Fay/Compiler/QName.hs +11/−0
- src/Fay/Types.hs +1/−0
- src/tests/Test/Compile.hs +10/−2
- tests/Compile/EnumChar.hs +9/−0
- tests/Compile/StrictWrapper.hs +5/−1
- tests/Compile/StrictWrapper.res +1/−0
- tests/ModuleRecordClash2.hs +11/−0
- tests/ModuleRecordClash2.res +1/−0
- tests/ModuleRecordClash2_Hello.hs +9/−0
- tests/ModuleRecordClash2_Hello.res +0/−0
+ CHANGELOG.md view
@@ -0,0 +1,159 @@+## Changelog++See full history at: <https://github.com/faylang/fay/commits>++**Note: 0.18.0.1 added source mappings returend by `Fay:compileFile` and friends meaning it should have been a major bump. Sorry about this!**++### 0.18.1.1 (2013-11-22)++* Fix a bug where records with the same name as top level modules wouldn't be initialized correctly.+* Fail when using enum syntax on unsupported literal types (for instance ['a'..'z'])++### 0.18.1 (2013-11-07)++* Add support for TupleSections++#### 0.18.0.5 (2013-10-28)++Bugfixes:+* Disallow unsupported patterns in where/let declarations instead of `<<loop>>`ing on them++Minor:+* Put upper bounds on all dependencies++#### 0.18.0.4 (2013-10-25)++Bugfixes:+* Allow `//` as an operator name (added flag to `hse-cpp`)+* Don't transcode function values when using an EmptyDataDecl++#### 0.18.0.3 (2013-10-23)++Minor:+* Allow `optparse-applicative == 0.7.*`+* Fix `examples/Cont.hs`++#### 0.18.0.2 (2013-10-16)++Bug fixes:+* Regression: Work around a bug in optparse-applicative 0.6 that prevents `--strict` from being used.++#### 0.18.0.1 (2013-10-16)++* Source maps for top level definitions, use `--sourcemap`++Bug fixes:+* Regression: Equality checks for (G)ADTs (`deriving Eq`)+* Fix `--strict` for top level ADT values (such as `module M where g = R`)+* Regression: Serialization in the presence of compression/renaming+* Pass NoImplicitPrelude (and other enabled extensions) to haskell-names to resolve ambiguities when Prelude isn't imported.++Minor:+* Bump optparse-applicative to 0.6.*+* Bump haskell-names to 0.3.1 to allow compilation with Cabal 1.14+* Ignore more declarations (useful when code sharing with GHC)++## 0.18.0.0 (2013-09-24)++New features:+* Support for qualified imports. Note: You still can't have multiple constructors with the same name in the FFI since the `instance` field in the serialization is still unqualified.+* `Automatic` transcoding now works for functions. See [[Calling Fay From JavaScript]]+* `--strict modulename[, ..]` generates strict and transcoding wrappers for a module's exports. See [[Calling Fay From JavaScript]]+* `--typecheck-only` just runs the GHC type checker with the appropriate Fay flags.+* `--runtime-path FILEPATH` allows you to supply a custom runtime. Probably only useful for debugging.++Bug fixes:+* Don't crash when trying to get the fayToJsFun of an object without constructor.name+* Fixed bug that accidentally flattened list arguments in `jsToFay`+* Fix construction with RecordWildCards not taking already listed fields into account++Breaking Changes:+* Fay.Compiler.Debug has been removed (for now)+* The interactive compilation mode has been removed (for now)++Internal changes:+* Migrated to haskell-src-ext's annotated AST.+* Name resolution is now done using haskell-names, Fay's name resolution code is now pure and a lot simpler.++## 0.17.0.0 (2013-08-27)++* With the `RebindableSyntax` and `OverloadedStrings` extensions Fay will treat Haskell string literals as JavaScript Strings. Add this in all modules and import Fay.Text (from the `fay-text` package). This is *not* a breaking change, without these extensions in a module `String` will be used, as before. All modules can still interoperate normally even if only some of them use this feature. Note that you may have to define `fromInteger` when using this with Num literals.++* The type signature of `Fay.FFI.ffi` (in fay) and `FFI.ffi` (in fay-base) has been generalized to `IsString s => s -> a` to support `RebindableSyntax`.++* Much faster compile time (of the compiler itself) by having the executables depend on the library.++Bugfixes:+* The empty list and unit is now serialized to `null` when using Automatic (it used to throw an error).++Minor:+* Restrict upper bound on `language-ecmascript` to `< 1.0`++#### 0.16.0.3 (2013-08-23)++* Support for tuple constructors (`(,,) 1,2,3`)++Minor:+* Bump `pretty-show` to `>= 1.6`+* Remove the `-fdevel` flag (when compiling fay itself)++#### 0.16.0.2 (2013-08-21)++Minor:+* Bump `haskell-src-exts` to `>= 1.14`++#### 0.16.0.1 (2013-08-08)++Bugfixes:+ * Allow combining multiline strings with CPP++## 0.16.0.0 (2013-08-05)+ * New module generation, modules generate code separately in the format `My.Module.foo` instead of `My$Module$foo`+ * Transcoding information is also produced separately for each module+ * Removed `--naked`, `--dispatcher`, and `--no-dispatcher`. They are probably not needed anymore+ * Removed `Fay$$fayToJsUserDefined` and `Fay$$jsToFayUserDefined`, instead call `Fay$$fayToJs` and `Fay$$jsToFay` respectively+ * Escape semi reserved words from `Object` when printing (`constructor` -> `$constructor`). This only matters if you call Fay from JS+ * `Automatic` now handles lists and tuples (#251)+ * `Language.Fay.FFI` renamed to `Fay.FFI` (as before, Fay code can import `FFI` from `fay-base`)++Minor:+ * Print location of parse errors+ * Compile with -XNoImplicitPrelude+ * Support for testing nested modules (module A, module A.B)+ * Bump `language-ecmascript to >= 0.15` (new API)+ * Rename/remove some CompileErrors+ * All tests are now included in dist++Bug fixes:+ * Force cars in string serialization (#306)++## 0.15.0.0 (2013-06-08)+ * Expression level FFI calls, `ffi "alert('hello!')" :: Fay ()`+ * Support let pattern matches+ * Smaller output for serialization code+ * --base-path flag to use a custom base (mainly for fay-prim)+ * Allow ExistentialQuantification, FlexibleContexts, FlexibleInstances, KindSignatures+ * Verify that GADTs using non-record syntax works+ * JS->Fay function serialization+ * Serialization support for `()`, tuples and `Char`+ * Add more reserved words for Google Closure++Bugfixes:+ * Fix a bug when an imported module contains types+ * Fix a bug with EModuleContents exports+ * Fix where clause inside pattern guards in function definitions+ * Fix type variables in serialization for multiple constructors+ * Fix EThingAll exports for types with constructors with a different name+ * Don't export types in EThingAll and EThingWith+++### 0.14.5.0 (2013-04-24)+* Support for newtypes (with no runtime cost!)+* --base-path flag to specify custom locations for fay-base+* Fix a bug where imports shadowing local bindings would prevent the local binding from being exported+++### 0.14.4.0 (2013-04-21)+* Fix record updates on IE <= 8+* Import tweaks, will make compilation a lot faster (4x reported) when there are a lot of imports+* Parse hs sources with base fixities
+ README.md view
@@ -0,0 +1,7 @@+# Fay programming language++[](http://travis-ci.org/faylang/fay)++We use the Github wiki for our home page and documentation: https://github.com/faylang/fay/wiki++[Changelog](CHANGELOG.md)
fay.cabal view
@@ -1,5 +1,5 @@ name: fay-version: 0.18.1+version: 0.18.1.1 synopsis: A compiler for Fay, a Haskell subset that compiles to JavaScript. description: Fay is a proper subset of Haskell which is type-checked with GHC, and compiled to JavaScript. It is lazy, pure, has a Fay monad,@@ -23,7 +23,7 @@ license: BSD3 license-file: LICENSE author: Chris Done, Adam Bergmark-maintainer: adam@edea.se+maintainer: adam@bergmark.nl copyright: 2012 Chris Done, Adam Bergmark category: Development, Web, Fay build-type: Custom@@ -31,6 +31,9 @@ data-files: js/runtime.js src/Fay/FFI.hs extra-source-files:+ LICENSE+ README.md+ CHANGELOG.md -- Examples examples/*.hs examples/*.html
src/Fay.hs view
@@ -20,8 +20,7 @@ ) where import Fay.Compiler-import Fay.Compiler.Misc (ioWarn,- printSrcSpanInfo)+import Fay.Compiler.Misc (ioWarn, printSrcSpanInfo) import Fay.Compiler.Packages import Fay.Compiler.Typecheck import qualified Fay.Exts as F@@ -29,15 +28,15 @@ import Control.Applicative import Control.Monad-import Data.Aeson (encode)-import qualified Data.ByteString.Lazy as L+import Data.Aeson (encode)+import qualified Data.ByteString.Lazy as L import Data.Default import Data.List import Language.Haskell.Exts.Annotated (prettyPrint) import Language.Haskell.Exts.Annotated.Syntax import Language.Haskell.Exts.SrcLoc import Paths_fay-import SourceMap (generate)+import SourceMap (generate) import SourceMap.Types import System.FilePath @@ -166,6 +165,7 @@ ShouldBeDesugared s -> "Expected this to be desugared (this is a bug): " ++ s UnableResolveQualified qname -> "unable to resolve qualified names " ++ prettyPrint qname UnsupportedDeclaration d -> "unsupported declaration: " ++ prettyPrint d+ UnsupportedEnum{} -> "only Int is allowed in enum expressions" UnsupportedExportSpec es -> "unsupported export specification: " ++ prettyPrint es UnsupportedExpression expr -> "unsupported expression syntax: " ++ prettyPrint expr UnsupportedFieldPattern p -> "unsupported field pattern: " ++ prettyPrint p
src/Fay/Compiler/Desugar.hs view
@@ -6,6 +6,7 @@ (desugar ) where +import Fay.Exts.NoAnnotation (unAnn) import Fay.Types (CompileError (..)) import Control.Applicative@@ -116,10 +117,10 @@ Paren l e -> Paren l <$> desugarExp e RecConstr l q f -> RecConstr l (desugarQName q) <$> mapM desugarFieldUpdate f RecUpdate l e f -> RecUpdate l <$> desugarExp e <*> mapM desugarFieldUpdate f- EnumFrom l e -> EnumFrom l <$> desugarExp e- EnumFromTo l e1 e2 -> EnumFromTo l <$> desugarExp e1 <*> desugarExp e2- EnumFromThen l e1 e2 -> EnumFromThen l <$> desugarExp e1 <*> desugarExp e2- EnumFromThenTo l e1 e2 e3 -> EnumFromThenTo l <$> desugarExp e1 <*> desugarExp e2 <*> desugarExp e3+ e@(EnumFrom l e1) -> checkEnum e >> (EnumFrom l <$> desugarExp e1)+ e@(EnumFromTo l e1 e2) -> checkEnum e >> (EnumFromTo l <$> desugarExp e1 <*> desugarExp e2)+ e@(EnumFromThen l e1 e2) -> checkEnum e >> (EnumFromThen l <$> desugarExp e1 <*> desugarExp e2)+ e@(EnumFromThenTo l e1 e2 e3) -> checkEnum e >> (EnumFromThenTo l <$> desugarExp e1 <*> desugarExp e2 <*> desugarExp e3) ListComp l e qs -> ListComp l <$> desugarExp e <*> mapM desugarQualStmt qs ParComp l e qqs -> ParComp l <$> desugarExp e <*> mapM (mapM desugarQualStmt) qqs ExpTypeSig l e t -> ExpTypeSig l <$> desugarExp e <*> return (desugarType t)@@ -286,3 +287,32 @@ (rn, re) <- genSlotNames l rest ns e' <- desugarExp e return (rn, e' : re)++-- | We only have Enum instance for Int, but GHC hard codes [x..y]+-- syntax to GHC.Base.Enum instead of using our Enum class so we check+-- for obviously incorrect usages and throw an error on them. This can+-- only checks literals, but it helps a bit.+checkEnum :: Exp l -> Desugar ()+checkEnum exp = case exp of+ EnumFrom _ e -> checkIntOrUnknown [e]+ EnumFromTo _ e1 e2 -> checkIntOrUnknown [e1,e2]+ EnumFromThen _ e1 e2 -> checkIntOrUnknown [e1,e2]+ EnumFromThenTo _ e1 e2 e3 -> checkIntOrUnknown [e1,e2,e3]+ _ -> error "checkEnum: Only for Enums"+ where+ checkIntOrUnknown :: [Exp l] -> Desugar ()+ checkIntOrUnknown es = if any isIntOrUnknown es+ then return ()+ else throwError . UnsupportedEnum $ unAnn exp+ isIntOrUnknown :: Exp l -> Bool+ isIntOrUnknown e = case e of+ Con {} -> False+ Lit _ Int{} -> True+ Lit {} -> False+ Tuple {} -> False+ List {} -> False+ EnumFrom {} -> False+ EnumFromTo {} -> False+ EnumFromThen {} -> False+ EnumFromThenTo {} -> False+ _ -> True
src/Fay/Compiler/Exp.hs view
@@ -28,6 +28,7 @@ import Control.Applicative import Control.Monad.Error import Control.Monad.RWS+import qualified Data.Char as Char import Language.Haskell.Exts.Annotated import Language.Haskell.Names @@ -276,18 +277,18 @@ compileRecConstr :: S.QName -> [S.FieldUpdate] -> Compile JsExp compileRecConstr name fieldUpdates = do -- var obj = new $_Type()- let unQualName = unQualify $ unAnn name+ let unQualName = withIdent lowerFirst . unQualify $ unAnn name qname <- unsafeResolveName name let record = JsVar (JsNameVar unQualName) (JsNew (JsConstructor qname) []) setFields <- liftM concat (forM fieldUpdates (updateStmt name))- return $ JsApp (JsFun Nothing [] (record:setFields) (Just $ JsName $ JsNameVar $ unQualify $ unAnn name)) []+ return $ JsApp (JsFun Nothing [] (record:setFields) (Just . JsName . JsNameVar . withIdent lowerFirst . unQualify $ unAnn name)) [] where -- updateStmt :: QName a -> S.FieldUpdate -> Compile [JsStmt] updateStmt (unAnn -> o) (FieldUpdate _ (unAnn -> field) value) = do exp <- compileExp value- return [JsSetProp (JsNameVar $ unQualify o) (JsNameVar $ unQualify field) exp]- updateStmt name (FieldWildcard (wildcardFields -> fields)) = do- return $ for fields $ \fieldName -> JsSetProp (JsNameVar $ unAnn name)+ return [JsSetProp (JsNameVar $ withIdent lowerFirst $ unQualify o) (JsNameVar $ unQualify field) exp]+ updateStmt o (FieldWildcard (wildcardFields -> fields)) = do+ return $ for fields $ \fieldName -> JsSetProp (JsNameVar . withIdent lowerFirst . unQualify . unAnn $ o) (JsNameVar fieldName) (JsName $ JsNameVar fieldName) -- I couldn't find a code that generates (FieldUpdate (FieldPun ..))@@ -296,6 +297,9 @@ wildcardFields l = case l of Scoped (RecExpWildcard es) _ -> map (unQualify . origName2QName) . map fst $ es _ -> []+ lowerFirst :: String -> String+ lowerFirst "" = ""+ lowerFirst (x:xs) = '_' : Char.toLower x : xs -- | Compile a record update. compileRecUpdate :: S.Exp -> [S.FieldUpdate] -> Compile JsExp
src/Fay/Compiler/QName.hs view
@@ -30,6 +30,17 @@ changeModule' f (Qual l (ModuleName ml mn) n) = Qual l (ModuleName ml $ f mn) n changeModule' _ x = x +withIdent :: (String -> String) -> QName a -> QName a+withIdent f q = case q of+ Qual l m n -> Qual l m $ withIdent' f n+ UnQual l n -> UnQual l $ withIdent' f n+ Special{} -> q+ where+ withIdent' :: (String -> String) -> Name a -> Name a+ withIdent' f' n' = case n' of+ Symbol{} -> n'+ Ident l s -> Ident l (f' s)+ -- | Extract the string from a Name. unname :: Name a -> String unname (Ident _ s) = s
src/Fay/Types.hs view
@@ -208,6 +208,7 @@ | ShouldBeDesugared String | UnableResolveQualified N.QName | UnsupportedDeclaration S.Decl+ | UnsupportedEnum N.Exp | UnsupportedExportSpec N.ExportSpec | UnsupportedExpression S.Exp | UnsupportedFieldPattern S.PatField
src/tests/Test/Compile.hs view
@@ -18,8 +18,7 @@ import Test.Framework import Test.Framework.Providers.HUnit import Test.Framework.TH-import Test.HUnit (Assertion, assertBool,- assertEqual, assertFailure)+import Test.HUnit (Assertion, assertBool, assertEqual, assertFailure) import Test.Util tests :: Test@@ -97,3 +96,12 @@ defConf :: CompileConfig defConf = addConfigDirectoryIncludePaths ["tests/"] $ def { configTypecheck = False }++case_charEnum :: Assertion+case_charEnum = do+ whatAGreatFramework <- fmap (lookup "HASKELL_PACKAGE_SANDBOX") getEnvironment+ res <- compileFile defConf { configPackageConf = whatAGreatFramework, configTypecheck = True, configFilePath = Just "tests/Compile/EnumChar.hs" } "tests/Compile/EnumChar.hs"+ case res of+ Left UnsupportedEnum{} -> return ()+ Left l -> assertFailure $ "Should have failed with UnsupportedEnum, but failed with: " ++ show l+ Right _ -> assertFailure $ "Should have failed with UnsupportedEnum, but compiled"
+ tests/Compile/EnumChar.hs view
@@ -0,0 +1,9 @@+module EnumChar where++import Prelude++f :: [Char]+f = ['a'..'z']++main :: Fay ()+main = print f
tests/Compile/StrictWrapper.hs view
@@ -1,4 +1,4 @@-module StrictWrapper (f,g,h,r) where+module StrictWrapper (f,g,h,r,clog) where import FFI import Prelude@@ -17,6 +17,9 @@ r :: R r = R 2 +clog :: a -> Fay ()+clog = ffi "console.log(%1)"+ -- You should probably not use the strict wrapper from Fay, this is just for the sake of the test. main :: Fay () main = do@@ -24,3 +27,4 @@ ffi "console.log(Strict.StrictWrapper.g({instance:'R',i:1}))" :: Fay () ffi "console.log(Strict.StrictWrapper.h({instance:'R',i:1}))" :: Fay () ffi "console.log(Strict.StrictWrapper.r)" :: Fay ()+ ffi "Strict.StrictWrapper.clog(123)" :: Fay ()
tests/Compile/StrictWrapper.res view
@@ -2,3 +2,4 @@ 1 { instance: 'R', i: 2 } { instance: 'R', i: 2 }+123
+ tests/ModuleRecordClash2.hs view
@@ -0,0 +1,11 @@+module Main where++import FFI+import ModuleRecordClash2_Hello+import Prelude++alert :: String -> Fay ()+alert = ffi "console.log(%1)"++main = do+ alert (greeting defaultHello)
+ tests/ModuleRecordClash2.res view
@@ -0,0 +1,1 @@+Hello, world!
+ tests/ModuleRecordClash2_Hello.hs view
@@ -0,0 +1,9 @@+-- This module needs to be top level to do the intended test.+module ModuleRecordClash2_Hello where++import Prelude++defaultHello :: ModuleRecordClash2_Hello+defaultHello = ModuleRecordClash2_Hello { greeting = "Hello, world!" }++data ModuleRecordClash2_Hello = ModuleRecordClash2_Hello { greeting :: String }
+ tests/ModuleRecordClash2_Hello.res view