mirror of
				https://gitea.invidious.io/iv-org/shard-ameba.git
				synced 2024-08-15 00:53:29 +00:00 
			
		
		
		
	Make BranchVisitor treat loop { … } calls as branchable
				
					
				
			This commit is contained in:
		
							parent
							
								
									9bb6c9ac75
								
							
						
					
					
						commit
						57898fd797
					
				
					 3 changed files with 70 additions and 1 deletions
				
			
		|  | @ -298,6 +298,34 @@ module Ameba::AST | ||||||
|       end |       end | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|  |     context "Crystal::Call" do | ||||||
|  |       context "loop" do | ||||||
|  |         it "constructs a branch in block" do | ||||||
|  |           branch = branch_of_assign_in_def <<-CRYSTAL | ||||||
|  |             def method(a) | ||||||
|  |               loop do | ||||||
|  |                 b = (a = 1) | ||||||
|  |               end | ||||||
|  |             end | ||||||
|  |             CRYSTAL | ||||||
|  |           branch.to_s.should eq "b = (a = 1)" | ||||||
|  |         end | ||||||
|  |       end | ||||||
|  | 
 | ||||||
|  |       context "other" do | ||||||
|  |         it "skips constructing a branch in block" do | ||||||
|  |           branch = branch_of_assign_in_def <<-CRYSTAL | ||||||
|  |             def method(a) | ||||||
|  |               1.upto(10) do | ||||||
|  |                 b = (a = 1) | ||||||
|  |               end | ||||||
|  |             end | ||||||
|  |             CRYSTAL | ||||||
|  |           branch.should be_nil | ||||||
|  |         end | ||||||
|  |       end | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|     describe "#initialize" do |     describe "#initialize" do | ||||||
|       it "creates new branch" do |       it "creates new branch" do | ||||||
|         nodes = as_nodes <<-CRYSTAL |         nodes = as_nodes <<-CRYSTAL | ||||||
|  | @ -358,6 +386,30 @@ module Ameba::AST | ||||||
|         branch = Branch.new nodes.assign_nodes.first, branchable |         branch = Branch.new nodes.assign_nodes.first, branchable | ||||||
|         branch.in_loop?.should be_false |         branch.in_loop?.should be_false | ||||||
|       end |       end | ||||||
|  | 
 | ||||||
|  |       context "Crystal::Call" do | ||||||
|  |         it "returns true if branch is in a loop" do | ||||||
|  |           nodes = as_nodes <<-CRYSTAL | ||||||
|  |             loop do | ||||||
|  |               a = 1 | ||||||
|  |             end | ||||||
|  |             CRYSTAL | ||||||
|  |           branchable = Branchable.new nodes.call_nodes.first | ||||||
|  |           branch = Branch.new nodes.assign_nodes.first, branchable | ||||||
|  |           branch.in_loop?.should be_true | ||||||
|  |         end | ||||||
|  | 
 | ||||||
|  |         it "returns false if branch is not in a loop" do | ||||||
|  |           nodes = as_nodes <<-CRYSTAL | ||||||
|  |             1.upto(10) do | ||||||
|  |               a = 1 | ||||||
|  |             end | ||||||
|  |             CRYSTAL | ||||||
|  |           branchable = Branchable.new nodes.call_nodes.first | ||||||
|  |           branch = Branch.new nodes.assign_nodes.first, branchable | ||||||
|  |           branch.in_loop?.should be_false | ||||||
|  |         end | ||||||
|  |       end | ||||||
|     end |     end | ||||||
|   end |   end | ||||||
| end | end | ||||||
|  |  | ||||||
|  | @ -259,6 +259,7 @@ module Ameba | ||||||
|       Crystal::MacroLiteral, |       Crystal::MacroLiteral, | ||||||
|       Crystal::Expressions, |       Crystal::Expressions, | ||||||
|       Crystal::ControlExpression, |       Crystal::ControlExpression, | ||||||
|  |       Crystal::Call, | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     def initialize(node) |     def initialize(node) | ||||||
|  |  | ||||||
|  | @ -1,3 +1,5 @@ | ||||||
|  | require "./util" | ||||||
|  | 
 | ||||||
| module Ameba::AST | module Ameba::AST | ||||||
|   # Represents the branch in Crystal code. |   # Represents the branch in Crystal code. | ||||||
|   # Branch is a part of a branchable statement. |   # Branch is a part of a branchable statement. | ||||||
|  | @ -67,6 +69,8 @@ module Ameba::AST | ||||||
| 
 | 
 | ||||||
|     # :nodoc: |     # :nodoc: | ||||||
|     private class BranchVisitor < Crystal::Visitor |     private class BranchVisitor < Crystal::Visitor | ||||||
|  |       include Util | ||||||
|  | 
 | ||||||
|       @current_branch : Crystal::ASTNode? |       @current_branch : Crystal::ASTNode? | ||||||
| 
 | 
 | ||||||
|       property branchable : Branchable? |       property branchable : Branchable? | ||||||
|  | @ -79,7 +83,7 @@ module Ameba::AST | ||||||
|         on_branchable_start(node, branches) |         on_branchable_start(node, branches) | ||||||
|       end |       end | ||||||
| 
 | 
 | ||||||
|       private def on_branchable_start(node, branches : Array | Tuple) |       private def on_branchable_start(node, branches : Enumerable) | ||||||
|         @branchable = Branchable.new(node, @branchable) |         @branchable = Branchable.new(node, @branchable) | ||||||
| 
 | 
 | ||||||
|         branches.each do |branch_node| |         branches.each do |branch_node| | ||||||
|  | @ -172,6 +176,18 @@ module Ameba::AST | ||||||
|       def end_visit(node : Crystal::MacroFor) |       def end_visit(node : Crystal::MacroFor) | ||||||
|         on_branchable_end node |         on_branchable_end node | ||||||
|       end |       end | ||||||
|  | 
 | ||||||
|  |       def visit(node : Crystal::Call) | ||||||
|  |         if loop?(node) && (block = node.block) | ||||||
|  |           on_branchable_start node, block.body | ||||||
|  |         end | ||||||
|  |       end | ||||||
|  | 
 | ||||||
|  |       def end_visit(node : Crystal::Call) | ||||||
|  |         if loop?(node) && node.block | ||||||
|  |           on_branchable_end node | ||||||
|  |         end | ||||||
|  |       end | ||||||
|     end |     end | ||||||
|   end |   end | ||||||
| end | end | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue