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_FullTypeExpr_AMPER_FullTypeExpr(self, *kids): self.val = qlast.TypeOp(left=kids[0].val, op='&', right=kids[2].val)
def reduce_TypeExpr_PIPE_TypeExpr(self, *kids): self.val = qlast.TypeOp(left=kids[0].val, op='|', right=kids[2].val)