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 +4 -4
- data/.github/workflows/ruby.yml +3 -1
- data/.gitignore +2 -0
- data/CHANGELOG.md +15 -0
- data/DEVELOPMENT.md +12 -4
- data/README.md +27 -46
- data/lib/solargraph/rails/annotate.rb +1 -1
- data/lib/solargraph/rails/devise.rb +1 -1
- data/lib/solargraph/rails/model.rb +6 -1
- data/lib/solargraph/rails/schema.rb +27 -8
- data/lib/solargraph/rails/storage.rb +1 -1
- data/lib/solargraph/rails/version.rb +1 -1
- data/lib/solargraph/rails/walker.rb +41 -37
- data/script/generate_definitions.rb +31 -24
- data/solargraph-rails.gemspec +1 -1
- metadata +8 -12
- data/assets/peek.png +0 -0
- data/assets/solar_rails_associations.gif +0 -0
- data/assets/solar_rails_autocomplete.gif +0 -0
- data/assets/solar_rails_goto.gif +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 674da2b5a3f833920c2c92893cfa936cb430e23e0bae6a7712b91cebe4b2815f
|
4
|
+
data.tar.gz: e7950faaeacc82868a4d91ceba186fc31aa78a6fe5e257969e9907ceb2b54656
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e3d254a4d99b5a85eb4f588d89014dc0bd349af5f702e3c42f011c5bc3dac6ad27901f3ab4267d04f277e011fe7124d20223e2864be241e48d7d50c932c82e9a
|
7
|
+
data.tar.gz: 21f12ce2c310c873f4b1d7539c30be580a57437f1411553bbad073e174cc29dea8ec85f761e569cb546e0719c5dbe51477cb5efce25f2f0834e92c0b6b5570ec
|
data/.github/workflows/ruby.yml
CHANGED
@@ -10,7 +10,7 @@ name: Ruby
|
|
10
10
|
on:
|
11
11
|
workflow_dispatch: {}
|
12
12
|
pull_request:
|
13
|
-
branches: [
|
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
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
|
-
|
23
|
-
|
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
|
85
|
+
All you have to do is execute the script and pass it a path to rails app:
|
78
86
|
|
79
87
|
```
|
80
|
-
ruby
|
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
|
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
|
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
|
33
|
+
![Go to attribute schema definition](assets/sg_rails_1_0_go_to_attribute_definition.gif)
|
44
34
|
|
45
|
-
...
|
35
|
+
... or ActiveRecord finders:
|
46
36
|
|
47
|
-
![
|
37
|
+
![ActiveRecord method support](assets/sg_rails_1_0_activerecord_support.gif)
|
48
38
|
|
49
|
-
|
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
|
-
|
41
|
+
![Association support](assets/sg_rails_1_0_association_completion.gif)
|
53
42
|
|
54
|
-
|
55
|
-
There is simplistic support for `belongs_to` and `has_many` macros:
|
43
|
+
... or routes file:
|
56
44
|
|
57
|
-
![
|
45
|
+
![Routes file support](assets/sg_rails_1_0_routes_support.gif)
|
58
46
|
|
59
|
-
|
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`
|
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
|
-
|
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
|
-
###
|
85
|
-
|
86
|
-
|
87
|
-
## Development
|
64
|
+
### Build YARD docs
|
65
|
+
In the project root, run `yard gems`.
|
88
66
|
|
89
|
-
|
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
|
-
|
70
|
+
1. create fork and clone the repo
|
94
71
|
|
95
|
-
|
72
|
+
2. install gem deps `bundle install`
|
96
73
|
|
97
|
-
|
74
|
+
3. install dummy rails app deps and build the yard cache:
|
98
75
|
|
99
|
-
|
76
|
+
```
|
77
|
+
$ cd spec/rails5
|
78
|
+
$ bundle install && yard gems
|
79
|
+
$ cd ../../
|
80
|
+
```
|
100
81
|
|
101
|
-
|
82
|
+
(and the same for rails 6 and rails 7)
|
102
83
|
|
103
|
-
|
84
|
+
4. now tests should pass locally and you can try different changes
|
104
85
|
|
105
|
-
|
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
|
18
|
+
return [] unless Model.valid_filename?(source_map.filename)
|
19
19
|
|
20
20
|
pins = []
|
21
21
|
walker = Walker.from_source(source_map.source)
|
@@ -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
|
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
|
39
|
+
return [] unless Model.valid_filename?(source_map.filename)
|
37
40
|
|
38
|
-
|
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
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
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)
|
@@ -2,12 +2,51 @@ module Solargraph
|
|
2
2
|
module Rails
|
3
3
|
class Walker
|
4
4
|
class Hook
|
5
|
-
attr_reader :
|
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|
|
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
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
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
|
-
|
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
|
-
#
|
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
|
data/solargraph-rails.gemspec
CHANGED
@@ -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.
|
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-
|
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:
|
139
|
+
version: '0'
|
144
140
|
requirements: []
|
145
|
-
rubygems_version: 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
|
data/assets/solar_rails_goto.gif
DELETED
Binary file
|