| 133 | } |
| 134 | |
| 135 | absl::optional<Expr> ExpandExistsOneMacro2(MacroExprFactory& factory, |
| 136 | Expr& target, |
| 137 | absl::Span<Expr> args) { |
| 138 | if (args.size() != 3) { |
| 139 | return factory.ReportError("existsOne() requires 3 arguments"); |
| 140 | } |
| 141 | if (!args[0].has_ident_expr() || args[0].ident_expr().name().empty()) { |
| 142 | return factory.ReportErrorAt( |
| 143 | args[0], "existsOne() first variable name must be a simple identifier"); |
| 144 | } |
| 145 | if (!args[1].has_ident_expr() || args[1].ident_expr().name().empty()) { |
| 146 | return factory.ReportErrorAt( |
| 147 | args[1], |
| 148 | "existsOne() second variable name must be a simple identifier"); |
| 149 | } |
| 150 | if (args[0].ident_expr().name() == args[1].ident_expr().name()) { |
| 151 | return factory.ReportErrorAt( |
| 152 | args[0], |
| 153 | "existsOne() second variable must be different " |
| 154 | "from the first variable"); |
| 155 | } |
| 156 | if (args[0].ident_expr().name() == kAccumulatorVariableName) { |
| 157 | return factory.ReportErrorAt( |
| 158 | args[0], absl::StrCat("existsOne() first variable name cannot be ", |
| 159 | kAccumulatorVariableName)); |
| 160 | } |
| 161 | if (args[1].ident_expr().name() == kAccumulatorVariableName) { |
| 162 | return factory.ReportErrorAt( |
| 163 | args[1], absl::StrCat("existsOne() second variable name cannot be ", |
| 164 | kAccumulatorVariableName)); |
| 165 | } |
| 166 | auto init = factory.NewIntConst(0); |
| 167 | auto condition = factory.NewBoolConst(true); |
| 168 | auto step = |
| 169 | factory.NewCall(CelOperator::CONDITIONAL, std::move(args[2]), |
| 170 | factory.NewCall(CelOperator::ADD, factory.NewAccuIdent(), |
| 171 | factory.NewIntConst(1)), |
| 172 | factory.NewAccuIdent()); |
| 173 | auto result = factory.NewCall(CelOperator::EQUALS, factory.NewAccuIdent(), |
| 174 | factory.NewIntConst(1)); |
| 175 | return factory.NewComprehension( |
| 176 | args[0].ident_expr().name(), args[1].ident_expr().name(), |
| 177 | std::move(target), factory.AccuVarName(), std::move(init), |
| 178 | std::move(condition), std::move(step), std::move(result)); |
| 179 | } |
| 180 | |
| 181 | Macro MakeExistsOneMacro2() { |
| 182 | auto status_or_macro = Macro::Receiver("existsOne", 3, ExpandExistsOneMacro2); |
nothing calls this directly
no test coverage detected