Explorar el Código

Add static type checks in the parser

- Resolve types for all identifiers.
- Error when identifier is not found.
- Match return type and error when not returning a value when it should.
- Check unreachable code (code after sure return).
- Match argument count and types for function calls.
- Determine if return type of function call matches the assignment.
- Do static type check with match statement when possible.
- Use type hints to determine export type.
- Check compatibility between type hint and explicit export type.
George Marques hace 7 años
padre
commit
743053734f

+ 3 - 12
main/tests/test_gdscript.cpp

@@ -193,14 +193,6 @@ static String _parser_expr(const GDScriptParser::Node *p_expr) {
 				case GDScriptParser::OperatorNode::OP_BIT_INVERT: {
 					txt = "~" + _parser_expr(c_node->arguments[0]);
 				} break;
-				case GDScriptParser::OperatorNode::OP_PREINC: {
-				} break;
-				case GDScriptParser::OperatorNode::OP_PREDEC: {
-				} break;
-				case GDScriptParser::OperatorNode::OP_INC: {
-				} break;
-				case GDScriptParser::OperatorNode::OP_DEC: {
-				} break;
 				case GDScriptParser::OperatorNode::OP_IN: {
 					txt = _parser_expr(c_node->arguments[0]) + " in " + _parser_expr(c_node->arguments[1]);
 				} break;
@@ -455,10 +447,9 @@ static void _parser_show_class(const GDScriptParser::ClassNode *p_class, int p_i
 		print_line("\n");
 	}
 
-	for (int i = 0; i < p_class->constant_expressions.size(); i++) {
-
-		const GDScriptParser::ClassNode::Constant &constant = p_class->constant_expressions[i];
-		_print_indent(p_indent, "const " + String(constant.identifier) + "=" + _parser_expr(constant.expression));
+	for (Map<StringName, GDScriptParser::ClassNode::Constant>::Element *E = p_class->constant_expressions.front(); E; E = E->next()) {
+		const GDScriptParser::ClassNode::Constant &constant = E->get();
+		_print_indent(p_indent, "const " + String(E->key()) + "=" + _parser_expr(constant.expression));
 	}
 
 	for (int i = 0; i < p_class->variables.size(); i++) {

+ 5 - 0
modules/gdscript/gdscript.h

@@ -64,6 +64,7 @@ class GDScript : public Script {
 		StringName setter;
 		StringName getter;
 		MultiplayerAPI::RPCMode rpc_mode;
+		GDScriptDataType data_type;
 	};
 
 	friend class GDScriptInstance;
@@ -145,6 +146,10 @@ public:
 	const Map<StringName, Ref<GDScript> > &get_subclasses() const { return subclasses; }
 	const Map<StringName, Variant> &get_constants() const { return constants; }
 	const Set<StringName> &get_members() const { return members; }
+	const GDScriptDataType &get_member_type(const StringName &p_member) const {
+		ERR_FAIL_COND_V(!member_indices.has(p_member), GDScriptDataType());
+		return member_indices[p_member].data_type;
+	}
 	const Map<StringName, GDScriptFunction *> &get_member_functions() const { return member_functions; }
 	const Ref<GDScriptNativeClass> &get_native() const { return native; }
 

+ 6 - 13
modules/gdscript/gdscript_compiler.cpp

@@ -777,14 +777,6 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
 				case GDScriptParser::OperatorNode::OP_BIT_INVERT: {
 					if (!_create_unary_operator(codegen, on, Variant::OP_BIT_NEGATE, p_stack_level)) return -1;
 				} break;
-				case GDScriptParser::OperatorNode::OP_PREINC: {
-				} break; //?
-				case GDScriptParser::OperatorNode::OP_PREDEC: {
-				} break;
-				case GDScriptParser::OperatorNode::OP_INC: {
-				} break;
-				case GDScriptParser::OperatorNode::OP_DEC: {
-				} break;
 				//binary operators (in precedence order)
 				case GDScriptParser::OperatorNode::OP_IN: {
 					if (!_create_binary_operator(codegen, on, Variant::OP_IN, p_stack_level)) return -1;
@@ -1520,6 +1512,7 @@ Error GDScriptCompiler::_parse_function(GDScript *p_script, const GDScriptParser
 	if (p_func) {
 		gdfunc->_static = p_func->_static;
 		gdfunc->rpc_mode = p_func->rpc_mode;
+		gdfunc->argument_types.resize(p_func->argument_types.size());
 	}
 
 #ifdef TOOLS_ENABLED
@@ -1770,24 +1763,24 @@ Error GDScriptCompiler::_parse_class_level(GDScript *p_script, GDScript *p_owner
 #endif
 	}
 
-	for (int i = 0; i < p_class->constant_expressions.size(); i++) {
+	for (Map<StringName, GDScriptParser::ClassNode::Constant>::Element *E = p_class->constant_expressions.front(); E; E = E->next()) {
 
-		StringName name = p_class->constant_expressions[i].identifier;
+		StringName name = E->key();
 
-		ERR_CONTINUE(p_class->constant_expressions[i].expression->type != GDScriptParser::Node::TYPE_CONSTANT);
+		ERR_CONTINUE(E->get().expression->type != GDScriptParser::Node::TYPE_CONSTANT);
 
 		if (_is_class_member_property(p_script, name)) {
 			_set_error("Member '" + name + "' already exists as a class property.", p_class);
 			return ERR_ALREADY_EXISTS;
 		}
 
-		GDScriptParser::ConstantNode *constant = static_cast<GDScriptParser::ConstantNode *>(p_class->constant_expressions[i].expression);
+		GDScriptParser::ConstantNode *constant = static_cast<GDScriptParser::ConstantNode *>(E->get().expression);
 
 		p_script->constants.insert(name, constant->value);
 //p_script->constants[constant->value].make_const();
 #ifdef TOOLS_ENABLED
 
-		p_script->member_lines[name] = p_class->constant_expressions[i].expression->line;
+		p_script->member_lines[name] = E->get().expression->line;
 #endif
 	}
 

+ 12 - 20
modules/gdscript/gdscript_editor.cpp

@@ -1236,15 +1236,11 @@ static bool _guess_identifier_type(GDScriptCompletionContext &context, int p_lin
 	}
 
 	//guess type in constant
+	if (context._class->constant_expressions.has(p_identifier)) {
 
-	for (int i = 0; i < context._class->constant_expressions.size(); i++) {
-
-		if (context._class->constant_expressions[i].identifier == p_identifier) {
-
-			ERR_FAIL_COND_V(context._class->constant_expressions[i].expression->type != GDScriptParser::Node::TYPE_CONSTANT, false);
-			r_type = _get_type_from_variant(static_cast<const GDScriptParser::ConstantNode *>(context._class->constant_expressions[i].expression)->value);
-			return true;
-		}
+		ERR_FAIL_COND_V(context._class->constant_expressions[p_identifier].expression->type != GDScriptParser::Node::TYPE_CONSTANT, false);
+		r_type = _get_type_from_variant(static_cast<const GDScriptParser::ConstantNode *>(context._class->constant_expressions[p_identifier].expression)->value);
+		return true;
 	}
 
 	if (!(context.function && context.function->_static)) {
@@ -1372,8 +1368,8 @@ static void _find_identifiers_in_class(GDScriptCompletionContext &context, bool
 	}
 	if (!p_only_functions) {
 
-		for (int i = 0; i < context._class->constant_expressions.size(); i++) {
-			result.insert(context._class->constant_expressions[i].identifier);
+		for (Map<StringName, GDScriptParser::ClassNode::Constant>::Element *E = context._class->constant_expressions.front(); E; E = E->next()) {
+			result.insert(E->key());
 		}
 
 		for (int i = 0; i < context._class->subclasses.size(); i++) {
@@ -2320,9 +2316,8 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_base
 												options.insert(String(cl->variables[i].identifier));
 											}
 
-											for (int i = 0; i < cl->constant_expressions.size(); i++) {
-
-												options.insert(String(cl->constant_expressions[i].identifier));
+											for (Map<StringName, GDScriptParser::ClassNode::Constant>::Element *E = cl->constant_expressions.front(); E; E = E->next()) {
+												options.insert(String(E->key()));
 											}
 										}
 
@@ -2816,13 +2811,10 @@ Error GDScriptLanguage::lookup_code(const String &p_code, const String &p_symbol
 
 				//guess in class constants
 
-				for (int i = 0; i < context._class->constant_expressions.size(); i++) {
-
-					if (context._class->constant_expressions[i].identifier == p_symbol) {
-						r_result.type = ScriptLanguage::LookupResult::RESULT_SCRIPT_LOCATION;
-						r_result.location = context._class->constant_expressions[i].expression->line;
-						return OK;
-					}
+				if (context._class->constant_expressions.has(p_symbol)) {
+					r_result.type = ScriptLanguage::LookupResult::RESULT_SCRIPT_LOCATION;
+					r_result.location = context._class->constant_expressions[p_symbol].expression->line;
+					return OK;
 				}
 
 				//guess in class variables

+ 9 - 0
modules/gdscript/gdscript_function.cpp

@@ -1370,6 +1370,15 @@ int GDScriptFunction::get_default_argument_addr(int p_idx) const {
 	return default_arguments[p_idx];
 }
 
+GDScriptDataType GDScriptFunction::get_return_type() const {
+	return return_type;
+}
+
+GDScriptDataType GDScriptFunction::get_argument_type(int p_idx) const {
+	ERR_FAIL_INDEX_V(p_idx, argument_types.size(), GDScriptDataType());
+	return argument_types[p_idx];
+}
+
 StringName GDScriptFunction::get_name() const {
 
 	return name;

+ 20 - 0
modules/gdscript/gdscript_function.h

@@ -42,6 +42,22 @@
 class GDScriptInstance;
 class GDScript;
 
+struct GDScriptDataType {
+	bool has_type;
+	enum {
+		BUILTIN,
+		NATIVE,
+		SCRIPT,
+		GDSCRIPT
+	} kind;
+	Variant::Type builtin_type;
+	StringName native_type;
+	Ref<Script> script_type;
+
+	GDScriptDataType() :
+			has_type(false) {}
+};
+
 class GDScriptFunction {
 public:
 	enum Opcode {
@@ -139,6 +155,8 @@ private:
 #endif
 	Vector<int> default_arguments;
 	Vector<int> code;
+	Vector<GDScriptDataType> argument_types;
+	GDScriptDataType return_type;
 
 #ifdef TOOLS_ENABLED
 	Vector<StringName> arg_names;
@@ -199,6 +217,8 @@ public:
 	int get_max_stack_size() const;
 	int get_default_argument_count() const;
 	int get_default_argument_addr(int p_idx) const;
+	GDScriptDataType get_return_type() const;
+	GDScriptDataType get_argument_type(int p_idx) const;
 	GDScript *get_script() const { return _script; }
 	StringName get_source() const { return source; }
 

+ 12 - 11
modules/gdscript/gdscript_functions.cpp

@@ -1663,7 +1663,7 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) {
 
 			MethodInfo mi("weakref", PropertyInfo(Variant::OBJECT, "obj"));
 			mi.return_val.type = Variant::OBJECT;
-			mi.return_val.name = "WeakRef";
+			mi.return_val.class_name = "WeakRef";
 
 			return mi;
 
@@ -1672,19 +1672,20 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) {
 
 			MethodInfo mi("funcref", PropertyInfo(Variant::OBJECT, "instance"), PropertyInfo(Variant::STRING, "funcname"));
 			mi.return_val.type = Variant::OBJECT;
-			mi.return_val.name = "FuncRef";
+			mi.return_val.class_name = "FuncRef";
 			return mi;
 
 		} break;
 		case TYPE_CONVERT: {
 
-			MethodInfo mi("convert", PropertyInfo(Variant::NIL, "what"), PropertyInfo(Variant::INT, "type"));
-			mi.return_val.type = Variant::OBJECT;
+			MethodInfo mi("convert", PropertyInfo(Variant::NIL, "what", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_NIL_IS_VARIANT), PropertyInfo(Variant::INT, "type"));
+			mi.return_val.type = Variant::NIL;
+			mi.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
 			return mi;
 		} break;
 		case TYPE_OF: {
 
-			MethodInfo mi("typeof", PropertyInfo(Variant::NIL, "what"));
+			MethodInfo mi("typeof", PropertyInfo(Variant::NIL, "what", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_NIL_IS_VARIANT));
 			mi.return_val.type = Variant::INT;
 			return mi;
 
@@ -1760,7 +1761,7 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) {
 
 		} break;
 		case VAR_TO_STR: {
-			MethodInfo mi("var2str", PropertyInfo(Variant::NIL, "var"));
+			MethodInfo mi("var2str", PropertyInfo(Variant::NIL, "var", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_NIL_IS_VARIANT));
 			mi.return_val.type = Variant::STRING;
 			return mi;
 
@@ -1773,7 +1774,7 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) {
 			return mi;
 		} break;
 		case VAR_TO_BYTES: {
-			MethodInfo mi("var2bytes", PropertyInfo(Variant::NIL, "var"));
+			MethodInfo mi("var2bytes", PropertyInfo(Variant::NIL, "var", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_NIL_IS_VARIANT));
 			mi.return_val.type = Variant::POOL_BYTE_ARRAY;
 			return mi;
 
@@ -1796,7 +1797,7 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) {
 
 			MethodInfo mi("load", PropertyInfo(Variant::STRING, "path"));
 			mi.return_val.type = Variant::OBJECT;
-			mi.return_val.name = "Resource";
+			mi.return_val.class_name = "Resource";
 			return mi;
 		} break;
 		case INST2DICT: {
@@ -1826,13 +1827,13 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) {
 		} break;
 		case TO_JSON: {
 
-			MethodInfo mi("to_json", PropertyInfo(Variant::NIL, "var"));
+			MethodInfo mi("to_json", PropertyInfo(Variant::NIL, "var", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_NIL_IS_VARIANT));
 			mi.return_val.type = Variant::STRING;
 			return mi;
 		} break;
 		case HASH: {
 
-			MethodInfo mi("hash", PropertyInfo(Variant::NIL, "var"));
+			MethodInfo mi("hash", PropertyInfo(Variant::NIL, "var", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_NIL_IS_VARIANT));
 			mi.return_val.type = Variant::INT;
 			return mi;
 		} break;
@@ -1868,7 +1869,7 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) {
 			return mi;
 		} break;
 		case LEN: {
-			MethodInfo mi("len", PropertyInfo(Variant::NIL, "var"));
+			MethodInfo mi("len", PropertyInfo(Variant::NIL, "var", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_NIL_IS_VARIANT));
 			mi.return_val.type = Variant::INT;
 			return mi;
 		} break;

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 358 - 139
modules/gdscript/gdscript_parser.cpp


+ 117 - 27
modules/gdscript/gdscript_parser.h

@@ -37,6 +37,8 @@
 #include "object.h"
 #include "script_language.h"
 
+struct GDScriptDataType;
+
 class GDScriptParser {
 public:
 	struct ClassNode;
@@ -47,29 +49,93 @@ public:
 			NATIVE,
 			SCRIPT,
 			GDSCRIPT,
-			CLASS
+			CLASS,
+			UNRESOLVED
 		} kind;
 
 		bool has_type;
+		bool is_constant;
+		bool is_meta_type; // Whether the value can be used as a type
 
 		Variant::Type builtin_type;
 		StringName native_type;
 		Ref<Script> script_type;
 		ClassNode *class_type;
 
-		DataType *meta_type;
+		String to_string() const {
+			if (!has_type) return "var";
+			switch (kind) {
+				case BUILTIN: {
+					if (builtin_type == Variant::NIL) return "null";
+					return Variant::get_type_name(builtin_type);
+				} break;
+				case NATIVE: {
+					if (is_meta_type) {
+						return "GDScriptNativeClass";
+					}
+					return native_type.operator String();
+				} break;
+				case SCRIPT:
+				case GDSCRIPT: {
+					if (is_meta_type) {
+						return script_type->get_class_name().operator String();
+					}
+					String name = script_type->get_name();
+					if (name != String()) {
+						return name;
+					}
+					name = script_type->get_path().get_file();
+					if (name != String()) {
+						return name;
+					}
+					return native_type.operator String();
+				} break;
+				case CLASS: {
+					ERR_FAIL_COND_V(!class_type, String());
+					if (is_meta_type) {
+						return "GDScript";
+					}
+					if (class_type->name == StringName()) {
+						return "self";
+					}
+					return class_type->name.operator String();
+				} break;
+			}
+
+			return "Unresolved";
+		}
+
+		bool operator==(const DataType &other) const {
+			if (!has_type || !other.has_type) {
+				return true; // Can be considered equal for parsing purpose
+			}
+			if (kind != other.kind) {
+				return false;
+			}
+			switch (kind) {
+				case BUILTIN: {
+					return builtin_type == other.builtin_type;
+				} break;
+				case NATIVE: {
+					return native_type == other.native_type;
+				} break;
+				case GDSCRIPT:
+				case SCRIPT: {
+					return script_type == other.script_type;
+				} break;
+				case CLASS: {
+					return class_type == other.class_type;
+				} break;
+			}
+			return false;
+		}
 
 		DataType() :
 				has_type(false),
-				meta_type(NULL),
+				is_constant(false),
+				is_meta_type(false),
 				builtin_type(Variant::NIL),
 				class_type(NULL) {}
-
-		~DataType() {
-			if (meta_type) {
-				memdelete(meta_type);
-			}
-		}
 	};
 
 	struct Node {
@@ -108,6 +174,8 @@ public:
 	struct FunctionNode;
 	struct BlockNode;
 	struct ConstantNode;
+	struct LocalVarNode;
+	struct OperatorNode;
 
 	struct ClassNode : public Node {
 
@@ -129,10 +197,10 @@ public:
 			StringName getter;
 			int line;
 			Node *expression;
+			OperatorNode *initial_assignment;
 			MultiplayerAPI::RPCMode rpc_mode;
 		};
 		struct Constant {
-			StringName identifier;
 			Node *expression;
 			DataType type;
 		};
@@ -144,7 +212,7 @@ public:
 
 		Vector<ClassNode *> subclasses;
 		Vector<Member> variables;
-		Vector<Constant> constant_expressions;
+		Map<StringName, Constant> constant_expressions;
 		Vector<FunctionNode *> functions;
 		Vector<FunctionNode *> static_functions;
 		Vector<Signal> _signals;
@@ -167,6 +235,7 @@ public:
 
 		bool _static;
 		MultiplayerAPI::RPCMode rpc_mode;
+		bool has_yield;
 		StringName name;
 		DataType return_type;
 		Vector<StringName> arguments;
@@ -181,6 +250,7 @@ public:
 			type = TYPE_FUNCTION;
 			_static = false;
 			rpc_mode = MultiplayerAPI::RPC_MODE_DISABLED;
+			has_yield = false;
 		}
 	};
 
@@ -188,11 +258,9 @@ public:
 
 		ClassNode *parent_class;
 		BlockNode *parent_block;
-		Map<StringName, int> locals;
 		List<Node *> statements;
-		Vector<StringName> variables;
-		Vector<DataType> variable_types;
-		Vector<int> variable_lines;
+		Map<StringName, LocalVarNode *> variables;
+		bool has_return;
 
 		Node *if_condition; //tiny hack to improve code completion on if () blocks
 
@@ -205,15 +273,13 @@ public:
 			end_line = -1;
 			parent_block = NULL;
 			parent_class = NULL;
+			has_return = false;
 		}
 	};
 
 	struct TypeNode : public Node {
 
 		Variant::Type vtype;
-		DataType datatype;
-		virtual DataType get_datatype() const { return datatype; }
-		virtual void set_datatype(const DataType &p_datatype) { datatype = p_datatype; }
 		TypeNode() { type = TYPE_TYPE; }
 	};
 	struct BuiltInFunctionNode : public Node {
@@ -224,22 +290,30 @@ public:
 	struct IdentifierNode : public Node {
 
 		StringName name;
+		BlockNode *declared_block; // Simplify lookup by checking if it is declared locally
 		DataType datatype;
 		virtual DataType get_datatype() const { return datatype; }
 		virtual void set_datatype(const DataType &p_datatype) { datatype = p_datatype; }
-		IdentifierNode() { type = TYPE_IDENTIFIER; }
+		IdentifierNode() {
+			type = TYPE_IDENTIFIER;
+			declared_block = NULL;
+		}
 	};
 
 	struct LocalVarNode : public Node {
 
 		StringName name;
 		Node *assign;
+		OperatorNode *assign_op;
+		int assignments;
 		DataType datatype;
 		virtual DataType get_datatype() const { return datatype; }
 		virtual void set_datatype(const DataType &p_datatype) { datatype = p_datatype; }
 		LocalVarNode() {
 			type = TYPE_LOCAL_VAR;
 			assign = NULL;
+			assign_op = NULL;
+			assignments = 0;
 		}
 	};
 
@@ -304,10 +378,6 @@ public:
 			OP_POS,
 			OP_NOT,
 			OP_BIT_INVERT,
-			OP_PREINC,
-			OP_PREDEC,
-			OP_INC,
-			OP_DEC,
 			//binary operators (in precedence order)
 			OP_IN,
 			OP_EQUAL,
@@ -421,8 +491,9 @@ public:
 	struct CastNode : public Node {
 		Node *source_node;
 		DataType cast_type;
-		virtual DataType get_datatype() const { return cast_type; }
-		virtual void set_datatype(const DataType &p_datatype) { cast_type = p_datatype; }
+		DataType return_type;
+		virtual DataType get_datatype() const { return return_type; }
+		virtual void set_datatype(const DataType &p_datatype) { return_type = p_datatype; }
 		CastNode() { type = TYPE_CAST; }
 	};
 
@@ -462,6 +533,8 @@ public:
 		COMPLETION_VIRTUAL_FUNC,
 		COMPLETION_YIELD,
 		COMPLETION_ASSIGN,
+		COMPLETION_TYPE_HINT,
+		COMPLETION_TYPE_HINT_INDEX,
 	};
 
 private:
@@ -479,6 +552,7 @@ private:
 	String error;
 	int error_line;
 	int error_column;
+	bool check_types;
 
 	int pending_newline;
 
@@ -490,7 +564,6 @@ private:
 	ClassNode *current_class;
 	FunctionNode *current_function;
 	BlockNode *current_block;
-	Map<StringName, ClassNode *> class_map;
 
 	bool _get_completable_identifier(CompletionType p_type, StringName &identifier);
 	void _make_completable_call(int p_arg);
@@ -524,7 +597,7 @@ private:
 
 	PatternNode *_parse_pattern(bool p_static);
 	void _parse_pattern_block(BlockNode *p_block, Vector<PatternBranchNode *> &p_branches, bool p_static);
-	void _transform_match_statment(BlockNode *p_block, MatchNode *p_match_statement);
+	void _transform_match_statment(MatchNode *p_match_statement);
 	void _generate_pattern(PatternNode *p_pattern, Node *p_node_to_match, Node *&p_resulting_node, Map<StringName, Node *> &p_bindings);
 
 	void _parse_block(BlockNode *p_block, bool p_static);
@@ -534,6 +607,23 @@ private:
 
 	void _determine_inheritance(ClassNode *p_class);
 	bool _parse_type(DataType &r_type, bool p_can_be_void = false);
+	DataType _resolve_type(const DataType &p_source, int p_line);
+	DataType _type_from_variant(const Variant &p_value) const;
+	DataType _type_from_property(const PropertyInfo &p_property, bool p_nil_is_variant = true) const;
+	DataType _type_from_gdtype(const GDScriptDataType &p_gdtype) const;
+	DataType _get_operation_type(const Variant::Operator p_op, const DataType &p_a, const DataType &p_b, bool &r_valid) const;
+	Variant::Operator _get_variant_operation(const OperatorNode::Operator &p_op) const;
+	bool _get_function_signature(DataType &p_base_type, const StringName &p_function, DataType &r_return_type, List<DataType> &r_arg_types, int &r_default_arg_count, bool &r_static, bool &r_vararg) const;
+	bool _get_member_type(const DataType &p_base_type, const StringName &p_member, DataType &r_member_type) const;
+	bool _is_type_compatible(const DataType &p_container, const DataType &p_expression, bool p_allow_implicit_conversion = false) const;
+
+	DataType _reduce_node_type(Node *p_node);
+	DataType _reduce_function_call_type(const OperatorNode *p_call);
+	DataType _reduce_identifier_type(const DataType *p_base_type, const StringName &p_identifier, int p_line);
+	void _check_class_level_types(ClassNode *p_class);
+	void _check_class_blocks_types(ClassNode *p_class);
+	void _check_function_types(FunctionNode *p_function);
+	void _check_block_types(BlockNode *p_block);
 
 	Error _parse(const String &p_base_path);
 

Algunos archivos no se mostraron porque demasiados archivos cambiaron en este cambio