Skip to content
This repository has been archived by the owner on Jun 1, 2023. It is now read-only.

Make scry faster and lightweight #53

Merged
merged 8 commits into from Mar 6, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion .travis.yml
Expand Up @@ -15,7 +15,7 @@ matrix:
- DEPLOY_DIR=bin/darwin

install:
- bin/ci prepare_build
- bin/ci prepare_build

script:
- bin/ci build
Expand Down
1 change: 0 additions & 1 deletion Dockerfile
@@ -1,7 +1,6 @@
FROM crystallang/crystal:0.24.1

RUN apt-get update
RUN apt-get install -y llvm-4.0-dev
RUN apt-get clean
RUN rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

Expand Down
4 changes: 2 additions & 2 deletions README.md
Expand Up @@ -17,7 +17,7 @@ The server is implemented in Crystal.

To install scry download it from [releases page](https://github.com/crystal-lang-tools/scry/releases) or compile latest version using:

> **Note:** crystal and LLVM are required in order to compile scry.
> **Note:** crystal is required in order to compile scry.

```
git clone https://github.com/crystal-lang-tools/scry.git
Expand All @@ -32,7 +32,7 @@ Then setup `scry` binary path on your LSP client.
- Completion feature is still experimental.
- Unexpected diagnostics can appear on files using implicit `require`, try using explicit `require` at top of your files.
- Go to definition only work for some methods and variables. Go to classes or macros definition is not supported yet.
- Symbol listing is per file, listing workspace symbols isn't supported yet.
- Symbol listing works per file, searching for workspace symbols is not supported yet.

## Roadmap

Expand Down
5 changes: 2 additions & 3 deletions bin/ci
Expand Up @@ -65,8 +65,7 @@ prepare_build() {
on_linux docker build -t crystal/scry-image .

on_osx brew update
on_osx brew install llvm crystal-lang
on_osx brew link --overwrite --force llvm
on_osx brew install crystal-lang
}


Expand Down Expand Up @@ -139,4 +138,4 @@ case $command in
exit 1
fi
;;
esac
esac
2 changes: 1 addition & 1 deletion spec/scry/initialize_spec.cr
Expand Up @@ -6,7 +6,7 @@ module Scry
initer = Initializer.new(
InitializeParams.from_json({
processId: 1,
rootPath: "/homa/main/Projects/Experiment",
rootPath: "/home/main/Projects/Experiment",
capabilities: {} of String => String,
trace: "off",
}.to_json),
Expand Down
28 changes: 16 additions & 12 deletions src/scry/analyzer.cr
@@ -1,4 +1,3 @@
require "compiler/crystal/**"
require "./workspace"
require "./text_document"
require "./publish_diagnostic"
Expand Down Expand Up @@ -26,17 +25,22 @@ module Scry

# NOTE: compiler is a bit heavy in some projects.
private def analyze(source)
source = Crystal::Compiler::Source.new(@text_document.filename, source)
compiler = Crystal::Compiler.new
compiler.color = false
compiler.no_codegen = true
compiler.debug = Crystal::Debug::None
compiler.compile(source, source.filename + ".out")
[@diagnostic.clean]
rescue ex : Crystal::Exception
@diagnostic.from(ex)
ensure
GC.collect
response = crystal_build(@text_document.filename, source)
if response.empty?
[@diagnostic.clean]
else
@diagnostic.from(response)
end
rescue ex
Log.logger.error("A error was found while searching diagnostics\n#{ex}")
nil
end

private def crystal_build(filename, source)
code = IO::Memory.new(source)
String.build do |io|
Process.run("crystal", ["build", "--no-codegen", "--no-color", "--error-trace", "-f", "json", "--stdin-filename", filename], output: io, error: io, input: code)
end
end
end
end
30 changes: 13 additions & 17 deletions src/scry/implementations.cr
@@ -1,5 +1,3 @@
require "compiler/crystal/**"

require "./log"
require "./protocol/location"

Expand All @@ -21,29 +19,27 @@ module Scry

# NOTE: compiler is a bit heavy in some projects.
def search(filename, source, position)
source = Crystal::Compiler::Source.new(filename, source)
compiler = Crystal::Compiler.new
compiler.color = false
compiler.no_codegen = true
compiler.debug = Crystal::Debug::None
result = compiler.compile(source, filename + ".out")
loc = Crystal::Location.new(filename, position.line + 1, position.character + 1)
res = Crystal::ImplementationsVisitor.new(loc).process(result)
Log.logger.debug(res)
impls = res.implementations
if res.status == "ok" && impls
response = crystal_tool(filename, position)
parsed_response = JSON.parse(response)
impls = parsed_response["implementations"]?
if impls
locations = impls.map do |impl|
pos = Position.new(impl.line, impl.column)
pos = Position.new(impl["line"].as_i, impl["column"].as_i)
range = Range.new(pos, pos)
Location.new("file://" + impl.filename, range)
Location.new("file://" + impl["filename"].as_s, range)
end
ResponseMessage.new(@text_document.id, locations)
end
rescue ex
Log.logger.error("A error was found while searching definitions\n#{ex}")
nil
ensure
GC.collect
end

private def crystal_tool(filename, position)
location = "#{filename}:#{position.line + 1}:#{position.character + 1}"
String.build do |io|
Process.run("crystal", ["tool", "implementations", "--no-color", "--error-trace", "-f", "json", "-c", "#{location}", filename], output: io, error: io)
end
end
end
end
17 changes: 17 additions & 0 deletions src/scry/missing_methods.cr
@@ -0,0 +1,17 @@
# HACK: to avoid requiring the whole compiler
module Crystal
struct CrystalPath
class Error
def to_s_with_source(source, io)
end
end
end

class Exception
def to_json_single(json)
json.object do
json.field "message", @message
end
end
end
end
7 changes: 4 additions & 3 deletions src/scry/parse_analyzer.cr
@@ -1,8 +1,9 @@
require "compiler/crystal/**"

require "compiler/crystal/syntax"
require "compiler/crystal/crystal_path"
require "./workspace"
require "./text_document"
require "./publish_diagnostic"
require "./missing_methods"

module Scry
struct ParseAnalyzer
Expand All @@ -20,7 +21,7 @@ module Scry
parser.parse
[@diagnostic.clean]
rescue ex : Crystal::Exception
@diagnostic.from(ex)
@diagnostic.from(ex.to_json)
end
end
end
2 changes: 1 addition & 1 deletion src/scry/publish_diagnostic.cr
Expand Up @@ -26,7 +26,7 @@ module Scry
end

def from(ex)
build_failures = Array(BuildFailure).from_json(ex.to_json)
build_failures = Array(BuildFailure).from_json(ex)
build_failures
.uniq
.first(@workspace.max_number_of_problems)
Expand Down