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 74 75 76 | 10x 10x 10x 14x 14x 2x 12x 12x 49x | /**
* Access pattern assignment handlers (ADR-065).
*
* Handles assignments with global/this prefix and member chains:
* - GLOBAL_ARRAY: global.obj.field[i] <- value (member chain)
* - GLOBAL_MEMBER: global.Counter.value <- 5
* - THIS_MEMBER: this.count <- 5
* - MEMBER_CHAIN: struct.field.subfield <- value
*/
import AssignmentKind from "../../../../../types/AssignmentKind";
import IAssignmentContext from "../../../../2-Plan/types/IAssignmentContext";
import AssignmentHandlerUtils from "./AssignmentHandlerUtils";
import TAssignmentHandler from "./TAssignmentHandler";
/**
* Emission for a qualified access target: `global.Counter.value <- 5`,
* `global.obj.field[i] <- v`, `this.count <- 5`.
*
* #1322: there were two functions here, one per qualifier, and they became
* byte-identical when the checks they differed by moved to pass 2.1 --
* cross-scope visibility is E0435/E0436, and `this` outside a scope is E0431.
* What was left was one expression written twice, with the `this` copy still
* documented as "validates scope context", which it no longer did.
*
* The three assignment KINDS stay distinct: the classifier tells them apart,
* and a future rule may need to. What is shared is the emission, and it is
* shared by being one function rather than by two that happen to agree.
*/
function handleQualifiedAccess(ctx: IAssignmentContext): string {
// #1668 review: a qualified chain can end in bits too, `global.gp.bits[3]`;
// this emitted `gp.bits[3] = true;`, which C rejects. The same decision and
// the same write as any member chain.
Iif (ctx.analyzeTargetForBitAccess().isBitAccess) {
return AssignmentHandlerUtils.writeBits(ctx);
}
const target = ctx.renderTarget();
return `${target} ${ctx.cOp} ${ctx.generatedValue};`;
}
/**
* Handle member chain: struct.field.subfield <- value
*
* This is the catch-all for complex member access patterns
* that don't match more specific handlers.
*
* Special case: Detects bit access at the end of chain
* (e.g., grid[2][3].flags[0] <- true) and generates RMW.
*/
function handleMemberChain(ctx: IAssignmentContext): string {
// Check if this is bit access on a struct member
const bitAnalysis = ctx.analyzeTargetForBitAccess();
if (bitAnalysis.isBitAccess) {
// #1322: compound assignment on this target is E0857 in pass 2.1.
return AssignmentHandlerUtils.writeBits(ctx);
}
// Normal member chain assignment
const target = ctx.renderTarget();
return `${target} ${ctx.cOp} ${ctx.generatedValue};`;
}
/**
* All access pattern handlers for registration.
*/
const accessPatternHandlers: ReadonlyArray<
[AssignmentKind, TAssignmentHandler]
> = [
[AssignmentKind.GLOBAL_MEMBER, handleQualifiedAccess],
[AssignmentKind.GLOBAL_ARRAY, handleQualifiedAccess],
[AssignmentKind.THIS_MEMBER, handleQualifiedAccess],
[AssignmentKind.MEMBER_CHAIN, handleMemberChain],
];
export default accessPatternHandlers;
|