diff options
Diffstat (limited to 'modules/gdscript/gdscript_analyzer.cpp')
| -rw-r--r-- | modules/gdscript/gdscript_analyzer.cpp | 80 | 
1 files changed, 15 insertions, 65 deletions
| diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp index 851994eff3..4d9d01b261 100644 --- a/modules/gdscript/gdscript_analyzer.cpp +++ b/modules/gdscript/gdscript_analyzer.cpp @@ -2720,7 +2720,7 @@ void GDScriptAnalyzer::reduce_unary_op(GDScriptParser::UnaryOpNode *p_unary_op)  		mark_node_unsafe(p_unary_op);  	} else {  		bool valid = false; -		result = get_operation_type(p_unary_op->variant_op, p_unary_op->operand->get_datatype(), p_unary_op->operand->get_datatype(), valid, p_unary_op); +		result = get_operation_type(p_unary_op->variant_op, p_unary_op->operand->get_datatype(), valid, p_unary_op);  		if (!valid) {  			push_error(vformat(R"(Invalid operand of type "%s" for unary operator "%s".)", p_unary_op->operand->get_datatype().to_string(), Variant::get_operator_name(p_unary_op->variant_op)), p_unary_op->operand); @@ -3086,81 +3086,31 @@ bool GDScriptAnalyzer::is_shadowing(GDScriptParser::IdentifierNode *p_local, con  }  #endif -GDScriptParser::DataType GDScriptAnalyzer::get_operation_type(Variant::Operator p_operation, const GDScriptParser::DataType &p_a, const GDScriptParser::DataType &p_b, bool &r_valid, const GDScriptParser::Node *p_source) { -	// This function creates dummy variant values and apply the operation to those. Less error-prone than keeping a table of valid operations. +GDScriptParser::DataType GDScriptAnalyzer::get_operation_type(Variant::Operator p_operation, const GDScriptParser::DataType &p_a, bool &r_valid, const GDScriptParser::Node *p_source) { +	// Unary version. +	GDScriptParser::DataType nil_type; +	nil_type.builtin_type = Variant::NIL; +	return get_operation_type(p_operation, p_a, nil_type, r_valid, p_source); +} +GDScriptParser::DataType GDScriptAnalyzer::get_operation_type(Variant::Operator p_operation, const GDScriptParser::DataType &p_a, const GDScriptParser::DataType &p_b, bool &r_valid, const GDScriptParser::Node *p_source) {  	GDScriptParser::DataType result;  	result.kind = GDScriptParser::DataType::VARIANT;  	Variant::Type a_type = p_a.builtin_type;  	Variant::Type b_type = p_b.builtin_type; -	Variant a; -	REF a_ref; -	if (a_type == Variant::OBJECT) { -		a_ref.instance(); -		a = a_ref; -	} else { -		Callable::CallError err; -		Variant::construct(a_type, a, nullptr, 0, err); -		if (err.error != Callable::CallError::CALL_OK) { -			r_valid = false; -			ERR_FAIL_V_MSG(result, vformat("Could not construct value of type %s", Variant::get_type_name(a_type))); -		} -	} -	Variant b; -	REF b_ref; -	if (b_type == Variant::OBJECT) { -		b_ref.instance(); -		b = b_ref; -	} else { -		Callable::CallError err; -		Variant::construct(b_type, b, nullptr, 0, err); -		if (err.error != Callable::CallError::CALL_OK) { -			r_valid = false; -			ERR_FAIL_V_MSG(result, vformat("Could not construct value of type %s", Variant::get_type_name(b_type))); -		} -	} +	Variant::ValidatedOperatorEvaluator op_eval = Variant::get_validated_operator_evaluator(p_operation, a_type, b_type); -	// Avoid division by zero. -	switch (b_type) { -		case Variant::INT: -			b = 1; -			break; -		case Variant::FLOAT: -			b = 1.0; -			break; -		case Variant::VECTOR2: -			b = Vector2(1.0, 1.0); -			break; -		case Variant::VECTOR2I: -			b = Vector2i(1, 1); -			break; -		case Variant::VECTOR3: -			b = Vector3(1.0, 1.0, 1.0); -			break; -		case Variant::VECTOR3I: -			b = Vector3i(1, 1, 1); -			break; -		case Variant::COLOR: -			b = Color(1.0, 1.0, 1.0, 1.0); -			break; -		default: -			// No change needed. -			break; -	} - -	// Avoid error in formatting operator (%) where it doesn't find a placeholder. -	if (a_type == Variant::STRING && b_type != Variant::ARRAY) { -		a = String("%s"); +	if (op_eval == nullptr) { +		r_valid = false; +		return result;  	} -	Variant ret; -	Variant::evaluate(p_operation, a, b, ret, r_valid); +	r_valid = true; -	if (r_valid) { -		return type_from_variant(ret, p_source); -	} +	result.kind = GDScriptParser::DataType::BUILTIN; +	result.builtin_type = Variant::get_operator_return_type(p_operation, a_type, b_type);  	return result;  } |