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 +3/−0
- LICENSE +30/−0
- README.md +5/−0
- Setup.hs +2/−0
- language-dart.cabal +38/−0
- src/Language/Dart/Pretty.hs +754/−0
- src/Language/Dart/Syntax.hs +1325/−0
- test/Spec.hs +434/−0
+ 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++[](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* '*/'+--+-- documentationComment ::=+-- '/-- *' (CHARACTER | [CommentReference])* '*/'+-- | ('///' (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