diff --git a/src/definitions.zig b/src/definitions.zig index 1298eb4..fcd4bfa 100644 --- a/src/definitions.zig +++ b/src/definitions.zig @@ -180,8 +180,8 @@ pub const Property = struct { base: BaseDefinition, type: ?[]const u8 = null, - pub fn init(allocator: Allocator, name: []const u8, documentation: ?[]const u8) !*Self { - const base = try BaseDefinition.initBase(allocator, name, documentation); + pub fn init(allocator: Allocator, name: []const u8, propType: []const u8) !*Self { + const base = try BaseDefinition.initBase(allocator, name, null); errdefer base.deinitBase(); const p = try allocator.create(Self); @@ -189,7 +189,7 @@ pub const Property = struct { p.* = .{ .base = base, - .type = null, + .type = propType, }; return p; } @@ -230,8 +230,8 @@ pub const ClassProperty = struct { property: Property, class_name: []const u8, - pub fn init(allocator: Allocator, name: []const u8, class_name: []const u8, documentation: ?[]const u8) !*Self { - const prop = try Property.init(allocator, name, documentation); + pub fn init(allocator: Allocator, name: []const u8, class_name: []const u8) !*Self { + const prop = try Property.init(allocator, name, null); errdefer prop.deinit(); const class_name_copy = try allocator.dupe(u8, class_name); diff --git a/src/parser.zig b/src/parser.zig index 3673d11..77a9dcd 100644 --- a/src/parser.zig +++ b/src/parser.zig @@ -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 { - 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); 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); try self.class_map.put(name, class); try definitions.append(.{ .class = class }); } else if (std.mem.eql(u8, capture_name, "method")) { // 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| { 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")) { // 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| { const prop = try ClassProperty.init(self.allocator, name, cn, doc); @@ -188,24 +188,53 @@ pub const CodeParser = struct { try definitions.append(.{ .property = prop }); } } 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 }); } else if (std.mem.eql(u8, capture_name, "docstring")) { // Handle docstrings - already processed in extractDocumentation } } - - fn findParentClassName(self: *Self, node: ts.Node) ?[]const u8 { - var current = node.parent(); - while (current) |parent| { - if (std.mem.eql(u8, parent.kind(), "class_definition")) { - if (parent.childByFieldName("name")) |name_node| { - return self.source[name_node.startByte()..name_node.endByte()]; - } - return null; - } - current = parent.parent(); - } - return null; - } }; + +fn ancestor(node: ts.Node, parentType: []const u8) ?ts.Node { + var current = node.parent(); + while (current) |parent| { + if (std.mem.eql(u8, parent.kind(), parentType)) { + return current; + } + current = parent.parent(); + } + 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; +}