Skip to content

Commit c6111e7

Browse files
committed
introduce scripty expression validation
superhtml will now be able to report syntax errors in scripty expressions both in CLI mode and LSP mode
1 parent 8bb212b commit c6111e7

File tree

4 files changed

+61
-24
lines changed

4 files changed

+61
-24
lines changed

build.zig.zon

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@
2222
.hash = "lsp_kit-0.1.0-bi_PL18tCgAMyrZ0tgn_0PXnGEvxGWeNkkRygfe9pX9u",
2323
},
2424
.scripty = .{
25-
.url = "git+https://github.com/kristoff-it/scripty#3d56bb62a1aec0b07b634aea42ec46e72e017e33",
26-
.hash = "scripty-0.1.0-LKK5O2zEAADkO2rJa_QbMWwC_YmFnUKC384wwMeBGOQv",
25+
.url = "git+https://github.com/kristoff-it/scripty#76581b7e442f98e2a73769125fa68f07d2a7841b",
26+
.hash = "scripty-0.1.0-LKK5O6T4AADsciwZGm29PGEI4kwVR5cKOZGIdCGMTTi4",
2727
},
2828
},
2929
.paths = .{

src/Ast.zig

Lines changed: 57 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
const Ast = @This();
22

33
const std = @import("std");
4+
const Allocator = std.mem.Allocator;
5+
const Writer = std.Io.Writer;
46
const builtin = @import("builtin");
7+
const scripty = @import("scripty");
58
const html = @import("html.zig");
69
const HtmlNode = html.Ast.Node;
710
const Span = @import("root.zig").Span;
8-
const Writer = std.Io.Writer;
911

1012
const log = std.log.scoped(.ast);
1113

@@ -45,6 +47,18 @@ const Error = struct {
4547
text_and_html_are_mutually_exclusive,
4648
text_and_html_require_an_empty_element,
4749
duplicate_block: Span,
50+
scripty: scripty.Parser.Node.Tag,
51+
52+
pub fn message(k: @This()) []const u8 {
53+
return switch (k) {
54+
else => @tagName(k),
55+
.scripty => |s| s.errorMessage(),
56+
};
57+
}
58+
59+
pub fn format(k: @This(), w: *Writer) !void {
60+
try w.print("{s}", .{k.message()});
61+
}
4862
},
4963

5064
main_location: Span,
@@ -233,7 +247,7 @@ pub fn childrenCount(ast: Ast, node: Node) usize {
233247
return count;
234248
}
235249

236-
pub fn deinit(ast: *const Ast, gpa: std.mem.Allocator) void {
250+
pub fn deinit(ast: *const Ast, gpa: Allocator) void {
237251
var mut_ast = ast.*;
238252
mut_ast.interface.deinit(gpa);
239253
mut_ast.blocks.deinit(gpa);
@@ -242,7 +256,7 @@ pub fn deinit(ast: *const Ast, gpa: std.mem.Allocator) void {
242256
}
243257

244258
pub fn init(
245-
gpa: std.mem.Allocator,
259+
gpa: Allocator,
246260
html_ast: html.Ast,
247261
src: []const u8,
248262
) error{OutOfMemory}!Ast {
@@ -406,7 +420,7 @@ const Parser = struct {
406420
interface: std.StringArrayHashMapUnmanaged(u32) = .{},
407421
blocks: std.StringHashMapUnmanaged(u32) = .{},
408422

409-
pub fn deinit(p: *Parser, gpa: std.mem.Allocator) void {
423+
pub fn deinit(p: *Parser, gpa: Allocator) void {
410424
p.nodes.deinit(gpa);
411425
p.errors.deinit(gpa);
412426
p.interface.deinit(gpa);
@@ -432,7 +446,7 @@ const Parser = struct {
432446

433447
fn buildNode(
434448
p: *Parser,
435-
gpa: std.mem.Allocator,
449+
gpa: Allocator,
436450
elem_idx: u32,
437451
depth: u32,
438452
seen_non_comment_elems: bool,
@@ -657,6 +671,8 @@ const Parser = struct {
657671
.main_location = value.span,
658672
});
659673
}
674+
675+
try p.validateScripty(gpa, value.span);
660676
} else {
661677
if (tmp_result.kind == .ctx) {
662678
try p.errors.append(gpa, .{
@@ -710,25 +726,24 @@ const Parser = struct {
710726
return null;
711727
}
712728

713-
const code = if (attr.value) |v|
714-
v.span.slice(p.src)
715-
else blk: {
729+
if (attr.value) |v| {
730+
try p.validateScripty(gpa, v.span);
731+
} else {
716732
try p.errors.append(gpa, .{
717733
.kind = .missing_attribute_value,
718734
.main_location = name,
719735
});
720-
break :blk "";
721-
};
722-
723-
if (code.len > 0 and
724-
std.mem.indexOfScalar(u8, code, '$') == null)
725-
{
726-
try p.errors.append(gpa, .{
727-
.kind = .unscripted_attr,
728-
.main_location = name,
729-
});
730736
}
731737

738+
// if (code.len > 0 and
739+
// std.mem.indexOfScalar(u8, code, '$') == null)
740+
// {
741+
// try p.errors.append(gpa, .{
742+
// .kind = .unscripted_attr,
743+
// .main_location = name,
744+
// });
745+
// }
746+
732747
switch (special_attr) {
733748
.@":text", .@":html" => {
734749
if (has_attr_text_html) {
@@ -805,7 +820,7 @@ const Parser = struct {
805820
return new_node;
806821
}
807822

808-
fn validate(p: *Parser, gpa: std.mem.Allocator) !void {
823+
fn validate(p: *Parser, gpa: Allocator) !void {
809824
var ast: Ast = undefined;
810825
ast.nodes = p.nodes.items;
811826
var c = ast.cursor(0);
@@ -992,6 +1007,28 @@ const Parser = struct {
9921007
// },
9931008
// }
9941009
}
1010+
1011+
fn validateScripty(p: *Parser, gpa: Allocator, attr_value: Span) error{OutOfMemory}!void {
1012+
const code = attr_value.slice(p.src);
1013+
var scripty_parser: scripty.Parser = .{};
1014+
1015+
while (scripty_parser.next(code)) |node| {
1016+
if (node.tag.isError()) {
1017+
try p.errors.append(gpa, .{
1018+
.kind = .{
1019+
.scripty = node.tag,
1020+
},
1021+
1022+
.main_location = .{
1023+
.start = node.loc.start + attr_value.start,
1024+
.end = node.loc.end + attr_value.start,
1025+
},
1026+
});
1027+
1028+
return;
1029+
}
1030+
}
1031+
}
9951032
};
9961033

9971034
pub fn printInterfaceAsHtml(
@@ -1040,7 +1077,7 @@ pub fn printErrors(
10401077
) !void {
10411078
for (ast.errors) |err| {
10421079
const range = err.main_location.range(src);
1043-
try w.print("{s}:{}:{}: {t}\n", .{
1080+
try w.print("{s}:{}:{}: {f}\n", .{
10441081
path orelse "<stdin>",
10451082
range.start.row,
10461083
range.start.col,

src/cli.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ pub fn main() !void {
8181
fatalHelp();
8282
};
8383

84-
if (cmd == .lsp) lsp_mode = true;
84+
// if (cmd == .lsp) lsp_mode = true;
8585

8686
_ = switch (cmd) {
8787
.check => check_exe.run(gpa, args[2..]),

src/cli/lsp/logic.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ pub fn loadFile(
6666
d.* = .{
6767
.range = range,
6868
.severity = .Error,
69-
.message = @tagName(err.kind),
69+
.message = err.kind.message(),
7070
};
7171
}
7272
res.diagnostics = diags;

0 commit comments

Comments
 (0)