yard-sequel 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/yard-sequel.rb +1 -0
- data/lib/yard-sequel/association_options.rb +56 -0
- data/lib/yard-sequel/associations/association_handler.rb +37 -5
- data/lib/yard-sequel/associations/many_to_one_handler.rb +4 -0
- data/lib/yard-sequel/associations/modules/dataset_method.rb +1 -2
- data/lib/yard-sequel/associations/modules/to_many_methods.rb +11 -11
- data/lib/yard-sequel/associations/modules/to_one_methods.rb +7 -7
- data/lib/yard-sequel/associations/one_to_many_handler.rb +4 -0
- data/lib/yard-sequel/ast_node_hash.rb +39 -2
- data/lib/yard-sequel/version.rb +2 -2
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: de753ba555cdc4d50a3529d696acfc430267520084be6be153350a53a7d6f0e0
|
4
|
+
data.tar.gz: a2a0b1b504e2e37dd52e484fdf8880186b13a7d7f28f4db8e11082cec38e86ec
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 18d50a853a958f1999996ecd350626c778a9be1c9288a37b45167927c8264e61bf5ac2521f7bf80501734dec183192cfac5d7bbcbc326f355dcf62c730810f0d
|
7
|
+
data.tar.gz: 222fcedd00f7b9be0f62ceffa307ca39ce62494447f4be0f76b86cb3ad8e13cad91c5321b0f325f5f5facc88a0d09fd73adf05352be3d10e4340630ee47a6071
|
data/lib/yard-sequel.rb
CHANGED
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module YardSequel
|
4
|
+
# Holds the options of an association macro call and makes them easily
|
5
|
+
# accessible.
|
6
|
+
# @author Kai Moschcau
|
7
|
+
class AssociationOptions
|
8
|
+
# @param [Hash<Yard::Parser::Ruby::AstNode>] ast_node_hash A Hash created
|
9
|
+
# with the {AstNodeHash} module, to get the options from.
|
10
|
+
def initialize(ast_node_hash)
|
11
|
+
@ast_node_hash = {}
|
12
|
+
ast_node_hash.each do |name, parameter|
|
13
|
+
@ast_node_hash[parse_symbol_node name] = parse_symbol_node parameter
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# @param [Symbol] option_name The name of the option, to get the parameter
|
18
|
+
# of.
|
19
|
+
# @return [Yard::Parser::Ruby::AstNode] the option parameter value.
|
20
|
+
def [](option_name)
|
21
|
+
@ast_node_hash[option_name]
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
# Extracts the String content of a Symbol literal AstNode as a Symbol. It
|
27
|
+
# gets the source, then removes the leading or trailing colon. Afterwards it
|
28
|
+
# removes the leading and trailing quotes, if there are any and returns the
|
29
|
+
# result as a Symbol.
|
30
|
+
# @param [Yard::Parser::Ruby::AstNode] ast_node The Symbol literal AstNode
|
31
|
+
# to get the content from.
|
32
|
+
# @return [Symbol] the Symbol literal's content as a Symbol.
|
33
|
+
def extract_symbol_content(ast_node)
|
34
|
+
ast_node.source.gsub(/(?:^:|:$)/, '').gsub(/(?:^['"]|['"]$)/, '').to_sym
|
35
|
+
end
|
36
|
+
|
37
|
+
# Parses a Symbol literal AstNode, if possible. This will return a Symbol
|
38
|
+
# with the Symbol literal's content String, if the literal is a Hash label,
|
39
|
+
# a normal Symbol literal or a dynamic Symbol literal without interpolation.
|
40
|
+
# @param [Yard::Parser::Ruby::AstNode] symbol_node The AstNode to get the
|
41
|
+
# content String from.
|
42
|
+
# @return [Symbol] the parsed Symbol.
|
43
|
+
# @return [Yard::Parser::Ruby::AstNode] the passed node, if it could not be
|
44
|
+
# parsed.
|
45
|
+
def parse_symbol_node(symbol_node)
|
46
|
+
if %i[symbol_literal label dyna_symbol].include? symbol_node.type
|
47
|
+
# Return if the literal contains interpolation
|
48
|
+
return symbol_node if symbol_node.jump(:string_embexpr) != symbol_node
|
49
|
+
|
50
|
+
return extract_symbol_content(symbol_node)
|
51
|
+
end
|
52
|
+
|
53
|
+
symbol_node
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -7,13 +7,14 @@ module YardSequel
|
|
7
7
|
class AssociationHandler < YARD::Handlers::Ruby::DSLHandler
|
8
8
|
def process
|
9
9
|
log.debug { "#{self.class.name}#process call" }
|
10
|
+
@association_options = association_options
|
10
11
|
end
|
11
12
|
|
12
13
|
protected
|
13
14
|
|
14
15
|
# Adds a parameter tag to a method object.
|
15
|
-
# @param [YARD::CodeObjects::MethodObject] method
|
16
|
-
#
|
16
|
+
# @param [YARD::CodeObjects::MethodObject] method The method to add the
|
17
|
+
# parameter tag to.
|
17
18
|
# @param [String] name The name of the parameter.
|
18
19
|
# @param [String] class_name The class name of the parameter.
|
19
20
|
# @param [String] description The description of the parameter.
|
@@ -25,15 +26,46 @@ module YardSequel
|
|
25
26
|
)
|
26
27
|
end
|
27
28
|
|
29
|
+
# @return [String] the association Class without namespace.
|
30
|
+
def association_class
|
31
|
+
class_param = @association_options&.[](:class)
|
32
|
+
return class_param.to_s.split('::').last if
|
33
|
+
[String, Symbol].include? class_param.class
|
34
|
+
|
35
|
+
association_name.classify
|
36
|
+
end
|
37
|
+
|
38
|
+
# @return [String] the namespace of the association class.
|
39
|
+
def association_class_namespace
|
40
|
+
class_namespace_param = @association_options&.[](:class_namespace)
|
41
|
+
return class_namespace_param.to_s if
|
42
|
+
[String, Symbol].include? class_namespace_param.class
|
43
|
+
|
44
|
+
class_param = @association_options&.[](:class)
|
45
|
+
return class_param.to_s.rpartition('::').first if
|
46
|
+
[String, Symbol].include? class_param.class
|
47
|
+
end
|
48
|
+
|
49
|
+
# @return [String] the association Class with namespace.
|
50
|
+
def association_full_class
|
51
|
+
[association_class_namespace, association_class].compact.join('::')
|
52
|
+
end
|
53
|
+
|
28
54
|
# @return [String] the name of the association
|
29
55
|
def association_name
|
30
56
|
@statement.parameters.first.jump(:ident).source
|
31
57
|
end
|
32
58
|
|
33
|
-
# @return [
|
34
|
-
#
|
59
|
+
# @return [nil] If the association does not have an options parameter or
|
60
|
+
# it is empty.
|
61
|
+
# @return [AssociationOptions] the AssociationOptions of the association.
|
35
62
|
def association_options
|
36
|
-
@statement.parameters[1]
|
63
|
+
option_param = @statement.parameters[1] || return
|
64
|
+
AssociationOptions.new AstNodeHash.from_ast(option_param)
|
65
|
+
rescue ArgumentError, TypeError => error
|
66
|
+
log.warn 'Could not parse association options due to syntax error.'
|
67
|
+
log.debug error.message
|
68
|
+
nil
|
37
69
|
end
|
38
70
|
|
39
71
|
# @param [String] name The name of the method object.
|
@@ -9,11 +9,15 @@ module YardSequel
|
|
9
9
|
include YardSequel::Associations::ToOneMethods
|
10
10
|
handles method_call(:many_to_one)
|
11
11
|
namespace_only
|
12
|
+
|
12
13
|
def process
|
13
14
|
super
|
15
|
+
original_group = extra_state.group
|
16
|
+
extra_state.group = "Many to one #{association_name} association"
|
14
17
|
create_to_one_getter
|
15
18
|
create_to_one_setter
|
16
19
|
create_dataset_method
|
20
|
+
extra_state.group = original_group
|
17
21
|
end
|
18
22
|
end
|
19
23
|
end
|
@@ -9,8 +9,7 @@ module YardSequel
|
|
9
9
|
# object.
|
10
10
|
def create_dataset_method
|
11
11
|
method = create_method_object("#{association_name}_dataset")
|
12
|
-
return_tag(method, 'Sequel::Dataset', 'the association\'s'
|
13
|
-
'dataset.')
|
12
|
+
return_tag(method, 'Sequel::Dataset', 'the association\'s dataset.')
|
14
13
|
method
|
15
14
|
end
|
16
15
|
end
|
@@ -10,12 +10,12 @@ module YardSequel
|
|
10
10
|
def create_to_many_adder
|
11
11
|
name = association_name
|
12
12
|
method = create_method_object "add_#{name.singularize}"
|
13
|
-
method.docstring += "Associates the passed #{
|
13
|
+
method.docstring += "Associates the passed #{association_class} "\
|
14
14
|
'with `self`.'
|
15
|
-
add_param_tag(method, name.singularize,
|
16
|
-
"The #{
|
17
|
-
return_tag(method,
|
18
|
-
"the associated #{
|
15
|
+
add_param_tag(method, name.singularize, association_full_class,
|
16
|
+
"The #{association_class} to associate with `self`.")
|
17
|
+
return_tag(method, association_full_class,
|
18
|
+
"the associated #{association_class}.")
|
19
19
|
method
|
20
20
|
end
|
21
21
|
|
@@ -25,7 +25,7 @@ module YardSequel
|
|
25
25
|
name = association_name
|
26
26
|
method = create_method_object "remove_all_#{name}"
|
27
27
|
method.docstring += 'Removes the association of all '\
|
28
|
-
"#{
|
28
|
+
"#{association_class.pluralize} with `self`."
|
29
29
|
void_return_tag method
|
30
30
|
method
|
31
31
|
end
|
@@ -35,8 +35,8 @@ module YardSequel
|
|
35
35
|
def create_to_many_getter
|
36
36
|
name = association_name
|
37
37
|
method = create_method_object name
|
38
|
-
return_tag(method, "Array<#{
|
39
|
-
"the associated #{
|
38
|
+
return_tag(method, "Array<#{association_full_class}>",
|
39
|
+
"the associated #{association_class.pluralize}.")
|
40
40
|
method
|
41
41
|
end
|
42
42
|
|
@@ -46,9 +46,9 @@ module YardSequel
|
|
46
46
|
name = association_name
|
47
47
|
method = create_method_object "remove_#{name.singularize}"
|
48
48
|
method.docstring += 'Removes the association of the passed '\
|
49
|
-
"#{
|
50
|
-
add_param_tag(method, name.singularize,
|
51
|
-
"The #{
|
49
|
+
"#{association_class} with `self`."
|
50
|
+
add_param_tag(method, name.singularize, association_full_class,
|
51
|
+
"The #{association_class} to remove the association "\
|
52
52
|
'with `self` from.')
|
53
53
|
void_return_tag method
|
54
54
|
method
|
@@ -10,8 +10,8 @@ module YardSequel
|
|
10
10
|
def create_to_one_getter
|
11
11
|
name = association_name
|
12
12
|
method = create_method_object name
|
13
|
-
return_tag(method,
|
14
|
-
"the associated #{
|
13
|
+
return_tag(method, association_full_class,
|
14
|
+
"the associated #{association_class}.")
|
15
15
|
method
|
16
16
|
end
|
17
17
|
|
@@ -20,12 +20,12 @@ module YardSequel
|
|
20
20
|
def create_to_one_setter
|
21
21
|
name = association_name
|
22
22
|
method = create_method_object "#{name}="
|
23
|
-
method.docstring += "Associates the passed #{
|
23
|
+
method.docstring += "Associates the passed #{association_class} "\
|
24
24
|
'with `self`.'
|
25
|
-
add_param_tag(method, name,
|
26
|
-
"The #{
|
27
|
-
return_tag(method,
|
28
|
-
"the associated #{
|
25
|
+
add_param_tag(method, name, association_full_class,
|
26
|
+
"The #{association_class} to associate with `self`.")
|
27
|
+
return_tag(method, association_full_class,
|
28
|
+
"the associated #{association_class}.")
|
29
29
|
method
|
30
30
|
end
|
31
31
|
end
|
@@ -9,13 +9,17 @@ module YardSequel
|
|
9
9
|
include YardSequel::Associations::ToManyMethods
|
10
10
|
handles method_call(:one_to_many)
|
11
11
|
namespace_only
|
12
|
+
|
12
13
|
def process
|
13
14
|
super
|
15
|
+
original_group = extra_state.group
|
16
|
+
extra_state.group = "One to many #{association_name} association"
|
14
17
|
create_to_many_adder
|
15
18
|
create_to_many_clearer
|
16
19
|
create_to_many_getter
|
17
20
|
create_to_many_remover
|
18
21
|
create_dataset_method
|
22
|
+
extra_state.group = original_group
|
19
23
|
end
|
20
24
|
end
|
21
25
|
end
|
@@ -1,16 +1,26 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module YardSequel
|
4
|
-
# Offers methods to convert an Abstract Syntax Tree
|
5
|
-
# of `YARD::Parser::Ruby::AstNode`s.
|
4
|
+
# Offers methods to convert an Abstract Syntax Tree of a Hash literal or named
|
5
|
+
# method parameters to a Hash consisting of `YARD::Parser::Ruby::AstNode`s.
|
6
6
|
# @author Kai Moschcau
|
7
7
|
module AstNodeHash
|
8
8
|
class << self
|
9
|
+
# Creates a new Hash from the passed AstNode. This is the main method to
|
10
|
+
# use, to create a new Hash.
|
11
|
+
# @param (see .node_hash_from_node)
|
12
|
+
# @raise (see .check_ast)
|
13
|
+
# @return (see .node_hash_from_node)
|
9
14
|
def from_ast(ast)
|
10
15
|
check_ast ast
|
11
16
|
node_hash_from_node ast
|
12
17
|
end
|
13
18
|
|
19
|
+
# Checks the passed AstNode for validity. If the AstNode is valid, this
|
20
|
+
# method does not raise an error.
|
21
|
+
# @raise [TypeError, ArgumentError] If the AstNode is not valid.
|
22
|
+
# @param [YARD::Parser::Ruby::AstNode] ast The AstNode to check for
|
23
|
+
# validity.
|
14
24
|
def check_ast(ast)
|
15
25
|
check_is_ast_node ast
|
16
26
|
check_is_hash_or_list ast
|
@@ -22,12 +32,19 @@ module YardSequel
|
|
22
32
|
|
23
33
|
private
|
24
34
|
|
35
|
+
# Checks if the given child AstNode has exactly two children.
|
36
|
+
# @raise [ArgumentError] If if does not have 2 children.
|
37
|
+
# @return [void]
|
25
38
|
def check_assoc_child_has_two_children(child_ast)
|
26
39
|
return if child_ast.children.size == 2
|
27
40
|
|
28
41
|
raise(ArgumentError, 'each `:assoc` child must have two children')
|
29
42
|
end
|
30
43
|
|
44
|
+
# Checks the children of the given AstNode. Mainly it first checks, if the
|
45
|
+
# AstNode has only `:assoc` type children and if each child has two
|
46
|
+
# further children.
|
47
|
+
# @return [void]
|
31
48
|
def check_children(ast)
|
32
49
|
check_has_only_assoc_children ast
|
33
50
|
ast.children.each do |child_ast|
|
@@ -35,6 +52,9 @@ module YardSequel
|
|
35
52
|
end
|
36
53
|
end
|
37
54
|
|
55
|
+
# Checks if the children of the passed AstNode are all of type `:assoc`.
|
56
|
+
# @raise [ArgumentError] If there is at least one not of type `:assoc`.
|
57
|
+
# @return [void]
|
38
58
|
def check_has_only_assoc_children(ast)
|
39
59
|
return unless ast.children.any? { |child| child.type != :assoc }
|
40
60
|
|
@@ -42,12 +62,18 @@ module YardSequel
|
|
42
62
|
'all children of the passed `ast` have to have the type `:assoc`')
|
43
63
|
end
|
44
64
|
|
65
|
+
# Checks the children of a `:hash` type AstNode. If the AstNode has no
|
66
|
+
# children, this does nothing. Otherwise it runs {.check_children}.
|
67
|
+
# @return [void]
|
45
68
|
def check_hash_children(ast)
|
46
69
|
return if ast.children.empty?
|
47
70
|
|
48
71
|
check_children ast
|
49
72
|
end
|
50
73
|
|
74
|
+
# Checks, whether the passed Object is a `YARD::Parser::Ruby::AstNode`.
|
75
|
+
# @raise [TypeError] If the passed Object is not of the correct type.
|
76
|
+
# @return [void]
|
51
77
|
def check_is_ast_node(ast)
|
52
78
|
return if ast.is_a? YARD::Parser::Ruby::AstNode
|
53
79
|
|
@@ -55,6 +81,9 @@ module YardSequel
|
|
55
81
|
'the passed `ast` has to be a `YARD::Parser::Ruby::AstNode`')
|
56
82
|
end
|
57
83
|
|
84
|
+
# Checks, whether the passed AstNode is of Type `:hash` or `:list`.
|
85
|
+
# @raise [ArgumentError] If the passed AstNode is not of the correct type.
|
86
|
+
# @return [void]
|
58
87
|
def check_is_hash_or_list(ast)
|
59
88
|
return if %i[hash list].include? ast.type
|
60
89
|
|
@@ -62,6 +91,10 @@ module YardSequel
|
|
62
91
|
"the passed `ast`'s type has to be `:hash` or `:list`")
|
63
92
|
end
|
64
93
|
|
94
|
+
# Checks the children of a `:list` type AstNode. If the AstNode has no
|
95
|
+
# children, this raises an error. Otherwise it runs {.check_children}.
|
96
|
+
# @raise [ArgumentError] If the passed AstNode has no children.
|
97
|
+
# @return [void]
|
65
98
|
def check_list_children(ast)
|
66
99
|
if ast.children.empty?
|
67
100
|
raise(ArgumentError,
|
@@ -70,6 +103,10 @@ module YardSequel
|
|
70
103
|
check_children ast
|
71
104
|
end
|
72
105
|
|
106
|
+
# Converts the passed AstNode to a Hash.
|
107
|
+
# @param [YARD::Parser::Ruby::AstNode] ast The AstNode to convert to a
|
108
|
+
# Hash.
|
109
|
+
# @return [Hash<YARD::Parser::Ruby::AstNode>] the converted Hash.
|
73
110
|
def node_hash_from_node(ast)
|
74
111
|
hash = {}
|
75
112
|
ast.children.each { |cn| hash[cn.children[0]] = cn.children[1] }
|
data/lib/yard-sequel/version.rb
CHANGED
@@ -7,11 +7,11 @@ module YardSequel
|
|
7
7
|
|
8
8
|
# The minor version number.
|
9
9
|
# Used for changes that are backwards compatible.
|
10
|
-
V_MINOR =
|
10
|
+
V_MINOR = 2
|
11
11
|
|
12
12
|
# The build version number.
|
13
13
|
# Used for internal changes.
|
14
|
-
V_BUILD =
|
14
|
+
V_BUILD = 0
|
15
15
|
|
16
16
|
# The version of the Sequel models.
|
17
17
|
VERSION = Gem::Version.new("#{V_MAJOR}.#{V_MINOR}.#{V_BUILD}")
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: yard-sequel
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kai Moschcau
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-12-
|
11
|
+
date: 2018-12-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: coveralls
|
@@ -122,6 +122,7 @@ extra_rdoc_files: []
|
|
122
122
|
files:
|
123
123
|
- ".yardopts"
|
124
124
|
- lib/yard-sequel.rb
|
125
|
+
- lib/yard-sequel/association_options.rb
|
125
126
|
- lib/yard-sequel/associations.rb
|
126
127
|
- lib/yard-sequel/associations/association_handler.rb
|
127
128
|
- lib/yard-sequel/associations/many_to_one_handler.rb
|