language-ecmascript 0.15 → 0.15.1
raw patch · 8 files changed
+33/−184 lines, 8 files
Files
- CHANGELOG +6/−0
- language-ecmascript.cabal +6/−11
- src/Language/ECMAScript3/PrettyPrint.hs +16/−9
- src/Language/ECMAScript3/SourceDiff.hs +3/−12
- test/Test/Diff.hs +0/−58
- test/Test/Pretty.hs +0/−43
- test/Test/Unit.hs +0/−49
- test/diff/expects/t1.diff +2/−2
CHANGELOG view
@@ -1,5 +1,11 @@ Version change log. +=0.15.1=+Added semicolons after the "return" statement in the pretty printer to+avoid certain class of syntax error when printed code is parsed+again. Changed the pretty-printer to put the IntLit in parenthesis if it's+found on the left-side of the '.' (field access) operator.+ =0.15= Bug fixes in the pretty-printer, the parser and the QuickCheck arbitrary instance for the AST. Refactored tests to use test-framework. Reorganized
language-ecmascript.cabal view
@@ -1,5 +1,5 @@ Name: language-ecmascript-Version: 0.15+Version: 0.15.1 Cabal-Version: >= 1.10 Copyright: (c) 2007-2012 Brown University, (c) 2008-2010 Claudiu Saftoiu, (c) 2012-2013 Stevens Institute of Technology@@ -17,11 +17,10 @@ Build-Type: Simple Synopsis: JavaScript parser and pretty-printer library Description:- Tools for working with ECMAScript 3 (popularly known as JavaScript).- Includes a parser, pretty-printer, a simple quasi-quoter and tools- for working with source tree annotations and an arbitrary- instance. Analyses have migrated to package- 'language-ecmascript-analysis'.+ Tools for working with ECMAScript 3 (popularly known as JavaScript). + Includes a parser, pretty-printer, tools for working with source tree+ annotations and an arbitrary instance. Analyses have migrated to + language-ecmascript-analysis Source-repository head type: git@@ -30,7 +29,7 @@ Source-repository this type: git location: git://github.com/jswebtools/language-ecmascript.git- tag: 0.15+ tag: 0.15.1 Library Hs-Source-Dirs:@@ -71,10 +70,6 @@ Hs-Source-Dirs: test Type: exitcode-stdio-1.0 Main-Is: TestMain.hs- Other-Modules:- Test.Diff- Test.Unit- Test.Pretty Build-Depends: base >= 4 && < 5, mtl >= 1.1.0.1,
src/Language/ECMAScript3/PrettyPrint.hs view
@@ -47,8 +47,8 @@ braces (nest 2 (vcat (map prettyPrint cases))) WhileStmt _ test body -> text "while" <+> parens (ppExpression True test) $$ prettyPrint body- ReturnStmt _ Nothing -> text "return"- ReturnStmt _ (Just e) -> text "return" <+> ppExpression True e+ ReturnStmt _ Nothing -> text "return" <> semi+ ReturnStmt _ (Just e) -> text "return" <+> ppExpression True e <> semi DoWhileStmt _ s e -> text "do" $$ (prettyPrint s <+> text "while" <+> parens (ppExpression True e)@@ -75,8 +75,7 @@ Just stmt -> text "finally" <> inBlock stmt ppCatch = case mcatch of Nothing -> empty- Just (CatchClause _ id s) -> - text "catch" <+> (parens.prettyPrint) id <+> inBlock s+ Just cc -> prettyPrint cc ThrowStmt _ e -> text "throw" <+> ppExpression True e <> semi WithStmt _ e s -> text "with" <+> parens (ppExpression True e) $$ prettyPrint s@@ -88,6 +87,10 @@ parens (cat $ punctuate comma (map prettyPrint args)) $$ asBlock body +instance Pretty (CatchClause a) where+ prettyPrint (CatchClause _ id s) =+ text "catch" <+> (parens.prettyPrint) id <+> inBlock s+ instance Pretty (ForInit a) where prettyPrint t = case t of NoInit -> empty@@ -103,7 +106,7 @@ instance Pretty (LValue a) where prettyPrint lv = case lv of LVar _ x -> text x- LDot _ e x -> ppMemberExpression e <> text "." <> text x+ LDot _ e x -> ppObjInDotRef e ppMemberExpression <> text "." <> text x LBracket _ e1 e2 -> ppMemberExpression e1 <> brackets (ppExpression True e2) @@ -273,7 +276,7 @@ text "function" <+> maybe name prettyPrint <+> parens (cat $ punctuate comma (map prettyPrint params)) $$ asBlock body- DotRef _ obj id -> ppMemberExpression obj <> text "." <> prettyPrint id+ DotRef _ obj id -> ppObjInDotRef obj ppMemberExpression <> text "." <> prettyPrint id BracketRef _ obj key -> ppMemberExpression obj <> brackets (ppExpression True key) NewExpr _ ctor args -> @@ -283,11 +286,15 @@ ppCallExpression :: Expression a -> Doc ppCallExpression e = case e of CallExpr _ f args -> ppCallExpression f <> ppArguments args- DotRef _ obj id -> ppCallExpression obj <> text "." <> prettyPrint id+ DotRef _ obj id -> ppObjInDotRef obj ppCallExpression <> text "." <> prettyPrint id BracketRef _ obj key -> ppCallExpression obj <> brackets (ppExpression True key)- _ -> ppMemberExpression e - + _ -> ppMemberExpression e++ppObjInDotRef :: Expression a -> (Expression a -> Doc) -> Doc+ppObjInDotRef i@(IntLit _ _) _ = parens (ppPrimaryExpression i)+ppObjInDotRef e p = p e+ ppArguments :: [Expression a] -> Doc ppArguments es = parens $ cat $ punctuate comma (map (ppAssignmentExpression True) es)
src/Language/ECMAScript3/SourceDiff.hs view
@@ -3,22 +3,13 @@ module Language.ECMAScript3.SourceDiff where import Data.Algorithm.Diff---import Data.Algorithm.DiffOutput+import Data.Algorithm.DiffOutput import Language.ECMAScript3.Syntax import Language.ECMAScript3.PrettyPrint-import Data.List (intersperse)-+import Data.List (intersperse, intercalate) jsDiff :: JavaScript a -> JavaScript a -> String jsDiff js1 js2 = - -- let plines = lines . show . prettyPrint- -- in ppDiff $ getGroupedDiff (plines js1) (plines js2) let plines = lines . show . prettyPrint diff = getGroupedDiff (plines js1) (plines js2)- formatDiff :: Diff [String] -> String- formatDiff d = let (prefix, strs) = case d of- First ss -> ('-', ss)- Second ss -> ('+', ss)- Both ss _ -> (' ', ss)- in concat $ intersperse "\n" $ map (prefix:) strs- in concat $ intersperse "\n" $ map formatDiff diff+ in ppDiff diff
− test/Test/Diff.hs
@@ -1,58 +0,0 @@-module Test.Diff where--import Test.HUnit hiding (Test)-import Test.Framework-import Test.Framework.Providers.HUnit-import System.Exit-import System.Directory-import qualified System.FilePath as FP-import Language.ECMAScript3.Parser-import Language.ECMAScript3.PrettyPrint-import Language.ECMAScript3.Syntax-import Language.ECMAScript3.Syntax.Annotations-import Language.ECMAScript3.SourceDiff-import Control.Monad--tests_diff :: Test-tests_diff =- buildTest $- do allLefts <- getDirectoryContents leftDir- allRights <- getDirectoryContents rightDir- allDiffs <- getDirectoryContents expectsDir- let validLefts = getValidJS allLefts- let validRights = getValidJS allRights- let validDiffs = getValidDiffs allDiffs- return $ testGroup "Source Diff tests" $- map genTest $ filter ((`elem` (map FP.dropExtension validDiffs)) .- FP.dropExtension)- $ filter (`elem` validRights) validLefts- where getValidJS = filter $ \x -> FP.takeExtension x == ".js"- getValidDiffs = filter $ \x -> FP.takeExtension x == ".diff"--leftDir = "test/diff/left"-rightDir = "test/diff/right"-expectsDir = "test/diff/expects"--genTest :: FilePath -> Test-genTest testFileName = testCase testFileName $- diffTest (leftDir `FP.combine` testFileName)- (rightDir `FP.combine` testFileName)- (expectsDir `FP.combine`- ((FP.dropExtension testFileName)- `FP.addExtension` "diff"))--diffTest :: FilePath -> FilePath -> FilePath -> Assertion-diffTest leftFile rightFile diffFile =- do left <- readFile leftFile- right <- readFile rightFile- expect<- readFile diffFile- let x = do ljs <- parseFromString left- rjs <- parseFromString right- return (removeAnnotations ljs, removeAnnotations rjs)- case x of- Left err -> assertFailure $ "Parsing error: " ++ (show err)- Right (ljs, rjs) ->- let diff = jsDiff ljs rjs- msg = "Failed to match diff output to an expected one. Expected:\n"- ++ expect ++ "\nSaw:\n" ++ diff- in unless (diff == expect) (assertFailure msg)
− test/Test/Pretty.hs
@@ -1,43 +0,0 @@-module Test.Pretty where--import Test.Framework-import Test.Framework.Providers.QuickCheck2-import Language.ECMAScript3.Parser-import Language.ECMAScript3.PrettyPrint-import Language.ECMAScript3.Syntax-import Language.ECMAScript3.Syntax.Arbitrary()-import Language.ECMAScript3.Syntax.Annotations---import System.Exit-import Language.ECMAScript3.SourceDiff-import Test.QuickCheck--tests_pretty :: Test-tests_pretty = testProperty "Parse is the inverse of pretty" prettyParseEquivalence---- main :: IO ()--- main = --- let qcArgs = Args {maxSuccess = 50--- ,maxDiscardRatio = 10--- ,maxSize = 10--- ,replay = Nothing--- ,chatty = False}--- in quickCheckWithResult qcArgs prettyParseEquivalence >>= \res ->--- case res of--- Success {} -> putStrLn "All tests passes"--- GaveUp {} -> putStrLn "Gave up"--- Failure {} -> putStrLn "Test failed" >> exitFailure--- NoExpectedFailure {} -> putStrLn "Unexpected failure" >> exitFailure--prettyParseEquivalence :: JavaScript () -> Property-prettyParseEquivalence orig =- let pp = show $ prettyPrint orig- in case parseFromString pp of- Left e -> - let err = "Can't parse pretty-printed code. The error was: " ++ (show e) ++- "\nThe pretty-printed code in question:\n" ++ pp- in whenFail (putStrLn err) False- Right parsed ->- let eq = (removeAnnotations parsed) == orig- msg ="The parse of the pretty-printed AST didn't match the original\n"- ++"Diff:\n" ++ jsDiff orig (reannotate (const ()) parsed)- in whenFail (putStrLn msg) eq
− test/Test/Unit.hs
@@ -1,49 +0,0 @@-module Test.Unit where--import Test.Framework-import Test.Framework.Providers.HUnit-import Test.HUnit hiding (Test)-import System.Exit-import System.Directory-import qualified System.FilePath as FilePath-import Language.ECMAScript3.Parser-import Language.ECMAScript3.PrettyPrint-import Language.ECMAScript3.Syntax-import Language.ECMAScript3.Syntax.Annotations-import Language.ECMAScript3.SourceDiff-import Control.Monad---tests_unit :: Test-tests_unit =- buildTest $- do allFiles <- getDirectoryContents testDir- let validFiles = filter (\x -> FilePath.takeExtension x == ".js") allFiles- return $ testGroup "Parser Unit tests" $ map genTest validFiles---genTest :: FilePath -> Test-genTest file = testCase file $ parsePrettyTest (testDir `FilePath.combine` file) --testDir = "test/parse-pretty"---- | tests the parser with pre-defined test-cases-parsePrettyTest :: FilePath -> Assertion-parsePrettyTest filename =- readFile filename >>= \src ->- case parseFromString src of- Left err -> assertFailure $ "Can't parse a test-case: " ++ filename- Right js -> let str = show $ prettyPrint js- in case parseFromString str of- Left err ->- let msg = "Can't parse pretty-printed code. The error was: "- ++ (show err)- ++ "\nThe pretty-printed code in question:\n" ++ str- in assertFailure msg- Right js' -> do- let str' = show $ prettyPrint js'- unless (str == str') $ do- let msg = "The parse of the pretty-printed AST didn't match the original\n"- ++ "Diff:\n" ++ jsDiff js js'- assertFailure msg-
test/diff/expects/t1.diff view
@@ -1,2 +1,2 @@- x = 1;--y = 2;+2d1+< y = 2;