From 23303cd0f8298c2d7b082fcb04919454c1c306ab Mon Sep 17 00:00:00 2001
From: Aleksey Kladov <aleksey.kladov@gmail.com>
Date: Mon, 3 Sep 2018 01:51:46 +0300
Subject: match scope

---
 crates/libeditor/src/scope/fn_scope.rs | 41 ++++++++++++++++++++++------------
 crates/libsyntax2/src/ast/generated.rs | 26 ++++++++++++++++++---
 crates/libsyntax2/src/grammar.ron      | 16 ++++++++++---
 3 files changed, 63 insertions(+), 20 deletions(-)

(limited to 'crates')

diff --git a/crates/libeditor/src/scope/fn_scope.rs b/crates/libeditor/src/scope/fn_scope.rs
index 78e9c061c..42cd71eb5 100644
--- a/crates/libeditor/src/scope/fn_scope.rs
+++ b/crates/libeditor/src/scope/fn_scope.rs
@@ -189,7 +189,20 @@ fn compute_expr_scopes(expr: ast::Expr, scopes: &mut FnScopes, scope: ScopeId) {
                 .chain(e.expr())
                 .for_each(|expr| compute_expr_scopes(expr, scopes, scope));
         }
-
+        ast::Expr::MatchExpr(e) => {
+            if let Some(expr) = e.expr() {
+                compute_expr_scopes(expr, scopes, scope);
+            }
+            for arm in e.match_arm_list().into_iter().flat_map(|it| it.arms()) {
+                let scope = scopes.new_scope(scope);
+                for pat in arm.pats() {
+                    scopes.add_bindings(scope, pat);
+                }
+                if let Some(expr) = arm.expr() {
+                    compute_expr_scopes(expr, scopes, scope);
+                }
+            }
+        }
         _ => {
             expr.syntax().children()
                 .filter_map(ast::Expr::cast)
@@ -279,17 +292,17 @@ mod tests {
         );
     }
 
-    // #[test]
-    // fn test_match() {
-    //     do_check(r"
-    //         fn quux() {
-    //             match () {
-    //                 Some(x) => {
-    //                     <|>
-    //                 }
-    //             };
-    //         }",
-    //         &["x"],
-    //     );
-    // }
+    #[test]
+    fn test_match() {
+        do_check(r"
+            fn quux() {
+                match () {
+                    Some(x) => {
+                        <|>
+                    }
+                };
+            }",
+            &["x"],
+        );
+    }
 }
diff --git a/crates/libsyntax2/src/ast/generated.rs b/crates/libsyntax2/src/ast/generated.rs
index f21e49437..bdee635ae 100644
--- a/crates/libsyntax2/src/ast/generated.rs
+++ b/crates/libsyntax2/src/ast/generated.rs
@@ -842,7 +842,17 @@ impl<'a> AstNode<'a> for MatchArm<'a> {
     fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
 }
 
-impl<'a> MatchArm<'a> {}
+impl<'a> MatchArm<'a> {
+    pub fn pats(self) -> impl Iterator<Item = Pat<'a>> + 'a {
+        super::children(self)
+    }
+pub fn guard(self) -> Option<MatchGuard<'a>> {
+        super::child_opt(self)
+    }
+pub fn expr(self) -> Option<Expr<'a>> {
+        super::child_opt(self)
+    }
+}
 
 // MatchArmList
 #[derive(Debug, Clone, Copy)]
@@ -860,7 +870,11 @@ impl<'a> AstNode<'a> for MatchArmList<'a> {
     fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
 }
 
-impl<'a> MatchArmList<'a> {}
+impl<'a> MatchArmList<'a> {
+    pub fn arms(self) -> impl Iterator<Item = MatchArm<'a>> + 'a {
+        super::children(self)
+    }
+}
 
 // MatchExpr
 #[derive(Debug, Clone, Copy)]
@@ -878,7 +892,13 @@ impl<'a> AstNode<'a> for MatchExpr<'a> {
     fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
 }
 
-impl<'a> MatchExpr<'a> {}
+impl<'a> MatchExpr<'a> {pub fn expr(self) -> Option<Expr<'a>> {
+        super::child_opt(self)
+    }
+pub fn match_arm_list(self) -> Option<MatchArmList<'a>> {
+        super::child_opt(self)
+    }
+}
 
 // MatchGuard
 #[derive(Debug, Clone, Copy)]
diff --git a/crates/libsyntax2/src/grammar.ron b/crates/libsyntax2/src/grammar.ron
index fbe8397d8..798725f7e 100644
--- a/crates/libsyntax2/src/grammar.ron
+++ b/crates/libsyntax2/src/grammar.ron
@@ -370,9 +370,19 @@ Grammar(
             options: [ "Block" ]
         ),
         "ReturnExpr": (),
-        "MatchExpr": (),
-        "MatchArmList": (),
-        "MatchArm": (),
+        "MatchExpr": (
+            options: [ "Expr", "MatchArmList" ],
+        ),
+        "MatchArmList": (
+            collections: [ ["arms", "MatchArm"] ],
+        ),
+        "MatchArm": (
+            options: [
+                [ "guard", "MatchGuard" ],
+                "Expr",
+            ],
+            collections: [ [ "pats", "Pat" ] ]
+        ),
         "MatchGuard": (),
         "StructLit": (),
         "NamedFieldList": (),
-- 
cgit v1.2.3