Skip to content

Add support for unparenthesized arrow functions of one parameter #90

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 16, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions src/Language/JavaScript/Parser/AST.hs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ module Language.JavaScript.Parser.AST
, JSArrayElement (..)
, JSCommaList (..)
, JSCommaTrailingList (..)
, JSArrowParameterList (..)

-- Modules
, JSModuleItem (..)
Expand Down Expand Up @@ -170,7 +171,7 @@ data JSExpression
| JSExpressionParen !JSAnnot !JSExpression !JSAnnot -- ^lb,expression,rb
| JSExpressionPostfix !JSExpression !JSUnaryOp -- ^expression, operator
| JSExpressionTernary !JSExpression !JSAnnot !JSExpression !JSAnnot !JSExpression -- ^cond, ?, trueval, :, falseval
| JSArrowExpression !JSAnnot !(JSCommaList JSIdent) !JSAnnot !JSAnnot !JSStatement -- ^parameter list,arrow,block`
| JSArrowExpression !JSArrowParameterList !JSAnnot !JSStatement -- ^parameter list,arrow,block`
| JSFunctionExpression !JSAnnot !JSIdent !JSAnnot !(JSCommaList JSIdent) !JSAnnot !JSBlock -- ^fn,name,lb, parameter list,rb,block`
| JSMemberDot !JSExpression !JSAnnot !JSExpression -- ^firstpart, dot, name
| JSMemberExpression !JSExpression !JSAnnot !(JSCommaList JSExpression) !JSAnnot -- expr, lb, args, rb
Expand All @@ -183,6 +184,11 @@ data JSExpression
| JSVarInitExpression !JSExpression !JSVarInitializer -- ^identifier, initializer
deriving (Data, Eq, Show, Typeable)

data JSArrowParameterList
= JSUnparenthesizedArrowParameter !JSIdent
| JSParenthesizedArrowParameterList !JSAnnot !(JSCommaList JSIdent) !JSAnnot
deriving (Data, Eq, Show, Typeable)

data JSBinOp
= JSBinOpAnd !JSAnnot
| JSBinOpAs !JSAnnot
Expand Down Expand Up @@ -369,7 +375,7 @@ instance ShowStripped JSExpression where
ss (JSExpressionParen _lp x _rp) = "JSExpressionParen (" ++ ss x ++ ")"
ss (JSExpressionPostfix xs op) = "JSExpressionPostfix (" ++ ss op ++ "," ++ ss xs ++ ")"
ss (JSExpressionTernary x1 _q x2 _c x3) = "JSExpressionTernary (" ++ ss x1 ++ "," ++ ss x2 ++ "," ++ ss x3 ++ ")"
ss (JSArrowExpression _ n _ _ e) = "JSArrowExpression (" ++ ss n ++ ") => " ++ ss e
ss (JSArrowExpression ps _ e) = "JSArrowExpression (" ++ ss ps ++ ") => " ++ ss e
ss (JSFunctionExpression _ n _lb pl _rb x3) = "JSFunctionExpression " ++ ssid n ++ " " ++ ss pl ++ " (" ++ ss x3 ++ "))"
ss (JSHexInteger _ s) = "JSHexInteger " ++ singleQuote s
ss (JSOctal _ s) = "JSOctal " ++ singleQuote s
Expand All @@ -388,6 +394,10 @@ instance ShowStripped JSExpression where
ss (JSVarInitExpression x1 x2) = "JSVarInitExpression (" ++ ss x1 ++ ") " ++ ss x2
ss (JSSpreadExpression _ x1) = "JSSpreadExpression (" ++ ss x1 ++ ")"

instance ShowStripped JSArrowParameterList where
ss (JSUnparenthesizedArrowParameter x) = ss x
ss (JSParenthesizedArrowParameterList _ xs _) = ss xs

instance ShowStripped JSModuleItem where
ss (JSModuleExportDeclaration _ x1) = "JSModuleExportDeclaration (" ++ ss x1 ++ ")"
ss (JSModuleImportDeclaration _ x1) = "JSModuleImportDeclaration (" ++ ss x1 ++ ")"
Expand Down
14 changes: 10 additions & 4 deletions src/Language/JavaScript/Parser/Grammar7.y
Original file line number Diff line number Diff line change
Expand Up @@ -1136,10 +1136,16 @@ FunctionExpression : ArrowFunctionExpression { $1 {- 'ArrowFunctionExpressio
| NamedFunctionExpression { $1 {- 'FunctionExpression2' -} }

ArrowFunctionExpression :: { AST.JSExpression }
ArrowFunctionExpression : LParen RParen Arrow StatementOrBlock
{ AST.JSArrowExpression $1 AST.JSLNil $2 $3 $4 {- 'ArrowFunctionExpression1' -} }
| LParen FormalParameterList RParen Arrow StatementOrBlock
{ AST.JSArrowExpression $1 $2 $3 $4 $5 {- 'ArrowFunctionExpression3' -} }
ArrowFunctionExpression : ArrowParameterList Arrow StatementOrBlock
{ AST.JSArrowExpression $1 $2 $3 }

ArrowParameterList :: { AST.JSArrowParameterList }
ArrowParameterList : Identifier
{ AST.JSUnparenthesizedArrowParameter (identName $1) }
| LParen RParen
{ AST.JSParenthesizedArrowParameterList $1 AST.JSLNil $2 }
| LParen FormalParameterList RParen
{ AST.JSParenthesizedArrowParameterList $1 $2 $3 }

StatementOrBlock :: { AST.JSStatement }
StatementOrBlock : Block MaybeSemi { blockToStatement $1 $2 }
Expand Down
5 changes: 4 additions & 1 deletion src/Language/JavaScript/Pretty/Printer.hs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ instance RenderJS JSExpression where

-- Non-Terminals
(|>) pacc (JSArrayLiteral als xs ars) = pacc |> als |> "[" |> xs |> ars |> "]"
(|>) pacc (JSArrowExpression lp xs rp a x) = pacc |> lp |> "(" |> xs |> rp |> ")" |> a |> "=>" |> x
(|>) pacc (JSArrowExpression xs a x) = pacc |> xs |> a |> "=>" |> x
(|>) pacc (JSAssignExpression lhs op rhs) = pacc |> lhs |> op |> rhs
(|>) pacc (JSCallExpression ex lb xs rb) = pacc |> ex |> lb |> "(" |> xs |> rb |> ")"
(|>) pacc (JSCallExpressionDot ex os xs) = pacc |> ex |> os |> "." |> xs
Expand All @@ -93,6 +93,9 @@ instance RenderJS JSExpression where
(|>) pacc (JSVarInitExpression x1 x2) = pacc |> x1 |> x2
(|>) pacc (JSSpreadExpression a e) = pacc |> a |> "..." |> e

instance RenderJS JSArrowParameterList where
(|>) pacc (JSUnparenthesizedArrowParameter p) = pacc |> p
(|>) pacc (JSParenthesizedArrowParameterList lb ps rb) = pacc |> lb |> "(" |> ps |> ")" |> rb
-- -----------------------------------------------------------------------------
-- Need an instance of RenderJS for every component of every JSExpression or JSAnnot
-- constuctor.
Expand Down
7 changes: 5 additions & 2 deletions src/Language/JavaScript/Process/Minify.hs
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ instance MinifyJS JSExpression where

-- Non-Terminals
fix _ (JSArrayLiteral _ xs _) = JSArrayLiteral emptyAnnot (map fixEmpty xs) emptyAnnot
fix _ (JSArrowExpression _ ps _ _ ss) = JSArrowExpression emptyAnnot (fixEmpty ps) emptyAnnot emptyAnnot (fixStmt emptyAnnot noSemi ss)
fix a (JSArrowExpression ps _ ss) = JSArrowExpression (fix a ps) emptyAnnot (fixStmt emptyAnnot noSemi ss)
fix a (JSAssignExpression lhs op rhs) = JSAssignExpression (fix a lhs) (fixEmpty op) (fixEmpty rhs)
fix a (JSCallExpression ex _ xs _) = JSCallExpression (fix a ex) emptyAnnot (fixEmpty xs) emptyAnnot
fix a (JSCallExpressionDot ex _ xs) = JSCallExpressionDot (fix a ex) emptyAnnot (fixEmpty xs)
Expand All @@ -169,6 +169,9 @@ instance MinifyJS JSExpression where
fix a (JSVarInitExpression x1 x2) = JSVarInitExpression (fix a x1) (fixEmpty x2)
fix a (JSSpreadExpression _ e) = JSSpreadExpression a (fixEmpty e)

instance MinifyJS JSArrowParameterList where
fix _ (JSUnparenthesizedArrowParameter p) = JSUnparenthesizedArrowParameter (fixEmpty p)
fix _ (JSParenthesizedArrowParameterList _ ps _) = JSParenthesizedArrowParameterList emptyAnnot (fixEmpty ps) emptyAnnot

fixVarList :: JSCommaList JSExpression -> JSCommaList JSExpression
fixVarList (JSLCons h _ v) = JSLCons (fixVarList h) emptyAnnot (fixEmpty v)
Expand Down Expand Up @@ -302,7 +305,7 @@ instance MinifyJS JSImportNameSpace where
fix a (JSImportNameSpace _ _ ident) = JSImportNameSpace (JSBinOpTimes a) (JSBinOpAs spaceAnnot) (fixSpace ident)

instance MinifyJS JSImportsNamed where
fix _ (JSImportsNamed _ imps _) = JSImportsNamed emptyAnnot (fixEmpty imps) emptyAnnot
fix _ (JSImportsNamed _ imps _) = JSImportsNamed emptyAnnot (fixEmpty imps) emptyAnnot

instance MinifyJS JSImportSpecifier where
fix _ (JSImportSpecifier x1) = JSImportSpecifier (fixEmpty x1)
Expand Down
1 change: 1 addition & 0 deletions test/Test/Language/Javascript/ExpressionParser.hs
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ testExpressionParser = describe "Parse expressions:" $ do
testExpr "function(){}" `shouldBe` "Right (JSAstExpression (JSFunctionExpression '' () (JSBlock []))))"
testExpr "function(a){}" `shouldBe` "Right (JSAstExpression (JSFunctionExpression '' (JSIdentifier 'a') (JSBlock []))))"
testExpr "function(a,b){}" `shouldBe` "Right (JSAstExpression (JSFunctionExpression '' (JSIdentifier 'a',JSIdentifier 'b') (JSBlock []))))"
testExpr "a => {}" `shouldBe` "Right (JSAstExpression (JSArrowExpression (JSIdentifier 'a') => JSStatementBlock []))"
testExpr "(a) => { a + 2 }" `shouldBe` "Right (JSAstExpression (JSArrowExpression ((JSIdentifier 'a')) => JSStatementBlock [JSExpressionBinary ('+',JSIdentifier 'a',JSDecimal '2')]))"
testExpr "(a, b) => {}" `shouldBe` "Right (JSAstExpression (JSArrowExpression ((JSIdentifier 'a',JSIdentifier 'b')) => JSStatementBlock []))"
testExpr "(a, b) => a + b" `shouldBe` "Right (JSAstExpression (JSArrowExpression ((JSIdentifier 'a',JSIdentifier 'b')) => JSExpressionBinary ('+',JSIdentifier 'a',JSIdentifier 'b')))"
Expand Down
1 change: 1 addition & 0 deletions test/Test/Language/Javascript/Minify.hs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ testMinifyExpr = describe "Minify expressions:" $ do
minifyExpr " function ( a ) { } " `shouldBe` "function(a){}"
minifyExpr " function ( a , b ) { return a + b ; } " `shouldBe` "function(a,b){return a+b}"

minifyExpr "a => {}" `shouldBe` "a=>{}"
minifyExpr "(a) => {}" `shouldBe` "(a)=>{}"
minifyExpr "( a ) => { a + 2 }" `shouldBe` "(a)=>a+2"
minifyExpr "(a, b) => a + b" `shouldBe` "(a,b)=>a+b"
Expand Down
1 change: 1 addition & 0 deletions test/Test/Language/Javascript/RoundTrip.hs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ testRoundTrip = describe "Roundtrip:" $ do
testRT "/*a*/x/*b*/=/*c*/{/*d*/get/*e*/ foo/*f*/(/*g*/)/*h*/ {/*i*/return/*j*/ 1/*k*/}/*l*/,/*m*/set/*n*/ foo/*o*/(/*p*/a/*q*/) /*r*/{/*s*/x/*t*/=/*u*/a/*v*/}/*w*/}"
testRT "... /*a*/ x"

testRT "a => {}"
testRT "(a) => { a + 2 }"
testRT "(a, b) => {}"
testRT "(a, b) => a + b"
Expand Down