language_server 0.3.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e4688b01593c24927d0572463de9080c66ecbeba
4
- data.tar.gz: a90af30ffe0433b3db1315f4134611be8d82fb09
3
+ metadata.gz: 7afd0094b57b216afc44723653a9bd07aa1f7910
4
+ data.tar.gz: 1c440fef75c1492a7c4048e31f70123cdcd5c049
5
5
  SHA512:
6
- metadata.gz: c29ea2b693915d53c8dd7790a8525399b1babeeddcaec5a14a2d97f53957ee88f4fe803b25d65b0d8f004cd452f3324f52c25745fe162e3915eb274b6d0bc016
7
- data.tar.gz: 6a0041a1048ea39ebe61671c199d1210231b78ee68bae222b2c8f94e67da36460ed01e2486d61b96dedd3666171d0078c2049b9d43d52478d165ffac401622af
6
+ metadata.gz: e9826d5f5402567b90eac9a722d4e4baa0cea4b9d388df2b263641a9a28190759f86cb739b56f355365302b1640c6c1f90890ae8abe91b1c08b99af8443c5864
7
+ data.tar.gz: f1eb2ab1791cdd3d1440500603e00498e886f68ba1e71f59e615e2cac6a1d59cc0fce0dbdfd0586d70369c32dc1b403b29d9bbc61fe60756cd82db3a6f0f1b01
@@ -1,5 +1,8 @@
1
1
  {
2
2
  "ruby-lsc.commandWithArgs": [
3
3
  "docker-compose", "run", "--rm", "app"
4
- ]
4
+ ],
5
+ "files.exclude": {
6
+ "vendor": true
7
+ }
5
8
  }
@@ -55,7 +55,7 @@ further defined and clarified by project maintainers.
55
55
  ## Enforcement
56
56
 
57
57
  Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
- reported by contacting the project team at TODO: Write your email address. All
58
+ reported by contacting the project team at mtsmfm@gmail.com. All
59
59
  complaints will be reviewed and investigated and will result in a response that
60
60
  is deemed necessary and appropriate to the circumstances. The project team is
61
61
  obligated to maintain confidentiality with regard to the reporter of an incident.
@@ -1,11 +1,12 @@
1
- FROM ruby:2.4.1
1
+ ARG RUBY_VERSION=2.4.1
2
+ FROM ruby:$RUBY_VERSION
2
3
 
3
4
  RUN apt-get update && apt-get install less -y
4
5
  RUN groupadd --gid 1000 ruby && useradd --uid 1000 --gid ruby --shell /bin/bash --create-home ruby
5
6
  RUN mkdir /app && chown ruby:ruby /app
6
7
 
7
8
  ENV LANG=C.UTF-8 \
8
- BUNDLE_PATH=/app/vendor/bundle \
9
+ BUNDLE_PATH=/app/vendor/bundle/$RUBY_VERSION \
9
10
  BUNDLE_JOBS=4
10
11
 
11
12
  USER ruby
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2017 TODO: Write your name
3
+ Copyright (c) 2017 Fumiaki MATSUSHIMA
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -4,7 +4,7 @@ A Ruby Language Server implementation.
4
4
 
5
5
  ## Installation
6
6
 
7
- If you are using vscode, instal [ruby-lsc](https://marketplace.visualstudio.com/items?itemName=mtsmfm.ruby-lsc) extension.
7
+ If you are using vscode, install [ruby-lsc](https://marketplace.visualstudio.com/items?itemName=mtsmfm.ruby-lsc) extension.
8
8
 
9
9
  ### Docker
10
10
 
@@ -61,11 +61,13 @@ https://github.com/EugenMayer/docker-sync/wiki/1.-Installation
61
61
 
62
62
  ### Run test
63
63
 
64
- $ docker-compose run app bundle exec rake test
64
+ $ docker-compose run app bin/m
65
+ $ docker-compose run ruby-2-3 bin/m
66
+ $ docker-compose run ruby-2-2 bin/m
65
67
 
66
68
  ## Contributing
67
69
 
68
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/language_server. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
70
+ Bug reports and pull requests are welcome on GitHub at https://github.com/mtsmfm/language_server-ruby. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
69
71
 
70
72
 
71
73
  ## License
@@ -1,3 +1,5 @@
1
1
  #!/usr/bin/env sh
2
2
 
3
+ set -ex
4
+ yarn install
3
5
  yarn run -s ts-node scripts/generateFiles.ts
data/bin/m ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+ #
4
+ # This file was generated by Bundler.
5
+ #
6
+ # The application 'm' is installed as part of a gem, and
7
+ # this file is here to facilitate running it.
8
+ #
9
+
10
+ require "pathname"
11
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
12
+ Pathname.new(__FILE__).realpath)
13
+
14
+ require "rubygems"
15
+ require "bundler/setup"
16
+
17
+ load Gem.bin_path("m", "m")
@@ -0,0 +1,31 @@
1
+ version: 2
2
+ jobs:
3
+ build:
4
+ docker:
5
+ - image: tmaier/docker-compose
6
+ working_directory: /project
7
+ steps:
8
+ - checkout
9
+ - setup_remote_docker:
10
+ version: 17.05.0-ce
11
+ - run:
12
+ name: setup
13
+ command: |
14
+ set -x
15
+ docker info
16
+ docker volume create mtsmfm-language-server-sync
17
+ docker create -v mtsmfm-language-server-sync:/app --name mtsmfm-language-server-sync busybox chown -R 1000:1000 /app
18
+ docker cp . mtsmfm-language-server-sync:/app
19
+ docker start mtsmfm-language-server-sync
20
+ docker-compose build
21
+ docker-compose run app bin/setup
22
+ docker-compose run ruby-2-3 bin/setup
23
+ docker-compose run ruby-2-2 bin/setup
24
+ - run:
25
+ name: test
26
+ command: |
27
+ set -x
28
+ docker-compose run node bin/generate_files
29
+ docker-compose run app bin/m
30
+ docker-compose run ruby-2-3 bin/m
31
+ docker-compose run ruby-2-2 bin/m
@@ -1,23 +1,35 @@
1
1
  version: '3.0'
2
2
  services:
3
- app:
4
- build:
3
+ app: &app
4
+ build: &app-build
5
5
  context: .
6
6
  dockerfile: Dockerfile.development
7
7
  volumes:
8
- - app-sync:/app:nocopy
8
+ - mtsmfm-language-server-sync:/app:nocopy
9
9
  - home:/home/ruby
10
10
  - $HOME/.gitconfig:/home/ruby/.gitconfig:ro
11
11
  - $HOME/.ssh:/home/ruby/.ssh:ro
12
12
  - $HOME/.gem:/home/ruby/.gem
13
+ ruby-2-3:
14
+ <<: *app
15
+ build:
16
+ <<: *app-build
17
+ args:
18
+ RUBY_VERSION: 2.3
19
+ ruby-2-2:
20
+ <<: *app
21
+ build:
22
+ <<: *app-build
23
+ args:
24
+ RUBY_VERSION: 2.2
13
25
  node:
14
26
  build:
15
27
  context: .
16
28
  dockerfile: Dockerfile-node.development
17
29
  volumes:
18
- - app-sync/:/app
30
+ - mtsmfm-language-server-sync:/app:nocopy
19
31
  - home:/home/node
20
32
  volumes:
21
- app-sync:
33
+ mtsmfm-language-server-sync:
22
34
  external: true
23
35
  home:
@@ -2,6 +2,8 @@ version: '2'
2
2
  options:
3
3
  verbose: true
4
4
  syncs:
5
- app-sync:
5
+ mtsmfm-language-server-sync:
6
6
  src: .
7
7
  sync_userid: 1000
8
+ image: mtsmfm/unison
9
+ sync_excludes: ['vendor', 'node_modules', 'tmp']
@@ -32,4 +32,6 @@ Gem::Specification.new do |spec|
32
32
  spec.add_development_dependency "minitest", "~> 5.0"
33
33
  spec.add_development_dependency "pry-byebug"
34
34
  spec.add_development_dependency "minitest-power_assert"
35
+ spec.add_development_dependency "m"
36
+ spec.add_development_dependency "awesome_print"
35
37
  end
@@ -4,7 +4,9 @@ require "language_server/protocol/constants"
4
4
  require "language_server/protocol/stdio"
5
5
  require "language_server/linter/ruby_wc"
6
6
  require "language_server/completion_provider/rcodetools"
7
- require "language_server/uri_store"
7
+ require "language_server/completion_provider/ad_hoc"
8
+ require "language_server/file_store"
9
+ require "language_server/project"
8
10
 
9
11
  require "json"
10
12
  require "logger"
@@ -18,6 +20,7 @@ module LanguageServer
18
20
  def run
19
21
  writer = Protocol::Stdio::Writer.new
20
22
  reader = Protocol::Stdio::Reader.new
23
+ variables = {}
21
24
 
22
25
  reader.read do |request|
23
26
  method = request[:method].to_sym
@@ -29,7 +32,12 @@ module LanguageServer
29
32
  }
30
33
 
31
34
  if subscriber
32
- result = subscriber.call(request, writer.method(:notify))
35
+ keys = subscriber.parameters.map(&:last)
36
+ result = subscriber.call(
37
+ {
38
+ request: request, notifier: writer.method(:notify), variables: variables
39
+ }.merge(variables).select {|k, _| keys.include?(k) }
40
+ )
33
41
 
34
42
  if request[:id]
35
43
  writer.respond(id: request[:id], result: result)
@@ -49,7 +57,10 @@ module LanguageServer
49
57
  end
50
58
  end
51
59
 
52
- on :initialize do
60
+ on :initialize do |request:, variables:|
61
+ variables[:file_store] = FileStore.new(load_paths: $LOAD_PATH, remote_root: request[:params][:rootPath], local_root: Dir.getwd)
62
+ variables[:project] = Project.new(variables[:file_store])
63
+
53
64
  Protocol::Interfaces::InitializeResult.new(
54
65
  capabilities: Protocol::Interfaces::ServerCapabilities.new(
55
66
  text_document_sync: Protocol::Interfaces::TextDocumentSyncOptions.new(
@@ -67,10 +78,11 @@ module LanguageServer
67
78
  exit
68
79
  end
69
80
 
70
- on :"textDocument/didChange" do |request, notifier|
81
+ on :"textDocument/didChange" do |request:, notifier:, file_store:, project:|
71
82
  uri = request[:params][:textDocument][:uri]
72
83
  text = request[:params][:contentChanges][0][:text]
73
- UriStore[uri] = text
84
+ file_store.cache(uri, text)
85
+ project.recalculate_result(uri)
74
86
 
75
87
  diagnostics = Linter::RubyWC.new(text).call.map do |error|
76
88
  Protocol::Interfaces::Diagnostic.new(
@@ -98,15 +110,13 @@ module LanguageServer
98
110
  )
99
111
  end
100
112
 
101
- on :"textDocument/completion" do |request|
113
+ on :"textDocument/completion" do |request:, file_store:, project:|
102
114
  uri = request[:params][:textDocument][:uri]
103
- line, character = request[:params][:position].fetch_values(:line, :character)
104
- CompletionProvider::Rcodetools.new(uri, line.to_i, character.to_i).call.map do |candidate|
105
- Protocol::Interfaces::CompletionItem.new(
106
- label: candidate.method_name,
107
- detail: candidate.description,
108
- kind: Protocol::Constants::CompletionItemKind::METHOD
109
- )
110
- end
115
+ line, character = request[:params][:position].fetch_values(:line, :character).map(&:to_i)
116
+
117
+ [
118
+ CompletionProvider::AdHoc.new(uri: uri, line: line, character: character, project: project),
119
+ CompletionProvider::Rcodetools.new(uri: uri, line: line, character: character, file_store: file_store)
120
+ ].flat_map(&:call)
111
121
  end
112
122
  end
@@ -0,0 +1,45 @@
1
+ require "language_server/project"
2
+
3
+ module LanguageServer
4
+ module CompletionProvider
5
+ class AdHoc
6
+ def initialize(uri:, line:, character:, project:)
7
+ @uri = uri
8
+ @line = line
9
+ @character = character
10
+ @project = project
11
+ end
12
+
13
+ def call
14
+ (project.constants(uri: uri, line: line, character: character).map {|c|
15
+ Protocol::Interfaces::CompletionItem.new(
16
+ label: c.name,
17
+ detail: c.full_name,
18
+ documentation: "#{c.remote_path}##{c.lineno}",
19
+ kind: Protocol::Constants::CompletionItemKind::ENUM
20
+ )
21
+ } +
22
+ project.classes(uri: uri, line: line, character: character).map {|c|
23
+ Protocol::Interfaces::CompletionItem.new(
24
+ label: c.name,
25
+ detail: c.full_name,
26
+ documentation: "#{c.remote_path}##{c.lineno}",
27
+ kind: Protocol::Constants::CompletionItemKind::CLASS
28
+ )
29
+ } +
30
+ project.modules(uri: uri, line: line, character: character).map {|m|
31
+ Protocol::Interfaces::CompletionItem.new(
32
+ label: m.name,
33
+ detail: m.full_name,
34
+ documentation: "#{m.remote_path}##{m.lineno}",
35
+ kind: Protocol::Constants::CompletionItemKind::MODULE
36
+ )
37
+ }).uniq(&:label)
38
+ end
39
+
40
+ private
41
+
42
+ attr_reader :uri, :line, :character, :project
43
+ end
44
+ end
45
+ end
@@ -1,22 +1,10 @@
1
- require "language_server/uri_store"
1
+ require "language_server/protocol/interfaces/completion_item"
2
+ require "language_server/protocol/constants/completion_item_kind"
2
3
 
3
4
  require "rcodetools/completion"
4
5
 
5
6
  module LanguageServer
6
7
  module CompletionProvider
7
- class Candidate
8
- attr_reader :method_name, :description
9
-
10
- def initialize(method_name:, description:)
11
- @method_name = method_name
12
- @description = description
13
- end
14
-
15
- def ==(other)
16
- method_name == other.method_name && description == other.description
17
- end
18
- end
19
-
20
8
  class Filter < ::Rcodetools::XMPCompletionFilter
21
9
  @candidates_with_description_flag = true
22
10
 
@@ -28,24 +16,29 @@ module LanguageServer
28
16
  end
29
17
 
30
18
  class Rcodetools
31
- def initialize(uri, line, character)
19
+ def initialize(uri:, line:, character:, file_store:)
32
20
  @uri = uri
33
21
  @line = line
34
22
  @character = character
23
+ @file_store = file_store
35
24
  end
36
25
 
37
26
  def call
38
27
  _, candidates = Filter.run(source, lineno: @line + 1, column: @character)
39
28
  candidates.map do |candidate|
40
29
  method_name, description = candidate.split(/\0/, 2)
41
- Candidate.new(method_name: method_name, description: description)
30
+ Protocol::Interfaces::CompletionItem.new(
31
+ label: method_name,
32
+ detail: description,
33
+ kind: Protocol::Constants::CompletionItemKind::METHOD
34
+ )
42
35
  end
43
36
  end
44
37
 
45
38
  private
46
39
 
47
40
  def source
48
- UriStore[@uri]
41
+ @file_store.read_remote_uri(@uri)
49
42
  end
50
43
  end
51
44
  end
@@ -0,0 +1,99 @@
1
+ require "uri"
2
+
3
+ module LanguageServer
4
+ class FileStore
5
+ include Enumerable
6
+
7
+ class FilePath
8
+ class << self
9
+ def from_remote_uri(remote_root:, local_root:, remote_uri:)
10
+ new(remote_root: remote_root, local_root: local_root, local_path: URI(remote_uri).path.sub(remote_root, local_root))
11
+ end
12
+ end
13
+
14
+ attr_reader :local_root, :remote_root, :local_path
15
+
16
+ def initialize(remote_root:, local_root:, local_path:)
17
+ @remote_root = remote_root
18
+ @local_root = local_root
19
+ @local_path = local_path
20
+ end
21
+
22
+ def remote_path
23
+ @remote_path ||= local_path.sub(local_root, remote_root)
24
+ end
25
+
26
+ def eql?(other)
27
+ self.class == other.class && remote_path == other.remote_path
28
+ end
29
+
30
+ def ==(other)
31
+ eql?(other)
32
+ end
33
+
34
+ def hash
35
+ self.remote_path.hash
36
+ end
37
+ end
38
+
39
+ def initialize(load_paths: [], remote_root: Dir.getwd, local_root: Dir.getwd)
40
+ @load_paths = load_paths
41
+ @remote_root = remote_root
42
+ @local_root = local_root
43
+ end
44
+
45
+ def cache(remote_uri, content)
46
+ cache_store[path_from_remote_uri(remote_uri)] = content
47
+ end
48
+
49
+ def path_from_remote_uri(remote_uri)
50
+ FilePath.from_remote_uri(local_root: local_root, remote_root: remote_root, remote_uri: remote_uri)
51
+ end
52
+
53
+ def read(path)
54
+ if exists_on_cache?(path)
55
+ read_from_cache(path)
56
+ else
57
+ read_from_local(path)
58
+ end
59
+ end
60
+
61
+ def read_remote_uri(remote_uri)
62
+ read(path_from_remote_uri(remote_uri))
63
+ end
64
+
65
+ def each(&block)
66
+ all_paths.each do |path|
67
+ block.call(read(path), path)
68
+ end
69
+ end
70
+
71
+ private
72
+
73
+ attr_reader :load_paths, :remote_root, :local_root
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
82
+
83
+ def exists_on_cache?(path)
84
+ cache_store.key?(path)
85
+ end
86
+
87
+ def read_from_cache(path)
88
+ cache_store[path]
89
+ end
90
+
91
+ def read_from_local(path)
92
+ File.read(path.local_path)
93
+ end
94
+
95
+ def cache_store
96
+ @cache_store ||= {}
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,67 @@
1
+ require 'language_server/project/parser'
2
+
3
+ module LanguageServer
4
+ class Project
5
+ def initialize(file_store)
6
+ @file_store = file_store
7
+ @result_store = {}
8
+
9
+ fetch_result
10
+ end
11
+
12
+ def recalculate_result(uri)
13
+ path = file_store.path_from_remote_uri(uri)
14
+ result_store[path] = calculate(file_store.read(path), path)
15
+ end
16
+
17
+ def constants(uri: nil, line: nil, character: nil)
18
+ node = find_nearest_node(uri: uri, line: line, character: character) if uri && line && character
19
+
20
+ lazy_constants.select {|n| n.names[0..-2] == Array(node && node.names).first(n.names.size - 1) }.force
21
+ end
22
+
23
+ def modules(uri: nil, line: nil, character: nil)
24
+ node = find_nearest_node(uri: uri, line: line, character: character) if uri && line && character
25
+
26
+ lazy_modules.select {|n| n.names[0..-2] == Array(node && node.names).first(n.names.size - 1) }.force
27
+ end
28
+
29
+ def classes(uri: nil, line: nil, character: nil)
30
+ node = find_nearest_node(uri: uri, line: line, character: character) if uri && line && character
31
+
32
+ lazy_classes.select {|n| n.names[0..-2] == Array(node && node.names).first(n.names.size - 1) }.force
33
+ end
34
+
35
+ private
36
+
37
+ attr_reader :file_store, :result_store
38
+
39
+ def lazy_constants
40
+ result_store.each_value.lazy.flat_map(&:constants)
41
+ end
42
+
43
+ def lazy_modules
44
+ result_store.each_value.lazy.flat_map(&:modules)
45
+ end
46
+
47
+ def lazy_classes
48
+ result_store.each_value.lazy.flat_map(&:classes)
49
+ end
50
+
51
+ def fetch_result
52
+ file_store.each {|content, path|
53
+ result_store[path] = calculate(content, path)
54
+ }
55
+ end
56
+
57
+ def find_nearest_node(uri:, line:, character:)
58
+ result = result_store[file_store.path_from_remote_uri(uri)]
59
+
60
+ (result.modules + result.classes).select {|node| node.lines.include?(line) }.min_by {|node| node.lines.size }
61
+ end
62
+
63
+ def calculate(content, path)
64
+ Parser.parse(content, path)
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,96 @@
1
+ module LanguageServer
2
+ class Project
3
+ class Node
4
+ class << self
5
+ def attributes(*attrs)
6
+ attr_accessor(*attrs)
7
+ attribute_names.concat(attrs)
8
+ class_eval <<-RUBY, __FILE__, __LINE__
9
+ def initialize(#{attribute_names.map {|n| "#{n}:" }.join(',')})
10
+ #{
11
+ attribute_names.map {|n|
12
+ "@#{n} = #{n}"
13
+ }.join("\n")
14
+ }
15
+ end
16
+ RUBY
17
+ end
18
+
19
+ def attribute_names
20
+ @attribute_names ||= superclass.respond_to?(:attribute_names) ? superclass.attribute_names.dup : []
21
+ end
22
+ end
23
+
24
+ attributes :lineno, :path
25
+
26
+ def remote_path; path.remote_path; end
27
+ def local_path; path.local_path; end
28
+
29
+ def eql?(other)
30
+ other.instance_of?(self.class) && attributes == other.attributes
31
+ end
32
+
33
+ def ==(other)
34
+ eql?(other)
35
+ end
36
+
37
+ def hash
38
+ self.attributes.hash
39
+ end
40
+
41
+ def attributes
42
+ self.class.attribute_names.map {|a|
43
+ [a, public_send(a)]
44
+ }.to_h
45
+ end
46
+ end
47
+
48
+ class Constant < Node
49
+ attributes :namespaces, :name, :value
50
+
51
+ def unshift_namespace(class_or_module)
52
+ namespaces.unshift(class_or_module)
53
+ end
54
+
55
+ def names
56
+ namespaces.flat_map(&:names) + [name]
57
+ end
58
+
59
+ def full_name
60
+ names.join('::')
61
+ end
62
+ end
63
+
64
+ class LiteralValue < Node
65
+ attributes :value
66
+ end
67
+
68
+ class Module < Node
69
+ attributes :constant, :children
70
+
71
+ %i(name namespaces full_name names).each do |m|
72
+ define_method(m) { constant.__send__(m) }
73
+ end
74
+
75
+ def unshift_namespace(class_or_module)
76
+ constant.unshift_namespace(class_or_module)
77
+ end
78
+
79
+ def lines
80
+ constant.lineno..lineno
81
+ end
82
+
83
+ def inspect
84
+ "<Module #{full_name}#L#{lines.begin}-#{lines.end}>"
85
+ end
86
+ end
87
+
88
+ class Class < Module
89
+ attributes :superclass
90
+
91
+ def inspect
92
+ "<Class #{full_name}#L#{lines.begin}-#{lines.end}>"
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,80 @@
1
+ require 'language_server/project/node'
2
+ require 'ripper'
3
+
4
+ module LanguageServer
5
+ class Project
6
+ class Parser < Ripper
7
+ class Result
8
+ attr_reader :constants, :classes, :modules
9
+
10
+ def initialize
11
+ @constants = []
12
+ @classes = []
13
+ @modules = []
14
+ end
15
+ end
16
+
17
+ class << self
18
+ def parse(src, path = nil)
19
+ new(src, path).tap(&:parse).result
20
+ end
21
+ end
22
+
23
+ attr_reader :result
24
+
25
+ def initialize(src, path)
26
+ super(src, path && path.remote_path)
27
+
28
+ @path = path
29
+ @result = Result.new
30
+ @current_constants = []
31
+ end
32
+
33
+ private
34
+
35
+ attr_reader :path
36
+
37
+ def lineno
38
+ # Language Server Protocol's lineno is zero origin
39
+ super - 1
40
+ end
41
+
42
+ def on_const(name)
43
+ Constant.new(namespaces: [], name: name, value: nil, lineno: lineno, path: path).tap do |c|
44
+ @current_constants.push(c)
45
+ end
46
+ end
47
+
48
+ def on_int(value)
49
+ LiteralValue.new(value: value.to_i, lineno: lineno, path: path)
50
+ end
51
+
52
+ def on_stmts_add(*args)
53
+ args.flatten.compact
54
+ end
55
+
56
+ def on_assign(left, right)
57
+ result.constants << left if Constant === left
58
+
59
+ left.value = right if left.respond_to?(:value) # TODO: remove this condition
60
+ left
61
+ end
62
+
63
+ def on_module(constant, children)
64
+ cn = children.select {|child| child.instance_of?(Constant) || child.instance_of?(Module) || child.instance_of?(Class)}
65
+ Module.new(constant: constant, lineno: lineno, path: path, children: cn).tap do |m|
66
+ result.modules << m
67
+ cn.each {|child| child.unshift_namespace(m) }
68
+ end
69
+ end
70
+
71
+ def on_class(constant, superclass, children)
72
+ cn = children.select {|child| child.instance_of?(Constant) || child.instance_of?(Module) || child.instance_of?(Class)}
73
+ Class.new(constant: constant, superclass: superclass, lineno: lineno, path: path, children: cn).tap do |c|
74
+ result.classes << c
75
+ cn.each {|child| child.unshift_namespace(c) }
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
@@ -1,3 +1,3 @@
1
1
  module LanguageServer
2
- VERSION = "0.3.1"
2
+ VERSION = "0.4.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: language_server
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Fumiaki MATSUSHIMA
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-05-26 00:00:00.000000000 Z
11
+ date: 2017-08-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rcodetools
@@ -94,6 +94,34 @@ dependencies:
94
94
  - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: m
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: awesome_print
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
97
125
  description: A Ruby Language Server implementation
98
126
  email:
99
127
  - mtsmfm@gmail.com
@@ -114,14 +142,21 @@ files:
114
142
  - Rakefile
115
143
  - bin/console
116
144
  - bin/generate_files
145
+ - bin/m
117
146
  - bin/setup
147
+ - circle.yml
118
148
  - docker-compose.yml
119
149
  - docker-sync.yml
120
150
  - exe/language_server
121
151
  - language_server.gemspec
122
152
  - lib/language_server.rb
153
+ - lib/language_server/completion_provider/ad_hoc.rb
123
154
  - lib/language_server/completion_provider/rcodetools.rb
155
+ - lib/language_server/file_store.rb
124
156
  - lib/language_server/linter/ruby_wc.rb
157
+ - lib/language_server/project.rb
158
+ - lib/language_server/project/node.rb
159
+ - lib/language_server/project/parser.rb
125
160
  - lib/language_server/protocol/constants.rb
126
161
  - lib/language_server/protocol/constants/completion_item_kind.rb
127
162
  - lib/language_server/protocol/constants/diagnostic_severity.rb
@@ -225,7 +260,6 @@ files:
225
260
  - lib/language_server/protocol/stdio.rb
226
261
  - lib/language_server/protocol/stdio/reader.rb
227
262
  - lib/language_server/protocol/stdio/writer.rb
228
- - lib/language_server/uri_store.rb
229
263
  - lib/language_server/version.rb
230
264
  - package.json
231
265
  - scripts/generateFiles.ts
@@ -1,23 +0,0 @@
1
- module LanguageServer
2
- class UriStore
3
- class << self
4
- def []=(uri, content)
5
- store[uri] = content
6
- end
7
-
8
- def [](uri)
9
- store[uri]
10
- end
11
-
12
- def clear
13
- store.clear
14
- end
15
-
16
- private
17
-
18
- def store
19
- @store ||= {}
20
- end
21
- end
22
- end
23
- end