mirror of
				https://github.com/godotengine/godot.git
				synced 2025-10-31 21:51:22 +00:00 
			
		
		
		
	GDScript: Add annotation to ignore warnings
This commit is contained in:
		
							parent
							
								
									1032c2c434
								
							
						
					
					
						commit
						fd643c903d
					
				
					 7 changed files with 116 additions and 12 deletions
				
			
		|  | @ -39,6 +39,7 @@ | |||
| #ifdef DEBUG_ENABLED | ||||
| #include "core/os/os.h" | ||||
| #include "core/string/string_builder.h" | ||||
| #include "gdscript_warning.h" | ||||
| #endif // DEBUG_ENABLED
 | ||||
| 
 | ||||
| #ifdef TOOLS_ENABLED | ||||
|  | @ -132,9 +133,9 @@ GDScriptParser::GDScriptParser() { | |||
| 	register_annotation(MethodInfo("@export_flags_3d_render"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_LAYERS_3D_RENDER, Variant::INT>); | ||||
| 	register_annotation(MethodInfo("@export_flags_3d_physics"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_LAYERS_3D_PHYSICS, Variant::INT>); | ||||
| 	register_annotation(MethodInfo("@export_flags_3d_navigation"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_LAYERS_3D_NAVIGATION, Variant::INT>); | ||||
| 	register_annotation(MethodInfo("@warning_ignore", { Variant::STRING, "warning" }), AnnotationInfo::CLASS | AnnotationInfo::VARIABLE | AnnotationInfo::SIGNAL | AnnotationInfo::CONSTANT | AnnotationInfo::FUNCTION | AnnotationInfo::STATEMENT, &GDScriptParser::warning_annotations, 0, true); | ||||
| 	// Networking.
 | ||||
| 	register_annotation(MethodInfo("@rpc", { Variant::STRING, "mode" }, { Variant::STRING, "sync" }, { Variant::STRING, "transfer_mode" }, { Variant::INT, "transfer_channel" }), AnnotationInfo::FUNCTION, &GDScriptParser::network_annotations<Multiplayer::RPC_MODE_AUTHORITY>, 4, true); | ||||
| 	// TODO: Warning annotations.
 | ||||
| } | ||||
| 
 | ||||
| GDScriptParser::~GDScriptParser() { | ||||
|  | @ -196,6 +197,10 @@ void GDScriptParser::push_warning(const Node *p_source, GDScriptWarning::Code p_ | |||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	if (ignored_warning_codes.has(p_code)) { | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	String warn_name = GDScriptWarning::get_name_from_code((GDScriptWarning::Code)p_code).to_lower(); | ||||
| 	if (ignored_warnings.has(warn_name)) { | ||||
| 		return; | ||||
|  | @ -701,24 +706,21 @@ void GDScriptParser::parse_extends() { | |||
| template <class T> | ||||
| void GDScriptParser::parse_class_member(T *(GDScriptParser::*p_parse_function)(), AnnotationInfo::TargetKind p_target, const String &p_member_kind) { | ||||
| 	advance(); | ||||
| 	T *member = (this->*p_parse_function)(); | ||||
| 	if (member == nullptr) { | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| #ifdef TOOLS_ENABLED | ||||
| 	int doc_comment_line = member->start_line - 1; | ||||
| 	int doc_comment_line = previous.start_line - 1; | ||||
| #endif // TOOLS_ENABLED
 | ||||
| 
 | ||||
| 	// Consume annotations.
 | ||||
| 	List<AnnotationNode *> annotations; | ||||
| 	while (!annotation_stack.is_empty()) { | ||||
| 		AnnotationNode *last_annotation = annotation_stack.back()->get(); | ||||
| 		if (last_annotation->applies_to(p_target)) { | ||||
| 			member->annotations.push_front(last_annotation); | ||||
| 			annotations.push_front(last_annotation); | ||||
| 			annotation_stack.pop_back(); | ||||
| 		} else { | ||||
| 			push_error(vformat(R"(Annotation "%s" cannot be applied to a %s.)", last_annotation->name, p_member_kind)); | ||||
| 			clear_unused_annotations(); | ||||
| 			return; | ||||
| 		} | ||||
| #ifdef TOOLS_ENABLED | ||||
| 		if (last_annotation->start_line == doc_comment_line) { | ||||
|  | @ -727,6 +729,16 @@ void GDScriptParser::parse_class_member(T *(GDScriptParser::*p_parse_function)() | |||
| #endif // TOOLS_ENABLED
 | ||||
| 	} | ||||
| 
 | ||||
| 	T *member = (this->*p_parse_function)(); | ||||
| 	if (member == nullptr) { | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	// Apply annotations.
 | ||||
| 	for (AnnotationNode *&annotation : annotations) { | ||||
| 		member->annotations.push_back(annotation); | ||||
| 	} | ||||
| 
 | ||||
| #ifdef TOOLS_ENABLED | ||||
| 	// Consume doc comments.
 | ||||
| 	class_doc_line = MIN(class_doc_line, doc_comment_line - 1); | ||||
|  | @ -1507,6 +1519,8 @@ GDScriptParser::Node *GDScriptParser::parse_statement() { | |||
| 	bool unreachable = current_suite->has_return && !current_suite->has_unreachable_code; | ||||
| #endif | ||||
| 
 | ||||
| 	bool is_annotation = false; | ||||
| 
 | ||||
| 	switch (current.type) { | ||||
| 		case GDScriptTokenizer::Token::PASS: | ||||
| 			advance(); | ||||
|  | @ -1576,6 +1590,7 @@ GDScriptParser::Node *GDScriptParser::parse_statement() { | |||
| 			break; | ||||
| 		case GDScriptTokenizer::Token::ANNOTATION: { | ||||
| 			advance(); | ||||
| 			is_annotation = true; | ||||
| 			AnnotationNode *annotation = parse_annotation(AnnotationInfo::STATEMENT); | ||||
| 			if (annotation != nullptr) { | ||||
| 				annotation_stack.push_back(annotation); | ||||
|  | @ -1616,6 +1631,18 @@ GDScriptParser::Node *GDScriptParser::parse_statement() { | |||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// Apply annotations to statement.
 | ||||
| 	while (!is_annotation && result != nullptr && !annotation_stack.is_empty()) { | ||||
| 		AnnotationNode *last_annotation = annotation_stack.back()->get(); | ||||
| 		if (last_annotation->applies_to(AnnotationInfo::STATEMENT)) { | ||||
| 			result->annotations.push_front(last_annotation); | ||||
| 			annotation_stack.pop_back(); | ||||
| 		} else { | ||||
| 			push_error(vformat(R"(Annotation "%s" cannot be applied to a statement.)", last_annotation->name)); | ||||
| 			clear_unused_annotations(); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| #ifdef DEBUG_ENABLED | ||||
| 	if (unreachable && result != nullptr) { | ||||
| 		current_suite->has_unreachable_code = true; | ||||
|  | @ -3552,7 +3579,24 @@ bool GDScriptParser::export_annotations(const AnnotationNode *p_annotation, Node | |||
| } | ||||
| 
 | ||||
| bool GDScriptParser::warning_annotations(const AnnotationNode *p_annotation, Node *p_node) { | ||||
| 	ERR_FAIL_V_MSG(false, "Not implemented."); | ||||
| #ifdef DEBUG_ENABLED | ||||
| 	bool has_error = false; | ||||
| 	for (const Variant &warning_name : p_annotation->resolved_arguments) { | ||||
| 		GDScriptWarning::Code warning = GDScriptWarning::get_code_from_name(String(warning_name).to_upper()); | ||||
| 		if (warning == GDScriptWarning::WARNING_MAX) { | ||||
| 			push_error(vformat(R"(Invalid warning name: "%s".)", warning_name), p_annotation); | ||||
| 			has_error = true; | ||||
| 		} else { | ||||
| 			p_node->ignored_warnings.push_back(warning); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return !has_error; | ||||
| 
 | ||||
| #else // ! DEBUG_ENABLED
 | ||||
| 	// Only available in debug builds.
 | ||||
| 	return true; | ||||
| #endif // DEBUG_ENABLED
 | ||||
| } | ||||
| 
 | ||||
| template <Multiplayer::RPCMode t_mode> | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 George Marques
						George Marques