Browse Source

Manually fix, merge and close #15168

Juan Linietsky 7 years ago
parent
commit
d2aaf460fb
2 changed files with 45 additions and 11 deletions
  1. 44 10
      servers/visual/shader_language.cpp
  2. 1 1
      servers/visual/shader_language.h

+ 44 - 10
servers/visual/shader_language.cpp

@@ -2306,24 +2306,54 @@ bool ShaderLanguage::_is_operator_assign(Operator p_op) const {
 	return false;
 }
 
-bool ShaderLanguage::_validate_assign(Node *p_node, const Map<StringName, BuiltInInfo> &p_builtin_types) {
+bool ShaderLanguage::_validate_assign(Node *p_node, const Map<StringName, BuiltInInfo> &p_builtin_types, String *r_message) {
 
 	if (p_node->type == Node::TYPE_OPERATOR) {
 
 		OperatorNode *op = static_cast<OperatorNode *>(p_node);
+
 		if (op->op == OP_INDEX) {
-			return _validate_assign(op->arguments[0], p_builtin_types);
+			return _validate_assign(op->arguments[0], p_builtin_types, r_message);
+
+		} else if (_is_operator_assign(op->op)) {
+			//chained assignment
+			return _validate_assign(op->arguments[1], p_builtin_types, r_message);
+
+		} else if (op->op == OP_CALL) {
+			if (r_message)
+				*r_message = RTR("Assignment to function.");
+			return false;
 		}
-	}
 
-	if (p_node->type == Node::TYPE_VARIABLE) {
+	} else if (p_node->type == Node::TYPE_MEMBER) {
+
+		MemberNode *member = static_cast<MemberNode *>(p_node);
+		return _validate_assign(member->owner, p_builtin_types, r_message);
+
+	} else if (p_node->type == Node::TYPE_VARIABLE) {
 
 		VariableNode *var = static_cast<VariableNode *>(p_node);
-		if (p_builtin_types.has(var->name) && p_builtin_types[var->name].constant) {
-			return false; //ops not valid
+
+		if (shader->uniforms.has(var->name)) {
+			if (r_message)
+				*r_message = RTR("Assignment to uniform.");
+			return false;
+		}
+
+		if (shader->varyings.has(var->name) && current_function != String("vertex")) {
+			if (r_message)
+				*r_message = RTR("Varyings can only be assigned in vertex function.");
+			return false;
+		}
+
+		if (!(p_builtin_types.has(var->name) && p_builtin_types[var->name].constant)) {
+			return true;
 		}
 	}
-	return true;
+
+	if (r_message)
+		*r_message = "Assignment to constant expression.";
+	return false;
 }
 
 ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types) {
@@ -3090,10 +3120,14 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
 				ERR_FAIL_V(NULL);
 			}
 
-			if (_is_operator_assign(op->op) && !_validate_assign(expression[next_op - 1].node, p_builtin_types)) {
+			if (_is_operator_assign(op->op)) {
 
-				_set_error("Assignment to constant expression.");
-				return NULL;
+				String assign_message;
+				if (!_validate_assign(expression[next_op - 1].node, p_builtin_types, &assign_message)) {
+
+					_set_error(assign_message);
+					return NULL;
+				}
 			}
 
 			if (expression[next_op + 1].is_op) {

+ 1 - 1
servers/visual/shader_language.h

@@ -617,7 +617,7 @@ private:
 	bool _find_identifier(const BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types, const StringName &p_identifier, DataType *r_data_type = NULL, IdentifierType *r_type = NULL);
 
 	bool _is_operator_assign(Operator p_op) const;
-	bool _validate_assign(Node *p_node, const Map<StringName, BuiltInInfo> &p_builtin_types);
+	bool _validate_assign(Node *p_node, const Map<StringName, BuiltInInfo> &p_builtin_types, String *r_message = NULL);
 
 	bool _validate_operator(OperatorNode *p_op, DataType *r_ret_type = NULL);