Browse Source

add TEnumIndex and make matcher generate that instead of Type.enumIndex call (#6364)

Dan Korostelev 8 years ago
parent
commit
94809e3dc6

+ 1 - 1
src/display/display.ml

@@ -452,7 +452,7 @@ module Diagnostics = struct
 				()
 				()
 			| TConst _ | TLocal _ | TTypeExpr _ | TFunction _ when not in_value ->
 			| TConst _ | TLocal _ | TTypeExpr _ | TFunction _ when not in_value ->
 				no_effect e.epos;
 				no_effect e.epos;
-			| TConst _ | TLocal _ | TTypeExpr _ | TEnumParameter _ | TVar _ ->
+			| TConst _ | TLocal _ | TTypeExpr _ | TEnumParameter _ | TEnumIndex _ | TVar _ ->
 				()
 				()
 			| TFunction tf ->
 			| TFunction tf ->
 				loop false tf.tf_expr
 				loop false tf.tf_expr

+ 1 - 1
src/generators/codegen.ml

@@ -526,7 +526,7 @@ let rec constructor_side_effects e =
 		true
 		true
 	| TField (_,FEnum _) ->
 	| TField (_,FEnum _) ->
 		false
 		false
-	| TUnop _ | TArray _ | TField _ | TEnumParameter _ | TCall _ | TNew _ | TFor _ | TWhile _ | TSwitch _ | TReturn _ | TThrow _ ->
+	| TUnop _ | TArray _ | TField _ | TEnumParameter _ | TEnumIndex _ | TCall _ | TNew _ | TFor _ | TWhile _ | TSwitch _ | TReturn _ | TThrow _ ->
 		true
 		true
 	| TBinop _ | TTry _ | TIf _ | TBlock _ | TVar _
 	| TBinop _ | TTry _ | TIf _ | TBlock _ | TVar _
 	| TFunction _ | TArrayDecl _ | TObjectDecl _
 	| TFunction _ | TArrayDecl _ | TObjectDecl _

+ 4 - 0
src/generators/genas3.ml

@@ -633,6 +633,9 @@ and gen_expr ctx e =
 		gen_expr ctx e1;
 		gen_expr ctx e1;
 		spr ctx ")";
 		spr ctx ")";
 		gen_field_access ctx e1.etype (field_name s)
 		gen_field_access ctx e1.etype (field_name s)
+	| TEnumIndex e ->
+		gen_value ctx e;
+		print ctx ".index";
 	| TEnumParameter (e,_,i) ->
 	| TEnumParameter (e,_,i) ->
 		gen_value ctx e;
 		gen_value ctx e;
 		print ctx ".params[%i]" i;
 		print ctx ".params[%i]" i;
@@ -882,6 +885,7 @@ and gen_value ctx e =
 	| TBinop _
 	| TBinop _
 	| TField _
 	| TField _
 	| TEnumParameter _
 	| TEnumParameter _
+	| TEnumIndex _
 	| TTypeExpr _
 	| TTypeExpr _
 	| TParenthesis _
 	| TParenthesis _
 	| TObjectDecl _
 	| TObjectDecl _

+ 9 - 3
src/generators/gencommon/enumToClass.ml

@@ -253,7 +253,7 @@ struct
 	let name = "enum_to_class_exprf"
 	let name = "enum_to_class_exprf"
 	let priority = solve_deps name [DBefore TArrayTransform.priority]
 	let priority = solve_deps name [DBefore TArrayTransform.priority]
 
 
-	let configure gen t opt_get_native_enum_tag =
+	let configure gen t mk_enum_index_call =
 		let rec run e =
 		let rec run e =
 			let get_converted_enum_type et =
 			let get_converted_enum_type et =
 				let en, eparams = match follow (gen.gfollow#run_f et) with
 				let en, eparams = match follow (gen.gfollow#run_f et) with
@@ -265,6 +265,12 @@ struct
 			in
 			in
 
 
 			match e.eexpr with
 			match e.eexpr with
+			| TEnumIndex f ->
+				let f = run f in
+				(try
+					mk_field_access gen {f with etype = get_converted_enum_type f.etype} "index" e.epos
+				with Not_found ->
+					mk_enum_index_call f e.epos)
 			| TCall (({eexpr = TField(_, FStatic({cl_path=[],"Type"},{cf_name="enumIndex"}))} as left), [f]) ->
 			| TCall (({eexpr = TField(_, FStatic({cl_path=[],"Type"},{cf_name="enumIndex"}))} as left), [f]) ->
 				let f = run f in
 				let f = run f in
 				(try
 				(try
@@ -289,7 +295,7 @@ struct
 
 
 end;;
 end;;
 
 
-let configure gen opt_get_native_enum_tag convert_all convert_if_has_meta enum_base_class param_enum_class =
+let configure gen convert_all convert_if_has_meta enum_base_class param_enum_class mk_enum_index_call =
 	let t = new_t () in
 	let t = new_t () in
 	EnumToClassModf.configure gen t convert_all convert_if_has_meta enum_base_class param_enum_class;
 	EnumToClassModf.configure gen t convert_all convert_if_has_meta enum_base_class param_enum_class;
-	EnumToClassExprf.configure gen t opt_get_native_enum_tag
+	EnumToClassExprf.configure gen t mk_enum_index_call

+ 17 - 9
src/generators/gencommon/enumToClass2.ml

@@ -337,7 +337,7 @@ end;;
 
 
 
 
 module EnumToClass2Exprf = struct
 module EnumToClass2Exprf = struct
-	let init com ec_tbl =
+	let init com ec_tbl mk_enum_index_call =
 		let v_as = alloc_var "__as__" t_dynamic in
 		let v_as = alloc_var "__as__" t_dynamic in
 		let rec run e =
 		let rec run e =
 			let get_converted_enum_classes et =
 			let get_converted_enum_classes et =
@@ -347,14 +347,22 @@ module EnumToClass2Exprf = struct
 				in
 				in
 				Hashtbl.find ec_tbl en.e_path
 				Hashtbl.find ec_tbl en.e_path
 			in
 			in
-
+			let mk_converted_enum_index_access f =
+				let cl = (get_converted_enum_classes f.etype).base in
+				let e_enum = { f with etype = TInst (cl, []) } in
+				Codegen.field e_enum "_hx_index" com.basic.tint e.epos
+			in
 			match e.eexpr with
 			match e.eexpr with
+			| TEnumIndex f ->
+				let f = run f in
+				(try
+					mk_converted_enum_index_access f
+				with Not_found ->
+					mk_enum_index_call f e.epos)
 			| TCall ({ eexpr = TField (_, FStatic ({ cl_path = ([], "Type") }, { cf_name = "enumIndex" })) } as left, [f]) ->
 			| TCall ({ eexpr = TField (_, FStatic ({ cl_path = ([], "Type") }, { cf_name = "enumIndex" })) } as left, [f]) ->
 				let f = run f in
 				let f = run f in
 				(try
 				(try
-					let cl = (get_converted_enum_classes f.etype).base in
-					let e_enum = { f with etype = TInst (cl, []) } in
-					Codegen.field e_enum "_hx_index" com.basic.tint e.epos
+					mk_converted_enum_index_access f
 				with Not_found ->
 				with Not_found ->
 					{ e with eexpr = TCall(left, [f]) })
 					{ e with eexpr = TCall(left, [f]) })
 			| TEnumParameter(f, ef, i) ->
 			| TEnumParameter(f, ef, i) ->
@@ -381,12 +389,12 @@ module EnumToClass2Exprf = struct
 	let name = "enum_to_class2_exprf"
 	let name = "enum_to_class2_exprf"
 	let priority = solve_deps name []
 	let priority = solve_deps name []
 
 
-	let configure gen ec_tbl =
-		let run = init gen.gcon ec_tbl in
+	let configure gen ec_tbl mk_enum_index_call =
+		let run = init gen.gcon ec_tbl mk_enum_index_call in
 		gen.gexpr_filters#add name (PCustom priority) run
 		gen.gexpr_filters#add name (PCustom priority) run
 end;;
 end;;
 
 
-let configure gen enum_base_class =
+let configure gen enum_base_class mk_enum_index_call =
 	let ec_tbl = Hashtbl.create 10 in
 	let ec_tbl = Hashtbl.create 10 in
 	EnumToClass2Modf.configure gen ec_tbl enum_base_class;
 	EnumToClass2Modf.configure gen ec_tbl enum_base_class;
-	EnumToClass2Exprf.configure gen ec_tbl;
+	EnumToClass2Exprf.configure gen ec_tbl mk_enum_index_call;

+ 1 - 0
src/generators/gencommon/expressionUnwrap.ml

@@ -226,6 +226,7 @@ let rec shallow_expr_type expr : shallow_expr_type =
 		| TBinop _
 		| TBinop _
 		| TField _
 		| TField _
 		| TEnumParameter _
 		| TEnumParameter _
+		| TEnumIndex _
 		| TTypeExpr _
 		| TTypeExpr _
 		| TObjectDecl _
 		| TObjectDecl _
 		| TArrayDecl _
 		| TArrayDecl _

+ 1 - 0
src/generators/gencommon/switchToIf.ml

@@ -124,6 +124,7 @@ let configure gen (should_convert:texpr->bool) =
 			begin
 			begin
 				try
 				try
 					match (simplify_expr cond).eexpr with
 					match (simplify_expr cond).eexpr with
+					| TEnumIndex enum
 					| TCall  ({ eexpr = TField (_, FStatic ({ cl_path = [],"Type" }, { cf_name = "enumIndex" })) }, [enum]) ->
 					| TCall  ({ eexpr = TField (_, FStatic ({ cl_path = [],"Type" }, { cf_name = "enumIndex" })) }, [enum]) ->
 						let real_enum =
 						let real_enum =
 							match enum.etype with
 							match enum.etype with

+ 16 - 9
src/generators/gencpp.ml

@@ -2338,7 +2338,7 @@ let is_gc_element ctx member_type =
    | TCppWrapped _
    | TCppWrapped _
    | TCppScalarArray _
    | TCppScalarArray _
    | TCppInst _
    | TCppInst _
-   | TCppInterface _ 
+   | TCppInterface _
    | TCppClass
    | TCppClass
        -> true
        -> true
    | _ -> false
    | _ -> false
@@ -2423,6 +2423,10 @@ let retype_expression ctx request_type function_args function_type expression_tr
             let retypedObj = retype TCppDynamic enumObj in
             let retypedObj = retype TCppDynamic enumObj in
             CppEnumParameter( retypedObj, enumField, enumIndex ), cpp_cast_variant_type_of (cpp_type_of (get_nth_type enumField enumIndex))
             CppEnumParameter( retypedObj, enumField, enumIndex ), cpp_cast_variant_type_of (cpp_type_of (get_nth_type enumField enumIndex))
 
 
+         | TEnumIndex enumObj ->
+            let retypedObj = retype TCppDynamic enumObj in
+            CppEnumIndex retypedObj, TCppScalar "int"
+
          | TConst TThis ->
          | TConst TThis ->
             uses_this := Some !this_real;
             uses_this := Some !this_real;
             CppThis(!this_real), if !this_real=ThisDynamic then TCppDynamic else cpp_type_of expr.etype
             CppThis(!this_real), if !this_real=ThisDynamic then TCppDynamic else cpp_type_of expr.etype
@@ -3162,7 +3166,7 @@ let retype_expression ctx request_type function_args function_type expression_tr
             Using the 'typedef hack', where we use typedef X<T> = T, allows the
             Using the 'typedef hack', where we use typedef X<T> = T, allows the
             haxe compiler to use these types interchangeably. We then work
             haxe compiler to use these types interchangeably. We then work
             out the correct way to convert between them when one is expected, but another provided.
             out the correct way to convert between them when one is expected, but another provided.
- 
+
             TCppFunction: these do not really interact with the haxe function type, T
             TCppFunction: these do not really interact with the haxe function type, T
             Since they are implemented with cpp::Function, conversion to/from Dynamic should happen automatically
             Since they are implemented with cpp::Function, conversion to/from Dynamic should happen automatically
                CallableData<T> = T;
                CallableData<T> = T;
@@ -3394,9 +3398,9 @@ let gen_cpp_ast_expression_tree ctx class_name func_name function_args function_
 
 
       | CppEnumIndex(obj) ->
       | CppEnumIndex(obj) ->
          gen obj;
          gen obj;
-         (*if cpp_is_dynamic_type obj.cpptype then*)
+         if cpp_is_dynamic_type obj.cpptype then
             out ".StaticCast< ::hx::EnumBase >()";
             out ".StaticCast< ::hx::EnumBase >()";
-         out "->getIndex()"
+         out "->_hx_getIndex()"
 
 
       | CppNullAccess -> out ("hx::Throw(" ^ strq "Null access" ^ ")")
       | CppNullAccess -> out ("hx::Throw(" ^ strq "Null access" ^ ")")
       | CppFunction(func,_) ->
       | CppFunction(func,_) ->
@@ -6233,7 +6237,7 @@ let generate_class_files baseCtx super_deps constructor_deps class_def inScripta
          List.iter dump_script_static class_def.cl_ordered_statics;
          List.iter dump_script_static class_def.cl_ordered_statics;
 
 
          output_cpp "static hx::ScriptNamedFunction __scriptableFunctions[] = {\n";
          output_cpp "static hx::ScriptNamedFunction __scriptableFunctions[] = {\n";
-         let dump_func f isStaticFlag = 
+         let dump_func f isStaticFlag =
             let s = try Hashtbl.find sigs f.cf_name with Not_found -> "v" in
             let s = try Hashtbl.find sigs f.cf_name with Not_found -> "v" in
             output_cpp ("  hx::ScriptNamedFunction(\"" ^ f.cf_name ^ "\",__s_" ^ f.cf_name ^ ",\"" ^ s ^ "\", " ^ isStaticFlag ^ " ),\n" )
             output_cpp ("  hx::ScriptNamedFunction(\"" ^ f.cf_name ^ "\",__s_" ^ f.cf_name ^ ",\"" ^ s ^ "\", " ^ isStaticFlag ^ " ),\n" )
          in
          in
@@ -7559,6 +7563,9 @@ class script_writer ctx filename asciiOut =
          in
          in
          this#write ( (this#op IaEnumI) ^ (this#typeText (TEnum(enum,[])) ) ^ (string_of_int i) ^ "\n");
          this#write ( (this#op IaEnumI) ^ (this#typeText (TEnum(enum,[])) ) ^ (string_of_int i) ^ "\n");
          this#gen_expression expr;
          this#gen_expression expr;
+   | TEnumIndex expr ->
+         this#write ( (this#op IaCallMember) ^ (this#typeTextString "hx::EnumBase") ^ " " ^ (this#stringText "__Index") ^ "0" ^ (this#commentOf ("Enum index") ) ^ "\n");
+         this#gen_expression expr;
    | TSwitch (condition,cases,optional_default)  ->
    | TSwitch (condition,cases,optional_default)  ->
          this#write ( (this#op IaSwitch) ^ (string_of_int (List.length cases)) ^ " " ^
          this#write ( (this#op IaSwitch) ^ (string_of_int (List.length cases)) ^ " " ^
                            (match optional_default with None -> "0" | Some _ -> "1") ^ "\n");
                            (match optional_default with None -> "0" | Some _ -> "1") ^ "\n");
@@ -7743,7 +7750,7 @@ class script_writer ctx filename asciiOut =
             gen_expression e;
             gen_expression e;
 
 
          | CppCompare(_, left, right, op) ->
          | CppCompare(_, left, right, op) ->
-            this#writeOpLine (IaBinOp op); 
+            this#writeOpLine (IaBinOp op);
             gen_expression left;
             gen_expression left;
             gen_expression right;
             gen_expression right;
 
 
@@ -7870,7 +7877,7 @@ class script_writer ctx filename asciiOut =
          | CppCastScalar(expr,_) -> match_expr expr
          | CppCastScalar(expr,_) -> match_expr expr
          | CppCastVariant(expr) -> match_expr expr
          | CppCastVariant(expr) -> match_expr expr
          | CppCastStatic(expr,_) -> match_expr expr
          | CppCastStatic(expr,_) -> match_expr expr
-         | CppNullAccess -> 
+         | CppNullAccess ->
             this#writeOpLine IaThrow;
             this#writeOpLine IaThrow;
             this#begin_expr;
             this#begin_expr;
             this#writeCppPos expression;
             this#writeCppPos expression;
@@ -8137,13 +8144,13 @@ let generate_source ctx =
                let id = gen_hash32 seed class_name in
                let id = gen_hash32 seed class_name in
                (* reserve first 100 ids for runtime *)
                (* reserve first 100 ids for runtime *)
                if id < Int32.of_int 100 || Hashtbl.mem existingIds id then
                if id < Int32.of_int 100 || Hashtbl.mem existingIds id then
-                  makeId class_name (seed+100) 
+                  makeId class_name (seed+100)
                else begin
                else begin
                   Hashtbl.add existingIds id true;
                   Hashtbl.add existingIds id true;
                   Hashtbl.add ctx.ctx_type_ids class_name id;
                   Hashtbl.add ctx.ctx_type_ids class_name id;
                end in
                end in
             makeId name 0;
             makeId name 0;
- 
+
             build_xml := !build_xml ^ (get_class_code class_def Meta.BuildXml);
             build_xml := !build_xml ^ (get_class_code class_def Meta.BuildXml);
             if (has_init_field class_def) then
             if (has_init_field class_def) then
                init_classes := class_def.cl_path ::  !init_classes;
                init_classes := class_def.cl_path ::  !init_classes;

+ 6 - 1
src/generators/gencs.ml

@@ -1654,6 +1654,7 @@ let generate con =
 					| TObjectDecl _ -> write w "[ obj decl not supported ]"; if !strict_mode then assert false
 					| TObjectDecl _ -> write w "[ obj decl not supported ]"; if !strict_mode then assert false
 					| TFunction _ -> write w "[ func decl not supported ]"; if !strict_mode then assert false
 					| TFunction _ -> write w "[ func decl not supported ]"; if !strict_mode then assert false
 					| TEnumParameter _ -> write w "[ enum parameter not supported ]"; if !strict_mode then assert false
 					| TEnumParameter _ -> write w "[ enum parameter not supported ]"; if !strict_mode then assert false
+					| TEnumIndex _ -> write w "[ enum index not supported ]"; if !strict_mode then assert false
 			)
 			)
 			and do_call w e el =
 			and do_call w e el =
 				let params, el = extract_tparams [] el in
 				let params, el = extract_tparams [] el in
@@ -2727,7 +2728,11 @@ let generate con =
 		ClosuresToClass.configure gen closure_t;
 		ClosuresToClass.configure gen closure_t;
 
 
 		let enum_base = (get_cl (get_type gen (["haxe";"lang"],"Enum")) ) in
 		let enum_base = (get_cl (get_type gen (["haxe";"lang"],"Enum")) ) in
-		EnumToClass2.configure gen enum_base;
+		let type_enumindex = mk_static_field_access_infer gen.gclasses.cl_type "enumIndex" null_pos [] in
+		let mk_enum_index_call e p =
+			mk (TCall (type_enumindex, [e])) gen.gcon.basic.tint p
+		in
+		EnumToClass2.configure gen enum_base mk_enum_index_call;
 
 
 		InterfaceVarsDeleteModf.configure gen;
 		InterfaceVarsDeleteModf.configure gen;
 
 

+ 2 - 0
src/generators/genhl.ml

@@ -1915,6 +1915,8 @@ and eval_expr ctx e =
 			r
 			r
 		| _ ->
 		| _ ->
 			abort ("Unknown native call " ^ v.v_name) e.epos)
 			abort ("Unknown native call " ^ v.v_name) e.epos)
+	| TEnumIndex v ->
+		get_enum_index ctx v
 	| TCall ({ eexpr = TField (_,FStatic ({ cl_path = [],"Type" },{ cf_name = "enumIndex" })) },[{ eexpr = TCast(v,_) }]) when (match follow v.etype with TEnum _ -> true | _ -> false) ->
 	| TCall ({ eexpr = TField (_,FStatic ({ cl_path = [],"Type" },{ cf_name = "enumIndex" })) },[{ eexpr = TCast(v,_) }]) when (match follow v.etype with TEnum _ -> true | _ -> false) ->
 		get_enum_index ctx v
 		get_enum_index ctx v
 	| TCall ({ eexpr = TField (_,FStatic ({ cl_path = [],"Type" },{ cf_name = "enumIndex" })) },[v]) when (match follow v.etype with TEnum _ -> true | _ -> false) ->
 	| TCall ({ eexpr = TField (_,FStatic ({ cl_path = [],"Type" },{ cf_name = "enumIndex" })) },[v]) when (match follow v.etype with TEnum _ -> true | _ -> false) ->

+ 6 - 1
src/generators/genjava.ml

@@ -1612,6 +1612,7 @@ let generate con =
 				| TObjectDecl _ -> write w "[ obj decl not supported ]"; if !strict_mode then assert false
 				| TObjectDecl _ -> write w "[ obj decl not supported ]"; if !strict_mode then assert false
 				| TFunction _ -> write w "[ func decl not supported ]"; if !strict_mode then assert false
 				| TFunction _ -> write w "[ func decl not supported ]"; if !strict_mode then assert false
 				| TEnumParameter _ -> write w "[ enum parameter not supported ]"; if !strict_mode then assert false
 				| TEnumParameter _ -> write w "[ enum parameter not supported ]"; if !strict_mode then assert false
+				| TEnumIndex _ -> write w "[ enum index not supported ]"; if !strict_mode then assert false
 		in
 		in
 		expr_s w e
 		expr_s w e
 	in
 	in
@@ -2105,7 +2106,11 @@ let generate con =
 
 
 	let enum_base = (get_cl (get_type gen (["haxe";"lang"],"Enum")) ) in
 	let enum_base = (get_cl (get_type gen (["haxe";"lang"],"Enum")) ) in
 	let param_enum_base = (get_cl (get_type gen (["haxe";"lang"],"ParamEnum")) ) in
 	let param_enum_base = (get_cl (get_type gen (["haxe";"lang"],"ParamEnum")) ) in
-	EnumToClass.configure gen (None) false true enum_base param_enum_base;
+	let type_enumindex = mk_static_field_access_infer gen.gclasses.cl_type "enumIndex" null_pos [] in
+	let mk_enum_index_call e p =
+		mk (TCall (type_enumindex, [e])) gen.gcon.basic.tint p
+	in
+	EnumToClass.configure gen false true enum_base param_enum_base mk_enum_index_call;
 
 
 	InterfaceVarsDeleteModf.configure gen;
 	InterfaceVarsDeleteModf.configure gen;
 
 

+ 4 - 0
src/generators/genjs.ml

@@ -500,6 +500,9 @@ and gen_expr ctx e =
 			print ctx "($_=";
 			print ctx "($_=";
 			gen_value ctx x;
 			gen_value ctx x;
 			print ctx ",$bind($_,$_%s))" (if Meta.has Meta.SelfCall f.cf_meta then "" else (field f.cf_name)))
 			print ctx ",$bind($_,$_%s))" (if Meta.has Meta.SelfCall f.cf_meta then "" else (field f.cf_name)))
+	| TEnumIndex x ->
+		gen_value ctx x;
+		print ctx "[1]"
 	| TEnumParameter (x,_,i) ->
 	| TEnumParameter (x,_,i) ->
 		gen_value ctx x;
 		gen_value ctx x;
 		print ctx "[%i]" (i + 2)
 		print ctx "[%i]" (i + 2)
@@ -865,6 +868,7 @@ and gen_value ctx e =
 	| TBinop _
 	| TBinop _
 	| TField _
 	| TField _
 	| TEnumParameter _
 	| TEnumParameter _
+	| TEnumIndex _
 	| TTypeExpr _
 	| TTypeExpr _
 	| TParenthesis _
 	| TParenthesis _
 	| TObjectDecl _
 	| TObjectDecl _

+ 4 - 0
src/generators/genlua.ml

@@ -543,6 +543,9 @@ and gen_expr ?(local=true) ctx e = begin
 	| TEnumParameter (x,_,i) ->
 	| TEnumParameter (x,_,i) ->
 		gen_value ctx x;
 		gen_value ctx x;
 		print ctx "[%i]" (i + 2)
 		print ctx "[%i]" (i + 2)
+	| TEnumIndex x ->
+		gen_value ctx x;
+		print ctx "[1]"
 	| TField (x, (FInstance(_,_,f) | FStatic(_,f) | FAnon(f))) when Meta.has Meta.SelfCall f.cf_meta ->
 	| TField (x, (FInstance(_,_,f) | FStatic(_,f) | FAnon(f))) when Meta.has Meta.SelfCall f.cf_meta ->
 		gen_value ctx x;
 		gen_value ctx x;
 	| TField ({ eexpr = TConst(TInt _ | TFloat _| TString _| TBool _) } as e , ((FInstance _ | FAnon _) as ef)) ->
 	| TField ({ eexpr = TConst(TInt _ | TFloat _| TString _| TBool _) } as e , ((FInstance _ | FAnon _) as ef)) ->
@@ -1041,6 +1044,7 @@ and gen_value ctx e =
 	| TBinop _
 	| TBinop _
 	| TField _
 	| TField _
 	| TEnumParameter _
 	| TEnumParameter _
+	| TEnumIndex _
 	| TTypeExpr _
 	| TTypeExpr _
 	| TParenthesis _
 	| TParenthesis _
 	| TObjectDecl _
 	| TObjectDecl _

+ 2 - 0
src/generators/genneko.ml

@@ -248,6 +248,8 @@ and gen_expr ctx e =
 		| _ -> assert false)
 		| _ -> assert false)
 	| TEnumParameter (e,_,i) ->
 	| TEnumParameter (e,_,i) ->
 		EArray (field p (gen_expr ctx e) "args",int p i),p
 		EArray (field p (gen_expr ctx e) "args",int p i),p
+	| TEnumIndex e ->
+		field p (gen_expr ctx e) "index"
 	| TField (e,f) ->
 	| TField (e,f) ->
 		field p (gen_expr ctx e) (field_name f)
 		field p (gen_expr ctx e) (field_name f)
 	| TTypeExpr t ->
 	| TTypeExpr t ->

+ 6 - 0
src/generators/genphp.ml

@@ -1316,6 +1316,11 @@ and gen_expr ctx e =
 		gen_value ctx e1;
 		gen_value ctx e1;
 		spr ctx ")";
 		spr ctx ")";
 		print ctx "->params[%d]" i;
 		print ctx "->params[%d]" i;
+	| TEnumIndex e1 ->
+		spr ctx "_hx_deref(";
+		gen_value ctx e1;
+		spr ctx ")";
+		print ctx "->index";
 	| TField (e1,s) ->
 	| TField (e1,s) ->
 		gen_tfield ctx e e1 s
 		gen_tfield ctx e e1 s
 	| TTypeExpr t ->
 	| TTypeExpr t ->
@@ -1804,6 +1809,7 @@ and gen_value ctx e =
 	| TArray _
 	| TArray _
 	| TBinop _
 	| TBinop _
 	| TEnumParameter _
 	| TEnumParameter _
+	| TEnumIndex _
 	| TField _
 	| TField _
 	| TParenthesis _
 	| TParenthesis _
 	| TObjectDecl _
 	| TObjectDecl _

+ 10 - 0
src/generators/genphp7.ml

@@ -1611,6 +1611,7 @@ class code_writer (ctx:Common.context) hx_type_path php_name =
 				| TCast (expr, mtype) -> self#write_expr_cast expr mtype
 				| TCast (expr, mtype) -> self#write_expr_cast expr mtype
 				| TMeta (_, expr) -> self#write_expr expr
 				| TMeta (_, expr) -> self#write_expr expr
 				| TEnumParameter (expr, constructor, index) -> self#write_expr_enum_parameter expr constructor index
 				| TEnumParameter (expr, constructor, index) -> self#write_expr_enum_parameter expr constructor index
+				| TEnumIndex expr -> self#write_expr_enum_index expr
 			);
 			);
 			expr_hierarchy <- List.tl expr_hierarchy
 			expr_hierarchy <- List.tl expr_hierarchy
 		(**
 		(**
@@ -2740,6 +2741,15 @@ class code_writer (ctx:Common.context) hx_type_path php_name =
 				| _ -> self#write_expr expr
 				| _ -> self#write_expr expr
 			);
 			);
 			self#write ("->params[" ^ (string_of_int index) ^ "]")
 			self#write ("->params[" ^ (string_of_int index) ^ "]")
+		(**
+			Write TEnumIndex expression to output buffer
+		*)
+		method write_expr_enum_index expr =
+			(match expr.eexpr with
+				| TConst TNull -> self#write "(null)"
+				| _ -> self#write_expr expr
+			);
+			self#write "->index"
 		(**
 		(**
 			Writes argument for function declarations or calls
 			Writes argument for function declarations or calls
 		*)
 		*)

+ 6 - 0
src/generators/genpy.ml

@@ -713,6 +713,10 @@ module Transformer = struct
 			let e1 = trans true [] e1 in
 			let e1 = trans true [] e1 in
 			let p = { ae.a_expr with eexpr = TEnumParameter(e1.a_expr,ef,i)} in
 			let p = { ae.a_expr with eexpr = TEnumParameter(e1.a_expr,ef,i)} in
 			lift true e1.a_blocks p
 			lift true e1.a_blocks p
+		| (_, TEnumIndex e1) ->
+			let e1 = trans true [] e1 in
+			let p = { ae.a_expr with eexpr = TEnumIndex e1.a_expr } in
+			lift true e1.a_blocks p
 		| (true, TIf(econd, eif, eelse)) ->
 		| (true, TIf(econd, eif, eelse)) ->
 			(let econd1 = trans true [] econd in
 			(let econd1 = trans true [] econd in
 			let eif1 = trans true [] eif in
 			let eif1 = trans true [] eif in
@@ -1189,6 +1193,8 @@ module Printer = struct
 				handle_keywords v.v_name
 				handle_keywords v.v_name
 			| TEnumParameter(e1,_,index) ->
 			| TEnumParameter(e1,_,index) ->
 				Printf.sprintf "%s.params[%i]" (print_expr pctx e1) index
 				Printf.sprintf "%s.params[%i]" (print_expr pctx e1) index
+			| TEnumIndex e1 ->
+				Printf.sprintf "%s.index" (print_expr pctx e1)
 			| TArray(e1,e2) when (is_type1 "" "list")(e1.etype) || is_underlying_array e1.etype ->
 			| TArray(e1,e2) when (is_type1 "" "list")(e1.etype) || is_underlying_array e1.etype ->
 				print_tarray_list pctx e1 e2
 				print_tarray_list pctx e1 e2
 			| TArray({etype = t} as e1,e2) when is_anon_or_dynamic t ->
 			| TArray({etype = t} as e1,e2) when is_anon_or_dynamic t ->

+ 4 - 0
src/generators/genswf9.ml

@@ -882,6 +882,9 @@ let rec gen_access ctx e (forset : 'a) : 'a access =
 		write ctx (HGetProp (ident "params"));
 		write ctx (HGetProp (ident "params"));
 		write ctx (HSmallInt i);
 		write ctx (HSmallInt i);
 		VArray
 		VArray
+	| TEnumIndex e1 ->
+		gen_expr ctx true e1;
+		VId (ident "index")
 	| TField (e1,fa) ->
 	| TField (e1,fa) ->
 		let f = field_name fa in
 		let f = field_name fa in
 		let id, k, closure = property ctx f e1.etype in
 		let id, k, closure = property ctx f e1.etype in
@@ -1060,6 +1063,7 @@ let rec gen_expr_content ctx retval e =
 		no_value ctx retval
 		no_value ctx retval
 	| TField _
 	| TField _
 	| TLocal _
 	| TLocal _
+	| TEnumIndex _
 	| TTypeExpr _ ->
 	| TTypeExpr _ ->
 		getvar ctx (gen_access ctx e Read)
 		getvar ctx (gen_access ctx e Read)
 	(* both accesses return dynamic so let's cast them to the real type *)
 	(* both accesses return dynamic so let's cast them to the real type *)

+ 4 - 0
src/macro/eval/evalJit.ml

@@ -303,6 +303,7 @@ and jit_expr jit return e =
 		if l < 256 then begin
 		if l < 256 then begin
 			let cases = Array.init l (fun i -> try IntMap.find (i + !shift) !h with Not_found -> exec_def) in
 			let cases = Array.init l (fun i -> try IntMap.find (i + !shift) !h with Not_found -> exec_def) in
 			if !shift = 0 then begin match (Texpr.skip e1).eexpr with
 			if !shift = 0 then begin match (Texpr.skip e1).eexpr with
+				| TEnumIndex e1
 				| TCall({eexpr = TField(_,FStatic({cl_path=[],"Type"},{cf_name="enumIndex"}))},[e1]) ->
 				| TCall({eexpr = TField(_,FStatic({cl_path=[],"Type"},{cf_name="enumIndex"}))},[e1]) ->
 					let exec = jit_expr jit false e1 in
 					let exec = jit_expr jit false e1 in
 					emit_enum_switch_array exec cases exec_def e1.epos
 					emit_enum_switch_array exec cases exec_def e1.epos
@@ -724,6 +725,9 @@ and jit_expr jit return e =
 	| TEnumParameter(e1,_,i) ->
 	| TEnumParameter(e1,_,i) ->
 		let exec = jit_expr jit false e1 in
 		let exec = jit_expr jit false e1 in
 		emit_enum_parameter_read exec i
 		emit_enum_parameter_read exec i
+	| TEnumIndex e1 ->
+		let exec = jit_expr jit false e1 in
+		emit_enum_index exec
 	(* ops *)
 	(* ops *)
 	| TBinop(OpEq,e1,{eexpr = TConst TNull}) | TBinop(OpEq,{eexpr = TConst TNull},e1) ->
 	| TBinop(OpEq,e1,{eexpr = TConst TNull}) | TBinop(OpEq,{eexpr = TConst TNull},e1) ->
 		let exec = jit_expr jit false e1 in
 		let exec = jit_expr jit false e1 in

+ 2 - 0
src/macro/macroApi.ml

@@ -1204,6 +1204,7 @@ and encode_texpr e =
 			| TCast(e1,mt) -> 24,[loop e1;match mt with None -> vnull | Some mt -> encode_module_type mt]
 			| TCast(e1,mt) -> 24,[loop e1;match mt with None -> vnull | Some mt -> encode_module_type mt]
 			| TMeta(m,e1) -> 25,[encode_meta_entry m;loop e1]
 			| TMeta(m,e1) -> 25,[encode_meta_entry m;loop e1]
 			| TEnumParameter(e1,ef,i) -> 26,[loop e1;encode_efield ef;vint i]
 			| TEnumParameter(e1,ef,i) -> 26,[loop e1;encode_efield ef;vint i]
+			| TEnumIndex e1 -> 27,[loop e1]
 		in
 		in
 		encode_obj OTypedExprDef [
 		encode_obj OTypedExprDef [
 			"pos", encode_pos e.epos;
 			"pos", encode_pos e.epos;
@@ -1350,6 +1351,7 @@ and decode_texpr v =
 		| 24, [v1;mto] -> TCast(loop v1,opt decode_module_type mto)
 		| 24, [v1;mto] -> TCast(loop v1,opt decode_module_type mto)
 		| 25, [m;v1] -> TMeta(decode_meta_entry m,loop v1)
 		| 25, [m;v1] -> TMeta(decode_meta_entry m,loop v1)
 		| 26, [v1;ef;i] -> TEnumParameter(loop v1,decode_efield ef,decode_int i)
 		| 26, [v1;ef;i] -> TEnumParameter(loop v1,decode_efield ef,decode_int i)
+		| 27, [v1] -> TEnumIndex(loop v1)
 		| i,el -> Printf.printf "%i %i\n" i (List.length el); raise Invalid_expr
 		| i,el -> Printf.printf "%i %i\n" i (List.length el); raise Invalid_expr
 	in
 	in
 	try
 	try

+ 6 - 1
src/optimization/analyzer.ml

@@ -420,6 +420,11 @@ module ConstPropagation = DataFlow(struct
 					| EnumValue(_,el) -> (try List.nth el i with Failure _ -> raise Exit)
 					| EnumValue(_,el) -> (try List.nth el i with Failure _ -> raise Exit)
 					| _ -> raise Exit
 					| _ -> raise Exit
 				end;
 				end;
+			| TEnumIndex e1 ->
+				begin match eval bb e1 with
+					| EnumValue(i,_) -> Const (TInt (Int32.of_int i))
+					| _ -> raise Exit
+				end;
 			| TCall ({ eexpr = TField (_,FStatic({cl_path=[],"Type"} as c,({cf_name="enumIndex"} as cf)))},[e1]) when ctx.com.platform = Eval ->
 			| TCall ({ eexpr = TField (_,FStatic({cl_path=[],"Type"} as c,({cf_name="enumIndex"} as cf)))},[e1]) when ctx.com.platform = Eval ->
 				begin match follow e1.etype,eval bb e1 with
 				begin match follow e1.etype,eval bb e1 with
 					| TEnum _,EnumValue(i,_) -> Const (TInt (Int32.of_int i))
 					| TEnum _,EnumValue(i,_) -> Const (TInt (Int32.of_int i))
@@ -606,7 +611,7 @@ module LocalDce = struct
 			| TNew _ | TCall _ | TBinop ((OpAssignOp _ | OpAssign),_,_) | TUnop ((Increment|Decrement),_,_) -> raise Exit
 			| TNew _ | TCall _ | TBinop ((OpAssignOp _ | OpAssign),_,_) | TUnop ((Increment|Decrement),_,_) -> raise Exit
 			| TReturn _ | TBreak | TContinue | TThrow _ | TCast (_,Some _) -> raise Exit
 			| TReturn _ | TBreak | TContinue | TThrow _ | TCast (_,Some _) -> raise Exit
 			| TFor _ -> raise Exit
 			| TFor _ -> raise Exit
-			| TArray _ | TEnumParameter _ | TCast (_,None) | TBinop _ | TUnop _ | TParenthesis _ | TMeta _ | TWhile _
+			| TArray _ | TEnumParameter _ | TEnumIndex _ | TCast (_,None) | TBinop _ | TUnop _ | TParenthesis _ | TMeta _ | TWhile _
 			| TField _ | TIf _ | TTry _ | TSwitch _ | TArrayDecl _ | TBlock _ | TObjectDecl _ | TVar _ -> Type.iter loop e
 			| TField _ | TIf _ | TTry _ | TSwitch _ | TArrayDecl _ | TBlock _ | TObjectDecl _ | TVar _ -> Type.iter loop e
 		in
 		in
 		try
 		try

+ 3 - 1
src/optimization/analyzerTexpr.ml

@@ -264,6 +264,8 @@ module TexprKindMapper = struct
 			{ e with eexpr = TThrow (f KThrow e1) }
 			{ e with eexpr = TThrow (f KThrow e1) }
 		| TEnumParameter (e1,ef,i) ->
 		| TEnumParameter (e1,ef,i) ->
 			{ e with eexpr = TEnumParameter(f KAccess e1,ef,i) }
 			{ e with eexpr = TEnumParameter(f KAccess e1,ef,i) }
+		| TEnumIndex e1 ->
+			{ e with eexpr = TEnumIndex (f KAccess e1) }
 		| TField (e1,v) ->
 		| TField (e1,v) ->
 			{ e with eexpr = TField (f KAccess e1,v) }
 			{ e with eexpr = TField (f KAccess e1,v) }
 		| TParenthesis e1 ->
 		| TParenthesis e1 ->
@@ -645,7 +647,7 @@ module Fusion = struct
 				state#dec_reads v;
 				state#dec_reads v;
 				block_element acc el
 				block_element acc el
 			(* no-side-effect *)
 			(* no-side-effect *)
-			| {eexpr = TEnumParameter _ | TFunction _ | TConst _ | TTypeExpr _} :: el ->
+			| {eexpr = TEnumParameter _ | TEnumIndex _ | TFunction _ | TConst _ | TTypeExpr _} :: el ->
 				block_element acc el
 				block_element acc el
 			| {eexpr = TMeta((Meta.Pure,_,_),_)} :: el ->
 			| {eexpr = TMeta((Meta.Pure,_,_),_)} :: el ->
 				block_element acc el
 				block_element acc el

+ 4 - 1
src/optimization/analyzerTexprTransformer.ml

@@ -159,6 +159,9 @@ let rec func ctx bb tf t p =
 		| TEnumParameter(e1,ef,ei) ->
 		| TEnumParameter(e1,ef,ei) ->
 			let bb,e1 = value bb e1 in
 			let bb,e1 = value bb e1 in
 			bb,{e with eexpr = TEnumParameter(e1,ef,ei)}
 			bb,{e with eexpr = TEnumParameter(e1,ef,ei)}
+		| TEnumIndex e1 ->
+			let bb,e1 = value bb e1 in
+			bb,{e with eexpr = TEnumIndex e1}
 		| TFunction tf ->
 		| TFunction tf ->
 			let bb_func,bb_func_end = func ctx bb tf e.etype e.epos in
 			let bb_func,bb_func_end = func ctx bb tf e.etype e.epos in
 			let e_fun = mk (TConst (TString "fun")) t_dynamic p in
 			let e_fun = mk (TConst (TString "fun")) t_dynamic p in
@@ -603,7 +606,7 @@ let rec func ctx bb tf t p =
 			add_texpr bb e;
 			add_texpr bb e;
 			bb
 			bb
 		(* no-side-effect *)
 		(* no-side-effect *)
-		| TEnumParameter _ | TFunction _ | TConst _ | TTypeExpr _ | TLocal _ ->
+		| TEnumParameter _ | TEnumIndex _ | TFunction _ | TConst _ | TTypeExpr _ | TLocal _ ->
 			bb
 			bb
 		(* no-side-effect composites *)
 		(* no-side-effect composites *)
 		| TParenthesis e1 | TMeta(_,e1) | TCast(e1,None) | TField(e1,_) | TUnop(_,_,e1) ->
 		| TParenthesis e1 | TMeta(_,e1) | TCast(e1,None) | TField(e1,_) | TUnop(_,_,e1) ->

+ 3 - 1
src/optimization/optimizer.ml

@@ -927,7 +927,7 @@ let standard_precedence op =
 
 
 let rec need_parent e =
 let rec need_parent e =
 	match e.eexpr with
 	match e.eexpr with
-	| TConst _ | TLocal _ | TArray _ | TField _ | TEnumParameter _ | TParenthesis _ | TCall _ | TNew _ | TTypeExpr _ | TObjectDecl _ | TArrayDecl _ -> false
+	| TConst _ | TLocal _ | TArray _ | TField _ | TEnumParameter _ | TEnumIndex _ | TParenthesis _ | TCall _ | TNew _ | TTypeExpr _ | TObjectDecl _ | TArrayDecl _ -> false
 	| TCast (e,None) | TMeta(_,e) -> need_parent e
 	| TCast (e,None) | TMeta(_,e) -> need_parent e
 	| TCast _ | TThrow _ | TReturn _ | TTry _ | TSwitch _ | TFor _ | TIf _ | TWhile _ | TBinop _ | TContinue | TBreak
 	| TCast _ | TThrow _ | TReturn _ | TTry _ | TSwitch _ | TFor _ | TIf _ | TWhile _ | TBinop _ | TContinue | TBreak
 	| TBlock _ | TVar _ | TFunction _ | TUnop _ -> true
 	| TBlock _ | TVar _ | TFunction _ | TUnop _ -> true
@@ -1019,6 +1019,8 @@ let sanitize_expr com e =
 		if need_parent e2 then { e with eexpr = TCall(parent e2,args) } else e
 		if need_parent e2 then { e with eexpr = TCall(parent e2,args) } else e
 	| TEnumParameter (e2,ef,i) ->
 	| TEnumParameter (e2,ef,i) ->
 		if need_parent e2 then { e with eexpr = TEnumParameter(parent e2,ef,i) } else e
 		if need_parent e2 then { e with eexpr = TEnumParameter(parent e2,ef,i) } else e
+	| TEnumIndex e2 ->
+		if need_parent e2 then { e with eexpr = TEnumIndex(parent e2) } else e
 	| TField (e2,f) ->
 	| TField (e2,f) ->
 		if need_parent e2 then { e with eexpr = TField(parent e2,f) } else e
 		if need_parent e2 then { e with eexpr = TField(parent e2,f) } else e
 	| TArray (e1,e2) ->
 	| TArray (e1,e2) ->

+ 1 - 1
src/optimization/optimizerTexpr.ml

@@ -69,7 +69,7 @@ let has_side_effect e =
 		| TNew(c,_,el) when (match c.cl_constructor with Some cf when PurityState.is_pure c cf -> true | _ -> false) -> List.iter loop el
 		| TNew(c,_,el) when (match c.cl_constructor with Some cf when PurityState.is_pure c cf -> true | _ -> false) -> List.iter loop el
 		| TNew _ | TCall _ | TBinop ((OpAssignOp _ | OpAssign),_,_) | TUnop ((Increment|Decrement),_,_) -> raise Exit
 		| TNew _ | TCall _ | TBinop ((OpAssignOp _ | OpAssign),_,_) | TUnop ((Increment|Decrement),_,_) -> raise Exit
 		| TReturn _ | TBreak | TContinue | TThrow _ | TCast (_,Some _) -> raise Exit
 		| TReturn _ | TBreak | TContinue | TThrow _ | TCast (_,Some _) -> raise Exit
-		| TArray _ | TEnumParameter _ | TCast (_,None) | TBinop _ | TUnop _ | TParenthesis _ | TMeta _ | TWhile _ | TFor _
+		| TArray _ | TEnumParameter _ | TEnumIndex _ | TCast (_,None) | TBinop _ | TUnop _ | TParenthesis _ | TMeta _ | TWhile _ | TFor _
 		| TField _ | TIf _ | TTry _ | TSwitch _ | TArrayDecl _ | TBlock _ | TObjectDecl _ | TVar _ -> Type.iter loop e
 		| TField _ | TIf _ | TTry _ | TSwitch _ | TArrayDecl _ | TBlock _ | TObjectDecl _ | TVar _ -> Type.iter loop e
 	in
 	in
 	try
 	try

+ 1 - 2
src/typing/matcher.ml

@@ -1261,8 +1261,7 @@ module TexprConverter = struct
 				   (correctly typed) neutral value because it doesn't actually matter. *)
 				   (correctly typed) neutral value because it doesn't actually matter. *)
 				mk (TConst (TInt (Int32.of_int 0))) ctx.t.tint e.epos
 				mk (TConst (TInt (Int32.of_int 0))) ctx.t.tint e.epos
 			else
 			else
-				let cf = PMap.find "enumIndex" c_type.cl_statics in
-				make_static_call ctx c_type cf (fun t -> t) [e] com.basic.tint e.epos
+				mk (TEnumIndex e) com.basic.tint e.epos
 		in
 		in
 		let mk_name_call e =
 		let mk_name_call e =
 			if not ctx.in_macro && not ctx.com.display.DisplayMode.dms_full_typing then
 			if not ctx.in_macro && not ctx.com.display.DisplayMode.dms_full_typing then

+ 17 - 2
src/typing/type.ml

@@ -138,6 +138,7 @@ and texpr_expr =
 	| TCast of texpr * module_type option
 	| TCast of texpr * module_type option
 	| TMeta of metadata_entry * texpr
 	| TMeta of metadata_entry * texpr
 	| TEnumParameter of texpr * tenum_field * int
 	| TEnumParameter of texpr * tenum_field * int
+	| TEnumIndex of texpr
 
 
 and tfield_access =
 and tfield_access =
 	| FInstance of tclass * tparams * tclass_field
 	| FInstance of tclass * tparams * tclass_field
@@ -983,6 +984,7 @@ let s_expr_kind e =
 	| TArray (_,_) -> "Array"
 	| TArray (_,_) -> "Array"
 	| TBinop (_,_,_) -> "Binop"
 	| TBinop (_,_,_) -> "Binop"
 	| TEnumParameter (_,_,_) -> "EnumParameter"
 	| TEnumParameter (_,_,_) -> "EnumParameter"
+	| TEnumIndex _ -> "EnumIndex"
 	| TField (_,_) -> "Field"
 	| TField (_,_) -> "Field"
 	| TTypeExpr _ -> "TypeExpr"
 	| TTypeExpr _ -> "TypeExpr"
 	| TParenthesis _ -> "Parenthesis"
 	| TParenthesis _ -> "Parenthesis"
@@ -1029,6 +1031,8 @@ let rec s_expr s_type e =
 		sprintf "%s[%s]" (loop e1) (loop e2)
 		sprintf "%s[%s]" (loop e1) (loop e2)
 	| TBinop (op,e1,e2) ->
 	| TBinop (op,e1,e2) ->
 		sprintf "(%s %s %s)" (loop e1) (s_binop op) (loop e2)
 		sprintf "(%s %s %s)" (loop e1) (s_binop op) (loop e2)
+	| TEnumIndex e1 ->
+		sprintf "EnumIndex %s" (loop e1)
 	| TEnumParameter (e1,_,i) ->
 	| TEnumParameter (e1,_,i) ->
 		sprintf "%s[%i]" (loop e1) i
 		sprintf "%s[%i]" (loop e1) i
 	| TField (e,f) ->
 	| TField (e,f) ->
@@ -1105,6 +1109,7 @@ let rec s_expr_pretty print_var_ids tabs top_level s_type e =
 	| TArray (e1,e2) -> sprintf "%s[%s]" (loop e1) (loop e2)
 	| TArray (e1,e2) -> sprintf "%s[%s]" (loop e1) (loop e2)
 	| TBinop (op,e1,e2) -> sprintf "%s %s %s" (loop e1) (s_binop op) (loop e2)
 	| TBinop (op,e1,e2) -> sprintf "%s %s %s" (loop e1) (s_binop op) (loop e2)
 	| TEnumParameter (e1,_,i) -> sprintf "%s[%i]" (loop e1) i
 	| TEnumParameter (e1,_,i) -> sprintf "%s[%i]" (loop e1) i
+	| TEnumIndex e1 -> sprintf "enumIndex %s" (loop e1)
 	| TField (e1,s) -> sprintf "%s.%s" (loop e1) (field_name s)
 	| TField (e1,s) -> sprintf "%s.%s" (loop e1) (field_name s)
 	| TTypeExpr mt -> (s_type_path (t_path mt))
 	| TTypeExpr mt -> (s_type_path (t_path mt))
 	| TParenthesis e1 -> sprintf "(%s)" (loop e1)
 	| TParenthesis e1 -> sprintf "(%s)" (loop e1)
@@ -1188,6 +1193,7 @@ let rec s_expr_ast print_var_ids tabs s_type e =
 	| TBinop (op,e1,e2) -> tag "Binop" [loop e1; s_binop op; loop e2]
 	| TBinop (op,e1,e2) -> tag "Binop" [loop e1; s_binop op; loop e2]
 	| TUnop (op,flag,e1) -> tag "Unop" [s_unop op; if flag = Postfix then "Postfix" else "Prefix"; loop e1]
 	| TUnop (op,flag,e1) -> tag "Unop" [s_unop op; if flag = Postfix then "Postfix" else "Prefix"; loop e1]
 	| TEnumParameter (e1,ef,i) -> tag "EnumParameter" [loop e1; ef.ef_name; string_of_int i]
 	| TEnumParameter (e1,ef,i) -> tag "EnumParameter" [loop e1; ef.ef_name; string_of_int i]
+	| TEnumIndex e1 -> tag "EnumIndex" [loop e1]
 	| TField (e1,fa) ->
 	| TField (e1,fa) ->
 		let sfa = match fa with
 		let sfa = match fa with
 			| FInstance(c,tl,cf) -> tag "FInstance" ~extra_tabs:"\t" [s_type (TInst(c,tl)); cf.cf_name]
 			| FInstance(c,tl,cf) -> tag "FInstance" ~extra_tabs:"\t" [s_type (TInst(c,tl)); cf.cf_name]
@@ -2254,6 +2260,7 @@ let iter f e =
 	| TThrow e
 	| TThrow e
 	| TField (e,_)
 	| TField (e,_)
 	| TEnumParameter (e,_,_)
 	| TEnumParameter (e,_,_)
+	| TEnumIndex e
 	| TParenthesis e
 	| TParenthesis e
 	| TCast (e,_)
 	| TCast (e,_)
 	| TUnop (_,_,e)
 	| TUnop (_,_,e)
@@ -2309,7 +2316,9 @@ let map_expr f e =
 	| TThrow e1 ->
 	| TThrow e1 ->
 		{ e with eexpr = TThrow (f e1) }
 		{ e with eexpr = TThrow (f e1) }
 	| TEnumParameter (e1,ef,i) ->
 	| TEnumParameter (e1,ef,i) ->
-		 { e with eexpr = TEnumParameter(f e1,ef,i) }
+		{ e with eexpr = TEnumParameter(f e1,ef,i) }
+	| TEnumIndex e1 ->
+		{ e with eexpr = TEnumIndex (f e1) }
 	| TField (e1,v) ->
 	| TField (e1,v) ->
 		{ e with eexpr = TField (f e1,v) }
 		{ e with eexpr = TField (f e1,v) }
 	| TParenthesis e1 ->
 	| TParenthesis e1 ->
@@ -2374,7 +2383,9 @@ let map_expr_type f ft fv e =
 	| TThrow e1 ->
 	| TThrow e1 ->
 		{ e with eexpr = TThrow (f e1); etype = ft e.etype }
 		{ e with eexpr = TThrow (f e1); etype = ft e.etype }
 	| TEnumParameter (e1,ef,i) ->
 	| TEnumParameter (e1,ef,i) ->
-		{ e with eexpr = TEnumParameter(f e1,ef,i); etype = ft e.etype }
+		{ e with eexpr = TEnumParameter (f e1,ef,i); etype = ft e.etype }
+	| TEnumIndex e1 ->
+		{ e with eexpr = TEnumIndex (f e1); etype = ft e.etype }
 	| TField (e1,v) ->
 	| TField (e1,v) ->
 		let e1 = f e1 in
 		let e1 = f e1 in
 		let v = try
 		let v = try
@@ -2570,6 +2581,7 @@ module TExprToExpr = struct
 			) cases in
 			) cases in
 			let def = match eopt def with None -> None | Some (EBlock [],_) -> Some (None,null_pos) | Some e -> Some (Some e,pos e) in
 			let def = match eopt def with None -> None | Some (EBlock [],_) -> Some (None,null_pos) | Some e -> Some (Some e,pos e) in
 			ESwitch (convert_expr e,cases,def)
 			ESwitch (convert_expr e,cases,def)
+		| TEnumIndex _
 		| TEnumParameter _ ->
 		| TEnumParameter _ ->
 			(* these are considered complex, so the AST is handled in TMeta(Meta.Ast) *)
 			(* these are considered complex, so the AST is handled in TMeta(Meta.Ast) *)
 			assert false
 			assert false
@@ -2741,6 +2753,9 @@ module Texpr = struct
 		| TEnumParameter (e1,ef,i) ->
 		| TEnumParameter (e1,ef,i) ->
 			let acc,e1 = f acc e1 in
 			let acc,e1 = f acc e1 in
 			acc,{ e with eexpr = TEnumParameter(e1,ef,i) }
 			acc,{ e with eexpr = TEnumParameter(e1,ef,i) }
+		| TEnumIndex e1 ->
+			let acc,e1 = f acc e1 in
+			acc,{ e with eexpr = TEnumIndex e1 }
 		| TField (e1,v) ->
 		| TField (e1,v) ->
 			let acc,e1 = f acc e1 in
 			let acc,e1 = f acc e1 in
 			acc,{ e with eexpr = TField (e1,v) }
 			acc,{ e with eexpr = TField (e1,v) }

+ 1 - 0
std/cs/_std/Type.hx

@@ -325,6 +325,7 @@ enum ValueType {
 		return Std.is(e, cs.system.Enum) ? [] : cast(e,HxEnum).getParams();
 		return Std.is(e, cs.system.Enum) ? [] : cast(e,HxEnum).getParams();
 	}
 	}
 
 
+	@:ifFeature("has_enum")
 	@:pure
 	@:pure
 	public static function enumIndex( e : EnumValue ) : Int
 	public static function enumIndex( e : EnumValue ) : Int
 	{
 	{

+ 5 - 0
std/haxe/macro/Type.hx

@@ -969,6 +969,11 @@ enum TypedExprDef {
 		Access to an enum parameter (generated by the pattern matcher).
 		Access to an enum parameter (generated by the pattern matcher).
 	**/
 	**/
 	TEnumParameter(e1:TypedExpr, ef:EnumField, index:Int);
 	TEnumParameter(e1:TypedExpr, ef:EnumField, index:Int);
+
+	/**
+		Access to an enum index (generated by the pattern matcher).
+	**/
+	TEnumIndex(e1:TypedExpr);
 }
 }
 
 
 /**
 /**

+ 3 - 1
std/haxe/macro/TypedExprTools.hx

@@ -54,6 +54,7 @@ class TypedExprTools {
 			case TWhile(e1, e2, flag): with(e, TWhile(f(e1), f(e2), flag));
 			case TWhile(e1, e2, flag): with(e, TWhile(f(e1), f(e2), flag));
 			case TThrow(e1): with(e, TThrow(f(e1)));
 			case TThrow(e1): with(e, TThrow(f(e1)));
 			case TEnumParameter(e1, ef, i): with(e, TEnumParameter(f(e1), ef, i));
 			case TEnumParameter(e1, ef, i): with(e, TEnumParameter(f(e1), ef, i));
+			case TEnumIndex(e1): with(e, TEnumIndex(f(e1)));
 			case TField(e1, fa): with(e, TField(f(e1), fa));
 			case TField(e1, fa): with(e, TField(f(e1), fa));
 			case TParenthesis(e1): with(e, TParenthesis(f(e1)));
 			case TParenthesis(e1): with(e, TParenthesis(f(e1)));
 			case TUnop(op, pre, e1): with(e, TUnop(op, pre, f(e1)));
 			case TUnop(op, pre, e1): with(e, TUnop(op, pre, f(e1)));
@@ -86,7 +87,7 @@ class TypedExprTools {
 			case TArray(e1, e2) | TBinop(_, e1, e2) | TFor(_, e1, e2) | TWhile(e1, e2, _):
 			case TArray(e1, e2) | TBinop(_, e1, e2) | TFor(_, e1, e2) | TWhile(e1, e2, _):
 				f(e1);
 				f(e1);
 				f(e2);
 				f(e2);
-			case TThrow(e1) | TEnumParameter(e1, _, _) | TField(e1, _) | TParenthesis(e1) | TUnop(_, _, e1) | TCast(e1, _) | TMeta(_, e1):
+			case TThrow(e1) | TEnumParameter(e1, _, _) | TEnumIndex(e1) | TField(e1, _) | TParenthesis(e1) | TUnop(_, _, e1) | TCast(e1, _) | TMeta(_, e1):
 				f(e1);
 				f(e1);
 			case TArrayDecl(el) | TNew(_, _, el) | TBlock(el):
 			case TArrayDecl(el) | TNew(_, _, el) | TBlock(el):
 				for (e in el) f(e);
 				for (e in el) f(e);
@@ -135,6 +136,7 @@ class TypedExprTools {
 			case TWhile(e1, e2, flag): with(e, TWhile(f(e1), f(e2), flag), ft(e.t));
 			case TWhile(e1, e2, flag): with(e, TWhile(f(e1), f(e2), flag), ft(e.t));
 			case TThrow(e1): with(e, TThrow(f(e1)), ft(e.t));
 			case TThrow(e1): with(e, TThrow(f(e1)), ft(e.t));
 			case TEnumParameter(e1, ef, i): with(e, TEnumParameter(f(e1), ef, i), ft(e.t));
 			case TEnumParameter(e1, ef, i): with(e, TEnumParameter(f(e1), ef, i), ft(e.t));
+			case TEnumIndex(e1): with(e, TEnumIndex(f(e1)), ft(e.t));
 			case TField(e1, fa): with(e, TField(f(e1), fa), ft(e.t));
 			case TField(e1, fa): with(e, TField(f(e1), fa), ft(e.t));
 			case TParenthesis(e1): with(e, TParenthesis(e1), ft(e.t));
 			case TParenthesis(e1): with(e, TParenthesis(e1), ft(e.t));
 			case TUnop(op, pre, e1): with(e, TUnop(op, pre, f(e1)), ft(e.t));
 			case TUnop(op, pre, e1): with(e, TUnop(op, pre, f(e1)), ft(e.t));

+ 1 - 0
std/java/_std/Type.hx

@@ -407,6 +407,7 @@ enum ValueType {
 		return null;
 		return null;
 	}
 	}
 
 
+	@:ifFeature("has_enum")
 	@:functionCode('
 	@:functionCode('
 		if (e instanceof java.lang.Enum)
 		if (e instanceof java.lang.Enum)
 			return ((java.lang.Enum) e).ordinal();
 			return ((java.lang.Enum) e).ordinal();

+ 4 - 0
tests/unit/src/unit/TestOverloads.hx

@@ -202,9 +202,11 @@ class TestOverloads extends Test
 		eq(child.someField(true, 10), 52);
 		eq(child.someField(true, 10), 52);
 		eq(child.initialized3, true);
 		eq(child.initialized3, true);
 
 
+		#if !cs // TODO: https://github.com/HaxeFoundation/haxe/issues/6352
 		var child:ChildJava4<Int, Bool, ChildJava3<Dynamic, Dynamic>> = new ChildJava4(Bytes.ofString("test"));
 		var child:ChildJava4<Int, Bool, ChildJava3<Dynamic, Dynamic>> = new ChildJava4(Bytes.ofString("test"));
 		eq(child.s, "test");
 		eq(child.s, "test");
 		eq(child.someField(child), null);
 		eq(child.someField(child), null);
+		#end
 	}
 	}
 }
 }
 
 
@@ -602,9 +604,11 @@ class ChildJava3<A, T : BaseJava> extends ChildJava2<T>
 	}
 	}
 }
 }
 
 
+#if !cs // TODO: https://github.com/HaxeFoundation/haxe/issues/6352
 class ChildJava4<X, Y, Z : ChildJava2<Dynamic>> extends ChildJava3<Y, Z>
 class ChildJava4<X, Y, Z : ChildJava2<Dynamic>> extends ChildJava3<Y, Z>
 {
 {
 }
 }
+#end
 
 
 interface NormalInterface
 interface NormalInterface
 {
 {