X-Git-Url: http://nitlanguage.org diff --git a/src/pretty.nit b/src/pretty.nit index 16e2a07..83d5a58 100644 --- a/src/pretty.nit +++ b/src/pretty.nit @@ -79,7 +79,7 @@ class PrettyPrinterVisitor current_token = nmodule.location.file.first_token visit nmodule catch_up nmodule.location.file.last_token - tpl.add "\n" + if skip_empty then tpl.add "\n" return tpl.as(not null) end @@ -172,7 +172,7 @@ class PrettyPrinterVisitor else abort end - assert current_token.location <= token.location + if current_token.location > token.location then return while current_token != token do visit current_token end @@ -183,7 +183,7 @@ class PrettyPrinterVisitor visit current_token end - while current_token isa TEol do skip + while current_token isa TEol do visit(current_token) end # The template under construction. @@ -223,6 +223,14 @@ class PrettyPrinterVisitor if current_length == 0 and last_line_is_blank then return previous_length = current_length current_length = 0 + if skip_empty then wait_addn += 1 + end + + # Perform `addn` even if not `skip_empty`. + fun forcen do + if current_length == 0 and last_line_is_blank then return + previous_length = current_length + current_length = 0 wait_addn += 1 end @@ -243,6 +251,15 @@ class PrettyPrinterVisitor consume "." end end + + # Do we break string literals that are too long? + var break_strings = false is public writable + + # Do we force `do` to be on the same line as the method signature? + var inline_do = false is public writable + + # Do we force the deletion of empty lines? + var skip_empty = false is public writable end # Base framework redefs @@ -255,7 +272,7 @@ redef class ANodes[E] if e != first then if not e_can_inline then v.add "," - v.addn + v.forcen v.indent += 1 v.addt v.indent -= 1 @@ -309,6 +326,17 @@ redef class Token redef fun was_inline do return true end +redef class TEol + redef fun accept_pretty_printer(v) do + if v.skip_empty then + super + else + v.add text + v.current_token = next_token + end + end +end + redef class Prod redef fun accept_pretty_printer(v) do v.visit first_token @@ -345,7 +373,7 @@ redef class Prod end redef fun was_inline do - return first_token.location.line_start == last_token.location.line_end + return start_token.location.line_start == last_token.location.line_end end end @@ -356,13 +384,13 @@ redef class TComment if is_adoc then v.addt super - v.addn + v.forcen return end if is_licence then super - v.addn + v.forcen if is_last_in_group then v.addn return end @@ -371,7 +399,7 @@ redef class TComment v.addn v.addt super - v.addn + v.forcen v.addn return end @@ -380,13 +408,14 @@ redef class TComment if next_token isa TComment and is_first_in_group then v.addn v.addt super - v.addn + v.forcen var prev_token = self.prev_token if prev_token isa TComment and prev_token.is_inline and is_last_in_group then v.addn return end super + if not v.skip_empty then v.forcen end # Is `self` part of an `ADoc`? @@ -435,7 +464,6 @@ redef class AAnnotations redef fun accept_pretty_printer(v) do v.adds v.consume "is" - if v.can_inline(self) then v.adds for n_item in n_items do @@ -444,21 +472,27 @@ redef class AAnnotations v.add ", " end end - v.finish_line - else if n_items.length > 1 then - v.addn + if not was_inline then + v.finish_line + if v.current_token isa TKwend then v.skip + end + else + v.forcen v.indent += 1 - for n_item in n_items do v.addt v.visit n_item v.finish_line - v.addn + if n_item != n_items.last then + if was_inline then + v.forcen + else + v.addn + end + end end - v.indent -= 1 end - if not was_inline and v.current_token isa TKwend then v.skip end redef fun is_inlinable do @@ -470,6 +504,10 @@ end redef class AAnnotation redef fun accept_pretty_printer(v) do + if n_visibility != null and not n_visibility isa APublicVisibility then + v.visit n_visibility + v.adds + end v.visit n_atid if not n_args.is_empty then if n_opar == null then @@ -495,7 +533,7 @@ redef class AModule v.visit n_moduledecl if not n_imports.is_empty then - v.addn + if v.skip_empty then v.addn for n_import in n_imports do v.catch_up n_import @@ -517,7 +555,7 @@ redef class AModule end if not n_classdefs.is_empty then - v.addn + if v.skip_empty then v.addn for n_classdef in n_classdefs do v.catch_up n_classdef @@ -562,7 +600,7 @@ redef class AModuledecl end v.finish_line - v.addn + if v.skip_empty then v.addn end end @@ -583,7 +621,7 @@ redef class ANoImport v.adds v.visit n_kwend v.finish_line - v.addn + if v.skip_empty then v.addn end end @@ -598,7 +636,7 @@ redef class AStdImport v.adds v.visit n_name v.finish_line - v.addn + if v.skip_empty then v.addn end end @@ -610,9 +648,9 @@ redef class AClassdef v.catch_up n_propdef if n_propdef.n_doc != null or not v.can_inline(n_propdef) then - if n_propdef != n_propdefs.first then v.addn + if v.skip_empty and n_propdef != n_propdefs.first then v.addn v.visit n_propdef - if n_propdef != n_propdefs.last then v.addn + if v.skip_empty and n_propdef != n_propdefs.last then v.addn else v.visit n_propdef end @@ -653,29 +691,17 @@ redef class AStdClassdef if can_inline then v.adds - if not n_superclasses.is_empty then - for n_superclass in n_superclasses do + if not n_propdefs.is_empty then + for n_superclass in n_propdefs do v.visit n_superclass v.adds end end else v.finish_line - v.addn + if v.skip_empty then v.addn v.indent += 1 - for n_superclass in n_superclasses do - v.catch_up n_superclass - v.addt - v.visit n_superclass - v.finish_line - v.addn - end - - if not n_superclasses.is_empty and not n_propdefs.is_empty then - v.addn - end - super v.catch_up n_kwend v.indent -= 1 @@ -683,14 +709,15 @@ redef class AStdClassdef v.visit n_kwend v.finish_line - v.addn + if v.skip_empty then v.addn assert v.indent == 0 end redef fun is_inlinable do if not super then return false - if not n_propdefs.is_empty then return false - if n_superclasses.length > 1 then return false + # FIXME: repair pretty-printing one-liner classes + if n_propdefs.length > 0 then return false + #if n_propdefs.length == 1 and not n_propdefs.first isa ASuperPropdef then return false if not collect_comments.is_empty then return false return true end @@ -747,14 +774,6 @@ redef class AType end end -redef class ASuperclass - redef fun accept_pretty_printer(v) do - v.visit n_kwsuper - v.adds - v.visit n_type - end -end - # Properties redef class APropdef @@ -762,7 +781,7 @@ redef class APropdef v.visit n_doc v.addt - if not n_visibility isa APublicVisibility then + if not n_visibility isa nullable APublicVisibility then v.visit n_visibility v.adds end @@ -786,16 +805,33 @@ redef class APropdef # # Were annotations printed inline? If so, we need to print the block differently. fun visit_block(v: PrettyPrinterVisitor, n_block: nullable AExpr, annot_inline: Bool) do + # var can_inline = v.can_inline(n_block) if n_block == null then return - while not v.current_token isa TKwdo do v.skip if n_annotations != null and not annot_inline then + v.forcen v.addt - else - v.adds end + if v.inline_do then + while not v.current_token isa TKwdo do v.skip + end + var token = v.current_token + var do_inline = true + loop + if token isa TEol then + v.skip + if not v.can_inline(n_block) then + v.forcen + v.addt + do_inline = false + end + end + token = v.current_token + if token isa TKwdo then break + end + if annot_inline and do_inline then v.adds v.consume "do" - if v.can_inline(n_block) then + if v.can_inline(n_block) and do_inline then v.adds if n_block isa ABlockExpr then @@ -812,7 +848,11 @@ redef class APropdef end else v.finish_line - v.addn + if was_inline then + v.forcen + else + v.addn + end v.indent += 1 if n_block isa ABlockExpr then @@ -822,7 +862,7 @@ redef class APropdef else v.addt v.visit n_block - v.addn + v.forcen end v.indent -= 1 @@ -942,8 +982,22 @@ end redef class AMainMethPropdef redef fun accept_pretty_printer(v) do v.visit n_block + if v.skip_empty then v.addn + end +end + +redef class ASuperPropdef + redef fun accept_pretty_printer(v) do + super + v.visit n_kwsuper + v.adds + v.visit n_type + visit_annotations(v, n_annotations) + v.finish_line v.addn end + + redef fun is_inlinable do return true end redef class ASignature @@ -1096,7 +1150,7 @@ redef class TExternCodeSegment for line in lines do v.add line.r_trim - v.addn + v.forcen end v.addt @@ -1186,11 +1240,18 @@ redef class AIfExpr else if n_then == null then v.add "end" end - v.skip_to last_token.last_real_token_in_line else v.finish_line - v.addn + if was_inline then + v.forcen + else if not v.skip_empty and n_then != null and + n_then.was_inline and + n_then.location.line_end == location.line_start then + v.forcen # Xymus fucking syntax + else + v.addn + end v.indent += 1 if n_then != null then @@ -1200,7 +1261,11 @@ redef class AIfExpr else v.addt v.visit n_then - v.addn + if n_then.was_inline then + v.forcen + else + v.addn + end end end @@ -1219,7 +1284,11 @@ redef class AIfExpr v.visit n_else else v.finish_line - v.addn + if was_inline then + v.forcen + else + v.addn + end v.indent += 1 if n_else isa ABlockExpr then @@ -1228,7 +1297,11 @@ redef class AIfExpr else v.addt v.visit n_else - v.addn + if n_else.was_inline then + v.forcen + else + v.addn + end end if last_token isa TKwend then @@ -2082,9 +2155,13 @@ end redef class AStringFormExpr redef fun accept_pretty_printer(v) do - var can_inline = v.can_inline(self) - - if can_inline then + if not v.break_strings then + # n_string.force_inline = true + v.visit n_string + return + end + if v.can_inline(self) then + n_string.force_inline = true v.visit n_string else var text = n_string.text @@ -2095,7 +2172,11 @@ redef class AStringFormExpr if v.current_length >= v.max_size and i <= text.length - 3 then v.add "\" +" - v.addn + if was_inline then + v.forcen + else + v.addn + end v.indent += 1 v.addt v.indent -= 1 @@ -2112,7 +2193,12 @@ end redef class ASuperstringExpr redef fun accept_pretty_printer(v) do - for n_expr in n_exprs do v.visit n_expr + for n_expr in n_exprs do + if not v.break_strings then + n_expr.force_inline = true + end + v.visit n_expr + end end redef fun must_be_inline do