[前][次][番号順一覧][スレッド一覧]

ruby-changes:72975

From: schneems <ko1@a...>
Date: Fri, 19 Aug 2022 10:02:39 +0900 (JST)
Subject: [ruby-changes:72975] 490af8dbdb (master): Sync SyntaxSuggest

https://git.ruby-lang.org/ruby.git/commit/?id=490af8dbdb

From 490af8dbdb66263f29d0b4e43752fbb298b94862 Mon Sep 17 00:00:00 2001
From: schneems <richard.schneeman+foo@g...>
Date: Tue, 26 Jul 2022 15:21:09 -0500
Subject: Sync SyntaxSuggest

```
$ tool/sync_default_gems.rb syntax_suggest
```
---
 lib/syntax_suggest.rb                              |   3 +
 lib/syntax_suggest/api.rb                          | 199 ++++++++++++++
 lib/syntax_suggest/around_block_scan.rb            | 224 +++++++++++++++
 lib/syntax_suggest/block_expand.rb                 |  74 +++++
 lib/syntax_suggest/capture_code_context.rb         | 233 ++++++++++++++++
 lib/syntax_suggest/clean_document.rb               | 304 +++++++++++++++++++++
 lib/syntax_suggest/cli.rb                          | 129 +++++++++
 lib/syntax_suggest/code_block.rb                   | 100 +++++++
 lib/syntax_suggest/code_frontier.rb                | 178 ++++++++++++
 lib/syntax_suggest/code_line.rb                    | 239 ++++++++++++++++
 lib/syntax_suggest/code_search.rb                  | 139 ++++++++++
 lib/syntax_suggest/core_ext.rb                     | 101 +++++++
 .../display_code_with_line_numbers.rb              |  70 +++++
 lib/syntax_suggest/display_invalid_blocks.rb       |  84 ++++++
 lib/syntax_suggest/explain_syntax.rb               | 103 +++++++
 lib/syntax_suggest/left_right_lex_count.rb         | 168 ++++++++++++
 lib/syntax_suggest/lex_all.rb                      |  55 ++++
 lib/syntax_suggest/lex_value.rb                    |  70 +++++
 .../parse_blocks_from_indent_line.rb               |  60 ++++
 lib/syntax_suggest/pathname_from_message.rb        |  59 ++++
 lib/syntax_suggest/priority_engulf_queue.rb        |  63 +++++
 lib/syntax_suggest/priority_queue.rb               | 105 +++++++
 lib/syntax_suggest/ripper_errors.rb                |  36 +++
 lib/syntax_suggest/syntax_suggest.gemspec          |  32 +++
 lib/syntax_suggest/unvisited_lines.rb              |  36 +++
 lib/syntax_suggest/version.rb                      |   5 +
 26 files changed, 2869 insertions(+)
 create mode 100644 lib/syntax_suggest.rb
 create mode 100644 lib/syntax_suggest/api.rb
 create mode 100644 lib/syntax_suggest/around_block_scan.rb
 create mode 100644 lib/syntax_suggest/block_expand.rb
 create mode 100644 lib/syntax_suggest/capture_code_context.rb
 create mode 100644 lib/syntax_suggest/clean_document.rb
 create mode 100644 lib/syntax_suggest/cli.rb
 create mode 100644 lib/syntax_suggest/code_block.rb
 create mode 100644 lib/syntax_suggest/code_frontier.rb
 create mode 100644 lib/syntax_suggest/code_line.rb
 create mode 100644 lib/syntax_suggest/code_search.rb
 create mode 100644 lib/syntax_suggest/core_ext.rb
 create mode 100644 lib/syntax_suggest/display_code_with_line_numbers.rb
 create mode 100644 lib/syntax_suggest/display_invalid_blocks.rb
 create mode 100644 lib/syntax_suggest/explain_syntax.rb
 create mode 100644 lib/syntax_suggest/left_right_lex_count.rb
 create mode 100644 lib/syntax_suggest/lex_all.rb
 create mode 100644 lib/syntax_suggest/lex_value.rb
 create mode 100644 lib/syntax_suggest/parse_blocks_from_indent_line.rb
 create mode 100644 lib/syntax_suggest/pathname_from_message.rb
 create mode 100644 lib/syntax_suggest/priority_engulf_queue.rb
 create mode 100644 lib/syntax_suggest/priority_queue.rb
 create mode 100644 lib/syntax_suggest/ripper_errors.rb
 create mode 100644 lib/syntax_suggest/syntax_suggest.gemspec
 create mode 100644 lib/syntax_suggest/unvisited_lines.rb
 create mode 100644 lib/syntax_suggest/version.rb

diff --git a/lib/syntax_suggest.rb b/lib/syntax_suggest.rb
new file mode 100644
index 0000000000..1a45dfa676
--- /dev/null
+++ b/lib/syntax_suggest.rb
@@ -0,0 +1,3 @@ https://github.com/ruby/ruby/blob/trunk/lib/syntax_suggest.rb#L1
+# frozen_string_literal: true
+
+require_relative "syntax_suggest/core_ext"
diff --git a/lib/syntax_suggest/api.rb b/lib/syntax_suggest/api.rb
new file mode 100644
index 0000000000..5b725e13d7
--- /dev/null
+++ b/lib/syntax_suggest/api.rb
@@ -0,0 +1,199 @@ https://github.com/ruby/ruby/blob/trunk/lib/syntax_suggest/api.rb#L1
+# frozen_string_literal: true
+
+require_relative "version"
+
+require "tmpdir"
+require "stringio"
+require "pathname"
+require "ripper"
+require "timeout"
+
+module SyntaxSuggest
+  # Used to indicate a default value that cannot
+  # be confused with another input.
+  DEFAULT_VALUE = Object.new.freeze
+
+  class Error < StandardError; end
+  TIMEOUT_DEFAULT = ENV.fetch("SYNTAX_SUGGEST_TIMEOUT", 1).to_i
+
+  # SyntaxSuggest.handle_error [Public]
+  #
+  # Takes a `SyntaxError` exception, uses the
+  # error message to locate the file. Then the file
+  # will be analyzed to find the location of the syntax
+  # error and emit that location to stderr.
+  #
+  # Example:
+  #
+  #   begin
+  #     require 'bad_file'
+  #   rescue => e
+  #     SyntaxSuggest.handle_error(e)
+  #   end
+  #
+  # By default it will re-raise the exception unless
+  # `re_raise: false`. The message output location
+  # can be configured using the `io: $stderr` input.
+  #
+  # If a valid filename cannot be determined, the original
+  # exception will be re-raised (even with
+  # `re_raise: false`).
+  def self.handle_error(e, re_raise: true, io: $stderr)
+    unless e.is_a?(SyntaxError)
+      io.puts("SyntaxSuggest: Must pass a SyntaxError, got: #{e.class}")
+      raise e
+    end
+
+    file = PathnameFromMessage.new(e.message, io: io).call.name
+    raise e unless file
+
+    io.sync = true
+
+    call(
+      io: io,
+      source: file.read,
+      filename: file
+    )
+
+    raise e if re_raise
+  end
+
+  # SyntaxSuggest.call [Private]
+  #
+  # Main private interface
+  def self.call(source:, filename: DEFAULT_VALUE, terminal: DEFAULT_VALUE, record_dir: DEFAULT_VALUE, timeout: TIMEOUT_DEFAULT, io: $stderr)
+    search = nil
+    filename = nil if filename == DEFAULT_VALUE
+    Timeout.timeout(timeout) do
+      record_dir ||= ENV["DEBUG"] ? "tmp" : nil
+      search = CodeSearch.new(source, record_dir: record_dir).call
+    end
+
+    blocks = search.invalid_blocks
+    DisplayInvalidBlocks.new(
+      io: io,
+      blocks: blocks,
+      filename: filename,
+      terminal: terminal,
+      code_lines: search.code_lines
+    ).call
+  rescue Timeout::Error => e
+    io.puts "Search timed out SYNTAX_SUGGEST_TIMEOUT=#{timeout}, run with DEBUG=1 for more info"
+    io.puts e.backtrace.first(3).join($/)
+  end
+
+  # SyntaxSuggest.record_dir [Private]
+  #
+  # Used to generate a unique directory to record
+  # search steps for debugging
+  def self.record_dir(dir)
+    time = Time.now.strftime("%Y-%m-%d-%H-%M-%s-%N")
+    dir = Pathname(dir)
+    dir.join(time).tap { |path|
+      path.mkpath
+      FileUtils.ln_sf(time, dir.join("last"))
+    }
+  end
+
+  # SyntaxSuggest.valid_without? [Private]
+  #
+  # This will tell you if the `code_lines` would be valid
+  # if you removed the `without_lines`. In short it's a
+  # way to detect if we've found the lines with syntax errors
+  # in our document yet.
+  #
+  #   code_lines = [
+  #     CodeLine.new(line: "def foo\n",   index: 0)
+  #     CodeLine.new(line: "  def bar\n", index: 1)
+  #     CodeLine.new(line: "end\n",       index: 2)
+  #   ]
+  #
+  #   SyntaxSuggest.valid_without?(
+  #     without_lines: code_lines[1],
+  #     code_lines: code_lines
+  #   )                                    # => true
+  #
+  #   SyntaxSuggest.valid?(code_lines) # => false
+  def self.valid_without?(without_lines:, code_lines:)
+    lines = code_lines - Array(without_lines).flatten
+
+    if lines.empty?
+      true
+    else
+      valid?(lines)
+    end
+  end
+
+  # SyntaxSuggest.invalid? [Private]
+  #
+  # Opposite of `SyntaxSuggest.valid?`
+  def self.invalid?(source)
+    source = source.join if source.is_a?(Array)
+    source = source.to_s
+
+    Ripper.new(source).tap(&:parse).error?
+  end
+
+  # SyntaxSuggest.valid? [Private]
+  #
+  # Returns truthy if a given input source is valid syntax
+  #
+  #   SyntaxSuggest.valid?(<<~EOM) # => true
+  #     def foo
+  #     end
+  #   EOM
+  #
+  #   SyntaxSuggest.valid?(<<~EOM) # => false
+  #     def foo
+  #       def bar # Syntax error here
+  #     end
+  #   EOM
+  #
+  # You can also pass in an array of lines and they'll be
+  # joined before evaluating
+  #
+  #   SyntaxSuggest.valid?(
+  #     [
+  #       "def foo\n",
+  #       "end\n"
+  #     ]
+  #   ) # => true
+  #
+  #   SyntaxSuggest.valid?(
+  #     [
+  #       "def foo\n",
+  #       "  def bar\n", # Syntax error here
+  #       "end\n"
+  #     ]
+  #   ) # => false
+  #
+  # As an FYI the CodeLine class instances respond to `to_s`
+  # so passing a CodeLine in as an object or as an array
+  # will convert it to it's code representation.
+  def self.valid?(source)
+    !invalid?(source)
+  end
+end
+
+# Integration
+require_relative "cli"
+
+# Core logic
+require_relative "code_search"
+require_relative "code_frontier"
+require_relative "explain_syntax"
+require_relative "clean_document"
+
+# Helpers
+require_relative "lex_all"
+require_relative "code_line"
+require_relative "code_block"
+require_relative "block_expand"
+require_relative "ripper_errors"
+require_relative "priority_queue"
+require_relative "unvisited_lines"
+require_relative "around_block_scan"
+require_relative "priority_engulf_queue"
+require_relative "pathname_from_message"
+require_relative "display_invalid_blocks"
+require_relative "parse_blocks_from_indent_line"
diff --git a/lib/syntax_suggest/around_block_scan.rb b/lib/syntax_suggest/around_block_scan.rb
new file mode 100644
index 0000000000..2a57d1b19e
--- /dev/null
+++ b/lib/syntax_suggest/around_block_scan.rb
@@ -0,0 +1,224 @@ https://github.com/ruby/ruby/blob/trunk/lib/syntax_suggest/around_block_scan.rb#L1
+# frozen_string_literal: true
+
+module SyntaxSuggest
+  # This class is useful for exploring contents before and after
+  # a block
+  #
+  # It searches above and below the passed in block to match for
+  # whatever criteria you give it:
+  #
+  # Examp (... truncated)

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]