Browse Source

Parse comments on enums fields

gingerBill 3 years ago
parent
commit
fe0b5bf4e2
6 changed files with 74 additions and 17 deletions
  1. 7 0
      src/check_expr.cpp
  2. 12 11
      src/check_type.cpp
  3. 6 5
      src/docs_writer.cpp
  4. 2 0
      src/entity.cpp
  5. 41 1
      src/parser.cpp
  6. 6 0
      src/parser.hpp

+ 7 - 0
src/check_expr.cpp

@@ -9341,6 +9341,13 @@ gbString write_expr_to_string(gbString str, Ast *node, bool shorthand) {
 		str = gb_string_appendc(str, " = ");
 		str = gb_string_appendc(str, " = ");
 		str = write_expr_to_string(str, fv->value, shorthand);
 		str = write_expr_to_string(str, fv->value, shorthand);
 	case_end;
 	case_end;
+	case_ast_node(fv, EnumFieldValue, node);
+		str = write_expr_to_string(str, fv->name, shorthand);
+		if (fv->value) {
+			str = gb_string_appendc(str, " = ");
+			str = write_expr_to_string(str, fv->value, shorthand);
+		}
+	case_end;
 
 
 	case_ast_node(ht, HelperType, node);
 	case_ast_node(ht, HelperType, node);
 		str = gb_string_appendc(str, "#type ");
 		str = gb_string_appendc(str, "#type ");

+ 12 - 11
src/check_type.cpp

@@ -732,20 +732,19 @@ void check_enum_type(CheckerContext *ctx, Type *enum_type, Type *named_type, Ast
 		Ast *ident = nullptr;
 		Ast *ident = nullptr;
 		Ast *init = nullptr;
 		Ast *init = nullptr;
 		u32 entity_flags = 0;
 		u32 entity_flags = 0;
-		if (field->kind == Ast_FieldValue) {
-			ast_node(fv, FieldValue, field);
-			if (fv->field == nullptr || fv->field->kind != Ast_Ident) {
-				error(field, "An enum field's name must be an identifier");
-				continue;
-			}
-			ident = fv->field;
-			init = fv->value;
-		} else if (field->kind == Ast_Ident) {
-			ident = field;
-		} else {
+		if (field->kind != Ast_EnumFieldValue) {
 			error(field, "An enum field's name must be an identifier");
 			error(field, "An enum field's name must be an identifier");
 			continue;
 			continue;
 		}
 		}
+		ident = field->EnumFieldValue.name;
+		init = field->EnumFieldValue.value;
+		if (ident == nullptr || ident->kind != Ast_Ident) {
+			error(field, "An enum field's name must be an identifier");
+			continue;
+		}
+		CommentGroup *docs    = field->EnumFieldValue.docs;
+		CommentGroup *comment = field->EnumFieldValue.comment;
+
 		String name = ident->Ident.token.string;
 		String name = ident->Ident.token.string;
 
 
 		if (init != nullptr) {
 		if (init != nullptr) {
@@ -803,6 +802,8 @@ void check_enum_type(CheckerContext *ctx, Type *enum_type, Type *named_type, Ast
 		e->flags |= EntityFlag_Visited;
 		e->flags |= EntityFlag_Visited;
 		e->state = EntityState_Resolved;
 		e->state = EntityState_Resolved;
 		e->Constant.flags |= entity_flags;
 		e->Constant.flags |= entity_flags;
+		e->Constant.docs = docs;
+		e->Constant.comment = comment;
 
 
 		if (scope_lookup_current(ctx->scope, name) != nullptr) {
 		if (scope_lookup_current(ctx->scope, name) != nullptr) {
 			error(ident, "'%.*s' is already declared in this enumeration", LIT(name));
 			error(ident, "'%.*s' is already declared in this enumeration", LIT(name));

+ 6 - 5
src/docs_writer.cpp

@@ -811,11 +811,12 @@ OdinDocEntityIndex odin_doc_add_entity(OdinDocWriter *w, Entity *e) {
 		comment = e->decl_info->comment;
 		comment = e->decl_info->comment;
 		docs = e->decl_info->docs;
 		docs = e->decl_info->docs;
 	}
 	}
-	if (!comment && e->kind == Entity_Variable) {
-		comment = e->Variable.comment;
-	}
-	if (!docs && e->kind == Entity_Variable) {
-		docs = e->Variable.docs;
+	if (e->kind == Entity_Variable) {
+		if (!comment) { comment          = e->Variable.comment; }
+		if (!docs)    { docs             = e->Variable.docs; }
+	} else if (e->kind == Entity_Constant) {
+		if (!comment) { comment          = e->Constant.comment; }
+		if (!docs)    { docs             = e->Constant.docs; }
 	}
 	}
 
 
 	String link_name = {};
 	String link_name = {};

+ 2 - 0
src/entity.cpp

@@ -161,6 +161,8 @@ struct Entity {
 			ParameterValue param_value;
 			ParameterValue param_value;
 			u32 flags;
 			u32 flags;
 			i32 field_group_index;
 			i32 field_group_index;
+			CommentGroup *docs;
+			CommentGroup *comment;
 		} Constant;
 		} Constant;
 		struct {
 		struct {
 			Ast *init_expr; // only used for some variables within procedure bodies
 			Ast *init_expr; // only used for some variables within procedure bodies

+ 41 - 1
src/parser.cpp

@@ -693,6 +693,16 @@ Ast *ast_field_value(AstFile *f, Ast *field, Ast *value, Token eq) {
 	return result;
 	return result;
 }
 }
 
 
+
+Ast *ast_enum_field_value(AstFile *f, Ast *name, Ast *value, CommentGroup *docs, CommentGroup *comment) {
+	Ast *result = alloc_ast_node(f, Ast_EnumFieldValue);
+	result->EnumFieldValue.name = name;
+	result->EnumFieldValue.value = value;
+	result->EnumFieldValue.docs = docs;
+	result->EnumFieldValue.comment = comment;
+	return result;
+}
+
 Ast *ast_compound_lit(AstFile *f, Ast *type, Array<Ast *> const &elems, Token open, Token close) {
 Ast *ast_compound_lit(AstFile *f, Ast *type, Array<Ast *> const &elems, Token open, Token close) {
 	Ast *result = alloc_ast_node(f, Ast_CompoundLit);
 	Ast *result = alloc_ast_node(f, Ast_CompoundLit);
 	result->CompoundLit.type = type;
 	result->CompoundLit.type = type;
@@ -1689,6 +1699,36 @@ Array<Ast *> parse_element_list(AstFile *f) {
 
 
 	return elems;
 	return elems;
 }
 }
+Array<Ast *> parse_enum_field_list(AstFile *f) {
+	auto elems = array_make<Ast *>(heap_allocator());
+
+	while (f->curr_token.kind != Token_CloseBrace &&
+	       f->curr_token.kind != Token_EOF) {
+		CommentGroup *docs = f->lead_comment;
+		CommentGroup *comment = nullptr;
+		Ast *name = parse_value(f);
+		Ast *value = nullptr;
+		if (f->curr_token.kind == Token_Eq) {
+			Token eq = expect_token(f, Token_Eq);
+			value = parse_value(f);
+		}
+
+		comment = f->line_comment;
+
+		Ast *elem = ast_enum_field_value(f, name, value, docs, comment);
+		array_add(&elems, elem);
+
+		if (!allow_token(f, Token_Comma)) {
+			break;
+		}
+
+		if (!elem->EnumFieldValue.comment) {
+			elem->EnumFieldValue.comment = f->line_comment;
+		}
+	}
+
+	return elems;
+}
 
 
 Ast *parse_literal_value(AstFile *f, Ast *type) {
 Ast *parse_literal_value(AstFile *f, Ast *type) {
 	Array<Ast *> elems = {};
 	Array<Ast *> elems = {};
@@ -2449,7 +2489,7 @@ Ast *parse_operand(AstFile *f, bool lhs) {
 		skip_possible_newline_for_literal(f);
 		skip_possible_newline_for_literal(f);
 		Token open = expect_token(f, Token_OpenBrace);
 		Token open = expect_token(f, Token_OpenBrace);
 
 
-		Array<Ast *> values = parse_element_list(f);
+		Array<Ast *> values = parse_enum_field_list(f);
 		Token close = expect_closing_brace_of_field_list(f);
 		Token close = expect_closing_brace_of_field_list(f);
 
 
 		return ast_enum_type(f, token, base_type, values);
 		return ast_enum_type(f, token, base_type, values);

+ 6 - 0
src/parser.hpp

@@ -383,6 +383,12 @@ AST_KIND(_ExprBegin,  "",  bool) \
 		void *sce_temp_data; \
 		void *sce_temp_data; \
 	}) \
 	}) \
 	AST_KIND(FieldValue,      "field value",              struct { Token eq; Ast *field, *value; }) \
 	AST_KIND(FieldValue,      "field value",              struct { Token eq; Ast *field, *value; }) \
+	AST_KIND(EnumFieldValue,  "enum field value",         struct { \
+		Ast *name;          \
+		Ast *value;         \
+		CommentGroup *docs; \
+		CommentGroup *comment; \
+	}) \
 	AST_KIND(TernaryIfExpr,   "ternary if expression",    struct { Ast *x, *cond, *y; }) \
 	AST_KIND(TernaryIfExpr,   "ternary if expression",    struct { Ast *x, *cond, *y; }) \
 	AST_KIND(TernaryWhenExpr, "ternary when expression",  struct { Ast *x, *cond, *y; }) \
 	AST_KIND(TernaryWhenExpr, "ternary when expression",  struct { Ast *x, *cond, *y; }) \
 	AST_KIND(OrElseExpr,      "or_else expression",       struct { Ast *x; Token token; Ast *y; }) \
 	AST_KIND(OrElseExpr,      "or_else expression",       struct { Ast *x; Token token; Ast *y; }) \