mirror of
https://gitea.invidious.io/iv-org/shard-ameba.git
synced 2024-08-15 00:53:29 +00:00
Populate Rule::Base+.parsed_doc
on compile time
This commit is contained in:
parent
cac1ce4138
commit
3d61254739
2 changed files with 54 additions and 50 deletions
|
@ -138,13 +138,15 @@ module Ameba::Rule
|
|||
end
|
||||
end
|
||||
|
||||
macro inherited
|
||||
protected def self.path_to_source_file
|
||||
__FILE__
|
||||
end
|
||||
private macro read_rule_doc(filepath = __FILE__)
|
||||
{{ run("../../read_rule_doc",
|
||||
@type.name.split("::").last,
|
||||
filepath
|
||||
).chomp.stringify }}.presence
|
||||
end
|
||||
|
||||
# Returns documentation for this rule if any.
|
||||
macro inherited
|
||||
# Returns documentation for this rule, if there is any.
|
||||
#
|
||||
# ```
|
||||
# module Ameba
|
||||
|
@ -158,37 +160,7 @@ module Ameba::Rule
|
|||
#
|
||||
# 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
|
||||
class_getter parsed_doc : String? = read_rule_doc
|
||||
end
|
||||
end
|
||||
|
||||
|
|
32
src/read_rule_doc.cr
Normal file
32
src/read_rule_doc.cr
Normal file
|
@ -0,0 +1,32 @@
|
|||
require "compiler/crystal/syntax/*"
|
||||
|
||||
private class DocFinder < Crystal::Visitor
|
||||
getter type_name : String?
|
||||
getter doc : 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
|
||||
|
||||
type_name, path_to_source_file = ARGV
|
||||
|
||||
source = File.read(path_to_source_file)
|
||||
nodes = Crystal::Parser.new(source)
|
||||
.tap(&.wants_doc = true)
|
||||
.parse
|
||||
|
||||
puts DocFinder.new(nodes, type_name).doc
|
Loading…
Reference in a new issue