language_server 0.3.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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