mirror of
				https://gitea.invidious.io/iv-org/shard-ameba.git
				synced 2024-08-15 00:53:29 +00:00 
			
		
		
		
	Dynamically load rule documentation
This commit is contained in:
		
							parent
							
								
									f8dab3bc34
								
							
						
					
					
						commit
						20938da89a
					
				
					 3 changed files with 57 additions and 0 deletions
				
			
		| 
						 | 
				
			
			@ -67,5 +67,11 @@ module Ameba::Rule
 | 
			
		|||
        rule.excluded?(Source.new "", "source.cr").should be_false
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    describe ".parsed_doc" do
 | 
			
		||||
      it "returns the parsed rule doc" do
 | 
			
		||||
        DummyRule.parsed_doc.should eq "Dummy Rule which does nothing."
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,6 +2,7 @@ require "spec"
 | 
			
		|||
require "../src/ameba"
 | 
			
		||||
 | 
			
		||||
module Ameba
 | 
			
		||||
  # Dummy Rule which does nothing.
 | 
			
		||||
  struct DummyRule < Rule::Base
 | 
			
		||||
    properties do
 | 
			
		||||
      description : String = "Dummy rule that does nothing."
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -120,6 +120,56 @@ module Ameba::Rule
 | 
			
		|||
    protected def self.subclasses
 | 
			
		||||
      {{ @type.subclasses }}
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    macro inherited
 | 
			
		||||
      protected def self.path_to_source_file
 | 
			
		||||
        __FILE__
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Returns documentation for this rule if any.
 | 
			
		||||
    #
 | 
			
		||||
    # ```
 | 
			
		||||
    # module Ameba
 | 
			
		||||
    #   # This is a test rule.
 | 
			
		||||
    #   # Does nothing.
 | 
			
		||||
    #   struct MyRule < Ameba::Rule::Base
 | 
			
		||||
    #     def test(source)
 | 
			
		||||
    #     end
 | 
			
		||||
    #   end
 | 
			
		||||
    # end
 | 
			
		||||
    #
 | 
			
		||||
    # MyRule.parsed_doc # => "This is a test rule.\nDoes nothing."
 | 
			
		||||
    # ```
 | 
			
		||||
    def self.parsed_doc
 | 
			
		||||
      source = File.read(path_to_source_file)
 | 
			
		||||
      nodes = Crystal::Parser.new(source).tap(&.wants_doc = true).parse
 | 
			
		||||
      type_name = rule_name.split("/").last?
 | 
			
		||||
      DocFinder.new(nodes, type_name).doc
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # :nodoc:
 | 
			
		||||
    private class DocFinder < Crystal::Visitor
 | 
			
		||||
      getter doc : String?
 | 
			
		||||
      getter type_name : String?
 | 
			
		||||
 | 
			
		||||
      def initialize(nodes, @type_name)
 | 
			
		||||
        self.accept(nodes)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def visit(node : Crystal::ASTNode)
 | 
			
		||||
        return false if @doc
 | 
			
		||||
 | 
			
		||||
        if node.responds_to?(:name) &&
 | 
			
		||||
           (name = node.name) &&
 | 
			
		||||
           name.is_a?(Crystal::Path) &&
 | 
			
		||||
           name.names.last? == @type_name
 | 
			
		||||
          @doc = node.doc
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        true
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  # Returns a list of all available rules.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue