Browse Source

Add `-vet-style` and `-vet-semicolon`

gingerBill 2 years ago
parent
commit
c35c58b023
4 changed files with 77 additions and 38 deletions
  1. 6 0
      src/build_settings.cpp
  2. 2 2
      src/check_expr.cpp
  3. 25 5
      src/main.cpp
  4. 44 31
      src/parser.cpp

+ 6 - 0
src/build_settings.cpp

@@ -222,6 +222,8 @@ enum VetFlags : u64 {
 	VetFlag_Shadowing  = 1u<<1, // 2
 	VetFlag_Shadowing  = 1u<<1, // 2
 	VetFlag_UsingStmt  = 1u<<2, // 4
 	VetFlag_UsingStmt  = 1u<<2, // 4
 	VetFlag_UsingParam = 1u<<3, // 8
 	VetFlag_UsingParam = 1u<<3, // 8
+	VetFlag_Style      = 1u<<4, // 16
+	VetFlag_Semicolon  = 1u<<5, // 32
 
 
 	VetFlag_Extra     = 1u<<16,
 	VetFlag_Extra     = 1u<<16,
 
 
@@ -239,6 +241,10 @@ u64 get_vet_flag_from_name(String const &name) {
 		return VetFlag_UsingStmt;
 		return VetFlag_UsingStmt;
 	} else if (name == "using-param") {
 	} else if (name == "using-param") {
 		return VetFlag_UsingParam;
 		return VetFlag_UsingParam;
+	} else if (name == "style") {
+		return VetFlag_Style;
+	} else if (name == "semicolon") {
+		return VetFlag_Semicolon;
 	} else if (name == "extra") {
 	} else if (name == "extra") {
 		return VetFlag_Extra;
 		return VetFlag_Extra;
 	}
 	}

+ 2 - 2
src/check_expr.cpp

@@ -2261,7 +2261,7 @@ gb_internal bool check_is_not_addressable(CheckerContext *c, Operand *o) {
 }
 }
 
 
 gb_internal void check_old_for_or_switch_value_usage(Ast *expr) {
 gb_internal void check_old_for_or_switch_value_usage(Ast *expr) {
-	if (!build_context.strict_style) {
+	if (!(build_context.strict_style || (check_vet_flags(expr) & VetFlag_Style))) {
 		return;
 		return;
 	}
 	}
 
 
@@ -2351,7 +2351,7 @@ gb_internal void check_unary_expr(CheckerContext *c, Operand *o, Token op, Ast *
 				o->type = alloc_type_pointer(o->type);
 				o->type = alloc_type_pointer(o->type);
 			}
 			}
 		} else {
 		} else {
-			if (build_context.strict_style && ast_node_expect(node, Ast_UnaryExpr)) {
+			if (ast_node_expect(node, Ast_UnaryExpr)) {
 				ast_node(ue, UnaryExpr, node);
 				ast_node(ue, UnaryExpr, node);
 				check_old_for_or_switch_value_usage(ue->expr);
 				check_old_for_or_switch_value_usage(ue->expr);
 			}
 			}

+ 25 - 5
src/main.cpp

@@ -653,12 +653,16 @@ enum BuildFlagKind {
 	BuildFlag_UseSeparateModules,
 	BuildFlag_UseSeparateModules,
 	BuildFlag_NoThreadedChecker,
 	BuildFlag_NoThreadedChecker,
 	BuildFlag_ShowDebugMessages,
 	BuildFlag_ShowDebugMessages,
+
 	BuildFlag_Vet,
 	BuildFlag_Vet,
 	BuildFlag_VetShadowing,
 	BuildFlag_VetShadowing,
 	BuildFlag_VetUnused,
 	BuildFlag_VetUnused,
 	BuildFlag_VetUsingStmt,
 	BuildFlag_VetUsingStmt,
 	BuildFlag_VetUsingParam,
 	BuildFlag_VetUsingParam,
+	BuildFlag_VetStyle,
+	BuildFlag_VetSemicolon,
 	BuildFlag_VetExtra,
 	BuildFlag_VetExtra,
+
 	BuildFlag_IgnoreUnknownAttributes,
 	BuildFlag_IgnoreUnknownAttributes,
 	BuildFlag_ExtraLinkerFlags,
 	BuildFlag_ExtraLinkerFlags,
 	BuildFlag_ExtraAssemblerFlags,
 	BuildFlag_ExtraAssemblerFlags,
@@ -839,7 +843,9 @@ gb_internal bool parse_build_flags(Array<String> args) {
 	add_flag(&build_flags, BuildFlag_VetUnused,               str_lit("vet-unused"),                BuildFlagParam_None,    Command__does_check);
 	add_flag(&build_flags, BuildFlag_VetUnused,               str_lit("vet-unused"),                BuildFlagParam_None,    Command__does_check);
 	add_flag(&build_flags, BuildFlag_VetShadowing,            str_lit("vet-shadowing"),             BuildFlagParam_None,    Command__does_check);
 	add_flag(&build_flags, BuildFlag_VetShadowing,            str_lit("vet-shadowing"),             BuildFlagParam_None,    Command__does_check);
 	add_flag(&build_flags, BuildFlag_VetUsingStmt,            str_lit("vet-using-stmt"),            BuildFlagParam_None,    Command__does_check);
 	add_flag(&build_flags, BuildFlag_VetUsingStmt,            str_lit("vet-using-stmt"),            BuildFlagParam_None,    Command__does_check);
-	add_flag(&build_flags, BuildFlag_VetUsingParam,           str_lit("vet-using-param"),            BuildFlagParam_None,    Command__does_check);
+	add_flag(&build_flags, BuildFlag_VetUsingParam,           str_lit("vet-using-param"),           BuildFlagParam_None,    Command__does_check);
+	add_flag(&build_flags, BuildFlag_VetStyle,                str_lit("vet-style"),                 BuildFlagParam_None,    Command__does_check);
+	add_flag(&build_flags, BuildFlag_VetSemicolon,            str_lit("vet-semicolon"),             BuildFlagParam_None,    Command__does_check);
 	add_flag(&build_flags, BuildFlag_VetExtra,                str_lit("vet-extra"),                 BuildFlagParam_None,    Command__does_check);
 	add_flag(&build_flags, BuildFlag_VetExtra,                str_lit("vet-extra"),                 BuildFlagParam_None,    Command__does_check);
 
 
 	add_flag(&build_flags, BuildFlag_IgnoreUnknownAttributes, str_lit("ignore-unknown-attributes"), BuildFlagParam_None,    Command__does_check);
 	add_flag(&build_flags, BuildFlag_IgnoreUnknownAttributes, str_lit("ignore-unknown-attributes"), BuildFlagParam_None,    Command__does_check);
@@ -1380,10 +1386,12 @@ gb_internal bool parse_build_flags(Array<String> args) {
 							}
 							}
 							break;
 							break;
 
 
-						case BuildFlag_VetUnused:     build_context.vet_flags |= VetFlag_Unused;    break;
-						case BuildFlag_VetShadowing:  build_context.vet_flags |= VetFlag_Shadowing; break;
-						case BuildFlag_VetUsingStmt:  build_context.vet_flags |= VetFlag_UsingStmt; break;
+						case BuildFlag_VetUnused:     build_context.vet_flags |= VetFlag_Unused;     break;
+						case BuildFlag_VetShadowing:  build_context.vet_flags |= VetFlag_Shadowing;  break;
+						case BuildFlag_VetUsingStmt:  build_context.vet_flags |= VetFlag_UsingStmt;  break;
 						case BuildFlag_VetUsingParam: build_context.vet_flags |= VetFlag_UsingParam; break;
 						case BuildFlag_VetUsingParam: build_context.vet_flags |= VetFlag_UsingParam; break;
+						case BuildFlag_VetStyle:      build_context.vet_flags |= VetFlag_Style;      break;
+						case BuildFlag_VetSemicolon:  build_context.vet_flags |= VetFlag_Semicolon;  break;
 
 
 						case BuildFlag_VetExtra:
 						case BuildFlag_VetExtra:
 							build_context.vet_flags = VetFlag_All | VetFlag_Extra;
 							build_context.vet_flags = VetFlag_All | VetFlag_Extra;
@@ -2173,6 +2181,16 @@ gb_internal void print_show_help(String const arg0, String const &command) {
 		print_usage_line(2, "'using' is considered bad practice outside of immediate refactoring");
 		print_usage_line(2, "'using' is considered bad practice outside of immediate refactoring");
 		print_usage_line(0, "");
 		print_usage_line(0, "");
 
 
+		print_usage_line(1, "-vet-style");
+		print_usage_line(2, "Errs on missing trailing commas followed by a newline");
+		print_usage_line(2, "Errs on deprecated syntax");
+		print_usage_line(2, "Does not err on unneeded tokens (unlike -strict-style)");
+		print_usage_line(0, "");
+
+		print_usage_line(1, "-vet-semicolon");
+		print_usage_line(2, "Errs on unneeded semicolons");
+		print_usage_line(0, "");
+
 		print_usage_line(1, "-vet-extra");
 		print_usage_line(1, "-vet-extra");
 		print_usage_line(2, "Do even more checks than standard vet on the code");
 		print_usage_line(2, "Do even more checks than standard vet on the code");
 		print_usage_line(2, "To treat the extra warnings as errors, use -warnings-as-errors");
 		print_usage_line(2, "To treat the extra warnings as errors, use -warnings-as-errors");
@@ -2249,10 +2267,12 @@ gb_internal void print_show_help(String const arg0, String const &command) {
 
 
 		print_usage_line(1, "-strict-style");
 		print_usage_line(1, "-strict-style");
 		print_usage_line(2, "Errs on unneeded tokens, such as unneeded semicolons");
 		print_usage_line(2, "Errs on unneeded tokens, such as unneeded semicolons");
+		print_usage_line(2, "Errs on missing trailing commas followed by a newline");
+		print_usage_line(2, "Errs on deprecated syntax");
 		print_usage_line(0, "");
 		print_usage_line(0, "");
 
 
 		print_usage_line(1, "-strict-style-init-only");
 		print_usage_line(1, "-strict-style-init-only");
-		print_usage_line(2, "Errs on unneeded tokens, such as unneeded semicolons, only on the initial project");
+		print_usage_line(2, "Same as -strict-style but only on the initial package");
 		print_usage_line(0, "");
 		print_usage_line(0, "");
 
 
 		print_usage_line(1, "-ignore-warnings");
 		print_usage_line(1, "-ignore-warnings");

+ 44 - 31
src/parser.cpp

@@ -1,7 +1,21 @@
 #include "parser_pos.cpp"
 #include "parser_pos.cpp"
 
 
-// #undef at the bottom of this file
-#define ALLOW_NEWLINE (!build_context.strict_style)
+gb_internal u64 ast_file_vet_flags(AstFile *f) {
+	if (f->vet_flags_set) {
+		return f->vet_flags;
+	}
+	return build_context.vet_flags;
+}
+
+gb_internal bool ast_file_vet_style(AstFile *f) {
+	return (ast_file_vet_flags(f) & VetFlag_Style) != 0;
+}
+
+
+gb_internal bool file_allow_newline(AstFile *f) {
+	bool is_strict = build_context.strict_style || ast_file_vet_style(f);
+	return !is_strict;
+}
 
 
 gb_internal Token token_end_of_line(AstFile *f, Token tok) {
 gb_internal Token token_end_of_line(AstFile *f, Token tok) {
 	u8 const *start = f->tokenizer.start + tok.pos.offset;
 	u8 const *start = f->tokenizer.start + tok.pos.offset;
@@ -1567,29 +1581,31 @@ gb_internal void assign_removal_flag_to_semicolon(AstFile *f) {
 	Token *prev_token = &f->tokens[f->prev_token_index];
 	Token *prev_token = &f->tokens[f->prev_token_index];
 	Token *curr_token = &f->tokens[f->curr_token_index];
 	Token *curr_token = &f->tokens[f->curr_token_index];
 	GB_ASSERT(prev_token->kind == Token_Semicolon);
 	GB_ASSERT(prev_token->kind == Token_Semicolon);
-	if (prev_token->string == ";") {
-		bool ok = false;
-		if (curr_token->pos.line > prev_token->pos.line) {
+	if (prev_token->string != ";") {
+		return;
+	}
+	bool ok = false;
+	if (curr_token->pos.line > prev_token->pos.line) {
+		ok = true;
+	} else if (curr_token->pos.line == prev_token->pos.line) {
+		switch (curr_token->kind) {
+		case Token_CloseBrace:
+		case Token_CloseParen:
+		case Token_EOF:
 			ok = true;
 			ok = true;
-		} else if (curr_token->pos.line == prev_token->pos.line) {
-			switch (curr_token->kind) {
-			case Token_CloseBrace:
-			case Token_CloseParen:
-			case Token_EOF:
-				ok = true;
-				break;
-			}
-		}
-			
-		if (ok) {
-			if (build_context.strict_style) {
-				syntax_error(*prev_token, "Found unneeded semicolon");
-			} else if (build_context.strict_style_init_only && f->pkg->kind == Package_Init) {
-				syntax_error(*prev_token, "Found unneeded semicolon");
-			}
-			prev_token->flags |= TokenFlag_Remove;
+			break;
 		}
 		}
 	}
 	}
+	if (!ok) {
+		return;
+	}
+
+	if (build_context.strict_style || (ast_file_vet_flags(f) & VetFlag_Semicolon)) {
+		syntax_error(*prev_token, "Found unneeded semicolon");
+	} else if (build_context.strict_style_init_only && f->pkg->kind == Package_Init) {
+		syntax_error(*prev_token, "Found unneeded semicolon");
+	}
+	prev_token->flags |= TokenFlag_Remove;
 }
 }
 
 
 gb_internal void expect_semicolon(AstFile *f) {
 gb_internal void expect_semicolon(AstFile *f) {
@@ -2748,7 +2764,7 @@ gb_internal Ast *parse_call_expr(AstFile *f, Ast *operand) {
 	isize prev_expr_level = f->expr_level;
 	isize prev_expr_level = f->expr_level;
 	bool prev_allow_newline = f->allow_newline;
 	bool prev_allow_newline = f->allow_newline;
 	f->expr_level = 0;
 	f->expr_level = 0;
-	f->allow_newline = ALLOW_NEWLINE;
+	f->allow_newline = file_allow_newline(f);
 
 
 	open_paren = expect_token(f, Token_OpenParen);
 	open_paren = expect_token(f, Token_OpenParen);
 
 
@@ -3147,7 +3163,7 @@ gb_internal Ast *parse_expr(AstFile *f, bool lhs) {
 
 
 gb_internal Array<Ast *> parse_expr_list(AstFile *f, bool lhs) {
 gb_internal Array<Ast *> parse_expr_list(AstFile *f, bool lhs) {
 	bool allow_newline = f->allow_newline;
 	bool allow_newline = f->allow_newline;
-	f->allow_newline = ALLOW_NEWLINE;
+	f->allow_newline = file_allow_newline(f);
 
 
 	auto list = array_make<Ast *>(heap_allocator());
 	auto list = array_make<Ast *>(heap_allocator());
 	for (;;) {
 	for (;;) {
@@ -3472,7 +3488,7 @@ gb_internal Ast *parse_results(AstFile *f, bool *diverging) {
 	Ast *list = nullptr;
 	Ast *list = nullptr;
 	expect_token(f, Token_OpenParen);
 	expect_token(f, Token_OpenParen);
 	list = parse_field_list(f, nullptr, FieldFlag_Results, Token_CloseParen, true, false);
 	list = parse_field_list(f, nullptr, FieldFlag_Results, Token_CloseParen, true, false);
-	if (ALLOW_NEWLINE) {
+	if (file_allow_newline(f)) {
 		skip_possible_newline(f);
 		skip_possible_newline(f);
 	}
 	}
 	expect_token_after(f, Token_CloseParen, "parameter list");
 	expect_token_after(f, Token_CloseParen, "parameter list");
@@ -3532,7 +3548,7 @@ gb_internal Ast *parse_proc_type(AstFile *f, Token proc_token) {
 
 
 	expect_token(f, Token_OpenParen);
 	expect_token(f, Token_OpenParen);
 	params = parse_field_list(f, nullptr, FieldFlag_Signature, Token_CloseParen, true, true);
 	params = parse_field_list(f, nullptr, FieldFlag_Signature, Token_CloseParen, true, true);
-	if (ALLOW_NEWLINE) {
+	if (file_allow_newline(f)) {
 		skip_possible_newline(f);
 		skip_possible_newline(f);
 	}
 	}
 	expect_token_after(f, Token_CloseParen, "parameter list");
 	expect_token_after(f, Token_CloseParen, "parameter list");
@@ -3754,7 +3770,7 @@ gb_internal bool allow_field_separator(AstFile *f) {
 	}
 	}
 	if (token.kind == Token_Semicolon) {
 	if (token.kind == Token_Semicolon) {
 		bool ok = false;
 		bool ok = false;
-		if (ALLOW_NEWLINE && token_is_newline(token)) {
+		if (file_allow_newline(f) && token_is_newline(token)) {
 			TokenKind next = peek_token(f).kind;
 			TokenKind next = peek_token(f).kind;
 			switch (next) {
 			switch (next) {
 			case Token_CloseBrace:
 			case Token_CloseBrace:
@@ -3818,7 +3834,7 @@ gb_internal bool check_procedure_name_list(Array<Ast *> const &names) {
 gb_internal Ast *parse_field_list(AstFile *f, isize *name_count_, u32 allowed_flags, TokenKind follow, bool allow_default_parameters, bool allow_typeid_token) {
 gb_internal Ast *parse_field_list(AstFile *f, isize *name_count_, u32 allowed_flags, TokenKind follow, bool allow_default_parameters, bool allow_typeid_token) {
 	bool prev_allow_newline = f->allow_newline;
 	bool prev_allow_newline = f->allow_newline;
 	defer (f->allow_newline = prev_allow_newline);
 	defer (f->allow_newline = prev_allow_newline);
-	f->allow_newline = ALLOW_NEWLINE;
+	f->allow_newline = file_allow_newline(f);
 
 
 	Token start_token = f->curr_token;
 	Token start_token = f->curr_token;
 
 
@@ -6005,6 +6021,3 @@ gb_internal ParseFileError parse_packages(Parser *p, String init_filename) {
 	return ParseFile_None;
 	return ParseFile_None;
 }
 }
 
 
-
-
-#undef ALLOW_NEWLINE