Prechádzať zdrojové kódy

-added new code completion guess locations, closes #1032
-moved commandline fix to mingw-only, should fix #1064

Juan Linietsky 10 rokov pred
rodič
commit
6b5b95bb4e

+ 0 - 20
SConstruct

@@ -170,26 +170,6 @@ if selected_platform in platform_list:
 	else:
 		env = env_base.Clone()
 
-	# Workaround for MinGW. See:
-	# http://www.scons.org/wiki/LongCmdLinesOnWin32
-	if (os.name=="nt"):
-		import subprocess
-		def mySpawn(sh, escape, cmd, args, env):
-				newargs = ' '.join(args[1:])
-				cmdline = cmd + " " + newargs
-				startupinfo = subprocess.STARTUPINFO()
-				startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
-				proc = subprocess.Popen(cmdline, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
-					stderr=subprocess.PIPE, startupinfo=startupinfo, shell = False, env = env)
-				data, err = proc.communicate()
-				rv = proc.wait()
-				if rv:
-					print "====="
-					print err
-					print "====="
-				return rv
-		env['SPAWN'] = mySpawn
-
 	env.extra_suffix=""
 
 	CCFLAGS = env.get('CCFLAGS', '')

+ 25 - 0
core/os/input.cpp

@@ -29,6 +29,7 @@
 #include "input.h"
 #include "input_map.h"
 #include "os/os.h"
+#include "globals.h"
 Input *Input::singleton=NULL;
 
 Input *Input::get_singleton() {
@@ -69,6 +70,30 @@ void Input::_bind_methods() {
 	ADD_SIGNAL( MethodInfo("joy_connection_changed", PropertyInfo(Variant::INT, "index"), PropertyInfo(Variant::BOOL, "connected")) );
 }
 
+void Input::get_argument_options(const StringName& p_function,int p_idx,List<String>*r_options) const {
+#ifdef TOOLS_ENABLED
+
+	String pf=p_function;
+	if (p_idx==0 && (pf=="is_action_pressed" || pf=="action_press" || pf=="action_release")) {
+
+		List<PropertyInfo> pinfo;
+		Globals::get_singleton()->get_property_list(&pinfo);
+
+		for(List<PropertyInfo>::Element *E=pinfo.front();E;E=E->next()) {
+			const PropertyInfo &pi=E->get();
+
+			if (!pi.name.begins_with("input/"))
+				continue;
+
+			String name = pi.name.substr(pi.name.find("/")+1,pi.name.length());
+			r_options->push_back("\""+name+"\"");
+
+		}
+	}
+#endif
+
+}
+
 Input::Input() {
 
 	singleton=this;

+ 2 - 0
core/os/input.h

@@ -76,6 +76,8 @@ public:
 	virtual void action_press(const StringName& p_action)=0;
 	virtual void action_release(const StringName& p_action)=0;
 
+	void get_argument_options(const StringName& p_function,int p_idx,List<String>*r_options) const;
+
 
 	Input();
 };

+ 1 - 1
drivers/gles2/rasterizer_gles2.cpp

@@ -145,7 +145,7 @@ static _FORCE_INLINE_ uint16_t make_half_float(float f) {
 
 	hf = (((uint16_t)sign) << 15) | (uint16_t)(mantissa);
 	*/
-	hf=0; //denormals do not work for 3D
+	hf=0; //denormals do not work for 3D, convert to zero
     }
     else
     {

+ 50 - 3
modules/gdscript/gd_editor.cpp

@@ -28,7 +28,7 @@
 /*************************************************************************/
 #include "gd_script.h"
 #include "gd_compiler.h"
-
+#include "globals.h"
 
 void GDScriptLanguage::get_comment_delimiters(List<String> *p_delimiters) const {
 
@@ -1276,7 +1276,23 @@ static void _make_function_hint(const GDParser::FunctionNode* p_func,int p_argid
 static void _find_type_arguments(const GDParser::Node*p_node,int p_line,const StringName& p_method,const GDCompletionIdentifier& id, int p_argidx, Set<String>& result, String& arghint) {
 
 
-	if (id.type==Variant::OBJECT && id.obj_type!=StringName()) {
+	if (id.type==Variant::INPUT_EVENT && String(p_method)=="is_action" && p_argidx==0) {
+
+		List<PropertyInfo> pinfo;
+		Globals::get_singleton()->get_property_list(&pinfo);
+
+		for(List<PropertyInfo>::Element *E=pinfo.front();E;E=E->next()) {
+			const PropertyInfo &pi=E->get();
+
+			if (!pi.name.begins_with("input/"))
+				continue;
+
+			String name = pi.name.substr(pi.name.find("/")+1,pi.name.length());
+			result.insert("\""+name+"\"");
+		}
+
+
+	} else if (id.type==Variant::OBJECT && id.obj_type!=StringName()) {
 
 
 		MethodBind *m = ObjectTypeDB::get_method(id.obj_type,p_method);
@@ -1299,7 +1315,7 @@ static void _find_type_arguments(const GDParser::Node*p_node,int p_line,const St
 				const GDParser::OperatorNode *op=static_cast<const GDParser::OperatorNode *>(p_node);
 				if (op->arguments.size()>)
 
-			}*/
+			}*/		
 		} else {
 
 			Object *obj=id.value;
@@ -1826,6 +1842,37 @@ Error GDScriptLanguage::complete_code(const String& p_code, const String& p_base
 
 			_find_call_arguments(context,p.get_completion_node(),p.get_completion_line(),p.get_completion_argument_index(),options,r_call_hint);
 		} break;
+		case GDParser::COMPLETION_VIRTUAL_FUNC: {
+
+			GDCompletionIdentifier cid = _get_native_class(context);
+
+			if (cid.obj_type!=StringName()) {
+				List<MethodInfo> vm;
+				ObjectTypeDB::get_virtual_methods(cid.obj_type,&vm);
+				for(List<MethodInfo>::Element *E=vm.front();E;E=E->next()) {
+
+					MethodInfo &mi=E->get();
+					String m = mi.name;
+					if (m.find(":")!=-1)
+						m=m.substr(0,m.find(":"));
+					m+="(";
+
+					if (mi.arguments.size()) {
+						for(int i=0;i<mi.arguments.size();i++) {
+							if (i>0)
+								m+=", ";
+							String n =mi.arguments[i].name;
+							if (n.find(":")!=-1)
+								n=n.substr(0,n.find(":"));
+							m+=n;
+						}
+					}
+					m+="):";
+
+					options.insert(m);
+				}
+			}
+		} break;
 
 
 	}

+ 10 - 4
modules/gdscript/gd_parser.cpp

@@ -2027,14 +2027,20 @@ void GDParser::_parse_class(ClassNode *p_class) {
 				}
 
 
-				if (tokenizer->get_token(1)!=GDTokenizer::TK_IDENTIFIER) {
+				tokenizer->advance();
+				StringName name;
+
+				if (_get_completable_identifier(COMPLETION_VIRTUAL_FUNC,name)) {
+
+				}
+
+
+				if (name==StringName()) {
 
 					_set_error("Expected identifier after 'func' (syntax: 'func <identifier>([arguments]):' ).");
 					return;
 				}
 
-				StringName name = tokenizer->get_token_identifier(1);
-
 				for(int i=0;i<p_class->functions.size();i++) {
 					if (p_class->functions[i]->name==name) {
 						_set_error("Function '"+String(name)+"' already exists in this class (at line: "+itos(p_class->functions[i]->line)+").");
@@ -2045,7 +2051,7 @@ void GDParser::_parse_class(ClassNode *p_class) {
 						_set_error("Function '"+String(name)+"' already exists in this class (at line: "+itos(p_class->static_functions[i]->line)+").");
 					}
 				}
-				tokenizer->advance(2);
+
 
 				if (tokenizer->get_token()!=GDTokenizer::TK_PARENTHESIS_OPEN) {
 

+ 1 - 0
modules/gdscript/gd_parser.h

@@ -363,6 +363,7 @@ public:
 		COMPLETION_METHOD,
 		COMPLETION_CALL_ARGUMENTS,
 		COMPLETION_INDEX,
+		COMPLETION_VIRTUAL_FUNC
 	};
 
 

+ 21 - 0
platform/windows/detect.py

@@ -135,6 +135,27 @@ def configure(env):
 		env.Append(LIBPATH=[DIRECTX_PATH+"/Lib/x86"])
 		env['ENV'] = os.environ;
 	else:
+
+		# Workaround for MinGW. See:
+		# http://www.scons.org/wiki/LongCmdLinesOnWin32
+		if (os.name=="nt"):
+			import subprocess
+			def mySpawn(sh, escape, cmd, args, env):
+				newargs = ' '.join(args[1:])
+				cmdline = cmd + " " + newargs
+				startupinfo = subprocess.STARTUPINFO()
+				startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
+				proc = subprocess.Popen(cmdline, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
+				    stderr=subprocess.PIPE, startupinfo=startupinfo, shell = False, env = env)
+				data, err = proc.communicate()
+				rv = proc.wait()
+				if rv:
+					print "====="
+					print err
+					print "====="
+				return rv
+			env['SPAWN'] = mySpawn
+
 		#build using mingw
 		if (os.name=="nt"):
 			env['ENV']['TMP'] = os.environ['TMP'] #way to go scons, you can be so stupid sometimes

+ 31 - 9
scene/gui/text_edit.cpp

@@ -3274,19 +3274,41 @@ void TextEdit::_update_completion_candidates() {
 	
 	
 	String s;
-	
-	while(cofs>0 && l[cofs-1]>32 && _is_completable(l[cofs-1])) {
-		s=String::chr(l[cofs-1])+s;
-		if (l[cofs-1]=='\'' || l[cofs-1]=='"')
-			break;
-		
-		cofs--;
+
+	//look for keywords first
+
+	bool pre_keyword=false;
+
+	if (cofs>0 && l[cofs-1]==' ') {
+		int kofs=cofs-1;
+		String kw;
+		while (kofs>=0 && l[kofs]==' ')
+			kofs--;
+
+		while(kofs>=0 && l[kofs]>32 && _is_completable(l[kofs])) {
+			kw=String::chr(l[kofs])+kw;
+			kofs--;
+		}
+
+		pre_keyword=keywords.has(kw);
+		print_line("KW "+kw+"? "+itos(pre_keyword));
+
+	} else {
+
+
+		while(cofs>0 && l[cofs-1]>32 && _is_completable(l[cofs-1])) {
+			s=String::chr(l[cofs-1])+s;
+			if (l[cofs-1]=='\'' || l[cofs-1]=='"')
+				break;
+
+			cofs--;
+		}
 	}
-	
+
 	
 	update();
 	
-	if (s=="" && (cofs==0 || !completion_prefixes.has(String::chr(l[cofs-1])))) {
+	if (!pre_keyword && s=="" && (cofs==0 || !completion_prefixes.has(String::chr(l[cofs-1])))) {
 		//none to complete, cancel
 		_cancel_completion();
 		return;