mirror of
				https://gitea.invidious.io/iv-org/shard-ameba.git
				synced 2024-08-15 00:53:29 +00:00 
			
		
		
		
	Use NodeVisitor by default and remove the boilerplace code
This commit is contained in:
		
							parent
							
								
									1d827b4969
								
							
						
					
					
						commit
						1a0468c653
					
				
					 26 changed files with 6 additions and 101 deletions
				
			
		| 
						 | 
					@ -32,7 +32,12 @@ module Ameba::Rule
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # This method is designed to test the source passed in. If source has issues
 | 
					    # This method is designed to test the source passed in. If source has issues
 | 
				
			||||||
    # that are tested by this rule, it should add an issue.
 | 
					    # that are tested by this rule, it should add an issue.
 | 
				
			||||||
    abstract def test(source : Source)
 | 
					    #
 | 
				
			||||||
 | 
					    # Be default it uses a node visitor to traverse all the nodes in the source.
 | 
				
			||||||
 | 
					    # Must be overriten for other type of rules.
 | 
				
			||||||
 | 
					    def test(source : Source)
 | 
				
			||||||
 | 
					      AST::NodeVisitor.new self, source
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test(source : Source, node : Crystal::ASTNode, *opts)
 | 
					    def test(source : Source, node : Crystal::ASTNode, *opts)
 | 
				
			||||||
      # can't be abstract
 | 
					      # can't be abstract
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -28,10 +28,6 @@ module Ameba::Rule::Lint
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    MSG = "Comparison to a boolean is pointless"
 | 
					    MSG = "Comparison to a boolean is pointless"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test(source)
 | 
					 | 
				
			||||||
      AST::NodeVisitor.new self, source
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test(source, node : Crystal::Call)
 | 
					    def test(source, node : Crystal::Call)
 | 
				
			||||||
      comparison = %w(== != ===).includes?(node.name)
 | 
					      comparison = %w(== != ===).includes?(node.name)
 | 
				
			||||||
      to_boolean = node.args.first?.try &.is_a?(Crystal::BoolLiteral) ||
 | 
					      to_boolean = node.args.first?.try &.is_a?(Crystal::BoolLiteral) ||
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -18,10 +18,6 @@ module Ameba::Rule::Lint
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    MSG = "Possible forgotten debugger statement detected"
 | 
					    MSG = "Possible forgotten debugger statement detected"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test(source)
 | 
					 | 
				
			||||||
      AST::NodeVisitor.new self, source
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test(source, node : Crystal::Call)
 | 
					    def test(source, node : Crystal::Call)
 | 
				
			||||||
      return unless node.name == "debugger" &&
 | 
					      return unless node.name == "debugger" &&
 | 
				
			||||||
                    node.args.empty? &&
 | 
					                    node.args.empty? &&
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -46,10 +46,6 @@ module Ameba::Rule::Lint
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    MSG = "Empty `ensure` block detected"
 | 
					    MSG = "Empty `ensure` block detected"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test(source)
 | 
					 | 
				
			||||||
      AST::NodeVisitor.new self, source
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test(source, node : Crystal::ExceptionHandler)
 | 
					    def test(source, node : Crystal::ExceptionHandler)
 | 
				
			||||||
      node_ensure = node.ensure
 | 
					      node_ensure = node.ensure
 | 
				
			||||||
      return if node_ensure.nil? || !node_ensure.nop?
 | 
					      return if node_ensure.nil? || !node_ensure.nop?
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -38,10 +38,6 @@ module Ameba::Rule::Lint
 | 
				
			||||||
    MSG      = "Avoid empty expression %s"
 | 
					    MSG      = "Avoid empty expression %s"
 | 
				
			||||||
    MSG_EXRS = "Avoid empty expressions"
 | 
					    MSG_EXRS = "Avoid empty expressions"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test(source)
 | 
					 | 
				
			||||||
      AST::NodeVisitor.new self, source
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test(source, node : Crystal::NilLiteral)
 | 
					    def test(source, node : Crystal::NilLiteral)
 | 
				
			||||||
      exp = node_source(node, source.lines).try &.join
 | 
					      exp = node_source(node, source.lines).try &.join
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -27,10 +27,6 @@ module Ameba::Rule::Lint
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    MSG = "Duplicated keys in hash literal: %s"
 | 
					    MSG = "Duplicated keys in hash literal: %s"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test(source)
 | 
					 | 
				
			||||||
      AST::NodeVisitor.new self, source
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test(source, node : Crystal::HashLiteral)
 | 
					    def test(source, node : Crystal::HashLiteral)
 | 
				
			||||||
      return unless (keys = duplicated_keys(node.entries)).any?
 | 
					      return unless (keys = duplicated_keys(node.entries)).any?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -30,10 +30,6 @@ module Ameba::Rule::Lint
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    MSG = "Literal value found in conditional"
 | 
					    MSG = "Literal value found in conditional"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test(source)
 | 
					 | 
				
			||||||
      AST::NodeVisitor.new self, source
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def check_node(source, node)
 | 
					    def check_node(source, node)
 | 
				
			||||||
      return unless literal?(node.cond)
 | 
					      return unless literal?(node.cond)
 | 
				
			||||||
      issue_for node, MSG
 | 
					      issue_for node, MSG
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -25,10 +25,6 @@ module Ameba::Rule::Lint
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    MSG = "Literal value found in interpolation"
 | 
					    MSG = "Literal value found in interpolation"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test(source)
 | 
					 | 
				
			||||||
      AST::NodeVisitor.new self, source
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test(source, node : Crystal::StringInterpolation)
 | 
					    def test(source, node : Crystal::StringInterpolation)
 | 
				
			||||||
      found = node.expressions.any? { |e| !e.is_a?(Crystal::StringLiteral) && literal?(e) }
 | 
					      found = node.expressions.any? { |e| !e.is_a?(Crystal::StringLiteral) && literal?(e) }
 | 
				
			||||||
      return unless found
 | 
					      return unless found
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -30,10 +30,6 @@ module Ameba::Rule::Lint
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    MSG = "%s always returns 0"
 | 
					    MSG = "%s always returns 0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test(source)
 | 
					 | 
				
			||||||
      AST::NodeVisitor.new self, source
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test(source, node : Crystal::Call)
 | 
					    def test(source, node : Crystal::Call)
 | 
				
			||||||
      return unless node.name == "rand" &&
 | 
					      return unless node.name == "rand" &&
 | 
				
			||||||
                    node.args.size == 1 &&
 | 
					                    node.args.size == 1 &&
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -32,10 +32,6 @@ module Ameba::Rule::Lint
 | 
				
			||||||
      description "Disallows redundant `with_index` calls"
 | 
					      description "Disallows redundant `with_index` calls"
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test(source)
 | 
					 | 
				
			||||||
      AST::NodeVisitor.new self, source
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test(source, node : Crystal::Call)
 | 
					    def test(source, node : Crystal::Call)
 | 
				
			||||||
      args, block = node.args, node.block
 | 
					      args, block = node.args, node.block
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -33,10 +33,6 @@ module Ameba::Rule::Lint
 | 
				
			||||||
      description "Disallows redundant `with_object` calls"
 | 
					      description "Disallows redundant `with_object` calls"
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test(source)
 | 
					 | 
				
			||||||
      AST::NodeVisitor.new self, source
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test(source, node : Crystal::Call)
 | 
					    def test(source, node : Crystal::Call)
 | 
				
			||||||
      return if node.name != "each_with_object" ||
 | 
					      return if node.name != "each_with_object" ||
 | 
				
			||||||
                node.args.size != 1 ||
 | 
					                node.args.size != 1 ||
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -41,10 +41,6 @@ module Ameba::Rule::Lint
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    MSG = "Exception handler has shadowed exceptions: %s"
 | 
					    MSG = "Exception handler has shadowed exceptions: %s"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test(source)
 | 
					 | 
				
			||||||
      AST::NodeVisitor.new self, source
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test(source, node : Crystal::ExceptionHandler)
 | 
					    def test(source, node : Crystal::ExceptionHandler)
 | 
				
			||||||
      return unless excs = node.rescues
 | 
					      return unless excs = node.rescues
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -51,10 +51,6 @@ module Ameba::Rule::Lint
 | 
				
			||||||
      issue_for cond, MSG
 | 
					      issue_for cond, MSG
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test(source)
 | 
					 | 
				
			||||||
      AST::NodeVisitor.new self, source
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test(source, node : Crystal::When)
 | 
					    def test(source, node : Crystal::When)
 | 
				
			||||||
      ConditionInWhenVisitor.new self, source, node
 | 
					      ConditionInWhenVisitor.new self, source, node
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -17,10 +17,6 @@ module Ameba::Rule::Metrics
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    MSG = "Cyclomatic complexity too high [%d/%d]"
 | 
					    MSG = "Cyclomatic complexity too high [%d/%d]"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test(source)
 | 
					 | 
				
			||||||
      AST::NodeVisitor.new self, source
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test(source, node : Crystal::Def)
 | 
					    def test(source, node : Crystal::Def)
 | 
				
			||||||
      complexity = AST::CountingVisitor.new(node).count
 | 
					      complexity = AST::CountingVisitor.new(node).count
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -34,10 +34,6 @@ module Ameba::Rule::Performance
 | 
				
			||||||
      description "Identifies usage of `any?` calls that follow filters."
 | 
					      description "Identifies usage of `any?` calls that follow filters."
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test(source)
 | 
					 | 
				
			||||||
      AST::NodeVisitor.new self, source
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test(source, node : Crystal::Call)
 | 
					    def test(source, node : Crystal::Call)
 | 
				
			||||||
      return unless node.name == ANY_NAME && (obj = node.obj)
 | 
					      return unless node.name == ANY_NAME && (obj = node.obj)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -29,10 +29,6 @@ module Ameba::Rule::Style
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    MSG = "Constant name should be screaming-cased: %s, not %s"
 | 
					    MSG = "Constant name should be screaming-cased: %s, not %s"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test(source)
 | 
					 | 
				
			||||||
      AST::NodeVisitor.new self, source
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test(source, node : Crystal::Assign)
 | 
					    def test(source, node : Crystal::Assign)
 | 
				
			||||||
      if (target = node.target).is_a? Crystal::Path
 | 
					      if (target = node.target).is_a? Crystal::Path
 | 
				
			||||||
        name = target.names.first
 | 
					        name = target.names.first
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -45,10 +45,6 @@ module Ameba::Rule::Style
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    MSG = "Method name should be underscore-cased: %s, not %s"
 | 
					    MSG = "Method name should be underscore-cased: %s, not %s"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test(source)
 | 
					 | 
				
			||||||
      AST::NodeVisitor.new self, source
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test(source, node : Crystal::Def)
 | 
					    def test(source, node : Crystal::Def)
 | 
				
			||||||
      return if (expected = node.name.underscore) == node.name
 | 
					      return if (expected = node.name.underscore) == node.name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -34,10 +34,6 @@ module Ameba::Rule::Style
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    MSG = "Avoid negated conditions in unless blocks"
 | 
					    MSG = "Avoid negated conditions in unless blocks"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test(source)
 | 
					 | 
				
			||||||
      AST::NodeVisitor.new self, source
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test(source, node : Crystal::Unless)
 | 
					    def test(source, node : Crystal::Unless)
 | 
				
			||||||
      return unless negated_condition? node.cond
 | 
					      return unless negated_condition? node.cond
 | 
				
			||||||
      issue_for node, MSG
 | 
					      issue_for node, MSG
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -37,10 +37,6 @@ module Ameba::Rule::Style
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    MSG = "Favour method name '%s?' over '%s'"
 | 
					    MSG = "Favour method name '%s?' over '%s'"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test(source)
 | 
					 | 
				
			||||||
      AST::NodeVisitor.new self, source
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test(source, node : Crystal::Def)
 | 
					    def test(source, node : Crystal::Def)
 | 
				
			||||||
      if node.name =~ /^(is|has)_(\w+)\?/
 | 
					      if node.name =~ /^(is|has)_(\w+)\?/
 | 
				
			||||||
        alternative = $2
 | 
					        alternative = $2
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -64,10 +64,6 @@ module Ameba::Rule::Style
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    MSG = "Redundant `begin` block detected"
 | 
					    MSG = "Redundant `begin` block detected"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test(source)
 | 
					 | 
				
			||||||
      AST::NodeVisitor.new self, source
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test(source, node : Crystal::Def)
 | 
					    def test(source, node : Crystal::Def)
 | 
				
			||||||
      return unless redundant_begin?(source, node)
 | 
					      return unless redundant_begin?(source, node)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -105,10 +105,6 @@ module Ameba::Rule::Style
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    MSG = "Redundant `next` detected"
 | 
					    MSG = "Redundant `next` detected"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test(source)
 | 
					 | 
				
			||||||
      AST::NodeVisitor.new self, source
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test(source, node : Crystal::Block)
 | 
					    def test(source, node : Crystal::Block)
 | 
				
			||||||
      AST::RedundantControlExpressionVisitor.new(self, source, node.body)
 | 
					      AST::RedundantControlExpressionVisitor.new(self, source, node.body)
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -102,10 +102,6 @@ module Ameba::Rule::Style
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    MSG = "Redundant `return` detected"
 | 
					    MSG = "Redundant `return` detected"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test(source)
 | 
					 | 
				
			||||||
      AST::NodeVisitor.new self, source
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test(source, node : Crystal::Def)
 | 
					    def test(source, node : Crystal::Def)
 | 
				
			||||||
      AST::RedundantControlExpressionVisitor.new(self, source, node.body)
 | 
					      AST::RedundantControlExpressionVisitor.new(self, source, node.body)
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -59,10 +59,6 @@ module Ameba::Rule::Style
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    MSG = "Type name should be camelcased: %s, but it was %s"
 | 
					    MSG = "Type name should be camelcased: %s, but it was %s"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test(source)
 | 
					 | 
				
			||||||
      AST::NodeVisitor.new self, source
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    private def check_node(source, node)
 | 
					    private def check_node(source, node)
 | 
				
			||||||
      name = node.name.to_s
 | 
					      name = node.name.to_s
 | 
				
			||||||
      expected = name.camelcase
 | 
					      expected = name.camelcase
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -50,10 +50,6 @@ module Ameba::Rule::Style
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    MSG = "Favour if over unless with else"
 | 
					    MSG = "Favour if over unless with else"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test(source)
 | 
					 | 
				
			||||||
      AST::NodeVisitor.new self, source
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test(source, node : Crystal::Unless)
 | 
					    def test(source, node : Crystal::Unless)
 | 
				
			||||||
      return if node.else.nop?
 | 
					      return if node.else.nop?
 | 
				
			||||||
      issue_for node, MSG
 | 
					      issue_for node, MSG
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -30,10 +30,6 @@ module Ameba::Rule::Style
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    MSG = "Var name should be underscore-cased: %s, not %s"
 | 
					    MSG = "Var name should be underscore-cased: %s, not %s"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test(source)
 | 
					 | 
				
			||||||
      AST::NodeVisitor.new self, source
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    private def check_node(source, node)
 | 
					    private def check_node(source, node)
 | 
				
			||||||
      return if (expected = node.name.underscore) == node.name
 | 
					      return if (expected = node.name.underscore) == node.name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -33,10 +33,6 @@ module Ameba::Rule::Style
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    MSG = "While statement using true literal as condition"
 | 
					    MSG = "While statement using true literal as condition"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test(source)
 | 
					 | 
				
			||||||
      AST::NodeVisitor.new self, source
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test(source, node : Crystal::While)
 | 
					    def test(source, node : Crystal::While)
 | 
				
			||||||
      return unless node.cond.true_literal?
 | 
					      return unless node.cond.true_literal?
 | 
				
			||||||
      issue_for node, MSG
 | 
					      issue_for node, MSG
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue