------------------------------------------------------------------------------- |-- Module : Language.Haskell.Exts-- Copyright : (c) Niklas Broberg 2004-2009-- License : BSD-style (see the file LICENSE.txt)---- Maintainer : Niklas Broberg, d00nibro@chalmers.se-- Stability : stable-- Portability : portable---- An umbrella module for the various functionality-- of the package. Also provides some convenient-- functionality for dealing directly with source files.-------------------------------------------------------------------------------moduleLanguage.Haskell.Exts(-- * Re-exported modulesmoduleLanguage.Haskell.Exts.Syntax,moduleLanguage.Haskell.Exts.Build,moduleLanguage.Haskell.Exts.Lexer,moduleLanguage.Haskell.Exts.Pretty,moduleLanguage.Haskell.Exts.Fixity,moduleLanguage.Haskell.Exts.ExactPrint,moduleLanguage.Haskell.Exts.SrcLoc,moduleLanguage.Haskell.Exts.Comments,moduleLanguage.Haskell.Exts.Extension,moduleLanguage.Haskell.Exts.Parser-- * Parsing of Haskell source files,parseFile,parseFileWithMode,parseFileWithExts,parseFileWithComments,parseFileWithCommentsAndPragmas,parseFileContents,parseFileContentsWithMode,parseFileContentsWithExts,parseFileContentsWithComments-- * Read extensions declared in LANGUAGE pragmas,readExtensions)whereimportLanguage.Haskell.Exts.BuildimportLanguage.Haskell.Exts.CommentsimportLanguage.Haskell.Exts.ParserimportLanguage.Haskell.Exts.SyntaximportLanguage.Haskell.Exts.Lexer(lexTokenStream,lexTokenStreamWithMode,Token(..))importLanguage.Haskell.Exts.PrettyimportLanguage.Haskell.Exts.FixityimportLanguage.Haskell.Exts.ExactPrintimportLanguage.Haskell.Exts.SrcLocimportLanguage.Haskell.Exts.ExtensionimportData.ListimportData.Maybe(fromMaybe)importLanguage.Preprocessor.UnlitimportSystem.IO-- | Parse a source file on disk, using the default parse mode.parseFile::FilePath->IO(ParseResult(ModuleSrcSpanInfo))parseFilefp=parseFileWithMode(defaultParseMode{parseFilename=fp})fp-- | Parse a source file on disk, with an extra set of extensions to know about-- on top of what the file itself declares.parseFileWithExts::[Extension]->FilePath->IO(ParseResult(ModuleSrcSpanInfo))parseFileWithExtsextsfp=parseFileWithMode(defaultParseMode{extensions=exts,parseFilename=fp})fp-- | Parse a source file on disk, supplying a custom parse mode.parseFileWithMode::ParseMode->FilePath->IO(ParseResult(ModuleSrcSpanInfo))parseFileWithModepfp=readUTF8Filefp>>=return.parseFileContentsWithModepparseFileWithComments::ParseMode->FilePath->IO(ParseResult(ModuleSrcSpanInfo,[Comment]))parseFileWithCommentspfp=readUTF8Filefp>>=return.parseFileContentsWithCommentsp-- | Parse a source file on disk, supplying a custom parse mode, and retaining comments-- as well as unknown pragmas.parseFileWithCommentsAndPragmas::ParseMode->FilePath->IO(ParseResult(ModuleSrcSpanInfo,[Comment],[UnknownPragma]))parseFileWithCommentsAndPragmaspfp=readUTF8Filefp>>=return.parseFileContentsWithCommentsAndPragmasp-- | Parse a source file from a string using a custom parse mode retaining comments-- as well as unknown pragmas.parseFileContentsWithCommentsAndPragmas::ParseMode->String->ParseResult(ModuleSrcSpanInfo,[Comment],[UnknownPragma])parseFileContentsWithCommentsAndPragmaspmodestr=separatePragmasparseResultwhereparseResult=parseFileContentsWithCommentspmodestr-- | Parse a source file from a string using the default parse mode.parseFileContents::String->ParseResult(ModuleSrcSpanInfo)parseFileContents=parseFileContentsWithModedefaultParseMode-- | Parse a source file from a string, with an extra set of extensions to know about-- on top of what the file itself declares.parseFileContentsWithExts::[Extension]->String->ParseResult(ModuleSrcSpanInfo)parseFileContentsWithExtsexts=parseFileContentsWithMode(defaultParseMode{extensions=exts})-- | Parse a source file from a string using a custom parse mode.parseFileContentsWithMode::ParseMode->String->ParseResult(ModuleSrcSpanInfo)parseFileContentsWithModep@(ParseModefnoldLangextsign___)rawStr=letmd=delitfn$ppContentsrawStr(bLang,extraExts)=case(ign,readExtensionsmd)of(False,Just(mLang,es))->(fromMaybeoldLangmLang,es)_->(oldLang,[])in-- trace (fn ++ ": " ++ show extraExts) $parseModuleWithMode(p{baseLanguage=bLang,extensions=exts++extraExts})mdparseFileContentsWithComments::ParseMode->String->ParseResult(ModuleSrcSpanInfo,[Comment])parseFileContentsWithCommentsp@(ParseModefnoldLangextsign___)rawStr=letmd=delitfn$ppContentsrawStr(bLang,extraExts)=case(ign,readExtensionsmd)of(False,Just(mLang,es))->(fromMaybeoldLangmLang,es)_->(oldLang,[])inparseModuleWithComments(p{baseLanguage=bLang,extensions=exts++extraExts})md-- | Gather the extensions declared in LANGUAGE pragmas-- at the top of the file. Returns 'Nothing' if the-- parse of the pragmas fails.readExtensions::String->Maybe(MaybeLanguage,[Extension])readExtensionsstr=casegetTopPragmasstrofParseOkpgms->extractLang$concatMapgetExtspgms_->NothingwheregetExts::ModulePragmal->[EitherLanguageExtension]getExts(LanguagePragma_ns)=mapreadExtnsgetExts_=[]readExt(Ident_e)=caseclassifyLanguageeofUnknownLanguage_->Right$classifyExtensionelang->LeftlangreadExtSymbol{}=error"readExt: Symbol"extractLang=extractLang'Nothing[]extractLang'lacceacc[]=Just(lacc,eacc)extractLang'Nothingeacc(Leftl:rest)=extractLang'(Justl)eaccrestextractLang'(Justl1)eacc(Leftl2:rest)|l1==l2=extractLang'(Justl1)eaccrest|otherwise=NothingextractLang'lacceacc(Rightext:rest)=extractLang'lacc(ext:eacc)restppContents::String->StringppContents=unlines.f.lineswheref(('#':_):rest)=restfx=xdelit::String->String->Stringdelitfn=if".lhs"`isSuffixOf`fnthenunlitfnelseidreadUTF8File::FilePath->IOStringreadUTF8Filefp=doh<-openFilefpReadModehSetEncodinghutf8hGetContentsh-- | Converts a parse result with comments to a parse result with comments and-- unknown pragmas.separatePragmas::ParseResult(ModuleSrcSpanInfo,[Comment])->ParseResult(ModuleSrcSpanInfo,[Comment],[UnknownPragma])separatePragmasr=caserofParseOk(m,comments)->let(pragmas,comments')=partitionpragLikecommentsinParseOk(m,comments',mapcommentToPragmapragmas)wherecommentToPragma(Comment_ls)=UnknownPragmal$init$drop1spragLike(Commentb_s)=b&&pcondspconds=lengths>1&&take1s=="#"&&lasts=='#'ParseFailedls->ParseFailedls