Skip to content

Commit 77bddeb

Browse files
committed
add compilation flags support
1 parent d7fc6e5 commit 77bddeb

File tree

6 files changed

+42
-14
lines changed

6 files changed

+42
-14
lines changed

README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,17 @@ crystalline:
339339

340340
Each of these projects must contain the `shard.yml`, ideally with the entry point as mentioned above. However, even if no entry point is present, `require`s will still be resolved relative to the project directory rather than the root directory.
341341

342+
### Compilation flags
343+
344+
To use specific compilation flags, you can add a `crystalline/flags` key in the `shard.yml` file:
345+
346+
```yml
347+
crystalline:
348+
flags:
349+
- preview_mt
350+
- execution_context
351+
```
352+
342353
## Features
343354

344355
**Disclaimer: `Crystalline` is not as extensive in terms of features as other

shard.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,8 @@ development_dependencies:
2323

2424
crystal: ">= 0.36.1, < 2.0.0"
2525

26+
crystalline:
27+
flags:
28+
- preview_mt
29+
2630
license: MIT

src/crystalline/analysis/analysis.cr

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,24 +18,25 @@ module Crystalline::Analysis
1818
end
1919

2020
# Compile a target *file_uri*.
21-
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)
21+
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, compiler_flags : Array(String) = [] of String)
2222
if file_uri.scheme == "file"
2323
file = File.new file_uri.decoded_path
2424
sources = [
2525
Crystal::Compiler::Source.new(file_uri.decoded_path, file.gets_to_end),
2626
]
2727
file.close
28-
self.compile(server, sources, lib_path: lib_path, file_overrides: file_overrides, ignore_diagnostics: ignore_diagnostics, wants_doc: wants_doc, top_level: top_level)
28+
self.compile(server, sources, lib_path: lib_path, file_overrides: file_overrides, ignore_diagnostics: ignore_diagnostics, wants_doc: wants_doc, top_level: top_level, compiler_flags: compiler_flags)
2929
end
3030
end
3131

3232
# Compile an array of *sources*.
33-
def self.compile(server : LSP::Server, sources : Array(Crystal::Compiler::Source), *, lib_path : String? = nil, file_overrides : Hash(String, String)? = nil, ignore_diagnostics = false, wants_doc = false, fail_fast = false, top_level = false)
33+
def self.compile(server : LSP::Server, sources : Array(Crystal::Compiler::Source), *, lib_path : String? = nil, file_overrides : Hash(String, String)? = nil, ignore_diagnostics = false, wants_doc = false, fail_fast = false, top_level = false, compiler_flags : Array(String) = [] of String)
3434
diagnostics = Diagnostics.new
3535
reply_channel = Channel(Crystal::Compiler::Result | Exception).new
3636

3737
# LSP::Log.info { "sources: #{sources.map(&.filename)}" }
3838
# LSP::Log.info { "lib_path: #{lib_path}" }
39+
LSP::Log.info { "compiler_flags: #{compiler_flags}" }
3940

4041
# Delegate heavy processing to a separate thread.
4142
spawn_dedicated do
@@ -48,6 +49,7 @@ module Crystalline::Analysis
4849
compiler.wants_doc = wants_doc
4950
compiler.stdout = dev_null
5051
compiler.stderr = dev_null
52+
compiler.flags = compiler_flags
5153

5254
if lib_path_override = lib_path
5355
path = Crystal::CrystalPath.default_path_without_lib.split(Process::PATH_DELIMITER)

src/crystalline/main.cr

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,9 @@ module Crystalline
4646

4747
def self.init(*, input : IO = STDIN, output : IO = STDOUT)
4848
EnvironmentConfig.run
49-
# ::Log.setup(:debug, LSP::Log.backend.not_nil!)
49+
{% if flag?(:debug) %}
50+
::Log.setup(:debug, LSP::Log.backend.not_nil!)
51+
{% end %}
5052
server = LSP::Server.new(input, output, SERVER_CAPABILITIES)
5153
Controller.new(server)
5254
rescue ex

src/crystalline/project.cr

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,11 @@ class Crystalline::Project
77
property dependencies : Set(String) = Set(String).new
88
# Determines the project entry point.
99
getter? entry_point : URI? do
10-
path = Path[root_uri.decoded_path, "shard.yml"]
11-
shards_yaml = File.open(path) do |file|
12-
YAML.parse(file)
13-
end
14-
shard_name = shards_yaml["name"].as_s
10+
shard_name = shard_yaml["name"].as_s
1511
# If shard.yml has the `crystalline/main` key, use that.
16-
relative_main = shards_yaml.dig?("crystalline", "main").try &.as_s
12+
relative_main = shard_yaml.dig?("crystalline", "main").try &.as_s
1713
# Else if shard.yml has a `targets/[shard name]/main` key, use that.
18-
relative_main ||= shards_yaml.dig?("targets", shard_name, "main").try &.as_s
14+
relative_main ||= shard_yaml.dig?("targets", shard_name, "main").try &.as_s
1915
if relative_main && File.exists? Path[root_uri.decoded_path, relative_main]
2016
main_path = Path[root_uri.decoded_path, relative_main]
2117
# Add the entry point as a dependency to itself.
@@ -25,6 +21,19 @@ class Crystalline::Project
2521
rescue e
2622
nil
2723
end
24+
# Flags to pass to the underlying compiler (-Dpreview_mt, etc).
25+
getter flags : Array(String) do
26+
(shard_yaml.dig?("crystalline", "flags").try(&.as_a.map(&.as_s)) || [] of String).tap do |flags|
27+
LSP::Log.info { "Flags for project #{root_uri}: #{flags}" }
28+
end
29+
end
30+
31+
private getter shard_yaml : YAML::Any do
32+
path = Path[root_uri.decoded_path, "shard.yml"]
33+
shards_yaml = File.open(path) do |file|
34+
YAML.parse(file)
35+
end
36+
end
2837

2938
def initialize(@root_uri)
3039
end

src/crystalline/workspace.cr

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ class Crystalline::Workspace
9191
return unless target = project.entry_point?
9292

9393
lib_path = project.default_lib_path
94-
Analysis.compile(server, target, lib_path: lib_path, ignore_diagnostics: true, wants_doc: false, top_level: true).try { |result|
94+
Analysis.compile(server, target, lib_path: lib_path, ignore_diagnostics: true, wants_doc: false, top_level: true, compiler_flags: project.flags).try { |result|
9595
project.dependencies = result.program.requires
9696
}
9797
rescue
@@ -114,7 +114,7 @@ class Crystalline::Workspace
114114
text_overrides = nil,
115115
fail_fast = false,
116116
top_level = false,
117-
discard_nil_cached_result = false
117+
discard_nil_cached_result = false,
118118
)
119119
@projects.each do |project|
120120
# If the project has less than 1 dependency, it could mean that the last
@@ -185,7 +185,7 @@ class Crystalline::Workspace
185185
end
186186

187187
lib_path = project.try(&.default_lib_path)
188-
result = Analysis.compile(server, sources || target, lib_path: lib_path, file_overrides: file_overrides, ignore_diagnostics: ignore_diagnostics, wants_doc: wants_doc, top_level: top_level)
188+
result = Analysis.compile(server, sources || target, lib_path: lib_path, file_overrides: file_overrides, ignore_diagnostics: ignore_diagnostics, wants_doc: wants_doc, top_level: top_level, compiler_flags: project.try(&.flags) || [] of String)
189189
# Store the result in the cache, unless a client event invalided the previous cache.
190190
# For instance if a compilation is running, but the user saved the document in the meantime (before completion)
191191
# then we discard the result because it is already outdated.

0 commit comments

Comments
 (0)