Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | import type IStringConcatOps from "./IStringConcatOps";
import type ISubstringOps from "./ISubstringOps";
/**
* How a bounded string's initializer is rendered (ADR-045).
*
* `string<N> s <- ...` admits four initializers and they are distinguished in
* a FIXED ORDER: concatenation, then substring extraction, then a literal,
* then a copy from another string. The order is not cosmetic -- each question
* is asked of the same expression, and the first that answers wins -- so this
* is a record whose fields are consulted in declaration order rather than a
* union whose arm is already chosen.
*
* ## Why the last two questions are thunks
*
* Generating an expression registers effects: it can request an include and it
* can allocate a C++ temp into `pendingTempDeclarations`, which the enclosing
* block then emits. An effect raised for a value that is afterwards discarded
* changes the emitted C. So a field whose answer is needed on only SOME arms
* comes over unevaluated, and the renderer pays for exactly the arm it takes.
*
* `concat` is the exception and is eager: deciding it reads the type registry
* by name and generates nothing (`StringOperationsHelper.getStringConcatOperands`
* takes two source texts), so asking it always costs what asking it once cost.
*
* `renderSubstring` is the sharp one. `getSubstringOperands` asks the source's
* capacity FIRST -- that lookup is what makes `s[i]` a substring rather than an
* array index -- and generates the index expressions only once the answer is
* yes. Calling it is therefore free when it declines and raises effects when
* it does not, which is precisely the combination that must not be hoisted to
* plan time on the chance that a caller wants it.
*/
interface IPlannedStringInit {
/**
* ADR-045 concatenation operands, or null.
*
* Asked FIRST. Pure -- see the class comment.
*/
readonly concat: IStringConcatOps | null;
/**
* ADR-045 substring operands, or null when the source is not a string.
*
* Asked SECOND, and only when `concat` is null. Raises effects when it
* answers, none when it declines.
*/
readonly renderSubstring: () => ISubstringOps | null;
/**
* The initializer's SOURCE text.
*
* What decides literal-versus-copy, and what the capacity diagnostics quote.
* It is deliberately not generated code: a string literal's length and a
* declared string's capacity are both answered from the spelling.
*/
readonly text: string;
/**
* #1668 (C7): the initializer's string capacity -- a literal's length, or
* a string variable's declared capacity -- or null when it is neither
*/
readonly sourceCapacity: number | null;
/**
* The initializer as generated C.
*
* Asked LAST, on the literal and copy arms only.
*/
readonly render: () => string;
}
export default IPlannedStringInit;
|