Skip to content

Commit

Permalink
Bump version to 0.2.0.pre and update files for name change
Browse files Browse the repository at this point in the history
Gem is now named solargraph-rails, had to change the directory structure
for the naming to make sense.
  • Loading branch information
iftheshoefritz committed Jan 9, 2021
1 parent 4a5281d commit 9419ca8
Show file tree
Hide file tree
Showing 19 changed files with 261 additions and 260 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# SolargraphRails - Help solargraph with Rails
# Solargraph::Rails - Help solargraph with Rails

## Work in progress - here be dragons
There are significant rough edges to this gem still. Don't use it if you're not willing to do things like build gems from source and install them locally. See `Installation` below for more info.
Expand Down Expand Up @@ -84,7 +84,7 @@ plugins:
```

### Add annotate
Add schema comments your model files using [Annotate](https://github.com/ctran/annotate_models/). At the moment SolargraphRails assumes your schema comments are at the top of the source file.
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.

## Development

Expand Down
2 changes: 1 addition & 1 deletion bin/console
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env ruby

require "bundler/setup"
require "solargraph_rails"
require "solargraph-rails"

# You can add fixtures and/or initialization code here to make experimenting
# with your gem easier. You can also use a different console, if you like.
Expand Down
32 changes: 32 additions & 0 deletions lib/solargraph-rails.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# frozen_string_literal: true

require 'solargraph'
require 'solargraph/rails/version'
require_relative 'solargraph/rails/pin_creator'
require_relative 'solargraph/rails/ruby_parser'
require_relative 'solargraph/rails/files_loader'

module Solargraph
module Rails
class DynamicAttributes < Solargraph::Convention::Base
def global yard_map
Solargraph::Environ.new(pins: parse_models)
end

private

def parse_models
pins = []

FilesLoader.new(
Dir[File.join(Dir.pwd, 'app', 'models', '**', '*.rb')]
).each { |file, contents| pins.push *PinCreator.new(file, contents).create_pins }

pins
end
end
end
end


Solargraph::Convention.register Solargraph::Rails::DynamicAttributes
16 changes: 16 additions & 0 deletions lib/solargraph/rails/files_loader.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
module Solargraph
module Rails
class FilesLoader
def initialize(file_names)
@file_names = file_names
end

def each(&blk)
@file_names.each do |file_name|
Solargraph::Logging.logger.info "loading from #{file_name}"
blk.call(file_name, File.read(file_name))
end
end
end
end
end
88 changes: 88 additions & 0 deletions lib/solargraph/rails/pin_creator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# frozen_string_literal: true

module Solargraph
module Rails
class PinCreator
attr_reader :contents, :path

def initialize(path, contents)
@path = path
@contents = contents
end

def create_pins
model_attrs = []
model_name = nil
module_names = []
parser = RubyParser.new(file_contents: contents)

parser.on_comment do |comment|
Solargraph::Logging.logger.info "found comment #{comment}"
col_name, col_type = col_with_type(comment)
if type_translation.keys.include?(col_type)
loc = Solargraph::Location.new(
path,
Solargraph::Range.from_to(
parser.current_line_number,
0,
parser.current_line_number,
parser.current_line_length - 1
)
)
model_attrs << { name: col_name, type: col_type, location: loc }
else
Solargraph::Logging.logger.info 'could not find annotation in comment'
end
end

parser.on_module do |mod_name|
Solargraph::Logging.logger.info "found module #{mod_name}"
module_names << mod_name
end

parser.on_class do |klass, superklass|
Solargraph::Logging.logger.info "found class: #{klass} < #{superklass}"
if ['ActiveRecord::Base', 'ApplicationRecord'].include?(superklass)
model_name = klass
else
Solargraph::Logging.logger.info "Unable to find ActiveRecord model from #{klass} #{superklass}"
model_attrs = [] # don't include anything from this file
end
end

parser.parse

Solargraph::Logging.logger.info "Adding #{model_attrs.count} attributes as pins"
model_attrs.map do |attr|
Solargraph::Pin::Method.new(
name: attr[:name],
comments: "@return [#{type_translation[attr[:type]]}]",
location: attr[:location],
closure: Solargraph::Pin::Namespace.new(name: module_names.join('::') + "::#{model_name}"),
scope: :instance,
attribute: true
)
end
end

def col_with_type(line)
line
.gsub(/[\(\),:\d]/, '')
.split
.first(2)
end

def type_translation
{
'decimal' => 'BigDecimal',
'integer' => 'Integer',
'date' => 'Date',
'datetime' => 'ActiveSupport::TimeWithZone',
'string' => 'String',
'boolean' => 'Boolean',
'text' => 'String'
}
end
end
end
end
70 changes: 70 additions & 0 deletions lib/solargraph/rails/ruby_parser.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
module Solargraph
module Rails
class RubyParser
attr_reader :current_line_number, :current_line_length

def initialize(file_contents: '')
@lines = file_contents.lines
@comment_handlers = []
@class_handlers = []
@module_handlers = []
end

def on_comment(&blk)
@comment_handlers << blk
end

def on_class(&blk)
@class_handlers << blk
end

def on_module(&blk)
@module_handlers << blk
end

def parse
@lines
.map(&:rstrip)
.each_with_index do |line, i|
@current_line_number = i
@current_line_length = line.length

if is_comment?(line)
comment_content = line.gsub(/#\s*/, '')
@comment_handlers.each { |handler| handler.call(comment_content) }
end

if is_class?(line)
line.scan(/(?:(?<!<\s)(?:(\b\w+\b)\:\:))/).flatten.each do |inline_module_name|
@module_handlers.each { | handler| handler.call(inline_module_name) }
end
line.match(/class\s+(?:\w*?(?:\:\:))*([A-Z]\w*)/)
klass_name = $1
line.match(/(?:<\s+)((?:[A-Z]\w*(?:\:\:)?)*)/)
superklass_name = $1
@class_handlers.each { |handler| handler.call(klass_name, superklass_name) }
end

if is_module?(line)
module_name = line.match(/^\s*module\s*?([A-Z]\w+)/)[1]
@module_handlers.each { |handler| handler.call(module_name) }
end
end
end

private

def is_comment?(line)
line =~ (/^\s*#/)
end

def is_class?(line)
line =~ /^[^#]?.*?class\s+?[A-Z]/
end

def is_module?(line)
line =~ (/^\s*module\s*?([A-Z]\w+)/)
end
end
end
end
5 changes: 5 additions & 0 deletions lib/solargraph/rails/version.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module Solargraph
module Rails
VERSION = '0.2.0.pre'
end
end
30 changes: 0 additions & 30 deletions lib/solargraph_rails.rb

This file was deleted.

14 changes: 0 additions & 14 deletions lib/solargraph_rails/files_loader.rb

This file was deleted.

86 changes: 0 additions & 86 deletions lib/solargraph_rails/pin_creator.rb

This file was deleted.

Loading

0 comments on commit 9419ca8

Please sign in to comment.