Skip to content

v3.4.0

Choose a tag to compare

@hiroshiyui hiroshiyui released this 01 Sep 14:01
· 338 commits to main since this release

The release that emptied doc/roadmap.md's What would make this easier to
work on
. Three rows closed since 3.3.0 and all three by the same method the
chapter kept recommending to itself -- attempt the row rather than believe it.
Two were built and the third talked the page out of itself.

The fourth warning (ADR-0283) is the first whose answer is a property of
the whole compilation rather than of one routine, and it is a fixed point
rather than a list: protecting one parameter stops its callers' arguments from
being threatened and exposes the next layer. One pass over this tree reports
130 sites and seven passes report zero, having added protected 54 times.

--format --range=L:H (ADR-0284) was recorded as needing a parse to know
where a range's indent begins. It needs no parse: the printer accumulates that
depth as it walks, so the lines before the range are walked without being
written. textDocument/rangeFormatting follows from it.

And the style: gate was tried and declined (ADR-0285). A reformat of this
tree rewrites 42 601 lines and grows the implementation 6.8%, almost all of it
style rather than defect. What the attempt was worth is five layout defects it
found -- every one token-preserving, so every oracle here was green on all
five.

Added

  • pascalc --format --range=L:H (ADR-0284) writes those lines alone, with
    the layout they have in the whole file. doc/roadmap.md had this down as
    needing the printer told where its indent begins, "a question about the
    enclosing structure that only a parse can answer"; the printer accumulates
    that depth itself, so the lines before the range are walked without being
    written and the depth on arrival is the one the whole file would have. A
    boundary inside a construct gets a line break there that the whole file would
    not have, which is what asking for part of a file means. A span it cannot use
    is refused rather than widened to the document.

  • The language server formats a selection. textDocument/rangeFormatting,
    beside the whole-document request. A client's range is a position pair and
    the formatter's unit is a line, so the selection is widened to every line it
    touches and the reply replaces whole lines; a range ending at character 0
    does not reach into that line, so three selected lines come back as three.

  • A var parameter nothing writes through is reported (ADR-0283). The
    fourth warning, and the first whose answer is a property of the whole
    compilation rather than of one routine. 6.7.3.1 spells such a parameter
    protected var, and the advice is exact rather than a guess: 6.5.1 forbids a
    statement to threaten a protected variable-identifier, 6.9.4 lists the six
    ways to threaten one, and the compiler already recorded every one of them --
    so "never threatened" is precisely the condition under which adding the word
    still compiles. A file or a pointer is never advised, 6.4.1 making it
    unprotectable.

    It is not advised where the word would be illegal, which is why it is
    written at the end of the compilation: a routine passed as a procedural
    actual cannot take it, since 6.6.3.6 compares the parameter lists with
    protected in them and the call may be written after the routine; and
    whether an exported routine is passed that way is a question no single
    component can answer.

Changed

  • A program that compiled with three warnings may now print a fourth. As
    in 3.3.0, nothing about what it does changes -- the emitted IR, the exit
    status and the program's own output are untouched -- but a var parameter
    the body never writes through is now remarked on. A build script that treats
    any compiler output as failure is what notices. Every --dump flag still
    suppresses warnings, and the new one is never written for an imported
    component, nor once an error has been reported.

  • 54 parameters of the compiler, the library and the language server are now
    protected var.
    They are the warning's own first finding, and three were
    groups like var l, r, v: str split into protected var l, r: str; var v: str, which had been claiming all three were writable when one was. Nothing
    about what any of them does changes -- protected is a Sema-only property
    and the code generator never reads it -- but a future change that writes
    through one of them is now a compilation error naming the clause.

Fixed

  • Five layout defects in the formatter (ADR-0285), found by pointing it at
    36 real sources rather than at a case someone wrote. Every one preserves the
    token stream, so every oracle here was green on all five. A blank line
    inside a parenthesised list dropped the rest of the list to column zero. A
    comment introducing an else took the indent of the arm above it. ^ was
    glued to whatever preceded it, which is right for a dereference and wrong
    for a pointer-type, printing = ^T as =^T. AP 6.4.13's ! is binary and
    took a space on one side only. And 6.9.2.1's empty statement after a
    case-label lost its space, printing red:;.

  • and then and or else were written straight to standard output by the
    formatter, which adjusted its column counter by hand rather than going
    through its one character sink. The bytes were identical either way, so
    nothing could see it until --range gave the sink something to suppress --
    and then those two word-symbols printed outside the range asked for.