def type_to_ql_typeref(t: s_obj.Object, *, _name=None, ctx: context.ContextLevel) -> qlast.TypeName: if 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.element_types.items() ]) 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() ]) return result
def _apply_field_ast(self, context, node, op): if op.property == 'spectargets': if op.new_value: node.commands.append( qlast.AlterTarget(targets=[ qlast.ObjectRef(name=t.classname.name, module=t.classname.module) for t in op.new_value ])) elif op.property == 'target': if op.new_value: node.commands.append( qlast.AlterTarget(targets=[ qlast.ObjectRef(name=op.new_value.classname.name, module=op.new_value.classname.module) ])) elif op.property == 'source': pass elif op.property == 'search': if op.new_value: v = qlast.Constant(value=str(op.new_value.weight)) self._set_attribute_ast(context, node, 'search_weight', v) else: self._drop_attribute_ast(context, node, 'search_weight') else: super()._apply_field_ast(context, node, op)
def _get_ast(self, schema, context): value = self.new_value new_value_empty = \ (value is None or (isinstance(value, collections.abc.Container) and not value)) old_value_empty = \ (self.old_value is None or (isinstance(self.old_value, collections.abc.Container) and not self.old_value)) if new_value_empty and not old_value_empty: op = qlast.DropAttributeValue( name=qlast.ObjectRef(module='', name=self.property)) return op if new_value_empty and old_value_empty: return if isinstance(value, s_expr.ExpressionText): value = edgeql.parse(str(value)) elif utils.is_nontrivial_container(value): value = qlast.Tuple(elements=[ qlast.BaseConstant.from_python(el) for el in value ]) else: value = qlast.BaseConstant.from_python(value) as_expr = isinstance(value, qlast.ExpressionText) op = qlast.SetField( name=qlast.ObjectRef(module='', name=self.property), value=value, as_expr=as_expr) return op
def visit_Set(self, node): if node.expr is not None: result = self.visit(node.expr) else: links = [] while node.rptr and (not node.show_as_anchor or self.context.inline_anchors): rptr = node.rptr ptrcls = rptr.ptrcls pname = ptrcls.shortname if isinstance(rptr.target.scls, s_objtypes.ObjectType): target = rptr.target.scls.shortname target = qlast.TypeName(maintype=qlast.ObjectRef( name=target.name, module=target.module)) else: target = None link = qlast.Ptr( ptr=qlast.ObjectRef(name=pname.name, ), direction=rptr.direction, target=target, ) if isinstance(ptrcls.source, s_links.Link): link.type = 'property' links.append(link) node = node.rptr.source result = qlast.Path() if node.show_as_anchor and not self.context.inline_anchors: if issubclass(node.show_as_anchor, qlast.Expr): step = node.show_as_anchor() else: step = qlast.ObjectRef(name=node.show_as_anchor) else: step = qlast.ObjectRef(name=node.scls.shortname.name, module=node.scls.shortname.module) result.steps.append(step) result.steps.extend(reversed(links)) if node.shape: result = qlast.Shape(expr=result, elements=[]) for el in node.shape: rptr = el.rptr ptrcls = rptr.ptrcls pn = ptrcls.shortname pn = qlast.ShapeElement(expr=qlast.Path(steps=[ qlast.Ptr(ptr=qlast.ObjectRef(name=pn.name), direction=rptr.direction) ])) result.elements.append(pn) return result
def _apply_rebase_ast(self, context, node, op): from . import inheriting parent_ctx = context.get(sd.CommandContextToken) parent_op = parent_ctx.op rebase = next( iter(parent_op.get_subcommands(type=inheriting.RebaseNamedObject))) dropped = rebase.removed_bases added = rebase.added_bases if dropped: node.commands.append( qlast.AlterDropInherit(bases=[ qlast.ObjectRef(module=b.classname.module, name=b.classname.name) for b in dropped ])) for bases, pos in added: if isinstance(pos, tuple): pos_node = qlast.Position(position=pos[0], ref=qlast.ObjectRef( module=pos[1].classname.module, name=pos[1].classname.name)) else: pos_node = qlast.Position(position=pos) node.commands.append( qlast.AlterAddInherit(bases=[ qlast.ObjectRef(module=b.classname.module, name=b.classname.name) for b in bases ], position=pos_node))
def _float_to_path(self, token, context): from edb.lang.schema import pointers as s_pointers # make sure that the float is of the type 0.1 parts = token.val.split('.') if not (len(parts) == 2 and parts[0].isdigit() and parts[1].isdigit()): raise EdgeQLSyntaxError( f"Unexpected {token.val!r}", context=token.context) # context for the AST is established manually here return [ qlast.Ptr( ptr=qlast.ObjectRef( name=parts[0], context=token.context, ), direction=s_pointers.PointerDirection.Outbound, context=context, ), qlast.Ptr( ptr=qlast.ObjectRef( name=parts[1], context=token.context, ), direction=s_pointers.PointerDirection.Outbound, context=token.context, ) ]
def visit_order(self, node): # if there is no specific ordering, then order by id if not node.value: return [ qlast.SortExpr( path=qlast.Path( steps=[qlast.Ptr(ptr=qlast.ObjectRef(name='id'))], partial=True, ), direction=qlast.SortAsc, ) ] # Ordering is handled by specifying a list of special Ordering objects. # Validation is already handled by this point. orderby = [] for enum in node.value: name, direction, nulls = self._visit_order_item(enum) orderby.append( qlast.SortExpr( path=qlast.Path( steps=[qlast.Ptr(ptr=qlast.ObjectRef(name=name))], partial=True, ), direction=direction, nones_order=nulls, )) return orderby
def type_to_ql_typeref(t: s_obj.Object) -> qlast.TypeName: if not isinstance(t, s_types.Collection): result = qlast.TypeName( maintype=qlast.ObjectRef(module=t.name.module, name=t.name.name)) else: result = qlast.TypeName( maintype=qlast.ObjectRef(name=t.schema_name), subtypes=[type_to_ql_typeref(st) for st in t.get_subtypes()]) return result
def typeref_to_ast(t: so.Object) -> ql_ast.TypeName: if not isinstance(t, s_types.Collection): if isinstance(t, so.ObjectRef): name = t.classname else: name = t.name result = ql_ast.TypeName( maintype=ql_ast.ObjectRef(module=name.module, name=name.name)) else: result = ql_ast.TypeName( maintype=ql_ast.ObjectRef(name=t.schema_name), subtypes=[typeref_to_ast(st) for st in t.get_subtypes()]) return result
def _apply_field_ast(self, context, node, op): if op.property == 'name': pass elif op.property == 'event': node.event = qlast.ObjectRef( name=op.new_value.classname.name, module=op.new_value.classname.module ) elif op.property == 'actions': node.actions = [qlast.ObjectRef( name=a.classname.name, module=a.classname.module ) for a in op.new_value] else: pass
def _get_ast(self, context): value = self.new_value new_value_empty = \ (value is None or (isinstance(value, collections.Container) and not value)) old_value_empty = \ (self.old_value is None or (isinstance(self.old_value, collections.Container) and not self.old_value)) if new_value_empty and not old_value_empty: op = qlast.DropAttributeValue( name=qlast.ObjectRef(module='', name=self.property)) return op if new_value_empty and old_value_empty: return if isinstance(value, s_expr.ExpressionText): value = edgeql.parse(str(value)) elif utils.is_nontrivial_container(value): value = qlast.Tuple(elements=[ qlast.Constant(value=el) for el in value ]) elif isinstance(value, nlang.WordCombination): forms = value.as_dict() if len(forms) > 1: items = [] for k, v in forms.items(): items.append(( qlast.Constant(value=k), qlast.Constant(value=v) )) value = qlast.Array(elements=[ qlast.Tuple(elements=[k, v]) for k, v in items ]) else: value = qlast.Constant(value=str(value)) else: value = qlast.Constant(value=value) as_expr = isinstance(value, qlast.ExpressionText) op = qlast.CreateAttributeValue( name=qlast.ObjectRef(module='', name=self.property), value=value, as_expr=as_expr) return op
def _apply_field_ast(self, context, node, op): objtype = context.get(LinkSourceCommandContext) if op.property == 'is_derived': pass elif op.property == 'spectargets': if op.new_value: node.targets = [ qlast.ObjectRef(name=t.classname.name, module=t.classname.module) for t in op.new_value ] elif op.property == 'default': self._encode_default(context, node, op) elif op.property == 'required': node.is_required = op.new_value elif op.property == 'source': pass elif op.property == 'search': if op.new_value: v = qlast.Constant(value=str(op.new_value.weight)) self._set_attribute_ast(context, node, 'search_weight', v) elif op.property == 'target' and objtype: if not node.targets: t = op.new_value node.targets = [utils.typeref_to_ast(t)] else: super()._apply_field_ast(context, node, op)
def reduce_NodeName_Shape(self, *kids): self.val = qlast.Shape(expr=qlast.Path(steps=[ qlast.ObjectRef(name=kids[0].val.name, module=kids[0].val.module, context=kids[0].context) ]), elements=kids[1].val)
def _get_ast(self, schema, context): astnode = self._get_ast_node(context) if isinstance(self.classname, sn.Name): nname = sn.shortname_from_fullname(self.classname) name = qlast.ObjectRef(module=nname.module, name=nname.name) else: name = qlast.ObjectRef(module='', name=self.classname) if astnode.get_field('name'): op = astnode(name=name) else: op = astnode() self._apply_fields_ast(schema, context, op) return op
def _apply_field_ast(self, schema, context, node, op): if op.property in ('id', 'name'): pass elif op.property == 'bases': if not isinstance(op.new_value, so.ObjectList): bases = so.ObjectList.create(schema, op.new_value) else: bases = op.new_value base_names = bases.names(schema, allow_unresolved=True) node.bases = [ qlast.TypeName( maintype=qlast.ObjectRef( name=b.name, module=b.module ) ) for b in base_names ] elif op.property == 'mro': pass elif op.property == 'is_abstract': node.is_abstract = op.new_value elif op.property == 'is_final': node.is_final = op.new_value else: super()._apply_field_ast(schema, context, node, op)
def edb_base_name(self): base = self.edb_base.get_name(self.edb_schema) return codegen.generate_source( qlast.ObjectRef( module=base.module, name=base.name, ))
def reduce_VIEW_Identifier_TurnstileBlob(self, *kids): self.val = esast.ViewDeclaration( name=kids[1].val, attributes=[esast.Attribute( name=qlast.ObjectRef(name='expr'), value=kids[2].val) ])
def reduce_VIEW_Identifier_AssignmentBlob(self, *kids): self.val = esast.ViewDeclaration( name=kids[1].val, fields=[esast.Field( name=qlast.ObjectRef(name='expr'), value=kids[2].val) ])
def visit_TypeCast(self, node): if node.type.subtypes: typ = qlast.TypeName( maintype=qlast.ObjectRef(name=node.type.maintype), subtypes=[ qlast.ObjectRef(module=stn.module, name=stn.name) for stn in node.type.subtypes ]) else: mtn = node.type.maintype mt = qlast.ObjectRef(module=mtn.module, name=mtn.name) typ = qlast.TypeName(maintype=mt) result = qlast.TypeCast(expr=self.visit(node.expr), type=typ) return result
def get_path_prefix(self, end_trim=None): # flatten the path path = [step for psteps in self._context.path for step in psteps] # find the first shadowed root for i, step in enumerate(path): base = step.type if isinstance(base, gt.GQLShadowType): break # trim the rest of the path path = path[i + 1:end_trim] prefix = [qlast.ObjectRef(module=base.module, name=base.short_name)] prefix.extend( qlast.Ptr(ptr=qlast.ObjectRef(name=step.name)) for step in path) return prefix
def _apply_fields_ast(self, context, node): super()._apply_fields_ast(context, node) if node.event is None: event_name = Policy.get_shortname(self.classname) node.event = qlast.ObjectRef( name=event_name.name, module=event_name.module )
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()]) return result
def reduce_DOT_ICONST(self, *kids): # this is a valid link-like syntax for accessing unnamed tuples from edb.lang.schema import pointers as s_pointers self.val = qlast.Ptr( ptr=qlast.ObjectRef(name=kids[1].val), direction=s_pointers.PointerDirection.Outbound )
def visit_TypeRef(self, node): # Bare TypeRef only appears as rhs of IS [NOT] and is always # an object type reference. mtn = node.maintype result = qlast.Path( steps=[qlast.ObjectRef(module=mtn.module, name=mtn.name)]) return result
def _set_attribute_ast(self, context, node, name, value): if isinstance(value, expr.ExpressionText): value = qlast.ExpressionText(expr=str(value)) as_expr = isinstance(value, qlast.ExpressionText) name_ref = qlast.ObjectRef( name=name, module='') node.commands.append(qlast.CreateAttributeValue( name=name_ref, value=value, as_expr=as_expr))
def _prepare_field(self, node): path = self._context.path[-1] include_base = self._context.include_base[-1] is_top = self._is_top_level_field(node) spath = self._context.path[-1] prevt, target = self._get_parent_and_current_type() # insert normal or specialized link steps = [] if include_base: base = spath[0].type steps.append( qlast.ObjectRef(module=base.module, name=base.short_name)) steps.append(qlast.Ptr(ptr=qlast.ObjectRef(name=node.name))) return is_top, path, prevt, target, steps
def reduce_ARRAY_LANGBRACKET_NonArrayTypeName_OptDimensions_RANGBRACKET( self, *kids): subtype = kids[2].val dimensions = kids[3].val self.val = qlast.TypeName( maintype=qlast.ObjectRef(name='array'), subtypes=[subtype], dimensions=dimensions, )
def reduce_CreateViewShortStmt(self, *kids): r"""%reduce \ CREATE VIEW NodeName TURNSTILE Expr \ """ self.val = qlast.CreateView(name=kids[2].val, commands=[ qlast.CreateAttributeValue( name=qlast.ObjectRef(name='expr'), value=kids[4].val, as_expr=True) ])
def _get_ast(self, context): metaclass = self.get_schema_metaclass() astnode = self._get_ast_node(context) if isinstance(self.classname, sn.Name): if hasattr(metaclass, 'get_shortname'): nname = metaclass.get_shortname(self.classname) else: nname = self.classname name = qlast.ObjectRef(module=nname.module, name=nname.name) else: name = qlast.ObjectRef(module='', name=self.classname) if astnode.get_field('name'): op = astnode(name=name) else: op = astnode() self._apply_fields_ast(context, op) return op
def _apply_field_ast(self, schema, context, node, op): if op.property == 'target': if op.new_value: node.commands.append( qlast.AlterTarget(targets=[ qlast.ObjectRef(name=op.new_value.classname.name, module=op.new_value.classname.module) ])) elif op.property == 'source': pass else: super()._apply_field_ast(schema, context, node, op)