(self: Parser, node: doc.FunctionDef)
| 198 | |
| 199 | @dispatch.register(token="relax", type_name="FunctionDef") |
| 200 | def visit_function_def(self: Parser, node: doc.FunctionDef) -> None: |
| 201 | is_inner_function = self.inside_function |
| 202 | self.inside_function = True |
| 203 | |
| 204 | # reserve a var for local function |
| 205 | func_val = self.var_table.get().get(node.name) |
| 206 | if not func_val and is_recursive(node): |
| 207 | collect_symbolic_var_from_params(self, node) |
| 208 | if node.returns is None: |
| 209 | ret_sinfo = relax.TupleStructInfo([]) |
| 210 | else: |
| 211 | ret_sinfo = eval_struct_info(self, node.returns, eval_str=True) |
| 212 | params_sinfo = [] |
| 213 | for arg in node.args.args: |
| 214 | if arg.annotation is None: |
| 215 | self.report_error(arg, "Type annotation is required for function parameters.") |
| 216 | param_sinfo = eval_struct_info(self, arg.annotation, eval_str=True) |
| 217 | params_sinfo.append(param_sinfo) |
| 218 | # created a var for the local function, the same var could be used for recursive call |
| 219 | local_func_var = relax.Var(node.name, relax.FuncStructInfo(params_sinfo, ret_sinfo)) |
| 220 | self.var_table.add(node.name, local_func_var) |
| 221 | |
| 222 | purity = find_decorator_annotation(node, "pure") |
| 223 | # treat the function as private if we are inside another function |
| 224 | # or if it has a privacy annotation |
| 225 | privacy = is_inner_function or find_decorator_annotation(node, "private", default=False) |
| 226 | |
| 227 | with self.var_table.with_frame(): |
| 228 | with self.with_dispatch_token("relax"): |
| 229 | with R.function(is_pure=purity, is_private=privacy): |
| 230 | R.func_name(node.name) |
| 231 | collect_symbolic_var_from_params(self, node) |
| 232 | |
| 233 | if node.returns is not None: |
| 234 | ann_sinfo = eval_struct_info(self, node.returns, eval_str=True) |
| 235 | R.func_ret_struct_info(ann_sinfo) |
| 236 | |
| 237 | self.visit(node.args) |
| 238 | |
| 239 | for stmt in node.body: |
| 240 | if isinstance(stmt, doc.FunctionDef): |
| 241 | if not stmt.decorator_list: |
| 242 | self.report_error(stmt, "Function must be decorated") |
| 243 | dec = self.eval_expr(stmt.decorator_list[-1]) |
| 244 | # inline prim_func was found |
| 245 | if dec.dispatch_token == "tirx": |
| 246 | self.report_error(stmt, "inline prim_func is disallowed in Relax IR") |
| 247 | |
| 248 | self.visit_body(node.body) |
| 249 | self.inside_function = is_inner_function |
| 250 | |
| 251 | |
| 252 | def find_decorator_annotation(node: doc.FunctionDef, annotation: str, default: bool = True) -> bool: |
nothing calls this directly
no test coverage detected
searching dependent graphs…