Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions .overcommit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,6 @@ PreCommit:
RuboCop:
enabled: true

Solargraph:
enabled: true
exclude:
- 'spec/**/*'

FixMe:
enabled: true
exclude:
Expand Down
1 change: 1 addition & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,4 @@ plugins:
- rubocop-rspec
- rubocop-rake
- rubocop-yard
- solargraph
18 changes: 18 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -136,3 +136,21 @@ task :overcommit do
# OVERCOMMIT_DEBUG=1 will show more detail
sh 'SOLARGRAPH_ASSERTS=on bundle exec overcommit --run --diff origin/master'
end

desc 'Generate a new cop with a template'
task :new_cop, [:cop] do |_task, args|
require 'rubocop'

cop_name = args.fetch(:cop) do
warn 'usage: bundle exec rake new_cop[Department/Name]'
exit!
end

generator = RuboCop::Cop::Generator.new(cop_name)

generator.write_source
generator.inject_require(root_file_path: 'lib/rubocop/cop/solargraph_cops.rb')
generator.inject_config(config_file_path: 'config/default.yml')

puts generator.todo
end
47 changes: 47 additions & 0 deletions config/default.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
---
Solargraph/Blah:
Description: 'Write a description of the cop.'
Enabled: true
VersionAdded: '<<next>>'

Solargraph/NewMeaninglessTag:
Description: 'Check meaningless tag'
Enabled: true
VersionAdded: '0.4.0'

Solargraph/NewTagTypeSyntax:
Description: 'Check syntax for yard tag type'
Enabled: true
VersionAdded: '0.5.0'

Solargraph/NewCollectionStyle:
Description: 'Check collection type style'
Enabled: true
VersionAdded: '0.5.0'
EnforcedStyle: long
SupportedStyles:
- long
- short

Solargraph/NewCollectionType:
Description: 'Check collection type syntax'
Enabled: true
VersionAdded: '0.5.0'
EnforcedStyle: long
SupportedStyles:
- long
- short

Solargraph/NewMismatchName:
Description: 'Check @param and @option name and method parameters'
Enabled: true
VersionAdded: '0.3.0'
EnforcedStylePrototypeName: after
SupportedStylesPrototypeName:
- before
- after

Solargraph/NewTagTypePosition:
Description: 'Notice tag type position'
Enabled: true
VersionAdded: '0.9.0'
88 changes: 88 additions & 0 deletions lib/rubocop/cop/solargraph/type_violation.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# frozen_string_literal: true

require 'yard'
require 'rubocop-yard'
require 'solargraph'

module ::RuboCop
module Cop
module Solargraph
# TODO: external_dependency_checksum should probably point to
# same things that invalidate Solargraph cache? Also solargraph
# config?
# TODO: Add one per type of typechecker error - there's a team concept'
class TypeViolation < ::RuboCop::Cop::Base
include RuboCop::Cop::YARD::Helper
include RangeHelp

# @param config [RuboCop::Config, nil]
# @param options [Hash, nil]
def initialize(config = nil, options = nil)
@@directory = Dir.pwd
# directory = File.realpath(options[:directory]) TODO allow options
@@mutex ||= Mutex.new
@@workspace ||= ::Solargraph::Workspace.new(@@directory)
# level = options[:level].to_sym TODO
@@level = :strong
@@rules ||= @@workspace.rules(@@level)
@@mutex.synchronize do
# do this in a mutex as it takes a while and these get called in parallel
@@api_map ||=
::Solargraph::ApiMap.load_with_cache(@@directory, $stdout,
loose_unions:
!@@rules.require_all_unique_types_support_call?)
end
super
end

def self.support_multiple_source?
true
end

# @return [void]
def on_new_investigation
file = processed_source.file_path



checker = ::Solargraph::TypeChecker.new(file,
api_map: @@api_map,
rules: @@rules, level: @@level,
workspace: @@workspace)
# @return [::Array<::Solargraph::TypeChecker::Problem, nil>]
problems = nil
begin
problems = checker.problems
rescue ::Solargraph::FileNotFoundError
# not a file covered by solargraph config
return
end

# @sg-ignore Declared type
# Array<Solargraph::TypeChecker::Problem, nil> does not
# match inferred type nil for variable problems @type - I
# think because it doesn't understand the absolute
# ::Solargraph in the context of a class Solargraph
#
# @param problem [::Solargraph::TypeChecker::Problem]
problems.each do |problem|
# @type [::Parser::Source::Buffer]
buffer = processed_source.buffer
contents = buffer.source
location = problem.location
start_position = location.range.start
end_position = location.range.ending
begin_offset = ::Solargraph::Position.to_offset(contents, start_position)
end_offset = ::Solargraph::Position.to_offset(contents, end_position)
range = ::Parser::Source::Range.new(buffer,
begin_offset,
end_offset)


add_offense(range, message: problem.message)
end
end
end
end
end
end
5 changes: 5 additions & 0 deletions lib/rubocop/solargraph_cops.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# frozen_string_literal: true

require 'solargraph'

require_relative 'cop/solargraph/type_violation'
1 change: 1 addition & 0 deletions lib/solargraph.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ class InvalidRubocopVersionError < RuntimeError; end
autoload :RbsMap, 'solargraph/rbs_map'
autoload :GemPins, 'solargraph/gem_pins'
autoload :PinCache, 'solargraph/pin_cache'
autoload :LintRoller, 'solargraph/lint_roller'

dir = File.dirname(__FILE__)
VIEWS_PATH = File.join(dir, 'solargraph', 'views')
Expand Down
53 changes: 53 additions & 0 deletions lib/solargraph/lint_roller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
require 'lint_roller'

module Solargraph
module LintRoller
class Plugin < ::LintRoller::Plugin
# @param config [Hash{String => String}] options passed to the plugin by the user
def initialize(config)
config['require_path'] = 'solargraph/rubocop'
super
end

# @sg-ignore Declared return type ::LintRoller::About does not
# match inferred type Solargraph::LintRoller::Plugin for
# Solargraph::LintRoller::Plugin#about
# @return [LintRoller::About]
def about
# @sg-ignore Unrecognized keyword argument name to Struct.new
::LintRoller::About.new(
name: "solargraph",
version: Solargraph::VERSION,
homepage: "https://github.com/castwide/solargraph",
description: "Configuration of Solargraph typechecking"
)
end

# @sg-ignore Solargraph::LintRoller::Plugin#supported? return
# type could not be inferred
# @param context [LintRoller::Context] provided by the runner
def supported?(context)
context.engine == :rubocop
end

# @param context [LintRoller::Context] provided by the runner
#
# @sg-ignore Declared return type ::LintRoller::Rules does not
# match inferred type Solargraph::LintRoller::Plugin for
# Solargraph::LintRoller::Plugin#rules
# @return [LintRoller::Rules]
def rules(context)
require 'solargraph/rubocop'

cwd = __dir__ || '.'

# @sg-ignore Unrecognized keyword argument type to Struct.new
::LintRoller::Rules.new(
type: :path,
config_format: :rubocop,
value: Pathname.new(cwd).join("../../config/default.yml")
)
end
end
end
end
1 change: 1 addition & 0 deletions lib/solargraph/rubocop.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require_relative '../rubocop/solargraph_cops'
Loading
Loading