Skip to content
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

derive Generic and NFData #122

Open
wants to merge 1 commit into
base: new-ast
Choose a base branch
from
Open
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
1 change: 1 addition & 0 deletions language-javascript.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ Cabal-version: >= 1.9.2
Library
Build-depends: base >= 4 && < 5
, array >= 0.3
, deepseq >= 1.4
, mtl >= 1.1
, containers >= 0.2
, blaze-builder >= 0.2
Expand Down
73 changes: 38 additions & 35 deletions src/Language/JavaScript/Parser/AST.hs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{-# LANGUAGE DeriveDataTypeable, FlexibleInstances #-}
{-# LANGUAGE DeriveGeneric, DeriveAnyClass #-}

module Language.JavaScript.Parser.AST
( JSExpression (..)
Expand Down Expand Up @@ -44,8 +45,10 @@ module Language.JavaScript.Parser.AST
, showStripped
) where

import Control.DeepSeq (NFData)
import Data.Data
import Data.List
import GHC.Generics (Generic)
import Language.JavaScript.Parser.SrcLocation (TokenPosn (..))
import Language.JavaScript.Parser.Token

Expand All @@ -55,7 +58,7 @@ data JSAnnot
= JSAnnot !TokenPosn ![CommentAnnotation] -- ^Annotation: position and comment/whitespace information
| JSAnnotSpace -- ^A single space character
| JSNoAnnot -- ^No annotation
deriving (Data, Eq, Show, Typeable)
deriving (Data, Eq, Generic, NFData, Show, Typeable)


data JSAST
Expand All @@ -64,67 +67,67 @@ data JSAST
| JSAstStatement !JSStatement !JSAnnot
| JSAstExpression !JSExpression !JSAnnot
| JSAstLiteral !JSExpression !JSAnnot
deriving (Data, Eq, Show, Typeable)
deriving (Data, Eq, Generic, NFData, Show, Typeable)

-- Shift AST
-- https://github.com/shapesecurity/shift-spec/blob/83498b92c436180cc0e2115b225a68c08f43c53e/spec.idl#L229-L234
data JSModuleItem
= JSModuleImportDeclaration !JSAnnot !JSImportDeclaration -- ^import,decl
| JSModuleExportDeclaration !JSAnnot !JSExportDeclaration -- ^export,decl
| JSModuleStatementListItem !JSStatement
deriving (Data, Eq, Show, Typeable)
deriving (Data, Eq, Generic, NFData, Show, Typeable)

data JSImportDeclaration
= JSImportDeclaration !JSImportClause !JSFromClause !JSSemi -- ^imports, module, semi
| JSImportDeclarationBare !JSAnnot !String !JSSemi -- ^module, module, semi
deriving (Data, Eq, Show, Typeable)
deriving (Data, Eq, Generic, NFData, Show, Typeable)

data JSImportClause
= JSImportClauseDefault !JSIdent -- ^default
| JSImportClauseNameSpace !JSImportNameSpace -- ^namespace
| JSImportClauseNamed !JSImportsNamed -- ^named imports
| JSImportClauseDefaultNameSpace !JSIdent !JSAnnot !JSImportNameSpace -- ^default, comma, namespace
| JSImportClauseDefaultNamed !JSIdent !JSAnnot !JSImportsNamed -- ^default, comma, named imports
deriving (Data, Eq, Show, Typeable)
deriving (Data, Eq, Generic, NFData, Show, Typeable)

data JSFromClause
= JSFromClause !JSAnnot !JSAnnot !String -- ^ from, string literal, string literal contents
deriving (Data, Eq, Show, Typeable)
deriving (Data, Eq, Generic, NFData, Show, Typeable)

-- | Import namespace, e.g. '* as whatever'
data JSImportNameSpace
= JSImportNameSpace !JSBinOp !JSAnnot !JSIdent -- ^ *, as, ident
deriving (Data, Eq, Show, Typeable)
deriving (Data, Eq, Generic, NFData, Show, Typeable)

-- | Named imports, e.g. '{ foo, bar, baz as quux }'
data JSImportsNamed
= JSImportsNamed !JSAnnot !(JSCommaList JSImportSpecifier) !JSAnnot -- ^lb, specifiers, rb
deriving (Data, Eq, Show, Typeable)
deriving (Data, Eq, Generic, NFData, Show, Typeable)

-- |
-- Note that this data type is separate from ExportSpecifier because the
-- grammar is slightly different (e.g. in handling of reserved words).
data JSImportSpecifier
= JSImportSpecifier !JSIdent -- ^ident
| JSImportSpecifierAs !JSIdent !JSAnnot !JSIdent -- ^ident, as, ident
deriving (Data, Eq, Show, Typeable)
deriving (Data, Eq, Generic, NFData, Show, Typeable)

data JSExportDeclaration
-- = JSExportAllFrom
= JSExportFrom JSExportClause JSFromClause !JSSemi -- ^exports, module, semi
| JSExportLocals JSExportClause !JSSemi -- ^exports, autosemi
| JSExport !JSStatement !JSSemi -- ^body, autosemi
-- | JSExportDefault
deriving (Data, Eq, Show, Typeable)
deriving (Data, Eq, Generic, NFData, Show, Typeable)

data JSExportClause
= JSExportClause !JSAnnot !(JSCommaList JSExportSpecifier) !JSAnnot -- ^lb, specifiers, rb
deriving (Data, Eq, Show, Typeable)
deriving (Data, Eq, Generic, NFData, Show, Typeable)

data JSExportSpecifier
= JSExportSpecifier !JSIdent -- ^ident
| JSExportSpecifierAs !JSIdent !JSAnnot !JSIdent -- ^ident1, as, ident2
deriving (Data, Eq, Show, Typeable)
deriving (Data, Eq, Generic, NFData, Show, Typeable)

data JSStatement
= JSStatementBlock !JSAnnot ![JSStatement] !JSAnnot !JSSemi -- ^lbrace, stmts, rbrace, autosemi
Expand Down Expand Up @@ -163,7 +166,7 @@ data JSStatement
| JSVariable !JSAnnot !(JSCommaList JSExpression) !JSSemi -- ^var, 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
deriving (Data, Eq, Show, Typeable)
deriving (Data, Eq, Generic, NFData, Show, Typeable)

data JSExpression
-- | Terminals
Expand Down Expand Up @@ -203,12 +206,12 @@ data JSExpression
| JSVarInitExpression !JSExpression !JSVarInitializer -- ^identifier, initializer
| JSYieldExpression !JSAnnot !(Maybe JSExpression) -- ^yield, optional expr
| JSYieldFromExpression !JSAnnot !JSAnnot !JSExpression -- ^yield, *, expr
deriving (Data, Eq, Show, Typeable)
deriving (Data, Eq, Generic, NFData, Show, Typeable)

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

data JSBinOp
= JSBinOpAnd !JSAnnot
Expand All @@ -235,7 +238,7 @@ data JSBinOp
| JSBinOpStrictNeq !JSAnnot
| JSBinOpTimes !JSAnnot
| JSBinOpUrsh !JSAnnot
deriving (Data, Eq, Show, Typeable)
deriving (Data, Eq, Generic, NFData, Show, Typeable)

data JSUnaryOp
= JSUnaryOpDecr !JSAnnot
Expand All @@ -247,12 +250,12 @@ data JSUnaryOp
| JSUnaryOpTilde !JSAnnot
| JSUnaryOpTypeof !JSAnnot
| JSUnaryOpVoid !JSAnnot
deriving (Data, Eq, Show, Typeable)
deriving (Data, Eq, Generic, NFData, Show, Typeable)

data JSSemi
= JSSemi !JSAnnot
| JSSemiAuto
deriving (Data, Eq, Show, Typeable)
deriving (Data, Eq, Generic, NFData, Show, Typeable)

data JSAssignOp
= JSAssign !JSAnnot
Expand All @@ -267,94 +270,94 @@ data JSAssignOp
| JSBwAndAssign !JSAnnot
| JSBwXorAssign !JSAnnot
| JSBwOrAssign !JSAnnot
deriving (Data, Eq, Show, Typeable)
deriving (Data, Eq, Generic, NFData, Show, Typeable)

data JSTryCatch
= JSCatch !JSAnnot !JSAnnot !JSExpression !JSAnnot !JSBlock -- ^catch,lb,ident,rb,block
| JSCatchIf !JSAnnot !JSAnnot !JSExpression !JSAnnot !JSExpression !JSAnnot !JSBlock -- ^catch,lb,ident,if,expr,rb,block
deriving (Data, Eq, Show, Typeable)
deriving (Data, Eq, Generic, NFData, Show, Typeable)

data JSTryFinally
= JSFinally !JSAnnot !JSBlock -- ^finally,block
| JSNoFinally
deriving (Data, Eq, Show, Typeable)
deriving (Data, Eq, Generic, NFData, Show, Typeable)

data JSBlock
= JSBlock !JSAnnot ![JSStatement] !JSAnnot -- ^lbrace, stmts, rbrace
deriving (Data, Eq, Show, Typeable)
deriving (Data, Eq, Generic, NFData, Show, Typeable)

data JSSwitchParts
= JSCase !JSAnnot !JSExpression !JSAnnot ![JSStatement] -- ^expr,colon,stmtlist
| JSDefault !JSAnnot !JSAnnot ![JSStatement] -- ^colon,stmtlist
deriving (Data, Eq, Show, Typeable)
deriving (Data, Eq, Generic, NFData, Show, Typeable)

data JSVarInitializer
= JSVarInit !JSAnnot !JSExpression -- ^ assignop, initializer
| JSVarInitNone
deriving (Data, Eq, Show, Typeable)
deriving (Data, Eq, Generic, NFData, Show, Typeable)

data JSObjectProperty
= JSPropertyNameandValue !JSPropertyName !JSAnnot ![JSExpression] -- ^name, colon, value
| JSPropertyIdentRef !JSAnnot !String
| JSObjectMethod !JSMethodDefinition
deriving (Data, Eq, Show, Typeable)
deriving (Data, Eq, Generic, NFData, Show, Typeable)

data JSMethodDefinition
= JSMethodDefinition !JSPropertyName !JSAnnot !(JSCommaList JSExpression) !JSAnnot !JSBlock -- name, lb, params, rb, block
| JSGeneratorMethodDefinition !JSAnnot !JSPropertyName !JSAnnot !(JSCommaList JSExpression) !JSAnnot !JSBlock -- ^*, name, lb, params, rb, block
| JSPropertyAccessor !JSAccessor !JSPropertyName !JSAnnot !(JSCommaList JSExpression) !JSAnnot !JSBlock -- ^get/set, name, lb, params, rb, block
deriving (Data, Eq, Show, Typeable)
deriving (Data, Eq, Generic, NFData, Show, Typeable)

data JSPropertyName
= JSPropertyIdent !JSAnnot !String
| JSPropertyString !JSAnnot !String
| JSPropertyNumber !JSAnnot !String
| JSPropertyComputed !JSAnnot !JSExpression !JSAnnot -- ^lb, expr, rb
deriving (Data, Eq, Show, Typeable)
deriving (Data, Eq, Generic, NFData, Show, Typeable)

type JSObjectPropertyList = JSCommaTrailingList JSObjectProperty

-- | Accessors for JSObjectProperty is either 'get' or 'set'.
data JSAccessor
= JSAccessorGet !JSAnnot
| JSAccessorSet !JSAnnot
deriving (Data, Eq, Show, Typeable)
deriving (Data, Eq, Generic, NFData, Show, Typeable)

data JSIdent
= JSIdentName !JSAnnot !String
| JSIdentNone
deriving (Data, Eq, Show, Typeable)
deriving (Data, Eq, Generic, NFData, Show, Typeable)

data JSArrayElement
= JSArrayElement !JSExpression
| JSArrayComma !JSAnnot
deriving (Data, Eq, Show, Typeable)
deriving (Data, Eq, Generic, NFData, Show, Typeable)

data JSCommaList a
= JSLCons !(JSCommaList a) !JSAnnot !a -- ^head, comma, a
| JSLOne !a -- ^ single element (no comma)
| JSLNil
deriving (Data, Eq, Show, Typeable)
deriving (Data, Eq, Generic, NFData, Show, Typeable)

data JSCommaTrailingList a
= JSCTLComma !(JSCommaList a) !JSAnnot -- ^list, trailing comma
| JSCTLNone !(JSCommaList a) -- ^list
deriving (Data, Eq, Show, Typeable)
deriving (Data, Eq, Generic, NFData, Show, Typeable)

data JSTemplatePart
= JSTemplatePart !JSExpression !JSAnnot !String -- ^expr, rb, suffix
deriving (Data, Eq, Show, Typeable)
deriving (Data, Eq, Generic, NFData, Show, Typeable)

data JSClassHeritage
= JSExtends !JSAnnot !JSExpression
| JSExtendsNone
deriving (Data, Eq, Show, Typeable)
deriving (Data, Eq, Generic, NFData, Show, Typeable)

data JSClassElement
= JSClassInstanceMethod !JSMethodDefinition
| JSClassStaticMethod !JSAnnot !JSMethodDefinition
| JSClassSemi !JSAnnot
deriving (Data, Eq, Show, Typeable)
deriving (Data, Eq, Generic, NFData, Show, Typeable)

-- -----------------------------------------------------------------------------
-- | Show the AST elements stripped of their JSAnnot data.
Expand Down
5 changes: 4 additions & 1 deletion src/Language/JavaScript/Parser/ParseError.hs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{-# LANGUAGE DeriveGeneric, DeriveAnyClass #-}
-----------------------------------------------------------------------------
-- |
-- Module : Language.JavaScript.ParseError
Expand All @@ -17,6 +18,8 @@ module Language.JavaScript.Parser.ParseError

--import Language.JavaScript.Parser.Pretty
-- import Control.Monad.Error.Class -- Control.Monad.Trans.Except
import Control.DeepSeq (NFData)
import GHC.Generics (Generic)
import Language.JavaScript.Parser.Lexer
import Language.JavaScript.Parser.SrcLocation (TokenPosn)
-- import Language.JavaScript.Parser.Token (Token)
Expand All @@ -29,7 +32,7 @@ data ParseError
-- ^ An error from the lexer. Character found where it should not be.
| StrError String
-- ^ A generic error containing a string message. No source location.
deriving (Eq, {- Ord,-} Show)
deriving (Eq, Generic, NFData, {- Ord,-} Show)

class Error a where
-- | Creates an exception without a message.
Expand Down
6 changes: 5 additions & 1 deletion src/Language/JavaScript/Parser/SrcLocation.hs
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric, DeriveAnyClass #-}

module Language.JavaScript.Parser.SrcLocation (
TokenPosn(..)
, tokenPosnEmpty
) where

import Control.DeepSeq (NFData)
import Data.Data
import GHC.Generics (Generic)

-- | `TokenPosn' records the location of a token in the input text. It has three
-- fields: the address (number of characters preceding the token), line number
Expand All @@ -14,7 +18,7 @@ import Data.Data
data TokenPosn = TokenPn !Int -- address (number of characters preceding the token)
!Int -- line number
!Int -- column
deriving (Eq,Show, Read, Data, Typeable)
deriving (Data, Eq, Generic, NFData, Read, Show, Typeable)

tokenPosnEmpty :: TokenPosn
tokenPosnEmpty = TokenPn 0 0 0
Expand Down
7 changes: 5 additions & 2 deletions src/Language/JavaScript/Parser/Token.hs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{-# LANGUAGE CPP, DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric, DeriveAnyClass #-}
-----------------------------------------------------------------------------
-- |
-- Module : Language.Python.Common.Token
Expand All @@ -23,14 +24,16 @@ module Language.JavaScript.Parser.Token
-- TokenClass (..),
) where

import Control.DeepSeq (NFData)
import Data.Data
import GHC.Generics (Generic)
import Language.JavaScript.Parser.SrcLocation

data CommentAnnotation
= CommentA TokenPosn String
| WhiteSpace TokenPosn String
| NoComment
deriving (Eq, Show, Typeable, Data, Read)
deriving (Data, Eq, Generic, NFData, Read, Show, Typeable)

-- | Lexical tokens.
-- Each may be annotated with any comment occurring between the prior token and this one
Expand Down Expand Up @@ -170,7 +173,7 @@ data Token
| AsToken { tokenSpan :: !TokenPosn, tokenLiteral :: !String, tokenComment :: ![CommentAnnotation] }
| TailToken { tokenSpan :: !TokenPosn, tokenComment :: ![CommentAnnotation] } -- ^ Stuff between last JS and EOF
| EOFToken { tokenSpan :: !TokenPosn, tokenComment :: ![CommentAnnotation] } -- ^ End of file
deriving (Eq, Show, Typeable)
deriving (Eq, Generic, NFData, Show, Typeable)


-- | Produce a string from a token containing detailed information. Mainly intended for debugging.
Expand Down