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…
Reference in a new issue