Exemple #1
0
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
Exemple #2
0
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
Exemple #3
0
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
Exemple #4
0
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
Exemple #5
0
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
Exemple #6
0
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
Exemple #7
0
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
Exemple #8
0
 def reduce_ANYTYPE(self, *kids):
     self.val = qlast.TypeName(maintype=qlast.AnyType())
Exemple #9
0
    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)