From 5afee6ba9266742c2c90153ffd98bdf7642dd894 Mon Sep 17 00:00:00 2001 From: Kevin Newton Date: Wed, 2 Nov 2022 10:36:10 -0400 Subject: [PATCH 01/17] Remove comments from initializers --- lib/syntax_tree/node.rb | 522 +++++++++++++++++++------------------- lib/syntax_tree/parser.rb | 28 +- 2 files changed, 276 insertions(+), 274 deletions(-) diff --git a/lib/syntax_tree/node.rb b/lib/syntax_tree/node.rb index aa133b7f..a1e5c0ae 100644 --- a/lib/syntax_tree/node.rb +++ b/lib/syntax_tree/node.rb @@ -146,11 +146,11 @@ class BEGINBlock < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(lbrace:, statements:, location:, comments: []) + def initialize(lbrace:, statements:, location:) @lbrace = lbrace @statements = statements @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -199,10 +199,10 @@ class CHAR < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(value:, location:, comments: []) + def initialize(value:, location:) @value = value @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -249,11 +249,11 @@ class ENDBlock < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(lbrace:, statements:, location:, comments: []) + def initialize(lbrace:, statements:, location:) @lbrace = lbrace @statements = statements @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -305,10 +305,10 @@ class EndContent < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(value:, location:, comments: []) + def initialize(value:, location:) @value = value @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -392,11 +392,11 @@ def format(q) # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(left:, right:, location:, comments: []) + def initialize(left:, right:, location:) @left = left @right = right @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -453,11 +453,11 @@ class ARef < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(collection:, index:, location:, comments: []) + def initialize(collection:, index:, location:) @collection = collection @index = index @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -514,11 +514,11 @@ class ARefField < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(collection:, index:, location:, comments: []) + def initialize(collection:, index:, location:) @collection = collection @index = index @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -577,10 +577,10 @@ class ArgParen < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(arguments:, location:, comments: []) + def initialize(arguments:, location:) @arguments = arguments @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -650,10 +650,10 @@ class Args < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(parts:, location:, comments: []) + def initialize(parts:, location:) @parts = parts @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -686,10 +686,10 @@ class ArgBlock < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(value:, location:, comments: []) + def initialize(value:, location:) @value = value @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -723,10 +723,10 @@ class ArgStar < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(value:, location:, comments: []) + def initialize(value:, location:) @value = value @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -773,10 +773,10 @@ class ArgsForward < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(value:, location:, comments: []) + def initialize(value:, location:) @value = value @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -955,11 +955,11 @@ def format(q) # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(lbracket:, contents:, location:, comments: []) + def initialize(lbracket:, contents:, location:) @lbracket = lbracket @contents = contents @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -1132,7 +1132,7 @@ def initialize( @rest = rest @posts = posts @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -1209,11 +1209,11 @@ class Assign < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(target:, value:, location:, comments: []) + def initialize(target:, value:, location:) @target = target @value = value @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -1271,11 +1271,11 @@ class Assoc < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(key:, value:, location:, comments: []) + def initialize(key:, value:, location:) @key = key @value = value @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -1330,10 +1330,10 @@ class AssocSplat < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(value:, location:, comments: []) + def initialize(value:, location:) @value = value @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -1368,10 +1368,10 @@ class Backref < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(value:, location:, comments: []) + def initialize(value:, location:) @value = value @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -1403,10 +1403,10 @@ class Backtick < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(value:, location:, comments: []) + def initialize(value:, location:) @value = value @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -1515,10 +1515,10 @@ class BareAssocHash < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(assocs:, location:, comments: []) + def initialize(assocs:, location:) @assocs = assocs @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -1557,10 +1557,10 @@ class Begin < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(bodystmt:, location:, comments: []) + def initialize(bodystmt:, location:) @bodystmt = bodystmt @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -1605,10 +1605,10 @@ class PinnedBegin < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(statement:, location:, comments: []) + def initialize(statement:, location:) @statement = statement @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -1677,12 +1677,12 @@ def name # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(left:, operator:, right:, location:, comments: []) + def initialize(left:, operator:, right:, location:) @left = left @operator = operator @right = right @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -1745,11 +1745,11 @@ class BlockVar < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(params:, locals:, location:, comments: []) + def initialize(params:, locals:, location:) @params = params @locals = locals @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -1803,10 +1803,10 @@ class BlockArg < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(name:, location:, comments: []) + def initialize(name:, location:) @name = name @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -1866,7 +1866,7 @@ def initialize( @else_clause = else_clause @ensure_clause = ensure_clause @location = location - @comments = comments + @comments = [] end def bind(start_char, start_column, end_char, end_column) @@ -2141,12 +2141,12 @@ class BraceBlock < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(lbrace:, block_var:, statements:, location:, comments: []) + def initialize(lbrace:, block_var:, statements:, location:) @lbrace = lbrace @block_var = block_var @statements = statements @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -2371,10 +2371,10 @@ class Break < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(arguments:, location:, comments: []) + def initialize(arguments:, location:) @arguments = arguments @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -2672,7 +2672,7 @@ def initialize( @message = message @arguments = arguments @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -2782,12 +2782,12 @@ class Case < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(keyword:, value:, consequent:, location:, comments: []) + def initialize(keyword:, value:, consequent:, location:) @keyword = keyword @value = value @consequent = consequent @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -2847,12 +2847,12 @@ class RAssign < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(value:, operator:, pattern:, location:, comments: []) + def initialize(value:, operator:, pattern:, location:) @value = value @operator = operator @pattern = pattern @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -2943,12 +2943,12 @@ class ClassDeclaration < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(constant:, superclass:, bodystmt:, location:, comments: []) + def initialize(constant:, superclass:, bodystmt:, location:) @constant = constant @superclass = superclass @bodystmt = bodystmt @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -3049,11 +3049,11 @@ class Command < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(message:, arguments:, location:, comments: []) + def initialize(message:, arguments:, location:) @message = message @arguments = arguments @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -3151,7 +3151,7 @@ def initialize( @message = message @arguments = arguments @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -3323,10 +3323,10 @@ class Const < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(value:, location:, comments: []) + def initialize(value:, location:) @value = value @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -3364,11 +3364,11 @@ class ConstPathField < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(parent:, constant:, location:, comments: []) + def initialize(parent:, constant:, location:) @parent = parent @constant = constant @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -3411,11 +3411,11 @@ class ConstPathRef < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(parent:, constant:, location:, comments: []) + def initialize(parent:, constant:, location:) @parent = parent @constant = constant @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -3457,10 +3457,10 @@ class ConstRef < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(constant:, location:, comments: []) + def initialize(constant:, location:) @constant = constant @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -3493,10 +3493,10 @@ class CVar < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(value:, location:, comments: []) + def initialize(value:, location:) @value = value @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -3535,12 +3535,12 @@ class Def < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(name:, params:, bodystmt:, location:, comments: []) + def initialize(name:, params:, bodystmt:, location:) @name = name @params = params @bodystmt = bodystmt @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -3625,7 +3625,7 @@ def initialize( @paren = paren @statement = statement @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -3690,10 +3690,10 @@ class Defined < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(value:, location:, comments: []) + def initialize(value:, location:) @value = value @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -3761,7 +3761,7 @@ def initialize( @params = params @bodystmt = bodystmt @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -3831,12 +3831,12 @@ class DoBlock < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(keyword:, block_var:, bodystmt:, location:, comments: []) + def initialize(keyword:, block_var:, bodystmt:, location:) @keyword = keyword @block_var = block_var @bodystmt = bodystmt @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -3915,11 +3915,11 @@ class Dot2 < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(left:, right:, location:, comments: []) + def initialize(left:, right:, location:) @left = left @right = right @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -3963,11 +3963,11 @@ class Dot3 < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(left:, right:, location:, comments: []) + def initialize(left:, right:, location:) @left = left @right = right @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -4050,11 +4050,11 @@ class DynaSymbol < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(parts:, quote:, location:, comments: []) + def initialize(parts:, quote:, location:) @parts = parts @quote = quote @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -4161,11 +4161,11 @@ class Else < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(keyword:, statements:, location:, comments: []) + def initialize(keyword:, statements:, location:) @keyword = keyword @statements = statements @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -4231,7 +4231,7 @@ def initialize( @statements = statements @consequent = consequent @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -4435,11 +4435,11 @@ class Ensure < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(keyword:, statements:, location:, comments: []) + def initialize(keyword:, statements:, location:) @keyword = keyword @statements = statements @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -4490,10 +4490,10 @@ class ExcessedComma < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(value:, location:, comments: []) + def initialize(value:, location:) @value = value @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -4532,11 +4532,11 @@ class FCall < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(value:, arguments:, location:, comments: []) + def initialize(value:, arguments:, location:) @value = value @arguments = arguments @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -4591,12 +4591,12 @@ class Field < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(parent:, operator:, name:, location:, comments: []) + def initialize(parent:, operator:, name:, location:) @parent = parent @operator = operator @name = name @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -4639,10 +4639,10 @@ class FloatLiteral < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(value:, location:, comments: []) + def initialize(value:, location:) @value = value @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -4688,13 +4688,13 @@ class FndPtn < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(constant:, left:, values:, right:, location:, comments: []) + def initialize(constant:, left:, values:, right:, location:) @constant = constant @left = left @values = values @right = right @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -4763,12 +4763,12 @@ class For < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(index:, collection:, statements:, location:, comments: []) + def initialize(index:, collection:, statements:, location:) @index = index @collection = collection @statements = statements @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -4822,10 +4822,10 @@ class GVar < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(value:, location:, comments: []) + def initialize(value:, location:) @value = value @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -4887,11 +4887,11 @@ def format(q) # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(lbrace:, assocs:, location:, comments: []) + def initialize(lbrace:, assocs:, location:) @lbrace = lbrace @assocs = assocs @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -4987,7 +4987,7 @@ def initialize( @dedent = dedent @parts = parts @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -5064,10 +5064,10 @@ class HeredocBeg < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(value:, location:, comments: []) + def initialize(value:, location:) @value = value @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -5103,10 +5103,10 @@ class HeredocEnd < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(value:, location:, comments: []) + def initialize(value:, location:) @value = value @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -5195,12 +5195,12 @@ def format(q) # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(constant:, keywords:, keyword_rest:, location:, comments: []) + def initialize(constant:, keywords:, keyword_rest:, location:) @constant = constant @keywords = keywords @keyword_rest = keyword_rest @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -5305,10 +5305,10 @@ class Ident < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(value:, location:, comments: []) + def initialize(value:, location:) @value = value @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -5574,7 +5574,7 @@ def initialize( @statements = statements @consequent = consequent @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -5619,12 +5619,12 @@ class IfOp < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(predicate:, truthy:, falsy:, location:, comments: []) + def initialize(predicate:, truthy:, falsy:, location:) @predicate = predicate @truthy = truthy @falsy = falsy @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -5761,11 +5761,11 @@ class IfMod < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(statement:, predicate:, location:, comments: []) + def initialize(statement:, predicate:, location:) @statement = statement @predicate = predicate @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -5803,10 +5803,10 @@ class Imaginary < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(value:, location:, comments: []) + def initialize(value:, location:) @value = value @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -5848,12 +5848,12 @@ class In < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(pattern:, statements:, consequent:, location:, comments: []) + def initialize(pattern:, statements:, consequent:, location:) @pattern = pattern @statements = statements @consequent = consequent @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -5909,10 +5909,10 @@ class Int < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(value:, location:, comments: []) + def initialize(value:, location:) @value = value @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -5953,10 +5953,10 @@ class IVar < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(value:, location:, comments: []) + def initialize(value:, location:) @value = value @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -6001,11 +6001,11 @@ class Kw < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(value:, location:, comments: []) + def initialize(value:, location:) @value = value @name = value.to_sym @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -6039,10 +6039,10 @@ class KwRestParam < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(name:, location:, comments: []) + def initialize(name:, location:) @name = name @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -6085,10 +6085,10 @@ class Label < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(value:, location:, comments: []) + def initialize(value:, location:) @value = value @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -6155,11 +6155,11 @@ class Lambda < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(params:, statements:, location:, comments: []) + def initialize(params:, statements:, location:) @params = params @statements = statements @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -6263,11 +6263,11 @@ class LambdaVar < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(params:, locals:, location:, comments: []) + def initialize(params:, locals:, location:) @params = params @locals = locals @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -6306,10 +6306,10 @@ class LBrace < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(value:, location:, comments: []) + def initialize(value:, location:) @value = value @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -6339,10 +6339,10 @@ class LBracket < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(value:, location:, comments: []) + def initialize(value:, location:) @value = value @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -6372,10 +6372,10 @@ class LParen < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(value:, location:, comments: []) + def initialize(value:, location:) @value = value @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -6421,11 +6421,11 @@ class MAssign < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(target:, value:, location:, comments: []) + def initialize(target:, value:, location:) @target = target @value = value @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -6468,11 +6468,11 @@ class MethodAddBlock < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(call:, block:, location:, comments: []) + def initialize(call:, block:, location:) @call = call @block = block @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -6529,11 +6529,11 @@ class MLHS < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(parts:, comma: false, location:, comments: []) + def initialize(parts:, comma: false, location:) @parts = parts @comma = comma @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -6573,11 +6573,11 @@ class MLHSParen < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(contents:, comma: false, location:, comments: []) + def initialize(contents:, comma: false, location:) @contents = contents @comma = comma @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -6631,11 +6631,11 @@ class ModuleDeclaration < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(constant:, bodystmt:, location:, comments: []) + def initialize(constant:, bodystmt:, location:) @constant = constant @bodystmt = bodystmt @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -6701,10 +6701,10 @@ class MRHS < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(parts:, location:, comments: []) + def initialize(parts:, location:) @parts = parts @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -6750,10 +6750,10 @@ class Next < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(arguments:, location:, comments: []) + def initialize(arguments:, location:) @arguments = arguments @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -6790,11 +6790,11 @@ class Op < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(value:, location:, comments: []) + def initialize(value:, location:) @value = value @name = value.to_sym @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -6835,12 +6835,12 @@ class OpAssign < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(target:, operator:, value:, location:, comments: []) + def initialize(target:, operator:, value:, location:) @target = target @operator = operator @value = value @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -7081,7 +7081,7 @@ def initialize( @keyword_rest = keyword_rest @block = block @location = location - @comments = comments + @comments = [] end # Params nodes are the most complicated in the tree. Occasionally you want @@ -7187,11 +7187,11 @@ class Paren < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(lparen:, contents:, location:, comments: []) + def initialize(lparen:, contents:, location:) @lparen = lparen @contents = contents @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -7239,10 +7239,10 @@ class Period < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(value:, location:, comments: []) + def initialize(value:, location:) @value = value @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -7272,10 +7272,10 @@ class Program < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(statements:, location:, comments: []) + def initialize(statements:, location:) @statements = statements @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -7316,11 +7316,11 @@ class QSymbols < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(beginning:, elements:, location:, comments: []) + def initialize(beginning:, elements:, location:) @beginning = beginning @elements = elements @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -7410,11 +7410,11 @@ class QWords < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(beginning:, elements:, location:, comments: []) + def initialize(beginning:, elements:, location:) @beginning = beginning @elements = elements @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -7501,10 +7501,10 @@ class RationalLiteral < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(value:, location:, comments: []) + def initialize(value:, location:) @value = value @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -7587,10 +7587,10 @@ class Redo < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(value:, location:, comments: []) + def initialize(value:, location:) @value = value @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -7732,12 +7732,12 @@ class RegexpLiteral < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(beginning:, ending:, parts:, location:, comments: []) + def initialize(beginning:, ending:, parts:, location:) @beginning = beginning @ending = ending @parts = parts @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -7843,11 +7843,11 @@ class RescueEx < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(exceptions:, variable:, location:, comments: []) + def initialize(exceptions:, variable:, location:) @exceptions = exceptions @variable = variable @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -7919,7 +7919,7 @@ def initialize( @statements = statements @consequent = consequent @location = location - @comments = comments + @comments = [] end def bind_end(end_char, end_column) @@ -8004,11 +8004,11 @@ class RescueMod < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(statement:, value:, location:, comments: []) + def initialize(statement:, value:, location:) @statement = statement @value = value @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -8061,10 +8061,10 @@ class RestParam < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(name:, location:, comments: []) + def initialize(name:, location:) @name = name @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -8098,10 +8098,10 @@ class Retry < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(value:, location:, comments: []) + def initialize(value:, location:) @value = value @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -8134,10 +8134,10 @@ class Return < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(arguments:, location:, comments: []) + def initialize(arguments:, location:) @arguments = arguments @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -8170,10 +8170,10 @@ class Return0 < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(value:, location:, comments: []) + def initialize(value:, location:) @value = value @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -8237,11 +8237,11 @@ class SClass < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(target:, bodystmt:, location:, comments: []) + def initialize(target:, bodystmt:, location:) @target = target @bodystmt = bodystmt @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -8294,11 +8294,11 @@ class Statements < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(parser, body:, location:, comments: []) + def initialize(parser, body:, location:) @parser = parser @body = body @location = location - @comments = comments + @comments = [] end def bind(start_char, start_column, end_char, end_column) @@ -8498,11 +8498,11 @@ class StringConcat < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(left:, right:, location:, comments: []) + def initialize(left:, right:, location:) @left = left @right = right @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -8544,10 +8544,10 @@ class StringDVar < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(variable:, location:, comments: []) + def initialize(variable:, location:) @variable = variable @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -8584,10 +8584,10 @@ class StringEmbExpr < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(statements:, location:, comments: []) + def initialize(statements:, location:) @statements = statements @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -8646,11 +8646,11 @@ class StringLiteral < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(parts:, quote:, location:, comments: []) + def initialize(parts:, quote:, location:) @parts = parts @quote = quote @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -8721,10 +8721,10 @@ class Super < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(arguments:, location:, comments: []) + def initialize(arguments:, location:) @arguments = arguments @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -8838,10 +8838,10 @@ class SymbolLiteral < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(value:, location:, comments: []) + def initialize(value:, location:) @value = value @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -8878,11 +8878,11 @@ class Symbols < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(beginning:, elements:, location:, comments: []) + def initialize(beginning:, elements:, location:) @beginning = beginning @elements = elements @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -9031,10 +9031,10 @@ class TopConstField < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(constant:, location:, comments: []) + def initialize(constant:, location:) @constant = constant @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -9069,10 +9069,10 @@ class TopConstRef < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(constant:, location:, comments: []) + def initialize(constant:, location:) @constant = constant @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -9144,10 +9144,10 @@ class TStringContent < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(value:, location:, comments: []) + def initialize(value:, location:) @value = value @location = location - @comments = comments + @comments = [] end def match?(pattern) @@ -9222,11 +9222,11 @@ class Not < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(statement:, parentheses:, location:, comments: []) + def initialize(statement:, parentheses:, location:) @statement = statement @parentheses = parentheses @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -9288,11 +9288,11 @@ class Unary < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(operator:, statement:, location:, comments: []) + def initialize(operator:, statement:, location:) @operator = operator @statement = statement @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -9355,10 +9355,10 @@ def format(q) # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(symbols:, location:, comments: []) + def initialize(symbols:, location:) @symbols = symbols @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -9417,7 +9417,7 @@ def initialize( @statements = statements @consequent = consequent @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -9459,11 +9459,11 @@ class UnlessMod < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(statement:, predicate:, location:, comments: []) + def initialize(statement:, predicate:, location:) @statement = statement @predicate = predicate @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -9556,11 +9556,11 @@ class Until < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(predicate:, statements:, location:, comments: []) + def initialize(predicate:, statements:, location:) @predicate = predicate @statements = statements @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -9612,11 +9612,11 @@ class UntilMod < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(statement:, predicate:, location:, comments: []) + def initialize(statement:, predicate:, location:) @statement = statement @predicate = predicate @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -9678,11 +9678,11 @@ class VarAlias < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(left:, right:, location:, comments: []) + def initialize(left:, right:, location:) @left = left @right = right @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -9722,10 +9722,10 @@ class VarField < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(value:, location:, comments: []) + def initialize(value:, location:) @value = value @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -9766,10 +9766,10 @@ class VarRef < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(value:, location:, comments: []) + def initialize(value:, location:) @value = value @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -9830,10 +9830,10 @@ class PinnedVarRef < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(value:, location:, comments: []) + def initialize(value:, location:) @value = value @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -9870,10 +9870,10 @@ class VCall < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(value:, location:, comments: []) + def initialize(value:, location:) @value = value @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -9910,9 +9910,9 @@ class VoidStmt < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(location:, comments: []) + def initialize(location:) @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -9963,7 +9963,7 @@ def initialize( @statements = statements @consequent = consequent @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -10055,11 +10055,11 @@ class While < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(predicate:, statements:, location:, comments: []) + def initialize(predicate:, statements:, location:) @predicate = predicate @statements = statements @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -10111,11 +10111,11 @@ class WhileMod < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(statement:, predicate:, location:, comments: []) + def initialize(statement:, predicate:, location:) @statement = statement @predicate = predicate @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -10177,10 +10177,10 @@ class Word < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(parts:, location:, comments: []) + def initialize(parts:, location:) @parts = parts @location = location - @comments = comments + @comments = [] end def match?(pattern) @@ -10220,11 +10220,11 @@ class Words < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(beginning:, elements:, location:, comments: []) + def initialize(beginning:, elements:, location:) @beginning = beginning @elements = elements @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -10342,10 +10342,10 @@ class XStringLiteral < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(parts:, location:, comments: []) + def initialize(parts:, location:) @parts = parts @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -10380,10 +10380,10 @@ class Yield < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(arguments:, location:, comments: []) + def initialize(arguments:, location:) @arguments = arguments @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -10430,10 +10430,10 @@ class Yield0 < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(value:, location:, comments: []) + def initialize(value:, location:) @value = value @location = location - @comments = comments + @comments = [] end def accept(visitor) @@ -10466,10 +10466,10 @@ class ZSuper < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(value:, location:, comments: []) + def initialize(value:, location:) @value = value @location = location - @comments = comments + @comments = [] end def accept(visitor) diff --git a/lib/syntax_tree/parser.rb b/lib/syntax_tree/parser.rb index 61a7ca57..abd9bd60 100644 --- a/lib/syntax_tree/parser.rb +++ b/lib/syntax_tree/parser.rb @@ -2104,17 +2104,20 @@ def on_lambda(params, statements) location = params.contents.location location = location.to(locals.last.location) if locals.any? - Paren.new( - lparen: params.lparen, - contents: - LambdaVar.new( - params: params.contents, - locals: locals, - location: location - ), - location: params.location, - comments: params.comments - ) + node = + Paren.new( + lparen: params.lparen, + contents: + LambdaVar.new( + params: params.contents, + locals: locals, + location: location + ), + location: params.location + ) + + node.comments.concat(params.comments) + node when Params # In this case we've gotten to the <3.2 plain set of parameters. In # this case there cannot be lambda locals, so we will wrap the @@ -2199,8 +2202,7 @@ def lambda_locals(source) on_comma: :item, on_rparen: :final }, - final: { - } + final: {} } tokens[(index + 1)..].each_with_object([]) do |token, locals| From 38a1b036593e1a220a6666817d3c655b432f4656 Mon Sep 17 00:00:00 2001 From: Kevin Newton Date: Wed, 2 Nov 2022 10:46:48 -0400 Subject: [PATCH 02/17] Fold IfMod into If and UnlessMod into Unless --- CHANGELOG.md | 5 + lib/syntax_tree/node.rb | 232 ++++++----------------- lib/syntax_tree/parser.rb | 14 +- lib/syntax_tree/visitor.rb | 6 - lib/syntax_tree/visitor/field_visitor.rb | 16 -- test/node_test.rb | 6 +- 6 files changed, 77 insertions(+), 202 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 45a06c13..5d944f7a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,11 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a ## [Unreleased] +### Changed + +- Nodes no longer have a `comments:` keyword on their initializers. By default, they initialize to an empty array. If you were previously passing comments into the initializer, you should now create the node first, then call `node.comments.concat` to add your comments. +- `IfMod` and `UnlessMod` are no longer nodes. Instead, they have been folded into `If` and `Unless`, respectively. The `If` and `Unless` nodes now have a `modifier?` method to tell you if they were original found in the modifier form. + ## [4.3.0] - 2022-10-28 ### Added diff --git a/lib/syntax_tree/node.rb b/lib/syntax_tree/node.rb index a1e5c0ae..2f23e9a1 100644 --- a/lib/syntax_tree/node.rb +++ b/lib/syntax_tree/node.rb @@ -2071,8 +2071,7 @@ def forced_brace_bounds?(q) when Paren, Statements # If we hit certain breakpoints then we know we're safe. return false - when If, IfMod, IfOp, Unless, UnlessMod, While, WhileMod, Until, - UntilMod + when If, IfOp, Unless, While, WhileMod, Until, UntilMod return true if parent.predicate == previous end @@ -3884,7 +3883,7 @@ def format(q) q.format(left) if left case q.parent - when If, IfMod, Unless, UnlessMod + when If, Unless q.text(" #{operator} ") else q.text(operator) @@ -5398,10 +5397,10 @@ def call(q, node) # and default instead to breaking them into multiple lines. def ternaryable?(statement) case statement - when Alias, Assign, Break, Command, CommandCall, Heredoc, If, IfMod, - IfOp, Lambda, MAssign, Next, OpAssign, RescueMod, Return, Return0, - Super, Undef, Unless, UnlessMod, Until, UntilMod, VarAlias, - VoidStmt, While, WhileMod, Yield, Yield0, ZSuper + when Alias, Assign, Break, Command, CommandCall, Heredoc, If, IfOp, + Lambda, MAssign, Next, OpAssign, RescueMod, Return, Return0, Super, + Undef, Unless, Until, UntilMod, VarAlias, VoidStmt, While, + WhileMod, Yield, Yield0, ZSuper # This is a list of nodes that should not be allowed to be a part of a # ternary clause. false @@ -5432,41 +5431,60 @@ def initialize(keyword, node) end def format(q) - # If we can transform this node into a ternary, then we're going to print - # a special version that uses the ternary operator if it fits on one line. - if Ternaryable.call(q, node) - format_ternary(q) - return - end + if node.modifier? + statement = node.statements.body[0] - # If the predicate of the conditional contains an assignment (in which - # case we can't know for certain that that assignment doesn't impact the - # statements inside the conditional) then we can't use the modifier form - # and we must use the block form. - if ContainsAssignment.call(node.predicate) - format_break(q, force: true) - return - end - - if node.consequent || node.statements.empty? || contains_conditional? - q.group { format_break(q, force: true) } + if ContainsAssignment.call(statement) || q.parent.is_a?(In) + q.group { format_flat(q) } + else + q.group { q.if_break { format_break(q, force: false) }.if_flat { format_flat(q) } } + end else - q.group do - q - .if_break { format_break(q, force: false) } - .if_flat do - Parentheses.flat(q) do - q.format(node.statements) - q.text(" #{keyword} ") - q.format(node.predicate) + # If we can transform this node into a ternary, then we're going to + # print a special version that uses the ternary operator if it fits on + # one line. + if Ternaryable.call(q, node) + format_ternary(q) + return + end + + # If the predicate of the conditional contains an assignment (in which + # case we can't know for certain that that assignment doesn't impact the + # statements inside the conditional) then we can't use the modifier form + # and we must use the block form. + if ContainsAssignment.call(node.predicate) + format_break(q, force: true) + return + end + + if node.consequent || node.statements.empty? || contains_conditional? + q.group { format_break(q, force: true) } + else + q.group do + q + .if_break { format_break(q, force: false) } + .if_flat do + Parentheses.flat(q) do + q.format(node.statements) + q.text(" #{keyword} ") + q.format(node.predicate) + end end - end + end end end end private + def format_flat(q) + Parentheses.flat(q) do + q.format(node.statements.body[0]) + q.text(" #{keyword} ") + q.format(node.predicate) + end + end + def format_break(q, force:) q.text("#{keyword} ") q.nest(keyword.length + 1) { q.format(node.predicate) } @@ -5537,7 +5555,7 @@ def contains_conditional? return false if statements.length != 1 case statements.first - when If, IfMod, IfOp, Unless, UnlessMod + when If, IfOp, Unless true else false @@ -5600,6 +5618,11 @@ def deconstruct_keys(_keys) def format(q) ConditionalFormatter.new("if", self).format(q) end + + # Checks if the node was originally found in the modifier form. + def modifier? + predicate.location.start_char > statements.location.start_char + end end # IfOp represents a ternary clause. @@ -5649,10 +5672,9 @@ def deconstruct_keys(_keys) def format(q) force_flat = [ - Alias, Assign, Break, Command, CommandCall, Heredoc, If, IfMod, IfOp, - Lambda, MAssign, Next, OpAssign, RescueMod, Return, Return0, Super, - Undef, Unless, UnlessMod, UntilMod, VarAlias, VoidStmt, WhileMod, Yield, - Yield0, ZSuper + Alias, Assign, Break, Command, CommandCall, Heredoc, If, IfOp, Lambda, + MAssign, Next, OpAssign, RescueMod, Return, Return0, Super, Undef, + Unless, UntilMod, VarAlias, VoidStmt, WhileMod, Yield, Yield0, ZSuper ] if q.parent.is_a?(Paren) || force_flat.include?(truthy.class) || @@ -5704,94 +5726,6 @@ def format_flat(q) end end - # Formats an IfMod or UnlessMod node. - class ConditionalModFormatter - # [String] the keyword associated with this conditional - attr_reader :keyword - - # [IfMod | UnlessMod] the node that is being formatted - attr_reader :node - - def initialize(keyword, node) - @keyword = keyword - @node = node - end - - def format(q) - if ContainsAssignment.call(node.statement) || q.parent.is_a?(In) - q.group { format_flat(q) } - else - q.group { q.if_break { format_break(q) }.if_flat { format_flat(q) } } - end - end - - private - - def format_break(q) - q.text("#{keyword} ") - q.nest(keyword.length + 1) { q.format(node.predicate) } - q.indent do - q.breakable_space - q.format(node.statement) - end - q.breakable_space - q.text("end") - end - - def format_flat(q) - Parentheses.flat(q) do - q.format(node.statement) - q.text(" #{keyword} ") - q.format(node.predicate) - end - end - end - - # IfMod represents the modifier form of an +if+ statement. - # - # expression if predicate - # - class IfMod < Node - # [untyped] the expression to be executed - attr_reader :statement - - # [untyped] the expression to be checked - attr_reader :predicate - - # [Array[ Comment | EmbDoc ]] the comments attached to this node - attr_reader :comments - - def initialize(statement:, predicate:, location:) - @statement = statement - @predicate = predicate - @location = location - @comments = [] - end - - def accept(visitor) - visitor.visit_if_mod(self) - end - - def child_nodes - [statement, predicate] - end - - alias deconstruct child_nodes - - def deconstruct_keys(_keys) - { - statement: statement, - predicate: predicate, - location: location, - comments: comments - } - end - - def format(q) - ConditionalModFormatter.new("if", self).format(q) - end - end - # Imaginary represents an imaginary number literal. # # 1i @@ -9443,50 +9377,10 @@ def deconstruct_keys(_keys) def format(q) ConditionalFormatter.new("unless", self).format(q) end - end - - # UnlessMod represents the modifier form of an +unless+ statement. - # - # expression unless predicate - # - class UnlessMod < Node - # [untyped] the expression to be executed - attr_reader :statement - - # [untyped] the expression to be checked - attr_reader :predicate - - # [Array[ Comment | EmbDoc ]] the comments attached to this node - attr_reader :comments - - def initialize(statement:, predicate:, location:) - @statement = statement - @predicate = predicate - @location = location - @comments = [] - end - - def accept(visitor) - visitor.visit_unless_mod(self) - end - - def child_nodes - [statement, predicate] - end - - alias deconstruct child_nodes - - def deconstruct_keys(_keys) - { - statement: statement, - predicate: predicate, - location: location, - comments: comments - } - end - def format(q) - ConditionalModFormatter.new("unless", self).format(q) + # Checks if the node was originally found in the modifier form. + def modifier? + predicate.location.start_char > statements.location.start_char end end diff --git a/lib/syntax_tree/parser.rb b/lib/syntax_tree/parser.rb index abd9bd60..c4d6f8e9 100644 --- a/lib/syntax_tree/parser.rb +++ b/lib/syntax_tree/parser.rb @@ -1911,13 +1911,14 @@ def on_ifop(predicate, truthy, falsy) end # :call-seq: - # on_if_mod: (untyped predicate, untyped statement) -> IfMod + # on_if_mod: (untyped predicate, untyped statement) -> If def on_if_mod(predicate, statement) consume_keyword(:if) - IfMod.new( - statement: statement, + If.new( predicate: predicate, + statements: Statements.new(self, body: [statement], location: statement.location), + consequent: nil, location: statement.location.to(predicate.location) ) end @@ -3586,13 +3587,14 @@ def on_unless(predicate, statements, consequent) end # :call-seq: - # on_unless_mod: (untyped predicate, untyped statement) -> UnlessMod + # on_unless_mod: (untyped predicate, untyped statement) -> Unless def on_unless_mod(predicate, statement) consume_keyword(:unless) - UnlessMod.new( - statement: statement, + Unless.new( predicate: predicate, + statements: Statements.new(self, body: [statement], location: statement.location), + consequent: nil, location: statement.location.to(predicate.location) ) end diff --git a/lib/syntax_tree/visitor.rb b/lib/syntax_tree/visitor.rb index e3b52077..0ea83e7b 100644 --- a/lib/syntax_tree/visitor.rb +++ b/lib/syntax_tree/visitor.rb @@ -206,9 +206,6 @@ class Visitor < BasicVisitor # Visit an If node. alias visit_if visit_child_nodes - # Visit an IfMod node. - alias visit_if_mod visit_child_nodes - # Visit an IfOp node. alias visit_if_op visit_child_nodes @@ -431,9 +428,6 @@ class Visitor < BasicVisitor # Visit an Unless node. alias visit_unless visit_child_nodes - # Visit an UnlessMod node. - alias visit_unless_mod visit_child_nodes - # Visit an Until node. alias visit_until visit_child_nodes diff --git a/lib/syntax_tree/visitor/field_visitor.rb b/lib/syntax_tree/visitor/field_visitor.rb index 6c5c6139..aa1b80ab 100644 --- a/lib/syntax_tree/visitor/field_visitor.rb +++ b/lib/syntax_tree/visitor/field_visitor.rb @@ -523,14 +523,6 @@ def visit_if(node) end end - def visit_if_mod(node) - node(node, "if_mod") do - field("statement", node.statement) - field("predicate", node.predicate) - comments(node) - end - end - def visit_if_op(node) node(node, "if_op") do field("predicate", node.predicate) @@ -982,14 +974,6 @@ def visit_unless(node) end end - def visit_unless_mod(node) - node(node, "unless_mod") do - field("statement", node.statement) - field("predicate", node.predicate) - comments(node) - end - end - def visit_until(node) node(node, "until") do field("predicate", node.predicate) diff --git a/test/node_test.rb b/test/node_test.rb index ce26f9ea..8400fa7c 100644 --- a/test/node_test.rb +++ b/test/node_test.rb @@ -583,7 +583,7 @@ def test_if_op end def test_if_mod - assert_node(IfMod, "expression if predicate") + assert_node(If, "expression if predicate") end def test_imaginary @@ -926,10 +926,6 @@ def test_unless assert_node(Unless, "unless value then else end") end - def test_unless_mod - assert_node(UnlessMod, "expression unless predicate") - end - def test_until assert_node(Until, "until value do end") end From b97b9cb03f65a6156657b19b656124a79b276863 Mon Sep 17 00:00:00 2001 From: Kevin Newton Date: Wed, 2 Nov 2022 11:02:50 -0400 Subject: [PATCH 03/17] Fold UntilMod and WhileMod --- CHANGELOG.md | 1 + lib/syntax_tree/node.rb | 226 +++++------------------ lib/syntax_tree/parser.rb | 12 +- lib/syntax_tree/visitor.rb | 6 - lib/syntax_tree/visitor/field_visitor.rb | 16 -- test/node_test.rb | 4 +- 6 files changed, 60 insertions(+), 205 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5d944f7a..faed7811 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a - Nodes no longer have a `comments:` keyword on their initializers. By default, they initialize to an empty array. If you were previously passing comments into the initializer, you should now create the node first, then call `node.comments.concat` to add your comments. - `IfMod` and `UnlessMod` are no longer nodes. Instead, they have been folded into `If` and `Unless`, respectively. The `If` and `Unless` nodes now have a `modifier?` method to tell you if they were original found in the modifier form. +- `WhileMod` and `UntilMod` are no longer nodes. Instead, they have been folded into `While` and `Until`, respectively. The `While` and `Until` nodes now have a `modifier?` method to tell you if they were originally found in the modifier form. ## [4.3.0] - 2022-10-28 diff --git a/lib/syntax_tree/node.rb b/lib/syntax_tree/node.rb index 2f23e9a1..71d5e0d8 100644 --- a/lib/syntax_tree/node.rb +++ b/lib/syntax_tree/node.rb @@ -2071,7 +2071,7 @@ def forced_brace_bounds?(q) when Paren, Statements # If we hit certain breakpoints then we know we're safe. return false - when If, IfOp, Unless, While, WhileMod, Until, UntilMod + when If, IfOp, Unless, While, Until return true if parent.predicate == previous end @@ -5399,8 +5399,8 @@ def ternaryable?(statement) case statement when Alias, Assign, Break, Command, CommandCall, Heredoc, If, IfOp, Lambda, MAssign, Next, OpAssign, RescueMod, Return, Return0, Super, - Undef, Unless, Until, UntilMod, VarAlias, VoidStmt, While, - WhileMod, Yield, Yield0, ZSuper + Undef, Unless, Until, VarAlias, VoidStmt, While, Yield, Yield0, + ZSuper # This is a list of nodes that should not be allowed to be a part of a # ternary clause. false @@ -5674,7 +5674,7 @@ def format(q) force_flat = [ Alias, Assign, Break, Command, CommandCall, Heredoc, If, IfOp, Lambda, MAssign, Next, OpAssign, RescueMod, Return, Return0, Super, Undef, - Unless, UntilMod, VarAlias, VoidStmt, WhileMod, Yield, Yield0, ZSuper + Unless, VarAlias, VoidStmt, Yield, Yield0, ZSuper ] if q.parent.is_a?(Paren) || force_flat.include?(truthy.class) || @@ -9384,40 +9384,60 @@ def modifier? end end - # Formats an Until, UntilMod, While, or WhileMod node. + # Formats an Until or While node. class LoopFormatter # [String] the name of the keyword used for this loop attr_reader :keyword - # [Until | UntilMod | While | WhileMod] the node that is being formatted + # [Until | While] the node that is being formatted attr_reader :node - # [untyped] the statements associated with the node - attr_reader :statements - - def initialize(keyword, node, statements) + def initialize(keyword, node) @keyword = keyword @node = node - @statements = statements end def format(q) - if ContainsAssignment.call(node.predicate) + # If we're in the modifier form and we're modifying a `begin`, then this + # is a special case where we need to explicitly use the modifier form + # because otherwise the semantic meaning changes. This looks like: + # + # begin + # foo + # end while bar + # + # Also, if the statement of the modifier includes an assignment, then we + # can't know for certain that it won't impact the predicate, so we need to + # force it to stay as it is. This looks like: + # + # foo = bar while foo + # + if node.modifier? && (statement = node.statements.body.first) && (statement.is_a?(Begin) || ContainsAssignment.call(statement)) + q.format(statement) + q.text(" #{keyword} ") + q.format(node.predicate) + elsif node.statements.empty? + q.group do + q.text("#{keyword} ") + q.nest(keyword.length + 1) { q.format(node.predicate) } + q.breakable_force + q.text("end") + end + elsif ContainsAssignment.call(node.predicate) format_break(q) q.break_parent - return - end - - q.group do - q - .if_break { format_break(q) } - .if_flat do - Parentheses.flat(q) do - q.format(statements) - q.text(" #{keyword} ") - q.format(node.predicate) + else + q.group do + q + .if_break { format_break(q) } + .if_flat do + Parentheses.flat(q) do + q.format(node.statements) + q.text(" #{keyword} ") + q.format(node.predicate) + end end - end + end end end @@ -9428,7 +9448,7 @@ def format_break(q) q.nest(keyword.length + 1) { q.format(node.predicate) } q.indent do q.breakable_empty - q.format(statements) + q.format(node.statements) end q.breakable_empty q.text("end") @@ -9477,83 +9497,11 @@ def deconstruct_keys(_keys) end def format(q) - if statements.empty? - keyword = "until " - - q.group do - q.text(keyword) - q.nest(keyword.length) { q.format(predicate) } - q.breakable_force - q.text("end") - end - else - LoopFormatter.new("until", self, statements).format(q) - end + LoopFormatter.new("until", self).format(q) end - end - # UntilMod represents the modifier form of a +until+ loop. - # - # expression until predicate - # - class UntilMod < Node - # [untyped] the expression to be executed - attr_reader :statement - - # [untyped] the expression to be checked - attr_reader :predicate - - # [Array[ Comment | EmbDoc ]] the comments attached to this node - attr_reader :comments - - def initialize(statement:, predicate:, location:) - @statement = statement - @predicate = predicate - @location = location - @comments = [] - end - - def accept(visitor) - visitor.visit_until_mod(self) - end - - def child_nodes - [statement, predicate] - end - - alias deconstruct child_nodes - - def deconstruct_keys(_keys) - { - statement: statement, - predicate: predicate, - location: location, - comments: comments - } - end - - def format(q) - # If we're in the modifier form and we're modifying a `begin`, then this - # is a special case where we need to explicitly use the modifier form - # because otherwise the semantic meaning changes. This looks like: - # - # begin - # foo - # end until bar - # - # Also, if the statement of the modifier includes an assignment, then we - # can't know for certain that it won't impact the predicate, so we need to - # force it to stay as it is. This looks like: - # - # foo = bar until foo - # - if statement.is_a?(Begin) || ContainsAssignment.call(statement) - q.format(statement) - q.text(" until ") - q.format(predicate) - else - LoopFormatter.new("until", self, statement).format(q) - end + def modifier? + predicate.location.start_char > statements.location.start_char end end @@ -9976,83 +9924,11 @@ def deconstruct_keys(_keys) end def format(q) - if statements.empty? - keyword = "while " - - q.group do - q.text(keyword) - q.nest(keyword.length) { q.format(predicate) } - q.breakable_force - q.text("end") - end - else - LoopFormatter.new("while", self, statements).format(q) - end - end - end - - # WhileMod represents the modifier form of a +while+ loop. - # - # expression while predicate - # - class WhileMod < Node - # [untyped] the expression to be executed - attr_reader :statement - - # [untyped] the expression to be checked - attr_reader :predicate - - # [Array[ Comment | EmbDoc ]] the comments attached to this node - attr_reader :comments - - def initialize(statement:, predicate:, location:) - @statement = statement - @predicate = predicate - @location = location - @comments = [] - end - - def accept(visitor) - visitor.visit_while_mod(self) - end - - def child_nodes - [statement, predicate] - end - - alias deconstruct child_nodes - - def deconstruct_keys(_keys) - { - statement: statement, - predicate: predicate, - location: location, - comments: comments - } + LoopFormatter.new("while", self).format(q) end - def format(q) - # If we're in the modifier form and we're modifying a `begin`, then this - # is a special case where we need to explicitly use the modifier form - # because otherwise the semantic meaning changes. This looks like: - # - # begin - # foo - # end while bar - # - # Also, if the statement of the modifier includes an assignment, then we - # can't know for certain that it won't impact the predicate, so we need to - # force it to stay as it is. This looks like: - # - # foo = bar while foo - # - if statement.is_a?(Begin) || ContainsAssignment.call(statement) - q.format(statement) - q.text(" while ") - q.format(predicate) - else - LoopFormatter.new("while", self, statement).format(q) - end + def modifier? + predicate.location.start_char > statements.location.start_char end end diff --git a/lib/syntax_tree/parser.rb b/lib/syntax_tree/parser.rb index c4d6f8e9..2b5231d2 100644 --- a/lib/syntax_tree/parser.rb +++ b/lib/syntax_tree/parser.rb @@ -3630,13 +3630,13 @@ def on_until(predicate, statements) end # :call-seq: - # on_until_mod: (untyped predicate, untyped statement) -> UntilMod + # on_until_mod: (untyped predicate, untyped statement) -> Until def on_until_mod(predicate, statement) consume_keyword(:until) - UntilMod.new( - statement: statement, + Until.new( predicate: predicate, + statements: Statements.new(self, body: [statement], location: statement.location), location: statement.location.to(predicate.location) ) end @@ -3756,13 +3756,13 @@ def on_while(predicate, statements) end # :call-seq: - # on_while_mod: (untyped predicate, untyped statement) -> WhileMod + # on_while_mod: (untyped predicate, untyped statement) -> While def on_while_mod(predicate, statement) consume_keyword(:while) - WhileMod.new( - statement: statement, + While.new( predicate: predicate, + statements: Statements.new(self, body: [statement], location: statement.location), location: statement.location.to(predicate.location) ) end diff --git a/lib/syntax_tree/visitor.rb b/lib/syntax_tree/visitor.rb index 0ea83e7b..efbd47c0 100644 --- a/lib/syntax_tree/visitor.rb +++ b/lib/syntax_tree/visitor.rb @@ -431,9 +431,6 @@ class Visitor < BasicVisitor # Visit an Until node. alias visit_until visit_child_nodes - # Visit an UntilMod node. - alias visit_until_mod visit_child_nodes - # Visit a VarAlias node. alias visit_var_alias visit_child_nodes @@ -455,9 +452,6 @@ class Visitor < BasicVisitor # Visit a While node. alias visit_while visit_child_nodes - # Visit a WhileMod node. - alias visit_while_mod visit_child_nodes - # Visit a Word node. alias visit_word visit_child_nodes diff --git a/lib/syntax_tree/visitor/field_visitor.rb b/lib/syntax_tree/visitor/field_visitor.rb index aa1b80ab..853fe4c7 100644 --- a/lib/syntax_tree/visitor/field_visitor.rb +++ b/lib/syntax_tree/visitor/field_visitor.rb @@ -982,14 +982,6 @@ def visit_until(node) end end - def visit_until_mod(node) - node(node, "until_mod") do - field("statement", node.statement) - field("predicate", node.predicate) - comments(node) - end - end - def visit_var_alias(node) node(node, "var_alias") do field("left", node.left) @@ -1040,14 +1032,6 @@ def visit_while(node) end end - def visit_while_mod(node) - node(node, "while_mod") do - field("statement", node.statement) - field("predicate", node.predicate) - comments(node) - end - end - def visit_word(node) node(node, "word") do list("parts", node.parts) diff --git a/test/node_test.rb b/test/node_test.rb index 8400fa7c..1419e151 100644 --- a/test/node_test.rb +++ b/test/node_test.rb @@ -931,7 +931,7 @@ def test_until end def test_until_mod - assert_node(UntilMod, "expression until predicate") + assert_node(Until, "expression until predicate") end def test_var_alias @@ -981,7 +981,7 @@ def test_while end def test_while_mod - assert_node(WhileMod, "expression while predicate") + assert_node(While, "expression while predicate") end def test_word From 672abb2d6c86f1a0ac2a8b04743dfdda0bd3b7ad Mon Sep 17 00:00:00 2001 From: Kevin Newton Date: Wed, 2 Nov 2022 11:06:58 -0400 Subject: [PATCH 04/17] Fold VarAlias into Alias --- CHANGELOG.md | 1 + lib/syntax_tree/node.rb | 61 ++++-------------------- lib/syntax_tree/parser.rb | 4 +- lib/syntax_tree/visitor.rb | 3 -- lib/syntax_tree/visitor/field_visitor.rb | 8 ---- test/node_test.rb | 2 +- 6 files changed, 13 insertions(+), 66 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index faed7811..e04aaa18 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a - Nodes no longer have a `comments:` keyword on their initializers. By default, they initialize to an empty array. If you were previously passing comments into the initializer, you should now create the node first, then call `node.comments.concat` to add your comments. - `IfMod` and `UnlessMod` are no longer nodes. Instead, they have been folded into `If` and `Unless`, respectively. The `If` and `Unless` nodes now have a `modifier?` method to tell you if they were original found in the modifier form. - `WhileMod` and `UntilMod` are no longer nodes. Instead, they have been folded into `While` and `Until`, respectively. The `While` and `Until` nodes now have a `modifier?` method to tell you if they were originally found in the modifier form. +- `VarAlias` is no longer a node. Instead it has been folded into the `Alias` node. The `Alias` node now has a `var_alias?` method to tell you if it is aliasing a global variable. ## [4.3.0] - 2022-10-28 diff --git a/lib/syntax_tree/node.rb b/lib/syntax_tree/node.rb index 71d5e0d8..1c69026b 100644 --- a/lib/syntax_tree/node.rb +++ b/lib/syntax_tree/node.rb @@ -359,7 +359,7 @@ class Alias < Node # Formats an argument to the alias keyword. For symbol literals it uses the # value of the symbol directly to look like bare words. class AliasArgumentFormatter - # [DynaSymbol | SymbolLiteral] the argument being passed to alias + # [Backref | DynaSymbol | GVar | SymbolLiteral] the argument being passed to alias attr_reader :argument def initialize(argument) @@ -383,10 +383,10 @@ def format(q) end end - # [DynaSymbol | SymbolLiteral] the new name of the method + # [DynaSymbol | GVar | SymbolLiteral] the new name of the method attr_reader :left - # [DynaSymbol | SymbolLiteral] the old name of the method + # [Backref | DynaSymbol | GVar | SymbolLiteral] the old name of the method attr_reader :right # [Array[ Comment | EmbDoc ]] the comments attached to this node @@ -428,6 +428,10 @@ def format(q) end end end + + def var_alias? + left.is_a?(GVar) + end end # ARef represents when you're pulling a value out of a collection at a @@ -5399,8 +5403,7 @@ def ternaryable?(statement) case statement when Alias, Assign, Break, Command, CommandCall, Heredoc, If, IfOp, Lambda, MAssign, Next, OpAssign, RescueMod, Return, Return0, Super, - Undef, Unless, Until, VarAlias, VoidStmt, While, Yield, Yield0, - ZSuper + Undef, Unless, Until, VoidStmt, While, Yield, Yield0, ZSuper # This is a list of nodes that should not be allowed to be a part of a # ternary clause. false @@ -5674,7 +5677,7 @@ def format(q) force_flat = [ Alias, Assign, Break, Command, CommandCall, Heredoc, If, IfOp, Lambda, MAssign, Next, OpAssign, RescueMod, Return, Return0, Super, Undef, - Unless, VarAlias, VoidStmt, Yield, Yield0, ZSuper + Unless, VoidStmt, Yield, Yield0, ZSuper ] if q.parent.is_a?(Paren) || force_flat.include?(truthy.class) || @@ -9505,52 +9508,6 @@ def modifier? end end - # VarAlias represents when you're using the +alias+ keyword with global - # variable arguments. - # - # alias $new $old - # - class VarAlias < Node - # [GVar] the new alias of the variable - attr_reader :left - - # [Backref | GVar] the current name of the variable to be aliased - attr_reader :right - - # [Array[ Comment | EmbDoc ]] the comments attached to this node - attr_reader :comments - - def initialize(left:, right:, location:) - @left = left - @right = right - @location = location - @comments = [] - end - - def accept(visitor) - visitor.visit_var_alias(self) - end - - def child_nodes - [left, right] - end - - alias deconstruct child_nodes - - def deconstruct_keys(_keys) - { left: left, right: right, location: location, comments: comments } - end - - def format(q) - keyword = "alias " - - q.text(keyword) - q.format(left) - q.text(" ") - q.format(right) - end - end - # VarField represents a variable that is being assigned a value. As such, it # is always a child of an assignment type node. # diff --git a/lib/syntax_tree/parser.rb b/lib/syntax_tree/parser.rb index 2b5231d2..a28bb296 100644 --- a/lib/syntax_tree/parser.rb +++ b/lib/syntax_tree/parser.rb @@ -3642,11 +3642,11 @@ def on_until_mod(predicate, statement) end # :call-seq: - # on_var_alias: (GVar left, (Backref | GVar) right) -> VarAlias + # on_var_alias: (GVar left, (Backref | GVar) right) -> Alias def on_var_alias(left, right) keyword = consume_keyword(:alias) - VarAlias.new( + Alias.new( left: left, right: right, location: keyword.location.to(right.location) diff --git a/lib/syntax_tree/visitor.rb b/lib/syntax_tree/visitor.rb index efbd47c0..06fa7e17 100644 --- a/lib/syntax_tree/visitor.rb +++ b/lib/syntax_tree/visitor.rb @@ -431,9 +431,6 @@ class Visitor < BasicVisitor # Visit an Until node. alias visit_until visit_child_nodes - # Visit a VarAlias node. - alias visit_var_alias visit_child_nodes - # Visit a VarField node. alias visit_var_field visit_child_nodes diff --git a/lib/syntax_tree/visitor/field_visitor.rb b/lib/syntax_tree/visitor/field_visitor.rb index 853fe4c7..c5b00c50 100644 --- a/lib/syntax_tree/visitor/field_visitor.rb +++ b/lib/syntax_tree/visitor/field_visitor.rb @@ -982,14 +982,6 @@ def visit_until(node) end end - def visit_var_alias(node) - node(node, "var_alias") do - field("left", node.left) - field("right", node.right) - comments(node) - end - end - def visit_var_field(node) node(node, "var_field") do field("value", node.value) diff --git a/test/node_test.rb b/test/node_test.rb index 1419e151..05ae2254 100644 --- a/test/node_test.rb +++ b/test/node_test.rb @@ -935,7 +935,7 @@ def test_until_mod end def test_var_alias - assert_node(VarAlias, "alias $new $old") + assert_node(Alias, "alias $new $old") end def test_var_field From 7f04f53fd2c0a7f24c404dc10b9b0302adf01f18 Mon Sep 17 00:00:00 2001 From: Kevin Newton Date: Wed, 2 Nov 2022 11:10:01 -0400 Subject: [PATCH 05/17] Fold Yield0 into Yield --- CHANGELOG.md | 1 + lib/syntax_tree/node.rb | 47 ++++-------------------- lib/syntax_tree/parser.rb | 4 +- lib/syntax_tree/visitor.rb | 3 -- lib/syntax_tree/visitor/field_visitor.rb | 4 -- test/node_test.rb | 2 +- 6 files changed, 12 insertions(+), 49 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e04aaa18..148da6f8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a - `IfMod` and `UnlessMod` are no longer nodes. Instead, they have been folded into `If` and `Unless`, respectively. The `If` and `Unless` nodes now have a `modifier?` method to tell you if they were original found in the modifier form. - `WhileMod` and `UntilMod` are no longer nodes. Instead, they have been folded into `While` and `Until`, respectively. The `While` and `Until` nodes now have a `modifier?` method to tell you if they were originally found in the modifier form. - `VarAlias` is no longer a node. Instead it has been folded into the `Alias` node. The `Alias` node now has a `var_alias?` method to tell you if it is aliasing a global variable. +- `Yield0` is no longer a node. Instead if has been folded into the `Yield` node. The `Yield` node can now have its `arguments` field be `nil`. ## [4.3.0] - 2022-10-28 diff --git a/lib/syntax_tree/node.rb b/lib/syntax_tree/node.rb index 1c69026b..7d4cb414 100644 --- a/lib/syntax_tree/node.rb +++ b/lib/syntax_tree/node.rb @@ -5403,7 +5403,7 @@ def ternaryable?(statement) case statement when Alias, Assign, Break, Command, CommandCall, Heredoc, If, IfOp, Lambda, MAssign, Next, OpAssign, RescueMod, Return, Return0, Super, - Undef, Unless, Until, VoidStmt, While, Yield, Yield0, ZSuper + Undef, Unless, Until, VoidStmt, While, Yield, ZSuper # This is a list of nodes that should not be allowed to be a part of a # ternary clause. false @@ -5677,7 +5677,7 @@ def format(q) force_flat = [ Alias, Assign, Break, Command, CommandCall, Heredoc, If, IfOp, Lambda, MAssign, Next, OpAssign, RescueMod, Return, Return0, Super, Undef, - Unless, VoidStmt, Yield, Yield0, ZSuper + Unless, VoidStmt, Yield, ZSuper ] if q.parent.is_a?(Paren) || force_flat.include?(truthy.class) || @@ -10101,7 +10101,7 @@ def format(q) # yield value # class Yield < Node - # [Args | Paren] the arguments passed to the yield + # [nil | Args | Paren] the arguments passed to the yield attr_reader :arguments # [Array[ Comment | EmbDoc ]] the comments attached to this node @@ -10128,6 +10128,11 @@ def deconstruct_keys(_keys) end def format(q) + if arguments.nil? + q.text("yield") + return + end + q.group do q.text("yield") @@ -10146,42 +10151,6 @@ def format(q) end end - # Yield0 represents the bare +yield+ keyword with no arguments. - # - # yield - # - class Yield0 < Node - # [String] the value of the keyword - attr_reader :value - - # [Array[ Comment | EmbDoc ]] the comments attached to this node - attr_reader :comments - - def initialize(value:, location:) - @value = value - @location = location - @comments = [] - end - - def accept(visitor) - visitor.visit_yield0(self) - end - - def child_nodes - [] - end - - alias deconstruct child_nodes - - def deconstruct_keys(_keys) - { value: value, location: location, comments: comments } - end - - def format(q) - q.text(value) - end - end - # ZSuper represents the bare +super+ keyword with no arguments. # # super diff --git a/lib/syntax_tree/parser.rb b/lib/syntax_tree/parser.rb index a28bb296..56cba022 100644 --- a/lib/syntax_tree/parser.rb +++ b/lib/syntax_tree/parser.rb @@ -3896,11 +3896,11 @@ def on_yield(arguments) end # :call-seq: - # on_yield0: () -> Yield0 + # on_yield0: () -> Yield def on_yield0 keyword = consume_keyword(:yield) - Yield0.new(value: keyword.value, location: keyword.location) + Yield.new(arguments: nil, location: keyword.location) end # :call-seq: diff --git a/lib/syntax_tree/visitor.rb b/lib/syntax_tree/visitor.rb index 06fa7e17..a41a3ed7 100644 --- a/lib/syntax_tree/visitor.rb +++ b/lib/syntax_tree/visitor.rb @@ -467,9 +467,6 @@ class Visitor < BasicVisitor # Visit a Yield node. alias visit_yield visit_child_nodes - # Visit a Yield0 node. - alias visit_yield0 visit_child_nodes - # Visit a ZSuper node. alias visit_zsuper visit_child_nodes diff --git a/lib/syntax_tree/visitor/field_visitor.rb b/lib/syntax_tree/visitor/field_visitor.rb index c5b00c50..52dca6f9 100644 --- a/lib/syntax_tree/visitor/field_visitor.rb +++ b/lib/syntax_tree/visitor/field_visitor.rb @@ -1060,10 +1060,6 @@ def visit_yield(node) end end - def visit_yield0(node) - visit_token(node, "yield0") - end - def visit_zsuper(node) visit_token(node, "zsuper") end diff --git a/test/node_test.rb b/test/node_test.rb index 05ae2254..608c7fbe 100644 --- a/test/node_test.rb +++ b/test/node_test.rb @@ -1013,7 +1013,7 @@ def test_yield end def test_yield0 - assert_node(Yield0, "yield") + assert_node(Yield, "yield") end def test_zsuper From 5f64ba7c0b38bfe7e01df913a011c56ec95d0c4a Mon Sep 17 00:00:00 2001 From: Kevin Newton Date: Wed, 2 Nov 2022 11:19:51 -0400 Subject: [PATCH 06/17] Fold FCall into Call --- CHANGELOG.md | 1 + lib/syntax_tree/node.rb | 101 ++++++++++--------------------------- lib/syntax_tree/parser.rb | 28 +++++----- lib/syntax_tree/visitor.rb | 3 -- test/node_test.rb | 2 +- 5 files changed, 41 insertions(+), 94 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 148da6f8..fbae9d38 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a - `WhileMod` and `UntilMod` are no longer nodes. Instead, they have been folded into `While` and `Until`, respectively. The `While` and `Until` nodes now have a `modifier?` method to tell you if they were originally found in the modifier form. - `VarAlias` is no longer a node. Instead it has been folded into the `Alias` node. The `Alias` node now has a `var_alias?` method to tell you if it is aliasing a global variable. - `Yield0` is no longer a node. Instead if has been folded into the `Yield` node. The `Yield` node can now have its `arguments` field be `nil`. +- `FCall` is no longer a node. Instead it has been folded into the `Call` node. The `Call` node can now have its `receiver` and `operator` fields be `nil`. ## [4.3.0] - 2022-10-28 diff --git a/lib/syntax_tree/node.rb b/lib/syntax_tree/node.rb index 7d4cb414..0277d8b1 100644 --- a/lib/syntax_tree/node.rb +++ b/lib/syntax_tree/node.rb @@ -2484,8 +2484,7 @@ def format(q) # nodes. parent = parents[3] if parent.is_a?(DoBlock) - if parent.is_a?(MethodAddBlock) && parent.call.is_a?(FCall) && - parent.call.value.value == "sig" + if parent.is_a?(MethodAddBlock) && parent.call.is_a?(Call) && parent.call.message.value == "sig" threshold = 2 end end @@ -2647,10 +2646,10 @@ def format_child( # receiver.message # class Call < Node - # [untyped] the receiver of the method call + # [nil | untyped] the receiver of the method call attr_reader :receiver - # [:"::" | Op | Period] the operator being used to send the message + # [nil | :"::" | Op | Period] the operator being used to send the message attr_reader :operator # [:call | Backtick | Const | Ident | Op] the message being sent @@ -2705,23 +2704,35 @@ def deconstruct_keys(_keys) end def format(q) - # If we're at the top of a call chain, then we're going to do some - # specialized printing in case we can print it nicely. We _only_ do this - # at the top of the chain to avoid weird recursion issues. - if CallChainFormatter.chained?(receiver) && - !CallChainFormatter.chained?(q.parent) - q.group do - q - .if_break { CallChainFormatter.new(self).format(q) } - .if_flat { format_contents(q) } + if receiver + # If we're at the top of a call chain, then we're going to do some + # specialized printing in case we can print it nicely. We _only_ do this + # at the top of the chain to avoid weird recursion issues. + if CallChainFormatter.chained?(receiver) && !CallChainFormatter.chained?(q.parent) + q.group do + q + .if_break { CallChainFormatter.new(self).format(q) } + .if_flat { format_contents(q) } + end + else + format_contents(q) end else - format_contents(q) + q.format(message) + + if arguments.is_a?(ArgParen) && arguments.arguments.nil? && !message.is_a?(Const) + # If you're using an explicit set of parentheses on something that looks + # like a constant, then we need to match that in order to maintain valid + # Ruby. For example, you could do something like Foo(), on which we + # would need to keep the parentheses to make it look like a method call. + else + q.format(arguments) + end end end # Print out the arguments to this call. If there are no arguments, then do - #nothing. + # nothing. def format_arguments(q) case arguments when ArgParen @@ -4518,64 +4529,6 @@ def format(q) end end - # FCall represents the piece of a method call that comes before any arguments - # (i.e., just the name of the method). It is used in places where the parser - # is sure that it is a method call and not potentially a local variable. - # - # method(argument) - # - # In the above example, it's referring to the +method+ segment. - class FCall < Node - # [Const | Ident] the name of the method - attr_reader :value - - # [nil | ArgParen | Args] the arguments to the method call - attr_reader :arguments - - # [Array[ Comment | EmbDoc ]] the comments attached to this node - attr_reader :comments - - def initialize(value:, arguments:, location:) - @value = value - @arguments = arguments - @location = location - @comments = [] - end - - def accept(visitor) - visitor.visit_fcall(self) - end - - def child_nodes - [value, arguments] - end - - alias deconstruct child_nodes - - def deconstruct_keys(_keys) - { - value: value, - arguments: arguments, - location: location, - comments: comments - } - end - - def format(q) - q.format(value) - - if arguments.is_a?(ArgParen) && arguments.arguments.nil? && - !value.is_a?(Const) - # If you're using an explicit set of parentheses on something that looks - # like a constant, then we need to match that in order to maintain valid - # Ruby. For example, you could do something like Foo(), on which we - # would need to keep the parentheses to make it look like a method call. - else - q.format(arguments) - end - end - end - # Field is always the child of an assignment. It represents assigning to a # “field” on an object. # @@ -6396,7 +6349,7 @@ def format(q) # method {} # class MethodAddBlock < Node - # [Call | Command | CommandCall | FCall] the method call + # [Call | Command | CommandCall] the method call attr_reader :call # [BraceBlock | DoBlock] the block being sent with the method call diff --git a/lib/syntax_tree/parser.rb b/lib/syntax_tree/parser.rb index 56cba022..7fa02c67 100644 --- a/lib/syntax_tree/parser.rb +++ b/lib/syntax_tree/parser.rb @@ -1608,9 +1608,9 @@ def on_excessed_comma(*) end # :call-seq: - # on_fcall: ((Const | Ident) value) -> FCall + # on_fcall: ((Const | Ident) value) -> Call def on_fcall(value) - FCall.new(value: value, arguments: nil, location: value.location) + Call.new(receiver: nil, operator: nil, message: value, arguments: nil, location: value.location) end # :call-seq: @@ -2305,29 +2305,25 @@ def on_massign(target, value) # :call-seq: # on_method_add_arg: ( - # (Call | FCall) call, + # Call call, # (ArgParen | Args) arguments - # ) -> Call | FCall + # ) -> Call def on_method_add_arg(call, arguments) location = call.location location = location.to(arguments.location) if arguments.is_a?(ArgParen) - if call.is_a?(FCall) - FCall.new(value: call.value, arguments: arguments, location: location) - else - Call.new( - receiver: call.receiver, - operator: call.operator, - message: call.message, - arguments: arguments, - location: location - ) - end + Call.new( + receiver: call.receiver, + operator: call.operator, + message: call.message, + arguments: arguments, + location: location + ) end # :call-seq: # on_method_add_block: ( - # (Call | Command | CommandCall | FCall) call, + # (Call | Command | CommandCall) call, # (BraceBlock | DoBlock) block # ) -> MethodAddBlock def on_method_add_block(call, block) diff --git a/lib/syntax_tree/visitor.rb b/lib/syntax_tree/visitor.rb index a41a3ed7..3b652f89 100644 --- a/lib/syntax_tree/visitor.rb +++ b/lib/syntax_tree/visitor.rb @@ -167,9 +167,6 @@ class Visitor < BasicVisitor # Visit an ExcessedComma node. alias visit_excessed_comma visit_child_nodes - # Visit a FCall node. - alias visit_fcall visit_child_nodes - # Visit a Field node. alias visit_field visit_child_nodes diff --git a/test/node_test.rb b/test/node_test.rb index 608c7fbe..69c147c3 100644 --- a/test/node_test.rb +++ b/test/node_test.rb @@ -487,7 +487,7 @@ def test_excessed_comma end def test_fcall - assert_node(FCall, "method(argument)") + assert_node(Call, "method(argument)") end def test_field From 087350aa095d04b9595b761a7eaaa2d7349300e3 Mon Sep 17 00:00:00 2001 From: Kevin Newton Date: Wed, 2 Nov 2022 11:32:38 -0400 Subject: [PATCH 07/17] Fold Dot2 and Dot3 into RangeLiteral --- CHANGELOG.md | 11 +-- lib/syntax_tree/node.rb | 103 +++++------------------ lib/syntax_tree/parser.rb | 10 ++- lib/syntax_tree/visitor.rb | 9 +- lib/syntax_tree/visitor/field_visitor.rb | 25 ++---- test/node_test.rb | 4 +- 6 files changed, 45 insertions(+), 117 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fbae9d38..25bb7891 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,11 +9,12 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a ### Changed - Nodes no longer have a `comments:` keyword on their initializers. By default, they initialize to an empty array. If you were previously passing comments into the initializer, you should now create the node first, then call `node.comments.concat` to add your comments. -- `IfMod` and `UnlessMod` are no longer nodes. Instead, they have been folded into `If` and `Unless`, respectively. The `If` and `Unless` nodes now have a `modifier?` method to tell you if they were original found in the modifier form. -- `WhileMod` and `UntilMod` are no longer nodes. Instead, they have been folded into `While` and `Until`, respectively. The `While` and `Until` nodes now have a `modifier?` method to tell you if they were originally found in the modifier form. -- `VarAlias` is no longer a node. Instead it has been folded into the `Alias` node. The `Alias` node now has a `var_alias?` method to tell you if it is aliasing a global variable. -- `Yield0` is no longer a node. Instead if has been folded into the `Yield` node. The `Yield` node can now have its `arguments` field be `nil`. -- `FCall` is no longer a node. Instead it has been folded into the `Call` node. The `Call` node can now have its `receiver` and `operator` fields be `nil`. +- A lot of nodes have been folded into other nodes to make it easier to interact with the AST. This means that a lot of visit methods have been removed from the visitor and a lot of class definitions are no longer present. This also means that the nodes that received more function now have additional methods or fields to be able to differentiate them. Note that none of these changes have resulted in different formatting. The changes are listed below: + - `IfMod`, `UnlessMod`, `WhileMod`, `UntilMod` have been folded into `If`, `Unless`, `While`, and `Until`. Each of the nodes now have a `modifier?` method to tell if it was originally in the modifier form. Consequently, the `visit_if_mod`, `visit_unless_mod`, `visit_while_mod`, and `visit_until_mod` methods have been removed from the visitor. + - `VarAlias` is no longer a node. Instead it has been folded into the `Alias` node. The `Alias` node now has a `var_alias?` method to tell you if it is aliasing a global variable. Consequently, the `visit_var_alias` method has been removed from the visitor interface. If you were previously using this method, you should now use `visit_alias` instead. + - `Yield0` is no longer a node. Instead if has been folded into the `Yield` node. The `Yield` node can now have its `arguments` field be `nil`. Consequently, the `visit_yield0` method has been removed from the visitor interface. If you were previously using this method, you should now use `visit_yield` instead. + - `FCall` is no longer a node. Instead it has been folded into the `Call` node. The `Call` node can now have its `receiver` and `operator` fields be `nil`. Consequently, the `visit_fcall` method has been removed from the visitor interface. If you were previously using this method, you should now use `visit_call` instead. + - `Dot2` and `Dot3` are no longer nodes. Instead they have become a single new `RangeLiteral` node. This node looks the same as `Dot2` and `Dot3`, except that it additionally has an `operator` field that contains the operator that created the node. Consequently, the `visit_dot2` and `visit_dot3` methods have been removed from the visitor interface. If you were previously using these methods, you should now use `visit_range_literal` instead. ## [4.3.0] - 2022-10-28 diff --git a/lib/syntax_tree/node.rb b/lib/syntax_tree/node.rb index 0277d8b1..8f3892e1 100644 --- a/lib/syntax_tree/node.rb +++ b/lib/syntax_tree/node.rb @@ -3878,38 +3878,8 @@ def format(q) end end - # Responsible for formatting Dot2 and Dot3 nodes. - class DotFormatter - # [String] the operator to display - attr_reader :operator - - # [Dot2 | Dot3] the node that is being formatter - attr_reader :node - - def initialize(operator, node) - @operator = operator - @node = node - end - - def format(q) - left = node.left - right = node.right - - q.format(left) if left - - case q.parent - when If, Unless - q.text(" #{operator} ") - else - q.text(operator) - end - - q.format(right) if right - end - end - - # Dot2 represents using the .. operator between two expressions. Usually this - # is to create a range object. + # RangeLiteral represents using the .. or the ... operator between two + # expressions. Usually this is to create a range object. # # 1..2 # @@ -3919,25 +3889,29 @@ def format(q) # end # # One of the sides of the expression may be nil, but not both. - class Dot2 < Node + class RangeLiteral < Node # [nil | untyped] the left side of the expression attr_reader :left + # [Op] the operator used for this range + attr_reader :operator + # [nil | untyped] the right side of the expression attr_reader :right # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(left:, right:, location:) + def initialize(left:, operator:, right:, location:) @left = left + @operator = operator @right = right @location = location @comments = [] end def accept(visitor) - visitor.visit_dot2(self) + visitor.visit_range_literal(self) end def child_nodes @@ -3947,59 +3921,20 @@ def child_nodes alias deconstruct child_nodes def deconstruct_keys(_keys) - { left: left, right: right, location: location, comments: comments } + { left: left, operator: operator, right: right, location: location, comments: comments } end def format(q) - DotFormatter.new("..", self).format(q) - end - end - - # Dot3 represents using the ... operator between two expressions. Usually this - # is to create a range object. It's effectively the same event as the Dot2 - # node but with this operator you're asking Ruby to omit the final value. - # - # 1...2 - # - # Like Dot2 it can also be used to create a flip-flop. - # - # if value == 5 ... value == 10 - # end - # - # One of the sides of the expression may be nil, but not both. - class Dot3 < Node - # [nil | untyped] the left side of the expression - attr_reader :left - - # [nil | untyped] the right side of the expression - attr_reader :right - - # [Array[ Comment | EmbDoc ]] the comments attached to this node - attr_reader :comments - - def initialize(left:, right:, location:) - @left = left - @right = right - @location = location - @comments = [] - end - - def accept(visitor) - visitor.visit_dot3(self) - end - - def child_nodes - [left, right] - end - - alias deconstruct child_nodes + q.format(left) if left - def deconstruct_keys(_keys) - { left: left, right: right, location: location, comments: comments } - end + case q.parent + when If, Unless + q.text(" #{operator.value} ") + else + q.text(operator.value) + end - def format(q) - DotFormatter.new("...", self).format(q) + q.format(right) if right end end @@ -9771,7 +9706,7 @@ def format(q) # last argument to the predicate is and endless range, then you are # forced to use the "then" keyword to make it parse properly. last = arguments.parts.last - if (last.is_a?(Dot2) || last.is_a?(Dot3)) && !last.right + if last.is_a?(RangeLiteral) && !last.right q.text(" then") end end diff --git a/lib/syntax_tree/parser.rb b/lib/syntax_tree/parser.rb index 7fa02c67..4bc0bb6f 100644 --- a/lib/syntax_tree/parser.rb +++ b/lib/syntax_tree/parser.rb @@ -1357,30 +1357,32 @@ def on_do_block(block_var, bodystmt) end # :call-seq: - # on_dot2: ((nil | untyped) left, (nil | untyped) right) -> Dot2 + # on_dot2: ((nil | untyped) left, (nil | untyped) right) -> RangeLiteral def on_dot2(left, right) operator = consume_operator(:"..") beginning = left || operator ending = right || operator - Dot2.new( + RangeLiteral.new( left: left, + operator: operator, right: right, location: beginning.location.to(ending.location) ) end # :call-seq: - # on_dot3: ((nil | untyped) left, (nil | untyped) right) -> Dot3 + # on_dot3: ((nil | untyped) left, (nil | untyped) right) -> RangeLiteral def on_dot3(left, right) operator = consume_operator(:"...") beginning = left || operator ending = right || operator - Dot3.new( + RangeLiteral.new( left: left, + operator: operator, right: right, location: beginning.location.to(ending.location) ) diff --git a/lib/syntax_tree/visitor.rb b/lib/syntax_tree/visitor.rb index 3b652f89..ad4757d7 100644 --- a/lib/syntax_tree/visitor.rb +++ b/lib/syntax_tree/visitor.rb @@ -131,12 +131,6 @@ class Visitor < BasicVisitor # Visit a DoBlock node. alias visit_do_block visit_child_nodes - # Visit a Dot2 node. - alias visit_dot2 visit_child_nodes - - # Visit a Dot3 node. - alias visit_dot3 visit_child_nodes - # Visit a DynaSymbol node. alias visit_dyna_symbol visit_child_nodes @@ -305,6 +299,9 @@ class Visitor < BasicVisitor # Visit a QWordsBeg node. alias visit_qwords_beg visit_child_nodes + # Visit a RangeLiteral node + alias visit_range_literal visit_child_nodes + # Visit a RAssign node. alias visit_rassign visit_child_nodes diff --git a/lib/syntax_tree/visitor/field_visitor.rb b/lib/syntax_tree/visitor/field_visitor.rb index 52dca6f9..ac7b3603 100644 --- a/lib/syntax_tree/visitor/field_visitor.rb +++ b/lib/syntax_tree/visitor/field_visitor.rb @@ -362,22 +362,6 @@ def visit_do_block(node) end end - def visit_dot2(node) - node(node, "dot2") do - field("left", node.left) if node.left - field("right", node.right) if node.right - comments(node) - end - end - - def visit_dot3(node) - node(node, "dot3") do - field("left", node.left) if node.left - field("right", node.right) if node.right - comments(node) - end - end - def visit_dyna_symbol(node) node(node, "dyna_symbol") do list("parts", node.parts) @@ -739,6 +723,15 @@ def visit_qwords_beg(node) node(node, "qwords_beg") { field("value", node.value) } end + def visit_range_literal(node) + node(node, "range_literal") do + field("left", node.left) if node.left + field("operator", node.operator) + field("right", node.right) if node.right + comments(node) + end + end + def visit_rassign(node) node(node, "rassign") do field("value", node.value) diff --git a/test/node_test.rb b/test/node_test.rb index 69c147c3..d27c0d5f 100644 --- a/test/node_test.rb +++ b/test/node_test.rb @@ -414,11 +414,11 @@ def test_do_block end def test_dot2 - assert_node(Dot2, "1..3") + assert_node(RangeLiteral, "1..3") end def test_dot3 - assert_node(Dot3, "1...3") + assert_node(RangeLiteral, "1...3") end def test_dyna_symbol From a99d08124ade363c0b9371897918e0ded74f42c3 Mon Sep 17 00:00:00 2001 From: Kevin Newton Date: Wed, 2 Nov 2022 12:02:42 -0400 Subject: [PATCH 08/17] Fold DefEndless into Def and Defs nodes --- CHANGELOG.md | 1 + lib/syntax_tree/node.rb | 171 +++++++------------- lib/syntax_tree/parser.rb | 16 +- lib/syntax_tree/visitor.rb | 3 - lib/syntax_tree/visitor/field_visitor.rb | 14 -- lib/syntax_tree/visitor/with_environment.rb | 4 - test/fixtures/def_endless.rb | 4 - test/node_test.rb | 4 +- 8 files changed, 70 insertions(+), 147 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 25bb7891..67b4e150 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a - `Yield0` is no longer a node. Instead if has been folded into the `Yield` node. The `Yield` node can now have its `arguments` field be `nil`. Consequently, the `visit_yield0` method has been removed from the visitor interface. If you were previously using this method, you should now use `visit_yield` instead. - `FCall` is no longer a node. Instead it has been folded into the `Call` node. The `Call` node can now have its `receiver` and `operator` fields be `nil`. Consequently, the `visit_fcall` method has been removed from the visitor interface. If you were previously using this method, you should now use `visit_call` instead. - `Dot2` and `Dot3` are no longer nodes. Instead they have become a single new `RangeLiteral` node. This node looks the same as `Dot2` and `Dot3`, except that it additionally has an `operator` field that contains the operator that created the node. Consequently, the `visit_dot2` and `visit_dot3` methods have been removed from the visitor interface. If you were previously using these methods, you should now use `visit_range_literal` instead. + - `DefEndless` has been folded into the `Def` and `Defs` nodes. ## [4.3.0] - 2022-10-28 diff --git a/lib/syntax_tree/node.rb b/lib/syntax_tree/node.rb index 8f3892e1..ebfcc336 100644 --- a/lib/syntax_tree/node.rb +++ b/lib/syntax_tree/node.rb @@ -3108,7 +3108,7 @@ def align(q, node, &block) part = parts.first case part - when Def, Defs, DefEndless + when Def, Defs q.text(" ") yield when IfOp @@ -3540,10 +3540,10 @@ class Def < Node # [Backtick | Const | Ident | Kw | Op] the name of the method attr_reader :name - # [Params | Paren] the parameter declaration for the method + # [nil | Params | Paren] the parameter declaration for the method attr_reader :params - # [BodyStmt] the expressions to be executed by the method + # [BodyStmt | untyped] the expressions to be executed by the method attr_reader :bodystmt # [Array[ Comment | EmbDoc ]] the comments attached to this node @@ -3583,112 +3583,41 @@ def format(q) q.text("def ") q.format(name) - if !params.is_a?(Params) || !params.empty? || params.comments.any? + case params + when Paren q.format(params) + when Params + q.format(params) if !params.empty? || params.comments.any? end end - unless bodystmt.empty? - q.indent do - q.breakable_force - q.format(bodystmt) + if endless? + q.text(" =") + q.group do + q.indent do + q.breakable_space + q.format(bodystmt) + end + end + else + unless bodystmt.empty? + q.indent do + q.breakable_force + q.format(bodystmt) + end end - end - q.breakable_force - q.text("end") + q.breakable_force + q.text("end") + end end end - end - - # DefEndless represents defining a single-line method since Ruby 3.0+. - # - # def method = result - # - class DefEndless < Node - # [untyped] the target where the method is being defined - attr_reader :target - - # [Op | Period] the operator being used to declare the method - attr_reader :operator - - # [Backtick | Const | Ident | Kw | Op] the name of the method - attr_reader :name - - # [nil | Params | Paren] the parameter declaration for the method - attr_reader :paren - - # [untyped] the expression to be executed by the method - attr_reader :statement - - # [Array[ Comment | EmbDoc ]] the comments attached to this node - attr_reader :comments - - def initialize( - target:, - operator:, - name:, - paren:, - statement:, - location:, - comments: [] - ) - @target = target - @operator = operator - @name = name - @paren = paren - @statement = statement - @location = location - @comments = [] - end - - def accept(visitor) - visitor.visit_def_endless(self) - end - def child_nodes - [target, operator, name, paren, statement] - end - - alias deconstruct child_nodes - - def deconstruct_keys(_keys) - { - target: target, - operator: operator, - name: name, - paren: paren, - statement: statement, - location: location, - comments: comments - } - end - - def format(q) - q.group do - q.text("def ") - - if target - q.format(target) - q.format(CallOperatorFormatter.new(operator), stackable: false) - end - - q.format(name) - - if paren - params = paren - params = params.contents if params.is_a?(Paren) - q.format(paren) unless params.empty? - end - - q.text(" =") - q.group do - q.indent do - q.breakable_space - q.format(statement) - end - end - end + # Returns true if the method was found in the source in the "endless" form, + # i.e. where the method body is defined using the `=` operator after the + # method name and parameters. + def endless? + !bodystmt.is_a?(BodyStmt) end end @@ -3751,10 +3680,10 @@ class Defs < Node # [Backtick | Const | Ident | Kw | Op] the name of the method attr_reader :name - # [Params | Paren] the parameter declaration for the method + # [nil | Params | Paren] the parameter declaration for the method attr_reader :params - # [BodyStmt] the expressions to be executed by the method + # [BodyStmt | untyped] the expressions to be executed by the method attr_reader :bodystmt # [Array[ Comment | EmbDoc ]] the comments attached to this node @@ -3808,22 +3737,42 @@ def format(q) q.format(CallOperatorFormatter.new(operator), stackable: false) q.format(name) - if !params.is_a?(Params) || !params.empty? || params.comments.any? + case params + when Paren q.format(params) + when Params + q.format(params) if !params.empty? || params.comments.any? end end - unless bodystmt.empty? - q.indent do - q.breakable_force - q.format(bodystmt) + if endless? + q.text(" =") + q.group do + q.indent do + q.breakable_space + q.format(bodystmt) + end + end + else + unless bodystmt.empty? + q.indent do + q.breakable_force + q.format(bodystmt) + end end - end - q.breakable_force - q.text("end") + q.breakable_force + q.text("end") + end end end + + # Returns true if the method was found in the source in the "endless" form, + # i.e. where the method body is defined using the `=` operator after the + # method name and parameters. + def endless? + !bodystmt.is_a?(BodyStmt) + end end # DoBlock represents passing a block to a method call using the +do+ and +end+ @@ -6971,7 +6920,7 @@ def format(q) end case q.parent - when Def, Defs, DefEndless + when Def, Defs q.nest(0) do q.text("(") q.group do diff --git a/lib/syntax_tree/parser.rb b/lib/syntax_tree/parser.rb index 4bc0bb6f..508348d8 100644 --- a/lib/syntax_tree/parser.rb +++ b/lib/syntax_tree/parser.rb @@ -1181,7 +1181,7 @@ def on_cvar(value) # (Backtick | Const | Ident | Kw | Op) name, # (nil | Params | Paren) params, # untyped bodystmt - # ) -> Def | DefEndless + # ) -> Def def on_def(name, params, bodystmt) # Make sure to delete this token in case you're defining something like # def class which would lead to this being a kw and causing all kinds of @@ -1234,12 +1234,10 @@ def on_def(name, params, bodystmt) # the statements list. Before, it was just the individual statement. statement = bodystmt.is_a?(BodyStmt) ? bodystmt.statements : bodystmt - DefEndless.new( - target: nil, - operator: nil, + Def.new( name: name, - paren: params, - statement: statement, + params: params, + bodystmt: statement, location: beginning.location.to(bodystmt.location) ) end @@ -1322,12 +1320,12 @@ def on_defs(target, operator, name, params, bodystmt) # the statements list. Before, it was just the individual statement. statement = bodystmt.is_a?(BodyStmt) ? bodystmt.statements : bodystmt - DefEndless.new( + Defs.new( target: target, operator: operator, name: name, - paren: params, - statement: statement, + params: params, + bodystmt: statement, location: beginning.location.to(bodystmt.location) ) end diff --git a/lib/syntax_tree/visitor.rb b/lib/syntax_tree/visitor.rb index ad4757d7..3bf3c72d 100644 --- a/lib/syntax_tree/visitor.rb +++ b/lib/syntax_tree/visitor.rb @@ -119,9 +119,6 @@ class Visitor < BasicVisitor # Visit a Def node. alias visit_def visit_child_nodes - # Visit a DefEndless node. - alias visit_def_endless visit_child_nodes - # Visit a Defined node. alias visit_defined visit_child_nodes diff --git a/lib/syntax_tree/visitor/field_visitor.rb b/lib/syntax_tree/visitor/field_visitor.rb index ac7b3603..14ecd2fc 100644 --- a/lib/syntax_tree/visitor/field_visitor.rb +++ b/lib/syntax_tree/visitor/field_visitor.rb @@ -322,20 +322,6 @@ def visit_def(node) end end - def visit_def_endless(node) - node(node, "def_endless") do - if node.target - field("target", node.target) - field("operator", node.operator) - end - - field("name", node.name) - field("paren", node.paren) if node.paren - field("statement", node.statement) - comments(node) - end - end - def visit_defined(node) node(node, "defined") do field("value", node.value) diff --git a/lib/syntax_tree/visitor/with_environment.rb b/lib/syntax_tree/visitor/with_environment.rb index 043cbd4c..006f7b09 100644 --- a/lib/syntax_tree/visitor/with_environment.rb +++ b/lib/syntax_tree/visitor/with_environment.rb @@ -60,10 +60,6 @@ def visit_defs(node) with_new_environment { super } end - def visit_def_endless(node) - with_new_environment { super } - end - # Visit for keeping track of local arguments, such as method and block # arguments def visit_params(node) diff --git a/test/fixtures/def_endless.rb b/test/fixtures/def_endless.rb index 15ea518b..4595fba9 100644 --- a/test/fixtures/def_endless.rb +++ b/test/fixtures/def_endless.rb @@ -4,8 +4,6 @@ def foo = bar def foo(bar) = baz % def foo() = bar -- -def foo = bar % # >= 3.1.0 def foo = bar baz % # >= 3.1.0 @@ -14,8 +12,6 @@ def self.foo = bar def self.foo(bar) = baz % # >= 3.1.0 def self.foo() = bar -- -def self.foo = bar % # >= 3.1.0 def self.foo = bar baz % diff --git a/test/node_test.rb b/test/node_test.rb index d27c0d5f..49f6f921 100644 --- a/test/node_test.rb +++ b/test/node_test.rb @@ -379,13 +379,13 @@ def method guard_version("3.0.0") do def test_def_endless - assert_node(DefEndless, "def method = result") + assert_node(Def, "def method = result") end end guard_version("3.1.0") do def test_def_endless_command - assert_node(DefEndless, "def method = result argument") + assert_node(Def, "def method = result argument") end end From 4a9a7c6a8b55764676f47b2ddcd10e614b4aff8c Mon Sep 17 00:00:00 2001 From: Kevin Newton Date: Wed, 2 Nov 2022 12:07:46 -0400 Subject: [PATCH 09/17] Fold Def and DefEndless --- CHANGELOG.md | 2 +- lib/syntax_tree/node.rb | 135 +++----------------- lib/syntax_tree/parser.rb | 10 +- lib/syntax_tree/visitor.rb | 3 - lib/syntax_tree/visitor/field_visitor.rb | 13 +- lib/syntax_tree/visitor/with_environment.rb | 4 - test/node_test.rb | 4 +- 7 files changed, 33 insertions(+), 138 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 67b4e150..10c33420 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,7 +15,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a - `Yield0` is no longer a node. Instead if has been folded into the `Yield` node. The `Yield` node can now have its `arguments` field be `nil`. Consequently, the `visit_yield0` method has been removed from the visitor interface. If you were previously using this method, you should now use `visit_yield` instead. - `FCall` is no longer a node. Instead it has been folded into the `Call` node. The `Call` node can now have its `receiver` and `operator` fields be `nil`. Consequently, the `visit_fcall` method has been removed from the visitor interface. If you were previously using this method, you should now use `visit_call` instead. - `Dot2` and `Dot3` are no longer nodes. Instead they have become a single new `RangeLiteral` node. This node looks the same as `Dot2` and `Dot3`, except that it additionally has an `operator` field that contains the operator that created the node. Consequently, the `visit_dot2` and `visit_dot3` methods have been removed from the visitor interface. If you were previously using these methods, you should now use `visit_range_literal` instead. - - `DefEndless` has been folded into the `Def` and `Defs` nodes. + - `DefEndless` and `Defs` have both been folded into the `Def` node. The `Def` node now has the `target` and `operator` fields which originally came from `Defs` which can both be `nil`. It also now has an `endless?` method on it to tell if the original node was found in the endless form. Finally the `bodystmt` field can now either be a `BodyStmt` as it was or any other kind of node since that was the body of the `DefEndless` node. The `visit_defs` and `visit_def_endless` methods on the visitor have therefore been removed. ## [4.3.0] - 2022-10-28 diff --git a/lib/syntax_tree/node.rb b/lib/syntax_tree/node.rb index ebfcc336..b1080f1f 100644 --- a/lib/syntax_tree/node.rb +++ b/lib/syntax_tree/node.rb @@ -3108,7 +3108,7 @@ def align(q, node, &block) part = parts.first case part - when Def, Defs + when Def q.text(" ") yield when IfOp @@ -3535,8 +3535,15 @@ def format(q) # Def represents defining a regular method on the current self object. # # def method(param) result end + # def object.method(param) result end # class Def < Node + # [nil | untyped] the target where the method is being defined + attr_reader :target + + # [nil | Op | Period] the operator being used to declare the method + attr_reader :operator + # [Backtick | Const | Ident | Kw | Op] the name of the method attr_reader :name @@ -3549,7 +3556,9 @@ class Def < Node # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(name:, params:, bodystmt:, location:) + def initialize(target:, operator:, name:, params:, bodystmt:, location:) + @target = target + @operator = operator @name = name @params = params @bodystmt = bodystmt @@ -3562,13 +3571,15 @@ def accept(visitor) end def child_nodes - [name, params, bodystmt] + [target, operator, name, params, bodystmt] end alias deconstruct child_nodes def deconstruct_keys(_keys) { + target: target, + operator: operator, name: name, params: params, bodystmt: bodystmt, @@ -3581,6 +3592,12 @@ def format(q) q.group do q.group do q.text("def ") + + if target + q.format(target) + q.format(CallOperatorFormatter.new(operator), stackable: false) + end + q.format(name) case params @@ -3666,115 +3683,6 @@ def format(q) end end - # Defs represents defining a singleton method on an object. - # - # def object.method(param) result end - # - class Defs < Node - # [untyped] the target where the method is being defined - attr_reader :target - - # [Op | Period] the operator being used to declare the method - attr_reader :operator - - # [Backtick | Const | Ident | Kw | Op] the name of the method - attr_reader :name - - # [nil | Params | Paren] the parameter declaration for the method - attr_reader :params - - # [BodyStmt | untyped] the expressions to be executed by the method - attr_reader :bodystmt - - # [Array[ Comment | EmbDoc ]] the comments attached to this node - attr_reader :comments - - def initialize( - target:, - operator:, - name:, - params:, - bodystmt:, - location:, - comments: [] - ) - @target = target - @operator = operator - @name = name - @params = params - @bodystmt = bodystmt - @location = location - @comments = [] - end - - def accept(visitor) - visitor.visit_defs(self) - end - - def child_nodes - [target, operator, name, params, bodystmt] - end - - alias deconstruct child_nodes - - def deconstruct_keys(_keys) - { - target: target, - operator: operator, - name: name, - params: params, - bodystmt: bodystmt, - location: location, - comments: comments - } - end - - def format(q) - q.group do - q.group do - q.text("def ") - q.format(target) - q.format(CallOperatorFormatter.new(operator), stackable: false) - q.format(name) - - case params - when Paren - q.format(params) - when Params - q.format(params) if !params.empty? || params.comments.any? - end - end - - if endless? - q.text(" =") - q.group do - q.indent do - q.breakable_space - q.format(bodystmt) - end - end - else - unless bodystmt.empty? - q.indent do - q.breakable_force - q.format(bodystmt) - end - end - - q.breakable_force - q.text("end") - end - end - end - - # Returns true if the method was found in the source in the "endless" form, - # i.e. where the method body is defined using the `=` operator after the - # method name and parameters. - def endless? - !bodystmt.is_a?(BodyStmt) - end - end - # DoBlock represents passing a block to a method call using the +do+ and +end+ # keywords. # @@ -6919,8 +6827,7 @@ def format(q) return end - case q.parent - when Def, Defs + if q.parent.is_a?(Def) q.nest(0) do q.text("(") q.group do diff --git a/lib/syntax_tree/parser.rb b/lib/syntax_tree/parser.rb index 508348d8..797f69d2 100644 --- a/lib/syntax_tree/parser.rb +++ b/lib/syntax_tree/parser.rb @@ -1224,6 +1224,8 @@ def on_def(name, params, bodystmt) ) Def.new( + target: nil, + operator: nil, name: name, params: params, bodystmt: bodystmt, @@ -1235,6 +1237,8 @@ def on_def(name, params, bodystmt) statement = bodystmt.is_a?(BodyStmt) ? bodystmt.statements : bodystmt Def.new( + target: nil, + operator: nil, name: name, params: params, bodystmt: statement, @@ -1268,7 +1272,7 @@ def on_defined(value) # (Backtick | Const | Ident | Kw | Op) name, # (Params | Paren) params, # BodyStmt bodystmt - # ) -> Defs + # ) -> Def def on_defs(target, operator, name, params, bodystmt) # Make sure to delete this token in case you're defining something # like def class which would lead to this being a kw and causing all kinds @@ -1307,7 +1311,7 @@ def on_defs(target, operator, name, params, bodystmt) ending.location.start_column ) - Defs.new( + Def.new( target: target, operator: operator, name: name, @@ -1320,7 +1324,7 @@ def on_defs(target, operator, name, params, bodystmt) # the statements list. Before, it was just the individual statement. statement = bodystmt.is_a?(BodyStmt) ? bodystmt.statements : bodystmt - Defs.new( + Def.new( target: target, operator: operator, name: name, diff --git a/lib/syntax_tree/visitor.rb b/lib/syntax_tree/visitor.rb index 3bf3c72d..9748d0e1 100644 --- a/lib/syntax_tree/visitor.rb +++ b/lib/syntax_tree/visitor.rb @@ -122,9 +122,6 @@ class Visitor < BasicVisitor # Visit a Defined node. alias visit_defined visit_child_nodes - # Visit a Defs node. - alias visit_defs visit_child_nodes - # Visit a DoBlock node. alias visit_do_block visit_child_nodes diff --git a/lib/syntax_tree/visitor/field_visitor.rb b/lib/syntax_tree/visitor/field_visitor.rb index 14ecd2fc..0fc8c908 100644 --- a/lib/syntax_tree/visitor/field_visitor.rb +++ b/lib/syntax_tree/visitor/field_visitor.rb @@ -315,6 +315,8 @@ def visit_cvar(node) def visit_def(node) node(node, "def") do + field("target", node.target) + field("operator", node.operator) field("name", node.name) field("params", node.params) field("bodystmt", node.bodystmt) @@ -329,17 +331,6 @@ def visit_defined(node) end end - def visit_defs(node) - node(node, "defs") do - field("target", node.target) - field("operator", node.operator) - field("name", node.name) - field("params", node.params) - field("bodystmt", node.bodystmt) - comments(node) - end - end - def visit_do_block(node) node(node, "do_block") do field("block_var", node.block_var) if node.block_var diff --git a/lib/syntax_tree/visitor/with_environment.rb b/lib/syntax_tree/visitor/with_environment.rb index 006f7b09..59033d50 100644 --- a/lib/syntax_tree/visitor/with_environment.rb +++ b/lib/syntax_tree/visitor/with_environment.rb @@ -56,10 +56,6 @@ def visit_def(node) with_new_environment { super } end - def visit_defs(node) - with_new_environment { super } - end - # Visit for keeping track of local arguments, such as method and block # arguments def visit_params(node) diff --git a/test/node_test.rb b/test/node_test.rb index 49f6f921..8bb28131 100644 --- a/test/node_test.rb +++ b/test/node_test.rb @@ -394,7 +394,7 @@ def test_defined end def test_defs - assert_node(Defs, "def object.method(param) result end") + assert_node(Def, "def object.method(param) result end") end def test_defs_paramless @@ -403,7 +403,7 @@ def object.method end SOURCE - assert_node(Defs, source) + assert_node(Def, source) end def test_do_block From 3445e6435639914c73309d412ad639c11a165763 Mon Sep 17 00:00:00 2001 From: Kevin Newton Date: Wed, 2 Nov 2022 12:24:42 -0400 Subject: [PATCH 10/17] Fold DoBlock and BraceBlock into Block --- CHANGELOG.md | 1 + lib/syntax_tree/node.rb | 396 ++++++++++------------- lib/syntax_tree/parser.rb | 16 +- lib/syntax_tree/visitor.rb | 9 +- lib/syntax_tree/visitor/field_visitor.rb | 24 +- test/node_test.rb | 6 +- 6 files changed, 186 insertions(+), 266 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 10c33420..92f03f01 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a - `FCall` is no longer a node. Instead it has been folded into the `Call` node. The `Call` node can now have its `receiver` and `operator` fields be `nil`. Consequently, the `visit_fcall` method has been removed from the visitor interface. If you were previously using this method, you should now use `visit_call` instead. - `Dot2` and `Dot3` are no longer nodes. Instead they have become a single new `RangeLiteral` node. This node looks the same as `Dot2` and `Dot3`, except that it additionally has an `operator` field that contains the operator that created the node. Consequently, the `visit_dot2` and `visit_dot3` methods have been removed from the visitor interface. If you were previously using these methods, you should now use `visit_range_literal` instead. - `DefEndless` and `Defs` have both been folded into the `Def` node. The `Def` node now has the `target` and `operator` fields which originally came from `Defs` which can both be `nil`. It also now has an `endless?` method on it to tell if the original node was found in the endless form. Finally the `bodystmt` field can now either be a `BodyStmt` as it was or any other kind of node since that was the body of the `DefEndless` node. The `visit_defs` and `visit_def_endless` methods on the visitor have therefore been removed. + - `DoBlock` and `BraceBlock` have now been folded into a `Block` node. The `Block` node now has a `keywords?` method on it that returns true if the block was constructed with the `do`..`end` keywords. The `visit_do_block` and `visit_brace_block` methods on the visitor have therefore been removed and replaced with the `visit_block` method. ## [4.3.0] - 2022-10-28 diff --git a/lib/syntax_tree/node.rb b/lib/syntax_tree/node.rb index b1080f1f..0ab33b83 100644 --- a/lib/syntax_tree/node.rb +++ b/lib/syntax_tree/node.rb @@ -1961,222 +1961,6 @@ def format(q) end end - # Responsible for formatting either a BraceBlock or a DoBlock. - class BlockFormatter - # Formats the opening brace or keyword of a block. - class BlockOpenFormatter - # [String] the actual output that should be printed - attr_reader :text - - # [LBrace | Keyword] the node that is being represented - attr_reader :node - - def initialize(text, node) - @text = text - @node = node - end - - def comments - node.comments - end - - def format(q) - q.text(text) - end - end - - # [BraceBlock | DoBlock] the block node to be formatted - attr_reader :node - - # [LBrace | Keyword] the node that opens the block - attr_reader :block_open - - # [String] the string that closes the block - attr_reader :block_close - - # [BodyStmt | Statements] the statements inside the block - attr_reader :statements - - def initialize(node, block_open, block_close, statements) - @node = node - @block_open = block_open - @block_close = block_close - @statements = statements - end - - def format(q) - # If this is nested anywhere inside of a Command or CommandCall node, then - # we can't change which operators we're using for the bounds of the block. - break_opening, break_closing, flat_opening, flat_closing = - if unchangeable_bounds?(q) - [block_open.value, block_close, block_open.value, block_close] - elsif forced_do_end_bounds?(q) - %w[do end do end] - elsif forced_brace_bounds?(q) - %w[{ } { }] - else - %w[do end { }] - end - - # If the receiver of this block a Command or CommandCall node, then there - # are no parentheses around the arguments to that command, so we need to - # break the block. - case q.parent.call - when Command, CommandCall - q.break_parent - format_break(q, break_opening, break_closing) - return - end - - q.group do - q - .if_break { format_break(q, break_opening, break_closing) } - .if_flat { format_flat(q, flat_opening, flat_closing) } - end - end - - private - - # If this is nested anywhere inside certain nodes, then we can't change - # which operators/keywords we're using for the bounds of the block. - def unchangeable_bounds?(q) - q.parents.any? do |parent| - # If we hit a statements, then we're safe to use whatever since we - # know for certain we're going to get split over multiple lines - # anyway. - case parent - when Statements, ArgParen - break false - when Command, CommandCall - true - else - false - end - end - end - - # If we're a sibling of a control-flow keyword, then we're going to have to - # use the do..end bounds. - def forced_do_end_bounds?(q) - case q.parent.call - when Break, Next, Return, Super - true - else - false - end - end - - # If we're the predicate of a loop or conditional, then we're going to have - # to go with the {..} bounds. - def forced_brace_bounds?(q) - previous = nil - q.parents.any? do |parent| - case parent - when Paren, Statements - # If we hit certain breakpoints then we know we're safe. - return false - when If, IfOp, Unless, While, Until - return true if parent.predicate == previous - end - - previous = parent - false - end - end - - def format_break(q, opening, closing) - q.text(" ") - q.format(BlockOpenFormatter.new(opening, block_open), stackable: false) - - if node.block_var - q.text(" ") - q.format(node.block_var) - end - - unless statements.empty? - q.indent do - q.breakable_space - q.format(statements) - end - end - - q.breakable_space - q.text(closing) - end - - def format_flat(q, opening, closing) - q.text(" ") - q.format(BlockOpenFormatter.new(opening, block_open), stackable: false) - - if node.block_var - q.breakable_space - q.format(node.block_var) - q.breakable_space - end - - if statements.empty? - q.text(" ") if opening == "do" - else - q.breakable_space unless node.block_var - q.format(statements) - q.breakable_space - end - - q.text(closing) - end - end - - # BraceBlock represents passing a block to a method call using the { } - # operators. - # - # method { |variable| variable + 1 } - # - class BraceBlock < Node - # [LBrace] the left brace that opens this block - attr_reader :lbrace - - # [nil | BlockVar] the optional set of parameters to the block - attr_reader :block_var - - # [Statements] the list of expressions to evaluate within the block - attr_reader :statements - - # [Array[ Comment | EmbDoc ]] the comments attached to this node - attr_reader :comments - - def initialize(lbrace:, block_var:, statements:, location:) - @lbrace = lbrace - @block_var = block_var - @statements = statements - @location = location - @comments = [] - end - - def accept(visitor) - visitor.visit_brace_block(self) - end - - def child_nodes - [lbrace, block_var, statements] - end - - alias deconstruct child_nodes - - def deconstruct_keys(_keys) - { - lbrace: lbrace, - block_var: block_var, - statements: statements, - location: location, - comments: comments - } - end - - def format(q) - BlockFormatter.new(self, lbrace, "}", statements).format(q) - end - end - # Formats either a Break, Next, or Return node. class FlowControlFormatter # [String] the keyword to print @@ -2479,10 +2263,10 @@ def format(q) # https://github.com/prettier/plugin-ruby/issues/863. parents = q.parents.take(4) if (parent = parents[2]) - # If we're at a do_block, then we want to go one more level up. This is - # because do blocks have BodyStmt nodes instead of just Statements - # nodes. - parent = parents[3] if parent.is_a?(DoBlock) + # If we're at a block with the `do` keywords, then we want to go one + # more level up. This is because do blocks have BodyStmt nodes instead + # of just Statements nodes. + parent = parents[3] if parent.is_a?(Block) && parent.keywords? if parent.is_a?(MethodAddBlock) && parent.call.is_a?(Call) && parent.call.message.value == "sig" threshold = 2 @@ -3683,27 +3467,51 @@ def format(q) end end - # DoBlock represents passing a block to a method call using the +do+ and +end+ - # keywords. + # Block represents passing a block to a method call using the +do+ and +end+ + # keywords or the +{+ and +}+ operators. # # method do |value| # end # - class DoBlock < Node - # [Kw] the do keyword that opens this block - attr_reader :keyword + # method { |value| } + # + class Block < Node + # Formats the opening brace or keyword of a block. + class BlockOpenFormatter + # [String] the actual output that should be printed + attr_reader :text + + # [LBrace | Keyword] the node that is being represented + attr_reader :node + + def initialize(text, node) + @text = text + @node = node + end + + def comments + node.comments + end + + def format(q) + q.text(text) + end + end + + # [LBrace | Kw] the left brace or the do keyword that opens this block + attr_reader :opening # [nil | BlockVar] the optional variable declaration within this block attr_reader :block_var - # [BodyStmt] the expressions to be executed within this block + # [BodyStmt | Statements] the expressions to be executed within this block attr_reader :bodystmt # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(keyword:, block_var:, bodystmt:, location:) - @keyword = keyword + def initialize(opening:, block_var:, bodystmt:, location:) + @opening = opening @block_var = block_var @bodystmt = bodystmt @location = location @@ -3711,18 +3519,18 @@ def initialize(keyword:, block_var:, bodystmt:, location:) end def accept(visitor) - visitor.visit_do_block(self) + visitor.visit_block(self) end def child_nodes - [keyword, block_var, bodystmt] + [opening, block_var, bodystmt] end alias deconstruct child_nodes def deconstruct_keys(_keys) { - keyword: keyword, + opening: opening, block_var: block_var, bodystmt: bodystmt, location: location, @@ -3731,7 +3539,129 @@ def deconstruct_keys(_keys) end def format(q) - BlockFormatter.new(self, keyword, "end", bodystmt).format(q) + # If this is nested anywhere inside of a Command or CommandCall node, then + # we can't change which operators we're using for the bounds of the block. + break_opening, break_closing, flat_opening, flat_closing = + if unchangeable_bounds?(q) + block_close = keywords? ? "end" : "}" + [opening.value, block_close, opening.value, block_close] + elsif forced_do_end_bounds?(q) + %w[do end do end] + elsif forced_brace_bounds?(q) + %w[{ } { }] + else + %w[do end { }] + end + + # If the receiver of this block a Command or CommandCall node, then there + # are no parentheses around the arguments to that command, so we need to + # break the block. + case q.parent.call + when Command, CommandCall + q.break_parent + format_break(q, break_opening, break_closing) + return + end + + q.group do + q + .if_break { format_break(q, break_opening, break_closing) } + .if_flat { format_flat(q, flat_opening, flat_closing) } + end + end + + def keywords? + opening.is_a?(Kw) + end + + private + + # If this is nested anywhere inside certain nodes, then we can't change + # which operators/keywords we're using for the bounds of the block. + def unchangeable_bounds?(q) + q.parents.any? do |parent| + # If we hit a statements, then we're safe to use whatever since we + # know for certain we're going to get split over multiple lines + # anyway. + case parent + when Statements, ArgParen + break false + when Command, CommandCall + true + else + false + end + end + end + + # If we're a sibling of a control-flow keyword, then we're going to have to + # use the do..end bounds. + def forced_do_end_bounds?(q) + case q.parent.call + when Break, Next, Return, Super + true + else + false + end + end + + # If we're the predicate of a loop or conditional, then we're going to have + # to go with the {..} bounds. + def forced_brace_bounds?(q) + previous = nil + q.parents.any? do |parent| + case parent + when Paren, Statements + # If we hit certain breakpoints then we know we're safe. + return false + when If, IfOp, Unless, While, Until + return true if parent.predicate == previous + end + + previous = parent + false + end + end + + def format_break(q, break_opening, break_closing) + q.text(" ") + q.format(BlockOpenFormatter.new(break_opening, opening), stackable: false) + + if block_var + q.text(" ") + q.format(block_var) + end + + unless bodystmt.empty? + q.indent do + q.breakable_space + q.format(bodystmt) + end + end + + q.breakable_space + q.text(break_closing) + end + + def format_flat(q, flat_opening, flat_closing) + q.text(" ") + q.format(BlockOpenFormatter.new(flat_opening, opening), stackable: false) + + if block_var + q.breakable_space + q.format(block_var) + q.breakable_space + end + + if bodystmt.empty? + q.text(" ") if flat_opening == "do" + else + q.breakable_space unless block_var + q.format(bodystmt) + q.breakable_space + end + + q.text(flat_closing) end end @@ -6144,7 +6074,7 @@ class MethodAddBlock < Node # [Call | Command | CommandCall] the method call attr_reader :call - # [BraceBlock | DoBlock] the block being sent with the method call + # [Block] the block being sent with the method call attr_reader :block # [Array[ Comment | EmbDoc ]] the comments attached to this node diff --git a/lib/syntax_tree/parser.rb b/lib/syntax_tree/parser.rb index 797f69d2..c7ac5e74 100644 --- a/lib/syntax_tree/parser.rb +++ b/lib/syntax_tree/parser.rb @@ -920,7 +920,7 @@ def on_bodystmt(statements, rescue_clause, else_clause, ensure_clause) # on_brace_block: ( # (nil | BlockVar) block_var, # Statements statements - # ) -> BraceBlock + # ) -> Block def on_brace_block(block_var, statements) lbrace = consume_token(LBrace) rbrace = consume_token(RBrace) @@ -947,10 +947,10 @@ def on_brace_block(block_var, statements) end_column: rbrace.location.end_column ) - BraceBlock.new( - lbrace: lbrace, + Block.new( + opening: lbrace, block_var: block_var, - statements: statements, + bodystmt: statements, location: location ) end @@ -1336,7 +1336,7 @@ def on_defs(target, operator, name, params, bodystmt) end # :call-seq: - # on_do_block: (BlockVar block_var, BodyStmt bodystmt) -> DoBlock + # on_do_block: (BlockVar block_var, BodyStmt bodystmt) -> Block def on_do_block(block_var, bodystmt) beginning = consume_keyword(:do) ending = consume_keyword(:end) @@ -1350,8 +1350,8 @@ def on_do_block(block_var, bodystmt) ending.location.start_column ) - DoBlock.new( - keyword: beginning, + Block.new( + opening: beginning, block_var: block_var, bodystmt: bodystmt, location: beginning.location.to(ending.location) @@ -2328,7 +2328,7 @@ def on_method_add_arg(call, arguments) # :call-seq: # on_method_add_block: ( # (Call | Command | CommandCall) call, - # (BraceBlock | DoBlock) block + # Block block # ) -> MethodAddBlock def on_method_add_block(call, block) MethodAddBlock.new( diff --git a/lib/syntax_tree/visitor.rb b/lib/syntax_tree/visitor.rb index 9748d0e1..2ee0fc15 100644 --- a/lib/syntax_tree/visitor.rb +++ b/lib/syntax_tree/visitor.rb @@ -62,6 +62,9 @@ class Visitor < BasicVisitor # Visit a Binary node. alias visit_binary visit_child_nodes + # Visit a Block node. + alias visit_block visit_child_nodes + # Visit a BlockArg node. alias visit_blockarg visit_child_nodes @@ -71,9 +74,6 @@ class Visitor < BasicVisitor # Visit a BodyStmt node. alias visit_bodystmt visit_child_nodes - # Visit a BraceBlock node. - alias visit_brace_block visit_child_nodes - # Visit a Break node. alias visit_break visit_child_nodes @@ -122,9 +122,6 @@ class Visitor < BasicVisitor # Visit a Defined node. alias visit_defined visit_child_nodes - # Visit a DoBlock node. - alias visit_do_block visit_child_nodes - # Visit a DynaSymbol node. alias visit_dyna_symbol visit_child_nodes diff --git a/lib/syntax_tree/visitor/field_visitor.rb b/lib/syntax_tree/visitor/field_visitor.rb index 0fc8c908..e1e75474 100644 --- a/lib/syntax_tree/visitor/field_visitor.rb +++ b/lib/syntax_tree/visitor/field_visitor.rb @@ -184,6 +184,14 @@ def visit_binary(node) end end + def visit_block(node) + node(node, "block") do + field("block_var", node.block_var) if node.block_var + field("bodystmt", node.bodystmt) + comments(node) + end + end + def visit_blockarg(node) node(node, "blockarg") do field("name", node.name) if node.name @@ -209,14 +217,6 @@ def visit_bodystmt(node) end end - def visit_brace_block(node) - node(node, "brace_block") do - field("block_var", node.block_var) if node.block_var - field("statements", node.statements) - comments(node) - end - end - def visit_break(node) node(node, "break") do field("arguments", node.arguments) @@ -331,14 +331,6 @@ def visit_defined(node) end end - def visit_do_block(node) - node(node, "do_block") do - field("block_var", node.block_var) if node.block_var - field("bodystmt", node.bodystmt) - comments(node) - end - end - def visit_dyna_symbol(node) node(node, "dyna_symbol") do list("parts", node.parts) diff --git a/test/node_test.rb b/test/node_test.rb index 8bb28131..05618552 100644 --- a/test/node_test.rb +++ b/test/node_test.rb @@ -276,7 +276,7 @@ def test_brace_block source = "method { |variable| variable + 1 }" at = location(chars: 7..34) - assert_node(BraceBlock, source, at: at, &:block) + assert_node(Block, source, at: at, &:block) end def test_break @@ -410,7 +410,7 @@ def test_do_block source = "method do |variable| variable + 1 end" at = location(chars: 7..37) - assert_node(DoBlock, source, at: at, &:block) + assert_node(Block, source, at: at, &:block) end def test_dot2 @@ -647,7 +647,7 @@ def test_lbrace source = "method {}" at = location(chars: 7..8) - assert_node(LBrace, source, at: at) { |node| node.block.lbrace } + assert_node(LBrace, source, at: at) { |node| node.block.opening } end def test_lparen From 0059a828241892c84c83196c758da92a4e6bfdbf Mon Sep 17 00:00:00 2001 From: Kevin Newton Date: Wed, 2 Nov 2022 18:16:15 -0400 Subject: [PATCH 11/17] Remove the "value" field from ZSuper --- CHANGELOG.md | 1 + lib/syntax_tree/node.rb | 10 +++------- lib/syntax_tree/parser.rb | 2 +- lib/syntax_tree/visitor/field_visitor.rb | 4 +++- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 92f03f01..989c0657 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a - `Dot2` and `Dot3` are no longer nodes. Instead they have become a single new `RangeLiteral` node. This node looks the same as `Dot2` and `Dot3`, except that it additionally has an `operator` field that contains the operator that created the node. Consequently, the `visit_dot2` and `visit_dot3` methods have been removed from the visitor interface. If you were previously using these methods, you should now use `visit_range_literal` instead. - `DefEndless` and `Defs` have both been folded into the `Def` node. The `Def` node now has the `target` and `operator` fields which originally came from `Defs` which can both be `nil`. It also now has an `endless?` method on it to tell if the original node was found in the endless form. Finally the `bodystmt` field can now either be a `BodyStmt` as it was or any other kind of node since that was the body of the `DefEndless` node. The `visit_defs` and `visit_def_endless` methods on the visitor have therefore been removed. - `DoBlock` and `BraceBlock` have now been folded into a `Block` node. The `Block` node now has a `keywords?` method on it that returns true if the block was constructed with the `do`..`end` keywords. The `visit_do_block` and `visit_brace_block` methods on the visitor have therefore been removed and replaced with the `visit_block` method. +- The `ZSuper` node no longer has a `value` field associated with it (which was always a "super" string literal). ## [4.3.0] - 2022-10-28 diff --git a/lib/syntax_tree/node.rb b/lib/syntax_tree/node.rb index 0ab33b83..f6baef2f 100644 --- a/lib/syntax_tree/node.rb +++ b/lib/syntax_tree/node.rb @@ -9830,14 +9830,10 @@ def format(q) # super # class ZSuper < Node - # [String] the value of the keyword - attr_reader :value - # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(value:, location:) - @value = value + def initialize(location:) @location = location @comments = [] end @@ -9853,11 +9849,11 @@ def child_nodes alias deconstruct child_nodes def deconstruct_keys(_keys) - { value: value, location: location, comments: comments } + { location: location, comments: comments } end def format(q) - q.text(value) + q.text("super") end end end diff --git a/lib/syntax_tree/parser.rb b/lib/syntax_tree/parser.rb index c7ac5e74..32b4562a 100644 --- a/lib/syntax_tree/parser.rb +++ b/lib/syntax_tree/parser.rb @@ -3908,7 +3908,7 @@ def on_yield0 def on_zsuper keyword = consume_keyword(:super) - ZSuper.new(value: keyword.value, location: keyword.location) + ZSuper.new(location: keyword.location) end end end diff --git a/lib/syntax_tree/visitor/field_visitor.rb b/lib/syntax_tree/visitor/field_visitor.rb index e1e75474..4fab1b6c 100644 --- a/lib/syntax_tree/visitor/field_visitor.rb +++ b/lib/syntax_tree/visitor/field_visitor.rb @@ -1023,7 +1023,9 @@ def visit_yield(node) end def visit_zsuper(node) - visit_token(node, "zsuper") + node(node, "zsuper") do + comments(node) + end end def visit___end__(node) From 0bdddcccd08827032434fd699391416d547fc944 Mon Sep 17 00:00:00 2001 From: Kevin Newton Date: Wed, 2 Nov 2022 18:21:25 -0400 Subject: [PATCH 12/17] Fold Return0 into Return --- CHANGELOG.md | 1 + lib/syntax_tree/node.rb | 53 ++++++------------------ lib/syntax_tree/parser.rb | 4 +- lib/syntax_tree/visitor.rb | 3 -- lib/syntax_tree/visitor/field_visitor.rb | 4 -- test/node_test.rb | 2 +- 6 files changed, 16 insertions(+), 51 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 989c0657..2d1fb994 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a - `Dot2` and `Dot3` are no longer nodes. Instead they have become a single new `RangeLiteral` node. This node looks the same as `Dot2` and `Dot3`, except that it additionally has an `operator` field that contains the operator that created the node. Consequently, the `visit_dot2` and `visit_dot3` methods have been removed from the visitor interface. If you were previously using these methods, you should now use `visit_range_literal` instead. - `DefEndless` and `Defs` have both been folded into the `Def` node. The `Def` node now has the `target` and `operator` fields which originally came from `Defs` which can both be `nil`. It also now has an `endless?` method on it to tell if the original node was found in the endless form. Finally the `bodystmt` field can now either be a `BodyStmt` as it was or any other kind of node since that was the body of the `DefEndless` node. The `visit_defs` and `visit_def_endless` methods on the visitor have therefore been removed. - `DoBlock` and `BraceBlock` have now been folded into a `Block` node. The `Block` node now has a `keywords?` method on it that returns true if the block was constructed with the `do`..`end` keywords. The `visit_do_block` and `visit_brace_block` methods on the visitor have therefore been removed and replaced with the `visit_block` method. + - `Return0` is no longer a node. Instead if has been folded into the `Return` node. The `Return` node can now have its `arguments` field be `nil`. Consequently, the `visit_return0` method has been removed from the visitor interface. If you were previously using this method, you should now use `visit_return` instead. - The `ZSuper` node no longer has a `value` field associated with it (which was always a "super" string literal). ## [4.3.0] - 2022-10-28 diff --git a/lib/syntax_tree/node.rb b/lib/syntax_tree/node.rb index f6baef2f..31e27da1 100644 --- a/lib/syntax_tree/node.rb +++ b/lib/syntax_tree/node.rb @@ -1975,6 +1975,13 @@ def initialize(keyword, node) end def format(q) + # If there are no arguments associated with this flow control, then we can + # safely just print the keyword and return. + if node.arguments.nil? + q.text(keyword) + return + end + q.group do q.text(keyword) @@ -5077,8 +5084,8 @@ def call(q, node) def ternaryable?(statement) case statement when Alias, Assign, Break, Command, CommandCall, Heredoc, If, IfOp, - Lambda, MAssign, Next, OpAssign, RescueMod, Return, Return0, Super, - Undef, Unless, Until, VoidStmt, While, Yield, ZSuper + Lambda, MAssign, Next, OpAssign, RescueMod, Return, Super, Undef, + Unless, Until, VoidStmt, While, Yield, ZSuper # This is a list of nodes that should not be allowed to be a part of a # ternary clause. false @@ -5351,8 +5358,8 @@ def deconstruct_keys(_keys) def format(q) force_flat = [ Alias, Assign, Break, Command, CommandCall, Heredoc, If, IfOp, Lambda, - MAssign, Next, OpAssign, RescueMod, Return, Return0, Super, Undef, - Unless, VoidStmt, Yield, ZSuper + MAssign, Next, OpAssign, RescueMod, Return, Super, Undef, Unless, + VoidStmt, Yield, ZSuper ] if q.parent.is_a?(Paren) || force_flat.include?(truthy.class) || @@ -7739,7 +7746,7 @@ def format(q) # return value # class Return < Node - # [Args] the arguments being passed to the keyword + # [nil | Args] the arguments being passed to the keyword attr_reader :arguments # [Array[ Comment | EmbDoc ]] the comments attached to this node @@ -7770,42 +7777,6 @@ def format(q) end end - # Return0 represents the bare +return+ keyword with no arguments. - # - # return - # - class Return0 < Node - # [String] the value of the keyword - attr_reader :value - - # [Array[ Comment | EmbDoc ]] the comments attached to this node - attr_reader :comments - - def initialize(value:, location:) - @value = value - @location = location - @comments = [] - end - - def accept(visitor) - visitor.visit_return0(self) - end - - def child_nodes - [] - end - - alias deconstruct child_nodes - - def deconstruct_keys(_keys) - { value: value, location: location, comments: comments } - end - - def format(q) - q.text(value) - end - end - # RParen represents the use of a right parenthesis, i.e., +)+. class RParen < Node # [String] the parenthesis diff --git a/lib/syntax_tree/parser.rb b/lib/syntax_tree/parser.rb index 32b4562a..9fe750d7 100644 --- a/lib/syntax_tree/parser.rb +++ b/lib/syntax_tree/parser.rb @@ -3084,11 +3084,11 @@ def on_return(arguments) end # :call-seq: - # on_return0: () -> Return0 + # on_return0: () -> Return def on_return0 keyword = consume_keyword(:return) - Return0.new(value: keyword.value, location: keyword.location) + Return.new(arguments: nil, location: keyword.location) end # :call-seq: diff --git a/lib/syntax_tree/visitor.rb b/lib/syntax_tree/visitor.rb index 2ee0fc15..57aca619 100644 --- a/lib/syntax_tree/visitor.rb +++ b/lib/syntax_tree/visitor.rb @@ -338,9 +338,6 @@ class Visitor < BasicVisitor # Visit a Return node. alias visit_return visit_child_nodes - # Visit a Return0 node. - alias visit_return0 visit_child_nodes - # Visit a RParen node. alias visit_rparen visit_child_nodes diff --git a/lib/syntax_tree/visitor/field_visitor.rb b/lib/syntax_tree/visitor/field_visitor.rb index 4fab1b6c..150a4e97 100644 --- a/lib/syntax_tree/visitor/field_visitor.rb +++ b/lib/syntax_tree/visitor/field_visitor.rb @@ -789,10 +789,6 @@ def visit_return(node) end end - def visit_return0(node) - visit_token(node, "return0") - end - def visit_rparen(node) node(node, "rparen") { field("value", node.value) } end diff --git a/test/node_test.rb b/test/node_test.rb index 05618552..cbfc6173 100644 --- a/test/node_test.rb +++ b/test/node_test.rb @@ -841,7 +841,7 @@ def test_return end def test_return0 - assert_node(Return0, "return") + assert_node(Return, "return") end def test_sclass From 1a006d47262494ed7f4b7a29ab7667d63b9e3fa2 Mon Sep 17 00:00:00 2001 From: Kevin Newton Date: Wed, 2 Nov 2022 18:24:12 -0400 Subject: [PATCH 13/17] Drop the value attribute from Redo and Retry --- CHANGELOG.md | 2 +- lib/syntax_tree/node.rb | 20 ++++++-------------- lib/syntax_tree/parser.rb | 4 ++-- lib/syntax_tree/visitor/field_visitor.rb | 6 ++++-- 4 files changed, 13 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d1fb994..d3c3e915 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,7 +18,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a - `DefEndless` and `Defs` have both been folded into the `Def` node. The `Def` node now has the `target` and `operator` fields which originally came from `Defs` which can both be `nil`. It also now has an `endless?` method on it to tell if the original node was found in the endless form. Finally the `bodystmt` field can now either be a `BodyStmt` as it was or any other kind of node since that was the body of the `DefEndless` node. The `visit_defs` and `visit_def_endless` methods on the visitor have therefore been removed. - `DoBlock` and `BraceBlock` have now been folded into a `Block` node. The `Block` node now has a `keywords?` method on it that returns true if the block was constructed with the `do`..`end` keywords. The `visit_do_block` and `visit_brace_block` methods on the visitor have therefore been removed and replaced with the `visit_block` method. - `Return0` is no longer a node. Instead if has been folded into the `Return` node. The `Return` node can now have its `arguments` field be `nil`. Consequently, the `visit_return0` method has been removed from the visitor interface. If you were previously using this method, you should now use `visit_return` instead. -- The `ZSuper` node no longer has a `value` field associated with it (which was always a "super" string literal). +- The `Redo`, `Retry`, and `ZSuper` nodes no longer have `value` fields associated with them (which were always string literals corresponding to the keyword being used). ## [4.3.0] - 2022-10-28 diff --git a/lib/syntax_tree/node.rb b/lib/syntax_tree/node.rb index 31e27da1..f93f4935 100644 --- a/lib/syntax_tree/node.rb +++ b/lib/syntax_tree/node.rb @@ -7199,14 +7199,10 @@ def deconstruct_keys(_keys) # redo # class Redo < Node - # [String] the value of the keyword - attr_reader :value - # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(value:, location:) - @value = value + def initialize(location:) @location = location @comments = [] end @@ -7222,11 +7218,11 @@ def child_nodes alias deconstruct child_nodes def deconstruct_keys(_keys) - { value: value, location: location, comments: comments } + { location: location, comments: comments } end def format(q) - q.text(value) + q.text("redo") end end @@ -7710,14 +7706,10 @@ def format(q) # retry # class Retry < Node - # [String] the value of the keyword - attr_reader :value - # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(value:, location:) - @value = value + def initialize(location:) @location = location @comments = [] end @@ -7733,11 +7725,11 @@ def child_nodes alias deconstruct child_nodes def deconstruct_keys(_keys) - { value: value, location: location, comments: comments } + { location: location, comments: comments } end def format(q) - q.text(value) + q.text("retry") end end diff --git a/lib/syntax_tree/parser.rb b/lib/syntax_tree/parser.rb index 9fe750d7..ef0b77a0 100644 --- a/lib/syntax_tree/parser.rb +++ b/lib/syntax_tree/parser.rb @@ -2903,7 +2903,7 @@ def on_rbracket(value) def on_redo keyword = consume_keyword(:redo) - Redo.new(value: keyword.value, location: keyword.location) + Redo.new(location: keyword.location) end # :call-seq: @@ -3069,7 +3069,7 @@ def on_rest_param(name) def on_retry keyword = consume_keyword(:retry) - Retry.new(value: keyword.value, location: keyword.location) + Retry.new(location: keyword.location) end # :call-seq: diff --git a/lib/syntax_tree/visitor/field_visitor.rb b/lib/syntax_tree/visitor/field_visitor.rb index 150a4e97..d32dc877 100644 --- a/lib/syntax_tree/visitor/field_visitor.rb +++ b/lib/syntax_tree/visitor/field_visitor.rb @@ -723,7 +723,7 @@ def visit_rbracket(node) end def visit_redo(node) - visit_token(node, "redo") + node(node, "redo") { comments(node) } end def visit_regexp_beg(node) @@ -779,7 +779,9 @@ def visit_rest_param(node) end def visit_retry(node) - visit_token(node, "retry") + node(node, "retry") do + comments(node) + end end def visit_return(node) From 73e59c7760809af285eb231772a94be32e6768f7 Mon Sep 17 00:00:00 2001 From: Kevin Newton Date: Wed, 2 Nov 2022 18:25:55 -0400 Subject: [PATCH 14/17] Remove ArgsForward value --- CHANGELOG.md | 2 +- lib/syntax_tree/node.rb | 10 +++------- lib/syntax_tree/parser.rb | 2 +- lib/syntax_tree/visitor/field_visitor.rb | 2 +- 4 files changed, 6 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d3c3e915..a2fae5b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,7 +18,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a - `DefEndless` and `Defs` have both been folded into the `Def` node. The `Def` node now has the `target` and `operator` fields which originally came from `Defs` which can both be `nil`. It also now has an `endless?` method on it to tell if the original node was found in the endless form. Finally the `bodystmt` field can now either be a `BodyStmt` as it was or any other kind of node since that was the body of the `DefEndless` node. The `visit_defs` and `visit_def_endless` methods on the visitor have therefore been removed. - `DoBlock` and `BraceBlock` have now been folded into a `Block` node. The `Block` node now has a `keywords?` method on it that returns true if the block was constructed with the `do`..`end` keywords. The `visit_do_block` and `visit_brace_block` methods on the visitor have therefore been removed and replaced with the `visit_block` method. - `Return0` is no longer a node. Instead if has been folded into the `Return` node. The `Return` node can now have its `arguments` field be `nil`. Consequently, the `visit_return0` method has been removed from the visitor interface. If you were previously using this method, you should now use `visit_return` instead. -- The `Redo`, `Retry`, and `ZSuper` nodes no longer have `value` fields associated with them (which were always string literals corresponding to the keyword being used). +- The `ArgsForward`, `Redo`, `Retry`, and `ZSuper` nodes no longer have `value` fields associated with them (which were always string literals corresponding to the keyword being used). ## [4.3.0] - 2022-10-28 diff --git a/lib/syntax_tree/node.rb b/lib/syntax_tree/node.rb index f93f4935..b1ddcc43 100644 --- a/lib/syntax_tree/node.rb +++ b/lib/syntax_tree/node.rb @@ -771,14 +771,10 @@ def format(q) # The ArgsForward node appears in both the caller (the request method calls) # and the callee (the get and post definitions). class ArgsForward < Node - # [String] the value of the operator - attr_reader :value - # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(value:, location:) - @value = value + def initialize(location:) @location = location @comments = [] end @@ -794,11 +790,11 @@ def child_nodes alias deconstruct child_nodes def deconstruct_keys(_keys) - { value: value, location: location, comments: comments } + { location: location, comments: comments } end def format(q) - q.text(value) + q.text("...") end end diff --git a/lib/syntax_tree/parser.rb b/lib/syntax_tree/parser.rb index ef0b77a0..324dfb47 100644 --- a/lib/syntax_tree/parser.rb +++ b/lib/syntax_tree/parser.rb @@ -575,7 +575,7 @@ def on_args_add_star(arguments, argument) def on_args_forward op = consume_operator(:"...") - ArgsForward.new(value: op.value, location: op.location) + ArgsForward.new(location: op.location) end # :call-seq: diff --git a/lib/syntax_tree/visitor/field_visitor.rb b/lib/syntax_tree/visitor/field_visitor.rb index d32dc877..c8014106 100644 --- a/lib/syntax_tree/visitor/field_visitor.rb +++ b/lib/syntax_tree/visitor/field_visitor.rb @@ -103,7 +103,7 @@ def visit_args(node) end def visit_args_forward(node) - visit_token(node, "args_forward") + node(node, "args_forward") { comments(node) } end def visit_array(node) From 321c5b9ba56f021abfe098ab126fc925c1b769e4 Mon Sep 17 00:00:00 2001 From: Kevin Newton Date: Wed, 2 Nov 2022 18:30:51 -0400 Subject: [PATCH 15/17] Move block down to CommandCall --- CHANGELOG.md | 1 + lib/syntax_tree/node.rb | 12 ++++++++++-- lib/syntax_tree/parser.rb | 27 ++++++++++++++++++++++----- 3 files changed, 33 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a2fae5b7..435c4f54 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a - `DoBlock` and `BraceBlock` have now been folded into a `Block` node. The `Block` node now has a `keywords?` method on it that returns true if the block was constructed with the `do`..`end` keywords. The `visit_do_block` and `visit_brace_block` methods on the visitor have therefore been removed and replaced with the `visit_block` method. - `Return0` is no longer a node. Instead if has been folded into the `Return` node. The `Return` node can now have its `arguments` field be `nil`. Consequently, the `visit_return0` method has been removed from the visitor interface. If you were previously using this method, you should now use `visit_return` instead. - The `ArgsForward`, `Redo`, `Retry`, and `ZSuper` nodes no longer have `value` fields associated with them (which were always string literals corresponding to the keyword being used). +- `CommandCall` now has a `block` attribute on it. This attribute is used in the place where you would previously have a `MethodAddBlock` structure. Where before the `MethodAddBlock` would have the `CommandCall` and `Block` as its two children, you now just have one `CommandCall` node with the `block` attribute set to the `Block` node. ## [4.3.0] - 2022-10-28 diff --git a/lib/syntax_tree/node.rb b/lib/syntax_tree/node.rb index b1ddcc43..9cd2dba6 100644 --- a/lib/syntax_tree/node.rb +++ b/lib/syntax_tree/node.rb @@ -2936,6 +2936,9 @@ class CommandCall < Node # [nil | Args] the arguments going along with the message attr_reader :arguments + # [nil | Block] the block associated with this method call + attr_reader :block + # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments @@ -2944,6 +2947,7 @@ def initialize( operator:, message:, arguments:, + block:, location:, comments: [] ) @@ -2951,6 +2955,7 @@ def initialize( @operator = operator @message = message @arguments = arguments + @block = block @location = location @comments = [] end @@ -2971,6 +2976,7 @@ def deconstruct_keys(_keys) operator: operator, message: message, arguments: arguments, + block: block, location: location, comments: comments } @@ -3011,6 +3017,8 @@ def format(q) end end end + + q.format(block) if block end private @@ -3559,8 +3567,8 @@ def format(q) # If the receiver of this block a Command or CommandCall node, then there # are no parentheses around the arguments to that command, so we need to # break the block. - case q.parent.call - when Command, CommandCall + parent = q.parent + if (parent.is_a?(MethodAddBlock) && parent.call.is_a?(Command)) || parent.is_a?(CommandCall) q.break_parent format_break(q, break_opening, break_closing) return diff --git a/lib/syntax_tree/parser.rb b/lib/syntax_tree/parser.rb index 324dfb47..257a25c2 100644 --- a/lib/syntax_tree/parser.rb +++ b/lib/syntax_tree/parser.rb @@ -1095,6 +1095,7 @@ def on_command_call(receiver, operator, message, arguments) operator: operator, message: message, arguments: arguments, + block: nil, location: receiver.location.to(ending.location) ) end @@ -2331,11 +2332,27 @@ def on_method_add_arg(call, arguments) # Block block # ) -> MethodAddBlock def on_method_add_block(call, block) - MethodAddBlock.new( - call: call, - block: block, - location: call.location.to(block.location) - ) + case call + when CommandCall + node = + CommandCall.new( + receiver: call.receiver, + operator: call.operator, + message: call.message, + arguments: call.arguments, + block: block, + location: call.location.to(block.location) + ) + + node.comments.concat(call.comments) + node + else + MethodAddBlock.new( + call: call, + block: block, + location: call.location.to(block.location) + ) + end end # :call-seq: From e0ce4ffbcdad0c8dddb8bcf25a807ebc08c64f3d Mon Sep 17 00:00:00 2001 From: Kevin Newton Date: Wed, 2 Nov 2022 18:34:39 -0400 Subject: [PATCH 16/17] Move block down to the command node --- CHANGELOG.md | 2 +- lib/syntax_tree/node.rb | 17 ++++++++++++----- lib/syntax_tree/parser.rb | 12 ++++++++++++ 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 435c4f54..642e7866 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,7 +19,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a - `DoBlock` and `BraceBlock` have now been folded into a `Block` node. The `Block` node now has a `keywords?` method on it that returns true if the block was constructed with the `do`..`end` keywords. The `visit_do_block` and `visit_brace_block` methods on the visitor have therefore been removed and replaced with the `visit_block` method. - `Return0` is no longer a node. Instead if has been folded into the `Return` node. The `Return` node can now have its `arguments` field be `nil`. Consequently, the `visit_return0` method has been removed from the visitor interface. If you were previously using this method, you should now use `visit_return` instead. - The `ArgsForward`, `Redo`, `Retry`, and `ZSuper` nodes no longer have `value` fields associated with them (which were always string literals corresponding to the keyword being used). -- `CommandCall` now has a `block` attribute on it. This attribute is used in the place where you would previously have a `MethodAddBlock` structure. Where before the `MethodAddBlock` would have the `CommandCall` and `Block` as its two children, you now just have one `CommandCall` node with the `block` attribute set to the `Block` node. +- The `Command` and `CommandCall` nodes now has `block` attributes on them. These attributes are used in the place where you would previously have had a `MethodAddBlock` structure. Where before the `MethodAddBlock` would have the command and block as its two children, you now just have one command node with the `block` attribute set to the `Block` node. ## [4.3.0] - 2022-10-28 diff --git a/lib/syntax_tree/node.rb b/lib/syntax_tree/node.rb index 9cd2dba6..e966e32f 100644 --- a/lib/syntax_tree/node.rb +++ b/lib/syntax_tree/node.rb @@ -2847,12 +2847,16 @@ class Command < Node # [Args] the arguments being sent with the message attr_reader :arguments + # [nil | Block] the optional block being passed to the method + attr_reader :block + # [Array[ Comment | EmbDoc ]] the comments attached to this node attr_reader :comments - def initialize(message:, arguments:, location:) + def initialize(message:, arguments:, block:, location:) @message = message @arguments = arguments + @block = block @location = location @comments = [] end @@ -2862,7 +2866,7 @@ def accept(visitor) end def child_nodes - [message, arguments] + [message, arguments, block] end alias deconstruct child_nodes @@ -2871,6 +2875,7 @@ def deconstruct_keys(_keys) { message: message, arguments: arguments, + block: block, location: location, comments: comments } @@ -2881,6 +2886,8 @@ def format(q) q.format(message) align(q, self) { q.format(arguments) } end + + q.format(block) if block end private @@ -2965,7 +2972,7 @@ def accept(visitor) end def child_nodes - [receiver, message, arguments] + [receiver, message, arguments, block] end alias deconstruct child_nodes @@ -3567,8 +3574,8 @@ def format(q) # If the receiver of this block a Command or CommandCall node, then there # are no parentheses around the arguments to that command, so we need to # break the block. - parent = q.parent - if (parent.is_a?(MethodAddBlock) && parent.call.is_a?(Command)) || parent.is_a?(CommandCall) + case q.parent + when Command, CommandCall q.break_parent format_break(q, break_opening, break_closing) return diff --git a/lib/syntax_tree/parser.rb b/lib/syntax_tree/parser.rb index 257a25c2..9344653b 100644 --- a/lib/syntax_tree/parser.rb +++ b/lib/syntax_tree/parser.rb @@ -1076,6 +1076,7 @@ def on_command(message, arguments) Command.new( message: message, arguments: arguments, + block: nil, location: message.location.to(arguments.location) ) end @@ -2333,6 +2334,17 @@ def on_method_add_arg(call, arguments) # ) -> MethodAddBlock def on_method_add_block(call, block) case call + when Command + node = + Command.new( + message: call.message, + arguments: call.arguments, + block: block, + location: call.location.to(block.location) + ) + + node.comments.concat(call.comments) + node when CommandCall node = CommandCall.new( From b8bebe0aee7335e06e6f6271dd07408abb0b269b Mon Sep 17 00:00:00 2001 From: Kevin Newton Date: Wed, 2 Nov 2022 18:40:40 -0400 Subject: [PATCH 17/17] Fix up call chaining with new folded nodes --- lib/syntax_tree/node.rb | 71 ++++++++++++++++-------- lib/syntax_tree/parser.rb | 23 ++++++-- lib/syntax_tree/visitor/field_visitor.rb | 8 +-- 3 files changed, 68 insertions(+), 34 deletions(-) diff --git a/lib/syntax_tree/node.rb b/lib/syntax_tree/node.rb index e966e32f..97bec379 100644 --- a/lib/syntax_tree/node.rb +++ b/lib/syntax_tree/node.rb @@ -359,7 +359,8 @@ class Alias < Node # Formats an argument to the alias keyword. For symbol literals it uses the # value of the symbol directly to look like bare words. class AliasArgumentFormatter - # [Backref | DynaSymbol | GVar | SymbolLiteral] the argument being passed to alias + # [Backref | DynaSymbol | GVar | SymbolLiteral] the argument being passed + # to alias attr_reader :argument def initialize(argument) @@ -2245,14 +2246,26 @@ def format(q) when Call case (receiver = child.receiver) when Call - children << receiver + if receiver.receiver.nil? + break + else + children << receiver + end when MethodAddBlock - receiver.call.is_a?(Call) ? children << receiver : break + if receiver.call.is_a?(Call) && !receiver.call.receiver.nil? + children << receiver + else + break + end else break end when MethodAddBlock - child.call.is_a?(Call) ? children << child.call : break + if child.call.is_a?(Call) && !child.call.receiver.nil? + children << child.call + else + break + end else break end @@ -2271,7 +2284,8 @@ def format(q) # of just Statements nodes. parent = parents[3] if parent.is_a?(Block) && parent.keywords? - if parent.is_a?(MethodAddBlock) && parent.call.is_a?(Call) && parent.call.message.value == "sig" + if parent.is_a?(MethodAddBlock) && parent.call.is_a?(Call) && + parent.call.message.value == "sig" threshold = 2 end end @@ -2300,7 +2314,7 @@ def format_chain(q, children) # formatter so it's as if we had descending normally into them. This is # necessary so they can check their parents as normal. q.stack.concat(children) - q.format(children.last.receiver) + q.format(children.last.receiver) if children.last.receiver q.group do if attach_directly?(children.last) @@ -2343,7 +2357,8 @@ def format_chain(q, children) # If the parent call node has a comment on the message then we need # to print the operator trailing in order to keep it working. last_child = children.last - if last_child.is_a?(Call) && last_child.message.comments.any? + if last_child.is_a?(Call) && last_child.message.comments.any? && + last_child.operator q.format(CallOperatorFormatter.new(last_child.operator)) skip_operator = true else @@ -2372,9 +2387,9 @@ def self.chained?(node) case node when Call - true + !node.receiver.nil? when MethodAddBlock - node.call.is_a?(Call) + node.call.is_a?(Call) && !node.call.receiver.nil? else false end @@ -2405,7 +2420,7 @@ def format_child( case child when Call q.group do - unless skip_operator + if !skip_operator && child.operator q.format(CallOperatorFormatter.new(child.operator)) end q.format(child.message) if child.message != :call @@ -2495,7 +2510,8 @@ def format(q) # If we're at the top of a call chain, then we're going to do some # specialized printing in case we can print it nicely. We _only_ do this # at the top of the chain to avoid weird recursion issues. - if CallChainFormatter.chained?(receiver) && !CallChainFormatter.chained?(q.parent) + if CallChainFormatter.chained?(receiver) && + !CallChainFormatter.chained?(q.parent) q.group do q .if_break { CallChainFormatter.new(self).format(q) } @@ -2507,11 +2523,13 @@ def format(q) else q.format(message) - if arguments.is_a?(ArgParen) && arguments.arguments.nil? && !message.is_a?(Const) - # If you're using an explicit set of parentheses on something that looks - # like a constant, then we need to match that in order to maintain valid - # Ruby. For example, you could do something like Foo(), on which we - # would need to keep the parentheses to make it look like a method call. + if arguments.is_a?(ArgParen) && arguments.arguments.nil? && + !message.is_a?(Const) + # If you're using an explicit set of parentheses on something that + # looks like a constant, then we need to match that in order to + # maintain valid Ruby. For example, you could do something like Foo(), + # on which we would need to keep the parentheses to make it look like + # a method call. else q.format(arguments) end @@ -3726,7 +3744,13 @@ def child_nodes alias deconstruct child_nodes def deconstruct_keys(_keys) - { left: left, operator: operator, right: right, location: location, comments: comments } + { + left: left, + operator: operator, + right: right, + location: location, + comments: comments + } end def format(q) @@ -5133,7 +5157,11 @@ def format(q) if ContainsAssignment.call(statement) || q.parent.is_a?(In) q.group { format_flat(q) } else - q.group { q.if_break { format_break(q, force: false) }.if_flat { format_flat(q) } } + q.group do + q + .if_break { format_break(q, force: false) } + .if_flat { format_flat(q) } + end end else # If we can transform this node into a ternary, then we're going to @@ -9063,7 +9091,8 @@ def format(q) # # foo = bar while foo # - if node.modifier? && (statement = node.statements.body.first) && (statement.is_a?(Begin) || ContainsAssignment.call(statement)) + if node.modifier? && (statement = node.statements.body.first) && + (statement.is_a?(Begin) || ContainsAssignment.call(statement)) q.format(statement) q.text(" #{keyword} ") q.format(node.predicate) @@ -9466,9 +9495,7 @@ def format(q) # last argument to the predicate is and endless range, then you are # forced to use the "then" keyword to make it parse properly. last = arguments.parts.last - if last.is_a?(RangeLiteral) && !last.right - q.text(" then") - end + q.text(" then") if last.is_a?(RangeLiteral) && !last.right end end diff --git a/lib/syntax_tree/parser.rb b/lib/syntax_tree/parser.rb index 9344653b..cd14672e 100644 --- a/lib/syntax_tree/parser.rb +++ b/lib/syntax_tree/parser.rb @@ -1616,7 +1616,13 @@ def on_excessed_comma(*) # :call-seq: # on_fcall: ((Const | Ident) value) -> Call def on_fcall(value) - Call.new(receiver: nil, operator: nil, message: value, arguments: nil, location: value.location) + Call.new( + receiver: nil, + operator: nil, + message: value, + arguments: nil, + location: value.location + ) end # :call-seq: @@ -1923,7 +1929,8 @@ def on_if_mod(predicate, statement) If.new( predicate: predicate, - statements: Statements.new(self, body: [statement], location: statement.location), + statements: + Statements.new(self, body: [statement], location: statement.location), consequent: nil, location: statement.location.to(predicate.location) ) @@ -2209,7 +2216,8 @@ def lambda_locals(source) on_comma: :item, on_rparen: :final }, - final: {} + final: { + } } tokens[(index + 1)..].each_with_object([]) do |token, locals| @@ -3622,7 +3630,8 @@ def on_unless_mod(predicate, statement) Unless.new( predicate: predicate, - statements: Statements.new(self, body: [statement], location: statement.location), + statements: + Statements.new(self, body: [statement], location: statement.location), consequent: nil, location: statement.location.to(predicate.location) ) @@ -3665,7 +3674,8 @@ def on_until_mod(predicate, statement) Until.new( predicate: predicate, - statements: Statements.new(self, body: [statement], location: statement.location), + statements: + Statements.new(self, body: [statement], location: statement.location), location: statement.location.to(predicate.location) ) end @@ -3791,7 +3801,8 @@ def on_while_mod(predicate, statement) While.new( predicate: predicate, - statements: Statements.new(self, body: [statement], location: statement.location), + statements: + Statements.new(self, body: [statement], location: statement.location), location: statement.location.to(predicate.location) ) end diff --git a/lib/syntax_tree/visitor/field_visitor.rb b/lib/syntax_tree/visitor/field_visitor.rb index c8014106..01c7de4e 100644 --- a/lib/syntax_tree/visitor/field_visitor.rb +++ b/lib/syntax_tree/visitor/field_visitor.rb @@ -779,9 +779,7 @@ def visit_rest_param(node) end def visit_retry(node) - node(node, "retry") do - comments(node) - end + node(node, "retry") { comments(node) } end def visit_return(node) @@ -1021,9 +1019,7 @@ def visit_yield(node) end def visit_zsuper(node) - node(node, "zsuper") do - comments(node) - end + node(node, "zsuper") { comments(node) } end def visit___end__(node)