language_server 0.9.0 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -11,35 +11,35 @@ module LanguageServer
11
11
  end
12
12
 
13
13
  def call
14
- (project.constants(uri: uri, line: line, character: character).map {|c|
14
+ (project.constants(uri: uri, line: line, character: character).map { |c|
15
15
  Protocol::Interface::CompletionItem.new(
16
16
  label: c.name,
17
17
  detail: c.full_name,
18
18
  documentation: "#{c.remote_path}##{c.lineno}",
19
- kind: Protocol::Constant::CompletionItemKind::ENUM
19
+ kind: Protocol::Constant::CompletionItemKind::ENUM,
20
20
  )
21
21
  } +
22
- project.classes(uri: uri, line: line, character: character).map {|c|
22
+ project.classes(uri: uri, line: line, character: character).map { |c|
23
23
  Protocol::Interface::CompletionItem.new(
24
24
  label: c.name,
25
25
  detail: c.full_name,
26
26
  documentation: "#{c.remote_path}##{c.lineno}",
27
- kind: Protocol::Constant::CompletionItemKind::CLASS
27
+ kind: Protocol::Constant::CompletionItemKind::CLASS,
28
28
  )
29
29
  } +
30
- project.modules(uri: uri, line: line, character: character).map {|m|
30
+ project.modules(uri: uri, line: line, character: character).map { |m|
31
31
  Protocol::Interface::CompletionItem.new(
32
32
  label: m.name,
33
33
  detail: m.full_name,
34
34
  documentation: "#{m.remote_path}##{m.lineno}",
35
- kind: Protocol::Constant::CompletionItemKind::MODULE
35
+ kind: Protocol::Constant::CompletionItemKind::MODULE,
36
36
  )
37
37
  }).uniq(&:label)
38
38
  end
39
39
 
40
40
  private
41
41
 
42
- attr_reader :uri, :line, :character, :project
42
+ attr_reader :uri, :line, :character, :project
43
43
  end
44
44
  end
45
45
  end
@@ -28,16 +28,16 @@ module LanguageServer
28
28
  Protocol::Interface::CompletionItem.new(
29
29
  label: method_name,
30
30
  detail: description,
31
- kind: Protocol::Constant::CompletionItemKind::METHOD
31
+ kind: Protocol::Constant::CompletionItemKind::METHOD,
32
32
  )
33
33
  end
34
34
  end
35
35
 
36
36
  private
37
37
 
38
- def source
39
- @file_store.read_remote_uri(@uri)
40
- end
38
+ def source
39
+ @file_store.read_remote_uri(@uri)
40
+ end
41
41
  end
42
42
  end
43
43
  end
@@ -15,20 +15,20 @@ module LanguageServer
15
15
  range: Protocol::Interface::Range.new(
16
16
  start: Protocol::Interface::Position.new(
17
17
  line: n.lines.begin,
18
- character: 0
18
+ character: 0,
19
19
  ),
20
20
  end: Protocol::Interface::Position.new(
21
21
  line: n.lines.end,
22
- character: 0
23
- )
24
- )
22
+ character: 0,
23
+ ),
24
+ ),
25
25
  )
26
26
  end
27
27
  end
28
28
 
29
29
  private
30
30
 
31
- attr_reader :uri, :line, :character, :project
31
+ attr_reader :uri, :line, :character, :project
32
32
  end
33
33
  end
34
34
  end
@@ -64,36 +64,36 @@ module LanguageServer
64
64
 
65
65
  def each(&block)
66
66
  all_paths.each do |path|
67
- block.call(read(path), path)
67
+ yield(read(path), path)
68
68
  end
69
69
  end
70
70
 
71
71
  private
72
72
 
73
- attr_reader :load_paths, :remote_root, :local_root
73
+ attr_reader :load_paths, :remote_root, :local_root
74
74
 
75
- def all_paths
76
- (cache_store.keys + load_paths.flat_map {|path|
77
- Dir.glob(File.join(path, "**", "*.rb"))
78
- }.map {|path|
79
- FilePath.new(local_root: local_root, remote_root: remote_root, local_path: path)
80
- }).uniq
81
- end
75
+ def all_paths
76
+ (cache_store.keys + load_paths.flat_map { |path|
77
+ Dir.glob(File.join(path, "**", "*.rb"))
78
+ }.map { |path|
79
+ FilePath.new(local_root: local_root, remote_root: remote_root, local_path: path)
80
+ }).uniq
81
+ end
82
82
 
83
- def exists_on_cache?(path)
84
- cache_store.key?(path)
85
- end
83
+ def exists_on_cache?(path)
84
+ cache_store.has_key?(path)
85
+ end
86
86
 
87
- def read_from_cache(path)
88
- cache_store[path]
89
- end
87
+ def read_from_cache(path)
88
+ cache_store[path]
89
+ end
90
90
 
91
- def read_from_local(path)
92
- File.read(path.local_path)
93
- end
91
+ def read_from_local(path)
92
+ File.read(path.local_path)
93
+ end
94
94
 
95
- def cache_store
96
- @cache_store ||= {}
97
- end
95
+ def cache_store
96
+ @cache_store ||= {}
97
+ end
98
98
  end
99
99
  end
@@ -1,22 +1,21 @@
1
1
  begin
2
- require 'rubocop'
2
+ require "rubocop"
3
3
  rescue LoadError
4
4
  end
5
5
 
6
6
  module LanguageServer
7
7
  module Linter
8
8
  class Rubocop
9
- def initialize(source, config_path="")
9
+ def initialize(source, config_path = "")
10
10
  @source = source
11
11
  @config_path = config_path
12
12
  end
13
13
 
14
-
15
14
  def call
16
15
  return [] unless defined? ::RuboCop
17
16
  args = []
18
- args += ["--config", @config_path] if @config_path != ''
19
- args += ["--format", "json","--stdin", "lsp_buffer.rb"]
17
+ args += ["--config", @config_path] if @config_path != ""
18
+ args += ["--format", "json", "--stdin", "lsp_buffer.rb"]
20
19
  o = nil
21
20
  begin
22
21
  $stdin = StringIO.new(@source)
@@ -32,24 +31,23 @@ module LanguageServer
32
31
  $stdout = STDOUT
33
32
  end
34
33
  return [] unless o
35
- JSON
36
- .parse(o)['files'].map { |v| v['offenses'] }
37
- .flatten
38
- .map { |v| Error.new(line_num: v['location']['line'].to_i - 1, message: v['message'], type: convert_type(v['severity'])) }
34
+ JSON.
35
+ parse(o)["files"].map { |v| v["offenses"] }.
36
+ flatten.
37
+ map { |v| Error.new(line_num: v["location"]["line"].to_i - 1, message: v["message"], type: convert_type(v["severity"])) }
39
38
  end
40
39
 
41
40
  private
42
41
 
43
- def convert_type(type)
44
- case type
45
- when 'refactor' then 'warning'
46
- when 'convention' then 'warning'
47
- when 'warning' then 'warning'
48
- when 'error' then 'error'
49
- when 'fatal' then 'error'
42
+ def convert_type(type)
43
+ case type
44
+ when "refactor" then "warning"
45
+ when "convention" then "warning"
46
+ when "warning" then "warning"
47
+ when "error" then "error"
48
+ when "fatal" then "error"
49
+ end
50
50
  end
51
- end
52
-
53
51
  end
54
52
  end
55
53
  end
@@ -3,10 +3,11 @@ require "stringio"
3
3
  module LanguageServer
4
4
  module Linter
5
5
  class Error
6
- attr_reader :line_num, :message, :type
6
+ attr_reader :line_num, :characters, :message, :type
7
7
 
8
- def initialize(line_num:, message:, type:)
8
+ def initialize(line_num:, characters: 0..0, message:, type:)
9
9
  @line_num = line_num
10
+ @characters = characters
10
11
  @message = message
11
12
  @type = type
12
13
  end
@@ -16,7 +17,7 @@ module LanguageServer
16
17
  end
17
18
 
18
19
  def ==(other)
19
- line_num == other.line_num && message == other.message
20
+ line_num == other.line_num && characters == other.characters && message == other.message
20
21
  end
21
22
  end
22
23
 
@@ -26,55 +27,65 @@ module LanguageServer
26
27
  end
27
28
 
28
29
  def call
29
- error_message.scan(/.+:(\d+):\s*(.+?)[,:]\s(.+)/).map do |line_num, type, message|
30
- Error.new(line_num: line_num.to_i - 1, message: message, type: type)
30
+ error_message.scan(/.+:(\d+):\s*(.+?)[,:]\s(.+)/).map do |line_num, type, message|
31
+ Error.new(line_num: line_num.to_i - 1, characters: get_characters_from_error_message(error_message, line_num.to_i - 1), message: message, type: type)
31
32
  end
32
33
  end
33
34
 
34
35
  private
35
36
 
36
- # Since Ruby 2.4, syntax error information is outputted to Exception#message instead of stderr
37
- if begin; stderr = $stderr; $stderr = StringIO.new; RubyVM::InstructionSequence.compile('='); rescue SyntaxError => e; e.message != 'compile error'; ensure; $stderr = stderr; end
38
- def error_message
39
- with_verbose do
40
- begin
41
- capture_stderr { RubyVM::InstructionSequence.compile(@source) }
42
- rescue SyntaxError => e
43
- e.message
37
+ # Since Ruby 2.4, syntax error information is outputted to Exception#message instead of stderr
38
+ if begin; stderr = $stderr; $stderr = StringIO.new; RubyVM::InstructionSequence.compile("="); rescue SyntaxError => e; e.message != "compile error"; ensure; $stderr = stderr; end
39
+ def error_message
40
+ with_verbose do
41
+ begin
42
+ capture_stderr { RubyVM::InstructionSequence.compile(@source) }
43
+ rescue SyntaxError => e
44
+ e.message
45
+ end
44
46
  end
45
47
  end
46
- end
47
- else
48
- def error_message
49
- with_verbose do
50
- capture_stderr do
51
- begin
52
- RubyVM::InstructionSequence.compile(@source)
53
- rescue SyntaxError
48
+ else
49
+ def error_message
50
+ with_verbose do
51
+ capture_stderr do
52
+ begin
53
+ RubyVM::InstructionSequence.compile(@source)
54
+ rescue SyntaxError
55
+ end
54
56
  end
55
57
  end
56
58
  end
57
59
  end
58
- end
59
60
 
60
- def with_verbose
61
- origin = $VERBOSE
62
- $VERBOSE = true
63
- yield
64
- ensure
65
- $VERBOSE = origin
66
- end
61
+ def with_verbose
62
+ origin = $VERBOSE
63
+ $VERBOSE = true
64
+ yield
65
+ ensure
66
+ $VERBOSE = origin
67
+ end
67
68
 
68
- def capture_stderr
69
- origin = $stderr
70
- $stderr = StringIO.new
69
+ def capture_stderr
70
+ origin = $stderr
71
+ $stderr = StringIO.new
71
72
 
72
- yield
73
+ yield
73
74
 
74
- $stderr.string
75
- ensure
76
- $stderr = origin
77
- end
75
+ $stderr.string
76
+ ensure
77
+ $stderr = origin
78
+ end
79
+
80
+ def get_characters_from_error_message(error_message, line_index)
81
+ error_mark_included_line = error_message.split("\n")[2]
82
+
83
+ if !error_mark_included_line.nil? && character_start = error_mark_included_line.index("^")
84
+ Range.new(character_start, character_start + 1)
85
+ else
86
+ Range.new(0, @source.split("\n")[line_index].length - 1)
87
+ end
88
+ end
78
89
  end
79
90
  end
80
91
  end
@@ -1,4 +1,4 @@
1
- require 'logger'
1
+ require "logger"
2
2
 
3
3
  module LanguageServer
4
4
  class << self
@@ -8,16 +8,16 @@ module LanguageServer
8
8
  end
9
9
 
10
10
  class Formatter
11
- RESET = "\e[0m"
12
- RED = "\e[31m"
13
- YELLOW = "\e[33m"
11
+ RESET = "\e[0m".freeze
12
+ RED = "\e[31m".freeze
13
+ YELLOW = "\e[33m".freeze
14
14
 
15
15
  def call(severity, *rest)
16
16
  msg = default_message(severity, *rest)
17
17
  case severity
18
- when 'ERROR'
18
+ when "ERROR"
19
19
  RED + msg + RESET
20
- when 'WARN'
20
+ when "WARN"
21
21
  YELLOW + msg + RESET
22
22
  else
23
23
  msg
@@ -26,12 +26,12 @@ module LanguageServer
26
26
 
27
27
  private
28
28
 
29
- def default_message(*args)
30
- default_formatter.call(*args)
31
- end
29
+ def default_message(*args)
30
+ default_formatter.call(*args)
31
+ end
32
32
 
33
- def default_formatter
34
- @default_formatter ||= ::Logger::Formatter.new
35
- end
33
+ def default_formatter
34
+ @default_formatter ||= ::Logger::Formatter.new
35
+ end
36
36
  end
37
37
  end
@@ -1,4 +1,4 @@
1
- require 'language_server/project/parser'
1
+ require "language_server/project/parser"
2
2
 
3
3
  module LanguageServer
4
4
  class Project
@@ -12,11 +12,11 @@ module LanguageServer
12
12
  def find_definitions(uri:, line:, character:)
13
13
  result = result_store[file_store.path_from_remote_uri(uri)]
14
14
 
15
- ref = result.refs.select {|node| node.lines.include?(line) && node.characters.include?(character) }.min_by {|node| node.characters.size }
15
+ ref = result.refs.select { |node| node.lines.include?(line) && node.characters.include?(character) }.min_by { |node| node.characters.size }
16
16
 
17
17
  return [] unless ref
18
18
 
19
- lazy_modules.select {|n| n.full_name == ref.full_name }.force + lazy_classes.select {|n| n.full_name == ref.full_name }.force
19
+ lazy_modules.select { |n| n.full_name == ref.full_name }.force + lazy_classes.select { |n| n.full_name == ref.full_name }.force
20
20
  end
21
21
 
22
22
  def recalculate_result(uri)
@@ -27,58 +27,58 @@ module LanguageServer
27
27
  def constants(uri: nil, line: nil, character: nil)
28
28
  node = find_nearest_node(uri: uri, line: line, character: character) if uri && line && character
29
29
 
30
- lazy_constants.select {|n| n.names[0..-2] == Array(node && node.names).first(n.names.size - 1) }.force
30
+ lazy_constants.select { |n| n.names[0..-2] == Array(node && node.names).first(n.names.size - 1) }.force
31
31
  end
32
32
 
33
33
  def modules(uri: nil, line: nil, character: nil)
34
34
  node = find_nearest_node(uri: uri, line: line, character: character) if uri && line && character
35
35
 
36
- lazy_modules.select {|n| n.names[0..-2] == Array(node && node.names).first(n.names.size - 1) }.force
36
+ lazy_modules.select { |n| n.names[0..-2] == Array(node && node.names).first(n.names.size - 1) }.force
37
37
  end
38
38
 
39
39
  def classes(uri: nil, line: nil, character: nil)
40
40
  node = find_nearest_node(uri: uri, line: line, character: character) if uri && line && character
41
41
 
42
- lazy_classes.select {|n| n.names[0..-2] == Array(node && node.names).first(n.names.size - 1) }.force
42
+ lazy_classes.select { |n| n.names[0..-2] == Array(node && node.names).first(n.names.size - 1) }.force
43
43
  end
44
44
 
45
45
  private
46
46
 
47
- attr_reader :file_store, :result_store
47
+ attr_reader :file_store, :result_store
48
48
 
49
- def lazy_constants
50
- result_store.each_value.lazy.flat_map(&:constants)
51
- end
52
-
53
- def lazy_modules
54
- result_store.each_value.lazy.flat_map(&:modules)
55
- end
49
+ def lazy_constants
50
+ result_store.each_value.lazy.flat_map(&:constants)
51
+ end
56
52
 
57
- def lazy_classes
58
- result_store.each_value.lazy.flat_map(&:classes)
59
- end
53
+ def lazy_modules
54
+ result_store.each_value.lazy.flat_map(&:modules)
55
+ end
60
56
 
61
- def fetch_result
62
- file_store.each {|content, path|
63
- calculate(content, path)
64
- }
65
- end
57
+ def lazy_classes
58
+ result_store.each_value.lazy.flat_map(&:classes)
59
+ end
66
60
 
67
- def find_nearest_node(uri:, line:, character:)
68
- result = result_store[file_store.path_from_remote_uri(uri)]
61
+ def fetch_result
62
+ file_store.each { |content, path|
63
+ calculate(content, path)
64
+ }
65
+ end
69
66
 
70
- (result.modules + result.classes).select {|node| node.lines.include?(line) }.min_by {|node| node.lines.size }
71
- end
67
+ def find_nearest_node(uri:, line:, character:)
68
+ result = result_store[file_store.path_from_remote_uri(uri)]
72
69
 
73
- def calculate(content, path)
74
- begin
75
- result = Parser.parse(content, path)
76
- rescue => e
77
- LanguageServer.logger.warn("Parse failed (local: #{path.local_path}, remote: #{path.remote_path})")
78
- LanguageServer.logger.warn(e)
70
+ (result.modules + result.classes).select { |node| node.lines.include?(line) }.min_by { |node| node.lines.size }
79
71
  end
80
72
 
81
- result_store[path] = result if result
82
- end
73
+ def calculate(content, path)
74
+ begin
75
+ result = Parser.parse(content, path)
76
+ rescue => e
77
+ LanguageServer.logger.warn("Parse failed (local: #{path.local_path}, remote: #{path.remote_path})")
78
+ LanguageServer.logger.warn(e)
79
+ end
80
+
81
+ result_store[path] = result if result
82
+ end
83
83
  end
84
84
  end