WIP: correct parsing #1
2 changed files with 53 additions and 24 deletions
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue