mirror of
				https://gitea.invidious.io/iv-org/shard-ameba.git
				synced 2024-08-15 00:53:29 +00:00 
			
		
		
		
	Rework variable references detection in macro
This commit is contained in:
		
							parent
							
								
									efe67212b0
								
							
						
					
					
						commit
						bf907ee98b
					
				
					 4 changed files with 37 additions and 9 deletions
				
			
		| 
						 | 
					@ -851,6 +851,22 @@ module Ameba::Rule
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        subject.catch(s).should_not be_valid
 | 
					        subject.catch(s).should_not be_valid
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      it "doesn't report if assignment is referenced in a macro below" do
 | 
				
			||||||
 | 
					        s = Source.new %(
 | 
				
			||||||
 | 
					          class Foo
 | 
				
			||||||
 | 
					            def foo
 | 
				
			||||||
 | 
					              a = 1
 | 
				
			||||||
 | 
					              macro_call
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            macro macro_call
 | 
				
			||||||
 | 
					              puts a
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        subject.catch(s).should be_valid
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    context "uninitialized" do
 | 
					    context "uninitialized" do
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -19,9 +19,6 @@ module Ameba::AST
 | 
				
			||||||
    # The actual AST node that represents a current scope.
 | 
					    # The actual AST node that represents a current scope.
 | 
				
			||||||
    getter node : Crystal::ASTNode
 | 
					    getter node : Crystal::ASTNode
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Macro literals in current scope
 | 
					 | 
				
			||||||
    getter macro_literals = [] of Crystal::MacroLiteral
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    delegate to_s, to: node
 | 
					    delegate to_s, to: node
 | 
				
			||||||
    delegate location, to: node
 | 
					    delegate location, to: node
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -117,7 +117,7 @@ module Ameba::AST
 | 
				
			||||||
    # false if not.
 | 
					    # false if not.
 | 
				
			||||||
    def used_in_macro?(scope = @scope)
 | 
					    def used_in_macro?(scope = @scope)
 | 
				
			||||||
      scope.inner_scopes.each do |inner_scope|
 | 
					      scope.inner_scopes.each do |inner_scope|
 | 
				
			||||||
        return true if inner_scope.macro_literals.any? { |literal| literal.value.includes?(name) }
 | 
					        return true if MacroLiteralFinder.new(inner_scope.node).references? node
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
      return true if (outer_scope = scope.outer_scope) && used_in_macro?(outer_scope)
 | 
					      return true if (outer_scope = scope.outer_scope) && used_in_macro?(outer_scope)
 | 
				
			||||||
      false
 | 
					      false
 | 
				
			||||||
| 
						 | 
					@ -142,5 +142,25 @@ module Ameba::AST
 | 
				
			||||||
        node.name == @node.name &&
 | 
					        node.name == @node.name &&
 | 
				
			||||||
        node.location == @node.location
 | 
					        node.location == @node.location
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private class MacroLiteralFinder < Crystal::Visitor
 | 
				
			||||||
 | 
					      @macro_literals = [] of Crystal::MacroLiteral
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      def initialize(node)
 | 
				
			||||||
 | 
					        node.accept self
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      def references?(node : Crystal::Var)
 | 
				
			||||||
 | 
					        @macro_literals.any? { |literal| literal.value.includes? node.name }
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      def visit(node : Crystal::ASTNode)
 | 
				
			||||||
 | 
					        true
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      def visit(node : Crystal::MacroLiteral)
 | 
				
			||||||
 | 
					        @macro_literals << node
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -127,11 +127,6 @@ module Ameba::AST
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # :nodoc:
 | 
					 | 
				
			||||||
    def visit(node : Crystal::MacroLiteral)
 | 
					 | 
				
			||||||
      @current_scope.macro_literals << node
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # :nodoc:
 | 
					    # :nodoc:
 | 
				
			||||||
    def visit(node : Crystal::Call)
 | 
					    def visit(node : Crystal::Call)
 | 
				
			||||||
      return true unless node.name == "super" && node.args.empty?
 | 
					      return true unless node.name == "super" && node.args.empty?
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue