Skip to content

Commit 98814f9

Browse files
committed
Difference tests for macros
In the process, I unpleasantly discovered a new bug #19 that is the result of the changing macro landscape. That aside, 'ast.rs' now diffs just fine, and 'parser.rs' is on it's way.
1 parent 3d4e964 commit 98814f9

File tree

2 files changed

+104
-18
lines changed

2 files changed

+104
-18
lines changed

src/Language/Rust/Parser/Internal.y

+8-7
Original file line numberDiff line numberDiff line change
@@ -1130,17 +1130,17 @@ stmt :: { Stmt Span }
11301130
: ntStmt { $1 }
11311131
| many(outer_attribute) let pat ':' ty initializer ';' { Local $3 (Just $5) $6 $1 ($1 # $2 # $>) }
11321132
| many(outer_attribute) let pat initializer ';' { Local $3 Nothing $4 $1 ($1 # $2 # $>) }
1133-
| many(outer_attribute) nonblock_expr ';' { toStmt ($1 `addAttrs` $2) True ($1 # $2 # $3) }
1134-
| many(outer_attribute) block_expr { toStmt ($1 `addAttrs` $2) False ($1 # $2) }
1135-
| many(outer_attribute) block_expr ';' { toStmt ($1 `addAttrs` $2) True ($1 # $2 # $3) }
1133+
| many(outer_attribute) nonblock_expr ';' { toStmt ($1 `addAttrs` $2) True False ($1 # $2 # $3) }
1134+
| many(outer_attribute) block_expr { toStmt ($1 `addAttrs` $2) False True ($1 # $2) }
1135+
| many(outer_attribute) block_expr ';' { toStmt ($1 `addAttrs` $2) True False ($1 # $2 # $3) }
11361136
| many(outer_attribute) stmt_item { ItemStmt (let Item i a n v s = $2 in Item i ($1 ++ a) n v s) ($1 # $2) }
11371137
| many(outer_attribute) pub stmt_item { ItemStmt (let Item i a n _ s = $3 in Item i ($1 ++ a) n PublicV s) ($1 # $2 # $3) }
11381138

11391139
-- List of statements where the last statement might be a no-semicolon statement.
11401140
stmts_possibly_no_semi :: { [Stmt Span] }
11411141
: stmt stmts_possibly_no_semi { $1 : $2 }
11421142
| stmt { [$1] }
1143-
| many(outer_attribute) nonblock_expr { [toStmt ($1 `addAttrs` $2) False ($1 # $2)] }
1143+
| many(outer_attribute) nonblock_expr { [toStmt ($1 `addAttrs` $2) False False ($1 # $2)] }
11441144

11451145
initializer :: { Maybe (Expr Span) }
11461146
: '=' expr { Just $2 }
@@ -1558,9 +1558,10 @@ toIdent (Spanned (IdentTok i) s) = Spanned i s
15581558

15591559
-- | Try to convert an expression to a statement given information about whether there is a trailing
15601560
-- semicolon
1561-
toStmt :: Expr Span -> Bool -> Span -> Stmt Span
1562-
toStmt (MacExpr a m s) hasSemi = MacStmt m (if hasSemi then SemicolonMac else BracesMac) a
1563-
toStmt e hasSemi = (if hasSemi then Semi else NoSemi) e
1561+
toStmt :: Expr Span -> Bool -> Bool -> Span -> Stmt Span
1562+
toStmt (MacExpr a m s) hasSemi isBlock | hasSemi = MacStmt m SemicolonMac a
1563+
| isBlock = MacStmt m BracesMac a
1564+
toStmt e hasSemi _ = (if hasSemi then Semi else NoSemi) e
15641565

15651566
-- | Add attributes to an expression
15661567
addAttrs :: [Attribute Span] -> Expr Span -> Expr Span

tests/rustc-tests/Diff.hs

+96-11
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ module Diff where
44
import Data.Aeson
55
import Language.Rust.Pretty
66
import Language.Rust.Syntax.AST
7+
import Language.Rust.Syntax.Token
78
import Language.Rust.Syntax.Ident
89

910
import Control.Monad (when)
@@ -15,9 +16,16 @@ import Data.Foldable (sequence_, toList)
1516
import Data.List.NonEmpty ((<|))
1617
import Data.Maybe (fromMaybe)
1718
import qualified Data.Text as T
19+
import qualified Data.Vector as V
1820

1921
import DiffUtils
2022

23+
-- TODO:
24+
-- * attributes
25+
-- * spans
26+
27+
28+
2129
-- | Lift a comparision to an array
2230
liftDiff :: (Foldable f, Show a) => (a -> Value -> Diff) -> (f a -> Value -> Diff)
2331
liftDiff f xs val@(Data.Aeson.Array v) = do
@@ -105,6 +113,8 @@ instance Show a => Diffable (Item a) where
105113
mtr === (n' ! "fields" ! 3)
106114
t === (n' ! "fields" ! 4)
107115
is === (n' ! "fields" ! 5)
116+
("Mac", MacItem m) ->
117+
m === (n' ! "fields" ! 0)
108118

109119
_ -> diff "different items" item val
110120

@@ -203,19 +213,37 @@ instance Show a => Diffable (ForeignItem a) where
203213
m === (n' ! "fields" ! 1)
204214
_ -> diff "different foreign item" f val
205215

216+
-- TODO: what is even happening here!?
206217
instance Show a => Diffable (ViewPath a) where
207218
v === val = do
208219
let n' = val ! "node"
209220
case (n' ! "variant", v) of
210221
("ViewPathGlob", ViewPathGlob g is _) ->
211-
let is' = if g then Ident "{{root}}" undefined : is else is
212-
in liftDiff diffViewPathIdent is' (n' ! "fields" ! 0 ! "segments")
222+
diffViewPathGlobal g is (n' ! "fields" ! 0 ! "segments")
213223
("ViewPathList", ViewPathList g is pl _) -> do
214-
let is' = if {- TODO g -} True then Ident "{{root}}" undefined : is else is
215-
-- liftDiff diffViewPathIdent is' (n' ! "fields" ! 0 ! "segments")
216-
pl === (n' ! "fields" ! 1)
217-
_ -> diff "Unimplemented: diffViewPath" v val
224+
diffViewPathGlobal g is (n' ! "fields" ! 0 ! "segments")
225+
pl === (n' ! "fields" ! 1)
226+
("ViewPathSimple", ViewPathSimple g is (PathListItem n (Just r) _) _) -> do
227+
diffString r (n' ! "fields" ! 0)
228+
diffViewPathGlobal g (is ++ [n]) (n' ! "fields" ! 1 ! "segments")
229+
("ViewPathSimple", ViewPathSimple g is (PathListItem n Nothing _) _) -> do
230+
diffString n (n' ! "fields" ! 0)
231+
diffViewPathGlobal g (is ++ [n]) (n' ! "fields" ! 1 ! "segments")
232+
_ -> diff "different view path" v val
218233
where
234+
diffViewPathGlobal :: Bool -> [Ident] -> Value -> Diff
235+
diffViewPathGlobal g is v
236+
| g || global is = liftDiff diffViewPathIdent is (jsonDrop 1 v)
237+
| otherwise = liftDiff diffViewPathIdent is v
238+
239+
global :: [Ident] -> Bool
240+
global (Ident "self" _ : _) = False
241+
global (Ident "super" _ : _) = False
242+
global _ = True
243+
244+
jsonDrop :: Int -> Value -> Value
245+
jsonDrop i (Data.Aeson.Array v) = Data.Aeson.Array (V.drop i v)
246+
219247
diffViewPathIdent :: Ident -> Value -> Diff
220248
diffViewPathIdent i val = do
221249
when (Null /= val ! "parameters") $
@@ -244,12 +272,17 @@ instance Show a => Diffable (FnDecl a) where
244272
when (Data.Aeson.Bool v /= v') $
245273
diff "different variadicity" decl val
246274

275+
-- TODO: make this more rigorous
247276
instance Show a => Diffable (Arg a) where
248-
SelfRegion ml m _ === val = pure () -- TODO
249-
SelfValue m _ === val = pure () -- TODO
250-
SelfExplicit t m _ === val = pure ()-- TODO
277+
SelfRegion ml m x === val =
278+
IdentP (ByValue m) "self" Nothing x === (val ! "pat")
279+
SelfValue m x === val =
280+
IdentP (ByValue m) "self" Nothing x === (val ! "pat")
281+
SelfExplicit t m x === val = do
282+
IdentP (ByValue m) "self" Nothing x === (val ! "pat")
283+
t === (val ! "ty")
251284
Arg p t _ === val = do
252-
-- p === (val ! "pat") TODO
285+
p === (val ! "pat")
253286
t === (val ! "ty")
254287

255288
instance Diffable Unsafety where
@@ -340,8 +373,16 @@ instance Show a => Diffable (Stmt a) where
340373
("Expr", NoSemi e _) -> e === (n' ! "fields" ! 0)
341374
("Semi", Semi e _) -> e === (n' ! "fields" ! 0)
342375
("Item", ItemStmt i _) -> i === (n' ! "fields" ! 0)
376+
("Mac", MacStmt m s as _) -> do
377+
m === (n' ! "fields" ! 0 ! 0)
378+
s === (n' ! "fields" ! 0 ! 1)
343379
_ -> diff "Unimplemented: diffStmt" stmt val
344380

381+
instance Diffable MacStmtStyle where
382+
SemicolonMac === "Semicolon" = pure ()
383+
BracesMac === "Braces" = pure ()
384+
sty === json = diff "different styles" sty json
385+
345386
instance Show a => Diffable (Visibility a) where
346387
PublicV === "Public" = pure ()
347388
CrateV === "Crate" = pure ()
@@ -434,7 +475,51 @@ instance Show a => Diffable (Pat a) where
434475
_ -> diff "differing patterns" p val
435476

436477
instance Show a => Diffable (Mac a) where
437-
m === val = diff "Unimplemented: diffMac" m val
478+
m@(Mac p tts _) === val = do
479+
p === (val ! "node" ! "path")
480+
tts === (val ! "node" ! "tts")
481+
482+
instance Diffable TokenTree where
483+
tt === val =
484+
case (val ! "variant", tt) of
485+
("Token", Token _ t) -> t === (val ! "fields" ! 1)
486+
("Delimited", Delimited _ d _ tts _) -> do
487+
d === (val ! "fields" ! 1 ! "delim")
488+
tts === (val ! "fields" ! 1 ! "tts")
489+
_ -> diff "Unimplemented: diffTokenTree" tt val
490+
491+
instance Diffable Delim where
492+
Paren === "Paren" = pure ()
493+
Bracket === "Bracket" = pure ()
494+
Brace === "Brace" = pure ()
495+
delim === json = diff "different delimiters" delim json
496+
497+
instance Diffable Token where
498+
Comma === "Comma" = pure ()
499+
Dot === "Dot" = pure ()
500+
Equal === "Eq" = pure ()
501+
Colon === "Colon" = pure ()
502+
ModSep === "ModSep" = pure ()
503+
Less === "Lt" = pure ()
504+
t === val@Object{} =
505+
case (val ! "variant", t) of
506+
("BinOp", b) ->
507+
case (val ! "fields" ! 0, t) of
508+
("Shl", LessLess) -> pure ()
509+
_ -> diff "Unimplemented: diffToken" t val
510+
("Ident", IdentTok i) -> diffString i (val ! "fields" ! 0)
511+
("Literal", LiteralTok l s) -> do
512+
l === (val ! "fields" ! 0)
513+
-- TODO suffix
514+
_ -> diff "Unimplemented: diffToken" t val
515+
t === val = diff "Unimplemented: diffToken" t val
516+
517+
instance Diffable LitTok where
518+
l === val =
519+
case (val ! "variant", l) of
520+
("Str_", StrTok s) | fromString s == (val ! "fields" ! 0) -> pure ()
521+
("Integer", IntegerTok s) | fromString s == (val ! "fields" ! 0) -> pure ()
522+
_ -> diff "Unimplemented: diffLitTok" l val
438523

439524
diffIntegral :: (Show i, Integral i) => i -> Value -> Diff
440525
diffIntegral i (Number s) | fromIntegral i == s = pure ()

0 commit comments

Comments
 (0)