solargraph 0.58.0 → 0.59.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.
Files changed (219) hide show
  1. checksums.yaml +4 -4
  2. data/.envrc +3 -0
  3. data/.gitattributes +2 -0
  4. data/.github/workflows/linting.yml +6 -5
  5. data/.github/workflows/plugins.yml +48 -35
  6. data/.github/workflows/rspec.yml +15 -28
  7. data/.github/workflows/typecheck.yml +3 -2
  8. data/.gitignore +1 -0
  9. data/.rubocop.yml +38 -6
  10. data/.rubocop_todo.yml +53 -966
  11. data/CHANGELOG.md +24 -0
  12. data/Gemfile +3 -1
  13. data/README.md +3 -3
  14. data/Rakefile +26 -23
  15. data/bin/solargraph +9 -8
  16. data/lib/solargraph/api_map/cache.rb +110 -110
  17. data/lib/solargraph/api_map/constants.rb +288 -279
  18. data/lib/solargraph/api_map/index.rb +204 -193
  19. data/lib/solargraph/api_map/source_to_yard.rb +110 -97
  20. data/lib/solargraph/api_map/store.rb +395 -384
  21. data/lib/solargraph/api_map.rb +1029 -945
  22. data/lib/solargraph/bench.rb +44 -45
  23. data/lib/solargraph/complex_type/conformance.rb +176 -0
  24. data/lib/solargraph/complex_type/type_methods.rb +240 -228
  25. data/lib/solargraph/complex_type/unique_type.rb +641 -482
  26. data/lib/solargraph/complex_type.rb +557 -444
  27. data/lib/solargraph/convention/data_definition/data_assignment_node.rb +61 -61
  28. data/lib/solargraph/convention/data_definition/data_definition_node.rb +93 -91
  29. data/lib/solargraph/convention/data_definition.rb +108 -105
  30. data/lib/solargraph/convention/gemfile.rb +15 -15
  31. data/lib/solargraph/convention/gemspec.rb +23 -23
  32. data/lib/solargraph/convention/rakefile.rb +17 -17
  33. data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +62 -61
  34. data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +103 -102
  35. data/lib/solargraph/convention/struct_definition.rb +168 -164
  36. data/lib/solargraph/convention.rb +78 -78
  37. data/lib/solargraph/converters/dd.rb +19 -17
  38. data/lib/solargraph/converters/dl.rb +17 -15
  39. data/lib/solargraph/converters/dt.rb +17 -15
  40. data/lib/solargraph/converters/misc.rb +3 -1
  41. data/lib/solargraph/diagnostics/require_not_found.rb +54 -53
  42. data/lib/solargraph/diagnostics/rubocop.rb +119 -118
  43. data/lib/solargraph/diagnostics/rubocop_helpers.rb +70 -68
  44. data/lib/solargraph/diagnostics/type_check.rb +56 -55
  45. data/lib/solargraph/diagnostics/update_errors.rb +37 -41
  46. data/lib/solargraph/doc_map.rb +438 -439
  47. data/lib/solargraph/equality.rb +34 -34
  48. data/lib/solargraph/gem_pins.rb +98 -98
  49. data/lib/solargraph/language_server/error_codes.rb +20 -20
  50. data/lib/solargraph/language_server/host/diagnoser.rb +89 -89
  51. data/lib/solargraph/language_server/host/dispatch.rb +130 -130
  52. data/lib/solargraph/language_server/host/message_worker.rb +113 -112
  53. data/lib/solargraph/language_server/host/sources.rb +100 -99
  54. data/lib/solargraph/language_server/host.rb +886 -878
  55. data/lib/solargraph/language_server/message/base.rb +97 -97
  56. data/lib/solargraph/language_server/message/client/register_capability.rb +13 -15
  57. data/lib/solargraph/language_server/message/completion_item/resolve.rb +58 -60
  58. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +108 -114
  59. data/lib/solargraph/language_server/message/extended/document.rb +24 -23
  60. data/lib/solargraph/language_server/message/extended/document_gems.rb +32 -32
  61. data/lib/solargraph/language_server/message/extended/download_core.rb +20 -19
  62. data/lib/solargraph/language_server/message/extended/search.rb +20 -20
  63. data/lib/solargraph/language_server/message/initialize.rb +197 -191
  64. data/lib/solargraph/language_server/message/text_document/completion.rb +58 -56
  65. data/lib/solargraph/language_server/message/text_document/definition.rb +49 -40
  66. data/lib/solargraph/language_server/message/text_document/document_highlight.rb +23 -16
  67. data/lib/solargraph/language_server/message/text_document/document_symbol.rb +36 -26
  68. data/lib/solargraph/language_server/message/text_document/formatting.rb +150 -148
  69. data/lib/solargraph/language_server/message/text_document/hover.rb +58 -58
  70. data/lib/solargraph/language_server/message/text_document/prepare_rename.rb +18 -11
  71. data/lib/solargraph/language_server/message/text_document/references.rb +23 -16
  72. data/lib/solargraph/language_server/message/text_document/rename.rb +26 -19
  73. data/lib/solargraph/language_server/message/text_document/signature_help.rb +25 -24
  74. data/lib/solargraph/language_server/message/text_document/type_definition.rb +33 -25
  75. data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +41 -35
  76. data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +48 -40
  77. data/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb +32 -26
  78. data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +33 -23
  79. data/lib/solargraph/language_server/message.rb +94 -94
  80. data/lib/solargraph/language_server/request.rb +29 -27
  81. data/lib/solargraph/language_server/transport/data_reader.rb +72 -74
  82. data/lib/solargraph/language_server/uri_helpers.rb +49 -49
  83. data/lib/solargraph/library.rb +702 -683
  84. data/lib/solargraph/location.rb +85 -82
  85. data/lib/solargraph/logging.rb +55 -37
  86. data/lib/solargraph/page.rb +92 -92
  87. data/lib/solargraph/parser/comment_ripper.rb +84 -69
  88. data/lib/solargraph/parser/flow_sensitive_typing.rb +471 -255
  89. data/lib/solargraph/parser/node_processor/base.rb +122 -92
  90. data/lib/solargraph/parser/node_processor.rb +63 -62
  91. data/lib/solargraph/parser/parser_gem/class_methods.rb +165 -149
  92. data/lib/solargraph/parser/parser_gem/flawed_builder.rb +19 -19
  93. data/lib/solargraph/parser/parser_gem/node_chainer.rb +191 -166
  94. data/lib/solargraph/parser/parser_gem/node_methods.rb +507 -486
  95. data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +22 -22
  96. data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +61 -59
  97. data/lib/solargraph/parser/parser_gem/node_processors/begin_node.rb +24 -15
  98. data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +45 -46
  99. data/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +60 -53
  100. data/lib/solargraph/parser/parser_gem/node_processors/defs_node.rb +38 -37
  101. data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +53 -23
  102. data/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb +42 -40
  103. data/lib/solargraph/parser/parser_gem/node_processors/lvasgn_node.rb +30 -29
  104. data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +61 -59
  105. data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +98 -98
  106. data/lib/solargraph/parser/parser_gem/node_processors/or_node.rb +22 -0
  107. data/lib/solargraph/parser/parser_gem/node_processors/orasgn_node.rb +17 -17
  108. data/lib/solargraph/parser/parser_gem/node_processors/resbody_node.rb +39 -38
  109. data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +51 -52
  110. data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +302 -291
  111. data/lib/solargraph/parser/parser_gem/node_processors/until_node.rb +29 -29
  112. data/lib/solargraph/parser/parser_gem/node_processors/when_node.rb +23 -0
  113. data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +33 -29
  114. data/lib/solargraph/parser/parser_gem/node_processors.rb +74 -70
  115. data/lib/solargraph/parser/parser_gem.rb +14 -12
  116. data/lib/solargraph/parser/region.rb +75 -69
  117. data/lib/solargraph/parser/snippet.rb +19 -17
  118. data/lib/solargraph/parser.rb +25 -23
  119. data/lib/solargraph/pin/base.rb +773 -729
  120. data/lib/solargraph/pin/base_variable.rb +375 -126
  121. data/lib/solargraph/pin/block.rb +127 -104
  122. data/lib/solargraph/pin/breakable.rb +15 -9
  123. data/lib/solargraph/pin/callable.rb +275 -231
  124. data/lib/solargraph/pin/closure.rb +69 -72
  125. data/lib/solargraph/pin/common.rb +97 -79
  126. data/lib/solargraph/pin/compound_statement.rb +55 -0
  127. data/lib/solargraph/pin/constant.rb +43 -45
  128. data/lib/solargraph/pin/conversions.rb +129 -123
  129. data/lib/solargraph/pin/delegated_method.rb +131 -120
  130. data/lib/solargraph/pin/documenting.rb +116 -114
  131. data/lib/solargraph/pin/instance_variable.rb +38 -34
  132. data/lib/solargraph/pin/keyword.rb +16 -20
  133. data/lib/solargraph/pin/local_variable.rb +31 -75
  134. data/lib/solargraph/pin/method.rb +724 -672
  135. data/lib/solargraph/pin/method_alias.rb +42 -34
  136. data/lib/solargraph/pin/namespace.rb +122 -115
  137. data/lib/solargraph/pin/parameter.rb +339 -275
  138. data/lib/solargraph/pin/proxy_type.rb +42 -39
  139. data/lib/solargraph/pin/reference/override.rb +47 -47
  140. data/lib/solargraph/pin/reference/superclass.rb +17 -15
  141. data/lib/solargraph/pin/reference/type_alias.rb +16 -0
  142. data/lib/solargraph/pin/reference.rb +59 -39
  143. data/lib/solargraph/pin/search.rb +62 -61
  144. data/lib/solargraph/pin/signature.rb +64 -61
  145. data/lib/solargraph/pin/symbol.rb +54 -53
  146. data/lib/solargraph/pin/until.rb +16 -18
  147. data/lib/solargraph/pin/while.rb +16 -18
  148. data/lib/solargraph/pin.rb +46 -44
  149. data/lib/solargraph/pin_cache.rb +248 -245
  150. data/lib/solargraph/position.rb +139 -119
  151. data/lib/solargraph/range.rb +113 -112
  152. data/lib/solargraph/rbs_map/conversions.rb +952 -823
  153. data/lib/solargraph/rbs_map/core_fills.rb +91 -84
  154. data/lib/solargraph/rbs_map/core_map.rb +65 -58
  155. data/lib/solargraph/rbs_map/stdlib_map.rb +71 -43
  156. data/lib/solargraph/rbs_map.rb +207 -163
  157. data/lib/solargraph/server_methods.rb +16 -16
  158. data/lib/solargraph/shell.rb +555 -352
  159. data/lib/solargraph/source/chain/array.rb +39 -37
  160. data/lib/solargraph/source/chain/call.rb +377 -337
  161. data/lib/solargraph/source/chain/class_variable.rb +13 -13
  162. data/lib/solargraph/source/chain/constant.rb +30 -26
  163. data/lib/solargraph/source/chain/global_variable.rb +13 -13
  164. data/lib/solargraph/source/chain/hash.rb +37 -34
  165. data/lib/solargraph/source/chain/if.rb +30 -28
  166. data/lib/solargraph/source/chain/instance_variable.rb +36 -13
  167. data/lib/solargraph/source/chain/link.rb +99 -109
  168. data/lib/solargraph/source/chain/literal.rb +51 -48
  169. data/lib/solargraph/source/chain/or.rb +29 -23
  170. data/lib/solargraph/source/chain/q_call.rb +13 -11
  171. data/lib/solargraph/source/chain/variable.rb +15 -13
  172. data/lib/solargraph/source/chain/z_super.rb +28 -30
  173. data/lib/solargraph/source/chain.rb +304 -291
  174. data/lib/solargraph/source/change.rb +89 -82
  175. data/lib/solargraph/source/cursor.rb +172 -166
  176. data/lib/solargraph/source/encoding_fixes.rb +22 -23
  177. data/lib/solargraph/source/source_chainer.rb +218 -194
  178. data/lib/solargraph/source/updater.rb +59 -55
  179. data/lib/solargraph/source.rb +522 -498
  180. data/lib/solargraph/source_map/clip.rb +245 -226
  181. data/lib/solargraph/source_map/data.rb +37 -34
  182. data/lib/solargraph/source_map/mapper.rb +286 -259
  183. data/lib/solargraph/source_map.rb +224 -212
  184. data/lib/solargraph/type_checker/problem.rb +34 -32
  185. data/lib/solargraph/type_checker/rules.rb +157 -84
  186. data/lib/solargraph/type_checker.rb +888 -814
  187. data/lib/solargraph/version.rb +5 -5
  188. data/lib/solargraph/workspace/config.rb +258 -255
  189. data/lib/solargraph/workspace/gemspecs.rb +367 -0
  190. data/lib/solargraph/workspace/require_paths.rb +98 -97
  191. data/lib/solargraph/workspace.rb +242 -220
  192. data/lib/solargraph/yard_map/helpers.rb +49 -44
  193. data/lib/solargraph/yard_map/mapper/to_method.rb +136 -130
  194. data/lib/solargraph/yard_map/mapper/to_namespace.rb +32 -31
  195. data/lib/solargraph/yard_map/mapper.rb +84 -79
  196. data/lib/solargraph/yard_map.rb +17 -18
  197. data/lib/solargraph/yard_tags.rb +20 -20
  198. data/lib/solargraph/yardoc.rb +90 -87
  199. data/lib/solargraph.rb +128 -105
  200. data/rbs/fills/rubygems/0/dependency.rbs +193 -0
  201. data/rbs/fills/tuple/tuple.rbs +28 -0
  202. data/rbs/shims/ast/0/node.rbs +5 -0
  203. data/rbs/shims/diff-lcs/1.5/diff-lcs.rbs +11 -0
  204. data/rbs_collection.yaml +1 -1
  205. data/solargraph.gemspec +37 -35
  206. metadata +52 -51
  207. data/lib/solargraph/type_checker/checks.rb +0 -124
  208. data/lib/solargraph/type_checker/param_def.rb +0 -37
  209. data/lib/solargraph/yard_map/to_method.rb +0 -89
  210. data/sig/shims/ast/0/node.rbs +0 -5
  211. /data/{sig → rbs}/shims/ast/2.4/.rbs_meta.yaml +0 -0
  212. /data/{sig → rbs}/shims/ast/2.4/ast.rbs +0 -0
  213. /data/{sig → rbs}/shims/parser/3.2.0.1/builders/default.rbs +0 -0
  214. /data/{sig → rbs}/shims/parser/3.2.0.1/manifest.yaml +0 -0
  215. /data/{sig → rbs}/shims/parser/3.2.0.1/parser.rbs +0 -0
  216. /data/{sig → rbs}/shims/parser/3.2.0.1/polyfill.rbs +0 -0
  217. /data/{sig → rbs}/shims/thor/1.2.0.1/.rbs_meta.yaml +0 -0
  218. /data/{sig → rbs}/shims/thor/1.2.0.1/manifest.yaml +0 -0
  219. /data/{sig → rbs}/shims/thor/1.2.0.1/thor.rbs +0 -0
@@ -1,84 +1,157 @@
1
- # frozen_string_literal: true
2
-
3
- module Solargraph
4
- class TypeChecker
5
- # Definitions of type checking rules to be performed at various levels
6
- #
7
- class Rules
8
- LEVELS = {
9
- normal: 0,
10
- typed: 1,
11
- strict: 2,
12
- strong: 3,
13
- alpha: 4
14
- }.freeze
15
-
16
- # @return [Symbol]
17
- attr_reader :level
18
-
19
- # @return [Integer]
20
- attr_reader :rank
21
-
22
- # @param level [Symbol]
23
- # @param overrides [Hash{Symbol => Symbol}]
24
- def initialize level, overrides
25
- @rank = if LEVELS.key?(level)
26
- LEVELS[level]
27
- else
28
- Solargraph.logger.warn "Unrecognized TypeChecker level #{level}, assuming normal"
29
- 0
30
- end
31
- @level = LEVELS[LEVELS.values.index(@rank)]
32
- @overrides = overrides
33
- end
34
-
35
- def ignore_all_undefined?
36
- !report_undefined?
37
- end
38
-
39
- def report_undefined?
40
- report?(:report_undefined, :strict)
41
- end
42
-
43
- def validate_consts?
44
- report?(:validate_consts, :strict)
45
- end
46
-
47
- def validate_calls?
48
- report?(:validate_calls, :strict)
49
- end
50
-
51
- def require_type_tags?
52
- report?(:validate_type_tags, :strong)
53
- end
54
-
55
- def must_tag_or_infer?
56
- report?(:must_tag_or_infer, :strict)
57
- end
58
-
59
- def validate_tags?
60
- report?(:validate_tags, :typed)
61
- end
62
-
63
- def require_all_return_types_match_inferred?
64
- report?(:require_all_return_types_match_inferred, :alpha)
65
- end
66
-
67
- # We keep this at strong because if you added an @ sg-ignore to
68
- # address a strong-level issue, then ran at a lower level, you'd
69
- # get a false positive - we don't run stronger level checks than
70
- # requested for performance reasons
71
- def validate_sg_ignores?
72
- report?(:validate_sg_ignores, :strong)
73
- end
74
-
75
- private
76
-
77
- # @param type [Symbol]
78
- # @param level [Symbol]
79
- def report?(type, level)
80
- rank >= LEVELS[@overrides.fetch(type, level)]
81
- end
82
- end
83
- end
84
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ class TypeChecker
5
+ # Definitions of type checking rules to be performed at various levels
6
+ #
7
+ class Rules
8
+ LEVELS = {
9
+ normal: 0,
10
+ typed: 1,
11
+ strict: 2,
12
+ strong: 3,
13
+ alpha: 4
14
+ }.freeze
15
+
16
+ # @return [Symbol]
17
+ attr_reader :level
18
+
19
+ # @return [Integer]
20
+ attr_reader :rank
21
+
22
+ # @param level [Symbol]
23
+ # @param overrides [Hash{Symbol => Symbol}]
24
+ def initialize level, overrides
25
+ @rank = if LEVELS.key?(level)
26
+ LEVELS[level]
27
+ else
28
+ Solargraph.logger.warn "Unrecognized TypeChecker level #{level}, assuming normal"
29
+ 0
30
+ end
31
+ @level = LEVELS[LEVELS.values.index(@rank)]
32
+ @overrides = overrides
33
+ end
34
+
35
+ def ignore_all_undefined?
36
+ !report_undefined?
37
+ end
38
+
39
+ def report_undefined?
40
+ report?(:report_undefined, :strict)
41
+ end
42
+
43
+ def validate_consts?
44
+ report?(:validate_consts, :strict)
45
+ end
46
+
47
+ def validate_calls?
48
+ report?(:validate_calls, :strict)
49
+ end
50
+
51
+ def require_type_tags?
52
+ report?(:validate_type_tags, :strong)
53
+ end
54
+
55
+ def must_tag_or_infer?
56
+ report?(:must_tag_or_infer, :strict)
57
+ end
58
+
59
+ def validate_tags?
60
+ report?(:validate_tags, :typed)
61
+ end
62
+
63
+ def require_inferred_type_params?
64
+ report?(:require_inferred_type_params, :alpha)
65
+ end
66
+
67
+ #
68
+ # False negatives:
69
+ #
70
+ # @todo 4: Missed nil violation
71
+ #
72
+ # pending code fixes (277):
73
+ #
74
+ # @todo 281: Need to add nil check here
75
+ # @todo 22: Translate to something flow sensitive typing understands
76
+ # @todo 3: Need a downcast here
77
+ #
78
+ # flow sensitive typing could handle (96):
79
+ #
80
+ # @todo 36: flow sensitive typing needs to handle attrs
81
+ # @todo 29: flow sensitive typing should be able to handle redefinition
82
+ # @todo 19: flow sensitive typing needs to narrow down type with an if is_a? check
83
+ # @todo 13: Need to validate config
84
+ # @todo 8: flow sensitive typing should support .class == .class
85
+ # @todo 6: need boolish support for ? methods
86
+ # @todo 6: flow sensitive typing needs better handling of ||= on lvars
87
+ # @todo 5: literal arrays in this module turn into ::Solargraph::Source::Chain::Array
88
+ # @todo 5: flow sensitive typing needs to handle 'raise if'
89
+ # @todo 4: flow sensitive typing needs to eliminate literal from union with [:bar].include?(foo)
90
+ # @todo 4: nil? support in flow sensitive typing
91
+ # @todo 3: flow sensitive typing ought to be able to handle 'when ClassName'
92
+ # @todo 2: downcast output of Enumerable#select
93
+ # @todo 2: flow sensitive typing should handle return nil if location&.name.nil?
94
+ # @todo 2: flow sensitive typing should handle is_a? and next
95
+ # @todo 2: Need to look at Tuple#include? handling
96
+ # @todo 2: Should better support meaning of '&' in RBS
97
+ # @todo 2: (*) flow sensitive typing needs to handle "if foo = bar"
98
+ # @todo 2: flow sensitive typing needs to handle "if foo = bar"
99
+ # @todo 2: Need to handle duck-typed method calls on union types
100
+ # @todo 2: Need better handling of #compact
101
+ # @todo 2: flow sensitive typing should allow shadowing of Kernel#caller
102
+ # @todo 1: flow sensitive typing not smart enough to handle this case
103
+ # @todo 1: flow sensitive typing needs to handle if foo = bar
104
+ # @todo 1: flow sensitive typing needs to handle "if foo.nil?"
105
+ # @todo 1: flow sensitive typing should support case/when
106
+ # @todo 1: flow sensitive typing should support ivars
107
+ # @todo 1: Need to support this in flow sensitive typing
108
+ # @todo 1: flow sensitive typing needs to handle self.class == other.class
109
+ # @todo 1: flow sensitive typing needs to remove literal with
110
+ # @todo 1: flow sensitive typing needs to understand reassignment
111
+ # @todo 1: flow sensitive typing should be able to identify more blocks that always return
112
+ # @todo 1: should warn on nil dereference below
113
+ # @todo 1: flow sensitive typing needs to create separate ranges for postfix if
114
+ # @todo 1: flow sensitive typing needs to handle constants
115
+ # @todo 1: flow sensitive typing needs to eliminate literal from union with return if foo == :bar
116
+ def require_all_unique_types_match_expected?
117
+ report?(:require_all_unique_types_match_expected, :strong)
118
+ end
119
+
120
+ def require_all_unique_types_support_call?
121
+ report?(:require_all_unique_types_support_call, :strong)
122
+ end
123
+
124
+ def require_no_undefined_args?
125
+ report?(:require_no_undefined_args, :alpha)
126
+ end
127
+
128
+ def require_generics_resolved?
129
+ report?(:require_generics_resolved, :alpha)
130
+ end
131
+
132
+ def require_interfaces_resolved?
133
+ report?(:require_interfaces_resolved, :alpha)
134
+ end
135
+
136
+ def require_downcasts?
137
+ report?(:require_downcasts, :alpha)
138
+ end
139
+
140
+ # We keep this at strong because if you added an @ sg-ignore to
141
+ # address a strong-level issue, then ran at a lower level, you'd
142
+ # get a false positive - we don't run stronger level checks than
143
+ # requested for performance reasons
144
+ def validate_sg_ignores?
145
+ report?(:validate_sg_ignores, :strong)
146
+ end
147
+
148
+ private
149
+
150
+ # @param type [Symbol]
151
+ # @param level [Symbol]
152
+ def report? type, level
153
+ rank >= LEVELS[@overrides.fetch(type, level)]
154
+ end
155
+ end
156
+ end
157
+ end