Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM crystallang/crystal:1.14.0-alpine
FROM crystallang/crystal:1.15.1-alpine

WORKDIR /app

Expand All @@ -9,7 +9,7 @@ RUN apk add --update --no-cache --force-overwrite \
# Build crystalline.
COPY . /app/

RUN git clone -b 1.14.0 --depth=1 https://github.com/crystal-lang/crystal \
RUN git clone -b 1.15.1 --depth=1 https://github.com/crystal-lang/crystal \
&& make -C crystal llvm_ext \
&& CRYSTAL_PATH=crystal/src:lib shards build crystalline \
--no-debug --progress --stats --production --static --release \
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ Building from source does take a long time._

| Crystal | Crystalline |
| -------- | ----------- |
| **1.14** | **0.15** |
| **1.15** | **0.16** |
| 1.14 | 0.15 |
| 1.13 | 0.14 |
| 1.12 | 0.13 |
| 1.11 | 0.12 |
Expand Down
81 changes: 45 additions & 36 deletions src/crystalline/analysis/analysis.cr
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,20 @@ require "./cursor_visitor"
require "./submodule_visitor"

module Crystalline::Analysis
{% if flag?(:preview_mt) %}
@@dedicated_thread : Thread = Thread.new(name: "crystalline-dedicated-thread") do
scheduler = Thread.current.scheduler
scheduler.run_loop
end
{% end %}

private def self.spawn_dedicated(*, name : String? = nil, &block)
fiber = Fiber.new(name, &block)
{% if flag?(:preview_mt) %} fiber.set_current_thread(@@dedicated_thread) {% end %}
fiber.enqueue
fiber
end

# Compile a target *file_uri*.
def self.compile(server : LSP::Server, file_uri : URI, *, lib_path : String? = nil, file_overrides : Hash(String, String)? = nil, ignore_diagnostics = false, wants_doc = false, fail_fast = false, top_level = false)
if file_uri.scheme == "file"
Expand All @@ -24,45 +38,40 @@ module Crystalline::Analysis
# LSP::Log.info { "lib_path: #{lib_path}" }

# Delegate heavy processing to a separate thread.
Thread.new do
wait_before_termination = Channel(Nil).new
spawn same_thread: true do
dev_null = File.open(File::NULL, "w")
compiler = Crystal::Compiler.new
compiler.no_codegen = true
compiler.color = false
compiler.no_cleanup = true
compiler.file_overrides = file_overrides
compiler.wants_doc = wants_doc
compiler.stdout = dev_null
compiler.stderr = dev_null

if lib_path_override = lib_path
path = Crystal::CrystalPath.default_path_without_lib.split(Process::PATH_DELIMITER)
path.insert(0, lib_path_override)
compiler.crystal_path = Crystal::CrystalPath.new(path)
end
spawn_dedicated do
dev_null = File.open(File::NULL, "w")
compiler = Crystal::Compiler.new
compiler.no_codegen = true
compiler.color = false
compiler.no_cleanup = true
compiler.file_overrides = file_overrides
compiler.wants_doc = wants_doc
compiler.stdout = dev_null
compiler.stderr = dev_null

if lib_path_override = lib_path
path = Crystal::CrystalPath.default_path_without_lib.split(Process::PATH_DELIMITER)
path.insert(0, lib_path_override)
compiler.crystal_path = Crystal::CrystalPath.new(path)
end

reply = begin
if top_level
# Top level only.
compiler.top_level_semantic(sources)
elsif fail_fast
# Regular parser + semantic analysis phases.
compiler.compile(sources, "")
else
# Fail-slow means that errors are collected instead of throwing during the semantic phase, and we still get a partially typed AST back.
compiler.fail_slow_compile(sources, "")
end
reply = begin
if top_level
# Top level only.
compiler.top_level_semantic(sources)
elsif fail_fast
# Regular parser + semantic analysis phases.
compiler.compile(sources, "")
else
# Fail-slow means that errors are collected instead of throwing during the semantic phase, and we still get a partially typed AST back.
compiler.fail_slow_compile(sources, "")
end
reply_channel.send(reply)
rescue e : Exception
reply_channel.send(e)
ensure
dev_null.try &.close
wait_before_termination.send nil
end
wait_before_termination.receive
reply_channel.send(reply)
rescue e : Exception
reply_channel.send(e)
ensure
dev_null.try &.close
end
result = reply_channel.receive

Expand Down
Loading