Browse Source

Merge pull request #48139 from vnen/gdscript-dict-keys

Fix mismatch between String and StringName in dictionary keys
Rémi Verschelde 4 years ago
parent
commit
d1dc28e46c

+ 4 - 20
modules/gdscript/gdscript_analyzer.cpp

@@ -2621,25 +2621,6 @@ void GDScriptAnalyzer::reduce_subscript(GDScriptParser::SubscriptNode *p_subscri
 
 	GDScriptParser::DataType result_type;
 
-	// Reduce index first. If it's a constant StringName, use attribute instead.
-	if (!p_subscript->is_attribute) {
-		if (p_subscript->index == nullptr) {
-			return;
-		}
-		reduce_expression(p_subscript->index);
-
-		if (p_subscript->index->is_constant && p_subscript->index->reduced_value.get_type() == Variant::STRING_NAME) {
-			GDScriptParser::IdentifierNode *attribute = parser->alloc_node<GDScriptParser::IdentifierNode>();
-			// Copy location for better error message.
-			attribute->start_line = p_subscript->index->start_line;
-			attribute->end_line = p_subscript->index->end_line;
-			attribute->leftmost_column = p_subscript->index->leftmost_column;
-			attribute->rightmost_column = p_subscript->index->rightmost_column;
-			p_subscript->is_attribute = true;
-			p_subscript->attribute = attribute;
-		}
-	}
-
 	if (p_subscript->is_attribute) {
 		if (p_subscript->attribute == nullptr) {
 			return;
@@ -2682,7 +2663,10 @@ void GDScriptAnalyzer::reduce_subscript(GDScriptParser::SubscriptNode *p_subscri
 			}
 		}
 	} else {
-		// Index was already reduced before.
+		if (p_subscript->index == nullptr) {
+			return;
+		}
+		reduce_expression(p_subscript->index);
 
 		if (p_subscript->base->is_constant && p_subscript->index->is_constant) {
 			// Just try to get it.

+ 4 - 4
modules/gdscript/gdscript_compiler.cpp

@@ -427,8 +427,8 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code
 						}
 						break;
 					case GDScriptParser::DictionaryNode::LUA_TABLE:
-						// Lua-style: key is an identifier interpreted as string.
-						String key = static_cast<const GDScriptParser::IdentifierNode *>(dn->elements[i].key)->name;
+						// Lua-style: key is an identifier interpreted as StringName.
+						StringName key = static_cast<const GDScriptParser::IdentifierNode *>(dn->elements[i].key)->name;
 						element = codegen.add_constant(key);
 						break;
 				}
@@ -680,9 +680,9 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code
 				name = subscript->attribute->name;
 				named = true;
 			} else {
-				if (subscript->index->type == GDScriptParser::Node::LITERAL && static_cast<const GDScriptParser::LiteralNode *>(subscript->index)->value.get_type() == Variant::STRING) {
+				if (subscript->index->is_constant && subscript->index->reduced_value.get_type() == Variant::STRING_NAME) {
 					// Also, somehow, named (speed up anyway).
-					name = static_cast<const GDScriptParser::LiteralNode *>(subscript->index)->value;
+					name = subscript->index->reduced_value;
 					named = true;
 				} else {
 					// Regular indexing.

+ 2 - 0
modules/gdscript/gdscript_parser.cpp

@@ -2440,6 +2440,8 @@ GDScriptParser::ExpressionNode *GDScriptParser::parse_dictionary(ExpressionNode
 							push_error(R"(Expected "=" after dictionary key.)");
 						}
 					}
+					key->is_constant = true;
+					key->reduced_value = static_cast<IdentifierNode *>(key)->name;
 					break;
 				case DictionaryNode::PYTHON_DICT:
 					if (!match(GDScriptTokenizer::Token::COLON)) {