summaryrefslogtreecommitdiff
path: root/lib/prism/node_ext.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/prism/node_ext.rb')
-rw-r--r--lib/prism/node_ext.rb348
1 files changed, 114 insertions, 234 deletions
diff --git a/lib/prism/node_ext.rb b/lib/prism/node_ext.rb
index b007a051ea..8a6624e76d 100644
--- a/lib/prism/node_ext.rb
+++ b/lib/prism/node_ext.rb
@@ -1,12 +1,17 @@
# frozen_string_literal: true
+# :markup: markdown
+#--
+# rbs_inline: enabled
+#--
# Here we are reopening the prism module to provide methods on nodes that aren't
# templated and are meant as convenience methods.
+#++
module Prism
class Node
+ #: (*String replacements) -> void
def deprecated(*replacements) # :nodoc:
- location = caller_locations(1, 1)
- location = location[0].label if location
+ location = caller_locations(1, 1)&.[](0)&.label
suggest = replacements.map { |replacement| "#{self.class}##{replacement}" }
warn(<<~MSG, uplevel: 1, category: :deprecated)
@@ -20,7 +25,9 @@ module Prism
module RegularExpressionOptions # :nodoc:
# Returns a numeric value that represents the flags that were used to create
# the regular expression.
- def options
+ #--
+ #: (Integer flags) -> Integer
+ def self.options(flags)
o = 0
o |= Regexp::IGNORECASE if flags.anybits?(RegularExpressionFlags::IGNORE_CASE)
o |= Regexp::EXTENDED if flags.anybits?(RegularExpressionFlags::EXTENDED)
@@ -32,43 +39,87 @@ module Prism
end
class InterpolatedMatchLastLineNode < Node
- include RegularExpressionOptions
+ # Returns a numeric value that represents the flags that were used to create
+ # the regular expression.
+ #--
+ #: () -> Integer
+ def options
+ RegularExpressionOptions.options(flags)
+ end
end
class InterpolatedRegularExpressionNode < Node
- include RegularExpressionOptions
+ # Returns a numeric value that represents the flags that were used to create
+ # the regular expression.
+ #--
+ #: () -> Integer
+ def options
+ RegularExpressionOptions.options(flags)
+ end
end
class MatchLastLineNode < Node
- include RegularExpressionOptions
+ # Returns a numeric value that represents the flags that were used to create
+ # the regular expression.
+ #--
+ #: () -> Integer
+ def options
+ RegularExpressionOptions.options(flags)
+ end
end
class RegularExpressionNode < Node
- include RegularExpressionOptions
+ # Returns a numeric value that represents the flags that were used to create
+ # the regular expression.
+ #--
+ #: () -> Integer
+ def options
+ RegularExpressionOptions.options(flags)
+ end
end
private_constant :RegularExpressionOptions
module HeredocQuery # :nodoc:
# Returns true if this node was represented as a heredoc in the source code.
- def heredoc?
+ #--
+ #: (String? opening) -> bool?
+ def self.heredoc?(opening)
+ # @type self: InterpolatedStringNode | InterpolatedXStringNode | StringNode | XStringNode
opening&.start_with?("<<")
end
end
class InterpolatedStringNode < Node
- include HeredocQuery
+ # Returns true if this node was represented as a heredoc in the source code.
+ #--
+ #: () -> bool?
+ def heredoc?
+ HeredocQuery.heredoc?(opening)
+ end
end
class InterpolatedXStringNode < Node
- include HeredocQuery
+ # Returns true if this node was represented as a heredoc in the source code.
+ #--
+ #: () -> bool?
+ def heredoc?
+ HeredocQuery.heredoc?(opening)
+ end
end
class StringNode < Node
- include HeredocQuery
+ # Returns true if this node was represented as a heredoc in the source code.
+ #--
+ #: () -> bool?
+ def heredoc?
+ HeredocQuery.heredoc?(opening)
+ end
# Occasionally it's helpful to treat a string as if it were interpolated so
# that there's a consistent interface for working with strings.
+ #--
+ #: () -> InterpolatedStringNode
def to_interpolated
InterpolatedStringNode.new(
source,
@@ -83,10 +134,17 @@ module Prism
end
class XStringNode < Node
- include HeredocQuery
+ # Returns true if this node was represented as a heredoc in the source code.
+ #--
+ #: () -> bool?
+ def heredoc?
+ HeredocQuery.heredoc?(opening)
+ end
# Occasionally it's helpful to treat a string as if it were interpolated so
# that there's a consistent interface for working with strings.
+ #--
+ #: () -> InterpolatedXStringNode
def to_interpolated
InterpolatedXStringNode.new(
source,
@@ -104,6 +162,8 @@ module Prism
class ImaginaryNode < Node
# Returns the value of the node as a Ruby Complex.
+ #--
+ #: () -> Complex
def value
Complex(0, numeric.value)
end
@@ -111,31 +171,25 @@ module Prism
class RationalNode < Node
# Returns the value of the node as a Ruby Rational.
+ #--
+ #: () -> Rational
def value
Rational(numerator, denominator)
end
-
- # Returns the value of the node as an IntegerNode or a FloatNode. This
- # method is deprecated in favor of #value or #numerator/#denominator.
- def numeric
- deprecated("value", "numerator", "denominator")
-
- if denominator == 1
- IntegerNode.new(source, -1, location.chop, flags, numerator)
- else
- FloatNode.new(source, -1, location.chop, 0, numerator.to_f / denominator)
- end
- end
end
class ConstantReadNode < Node
# Returns the list of parts for the full name of this constant.
# For example: [:Foo]
+ #--
+ #: () -> Array[Symbol]
def full_name_parts
[name]
end
# Returns the full name of this constant. For example: "Foo"
+ #--
+ #: () -> String
def full_name
name.to_s
end
@@ -144,11 +198,15 @@ module Prism
class ConstantWriteNode < Node
# Returns the list of parts for the full name of this constant.
# For example: [:Foo]
+ #--
+ #: () -> Array[Symbol]
def full_name_parts
[name]
end
# Returns the full name of this constant. For example: "Foo"
+ #--
+ #: () -> String
def full_name
name.to_s
end
@@ -163,13 +221,15 @@ module Prism
# local variable
class DynamicPartsInConstantPathError < StandardError; end
- # An error class raised when missing nodes are found while computing a
+ # An error class raised when error recovery nodes are found while computing a
# constant path's full name. For example:
# Foo:: -> raises because the constant path is missing the last part
- class MissingNodesInConstantPathError < StandardError; end
+ class ErrorRecoveryNodesInConstantPathError < StandardError; end
# Returns the list of parts for the full name of this constant path.
# For example: [:Foo, :Bar]
+ #--
+ #: () -> Array[Symbol]
def full_name_parts
parts = [] #: Array[Symbol]
current = self #: node?
@@ -177,7 +237,7 @@ module Prism
while current.is_a?(ConstantPathNode)
name = current.name
if name.nil?
- raise MissingNodesInConstantPathError, "Constant path contains missing nodes. Cannot compute full name"
+ raise ErrorRecoveryNodesInConstantPathError, "Constant path contains error recovery nodes. Cannot compute full name"
end
parts.unshift(name)
@@ -192,30 +252,21 @@ module Prism
end
# Returns the full name of this constant path. For example: "Foo::Bar"
+ #--
+ #: () -> String
def full_name
full_name_parts.join("::")
end
-
- # Previously, we had a child node on this class that contained either a
- # constant read or a missing node. To not cause a breaking change, we
- # continue to supply that API.
- def child
- deprecated("name", "name_loc")
-
- if name
- ConstantReadNode.new(source, -1, name_loc, 0, name)
- else
- MissingNode.new(source, -1, location, 0)
- end
- end
end
class ConstantPathTargetNode < Node
# Returns the list of parts for the full name of this constant path.
# For example: [:Foo, :Bar]
+ #--
+ #: () -> Array[Symbol]
def full_name_parts
parts =
- case parent
+ case (parent = self.parent)
when ConstantPathNode, ConstantReadNode
parent.full_name_parts
when nil
@@ -225,40 +276,33 @@ module Prism
raise ConstantPathNode::DynamicPartsInConstantPathError, "Constant target path contains dynamic parts. Cannot compute full name"
end
- if name.nil?
- raise ConstantPathNode::MissingNodesInConstantPathError, "Constant target path contains missing nodes. Cannot compute full name"
+ if (name = self.name).nil?
+ raise ConstantPathNode::ErrorRecoveryNodesInConstantPathError, "Constant target path contains error recovery nodes. Cannot compute full name"
end
parts.push(name)
end
# Returns the full name of this constant path. For example: "Foo::Bar"
+ #--
+ #: () -> String
def full_name
full_name_parts.join("::")
end
-
- # Previously, we had a child node on this class that contained either a
- # constant read or a missing node. To not cause a breaking change, we
- # continue to supply that API.
- def child
- deprecated("name", "name_loc")
-
- if name
- ConstantReadNode.new(source, -1, name_loc, 0, name)
- else
- MissingNode.new(source, -1, location, 0)
- end
- end
end
class ConstantTargetNode < Node
# Returns the list of parts for the full name of this constant.
# For example: [:Foo]
+ #--
+ #: () -> Array[Symbol]
def full_name_parts
[name]
end
# Returns the full name of this constant. For example: "Foo"
+ #--
+ #: () -> String
def full_name
name.to_s
end
@@ -266,6 +310,8 @@ module Prism
class ParametersNode < Node
# Mirrors the Method#parameters method.
+ #--
+ #: () -> Array[[Symbol, Symbol] | [Symbol]]
def signature
names = [] #: Array[[Symbol, Symbol] | [Symbol]]
@@ -275,7 +321,7 @@ module Prism
optionals.each { |param| names << [:opt, param.name] }
- if rest && rest.is_a?(RestParameterNode)
+ if (rest = self.rest).is_a?(RestParameterNode)
names << [:rest, rest.name || :*]
end
@@ -283,8 +329,7 @@ module Prism
case param
when MultiTargetNode
names << [:req]
- when NoKeywordsParameterNode, KeywordRestParameterNode, ForwardingParameterNode
- # Invalid syntax, e.g. "def f(**nil, ...)" moves the NoKeywordsParameterNode to posts
+ when ErrorRecoveryNode
raise "Invalid syntax"
else
names << [:req, param.name]
@@ -304,7 +349,7 @@ module Prism
keyopt.each { |param| names << [:key, param.name] }
- case keyword_rest
+ case (keyword_rest = self.keyword_rest)
when ForwardingParameterNode
names.concat([[:rest, :*], [:keyrest, :**], [:block, :&]])
when KeywordRestParameterNode
@@ -313,7 +358,13 @@ module Prism
names << [:nokey]
end
- names << [:block, block.name || :&] if block
+ case (block = self.block)
+ when BlockParameterNode
+ names << [:block, block.name || :&]
+ when NoBlockParameterNode
+ names << [:noblock]
+ end
+
names
end
end
@@ -328,181 +379,10 @@ module Prism
# can be any amount of space between the message and the = sign. However,
# sometimes you want the location of the full message including the inner
# space and the = sign. This method provides that.
+ #--
+ #: () -> Location?
def full_message_loc
attribute_write? ? message_loc&.adjoin("=") : message_loc
end
end
-
- class CallOperatorWriteNode < Node
- # Returns the binary operator used to modify the receiver. This method is
- # deprecated in favor of #binary_operator.
- def operator
- deprecated("binary_operator")
- binary_operator
- end
-
- # Returns the location of the binary operator used to modify the receiver.
- # This method is deprecated in favor of #binary_operator_loc.
- def operator_loc
- deprecated("binary_operator_loc")
- binary_operator_loc
- end
- end
-
- class ClassVariableOperatorWriteNode < Node
- # Returns the binary operator used to modify the receiver. This method is
- # deprecated in favor of #binary_operator.
- def operator
- deprecated("binary_operator")
- binary_operator
- end
-
- # Returns the location of the binary operator used to modify the receiver.
- # This method is deprecated in favor of #binary_operator_loc.
- def operator_loc
- deprecated("binary_operator_loc")
- binary_operator_loc
- end
- end
-
- class ConstantOperatorWriteNode < Node
- # Returns the binary operator used to modify the receiver. This method is
- # deprecated in favor of #binary_operator.
- def operator
- deprecated("binary_operator")
- binary_operator
- end
-
- # Returns the location of the binary operator used to modify the receiver.
- # This method is deprecated in favor of #binary_operator_loc.
- def operator_loc
- deprecated("binary_operator_loc")
- binary_operator_loc
- end
- end
-
- class ConstantPathOperatorWriteNode < Node
- # Returns the binary operator used to modify the receiver. This method is
- # deprecated in favor of #binary_operator.
- def operator
- deprecated("binary_operator")
- binary_operator
- end
-
- # Returns the location of the binary operator used to modify the receiver.
- # This method is deprecated in favor of #binary_operator_loc.
- def operator_loc
- deprecated("binary_operator_loc")
- binary_operator_loc
- end
- end
-
- class GlobalVariableOperatorWriteNode < Node
- # Returns the binary operator used to modify the receiver. This method is
- # deprecated in favor of #binary_operator.
- def operator
- deprecated("binary_operator")
- binary_operator
- end
-
- # Returns the location of the binary operator used to modify the receiver.
- # This method is deprecated in favor of #binary_operator_loc.
- def operator_loc
- deprecated("binary_operator_loc")
- binary_operator_loc
- end
- end
-
- class IndexOperatorWriteNode < Node
- # Returns the binary operator used to modify the receiver. This method is
- # deprecated in favor of #binary_operator.
- def operator
- deprecated("binary_operator")
- binary_operator
- end
-
- # Returns the location of the binary operator used to modify the receiver.
- # This method is deprecated in favor of #binary_operator_loc.
- def operator_loc
- deprecated("binary_operator_loc")
- binary_operator_loc
- end
- end
-
- class InstanceVariableOperatorWriteNode < Node
- # Returns the binary operator used to modify the receiver. This method is
- # deprecated in favor of #binary_operator.
- def operator
- deprecated("binary_operator")
- binary_operator
- end
-
- # Returns the location of the binary operator used to modify the receiver.
- # This method is deprecated in favor of #binary_operator_loc.
- def operator_loc
- deprecated("binary_operator_loc")
- binary_operator_loc
- end
- end
-
- class LocalVariableOperatorWriteNode < Node
- # Returns the binary operator used to modify the receiver. This method is
- # deprecated in favor of #binary_operator.
- def operator
- deprecated("binary_operator")
- binary_operator
- end
-
- # Returns the location of the binary operator used to modify the receiver.
- # This method is deprecated in favor of #binary_operator_loc.
- def operator_loc
- deprecated("binary_operator_loc")
- binary_operator_loc
- end
- end
-
- class CaseMatchNode < Node
- # Returns the else clause of the case match node. This method is deprecated
- # in favor of #else_clause.
- def consequent
- deprecated("else_clause")
- else_clause
- end
- end
-
- class CaseNode < Node
- # Returns the else clause of the case node. This method is deprecated in
- # favor of #else_clause.
- def consequent
- deprecated("else_clause")
- else_clause
- end
- end
-
- class IfNode < Node
- # Returns the subsequent if/elsif/else clause of the if node. This method is
- # deprecated in favor of #subsequent.
- def consequent
- deprecated("subsequent")
- subsequent
- end
- end
-
- class RescueNode < Node
- # Returns the subsequent rescue clause of the rescue node. This method is
- # deprecated in favor of #subsequent.
- def consequent
- deprecated("subsequent")
- subsequent
- end
- end
-
- class UnlessNode < Node
- # Returns the else clause of the unless node. This method is deprecated in
- # favor of #else_clause.
- def consequent
- deprecated("else_clause")
- else_clause
- end
- end
end