WIP: correct parsing #1

Draft
bruvduroiu wants to merge 1 commit from fix/parsing into main
2 changed files with 53 additions and 24 deletions

View file

@ -180,8 +180,8 @@ pub const Property = struct {
base: BaseDefinition, base: BaseDefinition,
type: ?[]const u8 = null, type: ?[]const u8 = null,
pub fn init(allocator: Allocator, name: []const u8, documentation: ?[]const u8) !*Self { pub fn init(allocator: Allocator, name: []const u8, propType: []const u8) !*Self {
const base = try BaseDefinition.initBase(allocator, name, documentation); const base = try BaseDefinition.initBase(allocator, name, null);
errdefer base.deinitBase(); errdefer base.deinitBase();
const p = try allocator.create(Self); const p = try allocator.create(Self);
@ -189,7 +189,7 @@ pub const Property = struct {
p.* = .{ p.* = .{
.base = base, .base = base,
.type = null, .type = propType,
}; };
return p; return p;
} }
@ -230,8 +230,8 @@ pub const ClassProperty = struct {
property: Property, property: Property,
class_name: []const u8, class_name: []const u8,
pub fn init(allocator: Allocator, name: []const u8, class_name: []const u8, documentation: ?[]const u8) !*Self { pub fn init(allocator: Allocator, name: []const u8, class_name: []const u8) !*Self {
const prop = try Property.init(allocator, name, documentation); const prop = try Property.init(allocator, name, null);
errdefer prop.deinit(); errdefer prop.deinit();
const class_name_copy = try allocator.dupe(u8, class_name); const class_name_copy = try allocator.dupe(u8, class_name);

View file

@ -142,16 +142,16 @@ pub const CodeParser = struct {
} }
fn processCapture(self: *Self, capture_name: []const u8, node: ts.Node, name: []const u8, doc: ?[]const u8, definitions: *DefinitionList) !void { fn processCapture(self: *Self, capture_name: []const u8, node: ts.Node, name: []const u8, doc: ?[]const u8, definitions: *DefinitionList) !void {
if (std.mem.eql(u8, capture_name, "function")) { if (std.mem.eql(u8, capture_name, "function") or std.mem.eql(u8, capture_name, "arrow_function")) {
const func = try Function.init(self.allocator, name, doc); const func = try Function.init(self.allocator, name, doc);
try definitions.append(.{ .function = func }); try definitions.append(.{ .function = func });
} else if (std.mem.eql(u8, capture_name, "class")) { } else if (std.mem.eql(u8, capture_name, "class") or std.mem.eql(u8, capture_name, "struct")) {
const class = try Class.init(self.allocator, name, doc); const class = try Class.init(self.allocator, name, doc);
try self.class_map.put(name, class); try self.class_map.put(name, class);
try definitions.append(.{ .class = class }); try definitions.append(.{ .class = class });
} else if (std.mem.eql(u8, capture_name, "method")) { } else if (std.mem.eql(u8, capture_name, "method")) {
// Find the parent class // Find the parent class
const class_name = self.findParentClassName(node); const class_name = if (ancestor(node, "class_definition")) |classNode| self.source[classNode.startByte()..classNode.endByte()] else null;
if (class_name) |cn| { if (class_name) |cn| {
const method = try Method.init(self.allocator, name, cn, doc); const method = try Method.init(self.allocator, name, cn, doc);
@ -171,7 +171,7 @@ pub const CodeParser = struct {
std.mem.eql(u8, capture_name, "class_variable")) std.mem.eql(u8, capture_name, "class_variable"))
{ {
// Find the parent class // Find the parent class
const class_name = self.findParentClassName(node); const class_name = if (ancestor(node, "class_definition")) |classNode| self.source[classNode.startByte()..classNode.endByte()] else null;
if (class_name) |cn| { if (class_name) |cn| {
const prop = try ClassProperty.init(self.allocator, name, cn, doc); const prop = try ClassProperty.init(self.allocator, name, cn, doc);
@ -188,24 +188,53 @@ pub const CodeParser = struct {
try definitions.append(.{ .property = prop }); try definitions.append(.{ .property = prop });
} }
} else if (std.mem.eql(u8, capture_name, "assignment")) { } else if (std.mem.eql(u8, capture_name, "assignment")) {
const prop = try Property.init(self.allocator, name, doc); ancestor(node, "impl_item") orelse ancestor(node, "class_declaration") orelse ancestor(node, "class_definition") orelse return;
ancestor(node, "function_declaration") orelse ancestor(node, "function_definition") orelse return;
const left = if (node.childByFieldName("left")) |n| self.source[n.startByte()..n.endByte()];
if (~std.mem.eql(u8, left, "") and self.language_type == .go and ~std.ascii.isUpper(left[0])) {
return;
}
const nodeType = if (node.childByFieldName("type")) |n| self.source[n.startByte()..n.endByte()] else "";
const prop = try Property.init(
self.allocator,
name,
nodeType,
);
try definitions.append(.{ .property = prop }); try definitions.append(.{ .property = prop });
} else if (std.mem.eql(u8, capture_name, "docstring")) { } else if (std.mem.eql(u8, capture_name, "docstring")) {
// Handle docstrings - already processed in extractDocumentation // Handle docstrings - already processed in extractDocumentation
} }
} }
};
fn findParentClassName(self: *Self, node: ts.Node) ?[]const u8 { fn ancestor(node: ts.Node, parentType: []const u8) ?ts.Node {
var current = node.parent(); var current = node.parent();
while (current) |parent| { while (current) |parent| {
if (std.mem.eql(u8, parent.kind(), "class_definition")) { if (std.mem.eql(u8, parent.kind(), parentType)) {
if (parent.childByFieldName("name")) |name_node| { return current;
return self.source[name_node.startByte()..name_node.endByte()];
}
return null;
} }
current = parent.parent(); current = parent.parent();
} }
return null; return null;
}
fn descendant(node: ts.Node, childType: []const u8) ?*ts.Node {
const cursor = node.walk();
defer cursor.destroy();
for (node.descendantCount()) |i| {
cursor.gotoDescendant(i);
const maybeDescendant: *ts.Node = cursor.node();
if (std.mem.eql(u8, maybeDescendant, childType)) {
return maybeDescendant;
} }
}; }
return null;
}