* Rule entry: report an impure leaf-ish rule (prelude purity is known, body already parsed), push the inherited-context frame, reset per-rule selector flags. * @param {{ isRulePrelude: boolean, treatAsLeaf: boolean, ownSkip: boolean, declarations: Declaration[] | null, childRules: Rule[] | null,
(opts)
| 1146 | * @param {{ isRulePrelude: boolean, treatAsLeaf: boolean, ownSkip: boolean, declarations: Declaration[] | null, childRules: Rule[] | null, preludeStart: number, preludeEnd: number }} opts entry options |
| 1147 | */ |
| 1148 | enterBlock(opts) { |
| 1149 | if (!this.enabled) return; |
| 1150 | const { |
| 1151 | isRulePrelude, |
| 1152 | treatAsLeaf, |
| 1153 | ownSkip, |
| 1154 | declarations, |
| 1155 | childRules, |
| 1156 | preludeStart, |
| 1157 | preludeEnd |
| 1158 | } = opts; |
| 1159 | const top = this.stack[this.stack.length - 1]; |
| 1160 | const skipOwn = top ? top.skipChildren : false; |
| 1161 | const reportable = |
| 1162 | !this.noCheck && |
| 1163 | !this.ignorePending && |
| 1164 | !skipOwn && |
| 1165 | isRulePrelude && |
| 1166 | this.ruleImpure; |
| 1167 | if (reportable) { |
| 1168 | const hasBody = Boolean(declarations || childRules); |
| 1169 | let leaf = treatAsLeaf || !hasBody; |
| 1170 | if (!leaf && hasBody) { |
| 1171 | const { hasDirectDecl, hasNestedBlock } = scanRuleBody( |
| 1172 | declarations, |
| 1173 | childRules |
| 1174 | ); |
| 1175 | leaf = hasDirectDecl || !hasNestedBlock; |
| 1176 | } |
| 1177 | if (leaf) this.report(preludeStart, preludeEnd); |
| 1178 | } |
| 1179 | this.stack.push({ |
| 1180 | ancestorHadLocal: |
| 1181 | this.ancestorHadLocal() || (isRulePrelude && !this.ruleImpure), |
| 1182 | skipChildren: ownSkip || skipOwn |
| 1183 | }); |
| 1184 | this.ignorePending = false; |
| 1185 | this.segmentLocal = false; |
| 1186 | this.ruleImpure = false; |
| 1187 | }, |
| 1188 | /** |
| 1189 | * Drop the inherited-context frame (no-op when pure-mode is off). |
| 1190 | */ |
no test coverage detected