Skip to content

Commit 88d5e3b

Browse files
committed
Change the types in Resolve, improve printing of tokentrees
* Resolve now supports tracking multiple errors/warnings/corrections (instead of stopping at the first one), and each such message is accompanied with a list of increasingly zoomed out syntax trees (to help you locate the problem in your initial syntax tree). * Printing macros and attributes is now much nicer: these will automatically remove spaces between tokens when those spaces are not needed and make things less pretty. That means that we now print #[derive(PartialOrd, PartialEq, Ord, Eq)] instead of #[derive ( PartialOrd , PartialEq , Ord , Eq )] * Experimented with an 'Annotated' class that can be derived. It could be nicer to use that instead of manually writing out all of the 'Located' instances.
1 parent 845e631 commit 88d5e3b

File tree

10 files changed

+994
-532
lines changed

10 files changed

+994
-532
lines changed

language-rust.cabal

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ library
5151
Language.Rust.Pretty.Literals
5252
Language.Rust.Pretty.Util
5353
Language.Rust.Syntax.AST
54+
Language.Rust.Syntax.Annotated
5455
Language.Rust.Syntax.Ident
5556
Language.Rust.Syntax.Token
5657

src/Language/Rust/Data/Position.hs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Portability : portable
99
1010
Everything to do with describing a position or a contiguous region in a file.
1111
-}
12-
{-# LANGUAGE DeriveDataTypeable, DeriveGeneric, CPP, DeriveAnyClass #-}
12+
{-# LANGUAGE DeriveDataTypeable, DeriveGeneric, CPP, UndecidableInstances, PolyKinds, DeriveAnyClass #-}
1313

1414
module Language.Rust.Data.Position (
1515
-- * Positions in files
@@ -19,6 +19,7 @@ module Language.Rust.Data.Position (
1919
) where
2020

2121
import GHC.Generics (Generic)
22+
2223
import Data.Data (Data)
2324
import Data.Typeable (Typeable)
2425
import Control.DeepSeq (NFData)
@@ -162,3 +163,4 @@ instance Located a => Located [a] where
162163
instance Located a => Located (NonEmpty a) where
163164
spanOf = foldMap spanOf
164165

166+

src/Language/Rust/Parser/Internal.y

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1167,13 +1167,27 @@ vis_safety_block :: { Expr Span }
11671167
}
11681168
11691169
1170+
{-
1171+
-- TODO: Just uncommenting these rules (without using them anywhere), causes everything to start failing
1172+
1173+
vis_union_nonblock_expr :: { Expr Span }
1174+
: union_expr { $1 }
1175+
| gen_expression_block(vis_union_nonblock_expr, expr, expr) { $1 }
1176+
1177+
union_expr :: { Expr Span }
1178+
: pub_or_inherited union {%
1179+
noVis $1 (PathExpr [] Nothing (Path False [("union", NoParameters mempty)] (spanOf $1)) (spanOf $1))
1180+
}
1181+
-}
1182+
11701183
stmt :: { Stmt Span }
11711184
: ntStmt { $1 }
11721185
| many(outer_attribute) let pat ':' ty initializer ';' { Local $3 (Just $5) $6 $1 ($1 # $2 # $>) }
11731186
| many(outer_attribute) let pat initializer ';' { Local $3 Nothing $4 $1 ($1 # $2 # $>) }
11741187
| many(outer_attribute) nonblock_expr ';' { toStmt ($1 `addAttrs` $2) True False ($1 # $2 # $3) }
11751188
| many(outer_attribute) block_like_expr ';' { toStmt ($1 `addAttrs` $2) True True ($1 # $2 # $3) }
11761189
| many(outer_attribute) postfix_block_expr ';' { toStmt ($1 `addAttrs` $2) True True ($1 # $2 # $3) }
1190+
-- | many(outer_attribute) vis_union_nonblock_expr ';' { toStmt ($1 `addAttrs` $2) True False ($1 # $2 # $3) }
11771191
| many(outer_attribute) block_like_expr %prec NOSEMI { toStmt ($1 `addAttrs` $2) False True ($1 # $2) }
11781192
| many(outer_attribute) vis_safety_block ';' { toStmt ($1 `addAttrs` $2) True True ($1 # $2 # $>) }
11791193
| many(outer_attribute) vis_safety_block %prec NOSEMI { toStmt ($1 `addAttrs` $2) False True ($1 # $2) }

src/Language/Rust/Pretty/Internal.hs

Lines changed: 44 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,9 @@ import Language.Rust.Syntax.Ident
3535
import Language.Rust.Pretty.Util
3636
import Data.Text.Prettyprint.Doc hiding ((<+>), hsep, indent, vsep)
3737

38-
import Data.Maybe (maybeToList)
38+
import Data.Maybe (maybeToList, fromMaybe)
3939
import Data.Foldable (toList)
40+
import Data.List (unfoldr)
4041
import Data.List.NonEmpty (NonEmpty(..))
4142
import qualified Data.List.NonEmpty as N
4243

@@ -88,24 +89,53 @@ printMac (Mac path ts x) d = annotate x (printPath path False <> "!" <> body)
8889
where body = block d True mempty mempty [ printTokenStream ts ]
8990

9091
-- | Given two positions, find out how to print appropriate amounts of space between them
91-
printSpaceBetween :: Span -> Span -> Doc a
92-
printSpaceBetween (Span _ (Position _ y1 x1)) (Span (Position _ y2 x2) _)
93-
| y2 == y1 = hcat (replicate (x2 - x1) space)
94-
| y2 > y1 = hcat (replicate (y2 - y1) line) <> column (\x1' -> hcat (replicate (x2 - x1') space))
95-
| otherwise = space
96-
printSpaceBetween _ _ = space
92+
printSpaceBetween :: Bool -> Span -> Span -> Maybe (Doc a)
93+
printSpaceBetween spaceNeeded (Span _ (Position _ y1 x1)) (Span (Position _ y2 x2) _)
94+
| y2 == y1 && x2 > x1 = Just $ hcat (replicate (x2 - x1) space)
95+
| y2 > y1 = Just $ hcat (replicate (y2 - y1) line) <> column (\x1' -> hcat (replicate (x2 - x1') space))
96+
| spaceNeeded = Just space
97+
| otherwise = Just mempty
98+
printSpaceBetween _ _ _ = Nothing
9799

98100
-- | Print a token tree (@print_tt@)
99101
printTt :: TokenTree -> Doc a
100102
printTt (Token _ t) = printToken t
101103
printTt (Delimited _ d ts) = block d True mempty mempty [ printTokenStream ts ]
102104

103-
-- | Print a list of token streams, with the right amount of space between successive elements
104-
printTokenStreams :: [TokenStream] -> Doc a
105-
printTokenStreams [] = mempty
106-
printTokenStreams [ts] = printTokenStream ts
107-
printTokenStreams (ts1:ts2:tss) = printTokenStream ts1 <> sp <> printTokenStreams (ts2:tss)
108-
where sp = printSpaceBetween (spanOf ts1) (spanOf ts2)
105+
-- | Print a list of token trees, with the right amount of space between successive elements
106+
printTokenTrees :: [TokenTree] -> Doc a
107+
printTokenTrees [] = mempty
108+
printTokenTrees [tt] = printTt tt
109+
printTokenTrees (tt1:tt2:tts) = printTt tt1 <> sp <> printTokenTrees (tt2:tts)
110+
where
111+
extremities :: TokenTree -> (Token, Token)
112+
extremities (Token _ t ) = (t,t)
113+
extremities (Delimited _ d _) = (OpenDelim d, CloseDelim d)
114+
115+
-- extremities in this particular situation
116+
(lastTt1, firstTt2) = (snd $ extremities tt1, fst $ extremities tt2)
117+
spNeeded = lastTt1 `spaceNeeded` firstTt2
118+
119+
-- Spacing of tokens, as informed by positional information on tokens
120+
spPos = printSpaceBetween spNeeded (spanOf tt1) (spanOf tt2)
121+
122+
-- Spacing of tokens, as informed by 'spaceNeeded' and special cases
123+
spTok = case (snd $ extremities tt1, fst $ extremities tt2) of
124+
(Comma, _) -> space
125+
(Colon, _) -> space
126+
(Semicolon, _) -> space
127+
(_, OpenDelim Brace) -> space
128+
(CloseDelim Brace, _) -> space
129+
(t1, t2) | t1 `elem` toksRequiringSp || t2 `elem` toksRequiringSp -> space
130+
| otherwise -> if spNeeded then space else mempty
131+
132+
-- List of tokens that want to have space on either side of them
133+
toksRequiringSp = [ Equal, GreaterEqual, GreaterGreaterEqual, EqualEqual, NotEqual, LessEqual,
134+
LessLessEqual, MinusEqual, AmpersandEqual, PipeEqual, PlusEqual, StarEqual,
135+
SlashEqual, CaretEqual, PercentEqual, RArrow, LArrow, FatArrow ]
136+
137+
-- Use 'spPos' with 'spTok' as a fallback
138+
sp = fromMaybe spTok spPos
109139

110140
-- | Print the space between a token stream and the mod-path before it
111141
printTokenStreamSp :: TokenStream -> Doc a
@@ -116,8 +146,7 @@ printTokenStreamSp (Stream (t:_)) = printTokenStreamSp t
116146

117147
-- | Print a token stream
118148
printTokenStream :: TokenStream -> Doc a
119-
printTokenStream (Tree tt) = printTt tt
120-
printTokenStream (Stream ts) = printTokenStreams ts
149+
printTokenStream = printTokenTrees . unfoldr unconsTokenStream
121150

122151
-- | Print a token (@token_to_string@)
123152
-- Single character expression-operator symbols.

0 commit comments

Comments
 (0)