Skip to content

Commit

Permalink
[ruby/prism] Split private types
Browse files Browse the repository at this point in the history
  • Loading branch information
nixme authored and matzbot committed Feb 24, 2024
1 parent e03e9c3 commit 7556fd9
Show file tree
Hide file tree
Showing 11 changed files with 65 additions and 38 deletions.
7 changes: 5 additions & 2 deletions lib/prism/node_ext.rb
Expand Up @@ -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])
Expand Down
1 change: 1 addition & 0 deletions lib/prism/pack.rb
Expand Up @@ -216,6 +216,7 @@ def describe
else
source = directive.source
end
# @type var source_width: Integer
" #{source.ljust(source_width)} #{directive.describe}"
end

Expand Down
12 changes: 4 additions & 8 deletions lib/prism/parse_result.rb
Expand Up @@ -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
Expand All @@ -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.
Expand Down Expand Up @@ -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.
Expand Down
1 change: 1 addition & 0 deletions lib/prism/parse_result/comments.rb
Expand Up @@ -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)
Expand Down
6 changes: 5 additions & 1 deletion lib/prism/parse_result/newlines.rb
Expand Up @@ -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
22 changes: 18 additions & 4 deletions lib/prism/pattern.rb
Expand Up @@ -69,21 +69,29 @@ 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
# pattern. If a block is given, it will be called with each node that
# 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
Expand Down Expand Up @@ -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
Expand Down
9 changes: 2 additions & 7 deletions lib/prism/prism.gemspec
Expand Up @@ -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",
Expand Down
5 changes: 4 additions & 1 deletion prism/config.yml
Expand Up @@ -692,7 +692,6 @@ nodes:
type: constant[]
- name: parameters
type: node?
kind: BlockParametersNode
- name: body
type: node?
- name: opening_loc
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion prism/templates/lib/prism/dot_visitor.rb.erb
Expand Up @@ -17,7 +17,7 @@ module Prism
if port
"<tr><td align=\"left\" colspan=\"2\" port=\"#{name}\">#{name}</td></tr>"
else
"<tr><td align=\"left\">#{name}</td><td>#{CGI.escapeHTML(value)}</td></tr>"
"<tr><td align=\"left\">#{name}</td><td>#{CGI.escapeHTML(value || raise)}</td></tr>"
end
end
end
Expand Down
11 changes: 3 additions & 8 deletions prism/templates/lib/prism/node.rb.erb
Expand Up @@ -182,14 +182,9 @@ module Prism
}.compact.join(", ") %>] #: Array[Prism::node | Location]
end

# def copy: (**params) -> <%= node.name %>
def copy(**params)
<%= node.name %>.new(
source,
<%- (node.fields.map(&:name) + ["location"]).map do |name| -%>
params.fetch(:<%= name %>) { <%= name %> },
<%- end -%>
)
# def copy: (<%= (node.fields.map { |field| "?#{field.name}: #{field.rbs_class}" } + ["?location: Location"]).join(", ") %>) -> <%= node.name %>
def copy(<%= (node.fields.map(&:name) + ["location"]).map { |field| "#{field}: self.#{field}" }.join(", ") %>)
<%= node.name %>.new(<%= ["source", *node.fields.map(&:name), "location"].join(", ") %>)
end

# def deconstruct: () -> Array[nil | Node]
Expand Down
27 changes: 21 additions & 6 deletions prism/templates/template.rb
Expand Up @@ -99,11 +99,11 @@ def java_cast
end

def specific_kind
@options[:kind] unless @options[:kind].is_a?(Array)
options[:kind] unless options[:kind].is_a?(Array)
end

def union_kind
options[:kind] if @options[:kind].is_a?(Array)
options[:kind] if options[:kind].is_a?(Array)
end
end

Expand Down Expand Up @@ -132,7 +132,7 @@ def rbs_class
if specific_kind
"#{specific_kind}?"
elsif union_kind
[union_kind, "nil"].join(" | ")
[*union_kind, "nil"].join(" | ")
else
"Prism::node?"
end
Expand All @@ -147,7 +147,13 @@ def rbi_class
# references and store them directly on the struct.
class NodeListField < Field
def rbs_class
"Array[Prism::node]"
if specific_kind
"Array[#{specific_kind}]"
elsif union_kind
"Array[#{union_kind.join(" | ")}]"
else
"Array[Prism::node]"
end
end

def rbi_class
Expand All @@ -157,6 +163,15 @@ def rbi_class
def java_type
"Node[]"
end

# TODO: unduplicate with NodeKindField
def specific_kind
options[:kind] unless options[:kind].is_a?(Array)
end

def union_kind
options[:kind] if options[:kind].is_a?(Array)
end
end

# This represents a field on a node that is the ID of a string interned
Expand Down Expand Up @@ -569,12 +584,12 @@ def locals
"src/token_type.c",
"rbi/prism.rbi",
"sig/prism.rbs",
"sig/prism/dot_visitor.rbs",
"sig/prism/dsl.rbs",
"sig/prism/mutation_compiler.rbs",
"sig/prism/node.rbs",
"sig/prism/ripper_compat.rbs",
"sig/prism/visitor.rbs",
"sig/prism/_private/dot_visitor.rbs",
"sig/prism/_private/ripper_compat.rbs",
]
end

Expand Down

0 comments on commit 7556fd9

Please sign in to comment.