def _create_begin(self, schema, context): fullname = self.classname shortname = sn.shortname_from_fullname(fullname) cp = self._get_param_desc_from_delta(schema, self) signature = f'{shortname}({", ".join(p.as_str(schema) for p in cp)})' func = schema.get(fullname, None) if func: raise errors.InvalidOperatorDefinitionError( f'cannot create the `{signature}` operator: ' f'an operator with the same signature ' f'is already defined', context=self.source_context) schema = super()._create_begin(schema, context) params: s_func.FuncParameterList = self.scls.get_params(schema) fullname = self.scls.get_name(schema) shortname = sn.shortname_from_fullname(fullname) return_type = self.scls.get_return_type(schema) return_typemod = self.scls.get_return_typemod(schema) get_signature = lambda: f'{shortname}{params.as_str(schema)}' for oper in schema.get_operators(shortname, ()): oper_return_typemod = oper.get_return_typemod(schema) if oper_return_typemod != return_typemod: raise errors.DuplicateOperatorDefinitionError( f'cannot create the `{get_signature()} -> ' f'{return_typemod.to_edgeql()} {return_type.name}` ' f'operator: overloading another operator with different ' f'return type {oper_return_typemod.to_edgeql()} ' f'{oper.get_return_type(schema).name}', context=self.source_context) return schema
def _create_begin(self, schema, context): fullname = self.classname shortname = sn.shortname_from_fullname(fullname) cp = self._get_param_desc_from_delta(schema, self) signature = f'{shortname}({", ".join(p.as_str(schema) for p in cp)})' func = schema.get(fullname, None) if func: raise errors.InvalidOperatorDefinitionError( f'cannot create the `{signature}` operator: ' f'an operator with the same signature ' f'is already defined', context=self.source_context) schema = super()._create_begin(schema, context) params: s_func.FuncParameterList = self.scls.get_params(schema) fullname = self.scls.get_name(schema) shortname = sn.shortname_from_fullname(fullname) return_type = self.scls.get_return_type(schema) return_typemod = self.scls.get_return_typemod(schema) recursive = self.scls.get_recursive(schema) get_signature = lambda: f'{shortname}{params.as_str(schema)}' # an operator must have operands if len(params) == 0: raise errors.InvalidOperatorDefinitionError( f'cannot create the `{signature}` operator: ' f'an operator must have operands', context=self.source_context) # We'll need to make sure that there's no mix of recursive and # non-recursive operators being overloaded. all_arrays = all_tuples = True for param in params.objects(schema): ptype = param.get_type(schema) all_arrays = all_arrays and ptype.is_array() all_tuples = all_tuples and ptype.is_tuple() # It's illegal to declare an operator as recursive unless all # of its operands are the same basic type of collection. if recursive and not (all_arrays or all_tuples): raise errors.InvalidOperatorDefinitionError( f'cannot create the `{signature}` operator: ' f'operands of a recursive operator must either be ' f'all arrays or all tuples', context=self.source_context) for oper in schema.get_operators(shortname, ()): oper_return_typemod = oper.get_return_typemod(schema) if oper_return_typemod != return_typemod: raise errors.DuplicateOperatorDefinitionError( f'cannot create the `{get_signature()} -> ' f'{return_typemod.to_edgeql()} {return_type.name}` ' f'operator: overloading another operator with different ' f'return type {oper_return_typemod.to_edgeql()} ' f'{oper.get_return_type(schema).name}', context=self.source_context) # Check if there is a recursive/non-recursive operator # overloading. oper_recursive = oper.get_recursive(schema) if recursive != oper_recursive: oper_signature = oper.get_display_signature(schema) oper_all_arrays = oper_all_tuples = True for param in oper.get_params(schema).objects(schema): ptype = param.get_type(schema) oper_all_arrays = oper_all_arrays and ptype.is_array() oper_all_tuples = oper_all_tuples and ptype.is_tuple() if (all_arrays == oper_all_arrays and all_tuples == oper_all_tuples): new_rec = 'recursive' if recursive else 'non-recursive' oper_rec = \ 'recursive' if oper_recursive else 'non-recursive' raise errors.InvalidOperatorDefinitionError( f'cannot create the {new_rec} `{signature}` operator: ' f'overloading a {oper_rec} operator ' f'`{oper_signature}` with a {new_rec} one ' f'is not allowed', context=self.source_context) return schema