yard-sequel 0.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|