added: structure method documentation
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Wed, 29 Mar 2023 15:02:27 +0000 (10:02 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Wed, 29 Mar 2023 15:02:27 +0000 (10:02 -0500)
compiler/include/astnodes.h
compiler/src/doc.c
compiler/src/parser.c
compiler/src/symres.c
core/container/result.onyx
core/doc/doc.onyx

index 3134c3954ac5e4c97c123438e252ce12187d323c..c9fd21af7c2f2654ce28021c2d9770b38fc42923 100644 (file)
@@ -1045,6 +1045,7 @@ struct AstInjection     {
     AstTyped* to_inject;
     AstTyped* dest;
     OnyxToken *symbol;
+    OnyxToken *documentation;
 };
 struct AstMemRes        {
     AstTyped_base;
@@ -1101,6 +1102,8 @@ struct AstOverloadedFunction {
     AstType *expected_return_node;
     Type    *expected_return_type;
 
+    AstBinding *original_binding_to_node;
+
     b32 locked : 1;
     b32 only_local_functions : 1;
 };
@@ -1318,6 +1321,8 @@ struct AstFunction {
 
     bh_arr(AstNode *) nodes_that_need_entities_after_clone;
 
+    AstBinding *original_binding_to_node;
+
     b32 is_exported        : 1;
     b32 is_foreign         : 1;
     b32 is_foreign_dyncall : 1;
@@ -1435,6 +1440,8 @@ struct AstMacro {
     AstTyped_base;
 
     AstTyped* body;
+
+    AstBinding *original_binding_to_node;
 };
 
 struct AstDirectiveLibrary {
index 99cf7e1152e702e90782bb6f8ed5b04c7c60295c..6e2505773ede1a1e964b991441ee5bec6ff92ba8 100644 (file)
@@ -144,25 +144,48 @@ void onyx_docs_emit_symbol_info(const char *dest) {
 
 void onyx_docs_submit(OnyxDocInfo *docs, AstBinding *binding) {
     if (!binding->entity || !binding->entity->package) return;
-    if (!(binding->flags & Ast_Flag_Binding_Isnt_Captured)) return;
 
     AstNode *node = binding->node;
+    if (!(binding->flags & Ast_Flag_Binding_Isnt_Captured)) {
+        if (node->kind == Ast_Kind_Function) {
+            ((AstFunction *) node)->original_binding_to_node = binding;
+        }
+
+        if (node->kind == Ast_Kind_Macro) {
+            ((AstMacro *) node)->original_binding_to_node = binding;
+        }
+
+        if (node->kind == Ast_Kind_Polymorphic_Proc) {
+            ((AstFunction *) node)->original_binding_to_node = binding;
+        }
+
+        if (node->kind == Ast_Kind_Overloaded_Function) {
+            ((AstOverloadedFunction *) node)->original_binding_to_node = binding;
+        }
+
+        return;   
+    }
+
     if (node->kind == Ast_Kind_Function) {
         AstFunction *func = (void *) node;
         if (!func->generated_from) {
+            func->original_binding_to_node = binding;
             bh_arr_push(docs->procedures, binding);
         }
     }
 
     if (node->kind == Ast_Kind_Macro) {
+        ((AstMacro *) node)->original_binding_to_node = binding;
         bh_arr_push(docs->procedures, binding);
     }
 
     if (node->kind == Ast_Kind_Polymorphic_Proc) {
+        ((AstFunction *) node)->original_binding_to_node = binding;
         bh_arr_push(docs->procedures, binding);
     }
 
     if (node->kind == Ast_Kind_Overloaded_Function) {
+        ((AstOverloadedFunction *) node)->original_binding_to_node = binding;
         bh_arr_push(docs->procedures, binding);
     }
 
@@ -496,8 +519,11 @@ static b32 write_doc_procedure(bh_buffer *buffer, AstBinding *binding, AstNode *
 }
 
 static b32 write_doc_structure(bh_buffer *buffer, AstBinding *binding, AstNode *node) {
+    Scope *method_scope = NULL;
+
     if (node->kind == Ast_Kind_Struct_Type) {
         AstStructType *struct_node = (void *) node;
+        method_scope = get_scope_from_node((AstNode *) struct_node);
 
         write_entity_header(buffer, binding, node->token->pos);
 
@@ -520,6 +546,8 @@ static b32 write_doc_structure(bh_buffer *buffer, AstBinding *binding, AstNode *
     }
     else if (node->kind == Ast_Kind_Poly_Struct_Type) {
         AstPolyStructType *poly_struct_node = (void *) node;
+        method_scope = get_scope_from_node((AstNode *) poly_struct_node);
+
         AstStructType *struct_node = poly_struct_node->base_struct;
 
         write_entity_header(buffer, binding, node->token->pos);
@@ -555,6 +583,35 @@ static b32 write_doc_structure(bh_buffer *buffer, AstBinding *binding, AstNode *
         bh_buffer_free(&type_buf);
     }
 
+    u32 count_patch = buffer->length;
+    bh_buffer_write_u32(buffer, 0);
+
+    u32 method_count = 0;
+    fori (i, 0, shlen(method_scope->symbols)) {
+        AstFunction* node = (AstFunction *) strip_aliases(method_scope->symbols[i].value);
+        if (node->kind != Ast_Kind_Function
+            && node->kind != Ast_Kind_Polymorphic_Proc
+            && node->kind != Ast_Kind_Overloaded_Function
+            && node->kind != Ast_Kind_Macro)
+            continue;
+
+        assert(node->entity);
+        assert(node->entity->function == node);
+
+        AstBinding *binding = NULL;
+        switch (node->kind) {
+            case Ast_Kind_Polymorphic_Proc:
+            case Ast_Kind_Function:            binding = node->original_binding_to_node; break;
+            case Ast_Kind_Macro:               binding = ((AstMacro *) node)->original_binding_to_node; break;
+            case Ast_Kind_Overloaded_Function: binding = ((AstOverloadedFunction *) node)->original_binding_to_node; break;
+        }
+
+        method_count++;
+        write_doc_procedure(buffer, binding, (AstNode *) node);
+    }
+
+    *((u32 *) bh_pointer_add(buffer->data, count_patch)) = method_count;
+
     return 1;
 }
 
index a9e0d20113094003ff42da0556824d34f8a748c1..17ae7a42bb3b6d941ebb47e411e2d5de6101fbbe 100644 (file)
@@ -3441,6 +3441,10 @@ static void parse_top_level_statement(OnyxParser* parser) {
                 inject->token = dir_token;
                 inject->full_loc = injection_point;
                 inject->to_inject = parse_top_level_expression(parser);
+                if (parser->last_documentation_token) {
+                    inject->documentation = parser->last_documentation_token;
+                    parser->last_documentation_token = NULL;
+                }
                 
                 ENTITY_SUBMIT(inject);
                 return;
@@ -3553,6 +3557,7 @@ submit_binding_to_entities:
             injection->dest = parser->injection_point;
             injection->symbol = binding->token;
             injection->to_inject = (AstTyped *) binding->node;
+            injection->documentation = binding->documentation;
 
             ENTITY_SUBMIT(injection);
             return;
index 1f5aaebb2f64f87c0deeea0ac7cf3ca450d4b5cb..d6600aacaaad94a9050d2c89e0e74e08f74782b9 100644 (file)
@@ -1451,10 +1451,13 @@ static SymresStatus symres_process_directive(AstNode* directive) {
             AstBinding *binding = onyx_ast_node_new(context.ast_alloc, sizeof(AstBinding), Ast_Kind_Binding);
             binding->token = inject->symbol;
             binding->node = (AstNode *) inject->to_inject;
+            binding->documentation = inject->documentation;
 
             Package *pac = NULL;
             if (inject->dest->kind == Ast_Kind_Package) {
                 pac = ((AstPackage *) inject->dest)->package;
+            } else {
+                pac = current_entity->package;
             }
 
             add_entities_for_node(NULL, (AstNode *) binding, scope, pac);
index 17d187ed5b8f7db5f9ee88def0cd7b7963f0cd1b..428a8eed94f81911f87b4a32ba9fbd00d33d3294 100644 (file)
@@ -127,17 +127,17 @@ Result_Data :: struct (T: type_expr, E: type_expr) {
         If result contains Err, the error is returned from the enclosing
         procedure. Otherwise, the Ok value is returned.
 
-        f :: () -> Result(i32, str) {
-            Result.return_err("Oh no...");
-        }
-
-        g :: () -> Result(str, str) {
-            // This returns from g with the error returned from f.
-            v := f()->forward_err();
-            println(v);
-
-           Result.return_ok("Success!");
-        }
+            f :: () -> Result(i32, str) {
+                Result.return_err("Oh no...");
+            }
+            
+            g :: () -> Result(str, str) {
+                // This returns from g with the error returned from f.
+                v := f()->forward_err();
+                println(v);
+                
+                Result.return_ok("Success!");
+            }
     """
     forward_err :: macro (r: Result($T, $E)) -> T {
         res := r;
@@ -160,8 +160,8 @@ Result_Data :: struct (T: type_expr, E: type_expr) {
     #doc """
         If result contains Err, the given code is run. This code is
         expected to either:
-            - Return a good value with `return`
-            - Return an error value with `return return`
+        - Return a good value with `return`
+        - Return an error value with `return return`
 
         This procedure is subject to change.
     """
index 44150245a11ae178267ec841105f73d540f4cffa..2b18a683313724f52f09384c9e3c16fdee8bf8ed 100644 (file)
@@ -95,6 +95,8 @@ Doc_Structure :: struct {
 
     members: [] Doc_Structure_Member;
     polymorph_arguments: [] Doc_Param;
+
+    methods: [] Doc_Procedure;
 }
 
 Doc_Structure_Member :: struct {
@@ -122,4 +124,4 @@ Doc_Enum :: struct {
 Doc_Enum_Value :: struct {
     name: str;
     value: u64;
-}
\ No newline at end of file
+}