mirror of
https://github.com/github/semantic.git
synced 2024-12-01 09:15:01 +03:00
Merge pull request #1283 from github/fine-grained-python-error-handling
Fine-grained Python error handling
This commit is contained in:
commit
f7ae07e3d9
@ -5,6 +5,7 @@ import Data.Blob
|
||||
import Data.ByteString (isSuffixOf)
|
||||
import Data.ByteString.Char8 (pack, unpack)
|
||||
import Data.Ix (inRange)
|
||||
import Data.List (intersperse)
|
||||
import Data.List.NonEmpty (nonEmpty)
|
||||
import Data.Semigroup
|
||||
import Data.Source
|
||||
@ -40,7 +41,7 @@ formatError includeSource colourize Blob{..} Error{..}
|
||||
then showString (unpack context) . (if "\n" `isSuffixOf` context then id else showChar '\n')
|
||||
. showString (replicate (succ (posColumn (spanStart errorSpan) + lineNumberDigits)) ' ') . withSGRCode colourize [SetColor Foreground Vivid Green] (showChar '^' . showChar '\n')
|
||||
else id)
|
||||
. showString (prettyCallStack callStack) . showChar '\n'
|
||||
. showCallStack colourize callStack . showChar '\n'
|
||||
where context = maybe "\n" (sourceBytes . sconcat) (nonEmpty [ fromBytes (pack (showLineNumber i)) <> fromBytes ": " <> l | (i, l) <- zip [1..] (sourceLines blobSource), inRange (posLine (spanStart errorSpan) - 2, posLine (spanStart errorSpan)) i ])
|
||||
showLineNumber n = let s = show n in replicate (lineNumberDigits - length s) ' ' <> s
|
||||
lineNumberDigits = succ (floor (logBase 10 (fromIntegral (posLine (spanStart errorSpan)) :: Double)))
|
||||
@ -73,3 +74,9 @@ showSymbols colourize = go
|
||||
showSpan :: Maybe FilePath -> Span -> ShowS
|
||||
showSpan path Span{..} = maybe (showParen True (showString "interactive")) showString path . showChar ':' . (if spanStart == spanEnd then showPos spanStart else showPos spanStart . showChar '-' . showPos spanEnd)
|
||||
where showPos Pos{..} = shows posLine . showChar ':' . shows posColumn
|
||||
|
||||
showCallStack :: Colourize -> CallStack -> ShowS
|
||||
showCallStack colourize callStack = foldr (.) id (intersperse (showChar '\n') (uncurry (showCallSite colourize) <$> getCallStack callStack))
|
||||
|
||||
showCallSite :: Colourize -> String -> SrcLoc -> ShowS
|
||||
showCallSite colourize symbol SrcLoc{..} = showString symbol . showChar ' ' . withSGRCode colourize [SetConsoleIntensity BoldIntensity] (showParen True (showSpan (Just srcLocFile) (Span (Pos srcLocStartLine srcLocStartCol) (Pos srcLocEndLine srcLocEndCol))))
|
||||
|
@ -12,9 +12,8 @@ import Data.Functor (void)
|
||||
import Data.Functor.Classes.Eq.Generic
|
||||
import Data.Functor.Classes.Show.Generic
|
||||
import Data.Maybe (fromMaybe)
|
||||
import Data.Tuple (swap)
|
||||
import Data.Record
|
||||
import Data.Syntax (emptyTerm, makeTerm, parseError)
|
||||
import Data.Syntax (emptyTerm, handleError, makeTerm)
|
||||
import qualified Data.Syntax as Syntax
|
||||
import Data.Syntax.Assignment hiding (Assignment, Error)
|
||||
import qualified Data.Syntax.Assignment as Assignment
|
||||
@ -102,10 +101,10 @@ instance Show1 Redirect where liftShowsPrec = genericLiftShowsPrec
|
||||
|
||||
-- | Assignment from AST in Python's grammar onto a program in Python's syntax.
|
||||
assignment :: Assignment
|
||||
assignment = makeTerm <$> symbol Module <*> children (Syntax.Program <$> many expression) <|> parseError
|
||||
assignment = handleError $ makeTerm <$> symbol Module <*> children (Syntax.Program <$> many expression)
|
||||
|
||||
expression :: Assignment
|
||||
expression =
|
||||
expression = handleError $
|
||||
argument
|
||||
<|> argumentList
|
||||
<|> assertStatement
|
||||
@ -142,7 +141,6 @@ expression =
|
||||
<|> nonlocalStatement
|
||||
<|> notOperator
|
||||
<|> parameter
|
||||
<|> parseError
|
||||
<|> passStatement
|
||||
<|> printStatement
|
||||
<|> raiseStatement
|
||||
@ -208,16 +206,16 @@ argumentList :: Assignment
|
||||
argumentList = makeTerm <$> symbol ArgumentList <*> children (many expression)
|
||||
|
||||
withStatement :: Assignment
|
||||
withStatement = symbol WithStatement >>= \ loc -> children (mk loc <$> some with)
|
||||
withStatement = mk <$> symbol WithStatement <*> children (some with)
|
||||
where
|
||||
mk _ [child] = child
|
||||
mk l children = makeTerm l children
|
||||
with = makeTerm <$> location <*> (uncurry Statement.Let . swap <$> withItem <*> expressions)
|
||||
withItem = (symbol WithItem *> children ((,) <$> expression <*> (expression <|> emptyTerm)))
|
||||
<|> ((,) <$> expression <*> emptyTerm)
|
||||
with = makeTerm <$> location <*> (withItem <*> (makeTerm <$> location <*> manyTill expression (void (symbol WithItem) <|> eof)))
|
||||
withItem = symbol WithItem *> children (flip Statement.Let <$> expression <*> (expression <|> emptyTerm))
|
||||
<|> flip Statement.Let <$> expression <*> emptyTerm
|
||||
|
||||
forStatement :: Assignment
|
||||
forStatement = symbol ForStatement >>= \ loc -> children (make loc <$> (makeTerm <$> symbol Variables <*> children (many expression)) <*> expressionList <*> expressions <*> optional (makeTerm <$> symbol ElseClause <*> children (many expression)))
|
||||
forStatement = symbol ForStatement >>= \ loc -> children (make loc <$> (makeTerm <$> symbol Variables <*> children (many expression)) <*> expressionList <*> (makeTerm <$> location <*> manyTill expression (void (symbol ElseClause) <|> eof)) <*> optional (makeTerm <$> symbol ElseClause <*> children (many expression)))
|
||||
where
|
||||
make loc binding subject body forElseClause = case forElseClause of
|
||||
Nothing -> makeTerm loc (Statement.ForEach binding subject body)
|
||||
@ -353,7 +351,7 @@ set = makeTerm <$> symbol Set <*> children (Literal.Set <$> many expression)
|
||||
|
||||
dictionary :: Assignment
|
||||
dictionary = makeTerm <$> symbol Dictionary <*> children (Literal.Hash <$> many (pair <|> comment))
|
||||
where pair = makeTerm <$> symbol Pair <*> children (Literal.KeyValue <$> expression <*> expression)
|
||||
where pair = makeTerm <$> symbol Pair <*> children (Literal.KeyValue <$ many comment <*> expression <* many comment <*> expression <* many comment)
|
||||
|
||||
list' :: Assignment
|
||||
list' = makeTerm <$> symbol List <*> children (Literal.Array <$> many expression)
|
||||
@ -378,7 +376,6 @@ import' = makeTerm <$> symbol ImportStatement <*> children (Declaration.Import
|
||||
<|> makeTerm <$> symbol ImportFromStatement <*> children (Declaration.Import <$> many expression)
|
||||
<|> makeTerm <$> symbol AliasedImport <*> children (flip Statement.Let <$> expression <*> expression <*> emptyTerm)
|
||||
<|> makeTerm <$> symbol WildcardImport <*> (Syntax.Identifier <$> source)
|
||||
<|> parseError
|
||||
|
||||
assertStatement :: Assignment
|
||||
assertStatement = makeTerm <$ symbol AssertStatement <*> location <*> children (Expression.Call <$> (makeTerm <$> symbol AnonAssert <*> (Syntax.Identifier <$> source)) <*> many expression <*> emptyTerm)
|
||||
|
Loading…
Reference in New Issue
Block a user