mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Sync SyntaxSuggest
``` $ tool/sync_default_gems.rb syntax_suggest ```
This commit is contained in:
parent
a50df1ab0e
commit
490af8dbdb
Notes:
git
2022-08-19 10:02:47 +09:00
26 changed files with 2869 additions and 0 deletions
100
lib/syntax_suggest/code_block.rb
Normal file
100
lib/syntax_suggest/code_block.rb
Normal file
|
@ -0,0 +1,100 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module SyntaxSuggest
|
||||
# Multiple lines form a singular CodeBlock
|
||||
#
|
||||
# Source code is made of multiple CodeBlocks.
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# code_block.to_s # =>
|
||||
# # def foo
|
||||
# # puts "foo"
|
||||
# # end
|
||||
#
|
||||
# code_block.valid? # => true
|
||||
# code_block.in_valid? # => false
|
||||
#
|
||||
#
|
||||
class CodeBlock
|
||||
UNSET = Object.new.freeze
|
||||
attr_reader :lines, :starts_at, :ends_at
|
||||
|
||||
def initialize(lines: [])
|
||||
@lines = Array(lines)
|
||||
@valid = UNSET
|
||||
@deleted = false
|
||||
@starts_at = @lines.first.number
|
||||
@ends_at = @lines.last.number
|
||||
end
|
||||
|
||||
def delete
|
||||
@deleted = true
|
||||
end
|
||||
|
||||
def deleted?
|
||||
@deleted
|
||||
end
|
||||
|
||||
def visible_lines
|
||||
@lines.select(&:visible?).select(&:not_empty?)
|
||||
end
|
||||
|
||||
def mark_invisible
|
||||
@lines.map(&:mark_invisible)
|
||||
end
|
||||
|
||||
def is_end?
|
||||
to_s.strip == "end"
|
||||
end
|
||||
|
||||
def hidden?
|
||||
@lines.all?(&:hidden?)
|
||||
end
|
||||
|
||||
# This is used for frontier ordering, we are searching from
|
||||
# the largest indentation to the smallest. This allows us to
|
||||
# populate an array with multiple code blocks then call `sort!`
|
||||
# on it without having to specify the sorting criteria
|
||||
def <=>(other)
|
||||
out = current_indent <=> other.current_indent
|
||||
return out if out != 0
|
||||
|
||||
# Stable sort
|
||||
starts_at <=> other.starts_at
|
||||
end
|
||||
|
||||
def current_indent
|
||||
@current_indent ||= lines.select(&:not_empty?).map(&:indent).min || 0
|
||||
end
|
||||
|
||||
def invalid?
|
||||
!valid?
|
||||
end
|
||||
|
||||
def valid?
|
||||
if @valid == UNSET
|
||||
# Performance optimization
|
||||
#
|
||||
# If all the lines were previously hidden
|
||||
# and we expand to capture additional empty
|
||||
# lines then the result cannot be invalid
|
||||
#
|
||||
# That means there's no reason to re-check all
|
||||
# lines with ripper (which is expensive).
|
||||
# Benchmark in commit message
|
||||
@valid = if lines.all? { |l| l.hidden? || l.empty? }
|
||||
true
|
||||
else
|
||||
SyntaxSuggest.valid?(lines.map(&:original).join)
|
||||
end
|
||||
else
|
||||
@valid
|
||||
end
|
||||
end
|
||||
|
||||
def to_s
|
||||
@lines.join
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Add table
Add a link
Reference in a new issue