mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-06-11 09:35:59 -04:00
xpath: apply review style/convention feedback
- Rename Result.zig / Ast.zig / Functions.zig to snake_case (no
top-level fields per Zig style guide)
- Restructure imports across xpath module: lib (std/lp) → relative
(further → nearer) → aliases
- Move `frame` to last parameter on Evaluator.evaluate, searchAll,
Functions.call, idFn (matches js bridge convention); call sites
updated in webapi/XPath{Result,Expression}.zig and cdp/domains/dom.zig
- Local-pos style in XPathResult.iterateNext
This commit is contained in:
@@ -33,7 +33,7 @@ const Node = @import("Node.zig");
|
||||
const XPathResult = @import("XPathResult.zig");
|
||||
|
||||
const xpath = struct {
|
||||
const Ast = @import("../xpath/Ast.zig");
|
||||
const Ast = @import("../xpath/ast.zig");
|
||||
const Parser = @import("../xpath/Parser.zig");
|
||||
const Evaluator = @import("../xpath/Evaluator.zig");
|
||||
};
|
||||
@@ -76,7 +76,7 @@ pub fn evaluate(
|
||||
const arena = try frame.getArena(.medium, "XPathResult");
|
||||
errdefer frame.releaseArena(arena);
|
||||
|
||||
const eval_result = try xpath.Evaluator.evaluate(arena, frame, self._expr, context_node);
|
||||
const eval_result = try xpath.Evaluator.evaluate(arena, self._expr, context_node, frame);
|
||||
return XPathResult.fromResult(arena, requested_type, eval_result);
|
||||
}
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ const Node = @import("Node.zig");
|
||||
const xpath = struct {
|
||||
const Parser = @import("../xpath/Parser.zig");
|
||||
const Evaluator = @import("../xpath/Evaluator.zig");
|
||||
const Result = @import("../xpath/Result.zig");
|
||||
const Result = @import("../xpath/result.zig");
|
||||
};
|
||||
|
||||
const Allocator = std.mem.Allocator;
|
||||
@@ -101,7 +101,7 @@ pub fn fromExpression(
|
||||
// dupe into our long-lived arena before parsing.
|
||||
const owned = try arena.dupe(u8, expression);
|
||||
const expr = try xpath.Parser.parse(arena, owned);
|
||||
const result = try xpath.Evaluator.evaluate(arena, frame, expr, context_node);
|
||||
const result = try xpath.Evaluator.evaluate(arena, expr, context_node, frame);
|
||||
return fromResult(arena, requested_type, result);
|
||||
}
|
||||
|
||||
@@ -220,9 +220,10 @@ pub fn iterateNext(self: *XPathResult) !?*Node {
|
||||
if (self._type != UNORDERED_NODE_ITERATOR_TYPE and self._type != ORDERED_NODE_ITERATOR_TYPE) {
|
||||
return error.InvalidStateError;
|
||||
}
|
||||
if (self._iter_pos >= self._value.nodes.len) return null;
|
||||
const node = self._value.nodes[self._iter_pos];
|
||||
self._iter_pos += 1;
|
||||
const pos = self._iter_pos;
|
||||
if (pos >= self._value.nodes.len) return null;
|
||||
const node = self._value.nodes[pos];
|
||||
self._iter_pos = pos + 1;
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,17 +30,19 @@
|
||||
//! reverse-axis positional predicates evaluate against proximity.
|
||||
|
||||
const std = @import("std");
|
||||
const Allocator = std.mem.Allocator;
|
||||
const lp = @import("lightpanda");
|
||||
|
||||
const Ast = @import("Ast.zig");
|
||||
const Parser = @import("Parser.zig");
|
||||
const Result = @import("Result.zig");
|
||||
const Functions = @import("Functions.zig");
|
||||
const Node = @import("../webapi/Node.zig");
|
||||
|
||||
const Ast = @import("ast.zig");
|
||||
const Parser = @import("Parser.zig");
|
||||
const Result = @import("result.zig");
|
||||
const Functions = @import("functions.zig");
|
||||
|
||||
const Frame = lp.Frame;
|
||||
const Element = Node.Element;
|
||||
const Document = Node.Document;
|
||||
const Frame = lp.Frame;
|
||||
const Allocator = std.mem.Allocator;
|
||||
|
||||
const Evaluator = @This();
|
||||
|
||||
@@ -62,7 +64,7 @@ frame: *Frame,
|
||||
|
||||
/// Public entry. Returns the AST's value; node-sets are sorted into
|
||||
/// document order before return per XPath spec §3.3.
|
||||
pub fn evaluate(arena: Allocator, frame: *Frame, expr: *const Ast.Expr, context_node: *Node) Error!Result.Result {
|
||||
pub fn evaluate(arena: Allocator, expr: *const Ast.Expr, context_node: *Node, frame: *Frame) Error!Result.Result {
|
||||
var ev = Evaluator{ .arena = arena, .frame = frame };
|
||||
const result = try ev.evalExpr(expr, context_node, 1, 1);
|
||||
if (result == .node_set) {
|
||||
@@ -77,9 +79,9 @@ pub const SearchError = Error || Parser.Error;
|
||||
/// evaluate and unwrap the node-set. Top-level scalar expressions yield
|
||||
/// an empty slice (decision #3 — these APIs are for finding nodes, not
|
||||
/// arbitrary computation).
|
||||
pub fn searchAll(arena: Allocator, frame: *Frame, root: *Node, expression: []const u8) SearchError![]const *Node {
|
||||
pub fn searchAll(arena: Allocator, root: *Node, expression: []const u8, frame: *Frame) SearchError![]const *Node {
|
||||
const expr = try Parser.parse(arena, expression);
|
||||
return switch (try evaluate(arena, frame, expr, root)) {
|
||||
return switch (try evaluate(arena, expr, root, frame)) {
|
||||
.node_set => |ns| ns,
|
||||
else => &.{},
|
||||
};
|
||||
@@ -506,7 +508,7 @@ fn evalFnCall(self: *Evaluator, fc: Ast.FnCall, ctx: *Node, pos: usize, size: us
|
||||
const eval_args = try self.arena.alloc(Result.Result, fc.args.len);
|
||||
for (fc.args, 0..) |a, i| eval_args[i] = try self.evalExpr(a, ctx, pos, size);
|
||||
|
||||
return Functions.call(self.arena, self.frame, fc.name, eval_args, ctx);
|
||||
return Functions.call(self.arena, fc.name, eval_args, ctx, self.frame);
|
||||
}
|
||||
|
||||
// ----- helpers -----
|
||||
@@ -726,7 +728,7 @@ test "Evaluator: searchAll on scalar expression returns empty (decision #3)" {
|
||||
// the Frame or the context node. Adding a DOM-touching expression
|
||||
// (e.g. `id('x')`) to this list would crash on dereference.
|
||||
inline for (.{ "1 + 2", "'hello'", "true()", "1 = 1" }) |expr| {
|
||||
const nodes = try searchAll(a, @ptrFromInt(0x1000), @ptrFromInt(0x2000), expr);
|
||||
const nodes = try searchAll(a, @ptrFromInt(0x2000), expr, @ptrFromInt(0x1000));
|
||||
try testing.expectEqual(@as(usize, 0), nodes.len);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,11 +25,12 @@
|
||||
//! and is valid for as long as the arena and input outlive it.
|
||||
|
||||
const std = @import("std");
|
||||
const Allocator = std.mem.Allocator;
|
||||
|
||||
const Tokenizer = @import("Tokenizer.zig");
|
||||
const Ast = @import("ast.zig");
|
||||
|
||||
const Token = Tokenizer.Token;
|
||||
const Ast = @import("Ast.zig");
|
||||
const Allocator = std.mem.Allocator;
|
||||
|
||||
const Parser = @This();
|
||||
|
||||
|
||||
@@ -37,14 +37,16 @@
|
||||
//! Allocations land in the caller's per-evaluation arena.
|
||||
|
||||
const std = @import("std");
|
||||
const Allocator = std.mem.Allocator;
|
||||
const lp = @import("lightpanda");
|
||||
|
||||
const Result = @import("Result.zig");
|
||||
const Node = @import("../webapi/Node.zig");
|
||||
|
||||
const Result = @import("result.zig");
|
||||
|
||||
const Frame = lp.Frame;
|
||||
const Element = Node.Element;
|
||||
const Document = Node.Document;
|
||||
const Frame = lp.Frame;
|
||||
const Allocator = std.mem.Allocator;
|
||||
|
||||
pub const Error = error{
|
||||
OutOfMemory,
|
||||
@@ -59,14 +61,14 @@ pub const Error = error{
|
||||
/// last lookup stop.
|
||||
pub fn call(
|
||||
arena: Allocator,
|
||||
frame: *Frame,
|
||||
name: []const u8,
|
||||
args: []const Result.Result,
|
||||
ctx: *Node,
|
||||
frame: *Frame,
|
||||
) Error!Result.Result {
|
||||
// -- Node-set --
|
||||
if (eql(name, "count")) return .{ .number = countFn(args) };
|
||||
if (eql(name, "id")) return idFn(arena, frame, args, ctx);
|
||||
if (eql(name, "id")) return idFn(arena, args, ctx, frame);
|
||||
if (eql(name, "local-name")) return .{ .string = try localNameFn(arena, args, ctx) };
|
||||
if (eql(name, "name")) return .{ .string = try nameFn(arena, args, ctx) };
|
||||
if (eql(name, "namespace-uri")) return .{ .string = "" };
|
||||
@@ -111,7 +113,7 @@ fn countFn(args: []const Result.Result) f64 {
|
||||
return @floatFromInt(args[0].node_set.len);
|
||||
}
|
||||
|
||||
fn idFn(arena: Allocator, frame: *Frame, args: []const Result.Result, ctx: *Node) Error!Result.Result {
|
||||
fn idFn(arena: Allocator, args: []const Result.Result, ctx: *Node, frame: *Frame) Error!Result.Result {
|
||||
if (args.len == 0) return .{ .node_set = &.{} };
|
||||
|
||||
// Polyfill: node-set arg → join `stringVal(n)` of each by ' '. Scalar
|
||||
@@ -345,7 +347,7 @@ fn evalScalar(a: Allocator, src: []const u8) !Result.Result {
|
||||
// Synthetic Frame/Node pointers — the public `evaluate` entry only
|
||||
// touches the Frame for path/axis evaluation. Pure-scalar expressions
|
||||
// (arithmetic, function calls returning scalars) never deref it.
|
||||
return Evaluator.evaluate(a, @ptrFromInt(0x1000), expr, @ptrFromInt(0x2000));
|
||||
return Evaluator.evaluate(a, expr, @ptrFromInt(0x2000), @ptrFromInt(0x1000));
|
||||
}
|
||||
|
||||
test "Functions: count() of non-node-set returns 0" {
|
||||
@@ -26,10 +26,11 @@
|
||||
//! shortcuts inherited from the polyfill (decision #2).
|
||||
|
||||
const std = @import("std");
|
||||
const Allocator = std.mem.Allocator;
|
||||
|
||||
const Node = @import("../webapi/Node.zig");
|
||||
|
||||
const CData = Node.CData;
|
||||
const Allocator = std.mem.Allocator;
|
||||
|
||||
pub const Result = union(enum) {
|
||||
/// Owned by the evaluator's arena. Order is significant only at the
|
||||
@@ -130,7 +130,7 @@ fn performSearch(cmd: *CDP.Command) !void {
|
||||
if (isXPathQuery(params.query)) {
|
||||
const arena = try frame.getArena(.medium, "DOM.performSearch");
|
||||
defer frame.releaseArena(arena);
|
||||
const nodes = try xpath.searchAll(arena, frame, root, params.query);
|
||||
const nodes = try xpath.searchAll(arena, root, params.query, frame);
|
||||
return finishSearch(cmd, bc, nodes);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user