diff --git a/src/Language/JavaScript/Parser/AST.hs b/src/Language/JavaScript/Parser/AST.hs index af80d65e..4dd67db2 100644 --- a/src/Language/JavaScript/Parser/AST.hs +++ b/src/Language/JavaScript/Parser/AST.hs @@ -292,6 +292,7 @@ data JSPropertyName = JSPropertyIdent !JSAnnot !String | JSPropertyString !JSAnnot !String | JSPropertyNumber !JSAnnot !String + | JSPropertyComputed !JSAnnot !JSExpression !JSAnnot -- ^lb, expr, rb deriving (Data, Eq, Show, Typeable) type JSObjectPropertyList = JSCommaTrailingList JSObjectProperty @@ -478,6 +479,7 @@ instance ShowStripped JSPropertyName where ss (JSPropertyIdent _ s) = "JSIdentifier " ++ singleQuote s ss (JSPropertyString _ s) = "JSIdentifier " ++ singleQuote s ss (JSPropertyNumber _ s) = "JSIdentifier " ++ singleQuote s + ss (JSPropertyComputed _ x _) = "JSPropertyComputed (" ++ ss x ++ ")" instance ShowStripped JSAccessor where ss (JSAccessorGet _) = "JSAccessorGet" diff --git a/src/Language/JavaScript/Parser/Grammar7.y b/src/Language/JavaScript/Parser/Grammar7.y index 4d8f6d42..baff8ce9 100644 --- a/src/Language/JavaScript/Parser/Grammar7.y +++ b/src/Language/JavaScript/Parser/Grammar7.y @@ -579,6 +579,7 @@ PropertyName :: { AST.JSPropertyName } PropertyName : IdentifierName { propName $1 {- 'PropertyName1' -} } | StringLiteral { propName $1 {- 'PropertyName2' -} } | NumericLiteral { propName $1 {- 'PropertyName3' -} } + | LSquare AssignmentExpression RSquare { AST.JSPropertyComputed $1 $2 $3 {- 'PropertyName4' -} } -- PropertySetParameterList : See 11.1.5 -- Identifier diff --git a/src/Language/JavaScript/Pretty/Printer.hs b/src/Language/JavaScript/Pretty/Printer.hs index f2c8795f..d0623dd4 100644 --- a/src/Language/JavaScript/Pretty/Printer.hs +++ b/src/Language/JavaScript/Pretty/Printer.hs @@ -276,6 +276,7 @@ instance RenderJS JSPropertyName where (|>) pacc (JSPropertyIdent a s) = pacc |> a |> s (|>) pacc (JSPropertyString a s) = pacc |> a |> s (|>) pacc (JSPropertyNumber a s) = pacc |> a |> s + (|>) pacc (JSPropertyComputed lb x rb) = pacc |> lb |> "[" |> x |> rb |> "]" instance RenderJS JSAccessor where (|>) pacc (JSAccessorGet annot) = pacc |> annot |> "get" diff --git a/src/Language/JavaScript/Process/Minify.hs b/src/Language/JavaScript/Process/Minify.hs index 992558f4..6096e3c8 100644 --- a/src/Language/JavaScript/Process/Minify.hs +++ b/src/Language/JavaScript/Process/Minify.hs @@ -364,6 +364,7 @@ instance MinifyJS JSPropertyName where fix a (JSPropertyIdent _ s) = JSPropertyIdent a s fix a (JSPropertyString _ s) = JSPropertyString a s fix a (JSPropertyNumber _ s) = JSPropertyNumber a s + fix _ (JSPropertyComputed _ x _) = JSPropertyComputed emptyAnnot (fixEmpty x) emptyAnnot instance MinifyJS JSAccessor where fix a (JSAccessorGet _) = JSAccessorGet a diff --git a/test/Test/Language/Javascript/ExpressionParser.hs b/test/Test/Language/Javascript/ExpressionParser.hs index 1422dd5a..8a76ffb7 100644 --- a/test/Test/Language/Javascript/ExpressionParser.hs +++ b/test/Test/Language/Javascript/ExpressionParser.hs @@ -58,6 +58,7 @@ testExpressionParser = describe "Parse expressions:" $ do testExpr "x={get foo() {return 1},set foo(a) {x=a}}" `shouldBe` "Right (JSAstExpression (JSOpAssign ('=',JSIdentifier 'x',JSObjectLiteral [JSPropertyAccessor JSAccessorGet (JSIdentifier 'foo') [] (JSBlock [JSReturn JSDecimal '1' ]),JSPropertyAccessor JSAccessorSet (JSIdentifier 'foo') [JSIdentifier 'a'] (JSBlock [JSOpAssign ('=',JSIdentifier 'x',JSIdentifier 'a')])])))" testExpr "{evaluate:evaluate,load:function load(s){if(x)return s;1}}" `shouldBe` "Right (JSAstExpression (JSObjectLiteral [JSPropertyNameandValue (JSIdentifier 'evaluate') [JSIdentifier 'evaluate'],JSPropertyNameandValue (JSIdentifier 'load') [JSFunctionExpression 'load' (JSIdentifier 's') (JSBlock [JSIf (JSIdentifier 'x') (JSReturn JSIdentifier 's' JSSemicolon),JSDecimal '1']))]]))" testExpr "obj = { name : 'A', 'str' : 'B', 123 : 'C', }" `shouldBe` "Right (JSAstExpression (JSOpAssign ('=',JSIdentifier 'obj',JSObjectLiteral [JSPropertyNameandValue (JSIdentifier 'name') [JSStringLiteral 'A'],JSPropertyNameandValue (JSIdentifier ''str'') [JSStringLiteral 'B'],JSPropertyNameandValue (JSIdentifier '123') [JSStringLiteral 'C'],JSComma])))" + testExpr "{[x]:1}" `shouldBe` "Right (JSAstExpression (JSObjectLiteral [JSPropertyNameandValue (JSPropertyComputed (JSIdentifier 'x')) [JSDecimal '1']]))" it "unary expression" $ do testExpr "delete y" `shouldBe` "Right (JSAstExpression (JSUnaryExpression ('delete',JSIdentifier 'y')))" diff --git a/test/Test/Language/Javascript/Minify.hs b/test/Test/Language/Javascript/Minify.hs index d032820a..56111bfc 100644 --- a/test/Test/Language/Javascript/Minify.hs +++ b/test/Test/Language/Javascript/Minify.hs @@ -42,6 +42,7 @@ testMinifyExpr = describe "Minify expressions:" $ do minifyExpr " { c : 3 , d : 4 , } " `shouldBe` "{c:3,d:4}" minifyExpr " { 'str' : true , 42 : false , } " `shouldBe` "{'str':true,42:false}" minifyExpr " { x , } " `shouldBe` "{x}" + minifyExpr " { [ x + y ] : 1 } " `shouldBe` "{[x+y]:1}" it "parentheses" $ do minifyExpr " ( 'hello' ) " `shouldBe` "('hello')" diff --git a/test/Test/Language/Javascript/RoundTrip.hs b/test/Test/Language/Javascript/RoundTrip.hs index f4098a52..3c5bca41 100644 --- a/test/Test/Language/Javascript/RoundTrip.hs +++ b/test/Test/Language/Javascript/RoundTrip.hs @@ -44,6 +44,7 @@ testRoundTrip = describe "Roundtrip:" $ do testRT "x=/*a*/{/*b*/x/*c*/:/*d*/1/*e*/,/*f*/y/*g*/:/*h*/2/*i*/}" testRT "x=/*a*/{/*b*/x/*c*/:/*d*/1/*e*/,/*f*/y/*g*/:/*h*/2/*i*/,/*j*/z/*k*/:/*l*/3/*m*/}" testRT "a=/*a*/{/*b*/x/*c*/:/*d*/1/*e*/,/*f*/}" + testRT "/*a*/{/*b*/[/*c*/x/*d*/+/*e*/y/*f*/]/*g*/:/*h*/1/*i*/}" it "miscellaneous" $ do testRT "/*a*/(/*b*/56/*c*/)"