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
|
rule.excluded?(Source.new "", "source.cr").should be_false
|
||||||
end
|
end
|
||||||
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
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,6 +2,7 @@ require "spec"
|
||||||
require "../src/ameba"
|
require "../src/ameba"
|
||||||
|
|
||||||
module Ameba
|
module Ameba
|
||||||
|
# Dummy Rule which does nothing.
|
||||||
struct DummyRule < Rule::Base
|
struct DummyRule < Rule::Base
|
||||||
properties do
|
properties do
|
||||||
description : String = "Dummy rule that does nothing."
|
description : String = "Dummy rule that does nothing."
|
||||||
|
|
|
@ -120,6 +120,56 @@ module Ameba::Rule
|
||||||
protected def self.subclasses
|
protected def self.subclasses
|
||||||
{{ @type.subclasses }}
|
{{ @type.subclasses }}
|
||||||
end
|
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
|
end
|
||||||
|
|
||||||
# Returns a list of all available rules.
|
# Returns a list of all available rules.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue