瀏覽代碼

Merge pull request #3051 from eska014/add-export-hints

Add GDScript export hints for named bit flags, exponential ranges and global filesystem
Rémi Verschelde 9 年之前
父節點
當前提交
9e9e4f96a2
共有 1 個文件被更改,包括 106 次插入8 次删除
  1. 106 8
      modules/gdscript/gd_parser.cpp

+ 106 - 8
modules/gdscript/gd_parser.cpp

@@ -2381,10 +2381,48 @@ void GDParser::_parse_class(ClassNode *p_class) {
 
 
 										current_export.hint=PROPERTY_HINT_ALL_FLAGS;
 										current_export.hint=PROPERTY_HINT_ALL_FLAGS;
 										tokenizer->advance();
 										tokenizer->advance();
-										if (tokenizer->get_token()!=GDTokenizer::TK_PARENTHESIS_CLOSE) {
-											_set_error("Expected ')' in hint.");
+
+										if (tokenizer->get_token()==GDTokenizer::TK_PARENTHESIS_CLOSE) {
+											break;
+										}
+										if (tokenizer->get_token()!=GDTokenizer::TK_COMMA)
+										{
+											_set_error("Expected ')' or ',' in bit flags hint.");
 											return;
 											return;
 										}
 										}
+
+										current_export.hint=PROPERTY_HINT_FLAGS;
+										tokenizer->advance();
+
+										bool first = true;
+										while(true) {
+
+											if (tokenizer->get_token()!=GDTokenizer::TK_CONSTANT || tokenizer->get_token_constant().get_type()!=Variant::STRING) {
+												current_export=PropertyInfo();
+												_set_error("Expected a string constant in named bit flags hint.");
+												return;
+											}
+
+											String c = tokenizer->get_token_constant();
+											if (!first)
+												current_export.hint_string+=",";
+											else
+												first=false;
+
+											current_export.hint_string+=c.xml_escape();
+
+											tokenizer->advance();
+											if (tokenizer->get_token()==GDTokenizer::TK_PARENTHESIS_CLOSE)
+												break;
+
+											if (tokenizer->get_token()!=GDTokenizer::TK_COMMA) {
+												current_export=PropertyInfo();
+												_set_error("Expected ')' or ',' in named bit flags hint.");
+												return;
+											}
+											tokenizer->advance();
+										}
+
 										break;
 										break;
 									}
 									}
 
 
@@ -2439,6 +2477,23 @@ void GDParser::_parse_class(ClassNode *p_class) {
 										break;
 										break;
 									}
 									}
 
 
+									// range
+									if (tokenizer->get_token()==GDTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier()=="EXP") {
+
+										current_export.hint=PROPERTY_HINT_EXP_RANGE;
+										tokenizer->advance();
+
+										if (tokenizer->get_token()==GDTokenizer::TK_PARENTHESIS_CLOSE)
+											break;
+										else if (tokenizer->get_token()!=GDTokenizer::TK_COMMA) {
+											_set_error("Expected ')' or ',' in exponential range hint.");
+											return;
+										}
+										tokenizer->advance();
+									}
+									else
+										current_export.hint=PROPERTY_HINT_RANGE;
+
 									float sign=1.0;
 									float sign=1.0;
 
 
 									if (tokenizer->get_token()==GDTokenizer::TK_OP_SUB) {
 									if (tokenizer->get_token()==GDTokenizer::TK_OP_SUB) {
@@ -2452,8 +2507,6 @@ void GDParser::_parse_class(ClassNode *p_class) {
 										return;
 										return;
 
 
 									}
 									}
-										//enumeration
-									current_export.hint=PROPERTY_HINT_RANGE;
 
 
 									current_export.hint_string=rtos(sign*double(tokenizer->get_token_constant()));
 									current_export.hint_string=rtos(sign*double(tokenizer->get_token_constant()));
 									tokenizer->advance();
 									tokenizer->advance();
@@ -2556,10 +2609,32 @@ void GDParser::_parse_class(ClassNode *p_class) {
 
 
 									if (tokenizer->get_token()==GDTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier()=="DIR") {
 									if (tokenizer->get_token()==GDTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier()=="DIR") {
 
 
-										current_export.hint=PROPERTY_HINT_DIR;
 										tokenizer->advance();
 										tokenizer->advance();
-										if (tokenizer->get_token()!=GDTokenizer::TK_PARENTHESIS_CLOSE) {
-											_set_error("Expected ')' in hint.");
+
+										if (tokenizer->get_token()==GDTokenizer::TK_PARENTHESIS_CLOSE)
+											current_export.hint=PROPERTY_HINT_DIR;
+										else if (tokenizer->get_token()==GDTokenizer::TK_COMMA ) {
+
+											tokenizer->advance();
+
+											if (tokenizer->get_token()!=GDTokenizer::TK_IDENTIFIER || !(tokenizer->get_token_identifier()=="GLOBAL")) {
+												_set_error("Expected 'GLOBAL' after comma in directory hint.");
+												return;
+											}
+											if (!p_class->tool) {
+												_set_error("Global filesystem hints may only be used in tool scripts.");
+												return;
+											}
+											current_export.hint=PROPERTY_HINT_GLOBAL_DIR;
+											tokenizer->advance();
+
+											if (tokenizer->get_token()!=GDTokenizer::TK_PARENTHESIS_CLOSE) {
+												_set_error("Expected ')' in hint.");
+												return;
+											}
+										}
+										else {
+											_set_error("Expected ')' or ',' in hint.");
 											return;
 											return;
 										}
 										}
 										break;
 										break;
@@ -2573,9 +2648,32 @@ void GDParser::_parse_class(ClassNode *p_class) {
 										if (tokenizer->get_token()==GDTokenizer::TK_COMMA) {
 										if (tokenizer->get_token()==GDTokenizer::TK_COMMA) {
 
 
 											tokenizer->advance();
 											tokenizer->advance();
+
+											if (tokenizer->get_token()==GDTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier()=="GLOBAL") {
+
+												if (!p_class->tool) {
+													_set_error("Global filesystem hints may only be used in tool scripts.");
+													return;
+												}
+												current_export.hint=PROPERTY_HINT_GLOBAL_FILE;
+												tokenizer->advance();
+
+												if (tokenizer->get_token()==GDTokenizer::TK_PARENTHESIS_CLOSE)
+													break;
+												else if (tokenizer->get_token()==GDTokenizer::TK_COMMA)
+													tokenizer->advance();
+												else {
+													_set_error("Expected ')' or ',' in hint.");
+													return;
+												}
+											}
+
 											if (tokenizer->get_token()!=GDTokenizer::TK_CONSTANT || tokenizer->get_token_constant().get_type()!=Variant::STRING) {
 											if (tokenizer->get_token()!=GDTokenizer::TK_CONSTANT || tokenizer->get_token_constant().get_type()!=Variant::STRING) {
 
 
-												_set_error("Expected string constant with filter");
+												if (current_export.hint==PROPERTY_HINT_GLOBAL_FILE)
+													_set_error("Expected string constant with filter");
+												else
+													_set_error("Expected 'GLOBAL' or string constant with filter");
 												return;
 												return;
 											}
 											}
 											current_export.hint_string=tokenizer->get_token_constant();
 											current_export.hint_string=tokenizer->get_token_constant();