packages feed

language-dart (empty) → 0.1.0.0

raw patch · 8 files changed

+2591/−0 lines, 8 filesdep +basedep +hspecdep +language-dartsetup-changed

Dependencies added: base, hspec, language-dart, pretty

Files

+ CHANGELOG.md view
@@ -0,0 +1,3 @@+# 0.1.0.0++* Initial release
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright Author Kwang Yul Seo (c) 2016++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above+      copyright notice, this list of conditions and the following+      disclaimer in the documentation and/or other materials provided+      with the distribution.++    * Neither the name of Author name here nor the names of other+      contributors may be used to endorse or promote products derived+      from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ README.md view
@@ -0,0 +1,5 @@+# language-dart++[![Build Status](https://travis-ci.org/kseo/language-dart.svg?branch=master)](https://travis-ci.org/kseo/language-dart)++A library for manipulating Dart source: abstract syntax and pretty-printer
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ language-dart.cabal view
@@ -0,0 +1,38 @@+name:                language-dart+version:             0.1.0.0+synopsis:            Manipulating Dart source: abstract syntax and pretty-printer+description:         Please see README.md+homepage:            https://github.com/kseo/language-dart#readme+license:             BSD3+license-file:        LICENSE+author:              Kwang Yul Seo+maintainer:          kwangyul.seo@gmail.com+copyright:           Kwang Yul Seo 2016+category:            Language+stability:           Experimental+build-type:          Simple+extra-source-files:  README.md+                     CHANGELOG.md+cabal-version:       >=1.10++library+  hs-source-dirs:      src+  exposed-modules:     Language.Dart.Pretty+                       Language.Dart.Syntax+  build-depends:       base >= 4.7 && < 5+                     , pretty >= 1.1+  default-language:    Haskell2010++test-suite language-dart-test+  type:                exitcode-stdio-1.0+  hs-source-dirs:      test+  main-is:             Spec.hs+  build-depends:       base+                     , hspec+                     , language-dart+  ghc-options:         -threaded -rtsopts -with-rtsopts=-N+  default-language:    Haskell2010++source-repository head+  type:     git+  location: https://github.com/kseo/language-dart
+ src/Language/Dart/Pretty.hs view
@@ -0,0 +1,754 @@+module Language.Dart.Pretty+  ( Pretty+  , prettyPrint+  ) where++import Data.Char (toLower)+import Data.List (partition)+import Text.PrettyPrint+import Text.Printf (printf)++import Language.Dart.Syntax++-- FIXME: Don't omit comments++prettyPrint :: Pretty a => a -> String+prettyPrint = show . pretty++parenPrec :: Int -> Int -> Doc -> Doc+parenPrec inheritedPrec currentPrec t+  | inheritedPrec > currentPrec = parens t+  | otherwise                   = t++class Pretty a where+  pretty :: a -> Doc+  pretty = prettyPrec 0++  prettyPrec :: Int -> a -> Doc+  prettyPrec _ = pretty++instance Pretty MapLiteralEntry where+  prettyPrec p (MapLiteralEntry key value) =+    hsep [ prettyPrec p key+         , colon+         , prettyPrec p value+         ]++instance Pretty TypedLiteral where+  prettyPrec p (MapLiteral isConst mTypeArguments entries)  =+    hsep [ optKeyword isConst "const"+         , maybePP p mTypeArguments+         ] <> braces (hsep (ppIntersperse p comma entries))++  prettyPrec p (ListLiteral isConst mTypeArguments elements) =+    hsep [ optKeyword isConst "const"+         , maybePP p mTypeArguments+         ] <> brackets (hsep (ppIntersperse p comma elements))++instance Pretty Literal where+  prettyPrec p (NullLiteral)      = text "null"+  prettyPrec p (BooleanLiteral b) = text . map toLower $ show b+  prettyPrec p (DoubleLiteral d)  = text (show d)+  prettyPrec p (IntegerLiteral i) = text (show i)+  prettyPrec p (TypedLiteral t)   = prettyPrec p t+  prettyPrec p (StringLiteral' s) = prettyPrec p s+  prettyPrec p (SymbolLiteral ts) = pound <> hsep (punctuate period (map text ts))++instance Pretty InterpolationElement where+  prettyPrec p (InterpolationString s) = text s++  prettyPrec p (InterpolationExpression expression) =+    dollar <> braces (prettyPrec p expression)++instance Pretty SingleStringLiteral where+  prettyPrec p (SimpleStringLiteral value) =+    doubleQuotes (text (concatMap escapeString value))++  prettyPrec p (StringInterpolation elements) =+    doubleQuotes (hcat (map (prettyPrec p) elements))++instance Pretty StringLiteral where+  prettyPrec p (SingleStringLiteral' l) = prettyPrec p l++  prettyPrec p (AdjacentStrings strings) =+    hsep (map (prettyPrec p) strings)++instance Pretty Combinator where+  prettyPrec p (ShowCombinator shownNames)  = text "show" <+>+    hsep (ppIntersperse p comma shownNames)++  prettyPrec p (HideCombinator hiddenNames) = text "hide" <+>+    hsep (ppIntersperse p comma hiddenNames)++-- FIXME: Handle configurations+instance Pretty NamespaceDirective where+  prettyPrec p (ExportDirective _ metadata libraryUri _ combinators) =+    ppMetadata p metadata $$+      hsep [ text "export"+           , prettyPrec p libraryUri+           , hsep (ppIntersperse p comma combinators)+           ] <> semi++  prettyPrec p (ImportDirective _ metadata libraryUri _ isDeferred mPrefix combinators) =+    ppMetadata p metadata $$+      hsep [ text "import"+           , prettyPrec  p libraryUri+           , optKeyword isDeferred "deferred"+           , maybe empty ((text "as" <+>) . prettyPrec p) mPrefix+           , hsep (ppIntersperse p comma combinators)+           ] <> semi++instance Pretty UriBasedDirective where+  prettyPrec p (NamespaceDirective nsDir) = prettyPrec p nsDir++  prettyPrec p (PartDirective _ metadata partUri) =+    ppMetadata p metadata $$ prettyPrec p partUri <> semi++instance Pretty Directive where+  prettyPrec p (UriBasedDirective dir) = prettyPrec p dir++  prettyPrec p (PartOfDirective _ metadata libraryName) =+    ppMetadata p metadata $$+      text "part of" <> prettyPrec p libraryName <> semi++  prettyPrec p (LibraryDirective _ metadata libraryName) =+    ppMetadata p metadata $$+      text "library" <> prettyPrec p libraryName <> semi++instance Pretty AsyncModifier where+  prettyPrec p AsyncStar  = text "async*"+  prettyPrec p Async      = text "async"+  prettyPrec p SyncStar   = text "sync*"+  prettyPrec p Sync       = empty++instance Pretty NormalFormalParameter where+  prettyPrec p (FunctionTypedFormalParameter _ metadata mReturnType identifier mTypeParameters parameters) =+    ppMetadata p metadata $$+      hsep [ maybePP p mReturnType+           , hcat [ prettyPrec p identifier+                  , maybePP p mTypeParameters+                  , prettyPrec p parameters+                  ]+           ]++  prettyPrec p (FieldFormalParameter _ metadata kind explicitThis identifier) =+    ppMetadata p metadata $$+      hsep [ maybePP p kind+           , opt explicitThis (text "this.") <> prettyPrec p identifier+           ]++  prettyPrec p (SimpleFormalParameter _ metadata kind identifier) =+    ppMetadata p metadata $$+      hsep [ prettyPrec p kind+           , prettyPrec p identifier+           ]++instance Pretty FormalParameter where+  prettyPrec p (NormalFormalParameter' parameter) = prettyPrec p parameter++  prettyPrec p (DefaultFormalParameter parameter kind mDefaultValue) =+    hsep [ prettyPrec p parameter+         , maybe empty ((separator kind <+>) . prettyPrec p) mDefaultValue+         ]+    where separator Positional = equals+          separator Named = colon++instance Pretty FormalParameterList where+  prettyPrec p (FormalParameterList parameters) =+    let (normals, defaults) = partition isNormal parameters+     in parens $ hcat [ hsep (ppIntersperse p comma normals)+                      , opt (not $ null defaults) (comma <+> (matchingBracket (head defaults)) (hsep (ppIntersperse p comma defaults)))+                      ]+    where isNormal (NormalFormalParameter' _) = True+          isNormal _ = False+          matchingBracket (DefaultFormalParameter _ Positional _) = brackets+          matchingBracket _ = braces++instance Pretty ConstructorName where+  prettyPrec p (ConstructorName type' mName) =+    hsep [ prettyPrec p type'+         , maybe empty ((period <>) . prettyPrec p) mName+         ]++instance Pretty SimpleIdentifier where+  prettyPrec _ (SimpleIdentifier token) = text token++instance Pretty LibraryIdentifier where+  prettyPrec p (LibraryIdentifier components) =+    hcat (ppIntersperse p period components)++instance Pretty Identifier where+  prettyPrec p (SimpleIdentifier' simpleId) = prettyPrec p simpleId++  prettyPrec p (PrefixedIdentifier prefix identifier) =+    hcat [ prettyPrec p prefix+         , period+         , prettyPrec p identifier+         ]++  prettyPrec p (LibraryIdentifier' libraryName) = prettyPrec p libraryName++instance Pretty TypeArgumentList where+  prettyPrec p (TypeArgumentList args) =+    angleBrackets (hsep (ppIntersperse p comma args))++instance Pretty TypeName where+  prettyPrec p (TypeName name typeArgList) = prettyPrec p name <> maybePP p typeArgList++instance Pretty PropertyKeyword where+  prettyPrec p Get   = text "get"+  prettyPrec p Set   = text "set"+  prettyPrec p Empty = empty++instance Pretty ArgumentList where+  prettyPrec p (ArgumentList args) =+    parens (hsep (ppIntersperse p comma args))++instance Pretty Annotation where+  prettyPrec p (Annotation name mConstructorName mArguments) =+    hcat [ at+         , prettyPrec p name+         , maybe empty ((period <>) . prettyPrec p) mConstructorName+         , maybePP p mArguments+         ]++instance Pretty ExtendsClause where+  prettyPrec p (ExtendsClause superclass) = text "extends" <+>+    prettyPrec p superclass++instance Pretty WithClause where+  prettyPrec p (WithClause mixinTypes) = text "with" <+>+    hsep (ppIntersperse p comma mixinTypes)++instance Pretty ImplementsClause where+  prettyPrec p (ImplementsClause interfaces) = text "implements" <+>+    hsep (ppIntersperse p comma interfaces)++instance Pretty TypeAlias where+  prettyPrec p (ClassTypeAlias _ metadata name mTypeParameters isAbstract superclass withClause mImplementsClause) =+    ppMetadata p metadata $$+      hsep [ optKeyword isAbstract "abstract"+           , text "class"+           , hcat [ prettyPrec p name+                  , maybePP p mTypeParameters+                  ]+           , equals+           , prettyPrec p superclass+           , prettyPrec p withClause+           , maybePP p mImplementsClause+           ] <> semi++  prettyPrec p (FunctionTypeAlias _ metadata mReturnType name mTypeParameters parameters) =+    ppMetadata p metadata $$+      hsep [ text "typedef"+           , maybePP p mReturnType+           , hcat [ prettyPrec p name+                  , maybePP p mTypeParameters+                  , prettyPrec p parameters+                  ]+           ] <> semi++instance Pretty EnumConstantDeclaration where+  prettyPrec p (EnumConstantDeclaration _ metadata name) =+    ppMetadata p metadata $$ prettyPrec p name++instance Pretty TypeParameter where+  prettyPrec p (TypeParameter _ metadata name mBound) =+    ppMetadata p metadata $$+      hsep [ prettyPrec p name+           , maybe empty ((text "extends" <+>) . prettyPrec p) mBound+           ]++instance Pretty TypeParameterList where+  prettyPrec p (TypeParameterList typeParameters) =+    angleBrackets (hsep (ppIntersperse p comma typeParameters))++instance Pretty Label where+  prettyPrec p (Label label) = prettyPrec p label <> char ':'++instance Pretty FinalConstVarOrType where+  prettyPrec p (FCVTFinal type')  = text "final" <+> prettyPrec p type'+  prettyPrec p (FCVTConst type')  = text "const" <+> prettyPrec p type'+  prettyPrec p (FCVTType type')   = prettyPrec p type'+  prettyPrec p FCVTVar            = text "var"++instance Pretty FinalVarOrType where+  prettyPrec p (FVTFinal type') = text "final" <+> prettyPrec p type'+  prettyPrec p (FVTType type')  = prettyPrec p type'+  prettyPrec p FVTVar           = text "var"++instance Pretty VariableDeclaration where+  prettyPrec p (VariableDeclaration name mInitializer) =+    hsep [ prettyPrec p name+         , maybe empty ((equals <+>) . prettyPrec p) mInitializer+         ]++instance Pretty VariableDeclarationList where+  prettyPrec p (VariableDeclarationList _ metadata kind variables) =+    ppMetadata p metadata $$+      prettyPrec p kind <+> hsep (ppIntersperse p comma variables)++instance Pretty CatchClause where+  prettyPrec p (CatchClause mExceptionType exceptionParameter mStackTraceParameter body) =+    case mExceptionType of+      Nothing -> text "catch" <+> parens (ppExceptionParameter p exceptionParameter mStackTraceParameter) $$ prettyPrec p body+      Just exceptionType -> text "on" <+> prettyPrec p exceptionType $$ prettyPrec p body+    where ppExceptionParameter p ep Nothing = prettyPrec p ep+          ppExceptionParameter p ep (Just stp) = hsep (ppIntersperse p comma [ep, stp])++instance Pretty SwitchMember where+  prettyPrec p (SwitchCase labels expression statements) =+    vcat (map (prettyPrec p) labels) $$+      vcat (ppSwitchCase p expression : map (nest 2 . prettyPrec p) statements)+    where ppSwitchCase p expression = text "case" <+> prettyPrec p expression <> colon++  prettyPrec p (SwitchDefault labels statements) =+    vcat (map (prettyPrec p) labels) $$+      vcat (ppSwitchDefault : map (nest 2 . prettyPrec p) statements)+    where ppSwitchDefault = text "default" <> colon++instance Pretty DeclaredIdentifier where+  prettyPrec p (DeclaredIdentifier _ metadata kind identifier) =+    ppMetadata p metadata $$+      hsep [ prettyPrec p kind+           , prettyPrec p identifier+           ]++instance Pretty Statement where+  prettyPrec p (Block' block) = prettyPrec p block++  prettyPrec p (VariableDeclarationStatement variableList) =+    prettyPrec p variableList <> semi++  prettyPrec p (ForStatement mVariableList mInitialization mCondition updaters body) =+    text "for" <+> (parens $ hsep [ maybe empty ((<> semi) . prettyPrec p) mVariableList+                                  , maybe empty ((<> semi) . prettyPrec p) mInitialization+                                  , maybePP p mCondition <> semi+                                  , hsep (ppIntersperse p comma updaters)+                                  ]) $+$ prettyNestedStmt p body++  prettyPrec p (ForEachStatementWithDeclaration isAwait loopVariable iterator body) = undefined+    hsep [ optKeyword isAwait "await"+         , text "for"+         , parens $ hsep [ prettyPrec p loopVariable+                         , text "in"+                         , prettyPrec p iterator+                         ]+         , prettyPrec p body+         ]++  prettyPrec p (ForEachStatementWithReference isAwait identifier iterator body) =+    hsep [ optKeyword isAwait "await"+         , text "for"+         , parens $ hsep [ prettyPrec p identifier+                         , text "in"+                         , prettyPrec p iterator+                         ]+         , prettyPrec p body+         ]++  prettyPrec p (WhileStatement condition body) =+    text "while" <+> parens (prettyPrec p condition) $+$ prettyNestedStmt 0 body++  prettyPrec p (DoStatement body condition) =+    text "do" $+$ prettyPrec p body <+> text "while" <+> parens (prettyPrec p condition) <> semi++  prettyPrec p (SwitchStatement expression members) =+    text "switch" <+> parens (prettyPrec p expression)+      $$ braceBlock (map (prettyPrec p) members)++  prettyPrec p (IfStatement condition thenStatement mElseStatement) =+    text "if" <+> parens (prettyPrec p condition) $+$+      prettyNestedStmt 0 thenStatement $+$ ppElseStatement mElseStatement+    where ppElseStatement Nothing = empty+          ppElseStatement (Just elseStatement) = text "else" $+$ prettyNestedStmt 0 elseStatement++  prettyPrec p (TryStatement body catchCaluses mFinallyBlock) =+    text "try" $$ prettyPrec p body $$+      vcat (map (prettyPrec p) catchCaluses ++ [ppFinally mFinallyBlock])+    where ppFinally Nothing = empty+          ppFinally (Just finally) = text "finally" $$ prettyPrec p finally++  prettyPrec p (BreakStatement mLabel) =+    text "break" <+> maybePP p mLabel <> semi++  prettyPrec p (ContinueStatement mLabel) =+    text "continue" <+> maybePP p mLabel <> semi++  prettyPrec p (ReturnStatement mExpression) =+    text "return" <+> maybePP p mExpression <> semi++  prettyPrec p (ExpressionStatement expression) =+    prettyPrec p expression <> semi++  prettyPrec p (FunctionDeclarationStatement functionDeclaration) =+    prettyPrec p functionDeclaration <> semi++  -- FIXME: Show message+  prettyPrec p (AssertStatement condition _) =+    hcat [ text "assert"+         , parens (prettyPrec p condition)+         , semi+         ]++  prettyPrec p (YieldStatement isStar expression) =+    hsep [ text "yield"+         , opt isStar star+         , prettyPrec p expression+         ] <> semi++  prettyPrec p (EmptyStatement) = semi++  prettyPrec p (LabeledStatement labels statement) =+    vcat (map (prettyPrec p) labels) $$+      prettyPrec p statement++instance Pretty Block where+  prettyPrec p (Block statements) = braceBlock (map (prettyPrec p) statements)++instance Pretty NewOrConst where+  prettyPrec p NCNew    = text "new"+  prettyPrec p NCConst  = text "const"++instance Pretty InvocationExpression where+  prettyPrec p (FunctionExpressionInvocation function mTypeArguments argumentList) =+    hcat [ prettyPrec p function+         , maybePP p mTypeArguments+         , prettyPrec p argumentList+         ]++  prettyPrec p (MethodInvocation mTarget methodName mTypeArguments argumentList) =+    hcat [ maybe empty ((<> period) . prettyPrec p) mTarget+         , prettyPrec p methodName+         , maybePP p mTypeArguments+         , prettyPrec p argumentList+         ]++instance Pretty Expression where+  prettyPrec p (Literal' literal) = prettyPrec p literal++  prettyPrec p (Identifier' identifier) = prettyPrec p identifier++  prettyPrec p (PrefixExpression  operator operand) =+    parenPrec p 15 $ text operator <> prettyPrec 15 operand++  prettyPrec p (PostfixExpression operand operator) =+    parenPrec p 16 $ prettyPrec 15 operand <> text operator++  prettyPrec p (BinaryExpression leftOperand operator rightOperand) =+    let prec = opPrec operator+     in parenPrec p prec $ hsep [ prettyPrec prec leftOperand+                                , text operator+                                , prettyPrec prec rightOperand+                                ]++  prettyPrec p (AssignmentExpression leftHandSide operator rightHandSide) =+    hsep [ prettyPrec p leftHandSide+         , text operator+         , prettyPrec p rightHandSide+         ]++  prettyPrec p (FunctionExpression' functionExpression) = prettyPrec p functionExpression++  prettyPrec p (InstanceCreationExpression newOrConst constructorName argumentList) =+    hsep [ prettyPrec p newOrConst+         , hcat [ prettyPrec p constructorName+                , prettyPrec p argumentList+                ]+         ]++  prettyPrec p (AsExpression expression type') =+    parenPrec p 8 $ hsep [ prettyPrec 8 expression+                         , text "as"+                         , prettyPrec 8 type'+                         ]++  prettyPrec p (IsExpression expression isNot type') =+    parenPrec p 8 $ hsep [ prettyPrec 8 expression+                         , text "is"+                         , opt isNot exclamation+                         , prettyPrec 8 type'+                         ]++  prettyPrec p (ThrowExpression expression) = text "throw" <+> prettyPrec p expression+  prettyPrec p (RethrowExpression)          = text "rethrow"++  prettyPrec p (ThisExpression)  = text "this"+  prettyPrec p (SuperExpression) = text "super"++  prettyPrec p (ParenthesizedExpression expression) = parens (prettyPrec p expression)++  prettyPrec p (PropertyAccess target propertyName) =+    hcat [ prettyPrec p target+         , period+         , prettyPrec p propertyName+         ]++  prettyPrec p (NamedExpression name expression) =+    hsep [ prettyPrec p name <> colon+         , prettyPrec p expression+         ]++  prettyPrec p (InvocationExpression invocationExpression) =+    prettyPrec p invocationExpression++  prettyPrec p (ConditionalExpression condition thenExpression elseExpression) =+    parenPrec p 3 $ hsep [ prettyPrec 3 condition+                         , questionMark+                         , prettyPrec p thenExpression+                         , colon+                         , prettyPrec 3 elseExpression+                         ]++  prettyPrec p (CascadeExpression target cascadeSections) =+    let sections = target:cascadeSections+     in parenPrec p 2 $ hsep (ppIntersperse 2 (text "..") sections)++  prettyPrec p (IndexExpressionForCasecade index) = brackets (prettyPrec p index)++  prettyPrec p (IndexExpressionForTarget target index) =+    prettyPrec p target <> brackets (prettyPrec p index)++  prettyPrec p (AwaitExpression expression) =+    hsep [ text "await"+         , prettyPrec p expression+         ]++instance Pretty FunctionBody where+  prettyPrec p (BlockFunctionBody asyncModifier block) =+    prettyPrec p asyncModifier <+> prettyPrec p block++  prettyPrec p (EmptyFunctionBody) = semi++  prettyPrec p (ExpressionFunctionBody isAsync expression) =+    hsep [ optKeyword isAsync "async"+         , text "=>"+         , prettyPrec p expression+         ] <> semi++  prettyPrec p (NativeFunctionBody stringLiteral) =+    text "native" <+> prettyPrec p stringLiteral <> semi++instance Pretty FunctionExpression where+  prettyPrec p (FunctionExpression mTypeParameters parameters body) =+    case body of+      BlockFunctionBody _ _      -> ppParams $$  prettyPrec p body+      ExpressionFunctionBody _ _ -> ppParams <+> prettyPrec p body+      _                          -> ppParams <> semi+    where ppParams = maybePP p mTypeParameters <> prettyPrec p parameters++instance Pretty FunctionDeclaration where+  prettyPrec p (FunctionDeclaration _ metadata isExternal mReturnType propertyKeyword name (FunctionExpression mTypeParameters parameters body)) =+    ppMetadata p metadata $$+      hsep [ optKeyword isExternal "external"+           , maybePP p mReturnType+           , prettyPrec p propertyKeyword+           , hcat [ prettyPrec p name+                  , maybePP p mTypeParameters+                  , prettyPrec p parameters+                  ]+           ] $$$ prettyPrec p body+   where ($$$) = case body of+                   (ExpressionFunctionBody _ _) -> (<+>)+                   (BlockFunctionBody _ _) -> ($$)+                   _ -> (<>)++instance Pretty ConstructorInitializer where+  prettyPrec p (RedirectingConstructorInvocation mConstructorName argumentList) =+    hcat [ text "this"+         , maybe empty ((period <>) . prettyPrec p) mConstructorName+         , prettyPrec p argumentList+         ]++  prettyPrec p (ConstructorFieldInitializer explicitThis fieldName expression) =+    hsep [ hcat [ opt explicitThis (text "this.")+                , prettyPrec p fieldName+                ]+         , equals+         , prettyPrec p expression+         ]++  prettyPrec p (SuperConstructorInvocation mConstructorName argumentList) =+    hcat [ text "super"+         , maybe empty ((period <>) . prettyPrec p) mConstructorName+         , prettyPrec p argumentList+         ]++instance Pretty MethodModifier where+  prettyPrec _ Abstract = text "abstract"+  prettyPrec _ Static   = text "static"++instance Pretty NamedCompilationUnitMember where+  prettyPrec p (FunctionDeclaration' funDecl) = prettyPrec p funDecl++  prettyPrec p (TypeAlias typeAlias) = prettyPrec p typeAlias++  prettyPrec p (EnumDeclaration _ metadata name constants) =+    ppMetadata p metadata $$+      hsep [ text "enum"+           , prettyPrec p name+           ] $$ braceBlock (ppIntersperse p comma constants)++  prettyPrec p (ClassDeclaration _ metadata isAbstract name mTypeParameters mExtendsClause mWithClause mImplementsClause members) =+    ppMetadata p metadata $$+      hsep [ optKeyword isAbstract "abstract"+           , text "class"+           , prettyPrec p name <> maybePP p mTypeParameters+           , maybePP p mExtendsClause+           , maybePP p mWithClause+           , maybePP p mImplementsClause+           ] $$ braceBlock (map (prettyPrec p) members)++instance Pretty CompilationUnitMember where+  prettyPrec p (TopLevelVariableDeclaration _ metadata variableList) =+    ppMetadata p metadata $$ prettyPrec p variableList++  prettyPrec p (NamedCompilationUnitMember member) = prettyPrec p member++instance Pretty ScriptTag where+  prettyPrec _ (ScriptTag token) = text token++instance Pretty CompilationUnit where+  prettyPrec p (CompilationUnit mScriptTag dirs members) =+    vcat $ [maybePP p mScriptTag] ++ map (prettyPrec p) dirs ++ map (prettyPrec p) members++ppMetadata :: Int -> [Annotation] -> Doc+ppMetadata p metadata = vcat (map (prettyPrec p) metadata)++instance Pretty ClassMember where+  prettyPrec p (ConstructorDeclaration _ metadata isExternal isConst isFactory className mName parameters initializers mRedirectedConstructor mBody) =+    ppMetadata p metadata $$+      case mRedirectedConstructor of+        Nothing -> hsep [ optKeyword isExternal "external"+                        , optKeyword isConst "const"+                        , optKeyword isFactory "factory"+                        , hcat [ prettyPrec p className+                               , maybe empty ((period <>) . prettyPrec p) mName+                               , prettyPrec p parameters+                               ]+                        , opt (not $ null initializers) (colon <+> vcat (ppIntersperse p comma initializers))+                        ] <> maybe semi (const empty) mBody $$ maybePP p mBody+        Just redirectedConstructor -> hsep [ optKeyword isConst "const"+                                           , text "factory"+                                           , hcat [ prettyPrec p className+                                                  , maybe empty ((period <>) . prettyPrec p) mName+                                                  , prettyPrec p parameters+                                                  ]+                                           , equals+                                           , prettyPrec p redirectedConstructor <> semi+                                           ]++  prettyPrec p (MethodDeclaration _ metadata isExternal methodModifier mReturnType propertyKeyword isOperator name mTypeParameters mParameters body) =+    ppMetadata p metadata $$+      hsep [ optKeyword isExternal "external"+           , maybePP p methodModifier+           , maybePP p mReturnType+           , prettyPrec p propertyKeyword+           , optKeyword isOperator "operator"+           , hcat [ prettyPrec p name, maybePP p mTypeParameters, maybePP p mParameters]+           ] $$ prettyPrec p body+  prettyPrec p (FieldDeclaration _ metadata isStatic fieldList) =+    ppMetadata p metadata $$+      optKeyword isStatic "static" <+> prettyPrec p fieldList <> semi++ppIntersperse :: (Pretty a) => Int -> Doc -> [a] -> [Doc]+ppIntersperse p s as = punctuate s (map (prettyPrec p) as)++-----------------------------------------------------------------------+---- Help functionality+prettyNestedStmt :: Int -> Statement -> Doc+prettyNestedStmt prio b@(Block' _) = prettyPrec prio b+prettyNestedStmt prio s = nest 2 (prettyPrec prio s)++maybePP :: Pretty a => Int -> Maybe a -> Doc+maybePP p = maybe empty (prettyPrec p)++pound :: Doc+pound = char '#'++period :: Doc+period = char '.'++star :: Doc+star = char '*'++at :: Doc+at = char '@'++dollar :: Doc+dollar = char '$'++questionMark :: Doc+questionMark = char '?'++exclamation :: Doc+exclamation = char '!'++angleBrackets :: Doc -> Doc -- ^ Wrap document in @<...>@+angleBrackets p = char '<' <> p <> char '>'++opt :: Bool -> Doc -> Doc+opt x a = if x then a else empty++optKeyword :: Bool -> String -> Doc+optKeyword x s = opt x (text s)++block :: Char -> Char -> [Doc] -> Doc+block open close xs = char open+    $+$ nest 2 (vcat xs)+    $+$ char close++braceBlock :: [Doc] -> Doc+braceBlock = block '{' '}'++bracketBlock :: [Doc] -> Doc+bracketBlock = block '[' ']'++escapeGeneral :: Char -> String+escapeGeneral '\b' = "\\b"+escapeGeneral '\t' = "\\t"+escapeGeneral '\n' = "\\n"+escapeGeneral '\f' = "\\f"+escapeGeneral '\r' = "\\r"+escapeGeneral '\\' = "\\\\"+escapeGeneral c | c >= ' ' && c < '\DEL' = [c]+                | c <= '\xFFFF' = printf "\\u%04x" (fromEnum c)+                | otherwise = error $ "Language.Dart.Pretty.escapeGeneral: Char " ++ show c ++ " too large for Dart char"++escapeChar :: Char -> String+escapeChar '\'' = "\\'"+escapeChar c = escapeGeneral c++escapeString :: Char -> String+escapeString '"' = "\\\""+escapeString c | c <= '\xFFFF' = escapeGeneral c+               | otherwise = escapeGeneral lead ++ escapeGeneral trail+                   where c' = fromEnum c - 0x010000+                         lead = toEnum $ 0xD800 + c' `div` 0x0400+                         trail = toEnum $ 0xDC00 + c' `mod` 0x0400++-- Operator precedence of binary operators+-- 20.2 of Dart Programming Language Specification+-- http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-408.pdf+opPrec :: String -> Int+opPrec "*"  = 14+opPrec "/"  = 14+opPrec "~/" = 14+opPrec "%"  = 14+opPrec "+"  = 13+opPrec "-"  = 13+opPrec "<<" = 12+opPrec ">>" = 12+opPrec "&"  = 11+opPrec "^"  = 10+opPrec "|"  = 9+opPrec "<"  = 8+opPrec ">"  = 8+opPrec "<=" = 8+opPrec ">=" = 8+opPrec "==" = 7+opPrec "!=" = 7+opPrec "&&" = 6+opPrec "||" = 5+opPrec "??" = 4+
+ src/Language/Dart/Syntax.hs view
@@ -0,0 +1,1325 @@+{-# LANGUAGE DeriveDataTypeable, DeriveGeneric #-}++module Language.Dart.Syntax+  ( AnnotatedNode(..)+  , Annotation(..)+  , ArgumentList(..)+  , AstNode(..)+  , AsyncModifier(..)+  , Block(..)+  , CatchClause(..)+  , ClassMember(..)+  , Combinator(..)+  , Comment(..)+  , CommentReference(..)+  , CommentType(..)+  , CompilationUnit(..)+  , CompilationUnitMember(..)+  , Configuration(..)+  , ConstructorInitializer(..)+  , ConstructorName(..)+  , Declaration(..)+  , DeclaredIdentifier(..)+  , Directive(..)+  , DottedName(..)+  , EnumConstantDeclaration(..)+  , Expression(..)+  , ExtendsClause(..)+  , FinalConstVarOrType(..)+  , FinalVarOrType(..)+  , FormalParameter(..)+  , FormalParameterList(..)+  , FunctionBody(..)+  , FunctionDeclaration(..)+  , FunctionExpression(..)+  , Identifier(..)+  , ImplementsClause(..)+  , InterpolationElement(..)+  , InvocationExpression(..)+  , Label(..)+  , LibraryIdentifier(..)+  , Literal(..)+  , MapLiteralEntry(..)+  , MethodModifier(..)+  , NamedCompilationUnitMember(..)+  , NamespaceDirective(..)+  , NewOrConst(..)+  , NormalFormalParameter(..)+  , ParameterKind(..)+  , PropertyKeyword(..)+  , ScriptTag(..)+  , SimpleIdentifier(..)+  , SingleStringLiteral(..)+  , Statement(..)+  , StringLiteral(..)+  , SwitchMember(..)+  , Token+  , TypeAlias(..)+  , TypeArgumentList(..)+  , TypedLiteral(..)+  , TypeName(..)+  , TypeParameter(..)+  , TypeParameterList(..)+  , UriBasedDirective(..)+  , VariableDeclaration(..)+  , VariableDeclarationList(..)+  , WithClause(..)+  ) where++import Data.Data+import GHC.Generics (Generic)++type Token = String++-- | A literal that has a type associated with it.+--+--      typedLiteral ::=+--          [ListLiteral]+--        | [MapLiteral]+data TypedLiteral+  -- | A literal map.+  --+  --      mapLiteral ::=+  --          'const'? ('<' [TypeName] (',' [TypeName])* '>')?+  --          '{' ([MapLiteralEntry] (',' [MapLiteralEntry])* ','?)? '}'+  = MapLiteral Bool -- isConst+               (Maybe TypeArgumentList) -- typeArguments+               [MapLiteralEntry] -- entries+  -- | A list literal.+  --+  --      listLiteral ::=+  --          'const'? ('<' [TypeName] '>')? '[' ([Expression] ','?)? ']'+  | ListLiteral Bool -- isConst+                (Maybe TypeArgumentList) -- typeArguments+                [Expression] -- elements+  deriving (Eq, Show, Typeable, Generic, Data)++-- | A node within a [StringInterpolation].+--+--      interpolationElement ::=+--          [InterpolationExpression]+--        | [InterpolationString]+data InterpolationElement+  -- | An expression embedded in a string interpolation.+  --+  --      interpolationExpression ::=+  --          '$' [SimpleIdentifier]+  --        | '$' '{' [Expression] '}'+  = InterpolationExpression Expression -- expression+  -- | A non-empty substring of an interpolated string.+  --+  --    interpolationString ::=+  --        characters+  | InterpolationString String -- value+  deriving (Eq, Show, Typeable, Generic, Data)++-- | A single string literal expression.+--+--      singleStringLiteral ::=+--          [SimpleStringLiteral]+--        | [StringInterpolation]+data SingleStringLiteral+  -- | A string literal expression that does not contain any interpolations.+  --+  --      simpleStringLiteral ::=+  --          rawStringLiteral+  --        | basicStringLiteral+  --+  --      rawStringLiteral ::=+  --          'r' basicStringLiteral+  --+  --      simpleStringLiteral ::=+  --          multiLineStringLiteral+  --        | singleLineStringLiteral+  --+  --      multiLineStringLiteral ::=+  --          "'''" characters "'''"+  --        | '"""' characters '"""'+  --+  --      singleLineStringLiteral ::=+  --          "'" characters "'"+  --        | '"' characters '"'+  = SimpleStringLiteral String -- value+  -- | A string interpolation literal.+  --+  --      stringInterpolation ::=+  --          ''' [InterpolationElement]* '''+  --        | '"' [InterpolationElement]* '"'+  | StringInterpolation [InterpolationElement] -- elements+  deriving (Eq, Show, Typeable, Generic, Data)++--   A string literal expression.+--+--      stringLiteral ::=+--          [SimpleStringLiteral]+--        | [AdjacentStrings]+--        | [StringInterpolation]+data StringLiteral+  = SingleStringLiteral' SingleStringLiteral+  -- | Two or more string literals that are implicitly concatenated because of being+  --   adjacent (separated only by whitespace).+  --+  --   While the grammar only allows adjacent strings when all of the strings are of+  --   the same kind (single line or multi-line), this class doesn't enforce that+  --   restriction.+  --+  --      adjacentStrings ::=+  --          [StringLiteral] [StringLiteral]++  | AdjacentStrings [StringLiteral] -- strings+  deriving (Eq, Show, Typeable, Generic, Data)++-- | A node that represents a literal expression.+--+--      literal ::=+--          [BooleanLiteral]+--        | [DoubleLiteral]+--        | [IntegerLiteral]+--        | [ListLiteral]+--        | [MapLiteral]+--        | [NullLiteral]+--        | [StringLiteral]+data Literal+  --   A boolean literal expression.+  --+  --      booleanLiteral ::=+  --          'false' | 'true'+  = BooleanLiteral Bool -- bool+  --   A floating point literal expression.+  --+  --      doubleLiteral ::=+  --          decimalDigit+ ('.' decimalDigit*)? exponent?+  --        | '.' decimalDigit+ exponent?+  --+  --      exponent ::=+  --          ('e' | 'E') ('+' | '-')? decimalDigit++  | DoubleLiteral Double -- value+  | TypedLiteral TypedLiteral+  -- | An integer literal expression.+  --+  --      integerLiteral ::=+  --          decimalIntegerLiteral+  --        | hexadecimalIntegerLiteral+  --+  --      decimalIntegerLiteral ::=+  --          decimalDigit++  --+  --      hexadecimalIntegerLiteral ::=+  --          '0x' hexadecimalDigit++  --        | '0X' hexadecimalDigit++  | IntegerLiteral Integer -- value+  -- | A null literal expression.+  --+  --      nullLiteral ::=+  --          'null'+  | NullLiteral+  | StringLiteral' StringLiteral+  -- | A symbol literal expression.+  --+  --      symbolLiteral ::=+  --          '#' (operator | (identifier ('.' identifier)*))+  | SymbolLiteral [Token] -- components+  deriving (Eq, Show, Typeable, Generic, Data)++data FinalConstVarOrType = FCVTFinal TypeName+                         | FCVTConst TypeName+                         | FCVTType  TypeName+                         | FCVTVar+  deriving (Eq, Show, Typeable, Generic, Data)++data FinalVarOrType = FVTFinal TypeName+                    | FVTType TypeName+                    | FVTVar+  deriving (Eq, Show, Typeable, Generic, Data)++data NewOrConst = NCNew | NCConst+  deriving (Eq, Show, Typeable, Generic, Data)++-- | An identifier that has an initial value associated with it. Instances of this+--   class are always children of the class [VariableDeclarationList].+--+--      variableDeclaration ::=+--          [SimpleIdentifier] ('=' [Expression])?+data VariableDeclaration = VariableDeclaration SimpleIdentifier -- name+                           (Maybe Expression) -- initializer+  deriving (Eq, Show, Typeable, Generic, Data)++-- | The declaration of one or more variables of the same type.+--+--      variableDeclarationList ::=+--          finalConstVarOrType [VariableDeclaration] (',' [VariableDeclaration])*+--+--      finalConstVarOrType ::=+--        | 'final' [TypeName]?+--        | 'const' [TypeName]?+--        | 'var'+--        | [TypeName]+data VariableDeclarationList = VariableDeclarationList (Maybe Comment) -- comment+                                                       [Annotation] -- metadata+                                                       FinalConstVarOrType -- kind+                                                       [VariableDeclaration] -- variables+  deriving (Eq, Show, Typeable, Generic, Data)++-- | The declaration of a single identifier.+--+--      declaredIdentifier ::=+--          [Annotation] finalConstVarOrType [SimpleIdentifier]+data DeclaredIdentifier = DeclaredIdentifier (Maybe Comment) -- comment+                                             [Annotation] -- metadata+                                             FinalConstVarOrType -- kind+                                             SimpleIdentifier -- identifier+  deriving (Eq, Show, Typeable, Generic, Data)++-- | The declaration of an enum constant.+data EnumConstantDeclaration = EnumConstantDeclaration (Maybe Comment)+                                                       [Annotation]+                                                       SimpleIdentifier+  deriving (Eq, Show, Typeable, Generic, Data)++data PropertyKeyword = Get | Set | Empty+  deriving (Eq, Show, Typeable, Generic, Data)++-- | A top-level declaration.+--+--      functionDeclaration ::=+--          'external' functionSignature+--        | functionSignature [FunctionBody]+--+--      functionSignature ::=+--          [Type]? ('get' | 'set')? [SimpleIdentifier] [FormalParameterList]+data FunctionDeclaration = FunctionDeclaration (Maybe Comment) -- comment+                                               [Annotation] -- metadata+                                               Bool -- isExternal+                                               (Maybe TypeName) -- returnType+                                               PropertyKeyword -- propertyKeyword+                                               SimpleIdentifier -- name+                                               FunctionExpression -- functionExpression+  deriving (Eq, Show, Typeable, Generic, Data)++-- | The with clause in a class declaration.+--+--      withClause ::=+--          'with' [TypeName] (',' [TypeName])*+newtype WithClause = WithClause [TypeName] -- mixinTypes+  deriving (Eq, Show, Typeable, Generic, Data)++-- | The "implements" clause in an class declaration.+--+--      implementsClause ::=+--          'implements' [TypeName] (',' [TypeName])*+newtype ImplementsClause = ImplementsClause [TypeName] -- interfaces+  deriving (Eq, Show, Typeable, Generic, Data)++-- | The declaration of a type alias.+--+--      typeAlias ::=+--          'typedef' typeAliasBody+--+--      typeAliasBody ::=+--          classTypeAlias+--        | functionTypeAlias+data TypeAlias+  -- | A class type alias.+  --+  --      classTypeAlias ::=+  --          [SimpleIdentifier] [TypeParameterList]? '=' 'abstract'? mixinApplication+  --+  --      mixinApplication ::=+  --          [TypeName] [WithClause] [ImplementsClause]? ';'+  = ClassTypeAlias    (Maybe Comment) -- comment+                      [Annotation] -- metadata+                      SimpleIdentifier -- name+                      (Maybe TypeParameterList) -- typeParameters+                      Bool -- isAbstract+                      TypeName -- superclass+                      WithClause -- withClause+                      (Maybe ImplementsClause) -- implementsClause+  -- | A function type alias.+  --+  --      functionTypeAlias ::=+  --          functionPrefix [TypeParameterList]? [FormalParameterList] ';'+  --+  --      functionPrefix ::=+  --          [TypeName]? [SimpleIdentifier]+  | FunctionTypeAlias (Maybe Comment) -- comment+                      [Annotation] -- metadata+                      (Maybe TypeName) -- returnType+                      SimpleIdentifier -- name+                      (Maybe TypeParameterList) -- typeParameters+                      FormalParameterList -- parameters+  deriving (Eq, Show, Typeable, Generic, Data)++-- | A node that declares a single name within the scope of a compilation unit.+data NamedCompilationUnitMember+  = FunctionDeclaration' FunctionDeclaration+  | TypeAlias TypeAlias+  -- | The declaration of a class.+  --+  --      classDeclaration ::=+  --          'abstract'? 'class' [SimpleIdentifier] [TypeParameterList]?+  --          ([ExtendsClause] [WithClause]?)?+  --          [ImplementsClause]?+  --          '{' [ClassMember]* '}'+  | ClassDeclaration (Maybe Comment) -- comment+                     [Annotation] -- metadata+                     Bool -- isAbstract+                     SimpleIdentifier -- name+                     (Maybe TypeParameterList) -- typeParameters+                     (Maybe ExtendsClause) -- extendsClause+                     (Maybe WithClause) -- withClause+                     (Maybe ImplementsClause) -- implementsClause+                     [ClassMember] -- members+  -- | The declaration of an enumeration.+  --+  --      enumType ::=+  --          metadata 'enum' [SimpleIdentifier] '{' [SimpleIdentifier] (',' [SimpleIdentifier])* (',')? '}'+  | EnumDeclaration (Maybe Comment) -- comment+                    [Annotation] -- metadata+                    SimpleIdentifier -- name+                    [EnumConstantDeclaration] -- constants+  deriving (Eq, Show, Typeable, Generic, Data)++-- | A node that declares one or more names within the scope of a compilation+--   unit.+--+--      compilationUnitMember ::=+--          [ClassDeclaration]+--        | [TypeAlias]+--        | [FunctionDeclaration]+--        | [MethodDeclaration]+--        | [VariableDeclaration]+--        | [VariableDeclaration]+data CompilationUnitMember+  -- | The declaration of one or more top-level variables of the same type.+  --+  --      topLevelVariableDeclaration ::=+  --          ('final' | 'const') type? staticFinalDeclarationList ';'+  --        | variableDeclaration ';'+  = TopLevelVariableDeclaration (Maybe Comment) -- comment+                                [Annotation] -- metadata+                                VariableDeclarationList -- variableList+  | NamedCompilationUnitMember NamedCompilationUnitMember+  deriving (Eq, Show, Typeable, Generic, Data)++data MethodModifier = Abstract | Static+  deriving (Eq, Show, Typeable, Generic, Data)++-- | A node that declares a name within the scope of a class.+data ClassMember+  --   A constructor declaration.+  --+  --      constructorDeclaration ::=+  --          constructorSignature [FunctionBody]?+  --        | constructorName formalParameterList ':' 'this' ('.' [SimpleIdentifier])? arguments+  --+  --      constructorSignature ::=+  --          'external'? constructorName formalParameterList initializerList?+  --        | 'external'? 'factory' factoryName formalParameterList initializerList?+  --        | 'external'? 'const'  constructorName formalParameterList initializerList?+  --+  --      constructorName ::=+  --          [SimpleIdentifier] ('.' [SimpleIdentifier])?+  --+  --      factoryName ::=+  --          [Identifier] ('.' [SimpleIdentifier])?+  --+  --      initializerList ::=+  --          ':' [ConstructorInitializer] (',' [ConstructorInitializer])*+  = ConstructorDeclaration (Maybe Comment) -- comment+                           [Annotation] -- metadata+                           Bool -- isExternal+                           Bool -- isConst+                           Bool -- isFactory+                           Identifier -- returnType+                           (Maybe SimpleIdentifier) -- name+                           FormalParameterList -- parameters+                           [ConstructorInitializer] -- initializers+                           (Maybe ConstructorName) -- redirectedConstructor+                           (Maybe FunctionBody) -- body+  -- | A method declaration.+  --+  --      methodDeclaration ::=+  --          methodSignature [FunctionBody]+  --+  --      methodSignature ::=+  --          'external'? ('abstract' | 'static')? [Type]? ('get' | 'set')?+  --          methodName [TypeParameterList] [FormalParameterList]+  --+  --      methodName ::=+  --          [SimpleIdentifier]+  --        | 'operator' [SimpleIdentifier]+  | MethodDeclaration (Maybe Comment) -- comment+                      [Annotation] -- metadata+                      Bool -- isExternal+                      (Maybe MethodModifier) -- methodModifier+                      (Maybe TypeName) -- returnType+                      PropertyKeyword+                      Bool -- isOperator+                      SimpleIdentifier -- name+                      (Maybe TypeParameterList) -- typeParameters+                      (Maybe FormalParameterList) -- parameters+                      FunctionBody -- body+  -- | The declaration of one or more fields of the same type.+  --+  --      fieldDeclaration ::=+  --          'static'? [VariableDeclarationList] ';'+  | FieldDeclaration  (Maybe Comment) -- comment+                      [Annotation] -- metadata+                      Bool -- isStatic+                      VariableDeclarationList -- fieldList+  deriving (Eq, Show, Typeable, Generic, Data)++-- |  A node that represents the declaration of one or more names. Each declared+--    name is visible within a name scope.+data Declaration+  = VariableDeclaration' VariableDeclaration+  | TypeParameter' TypeParameter+  | ClassMember ClassMember+  | DeclaredIdentifier' DeclaredIdentifier+  | EnumConstantDeclaration' EnumConstantDeclaration+  | CompilationUnitMember' CompilationUnitMember+  deriving (Eq, Show, Typeable, Generic, Data)++-- | A node that represents a directive that impacts the namespace of a library.+--+--      directive ::=+--          [ExportDirective]+--        | [ImportDirective]+data NamespaceDirective+  -- | An export directive.+  --+  --      exportDirective ::=+  --          [Annotation] 'export' [StringLiteral] [Combinator]* ';'+  = ExportDirective (Maybe Comment) -- comment+                    [Annotation] -- metadata+                    StringLiteral -- libraryUri+                    [Configuration] -- configurations+                    [Combinator] -- combinators+  -- | An import directive.+  --+  --      importDirective ::=+  --          [Annotation] 'import' [StringLiteral] ('as' identifier)? [Combinator]* ';'+  --        | [Annotation] 'import' [StringLiteral] 'deferred' 'as' identifier [Combinator]* ';'+  | ImportDirective (Maybe Comment) -- comment+                    [Annotation] -- metadata+                    StringLiteral -- libraryUri+                    [Configuration] -- configurations+                    Bool -- isDeferred+                    (Maybe SimpleIdentifier) -- prefix+                    [Combinator] -- combinators+  deriving (Eq, Show, Typeable, Generic, Data)++-- | A directive that references a URI.+--+--      uriBasedDirective ::=+--          [ExportDirective]+--        | [ImportDirective]+--        | [PartDirective]+data UriBasedDirective+  = NamespaceDirective NamespaceDirective+  -- | A part directive.+  --+  --      partDirective ::=+  --          [Annotation] 'part' [StringLiteral] ';'+  | PartDirective (Maybe Comment) -- comment+                  [Annotation] -- metadata+                  StringLiteral -- partUri+  deriving (Eq, Show, Typeable, Generic, Data)++-- | A node that represents a directive.+--+--      directive ::=+--          [ExportDirective]+--        | [ImportDirective]+--        | [LibraryDirective]+--        | [PartDirective]+--        | [PartOfDirective]+data Directive+  = UriBasedDirective UriBasedDirective+  -- | A part-of directive.+  --+  --      partOfDirective ::=+  --          [Annotation] 'part' 'of' [Identifier] ';'+  | PartOfDirective (Maybe Comment) -- comment+                    [Annotation] -- metadata+                    LibraryIdentifier -- libraryName+  -- | A library directive.+  --+  --      libraryDirective ::=+  --          [Annotation] 'library' [Identifier] ';'+  | LibraryDirective (Maybe Comment) -- comment+                     [Annotation] -- metadata+                     LibraryIdentifier -- name+  deriving (Eq, Show, Typeable, Generic, Data)++-- | An AST node that can be annotated with both a documentation comment and a+--   list of annotations.+data AnnotatedNode+  = VariableDeclarationList' VariableDeclarationList+  | Declaration' Declaration+  | Directive Directive+  deriving (Eq, Show, Typeable, Generic, Data)++-- | A node that can occur in the initializer list of a constructor declaration.+--+--      constructorInitializer ::=+--          [SuperConstructorInvocation]+--        | [ConstructorFieldInitializer]+--        | [RedirectingConstructorInvocation]+data ConstructorInitializer+  -- | The invocation of a constructor in the same class from within a constructor's+  --   initialization list.+  --+  --      redirectingConstructorInvocation ::=+  --          'this' ('.' identifier)? arguments+  = RedirectingConstructorInvocation (Maybe SimpleIdentifier) -- constructorName+                                     ArgumentList -- argumentList+  -- | The initialization of a field within a constructor's initialization list.+  --+  --      fieldInitializer ::=+  --          ('this' '.')? [SimpleIdentifier] '=' [Expression]+  | ConstructorFieldInitializer Bool -- explicitThis+                                SimpleIdentifier -- fieldName+                                Expression -- expression+  -- | The invocation of a superclass' constructor from within a constructor's+  --   initialization list.+  --+  --      superInvocation ::=+  --          'super' ('.' [SimpleIdentifier])? [ArgumentList]+  | SuperConstructorInvocation (Maybe SimpleIdentifier) -- constructorName+                               ArgumentList -- argumentList+  deriving (Eq, Show, Typeable, Generic, Data)++-- | A combinator associated with an import or export directive.+--+--      combinator ::=+--          [HideCombinator]+--        | [ShowCombinator]+data Combinator+  -- | A combinator that restricts the names being imported to those in a given list.+  --+  --      showCombinator ::=+  --          'show' [SimpleIdentifier] (',' [SimpleIdentifier])*+  = ShowCombinator [SimpleIdentifier] -- shownNames+  -- | A combinator that restricts the names being imported to those that are not in+  --   a given list.+  --+  --      hideCombinator ::=+  --          'hide' [SimpleIdentifier] (',' [SimpleIdentifier])*+  | HideCombinator [SimpleIdentifier] -- hiddenNames+  deriving (Eq, Show, Typeable, Generic, Data)++-- | A dotted name, used in a configuration within an import or export directive.+--+--      dottedName ::=+--          [SimpleIdentifier] ('.' [SimpleIdentifier])*+newtype DottedName = DottedName [SimpleIdentifier] -- components+  deriving (Eq, Show, Typeable, Generic, Data)++-- | A configuration in either an import or export directive.+--+--      configuration ::=+--          'if' '(' test ')' uri+--+--      test ::=+--          dottedName ('==' stringLiteral)?+--+--      dottedName ::=+--          identifier ('.' identifier)*+data Configuration = Configuration DottedName -- name+                                   StringLiteral -- value+                                   StringLiteral -- libraryUri+  deriving (Eq, Show, Typeable, Generic, Data)++-- | The "extends" clause in a class declaration.+--+--      extendsClause ::=+--          'extends' [TypeName]+newtype ExtendsClause = ExtendsClause TypeName -- superclass+  deriving (Eq, Show, Typeable, Generic, Data)++-- | A single key/value pair in a map literal.+--+--      mapLiteralEntry ::=+--          [Expression] ':' [Expression]+data MapLiteralEntry = MapLiteralEntry Expression -- key+                                       Expression -- value+  deriving (Eq, Show, Typeable, Generic, Data)++newtype ScriptTag = ScriptTag Token -- scriptTag+  deriving (Eq, Show, Typeable, Generic, Data)++-- | A node in the AST structure for a Dart program.+data AstNode+  = SwitchMember SwitchMember+  | Statement Statement+  | CatchClause' CatchClause+  | TypeNameNode TypeName+  | TypeArgumentList' TypeArgumentList+  | Label' Label+  | Annotation' Annotation+  | Comment' Comment+  | CommentReference' CommentReference+  | ArgumentList' ArgumentList+  | TypeParameterList' TypeParameterList+  | FormalParameterList' FormalParameterList+  | AnnotatedNode' AnnotatedNode+  | WithClause' WithClause+  | ExtendsClause' ExtendsClause+  | ConstructorName' ConstructorName+  | InterpolationElement' InterpolationElement+  | ConstructorInitializer ConstructorInitializer+  | Combinator Combinator+  | Configuration' Configuration+  | DottedName' DottedName+  --   A script tag that can optionally occur at the beginning of a compilation unit.+  --+  --      scriptTag ::=+  --          '#!' (~NEWLINE)* NEWLINE+  | ScriptTag' ScriptTag+  -- | The "native" clause in an class declaration.+  --+  --      nativeClause ::=+  --          'native' [StringLiteral]+  | NativeClause StringLiteral -- name+  | MapLiteralEntry' MapLiteralEntry+  deriving (Eq, Show, Typeable, Generic, Data)++data ParameterKind = Required | Positional | Named+  deriving (Eq, Show, Typeable, Generic, Data)++-- | A formal parameter that is required (is not optional).+--+--      normalFormalParameter ::=+--          [FunctionTypedFormalParameter]+--        | [FieldFormalParameter]+--        | [SimpleFormalParameter]+data NormalFormalParameter+  -- | A function-typed formal parameter.+  --+  --      functionSignature ::=+  --          [TypeName]? [SimpleIdentifier] [TypeParameterList]? [FormalParameterList]+  = FunctionTypedFormalParameter (Maybe Comment) -- comment+                                 [Annotation] -- metadata+                                 (Maybe TypeName) -- returnType+                                 SimpleIdentifier -- identifier+                                 (Maybe TypeParameterList) -- typeParameters+                                 FormalParameterList -- parameters+  -- | A field formal parameter.+  --+  --      fieldFormalParameter ::=+  --          ('final' [TypeName] | 'const' [TypeName] | 'var' | [TypeName])?+  --          'this' '.' [SimpleIdentifier]+  | FieldFormalParameter         (Maybe Comment) -- comment+                                 [Annotation] -- metadata+                                 (Maybe FinalConstVarOrType)+                                 Bool -- explicitThis+                                 SimpleIdentifier -- identifier+  -- | A simple formal parameter.+  --+  --      simpleFormalParameter ::=+  --          ('final' [TypeName] | 'var' | [TypeName])? [SimpleIdentifier]+  | SimpleFormalParameter        (Maybe Comment) -- comment+                                 [Annotation] -- metadata+                                 FinalVarOrType+                                 SimpleIdentifier -- identifier+  deriving (Eq, Show, Typeable, Generic, Data)++-- | A node representing a parameter to a function.+--+--      formalParameter ::=+--          [NormalFormalParameter]+--        | [DefaultFormalParameter]+data FormalParameter+  = NormalFormalParameter' NormalFormalParameter+  --   A formal parameter with a default value. There are two kinds of parameters+  --   that are both represented by this class: named formal parameters and+  --   positional formal parameters.+  --+  --      defaultFormalParameter ::=+  --          [NormalFormalParameter] ('=' [Expression])?+  --+  --      defaultNamedParameter ::=+  --          [NormalFormalParameter] (':' [Expression])?+  | DefaultFormalParameter NormalFormalParameter -- parameter+                           ParameterKind -- kind+                           (Maybe Expression) -- defaultValue+  deriving (Eq, Show, Typeable, Generic, Data)++-- | The formal parameter list of a method declaration, function declaration, or+--   function type alias.+--+--   While the grammar requires all optional formal parameters to follow all of+--   the normal formal parameters and at most one grouping of optional formal+--   parameters, this class does not enforce those constraints. All parameters are+--   flattened into a single list, which can have any or all kinds of parameters+--   (normal, named, and positional) in any order.+--+--      formalParameterList ::=+--          '(' ')'+--        | '(' normalFormalParameters (',' optionalFormalParameters)? ')'+--        | '(' optionalFormalParameters ')'+--+--      normalFormalParameters ::=+--          [NormalFormalParameter] (',' [NormalFormalParameter])*+--+--      optionalFormalParameters ::=+--          optionalPositionalFormalParameters+--        | namedFormalParameters+--+--      optionalPositionalFormalParameters ::=+--          '[' [DefaultFormalParameter] (',' [DefaultFormalParameter])* ']'+--+--      namedFormalParameters ::=+--          '{' [DefaultFormalParameter] (',' [DefaultFormalParameter])* '}'+newtype FormalParameterList = FormalParameterList [FormalParameter] -- parameters+  deriving (Eq, Show, Typeable, Generic, Data)++-- | A type parameter.+--+--      typeParameter ::=+--          [SimpleIdentifier] ('extends' [TypeName])?+data TypeParameter = TypeParameter (Maybe Comment) -- comment+                                   [Annotation] -- metadata+                                   SimpleIdentifier -- name+                                   (Maybe TypeName) -- bound+  deriving (Eq, Show, Typeable, Generic, Data)++-- | Type parameters within a declaration.+--+--      typeParameterList ::=+--          '<' [TypeParameter] (',' [TypeParameter])* '>'+newtype TypeParameterList = TypeParameterList [TypeParameter] -- typeParameters+  deriving (Eq, Show, Typeable, Generic, Data)++-- | A list of arguments in the invocation of an executable element (that is, a+--   function, method, or constructor).+--+--      argumentList ::=+--          '(' arguments? ')'+--+--      arguments ::=+--          [NamedExpression] (',' [NamedExpression])*+--        | [Expression] (',' [Expression])* (',' [NamedExpression])*+newtype ArgumentList = ArgumentList [Expression] -- arguments+  deriving (Eq, Show, Typeable, Generic, Data)++-- | A reference to a Dart element that is found within a documentation comment.+--+--      commentReference ::=+--          '[' 'new'? [Identifier] ']'+data CommentReference = CommentReference Bool -- isNew+                                         Identifier -- identifier+  deriving (Eq, Show, Typeable, Generic, Data)++data CommentType = BlockComment | DocumentationComment | EndOfLineComment+  deriving (Eq, Show, Typeable, Generic, Data)++-- | A comment within the source code.+--+--      comment ::=+--          endOfLineComment+--        | blockComment+--        | documentationComment+--+--      endOfLineComment ::=+--          '//' (CHARACTER - EOL)* EOL+--+--      blockComment ::=+--          '/--  ' CHARACTER* '&#42;/'+--+--      documentationComment ::=+--          '/--  *' (CHARACTER | [CommentReference])* '&#42;/'+--        | ('///' (CHARACTER - EOL)* EOL)++data Comment = Comment [Token] -- tokens+                       CommentType -- type+                       [CommentReference] -- references+  deriving (Eq, Show, Typeable, Generic, Data)++-- | An annotation that can be associated with an AST node.+--+--      metadata ::=+--          annotation*+--+--      annotation ::=+--          '@' [Identifier] ('.' [SimpleIdentifier])? [ArgumentList]?+data Annotation = Annotation Identifier -- name+                             (Maybe SimpleIdentifier) -- constructorName+                             (Maybe ArgumentList) -- arguments+  deriving (Eq, Show, Typeable, Generic, Data)++-- | A label on either a [LabeledStatement] or a [NamedExpression].+--+--      label ::=+--          [SimpleIdentifier] ':'+newtype Label = Label SimpleIdentifier -- label+  deriving (Eq, Show, Typeable, Generic, Data)++-- | The name of a type, which can optionally include type arguments.+--+--      typeName ::=+--          [Identifier] typeArguments?+data TypeName = TypeName Identifier -- name+                         (Maybe TypeArgumentList) --typeArguments+  deriving (Eq, Show, Typeable, Generic, Data)++-- | A list of type arguments.+--+--      typeArguments ::=+--          '<' typeName (',' typeName)* '>'+data TypeArgumentList = TypeArgumentList [TypeName] -- arguments+  deriving (Eq, Show, Typeable, Generic, Data)++-- | An element within a switch statement.+--+--      switchMember ::=+--          switchCase+--        | switchDefault+data SwitchMember+  -- | The default case in a switch statement.+  --+  --      switchDefault ::=+  --          [SimpleIdentifier]* 'default' ':' [Statement]*+  = SwitchDefault [Label] -- labels+                  [Statement] -- statements+  -- | A case in a switch statement.+  --+  --      switchCase ::=+  --          [SimpleIdentifier]* 'case' [Expression] ':' [Statement]*+  | SwitchCase [Label] -- labels+               Expression -- expression+               [Statement] -- statements+  deriving (Eq, Show, Typeable, Generic, Data)++-- | A catch clause within a try statement.+--+--      onPart ::=+--          catchPart [Block]+--        | 'on' type catchPart? [Block]+--+--      catchPart ::=+--          'catch' '(' [SimpleIdentifier] (',' [SimpleIdentifier])? ')'+data CatchClause = CatchClause (Maybe TypeName) -- exceptionType+                               SimpleIdentifier -- exceptionParameter+                               (Maybe SimpleIdentifier) -- stackTraceParameter+                               Block -- body+  deriving (Eq, Show, Typeable, Generic, Data)++-- | A sequence of statements.+--+--      block ::=+--          '{' statement* '}'+data Block = Block [Statement] -- statements+  deriving (Eq, Show, Typeable, Generic, Data)++-- | A simple identifier.+--+--      simpleIdentifier ::=+--          initialCharacter internalCharacter*+--+--      initialCharacter ::= '_' | '$' | letter+--+--      internalCharacter ::= '_' | '$' | letter | digit+newtype SimpleIdentifier = SimpleIdentifier Token -- token+  deriving (Eq, Show, Typeable, Generic, Data)++-- | The identifier for a library.+--+--      libraryIdentifier ::=+--          [SimpleIdentifier] ('.' [SimpleIdentifier])*+newtype LibraryIdentifier = LibraryIdentifier [SimpleIdentifier] -- components+  deriving (Eq, Show, Typeable, Generic, Data)++-- | A node that represents an identifier.+--+--      identifier ::=+--          [SimpleIdentifier]+--        | [PrefixedIdentifier]+data Identifier+  = SimpleIdentifier' SimpleIdentifier+  -- | An identifier that is prefixed or an access to an object property where the+  --   target of the property access is a simple identifier.+  --+  --      prefixedIdentifier ::=+  --          [SimpleIdentifier] '.' [SimpleIdentifier]+  | PrefixedIdentifier SimpleIdentifier -- prefix+                       SimpleIdentifier -- identifier+  | LibraryIdentifier' LibraryIdentifier+  deriving (Eq, Show, Typeable, Generic, Data)++data AsyncModifier = Async | Sync | AsyncStar | SyncStar+  deriving (Eq, Show, Typeable, Generic, Data)++-- | A node representing the body of a function or method.+--+--      functionBody ::=+--          [BlockFunctionBody]+--        | [EmptyFunctionBody]+--        | [ExpressionFunctionBody]+data FunctionBody+  -- | A function body that consists of a block of statements.+  --+  --      blockFunctionBody ::=+  --          ('async' | 'async' '*' | 'sync' '*')? [Block]+  = BlockFunctionBody AsyncModifier -- asyncModifier+                      Block -- block+  -- | An empty function body, which can only appear in constructors or abstract+  --   methods.+  --+  --      emptyFunctionBody ::=+  --          ';'+  | EmptyFunctionBody+  -- | A function body consisting of a single expression.+  --+  --      expressionFunctionBody ::=+  --          'async'? '=>' [Expression] ';'+  | ExpressionFunctionBody Bool -- isAsync+                           Expression -- expression+  -- | A function body that consists of a native keyword followed by a string+  --   literal.+  --+  --      nativeFunctionBody ::=+  --          'native' [SimpleStringLiteral] ';'+  | NativeFunctionBody StringLiteral -- stringLiteral+  deriving (Eq, Show, Typeable, Generic, Data)++-- | A function expression.+--+--      functionExpression ::=+--          [TypeParameterList]? [FormalParameterList] [FunctionBody]+data FunctionExpression = FunctionExpression (Maybe TypeParameterList) -- typeParameters+                                             FormalParameterList -- parameters+                                             FunctionBody -- body+  deriving (Eq, Show, Typeable, Generic, Data)++-- | The name of a constructor.+--+--      constructorName ::=+--          type ('.' identifier)?+data ConstructorName = ConstructorName TypeName -- type+                                       (Maybe SimpleIdentifier) -- name+  deriving (Eq, Show, Typeable, Generic, Data)++-- | The invocation of a function or method; either a+--   [FunctionExpressionInvocation] or a [MethodInvocation].+data InvocationExpression+  -- | The invocation of a function resulting from evaluating an expression.+  --   Invocations of methods and other forms of functions are represented by+  --   [MethodInvocation] nodes. Invocations of getters and setters are represented+  --   by either [PrefixedIdentifier] or [PropertyAccess] nodes.+  --+  --      functionExpressionInvocation ::=+  --          [Expression] [TypeArgumentList]? [ArgumentList]+  = FunctionExpressionInvocation Expression -- function+                                 (Maybe TypeArgumentList) -- typeArguments+                                 ArgumentList -- argumentList+  -- | The invocation of either a function or a method. Invocations of functions+  --   resulting from evaluating an expression are represented by+  --   [FunctionExpressionInvocation] nodes. Invocations of getters and setters are+  --   represented by either [PrefixedIdentifier] or [PropertyAccess] nodes.+  --+  --      methodInvocation ::=+  --          ([Expression] '.')? [SimpleIdentifier] [TypeArgumentList]? [ArgumentList]+  | MethodInvocation (Maybe Expression) -- target+                     SimpleIdentifier -- methodName+                     (Maybe TypeArgumentList) -- typeArguments+                     ArgumentList -- argumentList+  deriving (Eq, Show, Typeable, Generic, Data)++-- | A node that represents an expression.+--+--      expression ::=+--          [AssignmentExpression]+--        | [ConditionalExpression] cascadeSection*+--        | [ThrowExpression]+data Expression+  = Literal' Literal+  | Identifier' Identifier+  -- | A prefix unary expression.+  --+  --      prefixExpression ::=+  --          [Token] [Expression]+  | PrefixExpression Token -- operator+                     Expression -- operand+  -- | A postfix unary expression.+  --+  --      postfixExpression ::=+  --          [Expression] [Token]+  | PostfixExpression Expression -- operand+                      Token -- operator+  -- | A binary (infix) expression.+  --+  --      binaryExpression ::=+  --          [Expression] [Token] [Expression]+  | BinaryExpression Expression -- leftOperand+                     Token -- operator+                     Expression -- rightOperand+  -- | An assignment expression.+  --+  --      assignmentExpression ::=+  --          [Expression] operator [Expression]+  | AssignmentExpression Expression -- leftHandSide+                         Token -- operator+                         Expression -- rightHandSide+  | FunctionExpression' FunctionExpression+  -- | An instance creation expression.+  --+  --      newExpression ::=+  --          ('new' | 'const') [TypeName] ('.' [SimpleIdentifier])? [ArgumentList]+  | InstanceCreationExpression NewOrConst+                               ConstructorName -- constructorName+                               ArgumentList -- argumentList+  -- | An as expression.+  --+  --      asExpression ::=+  --          [Expression] 'as' [TypeName]+  | AsExpression Expression -- expression+                 TypeName -- type+  -- | An is expression.+  --+  --      isExpression ::=+  --          [Expression] 'is' '!'? [TypeName]+  | IsExpression Expression -- expression+                 Bool -- isNot+                 TypeName -- type+  -- | A throw expression.+  --+  --      throwExpression ::=+  --          'throw' [Expression]+  | ThrowExpression Expression -- expression+  -- | A rethrow expression.+  --+  --      rethrowExpression ::=+  --          'rethrow'+  | RethrowExpression+  -- | A this expression.+  --+  --      thisExpression ::=+  --          'this'+  | ThisExpression+  -- | A super expression.+  --+  --      superExpression ::=+  --          'super'+  | SuperExpression+  -- | A parenthesized expression.+  --+  --      parenthesizedExpression ::=+  --          '(' [Expression] ')'+  | ParenthesizedExpression Expression -- expression+  -- | The access of a property of an object.+  --+  --   Note, however, that accesses to properties of objects can also be represented+  --   as [PrefixedIdentifier] nodes in cases where the target is also a simple+  --   identifier.+  --+  --      propertyAccess ::=+  --          [Expression] '.' [SimpleIdentifier]+  | PropertyAccess Expression -- target+                   SimpleIdentifier -- propertyName+  -- | An expression that has a name associated with it. They are used in method+  --   invocations when there are named parameters.+  --+  --      namedExpression ::=+  --          [Label] [Expression]+  | NamedExpression Label -- name+                    Expression -- expression+  | InvocationExpression InvocationExpression+  -- | A conditional expression.+  --+  --      conditionalExpression ::=+  --          [Expression] '?' [Expression] ':' [Expression]+  | ConditionalExpression Expression -- condition+                          Expression -- thenExpression+                          Expression -- elseExpression+  -- | A sequence of cascaded expressions: expressions that share a common target.+  --   There are three kinds of expressions that can be used in a cascade+  --   expression: [IndexExpression], [MethodInvocation] and [PropertyAccess].+  --+  --      cascadeExpression ::=+  --          [Expression] cascadeSection*+  --+  --      cascadeSection ::=+  --          '..'  (cascadeSelector arguments*) (assignableSelector arguments*)*+  --          (assignmentOperator expressionWithoutCascade)?+  --+  --      cascadeSelector ::=+  --          '[ ' expression '] '+  --        | identifier+  | CascadeExpression Expression -- target+                      [Expression] -- cascadeSections+  -- | An index expression.+  --+  --      indexExpression ::=+  --          [Expression] '[' [Expression] ']'+  | IndexExpressionForCasecade Expression -- index+  | IndexExpressionForTarget   Expression -- target+                               Expression -- index+  -- | An await expression.+  --+  --      awaitExpression ::=+  --          'await' [Expression]+  | AwaitExpression Expression -- expression+  deriving (Eq, Show, Typeable, Generic, Data)++-- | A node that represents a statement.+--+--      statement ::=+--          [Block]+--        | [VariableDeclarationStatement]+--        | [ForStatement]+--        | [ForEachStatement]+--        | [WhileStatement]+--        | [DoStatement]+--        | [SwitchStatement]+--        | [IfStatement]+--        | [TryStatement]+--        | [BreakStatement]+--        | [ContinueStatement]+--        | [ReturnStatement]+--        | [ExpressionStatement]+--        | [FunctionDeclarationStatement]+data Statement+  = Block' Block+  -- | A list of variables that are being declared in a context where a statement is+  --   required.+  --+  --      variableDeclarationStatement ::=+  --          [VariableDeclarationList] ';'+  | VariableDeclarationStatement VariableDeclarationList -- variableList+  -- | A for statement.+  --+  --      forStatement ::=+  --          'for' '(' forLoopParts ')' [Statement]+  --+  --      forLoopParts ::=+  --          forInitializerStatement ';' [Expression]? ';' [Expression]?+  --+  --      forInitializerStatement ::=+  --          [DefaultFormalParameter]+  --        | [Expression]?+  | ForStatement (Maybe VariableDeclarationList) -- variableList+                 (Maybe Expression) -- initialization+                 (Maybe Expression) -- condition+                 [Expression] -- updaters+                 Statement -- body+  -- | A for-each statement.+  --+  --      forEachStatement ::=+  --          'await'? 'for' '(' [DeclaredIdentifier] 'in' [Expression] ')' [Block]+  --        | 'await'? 'for' '(' [SimpleIdentifier] 'in' [Expression] ')' [Block]+  | ForEachStatementWithDeclaration Bool -- isAwait+                                    DeclaredIdentifier -- loopVariable+                                    Expression -- iterator+                                    Statement -- body+  | ForEachStatementWithReference   Bool -- isAwait+                                    SimpleIdentifier -- identifier+                                    Expression -- iterator+                                    Statement -- body+  -- | A while statement.+  --+  --      whileStatement ::=+  --          'while' '(' [Expression] ')' [Statement]+  | WhileStatement Expression -- condition+                   Statement -- body+  -- | A do statement.+  --+  --      doStatement ::=+  --          'do' [Statement] 'while' '(' [Expression] ')' ';'+  | DoStatement Statement -- body+                Expression -- condition+  -- | A switch statement.+  --+  --      switchStatement ::=+  --          'switch' '(' [Expression] ')' '{' [SwitchCase]* [SwitchDefault]? '}'+  | SwitchStatement Expression -- expression+                    [SwitchMember] -- members+  -- | An if statement.+  --+  --      ifStatement ::=+  --          'if' '(' [Expression] ')' [Statement] ('else' [Statement])?+  | IfStatement Expression -- condition+                Statement -- thenStatement+                (Maybe Statement) -- elseStatement+  -- | A try statement.+  --+  --      tryStatement ::=+  --          'try' [Block] ([CatchClause]+ finallyClause? | finallyClause)+  --+  --      finallyClause ::=+  --          'finally' [Block]+  | TryStatement Block -- body+                 [CatchClause] -- catchClauses+                 (Maybe Block) -- finallyBlock+  --   A break statement.+  --+  --      breakStatement ::=+  --          'break' [SimpleIdentifier]? ';'+  | BreakStatement (Maybe SimpleIdentifier) -- label+  -- | A continue statement.+  --+  --      continueStatement ::=+  --          'continue' [SimpleIdentifier]? ';'+  | ContinueStatement (Maybe SimpleIdentifier) -- label+  -- | A return statement.+  --+  --      returnStatement ::=+  --          'return' [Expression]? ';'+  | ReturnStatement (Maybe Expression) -- expression+  -- | An expression used as a statement.+  --+  --      expressionStatement ::=+  --          [Expression]? ';'+  | ExpressionStatement Expression -- expression+  -- | A [FunctionDeclaration] used as a statement.+  | FunctionDeclarationStatement FunctionDeclaration+  -- | An assert statement.+  --+  --      assertStatement ::=+  --          'assert' '(' [Expression] ')' ';'+  | AssertStatement Expression -- condition+                    (Maybe Expression) -- message+  -- | A yield statement.+  --+  --    yieldStatement ::=+  --        'yield' '*'? [Expression] ‘;’+  | YieldStatement Bool -- isStar+                   Expression -- expression+  -- | An empty statement.+  --+  --      emptyStatement ::=+  --          ';'+  | EmptyStatement+  -- | A statement that has a label associated with them.+  --+  --      labeledStatement ::=+  --         [Label]+ [Statement]+  | LabeledStatement [Label] -- labels+                     Statement -- statement+  deriving (Eq, Show, Typeable, Generic, Data)++-- | A compilation unit.+--+--   While the grammar restricts the order of the directives and declarations+--   within a compilation unit, this class does not enforce those restrictions.+--   In particular, the children of a compilation unit will be visited in lexical+--   order even if lexical order does not conform to the restrictions of the+--   grammar.+--+--      compilationUnit ::=+--          directives declarations+--+--      directives ::=+--          [ScriptTag]? [LibraryDirective]? namespaceDirective* [PartDirective]*+--        | [PartOfDirective]+--+--      namespaceDirective ::=+--          [ImportDirective]+--        | [ExportDirective]+--+--      declarations ::=+--          [CompilationUnitMember]*+data CompilationUnit = CompilationUnit (Maybe ScriptTag) -- scriptTag+                                       [Directive] -- directives+                                       [CompilationUnitMember] -- declarations+  deriving (Eq, Show, Typeable, Generic, Data)+
+ test/Spec.hs view
@@ -0,0 +1,434 @@+import Test.Hspec++import Language.Dart.Pretty+import Language.Dart.Syntax++intExp :: Integer -> Expression+intExp = Literal' . IntegerLiteral++ident :: String -> Identifier+ident = SimpleIdentifier' . SimpleIdentifier++identExp :: String -> Expression+identExp = Identifier' . ident++tyName :: String -> TypeName+tyName name = TypeName (ident name) Nothing++strType = tyName "String"+numType = tyName "num"++formal :: TypeName -> String -> FormalParameter+formal ty p = NormalFormalParameter' $+  SimpleFormalParameter Nothing [] (FVTType ty) (SimpleIdentifier p)++posFormal :: TypeName -> String -> FormalParameter+posFormal ty p = DefaultFormalParameter parameter Positional Nothing+  where parameter = (SimpleFormalParameter Nothing [] (FVTType ty) (SimpleIdentifier p))++var :: String -> FormalParameter+var p = NormalFormalParameter' $+  SimpleFormalParameter Nothing [] FVTVar (SimpleIdentifier p)++strLit :: String -> StringLiteral+strLit = SingleStringLiteral' .  SimpleStringLiteral++strLitExp :: String -> Expression+strLitExp = Literal' . StringLiteral' . strLit++nullExp :: Expression+nullExp = Literal' NullLiteral++funStmt :: String -> Statement+funStmt name = ExpressionStatement (+                 InvocationExpression (+                   MethodInvocation Nothing+                                    (SimpleIdentifier name)+                                    Nothing+                                    (ArgumentList [])))++funStmt1 :: String -> Expression -> Statement+funStmt1 name arg1 = ExpressionStatement (+                       InvocationExpression (+                         MethodInvocation Nothing+                                          (SimpleIdentifier name)+                                          Nothing+                                          (ArgumentList [arg1])))++prettyPrintSpec :: Spec+prettyPrintSpec =+  describe "prettyPrint" $ do+    it "preserves operator precedence" $ do+      let l = BinaryExpression (intExp 1) "+" (intExp 2)+          r = BinaryExpression (intExp 3) "-" (intExp 2)+          e = BinaryExpression l "*" r+      prettyPrint e `shouldBe` "(1 + 2) * (3 - 2)"++    it "prints an import directive" $ do+      let libraryUri = strLit "package:analyzer/src/dart/ast/ast.dart"+          as = SimpleIdentifier "a"+          imp = ImportDirective Nothing+                                []+                                libraryUri+                                []+                                False+                                (Just as)+                                [ ShowCombinator [SimpleIdentifier "TypeName"]+                                , ShowCombinator [SimpleIdentifier "ArgumentList"]+                                ]+      prettyPrint imp `shouldBe` "import \"package:analyzer/src/dart/ast/ast.dart\" as a show TypeName, show ArgumentList;"++    it "prints a function declaration" $ do+      let formals = FormalParameterList [formal numType "aNumber"]+          arg = Literal' . StringLiteral' . SingleStringLiteral' $+                  StringInterpolation [ InterpolationString "The number is "+                                      , InterpolationExpression (identExp "aNumber")+                                      , InterpolationString "."]+          body = BlockFunctionBody Sync+                                   (Block [ ExpressionStatement (+                                             InvocationExpression (+                                               MethodInvocation Nothing+                                                                (SimpleIdentifier "print")+                                                                Nothing+                                                                (ArgumentList [arg])))])+          funExp = FunctionExpression Nothing formals body+          funDecl = FunctionDeclaration Nothing [] False Nothing Empty (SimpleIdentifier "printNumber") funExp+      prettyPrint funDecl `shouldBe` "printNumber(num aNumber)\n\+                                     \{\n\+                                     \  print(\"The number is ${aNumber}.\");\n\+                                     \}"++    it "prints an optional position parameter" $ do+      let formals = FormalParameterList [formal strType "from", formal strType "msg", posFormal strType "device"]+          str1 = Literal' . StringLiteral' . SingleStringLiteral' $+                  StringInterpolation [ InterpolationExpression (identExp "from")+                                      , InterpolationString " says "+                                      , InterpolationExpression (identExp "msg")+                                      ]+          str2 = Literal' . StringLiteral' . SingleStringLiteral' $+                  StringInterpolation [ InterpolationExpression (identExp "result")+                                      , InterpolationString " with a "+                                      , InterpolationExpression (identExp "device")+                                      ]+          body = BlockFunctionBody Sync+                                   (Block [ VariableDeclarationStatement (+                                              VariableDeclarationList Nothing+                                                                      []+                                                                      FCVTVar+                                                                      [VariableDeclaration (SimpleIdentifier "result") (Just str1)])+                                          , IfStatement (BinaryExpression (identExp "device") "!=" nullExp)+                                                        (Block' (Block [ ExpressionStatement (+                                                                          AssignmentExpression (identExp "result") "=" str2)]))+                                                        Nothing+                                          , ReturnStatement (Just (identExp "result"))+                                          ])+          funExp = FunctionExpression Nothing formals body+          funDecl = FunctionDeclaration Nothing [] False (Just strType) Empty (SimpleIdentifier "say") funExp+      prettyPrint funDecl `shouldBe` "String say(String from, String msg, [String device])\n\+                                     \{\n\+                                     \  var result = \"${from} says ${msg}\";\n\+                                     \  if (device != null)\n\+                                     \  {\n\+                                     \    result = \"${result} with a ${device}\";\n\+                                     \  }\n\+                                     \  return result;\n\+                                     \}"++    it "prints an expression function" $ do+      let body = ExpressionFunctionBody False (+                  ConditionalExpression (BinaryExpression (identExp "msg") "==" nullExp)+                                        (InvocationExpression+                                          (MethodInvocation (Just SuperExpression)+                                                            (SimpleIdentifier "toString")+                                                            Nothing+                                                            (ArgumentList [])))+                                        (identExp "msg"))++          funExp = FunctionExpression Nothing (FormalParameterList []) body+          funDecl = FunctionDeclaration Nothing [] False (Just strType) Empty (SimpleIdentifier "toString") funExp+      prettyPrint funDecl `shouldBe` "String toString() => msg == null ? super.toString() : msg;"++    it "prints an enum" $ do+      let enumConstDecls = [ EnumConstantDeclaration Nothing [] (SimpleIdentifier "red")+                           , EnumConstantDeclaration Nothing [] (SimpleIdentifier "green")+                           , EnumConstantDeclaration Nothing [] (SimpleIdentifier "blue")+                           ]+          enumDecl = EnumDeclaration Nothing [] (SimpleIdentifier "Color") enumConstDecls+      prettyPrint enumDecl `shouldBe` "enum Color\n\+                                      \{\n\+                                      \  red,\n\+                                      \  green,\n\+                                      \  blue\n\+                                      \}"++    it "prints a for loop" $ do+      let variableList = VariableDeclarationList Nothing+                                                 []+                                                 FCVTVar+                                                 [VariableDeclaration (SimpleIdentifier "i") (Just (intExp 0))]+          condition = BinaryExpression (identExp "i") "<" (intExp 5)+          updater = PostfixExpression (identExp "i") "++"+          body = (Block' (Block [ ExpressionStatement (+                                    InvocationExpression (+                                      MethodInvocation (Just (identExp "message"))+                                                       (SimpleIdentifier "write")+                                                       Nothing+                                                       (ArgumentList [strLitExp "!"])))]))+          forLoop = ForStatement (Just variableList)+                                 Nothing+                                 (Just condition)+                                 [updater]+                                 body+      prettyPrint forLoop `shouldBe` "for (var i = 0; i < 5; i++)\n\+                                     \{\n\+                                     \  message.write(\"!\");\n\+                                     \}"++    it "prints a list literal" $ do+      let litExp = Literal' . TypedLiteral $ ListLiteral False Nothing [intExp 0, intExp 1, intExp 2]+      prettyPrint litExp `shouldBe` "[0, 1, 2]"++    it "prints parameterized types" $ do+      let consName = ConstructorName (TypeName (SimpleIdentifier' (SimpleIdentifier "Map"))+                                               (Just (TypeArgumentList [tyName "int", tyName "View"])))+                                     Nothing+      let exp = InstanceCreationExpression NCNew consName (ArgumentList [])+      prettyPrint exp `shouldBe` "new Map<int, View>()"++    it "prints a switch statement" $ do+      let switchMembers = [ SwitchCase [] (strLitExp "CLOSED") [funStmt "executeClosed", (BreakStatement Nothing)]+                          , SwitchCase [] (strLitExp "PENDING") [funStmt "executePending", (BreakStatement Nothing)]+                          , SwitchCase [] (strLitExp "APPROVED") [funStmt "executeApproved", (BreakStatement Nothing)]+                          , SwitchCase [] (strLitExp "DENIED") [funStmt "executeDenied", (BreakStatement Nothing)]+                          , SwitchCase [] (strLitExp "OPEN") [funStmt "executeOpen", (BreakStatement Nothing)]+                          , SwitchDefault [] [funStmt "executeUnknown"]+                          ]+          switch = SwitchStatement (identExp "command") switchMembers+      prettyPrint switch `shouldBe` "switch (command)\n\+                                    \{\n\+                                    \  case \"CLOSED\":\n\+                                    \    executeClosed();\n\+                                    \    break;\n\+                                    \  case \"PENDING\":\n\+                                    \    executePending();\n\+                                    \    break;\n\+                                    \  case \"APPROVED\":\n\+                                    \    executeApproved();\n\+                                    \    break;\n\+                                    \  case \"DENIED\":\n\+                                    \    executeDenied();\n\+                                    \    break;\n\+                                    \  case \"OPEN\":\n\+                                    \    executeOpen();\n\+                                    \    break;\n\+                                    \  default:\n\+                                    \    executeUnknown();\n\+                                    \}"++    it "prints a try statement" $ do+      let arg = Literal' . StringLiteral' . SingleStringLiteral' $+                  StringInterpolation [ InterpolationString "Error: "+                                      , InterpolationExpression (identExp "e")+                                      ]+          try = TryStatement (Block [funStmt "breedMoreLlamas"])+                             [CatchClause Nothing (SimpleIdentifier "e") Nothing (Block [funStmt1 "print" arg])]+                             (Just (Block [funStmt "cleanLlamaStalls"]))+      prettyPrint try `shouldBe` "try\n\+                                 \{\n\+                                 \  breedMoreLlamas();\n\+                                 \}\n\+                                 \catch (e)\n\+                                 \{\n\+                                 \  print(\"Error: ${e}\");\n\+                                 \}\n\+                                 \finally\n\+                                 \{\n\+                                 \  cleanLlamaStalls();\n\+                                 \}"++    it "prints a constructor" $ do+      let varDeclList ty name = VariableDeclarationList Nothing+                                                        []+                                                        (FCVTType (tyName ty))+                                                        [VariableDeclaration (SimpleIdentifier name) Nothing]++          returnType = SimpleIdentifier' (SimpleIdentifier "Point")+          consFormals1 = FormalParameterList [ NormalFormalParameter' (FieldFormalParameter Nothing [] Nothing True (SimpleIdentifier "x"))+                                             , NormalFormalParameter' (FieldFormalParameter Nothing [] Nothing True (SimpleIdentifier "y"))+                                             ]+          consFormals2 = FormalParameterList [ NormalFormalParameter' (+                                                 FieldFormalParameter Nothing+                                                                      []+                                                                      (Just (FCVTType (tyName "Map")))+                                                                      False+                                                                      (SimpleIdentifier "json"))+                                             ]+          methodFormals = FormalParameterList [ NormalFormalParameter' (+                                                  FieldFormalParameter Nothing+                                                                       []+                                                                       (Just (FCVTType (tyName "Point")))+                                                                       False+                                                                       (SimpleIdentifier "other"))+                                              ]+          consBody = BlockFunctionBody Sync+                                   (Block [ ExpressionStatement (+                                              AssignmentExpression (identExp "x")+                                                                   "="+                                                                   (IndexExpressionForTarget (identExp "json") (strLitExp "x")))+                                          , ExpressionStatement (+                                              AssignmentExpression (identExp "y")+                                                                   "="+                                                                   (IndexExpressionForTarget (identExp "json") (strLitExp "y")))+                                          ])+          exp1 = BinaryExpression (identExp "x") "-" (PropertyAccess (identExp "other") (SimpleIdentifier "x"))+          exp2 = BinaryExpression (identExp "y") "-" (PropertyAccess (identExp "other") (SimpleIdentifier "y"))+          methodBody = BlockFunctionBody Sync+                                   (Block [ VariableDeclarationStatement (+                                              VariableDeclarationList Nothing+                                                                      []+                                                                      FCVTVar+                                                                      [VariableDeclaration (SimpleIdentifier "dx") (Just exp1)])+                                          , VariableDeclarationStatement (+                                              VariableDeclarationList Nothing+                                                                      []+                                                                      FCVTVar+                                                                      [VariableDeclaration (SimpleIdentifier "dy") (Just exp2)])+                                          , ReturnStatement (Just (+                                              InvocationExpression (+                                                MethodInvocation Nothing+                                                                 (SimpleIdentifier "sqrt")+                                                                 Nothing+                                                                 (ArgumentList [BinaryExpression (BinaryExpression (identExp "dx") "*" (identExp "dx"))+                                                                                                 "+"+                                                                                                 (BinaryExpression (identExp "dy") "*" (identExp "dy"))]))))+                                          ])+          classMembers = [ FieldDeclaration Nothing [] False (varDeclList "num" "x")+                         , FieldDeclaration Nothing [] False (varDeclList "num" "y")+                         , ConstructorDeclaration Nothing [] False False False returnType Nothing consFormals1 [] Nothing Nothing+                         , ConstructorDeclaration Nothing [] False False False returnType (Just (SimpleIdentifier "fromJson")) consFormals2 [] Nothing (Just consBody)+                         , MethodDeclaration Nothing [] False Nothing (Just (tyName "num")) Empty False (SimpleIdentifier "distanceTo") Nothing (Just methodFormals) methodBody+                         ]+          clazz = ClassDeclaration Nothing+                                   []+                                   False+                                   (SimpleIdentifier "Point")+                                   Nothing+                                   Nothing+                                   Nothing+                                   Nothing+                                   classMembers+      prettyPrint clazz `shouldBe` "class Point\n\+                                   \{\n\+                                   \  num x;\n\+                                   \  num y;\n\+                                   \  Point(this.x, this.y);\n\+                                   \  Point.fromJson(Map json)\n\+                                   \  {\n\+                                   \    x = json[\"x\"];\n\+                                   \    y = json[\"y\"];\n\+                                   \  }\n\+                                   \  num distanceTo(Point other)\n\+                                   \  {\n\+                                   \    var dx = x - other.x;\n\+                                   \    var dy = y - other.y;\n\+                                   \    return sqrt(dx * dx + dy * dy);\n\+                                   \  }\n\+                                   \}"++    it "prints the initializer lists of a constructor" $ do+      let varDeclList ty name = VariableDeclarationList Nothing+                                                        []+                                                        (FCVTType (tyName ty))+                                                        [VariableDeclaration (SimpleIdentifier name) Nothing]+          returnType = SimpleIdentifier' (SimpleIdentifier "Point")+          formals = FormalParameterList [ NormalFormalParameter' (FieldFormalParameter Nothing [] Nothing True (SimpleIdentifier "x"))+                                        , NormalFormalParameter' (FieldFormalParameter Nothing [] Nothing True (SimpleIdentifier "y"))+                                        ]+          exp = InvocationExpression (+                 MethodInvocation Nothing+                                  (SimpleIdentifier "sqrt")+                                  Nothing+                                  (ArgumentList [BinaryExpression (BinaryExpression (identExp "x") "*" (identExp "x"))+                                                                  "+"+                                                                  (BinaryExpression (identExp "y") "*" (identExp "y"))]))+          classMembers = [ FieldDeclaration Nothing [] False (varDeclList "num" "x")+                         , FieldDeclaration Nothing [] False (varDeclList "num" "y")+                         , FieldDeclaration Nothing [] False (varDeclList "num" "distanceFromOrigin")+                         , ConstructorDeclaration Nothing+                                                  []+                                                  False+                                                  False+                                                  False+                                                  returnType+                                                  Nothing+                                                  formals+                                                  [ ConstructorFieldInitializer False (SimpleIdentifier "x") (identExp "x")+                                                  , ConstructorFieldInitializer False (SimpleIdentifier "y") (identExp "y")+                                                  , ConstructorFieldInitializer False (SimpleIdentifier "distanceFromOrigin") exp+                                                  ]+                                                  Nothing+                                                  Nothing+                         ]+          clazz = ClassDeclaration Nothing+                                   []+                                   False+                                   (SimpleIdentifier "Point")+                                   Nothing+                                   Nothing+                                   Nothing+                                   Nothing+                                   classMembers++      prettyPrint clazz `shouldBe` "class Point\n\+                                   \{\n\+                                   \  num x;\n\+                                   \  num y;\n\+                                   \  num distanceFromOrigin;\n\+                                   \  Point(this.x, this.y) : x = x,\n\+                                   \                          y = y,\n\+                                   \                          distanceFromOrigin = sqrt(x * x + y * y);\n\+                                   \}"++    it "prints the implement clause" $ do+      let implements = ImplementsClause [tyName "Comparable", tyName "Location"]+          clazz = ClassDeclaration Nothing+                                   []+                                   False+                                   (SimpleIdentifier "Point")+                                   Nothing+                                   Nothing+                                   Nothing+                                   (Just implements)+                                   []+      prettyPrint clazz `shouldBe` "class Point implements Comparable, Location\n\+                                  \{\n\+                                  \}"++    it "prints the metadata" $ do+      let annotation = Annotation (SimpleIdentifier' (SimpleIdentifier "override")) Nothing Nothing+          methodFormals = FormalParameterList [ NormalFormalParameter' (+                                                  FieldFormalParameter Nothing+                                                                       []+                                                                       (Just (FCVTType (tyName "Invocation")))+                                                                       False+                                                                       (SimpleIdentifier "mirror"))+                                              ]+          methodDecl = MethodDeclaration Nothing+                                         [annotation]+                                         False+                                         Nothing+                                         (Just (tyName "void"))+                                         Empty+                                         False+                                         (SimpleIdentifier "noSuchMethod")+                                         Nothing+                                         (Just methodFormals)+                                         (BlockFunctionBody Sync (Block []))+      prettyPrint methodDecl `shouldBe` "@override\n\+                                        \void noSuchMethod(Invocation mirror)\n\+                                        \{\n\+                                        \}"++main :: IO ()+main = hspec $ do+  prettyPrintSpec