diff --git a/lib/prism/node_ext.rb b/lib/prism/node_ext.rb index 688e60a15957a6..36a43b6327e4c9 100644 --- a/lib/prism/node_ext.rb +++ b/lib/prism/node_ext.rb @@ -169,14 +169,17 @@ def full_name class ParametersNode < Node # Mirrors the Method#parameters method. def signature - names = [] #: Array[[:req | :opt | :rest | :keyreq | :key | :keyrest | :block, Symbol] | [:rest | :keyrest | :nokey]] + names = [] #: Array[[:req | :opt | :rest | :keyreq | :key | :keyrest | :block, Symbol] | [:req | :rest | :keyrest | :nokey]] requireds.each do |param| names << (param.is_a?(MultiTargetNode) ? [:req] : [:req, param.name]) end optionals.each { |param| names << [:opt, param.name] } - names << [:rest, rest.name || :*] if rest + + if rest && rest.is_a?(RestParameterNode) + names << [:rest, rest.name || :*] + end posts.each do |param| names << (param.is_a?(MultiTargetNode) ? [:req] : [:req, param.name]) diff --git a/lib/prism/pack.rb b/lib/prism/pack.rb index 0168e5e7496ada..31c768612328bd 100644 --- a/lib/prism/pack.rb +++ b/lib/prism/pack.rb @@ -216,6 +216,7 @@ def describe else source = directive.source end + # @type var source_width: Integer " #{source.ljust(source_width)} #{directive.describe}" end diff --git a/lib/prism/parse_result.rb b/lib/prism/parse_result.rb index 7cb982e69981f6..1d9e7008822faa 100644 --- a/lib/prism/parse_result.rb +++ b/lib/prism/parse_result.rb @@ -30,7 +30,7 @@ def encoding # Perform a byteslice on the source code using the given byte offset and # byte length. def slice(byte_offset, length) - source.byteslice(byte_offset, length) + source.byteslice(byte_offset, length) or raise end # Binary search through the offsets to find the line number for the given @@ -52,7 +52,7 @@ def column(byte_offset) # Return the character offset for the given byte offset. def character_offset(byte_offset) - source.byteslice(0, byte_offset).length + (source.byteslice(0, byte_offset) or raise).length end # Return the column number in characters for the given byte offset. @@ -157,12 +157,8 @@ def comments end # Create a new location object with the given options. - def copy(**options) - Location.new( - options.fetch(:source) { source }, - options.fetch(:start_offset) { start_offset }, - options.fetch(:length) { length } - ) + def copy(source: self.source, start_offset: self.start_offset, length: self.length) + Location.new(source, start_offset, length) end # Returns a string representation of this location. diff --git a/lib/prism/parse_result/comments.rb b/lib/prism/parse_result/comments.rb index 0f1522deade01c..314261ea470721 100644 --- a/lib/prism/parse_result/comments.rb +++ b/lib/prism/parse_result/comments.rb @@ -150,6 +150,7 @@ def nearest_targets(node, comment) target_end = target.end_offset if target.encloses?(comment) + # @type var target: NodeTarget # The comment is completely contained by this target. Abandon the # binary search at this level. return nearest_targets(target.node, comment) diff --git a/lib/prism/parse_result/newlines.rb b/lib/prism/parse_result/newlines.rb index ca05f5b7026767..96c97646ff141a 100644 --- a/lib/prism/parse_result/newlines.rb +++ b/lib/prism/parse_result/newlines.rb @@ -58,7 +58,11 @@ def visit_statements_node(node) # Walk the tree and mark nodes that are on a new line. def mark_newlines! - value.accept(Newlines.new(Array.new(1 + source.offsets.size, false))) + if ProgramNode === value + value.accept(Newlines.new(Array.new(1 + source.offsets.size, false))) + else + raise "ParseResult does not contain ProgramNode value" + end end end end diff --git a/lib/prism/pattern.rb b/lib/prism/pattern.rb index e1643671ec1131..8e0d235796cd2b 100644 --- a/lib/prism/pattern.rb +++ b/lib/prism/pattern.rb @@ -69,7 +69,14 @@ def initialize(query) # nodes. def compile result = Prism.parse("case nil\nin #{query}\nend") - compile_node(result.value.statements.body.last.conditions.last.pattern) + + case_match_node = result.value.statements.body.last + raise CompilationError, case_match_node.inspect unless case_match_node.is_a?(CaseMatchNode) + + in_node = case_match_node.conditions.last + raise CompilationError, in_node.inspect unless in_node.is_a?(InNode) + + compile_node(in_node.pattern) end # Scan the given node and all of its children for nodes that match the @@ -77,13 +84,14 @@ def compile # matches the pattern. If no block is given, an enumerator will be returned # that will yield each node that matches the pattern. def scan(root) - return to_enum(__method__, root) unless block_given? + return to_enum(__method__ || raise, root) unless block_given? @compiled ||= compile + compiled = @compiled #: Proc queue = [root] while (node = queue.shift) - yield node if @compiled.call(node) + yield node if compiled.call(node) queue.concat(node.compact_child_nodes) end end @@ -174,7 +182,13 @@ def compile_hash_pattern_node(node) preprocessed = node.elements.to_h do |element| - [element.key.unescaped.to_sym, compile_node(element.value)] + key = element.key + if key.respond_to?(:unescaped) + # @type var key: SymbolNode + [key.unescaped.to_sym, compile_node(element.value)] + else + raise CompilationError, element.inspect + end end compiled_keywords = ->(other) do diff --git a/lib/prism/prism.gemspec b/lib/prism/prism.gemspec index 8e642192a5a07d..16ae553e323501 100644 --- a/lib/prism/prism.gemspec +++ b/lib/prism/prism.gemspec @@ -125,19 +125,14 @@ Gem::Specification.new do |spec| "sig/manifest.yaml", "sig/prism.rbs", "sig/prism/compiler.rbs", - "sig/prism/debug.rbs", - "sig/prism/desugar_compiler.rbs", "sig/prism/dispatcher.rbs", "sig/prism/dot_visitor.rbs", "sig/prism/dsl.rbs", - "sig/prism/lex_compat.rbs", "sig/prism/mutation_compiler.rbs", - "sig/prism/node_ext.rbs", - "sig/prism/node_inspector.rbs", "sig/prism/node.rbs", + "sig/prism/node_ext.rbs", "sig/prism/pack.rbs", - "sig/prism/parse_result/comments.rbs", - "sig/prism/parse_result/newlines.rbs", + "sig/prism/parse_result.rbs", "sig/prism/pattern.rbs", "sig/prism/ripper_compat.rbs", "sig/prism/serialize.rbs", diff --git a/prism/config.yml b/prism/config.yml index 9a959c9cb88828..a89052d7699992 100644 --- a/prism/config.yml +++ b/prism/config.yml @@ -692,7 +692,6 @@ nodes: type: constant[] - name: parameters type: node? - kind: BlockParametersNode - name: body type: node? - name: opening_loc @@ -1583,8 +1582,12 @@ nodes: type: node? - name: elements type: node[] + kind: AssocNode - name: rest type: node? + kind: + - AssocSplatNode + - NoKeywordsParameterNode - name: opening_loc type: location? - name: closing_loc diff --git a/prism/templates/lib/prism/dot_visitor.rb.erb b/prism/templates/lib/prism/dot_visitor.rb.erb index 56f116b8d3944e..5a9b4954442884 100644 --- a/prism/templates/lib/prism/dot_visitor.rb.erb +++ b/prism/templates/lib/prism/dot_visitor.rb.erb @@ -17,7 +17,7 @@ module Prism if port "