solargraph-rails 1.0.0.pre.1 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 134394397585a1df968b364e98d20b8e38a2fb6294833bfe8bbcfb81b13c545f
4
- data.tar.gz: cb4e7fe2906a0769c95e8a3e7de08b6d0188b4dd8d509db2e001006e9367e6db
3
+ metadata.gz: 674da2b5a3f833920c2c92893cfa936cb430e23e0bae6a7712b91cebe4b2815f
4
+ data.tar.gz: e7950faaeacc82868a4d91ceba186fc31aa78a6fe5e257969e9907ceb2b54656
5
5
  SHA512:
6
- metadata.gz: c7acc8b51be9a665bcca385a67bcee5eed0ffd9e697c155bfab4e5e94dcd691cb4ccab4f04c09306166c99e9802e3276e9895374540d3df7b3c979c59be582d4
7
- data.tar.gz: 4de5589904080422ed72fec8d76e4679a53df812f551c7e99d5d0e6fc7a6cabefe5256a6403dab04ae96e0fd79ec85c92f7a171502202afdb7403e30b266ee04
6
+ metadata.gz: e3d254a4d99b5a85eb4f588d89014dc0bd349af5f702e3c42f011c5bc3dac6ad27901f3ab4267d04f277e011fe7124d20223e2864be241e48d7d50c932c82e9a
7
+ data.tar.gz: 21f12ce2c310c873f4b1d7539c30be580a57437f1411553bbad073e174cc29dea8ec85f761e569cb546e0719c5dbe51477cb5efce25f2f0834e92c0b6b5570ec
@@ -10,7 +10,7 @@ name: Ruby
10
10
  on:
11
11
  workflow_dispatch: {}
12
12
  pull_request:
13
- branches: [master]
13
+ branches: [main]
14
14
 
15
15
  jobs:
16
16
  test:
@@ -32,5 +32,7 @@ jobs:
32
32
  run: (cd spec/rails5; bundle install; yard gems)
33
33
  - name: Install Rails 6 deps
34
34
  run: (cd spec/rails6; bundle install; yard gems)
35
+ - name: Install Rails 7 deps
36
+ run: (cd spec/rails7; bundle install; yard gems)
35
37
  - name: Run tests
36
38
  run: bundle exec rspec
data/.gitignore CHANGED
@@ -11,6 +11,8 @@ spec/rails5/log/
11
11
  spec/rails5/tmp/
12
12
  spec/rails6/log/
13
13
  spec/rails6/tmp/
14
+ spec/rails7/log/
15
+ spec/rails7/tmp/
14
16
  .projections.json
15
17
  .byebug_history
16
18
 
data/CHANGELOG.md CHANGED
@@ -2,6 +2,21 @@
2
2
 
3
3
  ## Changes
4
4
 
5
+ ### v1.0.1
6
+
7
+ https://github.com/alisnic/solargraph-arc was merged, with the following features:
8
+ - fixes autocompletion for multi-level classes defined in 1 line `class Foo::Bar::Baz`. See https://github.com/castwide/solargraph/issues/506
9
+ - autocomplete database columns by parsing db/schema.rb
10
+ - autocomplete of model relations
11
+ - parsing of `delegate` calls
12
+ - completions for methods generated by Devise
13
+ - better support for running solargraph outside bundle
14
+ - better completion inside controllers. `request`, `response`, `params`, etc.
15
+ - autocomplete inside routes.rb
16
+ - autocomplete inside migrations
17
+ - completions for methods generated by ActiveStorage
18
+ - better ActiveRecord completions
19
+
5
20
  ### v1.0.0.pre.1
6
21
 
7
22
  https://github.com/alisnic/solargraph-arc was merged, with the following features:
data/DEVELOPMENT.md CHANGED
@@ -19,8 +19,16 @@
19
19
  $ bundle install && yard gems
20
20
  $ cd ../../
21
21
  ```
22
- 4. now tests should pass locally and you can try different changes
23
- 5. sumbit PR
22
+
23
+ 4. install dummy rails7 app deps and build its yard cache
24
+
25
+ ```
26
+ $ cd spec/rails7
27
+ $ bundle install && yard gems
28
+ $ cd ../../
29
+ ```
30
+ 5. now tests should pass locally and you can try different changes
31
+ 6. sumbit PR
24
32
 
25
33
  ## Completion coverage tracking
26
34
 
@@ -74,10 +82,10 @@ In case of option 2, don't forget to remove the flag after yml file has been upd
74
82
 
75
83
  In case a new set of assertion files has to be created (for a new Rails version for example), a script can be used - https://github.com/iftheshoefritz/solargraph-rails/blob/master/script/generate_definitions.rb.
76
84
 
77
- All you have to do is to go to the same Rails app root, and execute the script:
85
+ All you have to do is execute the script and pass it a path to rails app:
78
86
 
79
87
  ```
80
- ruby path/to/generate_definitions.rb
88
+ ruby script/generate_definitions.rb spec/rails6
81
89
  ```
82
90
 
83
91
  Make sure to review the script and uncomment relevant parts
data/README.md CHANGED
@@ -1,8 +1,5 @@
1
1
  # Solargraph::Rails - Help solargraph with Rails
2
2
 
3
- ## Work in progress - here be dragons
4
- There are significant rough edges to this gem still.
5
-
6
3
  ## Models
7
4
  Given a typical Rails model like this:
8
5
 
@@ -27,50 +24,33 @@ class MyBook < ApplicationRecord
27
24
  end
28
25
  ```
29
26
 
30
- The various Ruby intellisense tools are ok at knowing that there is a `MyBook` constant, and some (including Solargraph) are even aware that objects like `MyBook.new` have a method `.my_method`. But what about those magical dynamic attributes that ActiveRecord creates when Rails starts up? You can see these listed at the top of the file under `# == Schema Information`, the comments helpfully added by the Annotate gem.
27
+ The various Ruby intellisense tools are ok at knowing that there is a `MyBook` constant, and some (including Solargraph) are aware that objects like `MyBook.new` have a method `.my_method`. But what about those magical dynamic attributes that ActiveRecord creates when Rails starts up? You can see these listed at the top of the file under `# == Schema Information`, the comments helpfully added by the Annotate gem.
31
28
 
32
29
  Since these attributes are only created at runtime, static analysis alone can't identify them. Your editor has no idea that these attributes exist, but they're amongst the most common things that you will work with in any Rails app.
33
30
 
34
- That's where this plugin for Solargraph comes in: it parses the schema comments left by Annotate and uses those to give Solargraph some extra hints.
35
-
36
- With this you get autocompletion on ActiveRecord attributes:
37
-
38
- ![Autocompletion of dynamic attributes like created_at](assets/solar_rails_autocomplete.gif)
39
-
40
- ... and go to definition commands take you to the schema comment for that column:
41
-
31
+ That's where this plugin for Solargraph comes in: it parses the database schema and YARD docs of various gems to give Solargraph some extra hints. For instance database attributes:
42
32
 
43
- ![Go to definition of dynamic attributes like created_at](assets/solar_rails_goto.gif)
33
+ ![Go to attribute schema definition](assets/sg_rails_1_0_go_to_attribute_definition.gif)
44
34
 
45
- ... and peek commands show you documentation about the attribute:
35
+ ... or ActiveRecord finders:
46
36
 
47
- ![Peek at documentation of attributes like created_at, author, etc.](assets/peek.png)
37
+ ![ActiveRecord method support](assets/sg_rails_1_0_activerecord_support.gif)
48
38
 
49
- ### Reload workspace after migrations
50
- Solargraph won't know about attributes that you add during a session. Restart your LSP workspace to get the new attributes.
39
+ ... or associations:
51
40
 
52
- For my setup with Emacs, that means running `M-x lsp-workspace-restart`, YMMV in other editors.
41
+ ![Association support](assets/sg_rails_1_0_association_completion.gif)
53
42
 
54
- ## Associations (experimental)
55
- There is simplistic support for `belongs_to` and `has_many` macros:
43
+ ... or routes file:
56
44
 
57
- ![Experimental autocomplete and go to definition of associations](assets/solar_rails_associations.gif)
45
+ ![Routes file support](assets/sg_rails_1_0_routes_support.gif)
58
46
 
59
- ## Known issues
60
- This project is being used to write production code by the maintainer, but it is still WIP. Check out the issues tab and contribute if you are interested.
61
-
62
- Association support is slightly less functional in Rails 7.
47
+ and more!
63
48
 
64
49
  ## Installation
65
50
 
66
- ### Install `solargraph` and `solargraph-rails` locally
67
-
68
- Typically gems like these are not installed via the Gemfile, because most projects have more than one contributor and other contributors might have different setups for their editors in mind. Instead you need to use `gem install`.
51
+ ### Install `solargraph` and `solargraph-rails`
69
52
 
70
- `gem install solargraph-rails`
71
-
72
- #### Alternative: using bundler
73
- If you do want to use bundler, add `gem 'solargraph-rails'`
53
+ If you add them to your Gemfile, you'll have to tell your IDE plugin to use bundler to load the right version of solargraph.
74
54
 
75
55
  ### Add `solargraph-rails` to your `.solargraph.yml`
76
56
 
@@ -81,28 +61,29 @@ plugins:
81
61
  - solargraph-rails
82
62
  ```
83
63
 
84
- ### Add annotate
85
- Add schema comments your model files using [Annotate](https://github.com/ctran/annotate_models/). At the moment Solargraph::Rails assumes your schema comments are at the top of the source file.
86
-
87
- ## Development
64
+ ### Build YARD docs
65
+ In the project root, run `yard gems`.
88
66
 
89
- Fork the project, start hacking, put up a PR :).
90
-
91
- When you make changes, you probably need to shut down solargraph and restart it (maybe that requires you to shut down your whole editor?). You can speed up the feedback loop by running
67
+ ## Contributing
68
+ Bug reports and pull requests are welcome on GitHub at https://github.com/iftheshoefritz/solargraph_rails.
92
69
 
93
- `api_map = Solargraph::ApiMap.load(Rails.root.to_s)`
70
+ 1. create fork and clone the repo
94
71
 
95
- in the console of the Rails project where solargraph-rails is installed. This may require restarting the rails console each time, and possibly killing Spring.
72
+ 2. install gem deps `bundle install`
96
73
 
97
- Once you have an instance of `Solargraph::ApiMap`, you can interrogate it with Solargraph code like:
74
+ 3. install dummy rails app deps and build the yard cache:
98
75
 
99
- `pins = api_map.get_methods('MyBook')`
76
+ ```
77
+ $ cd spec/rails5
78
+ $ bundle install && yard gems
79
+ $ cd ../../
80
+ ```
100
81
 
101
- More examples here: https://solargraph.org/guides/code-examples
82
+ (and the same for rails 6 and rails 7)
102
83
 
103
- ## Contributing
84
+ 4. now tests should pass locally and you can try different changes
104
85
 
105
- Bug reports and pull requests are welcome on GitHub at https://github.com/iftheshoefritz/solargraph_rails.
86
+ 5. sumbit PR
106
87
 
107
88
  ## License
108
89
 
@@ -15,7 +15,7 @@ module Solargraph
15
15
 
16
16
  def process(source_map, ns)
17
17
  return [] if @schema_present
18
- return [] unless source_map.filename.include?('app/models')
18
+ return [] unless Model.valid_filename?(source_map.filename)
19
19
 
20
20
  pins = []
21
21
  walker = Walker.from_source(source_map.source)
@@ -6,7 +6,7 @@ module Solargraph
6
6
  end
7
7
 
8
8
  def process(source_map, ns)
9
- if source_map.filename.include?('app/models')
9
+ if Model.valid_filename?(source_map.filename)
10
10
  process_model(source_map.source, ns)
11
11
  else
12
12
  []
@@ -5,8 +5,12 @@ module Solargraph
5
5
  @instance ||= self.new
6
6
  end
7
7
 
8
+ def self.valid_filename?(filename)
9
+ filename.include?('app/models')
10
+ end
11
+
8
12
  def process(source_map, ns)
9
- return [] unless source_map.filename.include?('app/models')
13
+ return [] unless self.class.valid_filename?(source_map.filename)
10
14
 
11
15
  walker = Walker.from_source(source_map.source)
12
16
  pins = []
@@ -28,6 +32,7 @@ module Solargraph
28
32
  end
29
33
 
30
34
  walker.on :send, [nil, :scope] do |ast|
35
+ next if ast.children[2].nil?
31
36
  name = ast.children[2].children.last
32
37
 
33
38
  method_pin =
@@ -16,7 +16,10 @@ module Solargraph
16
16
  json: 'Hash',
17
17
  bigint: 'Integer',
18
18
  uuid: 'String',
19
- inet: 'IPAddr'
19
+ inet: 'IPAddr',
20
+ citext: 'String',
21
+ binary: 'String',
22
+ timestamp: 'ActiveSupport::TimeWithZone'
20
23
  }
21
24
 
22
25
  def self.instance
@@ -33,10 +36,9 @@ module Solargraph
33
36
 
34
37
  def process(source_map, ns)
35
38
  return [] unless @schema_present
36
- return [] unless source_map.filename.include?('app/models')
39
+ return [] unless Model.valid_filename?(source_map.filename)
37
40
 
38
- table_name = infer_table_name(ns)
39
- table = schema[table_name]
41
+ table = find_table(source_map, ns)
40
42
 
41
43
  return [] unless table
42
44
 
@@ -68,10 +70,27 @@ module Solargraph
68
70
  end
69
71
  end
70
72
 
71
- # TODO: support custom table names, by parsing `self.table_name = ` invokations
72
- # inside model
73
- def infer_table_name(ns)
74
- ns.name.underscore.pluralize
73
+ def find_table(source_map, ns)
74
+ table_name = nil
75
+ walker = Walker.from_source(source_map.source)
76
+ walker.on :send, [:self, :table_name=, :str] do |ast|
77
+ table_name = ast.children.last.children.first
78
+ end
79
+ walker.walk
80
+
81
+ # always use explicit table name if present
82
+ return schema[table_name] if table_name
83
+
84
+ infer_table_names(ns).filter_map { |table_name| schema[table_name] }.first
85
+ end
86
+
87
+ def infer_table_names(ns)
88
+ table_name = ns.name.tableize
89
+ if ns.namespace.present?
90
+ [ns.path.tableize.tr('/', '_'), table_name]
91
+ else
92
+ [table_name]
93
+ end
75
94
  end
76
95
 
77
96
  def extract_schema(ast)
@@ -6,7 +6,7 @@ module Solargraph
6
6
  end
7
7
 
8
8
  def process(source_map, ns)
9
- return [] unless source_map.filename.include?('app/models')
9
+ return [] unless Model.valid_filename?(source_map.filename)
10
10
 
11
11
  walker = Walker.from_source(source_map.source)
12
12
  pins = []
@@ -1,5 +1,5 @@
1
1
  module Solargraph
2
2
  module Rails
3
- VERSION = '1.0.0.pre.1'
3
+ VERSION = '1.0.1'
4
4
  end
5
5
  end
@@ -2,12 +2,51 @@ module Solargraph
2
2
  module Rails
3
3
  class Walker
4
4
  class Hook
5
- attr_reader :args, :proc, :node_type
5
+ attr_reader :node_type
6
6
  def initialize(node_type, args, &block)
7
7
  @node_type = node_type
8
8
  @args = args
9
9
  @proc = Proc.new(&block)
10
10
  end
11
+
12
+ def visit(node)
13
+ return unless matches?(node)
14
+
15
+ if @proc.arity == 1
16
+ @proc.call(node)
17
+ elsif @proc.arity == 2
18
+ walker = Walker.new(node)
19
+ @proc.call(node, walker)
20
+ walker.walk
21
+ end
22
+ end
23
+
24
+ private
25
+
26
+ def matches?(node)
27
+ return unless node.type == node_type
28
+ return unless node.children
29
+ return true if @args.empty?
30
+
31
+ a_child_matches = node.children.first.is_a?(::Parser::AST::Node) && node.children.any? do |child|
32
+ child.is_a?(::Parser::AST::Node) &&
33
+ match_children(child.children, @args[1..-1])
34
+ end
35
+
36
+ return true if a_child_matches
37
+
38
+ match_children(node.children)
39
+ end
40
+
41
+ def match_children(children, args = @args)
42
+ args.each_with_index.all? do |arg, i|
43
+ if children[i].is_a?(::Parser::AST::Node)
44
+ children[i].type == arg
45
+ else
46
+ children[i] == arg
47
+ end
48
+ end
49
+ end
11
50
  end
12
51
 
13
52
  # https://github.com/castwide/solargraph/issues/522
@@ -45,45 +84,10 @@ module Solargraph
45
84
  def traverse(node)
46
85
  return unless node.is_a?(::Parser::AST::Node)
47
86
 
48
- @hooks[node.type].each { |hook| try_match(node, hook) }
87
+ @hooks[node.type].each { |hook| hook.visit(node) }
49
88
 
50
89
  node.children.each { |child| traverse(child) }
51
90
  end
52
-
53
- def try_match(node, hook)
54
- return unless node.type == hook.node_type
55
- return unless node.children
56
-
57
- matched =
58
- hook.args.empty? || if node.children.first.is_a?(::Parser::AST::Node)
59
- node.children.any? do |child|
60
- child.is_a?(::Parser::AST::Node) &&
61
- match_children(hook.args[1..-1], child.children)
62
- end
63
- else
64
- match_children(hook.args, node.children)
65
- end
66
-
67
- if matched
68
- if hook.proc.arity == 1
69
- hook.proc.call(node)
70
- elsif hook.proc.arity == 2
71
- walker = Walker.new(node)
72
- hook.proc.call(node, walker)
73
- walker.walk
74
- end
75
- end
76
- end
77
-
78
- def match_children(args, children)
79
- args.each_with_index.all? do |arg, i|
80
- if children[i].is_a?(::Parser::AST::Node)
81
- children[i].type == arg
82
- else
83
- children[i] == arg
84
- end
85
- end
86
- end
87
91
  end
88
92
  end
89
93
  end
@@ -106,29 +106,36 @@ Rails.application.routes.draw do
106
106
  File.write('routes.yml', report.deep_stringify_keys.to_yaml)
107
107
  end
108
108
 
109
- # [Array, String, Time, Date, Class, DateTime, File, Hash, Integer, Kernel].each do |klass|
110
- # test = case klass
111
- # when Time
112
- # Time.now
113
- # when Date
114
- # Date.today
115
- # when File
116
- # false
117
- # else
118
- # klass.new rescue false
119
- # end
120
- #
121
- # report = core_ext_report(klass, test=test)
122
- # File.write("#{klass.to_s}.yml", report.deep_stringify_keys.to_yaml)
123
- # end
124
-
125
- # binding.pry
109
+ [
110
+ Array,
111
+ String,
112
+ Time,
113
+ Date,
114
+ Class,
115
+ DateTime,
116
+ File,
117
+ Hash,
118
+ Integer,
119
+ Kernel
120
+ ].each do |klass|
121
+ test =
122
+ case klass
123
+ when Time
124
+ Time.now
125
+ when Date
126
+ Date.today
127
+ when File
128
+ false
129
+ else
130
+ begin
131
+ klass.new
132
+ rescue StandardError
133
+ false
134
+ end
135
+ end
126
136
 
127
- # File.write("activerecord.yml", result.deep_stringify_keys.to_yaml)
137
+ report = core_ext_report(klass, test = test)
138
+ File.write("#{klass.to_s}.yml", report.deep_stringify_keys.to_yaml)
139
+ end
128
140
 
129
- # report = build_report(
130
- # ActionController::Base,
131
- # own_class_methods(ActionController::Base),
132
- # own_instance_methods(ActionController::Base)
133
- # )
134
- # File.write("actioncontroller.yml", report.deep_stringify_keys.to_yaml)
141
+ # binding.pry
@@ -17,7 +17,7 @@ Gem::Specification.new do |spec|
17
17
 
18
18
  spec.files =
19
19
  `git ls-files -z`.split("\x0").reject do |f|
20
- f.match(%r{^(test|spec|features)/})
20
+ f.match(%r{^(assets|test|spec|features)/})
21
21
  end
22
22
  spec.bindir = 'exe'
23
23
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: solargraph-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.pre.1
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Fritz Meissner
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-03-18 00:00:00.000000000 Z
11
+ date: 2022-10-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -100,10 +100,6 @@ files:
100
100
  - LICENSE.txt
101
101
  - README.md
102
102
  - Rakefile
103
- - assets/peek.png
104
- - assets/solar_rails_associations.gif
105
- - assets/solar_rails_autocomplete.gif
106
- - assets/solar_rails_goto.gif
107
103
  - bin/console
108
104
  - bin/setup
109
105
  - lib/solargraph-rails.rb
@@ -127,7 +123,7 @@ homepage: https://github.com/iftheshoefritz/solargraph-rails
127
123
  licenses:
128
124
  - MIT
129
125
  metadata: {}
130
- post_install_message:
126
+ post_install_message:
131
127
  rdoc_options: []
132
128
  require_paths:
133
129
  - lib
@@ -138,12 +134,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
138
134
  version: '0'
139
135
  required_rubygems_version: !ruby/object:Gem::Requirement
140
136
  requirements:
141
- - - ">"
137
+ - - ">="
142
138
  - !ruby/object:Gem::Version
143
- version: 1.3.1
139
+ version: '0'
144
140
  requirements: []
145
- rubygems_version: 3.2.3
146
- signing_key:
141
+ rubygems_version: 3.3.11
142
+ signing_key:
147
143
  specification_version: 4
148
144
  summary: Solargraph plugin that adds Rails-specific code through a Convention
149
145
  test_files: []
data/assets/peek.png DELETED
Binary file
Binary file
Binary file
Binary file