Skip to content

Support Export Statements - WIP #78

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

Closed
wants to merge 2 commits into from
Closed
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
5 changes: 5 additions & 0 deletions src/Language/JavaScript/Parser/AST.hs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ data JSStatement
| JSVariable !JSAnnot !(JSCommaList JSExpression) !JSSemi -- ^var|const, decl, autosemi
| JSWhile !JSAnnot !JSAnnot !JSExpression !JSAnnot !JSStatement -- ^while,lb,expr,rb,stmt
| JSWith !JSAnnot !JSAnnot !JSExpression !JSAnnot !JSStatement !JSSemi -- ^with,lb,expr,rb,stmt list
| JSExport !JSAnnot !(Maybe JSAnnot) !JSStatement !JSSemi -- ^export
deriving (Data, Eq, Show, Typeable)

data JSExpression
Expand Down Expand Up @@ -271,6 +272,10 @@ instance ShowStripped JSStatement where
ss (JSReturn _ (Just me) s) = "JSReturn " ++ ss me ++ " " ++ ss s
ss (JSReturn _ Nothing s) = "JSReturn " ++ ss s
ss (JSSwitch _ _lp x _rp _lb x2 _rb _) = "JSSwitch (" ++ ss x ++ ") " ++ ss x2
ss (JSExport _ df x1 _) = "JSExport " ++ exportDefault df ++ "(" ++ ss x1 ++ ")"
where
exportDefault (Just _) = "default "
exportDefault Nothing = ""
ss (JSThrow _ x _) = "JSThrow (" ++ ss x ++ ")"
ss (JSTry _ xt1 xtc xtf) = "JSTry (" ++ ss xt1 ++ "," ++ ss xtc ++ "," ++ ss xtf ++ ")"
ss (JSVariable _ xs _as) = "JSVariable " ++ ss xs
Expand Down
1 change: 1 addition & 0 deletions src/Language/JavaScript/Parser/Lexer.x
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,7 @@ keywordNames =
, ( "export", FutureToken )
, ( "extends", FutureToken )

, ( "export", ExportToken )
, ( "import", FutureToken )
, ( "super", FutureToken )

Expand Down
1 change: 1 addition & 0 deletions src/Language/JavaScript/Parser/Token.hs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ data Token
| VoidToken { tokenSpan :: !TokenPosn, tokenLiteral :: !String, tokenComment :: ![CommentAnnotation] }
| WhileToken { tokenSpan :: !TokenPosn, tokenLiteral :: !String, tokenComment :: ![CommentAnnotation] }
| WithToken { tokenSpan :: !TokenPosn, tokenLiteral :: !String, tokenComment :: ![CommentAnnotation] }
| ExportToken { tokenSpan :: !TokenPosn, tokenLiteral :: !String, tokenComment :: ![CommentAnnotation] }
-- Future reserved words
| FutureToken { tokenSpan :: !TokenPosn, tokenLiteral :: !String, tokenComment :: ![CommentAnnotation] }
-- Needed, not sure what they are though.
Expand Down
6 changes: 5 additions & 1 deletion src/Language/JavaScript/Pretty/Printer.hs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@ instance RenderJS JSAnnot where
(|>) pacc JSNoAnnot = pacc
(|>) pacc JSAnnotSpace = pacc |> " "

instance RenderJS (Maybe JSAnnot) where
(|>) pacc (Just e) = pacc |> e
(|>) pacc Nothing = pacc

instance RenderJS String where
(|>) (PosAccum (r,c) bb) s = PosAccum (r',c') (bb <> str s)
where
Expand Down Expand Up @@ -233,6 +237,7 @@ instance RenderJS JSStatement where
(|>) pacc (JSMethodCall e lp a rp s) = pacc |> e |> lp |> "(" |> a |> rp |> ")" |> s
(|>) pacc (JSReturn annot me s) = pacc |> annot |> "return" |> me |> s
(|>) pacc (JSSwitch annot alp x arp alb x2 arb s) = pacc |> annot |> "switch" |> alp |> "(" |> x |> arp |> ")" |> alb |> "{" |> x2 |> arb |> "}" |> s
(|>) pacc (JSExport annot df x1 s) = pacc |> annot |> "export" |> df |> "{" |> x1 |> "}" |> s
(|>) pacc (JSThrow annot x s) = pacc |> annot |> "throw" |> x |> s
(|>) pacc (JSTry annot tb tcs tf) = pacc |> annot |> "try" |> tb |> tcs |> tf
(|>) pacc (JSVariable annot xs s) = pacc |> annot |> "var" |> xs |> s
Expand Down Expand Up @@ -287,4 +292,3 @@ instance RenderJS JSVarInitializer where
(|>) pacc JSVarInitNone = pacc

-- EOF

1 change: 1 addition & 0 deletions src/Language/JavaScript/Process/Minify.hs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ fixStmt a s (JSMethodCall e _ args _ _) = JSMethodCall (fix a e) emptyAnnot (fix
fixStmt a s (JSReturn _ me _) = JSReturn a (fixSpace me) s
fixStmt a s (JSSwitch _ _ e _ _ sps _ _) = JSSwitch a emptyAnnot (fixEmpty e) emptyAnnot emptyAnnot (fixSwitchParts sps) emptyAnnot s
fixStmt a s (JSThrow _ e _) = JSThrow a (fixSpace e) s
fixStmt a s (JSExport _ df x1 _) = JSExport a (fixSpace df) (fixEmpty x1) s -- unsure what I'm doing here
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Think I'm just doing a lot of guess work right now, not sure what needs to be done here

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is why we have minify tests, which minifys something and then tried to parse it. As long as that works correctly for all cases that can be pasrsed it should be fine.

fixStmt a _ (JSTry _ b tc tf) = JSTry a (fixEmpty b) (map fixEmpty tc) (fixEmpty tf)
fixStmt a s (JSVariable _ ss _) = JSVariable a (fixVarList ss) s
fixStmt a s (JSWhile _ _ e _ st) = JSWhile a emptyAnnot (fixEmpty e) emptyAnnot (fixStmt a s st)
Expand Down
22 changes: 21 additions & 1 deletion test/Test/Language/Javascript/StatementParser.hs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,27 @@ testStatementParser = describe "Parse statements:" $ do
it "if" $
testStmt "if (1) {}" `shouldBe` "Right (JSAstStatement (JSIf (JSDecimal '1') (JSStatementBlock [])))"

it "export" $ do
testStmt "export a;" `shouldBe` "Right (JSAstStatement (JSExport (JSIdentifier 'a',JSSemicolon)))"
testStmt "export var a = 1;" `shouldBe` "Right (JSAstStatement (JSExport (JSVariable (JSVarInitExpression (JSIdentifier 'a') [JSDecimal '1']))))"
testStmt "export function () {};" `shouldBe` "Right (JSAstStatement (JSExport (JSFunctionExpression '' () (JSBlock [])),JSSemicolon)))"
testStmt "export {};" `shouldBe` "Right (JSAstStatement (JSExport (JSStatementBlock [])))"
testStmt "export default function () {};" `shouldBe` "Right (JSAstStatement (JSExport Default (JSFunctionExpression '' () (JSBlock [])),JSSemicolon)))"
testStmt "export default var a = 1;" `shouldBe` "Right (JSAstStatement (JSExport Default (JSVariable (JSVarInitExpression (JSIdentifier 'a') [JSDecimal '1']))))"
-- Unsure about handling all these cases taken from the specs
-- export { variable1 as name1, variable2 as name2, …, nameN };
-- export let name1, name2, …, nameN; // also var, const
-- export let name1 = …, name2 = …, …, nameN; // also var, const
-- export class ClassName {...}
-- export default expression;
-- export default function name1(…) { … } // also class, function*
-- export { name1 as default, … };

-- export * from …;
-- export { name1, name2, …, nameN } from …;
-- export { import1 as name1, import2 as name2, …, nameN } from …;
-- export { default } from …;

it "if/else" $ do
testStmt "if (1) {} else {}" `shouldBe` "Right (JSAstStatement (JSIfElse (JSDecimal '1') (JSStatementBlock []) (JSStatementBlock [])))"
testStmt "if (1) x=1; else {}" `shouldBe` "Right (JSAstStatement (JSIfElse (JSDecimal '1') (JSOpAssign ('=',JSIdentifier 'x',JSDecimal '1'),JSSemicolon) (JSStatementBlock [])))"
Expand Down Expand Up @@ -101,4 +122,3 @@ testStatementParser = describe "Parse statements:" $ do

testStmt :: String -> String
testStmt str = showStrippedMaybe (parseUsing parseStatement str "src")