Browse Source

GDScript: Fix issues when deriving from other scripts

George Marques 5 years ago
parent
commit
8ccf88a206

+ 6 - 3
modules/gdscript/gdscript_analyzer.cpp

@@ -182,7 +182,7 @@ Error GDScriptAnalyzer::resolve_inheritance(GDScriptParser::ClassNode *p_class,
 				return ERR_PARSE_ERROR;
 				return ERR_PARSE_ERROR;
 			}
 			}
 
 
-			Error err = parser->raise_status(GDScriptParserRef::INHERITANCE_SOLVED);
+			Error err = parser->raise_status(GDScriptParserRef::INTERFACE_SOLVED);
 			if (err != OK) {
 			if (err != OK) {
 				push_error(vformat(R"(Could not resolve super class inheritance from "%s".)", p_class->extends_path), p_class);
 				push_error(vformat(R"(Could not resolve super class inheritance from "%s".)", p_class->extends_path), p_class);
 				return err;
 				return err;
@@ -208,7 +208,7 @@ Error GDScriptAnalyzer::resolve_inheritance(GDScriptParser::ClassNode *p_class,
 						return ERR_PARSE_ERROR;
 						return ERR_PARSE_ERROR;
 					}
 					}
 
 
-					Error err = parser->raise_status(GDScriptParserRef::INHERITANCE_SOLVED);
+					Error err = parser->raise_status(GDScriptParserRef::INTERFACE_SOLVED);
 					if (err != OK) {
 					if (err != OK) {
 						push_error(vformat(R"(Could not resolve super class inheritance from "%s".)", name), p_class);
 						push_error(vformat(R"(Could not resolve super class inheritance from "%s".)", name), p_class);
 						return err;
 						return err;
@@ -227,7 +227,7 @@ Error GDScriptAnalyzer::resolve_inheritance(GDScriptParser::ClassNode *p_class,
 					return ERR_PARSE_ERROR;
 					return ERR_PARSE_ERROR;
 				}
 				}
 
 
-				Error err = parser->raise_status(GDScriptParserRef::INHERITANCE_SOLVED);
+				Error err = parser->raise_status(GDScriptParserRef::INTERFACE_SOLVED);
 				if (err != OK) {
 				if (err != OK) {
 					push_error(vformat(R"(Could not resolve super class inheritance from "%s".)", name), p_class);
 					push_error(vformat(R"(Could not resolve super class inheritance from "%s".)", name), p_class);
 					return err;
 					return err;
@@ -3254,6 +3254,9 @@ Error GDScriptAnalyzer::resolve_program() {
 	List<String> parser_keys;
 	List<String> parser_keys;
 	depended_parsers.get_key_list(&parser_keys);
 	depended_parsers.get_key_list(&parser_keys);
 	for (const List<String>::Element *E = parser_keys.front(); E != nullptr; E = E->next()) {
 	for (const List<String>::Element *E = parser_keys.front(); E != nullptr; E = E->next()) {
+		if (depended_parsers[E->get()].is_null()) {
+			return ERR_PARSE_ERROR;
+		}
 		depended_parsers[E->get()]->raise_status(GDScriptParserRef::FULLY_SOLVED);
 		depended_parsers[E->get()]->raise_status(GDScriptParserRef::FULLY_SOLVED);
 	}
 	}
 	depended_parsers.clear();
 	depended_parsers.clear();

+ 17 - 6
modules/gdscript/gdscript_compiler.cpp

@@ -2609,16 +2609,27 @@ Error GDScriptCompiler::_parse_class_level(GDScript *p_script, const GDScriptPar
 			p_script->_base = base.ptr();
 			p_script->_base = base.ptr();
 
 
 			if (p_class->base_type.kind == GDScriptParser::DataType::CLASS && p_class->base_type.class_type != nullptr) {
 			if (p_class->base_type.kind == GDScriptParser::DataType::CLASS && p_class->base_type.class_type != nullptr) {
-				if (!parsed_classes.has(p_script->_base)) {
-					if (parsing_classes.has(p_script->_base)) {
-						String class_name = p_class->identifier ? p_class->identifier->name : "<main>";
-						_set_error("Cyclic class reference for '" + class_name + "'.", p_class);
-						return ERR_PARSE_ERROR;
+				if (p_class->base_type.script_path == main_script->path) {
+					if (!parsed_classes.has(p_script->_base)) {
+						if (parsing_classes.has(p_script->_base)) {
+							String class_name = p_class->identifier ? p_class->identifier->name : "<main>";
+							_set_error("Cyclic class reference for '" + class_name + "'.", p_class);
+							return ERR_PARSE_ERROR;
+						}
+						Error err = _parse_class_level(p_script->_base, p_class->base_type.class_type, p_keep_state);
+						if (err) {
+							return err;
+						}
 					}
 					}
-					Error err = _parse_class_level(p_script->_base, p_class->base_type.class_type, p_keep_state);
+				} else {
+					Error err = OK;
+					base = GDScriptCache::get_full_script(p_class->base_type.script_path, err, main_script->path);
 					if (err) {
 					if (err) {
 						return err;
 						return err;
 					}
 					}
+					if (base.is_null() && !base->is_valid()) {
+						return ERR_COMPILATION_FAILED;
+					}
 				}
 				}
 			}
 			}
 
 

+ 0 - 1
modules/gdscript/gdscript_parser.cpp

@@ -631,7 +631,6 @@ void GDScriptParser::parse_extends() {
 		current_class->extends_path = previous.literal;
 		current_class->extends_path = previous.literal;
 
 
 		if (!match(GDScriptTokenizer::Token::PERIOD)) {
 		if (!match(GDScriptTokenizer::Token::PERIOD)) {
-			end_statement("superclass path");
 			return;
 			return;
 		}
 		}
 	}
 	}