def typeref_to_ast(schema, t, *, _name=None) -> qlast.TypeName: if t.is_type() and t.is_any(): result = qlast.TypeName(name=_name, maintype=qlast.AnyType()) elif t.is_type() and t.is_anytuple(): result = qlast.TypeName(name=_name, maintype=qlast.AnyTuple()) elif not isinstance(t, s_abc.Collection): result = qlast.TypeName(name=_name, maintype=qlast.ObjectRef( module=t.get_name(schema).module, name=t.get_name(schema).name)) elif isinstance(t, s_abc.Tuple) and t.named: result = qlast.TypeName(name=_name, maintype=qlast.ObjectRef(name=t.schema_name), subtypes=[ typeref_to_ast(schema, st, _name=sn) for sn, st in t.iter_subtypes(schema) ]) else: result = qlast.TypeName(name=_name, maintype=qlast.ObjectRef(name=t.schema_name), subtypes=[ typeref_to_ast(schema, st) for st in t.get_subtypes(schema) ]) return result
def type_to_ql_typeref(t: s_obj.Object, *, _name=None, ctx: context.ContextLevel) -> qlast.TypeName: if t.is_any(): result = qlast.TypeName(name=_name, maintype=qlast.AnyType()) elif t.is_anytuple(): result = qlast.TypeName(name=_name, maintype=qlast.AnyTuple()) elif not isinstance(t, s_abc.Collection): result = qlast.TypeName(name=_name, maintype=qlast.ObjectRef( module=t.get_name(ctx.env.schema).module, name=t.get_name(ctx.env.schema).name)) elif isinstance(t, s_abc.Tuple) and t.named: result = qlast.TypeName( name=_name, maintype=qlast.ObjectRef(name=t.schema_name), subtypes=[ type_to_ql_typeref(st, _name=sn, ctx=ctx) for sn, st in t.iter_subtypes(ctx.env.schema) ]) else: result = qlast.TypeName(name=_name, maintype=qlast.ObjectRef(name=t.schema_name), subtypes=[ type_to_ql_typeref(st, ctx=ctx) for st in t.get_subtypes(ctx.env.schema) ]) return result
def typeref_to_ast(schema, t: so.Object) -> ql_ast.TypeName: if not isinstance(t, s_abc.Collection): if t.is_type() and t.is_any(): ref = ql_ast.AnyType() elif t.is_type() and t.is_anytuple(): ref = ql_ast.AnyTuple() else: ref = ql_ast.ObjectRef( module=t.get_name(schema).module, name=t.get_name(schema).name ) result = ql_ast.TypeName( maintype=ref ) else: result = ql_ast.TypeName( maintype=ql_ast.ObjectRef( name=t.schema_name ), subtypes=[ typeref_to_ast(schema, st) for st in t.get_subtypes(schema) ] ) return result
def typeref_to_ast( schema: s_schema.Schema, ref: Union[so.Object, so.ObjectShell], *, _name: Optional[str] = None, ) -> qlast.TypeExpr: from . import types as s_types if isinstance(ref, so.ObjectShell): t = ref.resolve(schema) else: t = ref result: qlast.TypeExpr components: Tuple[so.Object, ...] if t.is_type() and cast(s_types.Type, t).is_any(schema): result = qlast.TypeName(name=_name, maintype=qlast.AnyType()) elif t.is_type() and cast(s_types.Type, t).is_anytuple(schema): result = qlast.TypeName(name=_name, maintype=qlast.AnyTuple()) elif isinstance(t, s_types.Tuple) and t.is_named(schema): result = qlast.TypeName(name=_name, maintype=qlast.ObjectRef(name=t.schema_name), subtypes=[ typeref_to_ast(schema, st, _name=sn) for sn, st in t.iter_subtypes(schema) ]) elif isinstance(t, (s_types.Array, s_types.Tuple)): # Here the concrete type Array is used because t.schema_name is used, # which is not defined for more generic collections and abcs result = qlast.TypeName(name=_name, maintype=qlast.ObjectRef(name=t.schema_name), subtypes=[ typeref_to_ast(schema, st) for st in t.get_subtypes(schema) ]) elif t.is_type() and cast(s_types.Type, t).is_union_type(schema): object_set: Optional[so.ObjectSet[s_types.Type]] = \ cast(s_types.Type, t).get_union_of(schema) assert object_set is not None component_objects = tuple(object_set.objects(schema)) result = typeref_to_ast(schema, component_objects[0]) for component_object in component_objects[1:]: result = qlast.TypeOp( left=result, op='|', right=typeref_to_ast(schema, component_object), ) elif isinstance(t, so.QualifiedObject): result = qlast.TypeName(name=_name, maintype=qlast.ObjectRef( module=t.get_name(schema).module, name=t.get_name(schema).name)) else: raise NotImplementedError(f'cannot represent {t!r} as a shell') return result
def typeref_to_ast(schema: s_schema.Schema, t: so.Object, *, _name: Optional[str] = None) -> qlast.TypeExpr: from . import types as s_types if isinstance(t, so.ObjectRef): # We want typenames like 'anytype` that are wrapped in an # ObjectRef to be unwrapped to proper types, so that we # can generate proper AST nodes for them (e.g. for `anytype` it # is `qlast.AnyType()`). t = t._resolve_ref(schema) result: qlast.TypeExpr components: Tuple[so.ObjectRef, ...] if t.is_type() and cast(s_types.Type, t).is_any(): result = qlast.TypeName(name=_name, maintype=qlast.AnyType()) elif t.is_type() and cast(s_types.Type, t).is_anytuple(): result = qlast.TypeName(name=_name, maintype=qlast.AnyTuple()) elif isinstance(t, s_types.Tuple) and t.named: result = qlast.TypeName(name=_name, maintype=qlast.ObjectRef(name=t.schema_name), subtypes=[ typeref_to_ast(schema, cast(so.ObjectRef, st), _name=sn) for sn, st in t.iter_subtypes(schema) ]) elif isinstance(t, (s_types.Array, s_types.Tuple)): # Here the concrete type Array is used because t.schema_name is used, # which is not defined for more generic collections and abcs result = qlast.TypeName(name=_name, maintype=qlast.ObjectRef(name=t.schema_name), subtypes=[ typeref_to_ast(schema, st) for st in t.get_subtypes(schema) ]) elif isinstance(t, s_types.UnionTypeRef): components = t.get_union_of(schema) result = typeref_to_ast(schema, components[0]) for component in components[1:]: result = qlast.TypeOp( left=result, op='|', right=typeref_to_ast(schema, component), ) elif t.is_type() and cast(s_types.Type, t).is_union_type(schema): object_set: Optional[so.ObjectSet[s_types.Type]] = \ cast(s_types.Type, t).get_union_of(schema) assert object_set is not None components = tuple(object_set.objects(schema)) result = typeref_to_ast(schema, components[0]) for component in components[1:]: result = qlast.TypeOp( left=result, op='|', right=typeref_to_ast(schema, component), ) else: result = qlast.TypeName(name=_name, maintype=qlast.ObjectRef( module=t.get_name(schema).module, name=t.get_name(schema).name)) return result
def shell_to_ast( schema: s_schema.Schema, t: so.ObjectShell, *, _name: Optional[str] = None, ) -> qlast.TypeExpr: from . import pseudo as s_pseudo from . import types as s_types result: qlast.TypeExpr qlref: qlast.BaseObjectRef if isinstance(t, s_pseudo.PseudoTypeShell): if t.name == 'anytype': qlref = qlast.AnyType() elif t.name == 'anytuple': qlref = qlast.AnyTuple() else: raise AssertionError(f'unexpected pseudo type shell: {t.name!r}') result = qlast.TypeName(name=_name, maintype=qlref) elif isinstance(t, s_types.TupleTypeShell): if t.is_named(): result = qlast.TypeName(name=_name, maintype=qlast.ObjectRef(name='tuple', ), subtypes=[ shell_to_ast(schema, st, _name=sn) for sn, st in t.iter_subtypes(schema) ]) else: result = qlast.TypeName(name=_name, maintype=qlast.ObjectRef(name='tuple', ), subtypes=[ shell_to_ast(schema, st) for st in t.get_subtypes(schema) ]) elif isinstance(t, s_types.ArrayTypeShell): result = qlast.TypeName(name=_name, maintype=qlast.ObjectRef(name='array', ), subtypes=[ shell_to_ast(schema, st) for st in t.get_subtypes(schema) ]) elif isinstance(t, s_types.UnionTypeShell): components = t.get_components(schema) result = typeref_to_ast(schema, components[0]) for component in components[1:]: result = qlast.TypeOp( left=result, op='|', right=typeref_to_ast(schema, component), ) elif isinstance(t, so.ObjectShell): name = t.name if isinstance(name, sn.SchemaName): qlref = qlast.ObjectRef( module=name.module, name=name.name, ) else: qlref = qlast.ObjectRef( module='', name=name, ) result = qlast.TypeName( name=_name, maintype=qlref, ) else: raise NotImplementedError(f'cannot represent {t!r} as a shell') return result
def typeref_to_ast( schema: s_schema.Schema, ref: Union[so.Object, so.ObjectShell], *, _name: Optional[str] = None, disambiguate_std: bool = False, ) -> qlast.TypeExpr: from . import types as s_types if isinstance(ref, so.ObjectShell): return shell_to_ast(schema, ref) else: t = ref result: qlast.TypeExpr components: Tuple[so.Object, ...] if t.is_type() and cast(s_types.Type, t).is_any(schema): result = qlast.TypeName(name=_name, maintype=qlast.AnyType()) elif t.is_type() and cast(s_types.Type, t).is_anytuple(schema): result = qlast.TypeName(name=_name, maintype=qlast.AnyTuple()) elif isinstance(t, s_types.Tuple) and t.is_named(schema): result = qlast.TypeName(name=_name, maintype=qlast.ObjectRef(name=t.schema_name), subtypes=[ typeref_to_ast( schema, st, _name=sn, disambiguate_std=disambiguate_std) for sn, st in t.iter_subtypes(schema) ]) elif isinstance(t, (s_types.Array, s_types.Tuple)): # Here the concrete type Array is used because t.schema_name is used, # which is not defined for more generic collections and abcs result = qlast.TypeName(name=_name, maintype=qlast.ObjectRef(name=t.schema_name), subtypes=[ typeref_to_ast( schema, st, disambiguate_std=disambiguate_std) for st in t.get_subtypes(schema) ]) elif t.is_type() and cast(s_types.Type, t).is_union_type(schema): object_set: Optional[so.ObjectSet[s_types.Type]] = \ cast(s_types.Type, t).get_union_of(schema) assert object_set is not None component_objects = tuple(object_set.objects(schema)) result = typeref_to_ast(schema, component_objects[0], disambiguate_std=disambiguate_std) for component_object in component_objects[1:]: result = qlast.TypeOp( left=result, op='|', right=typeref_to_ast(schema, component_object, disambiguate_std=disambiguate_std), ) elif isinstance(t, so.QualifiedObject): t_name = t.get_name(schema) module = t_name.module if disambiguate_std and module == 'std': # If the type is defined in 'std::', replace the module to # '__std__' to handle cases where 'std' name is aliased to # another module. module = '__std__' result = qlast.TypeName(name=_name, maintype=qlast.ObjectRef(module=module, name=t_name.name)) else: raise NotImplementedError(f'cannot represent {t!r} as a shell') return result
def reduce_ANYTYPE(self, *kids): self.val = qlast.TypeName(maintype=qlast.AnyType())
def _init_constraints(self, constraints): for constraint, decl in constraints.items(): attrs = {a.name.name: a.value for a in decl.fields} assert 'subject' not in attrs # TODO: Add proper validation assert 'subjectexpr' not in attrs # TODO: Add proper validation self._schema, params = s_func.FuncParameterList.from_ast( self._schema, decl, self._mod_aliases, func_fqname=constraint.get_name(self._schema), prepend=[ qlast.FuncParam( name='__subject__', type=qlast.TypeName(maintype=qlast.AnyType(), ), typemod=qltypes.TypeModifier.SINGLETON, kind=qltypes.ParameterKind.POSITIONAL, default=None, ), ], ) for param in params.objects(self._schema): p_kind = param.get_kind(self._schema) if p_kind is qltypes.ParameterKind.NAMED_ONLY: raise errors.InvalidConstraintDefinitionError( 'named only parameters are not allowed ' 'in this context', context=decl.context) if param.get_default(self._schema) is not None: raise errors.InvalidConstraintDefinitionError( 'constraints do not support parameters ' 'with defaults', context=decl.context) anchors, _ = qlcompiler.get_param_anchors_for_callable( params, self._schema) expr = attrs.pop('expr', None) if expr is not None: self._schema = constraint.set_field_value( self._schema, 'expr', s_expr.Expression.compiled( s_expr.Expression.from_ast(expr, self._schema, self._mod_aliases), schema=self._schema, modaliases=self._mod_aliases, anchors=anchors, func_params=params, allow_generic_type_output=True, parent_object_type=type(constraint), ), ) subjexpr = decl.subject if subjexpr is not None: self._schema = constraint.set_field_value( self._schema, 'subjectexpr', s_expr.Expression.compiled( s_expr.Expression.from_ast(subjexpr, self._schema, self._mod_aliases), schema=self._schema, modaliases=self._mod_aliases, anchors=anchors, func_params=params, allow_generic_type_output=True, parent_object_type=type(constraint), ), ) self._schema = constraint.set_field_value(self._schema, 'params', params)