Преглед на файлове

[php] Fixed issues fir -D php-prefix (see #8144); test -D php-prefix on CI

Alexander Kuzmenko преди 6 години
родител
ревизия
97aa17087d

+ 26 - 16
src/generators/genphp7.ml

@@ -1151,20 +1151,21 @@ let clear_wrappers () =
 	Check if specified type name is used in specified namespace
 *)
 let namespaces_types_cache = Hashtbl.create 512
-let type_name_used_in_namespace ctx name namespace =
-	let types = Hashtbl.find_all namespaces_types_cache namespace in
-	match types with
-		| [] ->
-			List.iter
-				(fun ctx_type ->
-					let wrapper = get_wrapper ctx_type in
-					Hashtbl.add namespaces_types_cache wrapper#get_namespace wrapper#get_name
-				)
-				ctx.types;
-			let types = Hashtbl.find_all namespaces_types_cache namespace in
-			List.mem name types
-		| _ ->
-			List.mem name types
+let type_name_used_in_namespace ctx type_path as_name namespace =
+	let types =
+		match Hashtbl.find_all namespaces_types_cache namespace with
+			| [] ->
+				List.iter
+					(fun ctx_type ->
+						let wrapper = get_wrapper ctx_type in
+						Hashtbl.add namespaces_types_cache wrapper#get_namespace wrapper#get_name
+					)
+					ctx.types;
+				Hashtbl.find_all namespaces_types_cache namespace
+			| types -> types
+	in
+	List.mem as_name types
+	&& (namespace, as_name) <> type_path
 
 (**
 	Simple list intersection implementation.
@@ -1347,13 +1348,17 @@ class code_writer (ctx:Common.context) hx_type_path php_name =
 		method use ?prefix (type_path:path) =
 			if type_path = hx_type_path then
 				php_name
-			else
+			else begin
+				let debug = snd hx_type_path = "Test" && snd type_path = "Wat" in
+				let orig_type_path = type_path in
 				let type_path = match type_path with (pack, name) -> (pack, get_real_name name) in
+				if debug then print_endline (get_full_type_name type_path);
 				let type_path =
 					match prefix with
 						| Some false -> type_path
 						| _ -> add_php_prefix ctx type_path
 				in
+				if debug then print_endline (get_full_type_name type_path);
 				let module_path = get_module_path type_path in
 				match type_path with
 					| ([], type_name) -> "\\" ^ type_name
@@ -1379,7 +1384,7 @@ class code_writer (ctx:Common.context) hx_type_path php_name =
 							prepend_alias (get_alias_next_part ());
 						while not !added do
 							try
-								if (get_module_path type_path) <> namespace && type_name_used_in_namespace ctx !alias namespace then
+								if (get_module_path type_path) <> namespace && type_name_used_in_namespace ctx orig_type_path !alias namespace then
 									prepend_alias (get_alias_next_part ())
 								else
 									let used_type = Hashtbl.find use_table !alias_upper in
@@ -1394,6 +1399,7 @@ class code_writer (ctx:Common.context) hx_type_path php_name =
 								| _ -> fail self#pos __POS__
 						done;
 						!alias
+			end
 		(**
 			Extracts type path from Type.t value and execute self#use on it
 			@return Unique alias for specified type.
@@ -1600,6 +1606,10 @@ class code_writer (ctx:Common.context) hx_type_path php_name =
 		method write_use =
 			self#indent 0;
 			let write _ used_type =
+				let namespace =
+					if hx_type_path = ([],"") then namespace (* ([],"") is for index.php *)
+					else (get_php_prefix ctx) @ namespace
+				in
 				if (get_module_path used_type.ut_type_path) <> namespace then
 					if get_type_name used_type.ut_type_path = used_type.ut_alias then
 						self#write_statement ("use " ^ (get_full_type_name used_type.ut_type_path))

+ 8 - 1
std/php/Boot.hx

@@ -433,6 +433,13 @@ class Boot {
 		if (type == null) return false;
 
 		var phpType = type.phpClassName;
+		#if php_prefix
+			var prefix = getPrefix();
+			if(Global.substr(phpType, 0, Global.strlen(prefix) + 1) == '$prefix\\') {
+				phpType = Global.substr(phpType, Global.strlen(prefix) + 1);
+			}
+		#end
+
 		switch (phpType) {
 			case 'Dynamic':
 				return value != null;
@@ -454,7 +461,7 @@ class Boot {
 				return value.is_string();
 			case 'php\\NativeArray', 'php\\_NativeArray\\NativeArray_Impl_':
 				return value.is_array();
-			case 'Enum', 'Class':
+			case 'Enum' | 'Class':
 				if (Std.is(value, HxClass)) {
 					var valuePhpClass = (cast value:HxClass).phpClassName;
 					var enumPhpClass = (cast HxEnum:HxClass).phpClassName;

+ 5 - 0
std/php/Global.hx

@@ -400,6 +400,11 @@ extern class Global {
 	**/
 	static function substr( string:String, start:Int, ?length:Int ) : EitherType<Bool,String>;
 
+	/**
+		@see http://php.net/manual/en/function.substr-count.php
+	**/
+	static function substr_count( haystack:String, needle:String, ?offset:Int, ?length:Int ) : Int;
+
 	/**
 		@see http://php.net/manual/en/function.substr_replace.php
 	**/

+ 8 - 1
std/php/_std/haxe/Resource.hx

@@ -33,7 +33,14 @@ class Resource {
 	}
 
 	static function getDir() : String {
-		return Global.dirname(Const.__FILE__) + "/../../res";
+		var pathToRoot = '/../..';
+		#if php_prefix
+			pathToRoot += '/..';
+			for(i in 0...Global.substr_count(Boot.getPrefix(), '.')) {
+				pathToRoot += '/..';
+			}
+		#end
+		return Global.dirname(Const.__FILE__) + pathToRoot + "/res";
 	}
 
 	@:access(haxe.io.Path.escape)

+ 13 - 0
tests/runci/System.hx

@@ -83,6 +83,19 @@ class System {
 			fail();
 	}
 
+	/**
+	 * Recursively delete a directory.
+	 * @return Int Exit code of a system command executed to perform deletion.
+	 */
+	static public function deleteDirectoryRecursively(dir:String):Int {
+		return switch (Sys.systemName()) {
+			case "Windows":
+				Sys.command("rmdir", ["/S", "/Q", StringTools.replace(sys.FileSystem.fullPath(dir), "/", "\\")]);
+			case _:
+				Sys.command("rm", ["-rf", dir]);
+		}
+	}
+
 	static public function fail():Void {
 		success = false;
 		throw Fail;

+ 9 - 1
tests/runci/targets/Php.hx

@@ -30,8 +30,16 @@ class Php {
 
 	static public function run(args:Array<String>) {
 		getPhpDependencies();
+
+		var binDir = "bin/php";
+
 		runCommand("haxe", ["compile-php.hxml"].concat(args));
-		runCommand("php", ["bin/php/index.php"]);
+		runCommand("php", [binDir + "/index.php"]);
+
+		deleteDirectoryRecursively(binDir);
+
+		runCommand("haxe", ["compile-php.hxml", "-D", "php-prefix=haxe"].concat(args));
+		runCommand("php", [binDir + "/index.php"]);
 
 		changeDirectory(sysDir);
 		runCommand("haxe", ["compile-php.hxml"]);

+ 5 - 4
tests/unit/src/unit/TestPhp.hx

@@ -218,12 +218,13 @@ class TestPhp extends Test
 
 	@:analyzer(no_user_var_fusion)
 	function testSyntaxNativeClassName() {
-		eq("Array_hx", Syntax.nativeClassName(Array));
-		eq("unit\\Annotation", Syntax.nativeClassName(Annotation));
+		var phpPrefix = #if php_prefix Boot.getPrefix() + "\\" #else "" #end;
+		eq(phpPrefix + "Array_hx", Syntax.nativeClassName(Array));
+		eq(phpPrefix + "unit\\Annotation", Syntax.nativeClassName(Annotation));
 		var cls = php.Web;
-		eq("php\\Web", Syntax.nativeClassName(cls));
+		eq(phpPrefix + "php\\Web", Syntax.nativeClassName(cls));
 		var enm = Annotation;
-		eq("unit\\Annotation", Syntax.nativeClassName(enm));
+		eq(phpPrefix + "unit\\Annotation", Syntax.nativeClassName(enm));
 	}
 
 	function testNativeString() {

+ 6 - 1
tests/unit/src/unit/TestSyntaxModule.hx

@@ -26,7 +26,12 @@ class TestSyntaxModule extends Test {
 	#if analyzer_optimize
 	function testConstruct() {
 		var className:String =
-			#if php "\\unit\\_TestSyntaxModule\\Construct";
+			#if php
+				#if php_prefix
+					'\\${php.Boot.getPrefix()}\\unit\\_TestSyntaxModule\\Construct';
+				#else
+					'\\unit\\_TestSyntaxModule\\Construct';
+				#end
 			#elseif js
 				#if js_unflatten "unit._TestSyntaxModule.Construct";
 				#else "unit__$TestSyntaxModule_Construct";