-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Description
When formatting some specific source code, the formatter produces an invalid result that doesn't parse anymore.
crystal tool format with Crystal 1.19.1 produces this invalid diff:
@@ -102,8 +101,8 @@ abstract class Admiral::Command
type = command.is_a?(TypeDeclaration) ? command.type : type
SubCommands::SPECS[name] = {
- type: type,
- description: {
+ type: type,
+ descri ption: {
name + (short ? ", #{short.id}" : ""),
description,
},I noticed the failure while formatting jwaldrip/admiral.cr@211937b in crystal-lang/test-ecosystem#89
The reproduction is not very concise because it requires certain line number arrangement to trigger the error. It can probably be minimized further.
Reproduction
abstract class Admiral::Command
private macro inherited
private struct SubCommands
SPECS = {} of String => NamedTuple(
)
def self.locate(name)
new(name.to_s).locate
end
def self.invoke(name, *args, **params)
new(name).invoke(*args, **params)
end
def initialize(name : ::Admiral::StringValue)
initialize name.value
end
def initialize(@name : String)
end
def invoke(*args, **params)
if sub_command_class = locate
sub_command_class.run(*args, **params, program_name: @name)
else
raise ::Admiral::Error.new("Invalid subcommand: #{@name}.")
end
end
end
def sub(command, *args, **params)
SubCommands.invoke(command, *args, **params, parent: self)
end
end
{%
SubCommands::SPECS[name] = {
type: type,
description: 1,
short: short,
}
%}
endIt looks like some AST nodes have incorrect locations which then throws off the formatter when it aligns the values in the named tuple literal. The alignment processing runs after the actual code is generated and is informed by the reported line numbers.
I noticed a similar issue while implementing #16748 where it was related to skip_space_or_newline.
Add a 👍 reaction to issues you find important.