summaryrefslogtreecommitdiff
path: root/compiler/GHC/Driver/Main.hs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/GHC/Driver/Main.hs')
-rw-r--r--compiler/GHC/Driver/Main.hs37
1 files changed, 37 insertions, 0 deletions
diff --git a/compiler/GHC/Driver/Main.hs b/compiler/GHC/Driver/Main.hs
index 80d50a4589..26647df369 100644
--- a/compiler/GHC/Driver/Main.hs
+++ b/compiler/GHC/Driver/Main.hs
@@ -239,6 +239,7 @@ import GHC.Data.Maybe
import GHC.Driver.Env.KnotVars
import GHC.Types.Name.Set (NonCaffySet)
import GHC.Driver.GenerateCgIPEStub (generateCgIPEStub)
+import Data.List.NonEmpty (NonEmpty ((:|)))
{- **********************************************************************
@@ -411,6 +412,17 @@ hscParse' mod_summary
Nothing -> liftIO $ hGetStringBuffer src_filename
let loc = mkRealSrcLoc (mkFastString src_filename) 1 1
+
+ let diag_opts = initDiagOpts dflags
+ when (wopt Opt_WarnUnicodeBidirectionalFormatCharacters dflags) $ do
+ case checkBidirectionFormatChars (PsLoc loc (BufPos 0)) buf of
+ Nothing -> pure ()
+ Just chars@((eloc,chr,_) :| _) ->
+ let span = mkSrcSpanPs $ mkPsSpan eloc (advancePsLoc eloc chr)
+ in logDiagnostics $ singleMessage $
+ mkPlainMsgEnvelope diag_opts span $
+ GhcPsMessage $ PsWarnBidirectionalFormatChars chars
+
let parseMod | HsigFile == ms_hsc_src mod_summary
= parseSignature
| otherwise = parseModule
@@ -469,9 +481,34 @@ hscParse' mod_summary
hsc_env <- getHscEnv
withPlugins hsc_env applyPluginAction res
+checkBidirectionFormatChars :: PsLoc -> StringBuffer -> Maybe (NonEmpty (PsLoc, Char, String))
+checkBidirectionFormatChars start_loc sb
+ | containsBidirectionalFormatChar sb = Just $ go start_loc sb
+ | otherwise = Nothing
+ where
+ go :: PsLoc -> StringBuffer -> NonEmpty (PsLoc, Char, String)
+ go loc sb
+ | atEnd sb = panic "checkBidirectionFormatChars: no char found"
+ | otherwise = case nextChar sb of
+ (chr, sb)
+ | Just desc <- lookup chr bidirectionalFormatChars ->
+ (loc, chr, desc) :| go1 (advancePsLoc loc chr) sb
+ | otherwise -> go (advancePsLoc loc chr) sb
+
+ go1 :: PsLoc -> StringBuffer -> [(PsLoc, Char, String)]
+ go1 loc sb
+ | atEnd sb = []
+ | otherwise = case nextChar sb of
+ (chr, sb)
+ | Just desc <- lookup chr bidirectionalFormatChars ->
+ (loc, chr, desc) : go1 (advancePsLoc loc chr) sb
+ | otherwise -> go1 (advancePsLoc loc chr) sb
+
-- -----------------------------------------------------------------------------
-- | If the renamed source has been kept, extract it. Dump it if requested.
+
+
extract_renamed_stuff :: ModSummary -> TcGblEnv -> Hsc RenamedStuff
extract_renamed_stuff mod_summary tc_result = do
let rn_info = getRenamedStuff tc_result