Browse Source

Changed MethodBind API to request information from methods. It's much claner now.
Also changed PropertyInfo to include informatino about class names.

Juan Linietsky 8 years ago
parent
commit
3d1c031871

+ 2 - 4
core/class_db.cpp

@@ -538,9 +538,7 @@ void ClassDB::get_method_list(StringName p_class, List<MethodInfo> *p_methods, b
 				minfo.arguments.push_back(method->get_argument_info(i));
 				minfo.arguments.push_back(method->get_argument_info(i));
 			}
 			}
 
 
-			if (method->get_argument_type(-1) != Variant::NIL) {
-				minfo.return_val = method->get_argument_info(-1);
-			}
+			minfo.return_val = method->get_return_info();
 
 
 			minfo.flags = method->get_hint_flags();
 			minfo.flags = method->get_hint_flags();
 			p_methods->push_back(minfo);
 			p_methods->push_back(minfo);
@@ -680,7 +678,7 @@ StringName ClassDB::get_integer_constant_enum(const StringName &p_class, const S
 			List<StringName> &constants_list = type->enum_map.get(*k);
 			List<StringName> &constants_list = type->enum_map.get(*k);
 			const List<StringName>::Element *found = constants_list.find(p_name);
 			const List<StringName>::Element *found = constants_list.find(p_name);
 			if (found)
 			if (found)
-				return found->get();
+				return *k;
 		}
 		}
 
 
 		if (p_no_inheritance)
 		if (p_no_inheritance)

+ 1 - 1
core/class_db.h

@@ -457,7 +457,7 @@ public:
 		}
 		}
 		type->method_map[p_name] = bind;
 		type->method_map[p_name] = bind;
 #ifdef DEBUG_METHODS_ENABLED
 #ifdef DEBUG_METHODS_ENABLED
-		bind->set_return_type("Variant");
+//		bind->set_return_type("Variant");
 		type->method_order.push_back(p_name);
 		type->method_order.push_back(p_name);
 #endif
 #endif
 
 

+ 9 - 9
core/make_binders.py

@@ -16,12 +16,11 @@ public:
 		$
 		$
 		return Variant::NIL;
 		return Variant::NIL;
 	}
 	}
-	virtual StringName _gen_argument_type_name(int p_arg) const { return _gen_argument_type_hint(p_arg); }
-	StringName _gen_argument_type_hint(int p_argument) const {
-		$ifret if (p_argument==-1) return GetTypeInfo<R>::get_class_name();$
-		$arg if (p_argument==(@-1)) return GetTypeInfo<P@>::get_class_name();
+	virtual PropertyInfo _gen_argument_type_info(int p_argument) const {
+		$ifret if (p_argument==-1) return GetTypeInfo<R>::get_class_info();$
+		$arg if (p_argument==(@-1)) return GetTypeInfo<P@>::get_class_info();
 		$
 		$
-		return StringName();
+		return PropertyInfo();
 	}
 	}
 #endif
 #endif
 	virtual String get_instance_class() const {
 	virtual String get_instance_class() const {
@@ -106,12 +105,13 @@ public:
 
 
 	virtual StringName _gen_argument_type_name(int p_arg) const { return _gen_argument_type_hint(p_arg); }
 	virtual StringName _gen_argument_type_name(int p_arg) const { return _gen_argument_type_hint(p_arg); }
 
 
-	StringName _gen_argument_type_hint(int p_argument) const {
-		$ifret if (p_argument==-1) return GetTypeInfo<R>::get_class_name();$
-		$arg if (p_argument==(@-1)) return GetTypeInfo<P@>::get_class_name();
+	virtual PropertyInfo _gen_argument_type_info(int p_argument) const {
+		$ifret if (p_argument==-1) return GetTypeInfo<R>::get_class_info();$
+		$arg if (p_argument==(@-1)) return GetTypeInfo<P@>::get_class_info();
 		$
 		$
-		return StringName();
+		return PropertyInfo();
 	}
 	}
+
 #endif
 #endif
 	virtual String get_instance_class() const {
 	virtual String get_instance_class() const {
 		return type_name;
 		return type_name;

+ 8 - 38
core/method_bind.cpp

@@ -36,31 +36,16 @@
 #ifdef DEBUG_METHODS_ENABLED
 #ifdef DEBUG_METHODS_ENABLED
 PropertyInfo MethodBind::get_argument_info(int p_argument) const {
 PropertyInfo MethodBind::get_argument_info(int p_argument) const {
 
 
-	if (p_argument >= 0) {
+	ERR_FAIL_INDEX_V(p_argument, get_argument_count(), PropertyInfo());
 
 
-		String name = p_argument < arg_names.size() ? String(arg_names[p_argument]) : String("arg" + itos(p_argument));
-		PropertyInfo pi(get_argument_type(p_argument), name);
-
-		if (!is_vararg() && pi.type == Variant::OBJECT) {
-			StringName type_hint = arg_type_hints[p_argument];
-
-			if (type_hint != StringName()) {
-				pi.hint = PROPERTY_HINT_RESOURCE_TYPE;
-				pi.hint_string = type_hint.operator String();
-			}
-		}
-		return pi;
+	PropertyInfo info = _gen_argument_type_info(p_argument);
+	info.name = p_argument < arg_names.size() ? String(arg_names[p_argument]) : String("arg" + itos(p_argument));
+	return info;
+}
 
 
-	} else {
+PropertyInfo MethodBind::get_return_info() const {
 
 
-		Variant::Type at = get_argument_type(-1);
-		if (at == Variant::OBJECT && ret_type)
-			return PropertyInfo(at, "ret", PROPERTY_HINT_RESOURCE_TYPE, ret_type);
-		else
-			return PropertyInfo(at, "ret");
-	}
-
-	return PropertyInfo();
+	return _gen_argument_type_info(-1);
 }
 }
 
 
 #endif
 #endif
@@ -91,16 +76,6 @@ Vector<StringName> MethodBind::get_argument_names() const {
 	return arg_names;
 	return arg_names;
 }
 }
 
 
-void MethodBind::set_argument_type_hints(const Vector<StringName> &p_type_hints) {
-
-	arg_type_hints = p_type_hints;
-}
-
-Vector<StringName> MethodBind::get_argument_type_hints() const {
-
-	return arg_type_hints;
-}
-
 #endif
 #endif
 
 
 void MethodBind::set_default_arguments(const Vector<Variant> &p_defargs) {
 void MethodBind::set_default_arguments(const Vector<Variant> &p_defargs) {
@@ -114,18 +89,13 @@ void MethodBind::_generate_argument_types(int p_count) {
 	set_argument_count(p_count);
 	set_argument_count(p_count);
 
 
 	Variant::Type *argt = memnew_arr(Variant::Type, p_count + 1);
 	Variant::Type *argt = memnew_arr(Variant::Type, p_count + 1);
-
-	arg_type_hints.resize(p_count);
-
 	argt[0] = _gen_argument_type(-1); // return type
 	argt[0] = _gen_argument_type(-1); // return type
-	set_return_type(_gen_argument_type_hint(-1));
 
 
 	for (int i = 0; i < p_count; i++) {
 	for (int i = 0; i < p_count; i++) {
 		argt[i + 1] = _gen_argument_type(i);
 		argt[i + 1] = _gen_argument_type(i);
-		arg_type_hints[i] = _gen_argument_type_hint(i);
 	}
 	}
 
 
-	set_argument_types(argt);
+	argument_types = argt;
 }
 }
 
 
 #endif
 #endif

+ 33 - 19
core/method_bind.h

@@ -188,23 +188,22 @@ class MethodBind {
 	Vector<Variant> default_arguments;
 	Vector<Variant> default_arguments;
 	int default_argument_count;
 	int default_argument_count;
 	int argument_count;
 	int argument_count;
-#ifdef DEBUG_METHODS_ENABLED
-	Vector<StringName> arg_names;
-	Vector<StringName> arg_type_hints;
-	Variant::Type *argument_types;
-	StringName ret_type;
-#endif
+
 	bool _const;
 	bool _const;
 	bool _returns;
 	bool _returns;
 
 
 protected:
 protected:
+#ifdef DEBUG_METHODS_ENABLED
+	Variant::Type *argument_types;
+	Vector<StringName> arg_names;
+#endif
 	void _set_const(bool p_const);
 	void _set_const(bool p_const);
 	void _set_returns(bool p_returns);
 	void _set_returns(bool p_returns);
 #ifdef DEBUG_METHODS_ENABLED
 #ifdef DEBUG_METHODS_ENABLED
 	virtual Variant::Type _gen_argument_type(int p_arg) const = 0;
 	virtual Variant::Type _gen_argument_type(int p_arg) const = 0;
-	virtual StringName _gen_argument_type_hint(int p_arg) const = 0;
+	virtual PropertyInfo _gen_argument_type_info(int p_arg) const = 0;
 	void _generate_argument_types(int p_count);
 	void _generate_argument_types(int p_count);
-	void set_argument_types(Variant::Type *p_types) { argument_types = p_types; }
+
 #endif
 #endif
 	void set_argument_count(int p_count) { argument_count = p_count; }
 	void set_argument_count(int p_count) { argument_count = p_count; }
 
 
@@ -234,9 +233,6 @@ public:
 
 
 #ifdef DEBUG_METHODS_ENABLED
 #ifdef DEBUG_METHODS_ENABLED
 
 
-	_FORCE_INLINE_ void set_return_type(const StringName &p_type) { ret_type = p_type; }
-	_FORCE_INLINE_ StringName get_return_type() const { return ret_type; }
-
 	_FORCE_INLINE_ Variant::Type get_argument_type(int p_argument) const {
 	_FORCE_INLINE_ Variant::Type get_argument_type(int p_argument) const {
 
 
 		ERR_FAIL_COND_V(p_argument < -1 || p_argument > argument_count, Variant::NIL);
 		ERR_FAIL_COND_V(p_argument < -1 || p_argument > argument_count, Variant::NIL);
@@ -244,12 +240,11 @@ public:
 	}
 	}
 
 
 	PropertyInfo get_argument_info(int p_argument) const;
 	PropertyInfo get_argument_info(int p_argument) const;
+	PropertyInfo get_return_info() const;
 
 
-	void set_argument_names(const Vector<StringName> &p_names);
+	void set_argument_names(const Vector<StringName> &p_names); //set by class, db, cant be inferred otherwise
 	Vector<StringName> get_argument_names() const;
 	Vector<StringName> get_argument_names() const;
 
 
-	void set_argument_type_hints(const Vector<StringName> &p_type_hints);
-	Vector<StringName> get_argument_type_hints() const;
 #endif
 #endif
 	void set_hint_flags(uint32_t p_hint) { hint_flags = p_hint; }
 	void set_hint_flags(uint32_t p_hint) { hint_flags = p_hint; }
 	uint32_t get_hint_flags() const { return hint_flags | (is_const() ? METHOD_FLAG_CONST : 0) | (is_vararg() ? METHOD_FLAG_VARARG : 0); }
 	uint32_t get_hint_flags() const { return hint_flags | (is_const() ? METHOD_FLAG_CONST : 0) | (is_vararg() ? METHOD_FLAG_VARARG : 0); }
@@ -305,18 +300,36 @@ public:
 
 
 protected:
 protected:
 	NativeCall call_method;
 	NativeCall call_method;
+#ifdef DEBUG_METHODS_ENABLED
+
+	MethodInfo arguments;
 
 
+#endif
 public:
 public:
-	virtual Variant::Type _gen_argument_type(int p_arg) const {
+#ifdef DEBUG_METHODS_ENABLED
 
 
-		return Variant::NIL;
+	virtual PropertyInfo _gen_argument_type_info(int p_arg) const {
+
+		if (p_arg < 0) {
+			return arguments.return_val;
+		} else if (p_arg < arguments.arguments.size()) {
+			return arguments.arguments[p_arg];
+		} else {
+			return PropertyInfo(Variant::NIL, "arg_" + itos(p_arg), PROPERTY_HINT_NONE, String(), PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_NIL_IS_VARIANT);
+		}
 	}
 	}
 
 
-	virtual StringName _gen_argument_type_hint(int p_arg) const {
+	virtual Variant::Type _gen_argument_type(int p_arg) const {
+		return _gen_argument_type_info(p_arg).type;
+	}
+
+#else
 
 
-		return "Variant";
+	virtual Variant::Type _gen_argument_type(int p_arg) const {
+		return Variant::NIL;
 	}
 	}
 
 
+#endif
 	virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Variant::CallError &r_error) {
 	virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Variant::CallError &r_error) {
 
 
 		T *instance = static_cast<T *>(p_object);
 		T *instance = static_cast<T *>(p_object);
@@ -341,7 +354,8 @@ public:
 
 
 			set_argument_names(names);
 			set_argument_names(names);
 		}
 		}
-		set_argument_types(at);
+		argument_types = at;
+		arguments = p_info;
 #endif
 #endif
 	}
 	}
 
 

+ 4 - 0
core/object.cpp

@@ -65,6 +65,7 @@ PropertyInfo::operator Dictionary() const {
 
 
 	Dictionary d;
 	Dictionary d;
 	d["name"] = name;
 	d["name"] = name;
+	d["class_name"] = class_name;
 	d["type"] = type;
 	d["type"] = type;
 	d["hint"] = hint;
 	d["hint"] = hint;
 	d["hint_string"] = hint_string;
 	d["hint_string"] = hint_string;
@@ -82,6 +83,9 @@ PropertyInfo PropertyInfo::from_dict(const Dictionary &p_dict) {
 	if (p_dict.has("name"))
 	if (p_dict.has("name"))
 		pi.name = p_dict["name"];
 		pi.name = p_dict["name"];
 
 
+	if (p_dict.has("class_name"))
+		pi.class_name = p_dict["class_name"];
+
 	if (p_dict.has("hint"))
 	if (p_dict.has("hint"))
 		pi.hint = PropertyHint(int(p_dict["hint"]));
 		pi.hint = PropertyHint(int(p_dict["hint"]));
 
 

+ 18 - 1
core/object.h

@@ -107,6 +107,8 @@ enum PropertyUsageFlags {
 	PROPERTY_USAGE_ANIMATE_AS_TRIGGER = 32768,
 	PROPERTY_USAGE_ANIMATE_AS_TRIGGER = 32768,
 	PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED = 65536,
 	PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED = 65536,
 	PROPERTY_USAGE_SCRIPT_DEFAULT_VALUE = 1 << 17,
 	PROPERTY_USAGE_SCRIPT_DEFAULT_VALUE = 1 << 17,
+	PROPERTY_USAGE_CLASS_IS_ENUM = 1 << 18,
+	PROPERTY_USAGE_NIL_IS_VARIANT = 1 << 19,
 
 
 	PROPERTY_USAGE_DEFAULT = PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_NETWORK,
 	PROPERTY_USAGE_DEFAULT = PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_NETWORK,
 	PROPERTY_USAGE_DEFAULT_INTL = PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_NETWORK | PROPERTY_USAGE_INTERNATIONALIZED,
 	PROPERTY_USAGE_DEFAULT_INTL = PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_NETWORK | PROPERTY_USAGE_INTERNATIONALIZED,
@@ -126,6 +128,7 @@ struct PropertyInfo {
 
 
 	Variant::Type type;
 	Variant::Type type;
 	String name;
 	String name;
+	StringName class_name; //for classes
 	PropertyHint hint;
 	PropertyHint hint;
 	String hint_string;
 	String hint_string;
 	uint32_t usage;
 	uint32_t usage;
@@ -145,13 +148,27 @@ struct PropertyInfo {
 		  hint(PROPERTY_HINT_NONE),
 		  hint(PROPERTY_HINT_NONE),
 		  usage(PROPERTY_USAGE_DEFAULT) {
 		  usage(PROPERTY_USAGE_DEFAULT) {
 	}
 	}
-	PropertyInfo(Variant::Type p_type, const String p_name, PropertyHint p_hint = PROPERTY_HINT_NONE, const String &p_hint_string = "", uint32_t p_usage = PROPERTY_USAGE_DEFAULT)
+	PropertyInfo(Variant::Type p_type, const String p_name, PropertyHint p_hint = PROPERTY_HINT_NONE, const String &p_hint_string = "", uint32_t p_usage = PROPERTY_USAGE_DEFAULT, const StringName &p_class_name = StringName())
 		: type(p_type),
 		: type(p_type),
 		  name(p_name),
 		  name(p_name),
 		  hint(p_hint),
 		  hint(p_hint),
 		  hint_string(p_hint_string),
 		  hint_string(p_hint_string),
 		  usage(p_usage) {
 		  usage(p_usage) {
+
+		if (hint == PROPERTY_HINT_RESOURCE_TYPE) {
+			class_name = hint_string;
+		} else {
+			class_name = p_class_name;
+		}
+	}
+	PropertyInfo(const StringName &p_class_name)
+		: type(Variant::OBJECT),
+		  hint(PROPERTY_HINT_NONE),
+		  usage(PROPERTY_USAGE_DEFAULT) {
+
+		class_name = p_class_name;
 	}
 	}
+
 	bool operator<(const PropertyInfo &p_info) const {
 	bool operator<(const PropertyInfo &p_info) const {
 		return name < p_info.name;
 		return name < p_info.name;
 	}
 	}

+ 4 - 4
core/reference.h

@@ -382,8 +382,8 @@ template <class T>
 struct GetTypeInfo<Ref<T> > {
 struct GetTypeInfo<Ref<T> > {
 	enum { VARIANT_TYPE = Variant::OBJECT };
 	enum { VARIANT_TYPE = Variant::OBJECT };
 
 
-	static inline StringName get_class_name() {
-		return T::get_class_static();
+	static inline PropertyInfo get_class_info() {
+		return PropertyInfo(Variant::OBJECT, String(), PROPERTY_HINT_RESOURCE_TYPE, T::get_class_static());
 	}
 	}
 };
 };
 
 
@@ -391,8 +391,8 @@ template <class T>
 struct GetTypeInfo<const Ref<T> &> {
 struct GetTypeInfo<const Ref<T> &> {
 	enum { VARIANT_TYPE = Variant::OBJECT };
 	enum { VARIANT_TYPE = Variant::OBJECT };
 
 
-	static inline StringName get_class_name() {
-		return T::get_class_static();
+	static inline PropertyInfo get_class_info() {
+		return PropertyInfo(Variant::OBJECT, String(), PROPERTY_HINT_RESOURCE_TYPE, T::get_class_static());
 	}
 	}
 };
 };
 
 

+ 52 - 33
core/type_info.h

@@ -41,9 +41,9 @@ template <class T, typename = void>
 struct GetTypeInfo {
 struct GetTypeInfo {
 	enum { VARIANT_TYPE = Variant::NIL };
 	enum { VARIANT_TYPE = Variant::NIL };
 
 
-	static inline StringName get_class_name() {
+	static inline PropertyInfo get_class_info() {
 		ERR_PRINT("GetTypeInfo fallback. Bug!");
 		ERR_PRINT("GetTypeInfo fallback. Bug!");
-		return StringName(); // Not "Nil", this is an error
+		return PropertyInfo(); // Not "Nil", this is an error
 	}
 	}
 };
 };
 
 
@@ -51,15 +51,15 @@ struct GetTypeInfo {
 	template <>                                                         \
 	template <>                                                         \
 	struct GetTypeInfo<m_type> {                                        \
 	struct GetTypeInfo<m_type> {                                        \
 		enum { VARIANT_TYPE = m_var_type };                             \
 		enum { VARIANT_TYPE = m_var_type };                             \
-		static inline StringName get_class_name() {                     \
-			return Variant::get_type_name((Variant::Type)VARIANT_TYPE); \
+		static inline PropertyInfo get_class_info() {                     \
+			return PropertyInfo((Variant::Type)VARIANT_TYPE,String()); \
 		}                                                               \
 		}                                                               \
 	};                                                                  \
 	};                                                                  \
 	template <>                                                         \
 	template <>                                                         \
 	struct GetTypeInfo<const m_type &> {                                \
 	struct GetTypeInfo<const m_type &> {                                \
 		enum { VARIANT_TYPE = m_var_type };                             \
 		enum { VARIANT_TYPE = m_var_type };                             \
-		static inline StringName get_class_name() {                     \
-			return Variant::get_type_name((Variant::Type)VARIANT_TYPE); \
+		static inline PropertyInfo get_class_info() {                     \
+			return PropertyInfo((Variant::Type)VARIANT_TYPE,String()); \
 		}                                                               \
 		}                                                               \
 	};
 	};
 
 
@@ -105,38 +105,54 @@ MAKE_TYPE_INFO(IP_Address, Variant::STRING)
 class BSP_Tree;
 class BSP_Tree;
 MAKE_TYPE_INFO(BSP_Tree, Variant::DICTIONARY)
 MAKE_TYPE_INFO(BSP_Tree, Variant::DICTIONARY)
 
 
-#define MAKE_TYPE_INFO_WITH_NAME(m_type, m_var_type, m_class_name) \
-	template <>                                                    \
-	struct GetTypeInfo<m_type> {                                   \
-		enum { VARIANT_TYPE = m_var_type };                        \
-		static inline StringName get_class_name() {                \
-			return m_class_name;                                   \
-		}                                                          \
-	};                                                             \
-	template <>                                                    \
-	struct GetTypeInfo<const m_type &> {                           \
-		enum { VARIANT_TYPE = m_var_type };                        \
-		static inline StringName get_class_name() {                \
-			return m_class_name;                                   \
-		}                                                          \
-	};
+//for RefPtr
+template <>
+struct GetTypeInfo<RefPtr> {
+	enum { VARIANT_TYPE = Variant::OBJECT };
+	static inline PropertyInfo get_class_info() {
+		return PropertyInfo(Variant::OBJECT,String(),PROPERTY_HINT_RESOURCE_TYPE,"Reference");
+	}
+};
+template <>
+struct GetTypeInfo<const RefPtr &> {
+	enum { VARIANT_TYPE = Variant::OBJECT };
+	static inline PropertyInfo get_class_info() {
+		return PropertyInfo(Variant::OBJECT,String(),PROPERTY_HINT_RESOURCE_TYPE,"Reference");
+	}
+};
+
+
+//for variant
+template<>
+struct GetTypeInfo<Variant> {
+	enum { VARIANT_TYPE = Variant::NIL };
+	static inline PropertyInfo get_class_info() {
+		return PropertyInfo(Variant::NIL,String(),PROPERTY_HINT_NONE,String(),PROPERTY_USAGE_DEFAULT|PROPERTY_USAGE_NIL_IS_VARIANT);
+	}
+};
+
+template<>
+struct GetTypeInfo<const Variant&> {
+	enum { VARIANT_TYPE = Variant::NIL };
+	static inline PropertyInfo get_class_info() {
+		return PropertyInfo(Variant::NIL,String(),PROPERTY_HINT_NONE,String(),PROPERTY_USAGE_DEFAULT|PROPERTY_USAGE_NIL_IS_VARIANT);
+	}
+};
 
 
-MAKE_TYPE_INFO_WITH_NAME(RefPtr, Variant::OBJECT, "Reference")
-MAKE_TYPE_INFO_WITH_NAME(Variant, Variant::NIL, "Variant")
 
 
 #define MAKE_TEMPLATE_TYPE_INFO(m_template, m_type, m_var_type)         \
 #define MAKE_TEMPLATE_TYPE_INFO(m_template, m_type, m_var_type)         \
 	template <>                                                         \
 	template <>                                                         \
 	struct GetTypeInfo<m_template<m_type> > {                           \
 	struct GetTypeInfo<m_template<m_type> > {                           \
 		enum { VARIANT_TYPE = m_var_type };                             \
 		enum { VARIANT_TYPE = m_var_type };                             \
-		static inline StringName get_class_name() {                     \
-			return Variant::get_type_name((Variant::Type)VARIANT_TYPE); \
+		static inline PropertyInfo get_class_info() {                     \
+			return PropertyInfo((Variant::Type)VARIANT_TYPE,String()); \
 		}                                                               \
 		}                                                               \
 	};                                                                  \
 	};                                                                  \
 	template <>                                                         \
 	template <>                                                         \
 	struct GetTypeInfo<const m_template<m_type> &> {                    \
 	struct GetTypeInfo<const m_template<m_type> &> {                    \
 		enum { VARIANT_TYPE = m_var_type };                             \
 		enum { VARIANT_TYPE = m_var_type };                             \
-		static inline StringName get_class_name() {                     \
-			return Variant::get_type_name((Variant::Type)VARIANT_TYPE); \
+		static inline PropertyInfo get_class_info() {                     \
+			return PropertyInfo((Variant::Type)VARIANT_TYPE,String()); \
 		}                                                               \
 		}                                                               \
 	};
 	};
 
 
@@ -159,17 +175,18 @@ template <typename T>
 struct GetTypeInfo<T *, typename EnableIf<TypeInherits<Object, T>::value>::type> {
 struct GetTypeInfo<T *, typename EnableIf<TypeInherits<Object, T>::value>::type> {
 	enum { VARIANT_TYPE = Variant::OBJECT };
 	enum { VARIANT_TYPE = Variant::OBJECT };
 
 
-	static inline StringName get_class_name() {
-		return T::get_class_static();
+	static inline PropertyInfo get_class_info() {
+		return PropertyInfo(StringName(T::get_class_static()));
 	}
 	}
+
 };
 };
 
 
 template <typename T>
 template <typename T>
 struct GetTypeInfo<const T *, typename EnableIf<TypeInherits<Object, T>::value>::type> {
 struct GetTypeInfo<const T *, typename EnableIf<TypeInherits<Object, T>::value>::type> {
 	enum { VARIANT_TYPE = Variant::OBJECT };
 	enum { VARIANT_TYPE = Variant::OBJECT };
 
 
-	static inline StringName get_class_name() {
-		return T::get_class_static();
+	static inline PropertyInfo get_class_info() {
+		return PropertyInfo(StringName(T::get_class_static()));
 	}
 	}
 };
 };
 
 
@@ -177,7 +194,9 @@ struct GetTypeInfo<const T *, typename EnableIf<TypeInherits<Object, T>::value>:
 	template <>                                                               \
 	template <>                                                               \
 	struct GetTypeInfo<m_impl> {                                              \
 	struct GetTypeInfo<m_impl> {                                              \
 		enum { VARIANT_TYPE = Variant::INT };                                 \
 		enum { VARIANT_TYPE = Variant::INT };                                 \
-		static inline StringName get_class_name() { return "enum." #m_enum; } \
+		static inline PropertyInfo get_class_info() { \
+			return PropertyInfo(Variant::INT,String(),PROPERTY_HINT_NONE,String(),PROPERTY_USAGE_DEFAULT|PROPERTY_USAGE_CLASS_IS_ENUM,String(#m_enum).replace("::","."));  \
+		}  	\
 	};
 	};
 
 
 #define MAKE_ENUM_TYPE_INFO(m_enum)                 \
 #define MAKE_ENUM_TYPE_INFO(m_enum)                 \
@@ -190,7 +209,7 @@ template <typename T>
 inline StringName __constant_get_enum_name(T param, const String &p_constant) {
 inline StringName __constant_get_enum_name(T param, const String &p_constant) {
 	if (GetTypeInfo<T>::VARIANT_TYPE == Variant::NIL)
 	if (GetTypeInfo<T>::VARIANT_TYPE == Variant::NIL)
 		ERR_PRINTS("Missing VARIANT_ENUM_CAST for constant's enum: " + p_constant);
 		ERR_PRINTS("Missing VARIANT_ENUM_CAST for constant's enum: " + p_constant);
-	return GetTypeInfo<T>::get_class_name();
+	return GetTypeInfo<T>::get_class_info().class_name;
 }
 }
 
 
 #else
 #else

+ 97 - 109
editor/doc/doc_data.cpp

@@ -196,10 +196,40 @@ void DocData::generate(bool p_basic_types) {
 			prop.name = E->get().name;
 			prop.name = E->get().name;
 			prop.setter = setter;
 			prop.setter = setter;
 			prop.getter = getter;
 			prop.getter = getter;
-			if (E->get().type == Variant::OBJECT && E->get().hint == PROPERTY_HINT_RESOURCE_TYPE)
-				prop.type = E->get().hint_string;
-			else
-				prop.type = Variant::get_type_name(E->get().type);
+
+			bool found_type = false;
+			if (getter != StringName()) {
+				MethodBind *mb = ClassDB::get_method(name, getter);
+				if (mb) {
+					PropertyInfo retinfo = mb->get_return_info();
+
+					found_type = true;
+					if (retinfo.type == Variant::INT && retinfo.usage & PROPERTY_USAGE_CLASS_IS_ENUM) {
+						prop.enumeration = retinfo.class_name;
+						prop.type = "int";
+					} else if (retinfo.class_name != StringName()) {
+						prop.type = retinfo.class_name;
+					} else if (retinfo.hint == PROPERTY_HINT_RESOURCE_TYPE) {
+
+						prop.type = retinfo.hint_string;
+					} else if (retinfo.type == Variant::NIL && retinfo.usage & PROPERTY_USAGE_NIL_IS_VARIANT) {
+
+						prop.type = "Variant";
+					} else if (retinfo.type == Variant::NIL) {
+						prop.type = "void";
+					} else {
+						prop.type = Variant::get_type_name(retinfo.type);
+					}
+				}
+			}
+
+			if (!found_type) {
+
+				if (E->get().type == Variant::OBJECT && E->get().hint == PROPERTY_HINT_RESOURCE_TYPE)
+					prop.type = E->get().hint_string;
+				else
+					prop.type = Variant::get_type_name(E->get().type);
+			}
 
 
 			c.properties.push_back(prop);
 			c.properties.push_back(prop);
 		}
 		}
@@ -217,8 +247,6 @@ void DocData::generate(bool p_basic_types) {
 
 
 			method.name = E->get().name;
 			method.name = E->get().name;
 
 
-			MethodBind *m = ClassDB::get_method(name, E->get().name);
-
 			if (E->get().flags & METHOD_FLAG_VIRTUAL)
 			if (E->get().flags & METHOD_FLAG_VIRTUAL)
 				method.qualifiers = "virtual";
 				method.qualifiers = "virtual";
 			if (E->get().flags & METHOD_FLAG_CONST) {
 			if (E->get().flags & METHOD_FLAG_CONST) {
@@ -234,122 +262,59 @@ void DocData::generate(bool p_basic_types) {
 
 
 			for (int i = -1; i < E->get().arguments.size(); i++) {
 			for (int i = -1; i < E->get().arguments.size(); i++) {
 
 
-				PropertyInfo arginfo;
-
 				if (i == -1) {
 				if (i == -1) {
 
 
-					arginfo = E->get().return_val;
 #ifdef DEBUG_METHODS_ENABLED
 #ifdef DEBUG_METHODS_ENABLED
-					if (m && m->get_return_type() != StringName())
-						method.return_type = m->get_return_type();
-					else if (method.name.find(":") != -1) {
-						method.return_type = method.name.get_slice(":", 1);
-						method.name = method.name.get_slice(":", 0);
 
 
-					} else if (arginfo.type != Variant::NIL) // {
+					PropertyInfo retinfo = E->get().return_val;
+
+					if (retinfo.type == Variant::INT && retinfo.usage & PROPERTY_USAGE_CLASS_IS_ENUM) {
+						method.return_enum = retinfo.class_name;
+						method.return_type = "int";
+					} else if (retinfo.class_name != StringName()) {
+						method.return_type = retinfo.class_name;
+					} else if (retinfo.hint == PROPERTY_HINT_RESOURCE_TYPE) {
+
+						method.return_type = retinfo.hint_string;
+					} else if (retinfo.type == Variant::NIL && retinfo.usage & PROPERTY_USAGE_NIL_IS_VARIANT) {
+
+						method.return_type = "Variant";
+					} else if (retinfo.type == Variant::NIL) {
+						method.return_type = "void";
+					} else {
+						method.return_type = Variant::get_type_name(retinfo.type);
+					}
 #endif
 #endif
-						method.return_type = (arginfo.hint == PROPERTY_HINT_RESOURCE_TYPE) ? arginfo.hint_string : Variant::get_type_name(arginfo.type);
-					//}
 
 
 				} else {
 				} else {
 
 
 					ArgumentDoc argument;
 					ArgumentDoc argument;
 
 
-					arginfo = E->get().arguments[i];
-
-					String type_name;
-
-					if (arginfo.name.find(":") != -1) {
-						type_name = arginfo.name.get_slice(":", 1);
-						arginfo.name = arginfo.name.get_slice(":", 0);
+					PropertyInfo arginfo = E->get().arguments[i];
 
 
+					if (arginfo.type == Variant::INT && arginfo.usage & PROPERTY_USAGE_CLASS_IS_ENUM) {
+						argument.enumeration = arginfo.class_name;
+						argument.type = "int";
+					} else if (arginfo.class_name != StringName()) {
+						argument.type = arginfo.class_name;
 					} else if (arginfo.hint == PROPERTY_HINT_RESOURCE_TYPE) {
 					} else if (arginfo.hint == PROPERTY_HINT_RESOURCE_TYPE) {
-						type_name = arginfo.hint_string;
-					} else if (arginfo.type == Variant::NIL)
-						type_name = "Variant";
-					else
-						type_name = Variant::get_type_name(arginfo.type);
 
 
-					if (arginfo.type == Variant::OBJECT) {
+						argument.type = arginfo.hint_string;
+					} else if (arginfo.type == Variant::NIL && arginfo.usage & PROPERTY_USAGE_NIL_IS_VARIANT) {
 
 
-						//print_line("validate: "+cname+"::"+method.name);
-					}
-
-					if (m && m->has_default_argument(i)) {
-						Variant default_arg = m->get_default_argument(i);
-						String default_arg_text = m->get_default_argument(i);
-
-						switch (default_arg.get_type()) {
-
-							case Variant::NIL:
-								default_arg_text = "NULL";
-								break;
-							// atomic types
-							case Variant::BOOL:
-								if (bool(default_arg))
-									default_arg_text = "true";
-								else
-									default_arg_text = "false";
-								break;
-							case Variant::INT:
-							case Variant::REAL:
-								//keep it
-								break;
-							case Variant::STRING:
-							case Variant::NODE_PATH:
-								default_arg_text = "\"" + default_arg_text + "\"";
-								break;
-							case Variant::TRANSFORM:
-								if (default_arg.operator Transform() == Transform()) {
-									default_arg_text = "";
-								}
-
-								default_arg_text = Variant::get_type_name(default_arg.get_type()) + "(" + default_arg_text + ")";
-								break;
-
-							case Variant::RECT3:
-							case Variant::COLOR:
-							case Variant::PLANE:
-							case Variant::POOL_BYTE_ARRAY:
-							case Variant::POOL_INT_ARRAY:
-							case Variant::POOL_REAL_ARRAY:
-							case Variant::POOL_STRING_ARRAY:
-							case Variant::POOL_VECTOR2_ARRAY:
-							case Variant::POOL_VECTOR3_ARRAY:
-							case Variant::POOL_COLOR_ARRAY:
-								default_arg_text = Variant::get_type_name(default_arg.get_type()) + "(" + default_arg_text + ")";
-								break;
-							case Variant::VECTOR2:
-							case Variant::RECT2:
-							case Variant::VECTOR3:
-							case Variant::QUAT:
-							case Variant::BASIS:
-								default_arg_text = Variant::get_type_name(default_arg.get_type()) + default_arg_text;
-								break;
-							case Variant::OBJECT:
-								if (default_arg.is_zero()) {
-									default_arg_text = "NULL";
-									break;
-								}
-							case Variant::DICTIONARY: // 20
-							case Variant::ARRAY:
-							case Variant::_RID:
-
-							default: {}
-						}
-
-						argument.type = type_name;
-						argument.name = arginfo.name;
-						argument.default_value = default_arg_text;
+						argument.type = "Variant";
+					} else if (arginfo.type == Variant::NIL) {
+						method.return_type = "void";
 					} else {
 					} else {
-
-						argument.type = type_name;
-						argument.name = arginfo.name;
+						argument.type = Variant::get_type_name(arginfo.type);
 					}
 					}
 
 
-					if (arginfo.type == Variant::OBJECT) {
+					argument.name = E->get().arguments[i].name;
+					int darg_idx = i - (E->get().arguments.size() - E->get().default_arguments.size());
 
 
-						//print_line("validate: "+cname+"::"+method.name);
+					if (darg_idx >= 0) {
+						Variant default_arg = E->get().default_arguments[darg_idx];
+						argument.default_value = default_arg.get_construct_string();
 					}
 					}
 
 
 					method.arguments.push_back(argument);
 					method.arguments.push_back(argument);
@@ -404,6 +369,7 @@ void DocData::generate(bool p_basic_types) {
 			ConstantDoc constant;
 			ConstantDoc constant;
 			constant.name = E->get();
 			constant.name = E->get();
 			constant.value = itos(ClassDB::get_integer_constant(name, E->get()));
 			constant.value = itos(ClassDB::get_integer_constant(name, E->get()));
+			constant.enumeration = ClassDB::get_integer_constant_enum(name, E->get());
 			c.constants.push_back(constant);
 			c.constants.push_back(constant);
 		}
 		}
 
 
@@ -565,6 +531,7 @@ void DocData::generate(bool p_basic_types) {
 			ConstantDoc cd;
 			ConstantDoc cd;
 			cd.name = GlobalConstants::get_global_constant_name(i);
 			cd.name = GlobalConstants::get_global_constant_name(i);
 			cd.value = itos(GlobalConstants::get_global_constant_value(i));
 			cd.value = itos(GlobalConstants::get_global_constant_value(i));
+			cd.enumeration = GlobalConstants::get_global_constant_enum(i);
 			c.constants.push_back(cd);
 			c.constants.push_back(cd);
 		}
 		}
 
 
@@ -680,6 +647,9 @@ static Error _parse_methods(Ref<XMLParser> &parser, Vector<DocData::MethodDoc> &
 							argument.name = parser->get_attribute_value("name");
 							argument.name = parser->get_attribute_value("name");
 							ERR_FAIL_COND_V(!parser->has_attribute("type"), ERR_FILE_CORRUPT);
 							ERR_FAIL_COND_V(!parser->has_attribute("type"), ERR_FILE_CORRUPT);
 							argument.type = parser->get_attribute_value("type");
 							argument.type = parser->get_attribute_value("type");
+							if (parser->has_attribute("enum")) {
+								argument.enumeration = parser->get_attribute_value("enum");
+							}
 
 
 							method.arguments.push_back(argument);
 							method.arguments.push_back(argument);
 
 
@@ -803,7 +773,8 @@ Error DocData::_load(Ref<XMLParser> parser) {
 									prop.getter = parser->get_attribute_value("getter");
 									prop.getter = parser->get_attribute_value("getter");
 								if (parser->has_attribute("brief"))
 								if (parser->has_attribute("brief"))
 									prop.brief_description = parser->get_attribute_value("brief").xml_unescape();
 									prop.brief_description = parser->get_attribute_value("brief").xml_unescape();
-
+								if (parser->has_attribute("enum"))
+									prop.enumeration = parser->get_attribute_value("enum");
 								parser->read();
 								parser->read();
 								if (parser->get_node_type() == XMLParser::NODE_TEXT)
 								if (parser->get_node_type() == XMLParser::NODE_TEXT)
 									prop.description = parser->get_node_data().strip_edges();
 									prop.description = parser->get_node_data().strip_edges();
@@ -861,6 +832,9 @@ Error DocData::_load(Ref<XMLParser> parser) {
 								constant.name = parser->get_attribute_value("name");
 								constant.name = parser->get_attribute_value("name");
 								ERR_FAIL_COND_V(!parser->has_attribute("value"), ERR_FILE_CORRUPT);
 								ERR_FAIL_COND_V(!parser->has_attribute("value"), ERR_FILE_CORRUPT);
 								constant.value = parser->get_attribute_value("value");
 								constant.value = parser->get_attribute_value("value");
+								if (parser->has_attribute("enum")) {
+									constant.enumeration = parser->get_attribute_value("enum");
+								}
 								parser->read();
 								parser->read();
 								if (parser->get_node_type() == XMLParser::NODE_TEXT)
 								if (parser->get_node_type() == XMLParser::NODE_TEXT)
 									constant.description = parser->get_node_data().strip_edges();
 									constant.description = parser->get_node_data().strip_edges();
@@ -955,10 +929,16 @@ Error DocData::save(const String &p_path) {
 			for (int j = 0; j < m.arguments.size(); j++) {
 			for (int j = 0; j < m.arguments.size(); j++) {
 
 
 				ArgumentDoc &a = m.arguments[j];
 				ArgumentDoc &a = m.arguments[j];
+
+				String enum_text;
+				if (a.enumeration != String()) {
+					enum_text = "enum=\"" + a.enumeration + "\"";
+				}
+
 				if (a.default_value != "")
 				if (a.default_value != "")
-					_write_string(f, 3, "<argument index=\"" + itos(j) + "\" name=\"" + a.name.xml_escape() + "\" type=\"" + a.type.xml_escape() + "\" default=\"" + a.default_value.xml_escape(true) + "\">");
+					_write_string(f, 3, "<argument index=\"" + itos(j) + "\" name=\"" + a.name.xml_escape() + "\" type=\"" + a.type.xml_escape() + "\" " + enum_text + " default=\"" + a.default_value.xml_escape(true) + "\">");
 				else
 				else
-					_write_string(f, 3, "<argument index=\"" + itos(j) + "\" name=\"" + a.name.xml_escape() + "\" type=\"" + a.type.xml_escape() + "\">");
+					_write_string(f, 3, "<argument index=\"" + itos(j) + "\" name=\"" + a.name.xml_escape() + "\" type=\"" + a.type.xml_escape() + "\" " + enum_text + ">");
 
 
 				_write_string(f, 3, "</argument>");
 				_write_string(f, 3, "</argument>");
 			}
 			}
@@ -980,8 +960,12 @@ Error DocData::save(const String &p_path) {
 
 
 			for (int i = 0; i < c.properties.size(); i++) {
 			for (int i = 0; i < c.properties.size(); i++) {
 
 
+				String enum_text;
+				if (c.properties[i].enumeration != String()) {
+					enum_text = "enum=\"" + c.properties[i].enumeration + "\"";
+				}
 				PropertyDoc &p = c.properties[i];
 				PropertyDoc &p = c.properties[i];
-				_write_string(f, 2, "<member name=\"" + p.name + "\" type=\"" + p.type + "\" setter=\"" + p.setter + "\" getter=\"" + p.getter + "\" brief=\"" + p.brief_description.xml_escape(true) + "\">");
+				_write_string(f, 2, "<member name=\"" + p.name + "\" type=\"" + p.type + "\" setter=\"" + p.setter + "\" getter=\"" + p.getter + "\" brief=\"" + p.brief_description.xml_escape(true) + "\" " + enum_text + " >");
 				if (p.description != "")
 				if (p.description != "")
 					_write_string(f, 3, p.description.xml_escape());
 					_write_string(f, 3, p.description.xml_escape());
 				_write_string(f, 2, "</member>");
 				_write_string(f, 2, "</member>");
@@ -1021,7 +1005,11 @@ Error DocData::save(const String &p_path) {
 		for (int i = 0; i < c.constants.size(); i++) {
 		for (int i = 0; i < c.constants.size(); i++) {
 
 
 			ConstantDoc &k = c.constants[i];
 			ConstantDoc &k = c.constants[i];
-			_write_string(f, 2, "<constant name=\"" + k.name + "\" value=\"" + k.value + "\">");
+			if (k.enumeration != String()) {
+				_write_string(f, 2, "<constant name=\"" + k.name + "\" value=\"" + k.value + "\">");
+			} else {
+				_write_string(f, 2, "<constant name=\"" + k.name + "\" value=\"" + k.value + "\" enum=\"" + k.enumeration + "\">");
+			}
 			if (k.description != "")
 			if (k.description != "")
 				_write_string(f, 3, k.description.xml_escape());
 				_write_string(f, 3, k.description.xml_escape());
 			_write_string(f, 2, "</constant>");
 			_write_string(f, 2, "</constant>");

+ 4 - 0
editor/doc/doc_data.h

@@ -40,6 +40,7 @@ public:
 
 
 		String name;
 		String name;
 		String type;
 		String type;
+		String enumeration;
 		String default_value;
 		String default_value;
 	};
 	};
 
 
@@ -47,6 +48,7 @@ public:
 
 
 		String name;
 		String name;
 		String return_type;
 		String return_type;
+		String return_enum;
 		String qualifiers;
 		String qualifiers;
 		String description;
 		String description;
 		Vector<ArgumentDoc> arguments;
 		Vector<ArgumentDoc> arguments;
@@ -59,6 +61,7 @@ public:
 
 
 		String name;
 		String name;
 		String value;
 		String value;
+		String enumeration;
 		String description;
 		String description;
 	};
 	};
 
 
@@ -66,6 +69,7 @@ public:
 
 
 		String name;
 		String name;
 		String type;
 		String type;
+		String enumeration;
 		String brief_description;
 		String brief_description;
 		String description;
 		String description;
 		String setter, getter;
 		String setter, getter;

+ 165 - 36
editor/editor_help.cpp

@@ -582,7 +582,18 @@ void EditorHelp::_class_list_select(const String &p_select) {
 void EditorHelp::_class_desc_select(const String &p_select) {
 void EditorHelp::_class_desc_select(const String &p_select) {
 
 
 	//print_line("LINK: "+p_select);
 	//print_line("LINK: "+p_select);
-	if (p_select.begins_with("#")) {
+	if (p_select.begins_with("$")) { //enum
+		//_goto_desc(p_select.substr(1,p_select.length()));
+		String select = p_select.substr(1, p_select.length());
+		String class_name;
+		if (select.find(".") != -1) {
+			class_name = select.get_slice(".", 0);
+		} else {
+			class_name = "@Global Scope";
+		}
+		emit_signal("go_to_help", "class_enum:" + class_name + ":" + select);
+		return;
+	} else if (p_select.begins_with("#")) {
 		//_goto_desc(p_select.substr(1,p_select.length()));
 		//_goto_desc(p_select.substr(1,p_select.length()));
 		emit_signal("go_to_help", "class_name:" + p_select.substr(1, p_select.length()));
 		emit_signal("go_to_help", "class_name:" + p_select.substr(1, p_select.length()));
 		return;
 		return;
@@ -614,16 +625,28 @@ void EditorHelp::_class_desc_input(const Ref<InputEvent> &p_input) {
 	set_focused();
 	set_focused();
 }
 }
 
 
-void EditorHelp::_add_type(const String &p_type) {
+void EditorHelp::_add_type(const String &p_type, const String &p_enum) {
 
 
 	String t = p_type;
 	String t = p_type;
 	if (t == "")
 	if (t == "")
 		t = "void";
 		t = "void";
-	bool can_ref = (t != "int" && t != "real" && t != "bool" && t != "void");
+	bool can_ref = (t != "int" && t != "real" && t != "bool" && t != "void") || p_enum != String();
 
 
+	if (p_enum != String()) {
+		if (p_enum.get_slice_count(".") > 1) {
+			t = p_enum.get_slice(".", 1);
+		} else {
+			t = p_enum.get_slice(".", 0);
+		}
+	}
 	class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/base_type_color"));
 	class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/base_type_color"));
-	if (can_ref)
-		class_desc->push_meta("#" + t); //class
+	if (can_ref) {
+		if (p_enum == "") {
+			class_desc->push_meta("#" + t); //class
+		} else {
+			class_desc->push_meta("$" + p_enum); //class
+		}
+	}
 	class_desc->add_text(t);
 	class_desc->add_text(t);
 	if (can_ref)
 	if (can_ref)
 		class_desc->pop();
 		class_desc->pop();
@@ -782,7 +805,7 @@ Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) {
 			class_desc->push_cell();
 			class_desc->push_cell();
 			class_desc->push_align(RichTextLabel::ALIGN_RIGHT);
 			class_desc->push_align(RichTextLabel::ALIGN_RIGHT);
 			class_desc->push_font(doc_code_font);
 			class_desc->push_font(doc_code_font);
-			_add_type(cd.properties[i].type);
+			_add_type(cd.properties[i].type, cd.properties[i].enumeration);
 			class_desc->add_text(" ");
 			class_desc->add_text(" ");
 			class_desc->pop();
 			class_desc->pop();
 			class_desc->pop();
 			class_desc->pop();
@@ -875,7 +898,7 @@ Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) {
 			method_line[methods[i].name] = class_desc->get_line_count() - 2; //gets overridden if description
 			method_line[methods[i].name] = class_desc->get_line_count() - 2; //gets overridden if description
 			class_desc->push_align(RichTextLabel::ALIGN_RIGHT);
 			class_desc->push_align(RichTextLabel::ALIGN_RIGHT);
 			class_desc->push_font(doc_code_font);
 			class_desc->push_font(doc_code_font);
-			_add_type(methods[i].return_type);
+			_add_type(methods[i].return_type, methods[i].return_enum);
 			//class_desc->add_text(" ");
 			//class_desc->add_text(" ");
 			class_desc->pop(); //align
 			class_desc->pop(); //align
 			class_desc->pop(); //font
 			class_desc->pop(); //font
@@ -899,7 +922,7 @@ Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) {
 				class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/text_color"));
 				class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/text_color"));
 				if (j > 0)
 				if (j > 0)
 					class_desc->add_text(", ");
 					class_desc->add_text(", ");
-				_add_type(methods[i].arguments[j].type);
+				_add_type(methods[i].arguments[j].type, methods[i].arguments[j].enumeration);
 				class_desc->add_text(" ");
 				class_desc->add_text(" ");
 				_add_text(methods[i].arguments[j].name);
 				_add_text(methods[i].arguments[j].name);
 				if (methods[i].arguments[j].default_value != "") {
 				if (methods[i].arguments[j].default_value != "") {
@@ -1048,44 +1071,133 @@ Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) {
 
 
 	if (cd.constants.size()) {
 	if (cd.constants.size()) {
 
 
-		class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color"));
-		class_desc->push_font(doc_title_font);
-		class_desc->add_text(TTR("Constants:"));
-		class_desc->pop();
-		class_desc->pop();
-		class_desc->push_indent(1);
-
-		class_desc->add_newline();
-		//class_desc->add_newline();
+		Map<String, Vector<DocData::ConstantDoc> > enums;
+		Vector<DocData::ConstantDoc> constants;
 
 
 		for (int i = 0; i < cd.constants.size(); i++) {
 		for (int i = 0; i < cd.constants.size(); i++) {
 
 
-			constant_line[cd.constants[i].name] = class_desc->get_line_count() - 2;
-			class_desc->push_font(doc_code_font);
-			class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/base_type_color"));
-			_add_text(cd.constants[i].name);
+			if (cd.constants[i].enumeration != String()) {
+				if (!enums.has(cd.constants[i].enumeration)) {
+					enums[cd.constants[i].enumeration] = Vector<DocData::ConstantDoc>();
+				}
+
+				enums[cd.constants[i].enumeration].push_back(cd.constants[i]);
+			} else {
+
+				constants.push_back(cd.constants[i]);
+			}
+		}
+
+		if (enums.size()) {
+
+			class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color"));
+			class_desc->push_font(doc_title_font);
+			class_desc->add_text(TTR("Enumerations:"));
 			class_desc->pop();
 			class_desc->pop();
-			class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/symbol_color"));
-			class_desc->add_text(" = ");
 			class_desc->pop();
 			class_desc->pop();
+			class_desc->push_indent(1);
+
+			class_desc->add_newline();
+			//class_desc->add_newline();
+
+			for (Map<String, Vector<DocData::ConstantDoc> >::Element *E = enums.front(); E; E = E->next()) {
+
+				enum_line[E->key()] = class_desc->get_line_count() - 2;
+
+				class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color"));
+				class_desc->add_text(TTR("enum  "));
+				class_desc->pop();
+				class_desc->push_font(doc_code_font);
+				String e = E->key();
+				if (e.get_slice_count(".")) {
+					e = e.get_slice(".", 1);
+				}
+
+				class_desc->add_text(e);
+				class_desc->pop();
+				class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color"));
+				class_desc->add_text(":");
+				class_desc->pop();
+				class_desc->add_newline();
+
+				class_desc->push_indent(1);
+				Vector<DocData::ConstantDoc> enum_list = E->get();
+
+				for (int i = 0; i < enum_list.size(); i++) {
+
+					class_desc->push_font(doc_code_font);
+					class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/base_type_color"));
+					_add_text(enum_list[i].name);
+					class_desc->pop();
+					class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/symbol_color"));
+					class_desc->add_text(" = ");
+					class_desc->pop();
+					class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color"));
+					_add_text(enum_list[i].value);
+					class_desc->pop();
+					class_desc->pop();
+					if (enum_list[i].description != "") {
+						class_desc->push_font(doc_font);
+						class_desc->add_text("  ");
+						class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/comment_color"));
+						_add_text(enum_list[i].description);
+						class_desc->pop();
+						class_desc->pop();
+					}
+
+					class_desc->add_newline();
+				}
+
+				class_desc->pop();
+
+				class_desc->add_newline();
+			}
+
+			class_desc->pop();
+			class_desc->add_newline();
+		}
+
+		if (constants.size()) {
+
 			class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color"));
 			class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color"));
-			_add_text(cd.constants[i].value);
+			class_desc->push_font(doc_title_font);
+			class_desc->add_text(TTR("Constants:"));
 			class_desc->pop();
 			class_desc->pop();
 			class_desc->pop();
 			class_desc->pop();
-			if (cd.constants[i].description != "") {
-				class_desc->push_font(doc_font);
-				class_desc->add_text("  ");
-				class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/comment_color"));
-				_add_text(cd.constants[i].description);
+			class_desc->push_indent(1);
+
+			class_desc->add_newline();
+			//class_desc->add_newline();
+
+			for (int i = 0; i < constants.size(); i++) {
+
+				constant_line[constants[i].name] = class_desc->get_line_count() - 2;
+				class_desc->push_font(doc_code_font);
+				class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/base_type_color"));
+				_add_text(constants[i].name);
+				class_desc->pop();
+				class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/symbol_color"));
+				class_desc->add_text(" = ");
+				class_desc->pop();
+				class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color"));
+				_add_text(constants[i].value);
 				class_desc->pop();
 				class_desc->pop();
 				class_desc->pop();
 				class_desc->pop();
+				if (constants[i].description != "") {
+					class_desc->push_font(doc_font);
+					class_desc->add_text("  ");
+					class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/comment_color"));
+					_add_text(constants[i].description);
+					class_desc->pop();
+					class_desc->pop();
+				}
+
+				class_desc->add_newline();
 			}
 			}
 
 
+			class_desc->pop();
 			class_desc->add_newline();
 			class_desc->add_newline();
 		}
 		}
-
-		class_desc->pop();
-		class_desc->add_newline();
 	}
 	}
 
 
 	if (cd.description != "") {
 	if (cd.description != "") {
@@ -1126,7 +1238,7 @@ Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) {
 			method_line[cd.properties[i].name] = class_desc->get_line_count() - 2;
 			method_line[cd.properties[i].name] = class_desc->get_line_count() - 2;
 
 
 			class_desc->push_font(doc_code_font);
 			class_desc->push_font(doc_code_font);
-			_add_type(cd.properties[i].type);
+			_add_type(cd.properties[i].type, cd.properties[i].enumeration);
 
 
 			class_desc->add_text(" ");
 			class_desc->add_text(" ");
 			class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/text_color"));
 			class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/text_color"));
@@ -1204,7 +1316,7 @@ Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) {
 			method_line[methods[i].name] = class_desc->get_line_count() - 2;
 			method_line[methods[i].name] = class_desc->get_line_count() - 2;
 
 
 			class_desc->push_font(doc_code_font);
 			class_desc->push_font(doc_code_font);
-			_add_type(methods[i].return_type);
+			_add_type(methods[i].return_type, methods[i].return_enum);
 
 
 			class_desc->add_text(" ");
 			class_desc->add_text(" ");
 			class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/text_color"));
 			class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/text_color"));
@@ -1217,7 +1329,7 @@ Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) {
 				class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/text_color"));
 				class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/text_color"));
 				if (j > 0)
 				if (j > 0)
 					class_desc->add_text(", ");
 					class_desc->add_text(", ");
-				_add_type(methods[i].arguments[j].type);
+				_add_type(methods[i].arguments[j].type, methods[i].arguments[j].enumeration);
 				class_desc->add_text(" ");
 				class_desc->add_text(" ");
 				_add_text(methods[i].arguments[j].name);
 				_add_text(methods[i].arguments[j].name);
 				if (methods[i].arguments[j].default_value != "") {
 				if (methods[i].arguments[j].default_value != "") {
@@ -1295,6 +1407,11 @@ void EditorHelp::_help_callback(const String &p_topic) {
 
 
 		if (property_line.has(name))
 		if (property_line.has(name))
 			line = property_line[name];
 			line = property_line[name];
+	} else if (what == "class_enum") {
+
+		print_line("go to enum:");
+		if (enum_line.has(name))
+			line = enum_line[name];
 	} else if (what == "class_theme_item") {
 	} else if (what == "class_theme_item") {
 
 
 		if (theme_property_line.has(name))
 		if (theme_property_line.has(name))
@@ -1743,8 +1860,20 @@ void EditorHelpBit::_go_to_help(String p_what) {
 
 
 void EditorHelpBit::_meta_clicked(String p_select) {
 void EditorHelpBit::_meta_clicked(String p_select) {
 
 
+	print_line("got meta " + p_select);
 	//print_line("LINK: "+p_select);
 	//print_line("LINK: "+p_select);
-	if (p_select.begins_with("#")) {
+	if (p_select.begins_with("$")) { //enum
+		//_goto_desc(p_select.substr(1,p_select.length()));
+		String select = p_select.substr(1, p_select.length());
+		String class_name;
+		if (select.find(".") != -1) {
+			class_name = select.get_slice(".", 0);
+		} else {
+			class_name = "@Global";
+		}
+		_go_to_help("class_enum:" + class_name + ":" + select);
+		return;
+	} else if (p_select.begins_with("#")) {
 		//_goto_desc(p_select.substr(1,p_select.length()));
 		//_goto_desc(p_select.substr(1,p_select.length()));
 		_go_to_help("class_name:" + p_select.substr(1, p_select.length()));
 		_go_to_help("class_name:" + p_select.substr(1, p_select.length()));
 		return;
 		return;

+ 2 - 1
editor/editor_help.h

@@ -123,6 +123,7 @@ class EditorHelp : public VBoxContainer {
 	Map<String, int> property_line;
 	Map<String, int> property_line;
 	Map<String, int> theme_property_line;
 	Map<String, int> theme_property_line;
 	Map<String, int> constant_line;
 	Map<String, int> constant_line;
+	Map<String, int> enum_line;
 	int description_line;
 	int description_line;
 
 
 	RichTextLabel *class_desc;
 	RichTextLabel *class_desc;
@@ -141,7 +142,7 @@ class EditorHelp : public VBoxContainer {
 	bool scroll_locked;
 	bool scroll_locked;
 
 
 	//void _button_pressed(int p_idx);
 	//void _button_pressed(int p_idx);
-	void _add_type(const String &p_type);
+	void _add_type(const String &p_type, const String &p_enum = String());
 
 
 	void _class_list_select(const String &p_select);
 	void _class_list_select(const String &p_select);
 	void _class_desc_select(const String &p_select);
 	void _class_desc_select(const String &p_select);

+ 6 - 6
modules/gdscript/gd_editor.cpp

@@ -1041,11 +1041,11 @@ static bool _guess_identifier_type(GDCompletionContext &context, int p_line, con
 
 
 						PropertyInfo arg = E->get().arguments[argindex];
 						PropertyInfo arg = E->get().arguments[argindex];
 
 
-						int scp = arg.name.find(":");
+						int scp = String(arg.name).find(":");
 						if (scp != -1) {
 						if (scp != -1) {
 
 
 							r_type.type = Variant::OBJECT;
 							r_type.type = Variant::OBJECT;
-							r_type.obj_type = arg.name.substr(scp + 1, arg.name.length());
+							r_type.obj_type = String(arg.name).substr(scp + 1, String(arg.name).length());
 							return true;
 							return true;
 
 
 						} else {
 						} else {
@@ -1271,7 +1271,7 @@ static void _find_identifiers_in_class(GDCompletionContext &context, bool p_stat
 				for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {
 				for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {
 					if (E->get().usage & (PROPERTY_USAGE_GROUP | PROPERTY_USAGE_CATEGORY))
 					if (E->get().usage & (PROPERTY_USAGE_GROUP | PROPERTY_USAGE_CATEGORY))
 						continue;
 						continue;
-					if (E->get().name.find("/") != -1)
+					if (String(E->get().name).find("/") != -1)
 						continue;
 						continue;
 					result.insert(E->get().name);
 					result.insert(E->get().name);
 				}
 				}
@@ -2111,7 +2111,7 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_base
 						for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {
 						for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {
 							if (E->get().usage & (PROPERTY_USAGE_GROUP | PROPERTY_USAGE_CATEGORY))
 							if (E->get().usage & (PROPERTY_USAGE_GROUP | PROPERTY_USAGE_CATEGORY))
 								continue;
 								continue;
-							if (E->get().name.find("/") != -1)
+							if (String(E->get().name).find("/") != -1)
 								continue;
 								continue;
 							options.insert(E->get().name);
 							options.insert(E->get().name);
 						}
 						}
@@ -2245,7 +2245,7 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_base
 						for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {
 						for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {
 							if (E->get().usage & (PROPERTY_USAGE_GROUP | PROPERTY_USAGE_CATEGORY))
 							if (E->get().usage & (PROPERTY_USAGE_GROUP | PROPERTY_USAGE_CATEGORY))
 								continue;
 								continue;
-							if (E->get().name.find("/") != -1)
+							if (String(E->get().name).find("/") != -1)
 								continue;
 								continue;
 							r_options->push_back(E->get().name);
 							r_options->push_back(E->get().name);
 						}
 						}
@@ -2277,7 +2277,7 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_base
 							t.value.get_property_list(&pl);
 							t.value.get_property_list(&pl);
 							for (List<PropertyInfo>::Element *E = pl.front(); E; E = E->next()) {
 							for (List<PropertyInfo>::Element *E = pl.front(); E; E = E->next()) {
 
 
-								if (E->get().name.find("/") == -1)
+								if (String(E->get().name).find("/") == -1)
 									options.insert(E->get().name);
 									options.insert(E->get().name);
 							}
 							}
 						}
 						}