Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/compiler/crystal/syntax/parser.cr
Original file line number Diff line number Diff line change
Expand Up @@ -627,7 +627,7 @@ module Crystal
def parse_prefix
name_location = @token.location
case token_type = @token.type
when .op_bang?, .op_plus?, .op_minus?, .op_tilde?, .op_amp_plus?, .op_amp_minus?
when .unary_operator?
location = @token.location
next_token_skip_space_or_newline
check_void_expression_keyword
Expand Down
1 change: 1 addition & 0 deletions src/compiler/crystal/syntax/to_s.cr
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,7 @@ module Crystal
visit_call node
end

# Related: `Token::Kind#unary_operator?`
UNARY_OPERATORS = {"+", "-", "~", "&+", "&-"}

def visit_call(node, ignore_obj = false)
Expand Down
7 changes: 7 additions & 0 deletions src/compiler/crystal/syntax/token.cr
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,13 @@ module Crystal
end
end

# Returns true if the operator can be used in prefix notation.
#
# Related: `ToSVisitor::UNARY_OPERATORS`
def unary_operator?
self.in?(OP_BANG, OP_PLUS, OP_MINUS, OP_TILDE, OP_AMP_PLUS, OP_AMP_MINUS)
end

def magic?
magic_dir? || magic_end_line? || magic_file? || magic_line?
end
Expand Down
15 changes: 8 additions & 7 deletions src/compiler/crystal/tools/formatter.cr
Original file line number Diff line number Diff line change
Expand Up @@ -2541,13 +2541,14 @@ module Crystal
write_token :OP_COLON_COLON if node.global?

if obj
{Token::Kind::OP_BANG, Token::Kind::OP_PLUS, Token::Kind::OP_MINUS, Token::Kind::OP_TILDE, Token::Kind::OP_AMP_PLUS, Token::Kind::OP_AMP_MINUS}.each do |op|
if node.name == op.to_s && @token.type == op && node.args.empty?
write op
next_token_skip_space_or_newline
accept obj
return false
end
# This handles unary operators written in prefix notation.
# The relevant distinction is that the call has a receiver and the
# current token is not that object but a unary operator.
if @token.type.unary_operator? && node.name == @token.type.to_s && node.args.empty?
write @token.type
next_token_skip_space_or_newline
accept obj
return false
end

accept obj
Expand Down