Skip to content
Open
Show file tree
Hide file tree
Changes from 11 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
32 changes: 0 additions & 32 deletions .ameba.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,49 +2,17 @@ Metrics/CyclomaticComplexity:
Enabled: false

Style/ParenthesesAroundCondition:
Description: Disallows redundant parentheses around control expressions
ExcludeTernary: false
AllowSafeAssignment: true
Enabled: true
Severity: Convention

Documentation/DocumentationAdmonition:
Enabled: false
Severity: Warning

Lint/NotNil:
Description: Identifies usage of `not_nil!` calls
Excluded:
- src/crystalline/analysis/analysis.cr
- src/crystalline/result_cache.cr
- src/crystalline/workspace.cr
Enabled: true
Severity: Warning

Naming/BlockParameterName:
Enabled: false
Severity: Convention

Lint/RedundantStringCoercion:
Description: Disallows redundant string conversions in interpolation
Enabled: true
Severity: Warning

Lint/ShadowingOuterLocalVar:
Description:
Disallows the usage of the same name as outer local variables for block
or proc arguments
Excluded:
- src/crystalline/ext/compiler.cr
Enabled: true
Severity: Warning

Naming/QueryBoolMethods:
Description: Reports boolean properties without the `?` suffix
Enabled: false
Severity: Convention

Style/WhileTrue:
Description: Disallows while statements with a true literal as condition
Enabled: false
Severity: Convention
37 changes: 6 additions & 31 deletions .github/workflows/crystal-ameba.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,47 +2,22 @@ name: Crystal Ameba

on:
push:
branches:
- master
paths:
- "**/*.cr"
pull_request:
branches:
- master
paths:
- "**/*.cr"

permissions:
contents: read

jobs:
lint:
runs-on: ubuntu-latest
strategy:
matrix:
ameba-version: [v1.6.4]

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Crystal
uses: crystal-lang/install-crystal@v1

- name: Cache Ameba binary
id: cache-ameba
uses: actions/cache@v3
with:
path: bin/ameba
key: ${{ runner.os }}-ameba-${{ matrix.ameba-version }}

- name: Build Ameba
if: steps.cache-ameba.outputs.cache-hit != 'true'
run: |
git clone --branch ${{ matrix.ameba-version }} --single-branch https://github.com/crystal-ameba/ameba.git
cd ameba
make bin/ameba CRFLAGS='-Dpreview_mt --no-debug'
mkdir -p ../bin
mv bin/ameba ../bin/ameba
cd ..
rm -rf ameba
- name: Download source
uses: actions/checkout@v6

- name: Run Ameba Linter
run: bin/ameba -c .ameba.yml
uses: crystal-ameba/github-action@master
2 changes: 1 addition & 1 deletion spec/crystalline_spec.cr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
require "spec"

it "works" do
true.should eq(true)
true.should be_true
end
32 changes: 16 additions & 16 deletions src/crystalline/analysis/analysis.cr
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ module Crystalline::Analysis
Crystal::Compiler::Source.new(file_uri.decoded_path, file.gets_to_end),
]
file.close
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)
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)
end
end

Expand Down Expand Up @@ -119,18 +119,18 @@ module Crystalline::Analysis
# Return the possible definition for the node at the given *location*.
def self.definitions_at_cursor(result : Crystal::Compiler::Result, location : Crystal::Location) : Definitions?
nodes, context = CursorVisitor.new(location).process(result)
nodes.last?.try { |node|
nodes.last?.try do |node|
LSP::Log.debug { "Class of node at cursor: #{node.class} " }
locations = begin
if node.is_a? Crystal::Call
if (defs = node.target_defs)
defs.compact_map { |d|
start_location = d.location.try { |loc| loc.expanded_location || loc }.not_nil!
end_location = d.end_location.try { |loc| loc.expanded_location || loc }.not_nil!
defs.compact_map do |d|
start_location = d.location.try { |loc| loc.expanded_location || loc }.not_nil! # ameba:disable Lint/NotNil!
end_location = d.end_location.try { |loc| loc.expanded_location || loc }.not_nil! # ameba:disable Lint/NotNil!
{start_location, end_location}
}
end
elsif (expanded_macro = node.expanded_macro)
start_location = expanded_macro.location.try { |loc| loc.expanded_location || loc }.not_nil!
start_location = expanded_macro.location.try { |loc| loc.expanded_location || loc }.not_nil! # ameba:disable Lint/NotNil!
end_location = expanded_macro.end_location.try { |loc| loc.expanded_location || loc } || start_location
[{start_location, end_location}]
end
Expand All @@ -139,14 +139,14 @@ module Crystalline::Analysis
filename = node.string
relative_to = location.try &.original_filename
filenames = result.program.find_in_path(filename, relative_to)
filenames.try &.map { |path|
filenames.try &.map do |path|
location = Crystal::Location.new(
path,
line_number: 1,
column_number: 1
)
{location, location}
}
end
elsif node.is_a? Crystal::Path
Utils.locations_from_path(node, nodes)
elsif node.is_a? Crystal::Union
Expand All @@ -172,15 +172,15 @@ module Crystalline::Analysis
end

Definitions.new(node: node, locations: locations)
}
end
end

def self.all_defs(type, *, accumulator = [] of {String, Crystal::Def, Crystal::Type, Int32}, nesting = 0)
if type.is_a? Crystal::UnionType
# TODO: intersection instead of union
type.union_types.each { |t|
type.union_types.each do |t|
all_defs(t, accumulator: accumulator, nesting: nesting)
}
end
return accumulator.uniq &.[1]
end

Expand All @@ -200,17 +200,17 @@ module Crystalline::Analysis
if type.responds_to? :instance_type
extends_self = type.instance_type == parent
end
self.all_defs(parent, accumulator: accumulator, nesting: extends_self ? nesting : nesting + 1)
all_defs(parent, accumulator: accumulator, nesting: extends_self ? nesting : nesting + 1)
end

accumulator
end

def self.all_macros(type, *, accumulator = [] of {String, Crystal::Macro, Crystal::Type, Int32}, nesting = 0)
if type.is_a? Crystal::UnionType
type.union_types.each { |t|
type.union_types.each do |t|
all_macros(t, accumulator: accumulator, nesting: nesting)
}
end
return accumulator.uniq &.[0]
end

Expand All @@ -221,7 +221,7 @@ module Crystalline::Analysis
end

type.parents.try &.each do |parent|
self.all_macros(parent, accumulator: accumulator, nesting: nesting + 1)
all_macros(parent, accumulator: accumulator, nesting: nesting + 1)
end

accumulator
Expand Down
4 changes: 2 additions & 2 deletions src/crystalline/analysis/cursor_visitor.cr
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ module Crystalline::Analysis
private def nearest_end_location(node)
return node.end_location if node.end_location

@nodes.reverse.find { |elt|
@nodes.reverse.find do |elt|
elt.responds_to?(:end_location) && elt.end_location
}.try &.end_location
end.try &.end_location
end

def visit_any(node : Crystal::Def | Crystal::Assign | Crystal::Block)
Expand Down
4 changes: 2 additions & 2 deletions src/crystalline/analysis/submodule_visitor.cr
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ module Crystalline::Analysis

def process_result(result : Crystal::Compiler::Result)
result.node.accept(self)
result.program.file_modules.each_value { |file_module|
result.program.file_modules.each_value do |file_module|
process(file_module)
}
end
@submodules
end

Expand Down
2 changes: 0 additions & 2 deletions src/crystalline/broken_source_fixer.cr
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,6 @@ class Crystalline::BrokenSourceFixer
"rescue"
elsif line.matches?(/\s*ensure\s*$/)
"ensure"
else
nil
end
end

Expand Down
48 changes: 23 additions & 25 deletions src/crystalline/controller.cr
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ class Crystalline::Controller
@pending_requests << message.id
case message
when LSP::DocumentFormattingRequest
@documents_lock.synchronize {
workspace.format_document(message.params).try { |(formatted_document, document)|
@documents_lock.synchronize do
workspace.format_document(message.params).try do |(formatted_document, document)|
range = LSP::Range.new(
start: LSP::Position.new(line: 0, character: 0),
end: LSP::Position.new(line: document.lines_nb + 1, character: 0),
Expand All @@ -46,34 +46,34 @@ class Crystalline::Controller
new_text: formatted_document,
),
]
}
}
end
end
when LSP::DocumentRangeFormattingRequest
@documents_lock.synchronize {
workspace.format_document(message.params).try { |(formatted_document, document)|
@documents_lock.synchronize do
workspace.format_document(message.params).try do |(formatted_document, document)|
[
LSP::TextEdit.new(
range: message.params.range,
new_text: formatted_document,
),
]
}
}
end
end
when LSP::HoverRequest
@compiler_lock.synchronize do
return nil unless @pending_requests.includes? message.id
return unless @pending_requests.includes? message.id
file_uri = URI.parse message.params.text_document.uri
workspace.hover(@server, file_uri, message.params.position)
end
when LSP::DefinitionRequest
@compiler_lock.synchronize do
return nil unless @pending_requests.includes? message.id
return unless @pending_requests.includes? message.id
file_uri = URI.parse message.params.text_document.uri
workspace.definitions(@server, file_uri, message.params.position)
end
when LSP::CompletionRequest
@compiler_lock.synchronize do
return nil unless @pending_requests.includes? message.id
return unless @pending_requests.includes? message.id
file_uri = URI.parse message.params.text_document.uri
workspace.completion(@server, file_uri, message.params.position, message.params.context.try &.trigger_character)
end
Expand All @@ -85,13 +85,11 @@ class Crystalline::Controller
if @server.client_capabilities.text_document.try &.document_symbol.try &.hierarchical_document_symbol_support
document_symbols
else
document_symbols.try &.reduce([] of LSP::SymbolInformation) { |acc, document_symbol|
document_symbols.try &.reduce([] of LSP::SymbolInformation) do |acc, document_symbol|
acc.concat(document_symbol.to_symbol_information_array(message.params.text_document.uri))
}
end
end
end
else
nil
end
rescue e : Crystal::TypeException
LSP::Log.warn(exception: e) { e.to_s }
Expand All @@ -106,29 +104,29 @@ class Crystalline::Controller
def on_notification(message : LSP::NotificationMessage) : Nil
case message
when LSP::DidOpenNotification
@documents_lock.synchronize {
@documents_lock.synchronize do
workspace.open_document(message.params)
}
end
when LSP::DidChangeNotification
@documents_lock.synchronize {
@documents_lock.synchronize do
workspace.update_document(@server, message.params)
}
end
when LSP::DidCloseNotification
@documents_lock.synchronize {
@documents_lock.synchronize do
workspace.close_document(@server, message.params)
}
end
when LSP::DidSaveNotification
@documents_lock.synchronize {
@documents_lock.synchronize do
workspace.save_document(@server, message.params)
}
@compiler_lock.synchronize {
end
@compiler_lock.synchronize do
file_uri = message.params.text_document.uri
workspace.compile(
@server,
URI.parse(file_uri),
discard_nil_cached_result: true,
)
}
end
when LSP::CancelNotification
@pending_requests.delete message.params.id
end
Expand Down
12 changes: 6 additions & 6 deletions src/crystalline/diagnostics.cr
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class Crystalline::Diagnostics

def append(diagnostic : LSP::Diagnostic)
key = "file://#{diagnostic.source}"
self.init_value(key)
init_value(key)
@diagnostics[key] << diagnostic
end

Expand All @@ -33,7 +33,7 @@ class Crystalline::Diagnostics

related_information = [] of LSP::DiagnosticRelatedInformation

error_stack.each_with_index { |err, i|
error_stack.each_with_index do |err, i|
bottom_error = i == error_stack.size - 1
if err.filename.is_a? Crystal::VirtualFile && (expanded_source = err.filename.as(Crystal::VirtualFile).expanded_location)
line = expanded_source.line_number || 1
Expand All @@ -44,7 +44,7 @@ class Crystalline::Diagnostics
end

if bottom_error
self.append(LSP::Diagnostic.new(
append(LSP::Diagnostic.new(
line: line,
column: column,
size: err.size || 0,
Expand All @@ -61,14 +61,14 @@ class Crystalline::Diagnostics
filename: err.true_filename,
)
end
}
end
end

def publish(server : LSP::Server)
@diagnostics.each { |key, value|
@diagnostics.each do |key, value|
server.try &.send(LSP::PublishDiagnosticsNotification.new(
params: LSP::PublishDiagnosticsParams.new(uri: key, diagnostics: value),
))
}
end
end
end
Loading
Loading