Explorar el Código

Merge pull request #20 from frabbit/genpy

add travis support for python
Simon Krajewski hace 11 años
padre
commit
4e856f2656

+ 1 - 0
.travis.yml

@@ -11,6 +11,7 @@ env:
     - TARGET=neko
     - TARGET=js
     - TARGET=php
+    - TARGET=python
     - TARGET=cpp
     - TARGET=flash9
     - TARGET=as3

+ 1 - 1
common.ml

@@ -637,7 +637,7 @@ let get_config com =
 	| Python ->
 		{
 			pf_static = false;
-			pf_sys = false;
+			pf_sys = true;
 			pf_locals_scope = false;
 			pf_captured_scope = false;
 			pf_unique_locals = false;

+ 19 - 32
filters.ml

@@ -66,13 +66,6 @@ let mk_block_context com gen_temp =
 	- array access
 *)
 let handle_side_effects com gen_temp e =
-	let has_direct_side_effect e = match e.eexpr with
-		| TConst _ | TLocal _ | TField _ | TTypeExpr _ | TFunction _ -> false
-		| TPatMatch _ | TNew _ | TCall _ | TBinop ((OpAssignOp _ | OpAssign),_,_) | TUnop ((Increment|Decrement),_,_) -> true
-		| TReturn _ | TBreak | TContinue | TThrow _ | TCast (_,Some _) -> true
-		| TIf _ | TTry _ | TSwitch _ -> true
-		| TArray _ | TEnumParameter _ | TCast (_,None) | TBinop _ | TUnop _ | TParenthesis _ | TMeta _ | TWhile _ | TFor _ | TArrayDecl _ | TVar _ | TBlock _ | TObjectDecl _ -> false
-	in
 	let block,declare_temp,close_block = mk_block_context com gen_temp in
 	let rec loop e =
 		match e.eexpr with
@@ -99,6 +92,15 @@ let handle_side_effects com gen_temp e =
 				e1,mk (TConst (TBool(false))) com.basic.tbool e.epos
 			in
 			mk (TIf(e_if,e_then,Some e_else)) com.basic.tbool e.epos
+		| TBinop((OpAssign | OpAssignOp _) as op,{eexpr = TArray(e11,e12)},e2) ->
+			let e1 = match ordered_list [e11;e12] with
+				| [e1;e2] ->
+					{e with eexpr = TArray(e1,e2)}
+				| _ ->
+					assert false
+			in
+			let e2 = loop e2 in
+			{e with eexpr = TBinop(op,e1,e2)}
  		| TBinop(op,e1,e2) ->
 			begin match ordered_list [e1;e2] with
 				| [e1;e2] ->
@@ -125,32 +127,16 @@ let handle_side_effects com gen_temp e =
 		| _ ->
 			Type.map_expr loop e
 	and ordered_list el =
-		let had_side_effect = ref false in
 		let bind e =
-			if !had_side_effect then
-				declare_temp e.etype (Some (loop e)) e.epos
-			else begin
-				had_side_effect := true;
-				e
-			end
+			declare_temp e.etype (Some (loop e)) e.epos
 		in
 		let rec no_side_effect e =
-			if has_direct_side_effect e then
+			if Optimizer.has_side_effect e then
 				bind e
 			else
-				Type.map_expr no_side_effect e
-		in
-		let rec loop2 acc el = match el with
-			| e :: el ->
-				let e = no_side_effect e in
-				if !had_side_effect then
-					(List.map no_side_effect (List.rev el)) @ e :: acc
-				else
-					loop2 (e :: acc) el
-			| [] ->
-				acc
+				e
 		in
-		List.map loop (loop2 [] (List.rev el))
+		List.map no_side_effect el
 	in
 	let e = loop e in
 	match close_block() with
@@ -998,6 +984,7 @@ let add_rtti ctx t =
 
 (* Adds member field initializations as assignments to the constructor *)
 let add_field_inits ctx t =
+	let is_as3 = Common.defined ctx.com Define.As3 && not ctx.in_macro in
 	let apply c =
 		let ethis = mk (TConst TThis) (TInst (c,List.map snd c.cl_types)) c.cl_pos in
 		(* TODO: we have to find a variable name which is not used in any of the functions *)
@@ -1006,8 +993,8 @@ let add_field_inits ctx t =
 		let inits,fields = List.fold_left (fun (inits,fields) cf ->
 			match cf.cf_kind,cf.cf_expr with
 			| Var _, Some _ ->
-				if Common.defined ctx.com Define.As3 then (inits, cf :: fields) else (cf :: inits, cf :: fields)
-			| Method MethDynamic, Some e when Common.defined ctx.com Define.As3 ->
+				if is_as3 then (inits, cf :: fields) else (cf :: inits, cf :: fields)
+			| Method MethDynamic, Some e when is_as3 ->
 				(* TODO : this would have a better place in genSWF9 I think - NC *)
 				(* we move the initialization of dynamic functions to the constructor and also solve the
 				   'this' problem along the way *)
@@ -1040,7 +1027,7 @@ let add_field_inits ctx t =
 					let lhs = mk (TField(ethis,FInstance (c,cf))) cf.cf_type e.epos in
 					cf.cf_expr <- None;
 					let eassign = mk (TBinop(OpAssign,lhs,e)) e.etype e.epos in
-					if Common.defined ctx.com Define.As3 then begin
+					if is_as3 then begin
 						let echeck = mk (TBinop(OpEq,lhs,(mk (TConst TNull) lhs.etype e.epos))) ctx.com.basic.tbool e.epos in
 						mk (TIf(echeck,eassign,None)) eassign.etype e.epos
 					end else
@@ -1153,13 +1140,13 @@ let run com tctx main =
  	let filters = [
 		Codegen.Abstract.handle_abstract_casts tctx;
 		blockify_ast;
-(* 		(match com.platform with
+		(match com.platform with
 			| Cpp | Flash8 -> (fun e ->
 				let save = save_locals tctx in
 				let e = handle_side_effects com (Typecore.gen_local tctx) e in
 				save();
 				e)
-			| _ -> fun e -> e); *)
+			| _ -> fun e -> e);
 		if com.foptimize then (fun e -> Optimizer.reduce_expression tctx (Optimizer.inline_constructors tctx e)) else Optimizer.sanitize tctx;
 		check_local_vars_init;
 		captured_vars com;

+ 100 - 66
std/Math.hx

@@ -25,6 +25,10 @@
 #if cpp @:include("hxMath") #end
 extern class Math
 {
+	/**
+		Represents the ratio of the circumference of a circle to its diameter, 
+		specified by the constant, π. `PI` is approximately 3.141592653589793.
+	**/
 	static var PI(default,null) : Float;
 
 	/**
@@ -33,22 +37,20 @@ extern class Math
 		For example, this is the result of -1.0 / 0.0.
 
 		Operations with NEGATIVE_INFINITY as an operand may result in
-		Operations with NEGATIVE_INFINITY as an operand may result in
-		NEGATIVE_INFINITY, POSITIVE_INFINITY or NaN. For detailed information,
-		see ...
+		NEGATIVE_INFINITY, POSITIVE_INFINITY or NaN. 
 
 		If this constant is converted to an Int, e.g. through Std.int(), the
 		result is unspecified.
 	**/
 	static var NEGATIVE_INFINITY(default, null) : Float;
+
 	/**
 		A special Float constant which denotes negative infinity.
 
 		For example, this is the result of 1.0 / 0.0.
 
 		Operations with POSITIVE_INFINITY as an operand may result in
-		NEGATIVE_INFINITY, POSITIVE_INFINITY or NaN. For detailed information,
-		see ...
+		NEGATIVE_INFINITY, POSITIVE_INFINITY or NaN. 
 
 		If this constant is converted to an Int, e.g. through Std.int(), the
 		result is unspecified.
@@ -69,21 +71,21 @@ extern class Math
 
 		In order to test if a value is NaN, you should use Math.isNaN() function.
 
-		(Php) In PHP versions prior to 5.3.1 VC 9 there may be unexpected
-		results when performing arithmetic operations with NaN on Windows, see:
-			https://bugs.php.net/bug.php?id=42143
+		@php In PHP versions prior to 5.3.1 VC 9 there may be unexpected
+		results when performing arithmetic operations with NaN on Windows, 
+		see [https://bugs.php.net/bug.php?id=42143]
 	**/
 	static var NaN(default, null) : Float;
 
 	/**
 		Returns the absolute value of `v`.
 
-		If `v` is positive or 0, the result is unchanged. Otherwise the result
+		If `v` is positive or 0, the result is unchanged. Otherwise the result 
 		is -`v`.
-
-		If `v` is NEGATIVE_INFINITY or POSITIVE_INFINITY, the result is
+		
+		If `v` is NEGATIVE_INFINITY or POSITIVE_INFINITY, the result is 
 		POSITIVE_INFINITY.
-
+		
 		If `v` is NaN, the result is NaN.
 	**/
 	static function abs(v:Float):Float;
@@ -92,9 +94,7 @@ extern class Math
 		Returns the smaller of values `a` and `b`.
 
 		If `a` or `b` are NaN, the result is NaN.
-
 		If `a` or `b` are NEGATIVE_INFINITY, the result is NEGATIVE_INFINITY.
-
 		If `a` and `b` are POSITIVE_INFINITY, the result is POSITIVE_INFINITY.
 	**/
 	static function min(a:Float, b:Float):Float;
@@ -103,119 +103,156 @@ extern class Math
 		Returns the greater of values `a` and `b`.
 
 		If `a` or `b` are NaN, the result is NaN.
-
 		If `a` or `b` are POSITIVE_INFINITY, the result is POSITIVE_INFINITY.
-
 		If `a` and `b` are NEGATIVE_INFINITY, the result is NEGATIVE_INFINITY.
 	**/
 	static function max(a:Float, b:Float):Float;
 
 	/**
-		Returns the trigonometric sine of `v`.
-
-		The unit of `v` is radians.
-
+		Returns the trigonometric sine of the specified angle `v`, in radians.
+		
 		If `v` is NaN or infinite, the result is NaN.
 	**/
 	static function sin(v:Float):Float;
 
 	/**
-		Returns the trigonometric cosine of `v`.
-
-		The unit of `v` is radians.
-
+		Returns the trigonometric cosine of the specified angle `v`, in radians.
+		
 		If `v` is NaN or infinite, the result is NaN.
 	**/
 	static function cos(v:Float):Float;
 
-	// TODO
+	/**
+		Returns the trigonometric tangent of the specified angle `v`, in radians.
+		
+		If `v` is NaN or infinite, the result is NaN.
+	**/
 	static function tan(v:Float):Float;
+
+	/**
+		Returns the trigonometric arc of the specified angle `v`, in radians.
+		
+		If `v` is NaN or infinite, the result is NaN.
+	**/
 	static function asin(v:Float):Float;
+
+	/**
+		Returns the trigonometric arc cosine of the specified angle `v`, 
+		in radians.
+		
+		If `v` is NaN or infinite, the result is NaN.
+	**/
 	static function acos(v:Float):Float;
+
+	/**
+		Returns the trigonometric arc tangent of the specified angle `v`, 
+		in radians.
+		
+		If `v` is NaN or infinite, the result is NaN.
+	**/
 	static function atan(v:Float):Float;
+
+	/**
+		Returns the trigonometric arc tangent whose tangent is the quotient of 
+		two specified numbers, in radians.
+		
+		If parameter `x` or `y`  is NaN, NEGATIVE_INFINITY or POSITIVE_INFINITY, 
+		the result is NaN.
+	**/
 	static function atan2(y:Float, x:Float):Float;
 
 	/**
 		Returns Euler's number, raised to the power of `v`.
-
+		
 		exp(1.0) is approximately 2.718281828459.
-
+		
 		If `v` is POSITIVE_INFINITY, the result is POSITIVE_INFINITY.
-
 		If `v` is NEGATIVE_INFINITY, the result is 0.0.
-
 		If `v` is NaN, the result is NaN.
 	**/
 	static function exp(v:Float):Float;
 
 	/**
 		Returns the natural logarithm of `v`.
-
-		If `v` is negative (including NEGATIVE_INFINITY) or NaN, the result is
-		NaN.
-
+		
+		This is the mathematical inverse operation of exp, 
+		i.e. `log(exp(v)) == v` always holds.
+		
+		If `v` is negative (including NEGATIVE_INFINITY) or NaN, the result 
+		is NaN.
 		If `v` is POSITIVE_INFINITY, the result is POSITIVE_INFINITY.
-
 		If `v` is 0.0, the result is NEGATIVE_INFINITY.
-
-		This is the inverse operation of exp, i.e. log(exp(v)) == v always
-		holds.
 	**/
 	static function log(v:Float):Float;
 
-	// TODO
-	// http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/Math.html#pow(double, double) <-- wtf?
+	/**
+		Returns a specified base `v` raised to the specified power `exp`.
+	**/
 	static function pow(v:Float, exp:Float):Float;
 
 	/**
 		Returns the square root of `v`.
-
-		If `v` is negative (including NEGATIVE_INFINITY) or NaN, the result is
-		NaN.
-
+		
+		If `v` is negative (including NEGATIVE_INFINITY) or NaN, the result 
+		is NaN.
 		If `v` is POSITIVE_INFINITY, the result is POSITIVE_INFINITY.
-
 		If `v` is 0.0, the result is 0.0.
 	**/
 	static function sqrt(v:Float):Float;
 
 	/**
-		Rounds `v` to the nearest Int value.
-
-		If v is outside of the signed Int32 range, or is NaN, NEGATIVE_INFINITY or POSITIVE_INFINITY, the result is unspecified.
-
-		TODO: need spec
+		Rounds `v` to the nearest integer value.
+		
+		If `v` is outside of the signed Int32 range, or is NaN, NEGATIVE_INFINITY 
+		or POSITIVE_INFINITY, the result is unspecified.
 	**/
 	static function round(v:Float):Int;
 
 	/**
-		Returns the largest Int value that is not greater than `v`.
-
-		If v is outside of the signed Int32 range, or is NaN, NEGATIVE_INFINITY or POSITIVE_INFINITY, the result is unspecified.
+		Returns the largest integer value that is not greater than `v`.
 
-		TODO: need spec
+		If `v` is outside of the signed Int32 range, or is NaN, NEGATIVE_INFINITY 
+		or POSITIVE_INFINITY, the result is unspecified.
 	**/
 	static function floor(v:Float):Int;
 
 	/**
-		Returns the smallest Int value that is not less than `v`.
+		Returns the smallest integer value that is not less than `v`.
 
-		If v is outside of the signed Int32 range, or is NaN, NEGATIVE_INFINITY or POSITIVE_INFINITY, the result is unspecified.
-
-		TODO: need spec
+		If `v` is outside of the signed Int32 range, or is NaN, NEGATIVE_INFINITY 
+		or POSITIVE_INFINITY, the result is unspecified.
 	**/
 	static function ceil(v:Float):Int;
 
 	/**
-		Returns a pseudo-random number which is greater than or equal to 0.0,
+		Returns a pseudo-random number which is greater than or equal to 0.0, 
 		and less than 1.0.
 	**/
 	static function random() : Float;
 
 	#if ((flash9 && !as3) || cpp)
+	/**
+		Returns the largest integer value that is not greater than `v`, as a Float.
 
+		If `v` is is NaN, NEGATIVE_INFINITY or POSITIVE_INFINITY, 
+		the result is unspecified.
+	**/
 	static function ffloor( v : Float ) : Float;
+
+	/**
+		Returns the smallest integer value that is not less than `v`, as a Float.
+
+		If `v` is is NaN, NEGATIVE_INFINITY or POSITIVE_INFINITY, 
+		the result is unspecified.
+	**/
 	static function fceil( v : Float ) : Float;
+
+	/**
+		Rounds `v` to the nearest integer value, as a Float.
+
+		If `v` is is NaN, NEGATIVE_INFINITY or POSITIVE_INFINITY, 
+		the result is unspecified.
+	**/
 	static function fround( v : Float ) : Float;
 
 	#else
@@ -238,20 +275,17 @@ extern class Math
 	/**
 		Tells if `f` is a finite number.
 
-		If `f` is POSITIVE_INFINITY, NEGATIVE_INFINITY or NaN, the result is
-		false.
-
-		Otherwise the result is true.
+		If `f` is POSITIVE_INFINITY, NEGATIVE_INFINITY or NaN, the result 
+		is false, otherwise the result is true.
 	**/
 	static function isFinite( f : Float ) : Bool;
 
 	/**
 		Tells if `f` is not a valid number.
 
-		If `f` is NaN, the result is true.
-
-		Otherwise the result is false. In particular, both POSITIVE_INFINITY and
-		NEGATIVE_INFINITY are not considered NaN.
+		If `f` is NaN, the result is true, otherwise the result is false. 
+		In particular, both POSITIVE_INFINITY and NEGATIVE_INFINITY are
+		not considered NaN.
 	**/
 	static function isNaN( f : Float ) : Bool;
 

+ 2 - 2
std/haxe/macro/TypedExprTools.hx

@@ -63,7 +63,7 @@ class TypedExprTools {
 			case TVar(v,eo): with(e, TVar(v, eo == null ? null : f(eo)));
 			case TFunction(fu): with(e, TFunction({ t: fu.t, args: fu.args, expr: f(fu.expr)}));
 			case TIf(e1, e2, e3): with(e, TIf(f(e1), f(e2), e3 == null ? null : f(e3)));
-			case TSwitch(e1, cases, e2): with(e, TSwitch(e1, cases.map(function(c) return { values: c.values, expr: f(c.expr) }), e2 == null ? null : f(e2)));
+			case TSwitch(e1, cases, e2): with(e, TSwitch(f(e1), cases.map(function(c) return { values: c.values, expr: f(c.expr) }), e2 == null ? null : f(e2)));
 			case TPatMatch: throw false;
 			case TTry(e1, catches): with(e, TTry(f(e1), catches.map(function(c) return { v:c.v, expr: f(c.expr) })));
 			case TReturn(e1): with(e, TReturn(e1 == null ? null : f(e1)));
@@ -102,7 +102,7 @@ class TypedExprTools {
 			case TVar(v,eo): with(e, TVar(fv(v), eo == null ? null : f(eo)), ft(e.t));
 			case TFunction(fu): with(e, TFunction({ t: ft(fu.t), args: fu.args.map(function(arg) return { v: fv(arg.v), value: arg.value }), expr: f(fu.expr)}), ft(e.t));
 			case TIf(e1, e2, e3): with(e, TIf(f(e1), f(e2), e3 == null ? null : f(e3)), ft(e.t));
-			case TSwitch(e1, cases, e2): with(e, TSwitch(e1, cases.map(function(c) return { values: c.values, expr: f(c.expr) }), e2 == null ? null : f(e2)), ft(e.t));
+			case TSwitch(e1, cases, e2): with(e, TSwitch(f(e1), cases.map(function(c) return { values: c.values, expr: f(c.expr) }), e2 == null ? null : f(e2)), ft(e.t));
 			case TPatMatch: throw false;
 			case TTry(e1, catches): with(e, TTry(f(e1), catches.map(function(c) return { v:fv(c.v), expr: f(c.expr) })), ft(e.t));
 			case TReturn(e1): with(e, TReturn(e1 == null ? null : f(e1)), ft(e.t));

+ 0 - 4
std/haxe/remoting/SocketConnection.hx

@@ -110,8 +110,6 @@ class SocketConnection implements AsyncConnection implements Dynamic<AsyncConnec
 		if( f.onResult != null ) f.onResult(ret);
 	}
 
-	#if (flash || js || neko)
-
 	function defaultLog(path,args,e) {
 		// exception inside the called method
 		var astr, estr;
@@ -178,6 +176,4 @@ class SocketConnection implements AsyncConnection implements Dynamic<AsyncConnec
 		return sc;
 	}
 
-	#end
-
 }

+ 2 - 1
std/python/_std/Array.hx

@@ -19,10 +19,11 @@
  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  * DEALINGS IN THE SOFTWARE.
  */
-
+#if !macro
 import python.lib.Builtin;
 import python.internal.ArrayImpl;
 import python.lib.Types;
+#end
 
 @:native("list")
 extern class Array<T> implements ArrayAccess<T> extends ArrayImpl {

+ 2 - 1
std/python/_std/String.hx

@@ -31,9 +31,10 @@ package;
 	String can be concatenated by using the + operator. If an operand is not a
 	String, it is passed through Std.string() first.
 **/
+#if !macro
 import python.internal.StringImpl;
 import python.lib.Builtin;
-
+#end
 extern class String extends StringImpl {
 
 

+ 4 - 2
std/python/internal/ArrayImpl.hx

@@ -22,6 +22,8 @@ package python.internal;
  * DEALINGS IN THE SOFTWARE.
  */
 
+
+
 import python.lib.FuncTools;
 import python.lib.Builtin;
 
@@ -44,7 +46,7 @@ class ArrayImpl {
 
 	@:keep public static inline function iterator<T>(x:Array<T>) : Iterator<T> 
 	{
-		return python.Lib.toHaxeIterator(x.__iter__());
+		return python.Lib.toHaxeIterator(untyped x.__iter__());
 	}
 
 	//public static function insert( pos : Int, x : T ) : Void;
@@ -135,7 +137,7 @@ class ArrayImpl {
 	}
 
 	@:keep public static inline function map<S,T>(x:Array<T>, f : T -> S ) : Array<S> {
-		return Builtin.list(Builtin.map(f,x));
+		return Builtin.list(Builtin.map(f,cast x));
 	}
 
 	@:keep public static inline function filter<T>(x:Array<T>, f : T -> Bool ) : Array<T> {

+ 5 - 1
std/python/internal/StringImpl.hx

@@ -34,8 +34,12 @@ class StringImpl {
 	}
 
 	public static inline function fromCharCode( code : Int ) : String {
+		#if doc_gen 
+		return "";
+		#else
 		var c = code;
-		return untyped (''.join)(Builtin.map(Builtin.chr, [c]));
+		return (untyped (''.join)(Builtin.map(Builtin.chr, [c])):String);
+		#end
 	}
 	
 }

+ 1 - 1
std/python/lib/Builtin.hx

@@ -84,7 +84,7 @@ extern class Builtin {
 	//public static function bytearray():Void;
 	//public static function float():Void;
 	
-
+	@:overload(function <T>(f:Array<T>):Array<T> {})
 	@:overload(function (f:String):Array<String> {})
 	@:overload(function <G>(f:Tuple<G>):Array<G> {})
 	public static function list<T>(i:PyIterable<T>):Array<T>;

+ 4 - 0
tests/RunTravis.hx

@@ -106,6 +106,10 @@ class RunTravis {
 				runCommand("sudo", ["apt-get", "install", "php5", "-y"], true);
 				runCommand("haxe", ["compile-php.hxml"]);
 				runCommand("php", ["php/index.php"]);
+			case "python":
+				runCommand("sudo", ["apt-get", "install", "python3", "-y"], true);
+				runCommand("haxe", ["compile-python.hxml"]);
+				runCommand("python3", ["unit.py"]);
 			case "cpp":
 				//hxcpp dependencies
 				runCommand("sudo", ["apt-get", "install", "gcc-multilib", "g++-multilib", "-y"], true);

+ 1 - 1
tests/unit/Test.hx

@@ -204,7 +204,7 @@ class Test #if swf_mark implements mt.Protect #end {
 	}
 
 	static function resetTimer() {
-		#if (neko || php || cpp || java || cs)
+		#if (neko || php || cpp || java || cs || python)
 		#else
 		if( timer != null ) timer.stop();
 		timer = new haxe.Timer(10000);

+ 4 - 1
tests/unit/TestMisc.hx

@@ -151,8 +151,11 @@ class TestMisc extends Test {
 		var o = { add : c.add };
 		eq( o.add(1,2), 103 );
 		eq( o.add, o.add ); // we shouldn't create a new closure here
-
+		#if python 
+		var o = { cos : function (x) return Math.cos(x) };
+		#else
 		var o = { cos : Math.cos };
+		#end
 		eq( o.cos(0), 1. );
 
 		// check enum

+ 3 - 0
tests/unit/compile-python.hxml

@@ -0,0 +1,3 @@
+compile-each.hxml
+unit.Test
+-python unit.py

+ 16 - 0
tests/unit/issues/Issue2750.hx → tests/unit/issues/Issue2750.hx.disabled

@@ -9,6 +9,12 @@ private class Parent extends Test {
 	function foo() {
 		return 1;
 	}
+	function bind() {
+		return 1;
+	}
+	function match() {
+		return 1;
+	}
 }
 
 class Issue2750 extends Parent {
@@ -19,6 +25,8 @@ class Issue2750 extends Parent {
     public function new() {
         super();
 		eq(3, foo());
+		eq(3, bind());
+		eq(3, match());
 		call(this);
 		t(unit.TestType.typeError(var x = super));
 		t(unit.TestType.typeError(call(super)));
@@ -29,6 +37,14 @@ class Issue2750 extends Parent {
 	override function foo() {
 		return 2 + super.foo();
 	}
+
+	override function bind() {
+		return 2 + super.bind();
+	}
+
+	override function match() {
+		return 2 + super.match();
+	}
 	
 	function call(c:Parent) { }
 }

+ 18 - 0
tests/unit/issues/Issue2766.hx

@@ -0,0 +1,18 @@
+package unit.issues;
+import unit.Test;
+
+private class Foo {
+    public var foo = "foo";
+    public function new () {}
+}
+
+class Issue2766 extends Test {
+
+	function test() {
+		eq("foo", getValue());
+	}
+	
+    macro static function getValue() {
+        return macro $v{new Foo().foo};
+    }
+}

+ 10 - 3
typeload.ml

@@ -77,7 +77,7 @@ let make_module ctx mpath file tdecls loadp =
 				e_constrs = PMap.empty;
 				e_names = [];
 				e_type = {
-					t_path = fst path, "Enum<" ^ (snd path) ^ ">";
+					t_path = [], "Enum<" ^ (s_type_path path) ^ ">";
 					t_module = m;
 					t_doc = None;
 					t_pos = p;
@@ -1849,8 +1849,15 @@ let init_class ctx c p context_init herits fields =
 						| (Meta.Op,[EBinop(op,_,_),_],_) :: _ ->
 							if is_macro then error "Macro operator functions are not supported" p;
 							let targ = if Meta.has Meta.Impl f.cff_meta then tthis else ta in
-							let left_eq = type_iseq t (tfun [targ;m] (mk_mono())) in
-							let right_eq = type_iseq t (tfun [mk_mono();targ] (mk_mono())) in
+							let left_eq,right_eq = match follow t with
+								| TFun([(_,_,t1);(_,_,t2)],_) ->
+									type_iseq targ t1,type_iseq targ t2
+								| _ ->
+									if Meta.has Meta.Impl cf.cf_meta then
+										error "Member @:op functions must accept exactly one argument" cf.cf_pos
+									else
+										error "Static @:op functions must accept exactly two arguments" cf.cf_pos
+							in
 							if not (left_eq || right_eq) then error ("The left or right argument type must be " ^ (s_type (print_context()) targ)) f.cff_pos;
 							if right_eq && Meta.has Meta.Commutative f.cff_meta then error ("@:commutative is only allowed if the right argument is not " ^ (s_type (print_context()) targ)) f.cff_pos;
 							a.a_ops <- (op,cf) :: a.a_ops;

+ 23 - 8
typer.ml

@@ -617,7 +617,7 @@ let rec type_module_type ctx t tparams p =
 	match t with
 	| TClassDecl c ->
 		let t_tmp = {
-			t_path = fst c.cl_path, "Class<" ^ (snd c.cl_path) ^ ">" ;
+			t_path = [],"Class<" ^ (s_type_path c.cl_path) ^ ">" ;
 			t_module = c.cl_module;
 			t_doc = None;
 			t_pos = c.cl_pos;
@@ -649,7 +649,7 @@ let rec type_module_type ctx t tparams p =
 	| TAbstractDecl a ->
 		if not (Meta.has Meta.RuntimeValue a.a_meta) then error (s_type_path a.a_path ^ " is not a value") p;
 		let t_tmp = {
-			t_path = fst a.a_path, "Abstract<" ^ (snd a.a_path) ^ ">";
+			t_path = [],"Abstract<" ^ (s_type_path a.a_path) ^ ">";
 			t_module = a.a_module;
 			t_doc = None;
 			t_pos = a.a_pos;
@@ -1132,16 +1132,16 @@ and type_field ?(resume=false) ctx e i p mode =
 				| MCall,Var {v_read = AccCall } ->
 					()
 				| MCall, Var _ ->
-					error "Cannot access superclass variable for calling: needs to be a proper method" p
+					display_error ctx "Cannot access superclass variable for calling: needs to be a proper method" p
 				| MCall, _ ->
 					()
 				| MGet,Var _
 				| MSet,Var _ when (match c2 with Some { cl_extern = true; cl_path = ("flash" :: _,_) } -> true | _ -> false) ->
 					()
 				| _, Method _ ->
-					error "Cannot create closure on super method" p
+					display_error ctx "Cannot create closure on super method" p
 				| _ ->
-					error "Normal variables cannot be accessed with 'super', use 'this' instead" p);
+					display_error ctx "Normal variables cannot be accessed with 'super', use 'this' instead" p);
 			if not (can_access ctx c f false) && not ctx.untyped then display_error ctx ("Cannot access private field " ^ i) p;
 			field_access ctx mode f (match c2 with None -> FAnon f | Some c -> FInstance (c,f)) (apply_params c.cl_types params t) e p
 		with Not_found -> try
@@ -2401,7 +2401,8 @@ and type_expr ctx (e,p) (with_type:with_type) =
 	| EField(_,n) when n.[0] = '$' ->
 		error "Field names starting with $ are not allowed" p
 	| EConst (Ident s) ->
-		if s = "super" && with_type <> NoValue then error "Cannot use super as value" p;
+		(* TODO: let's deal with this later *)
+		(* if s = "super" && with_type <> NoValue then error "Cannot use super as value" p; *)
 		(try
 			acc_get ctx (type_ident_raise ~imported_enums:false ctx s p MGet) p
 		with Not_found -> try
@@ -3059,7 +3060,13 @@ and type_expr ctx (e,p) (with_type:with_type) =
 		let old = ctx.in_display in
 		let opt_args args ret = TFun(List.map(fun (n,o,t) -> n,true,t) args,ret) in
 		ctx.in_display <- true;
-		let e = (try type_expr ctx e Value with Error (Unknown_ident n,_) -> raise (Parser.TypePath ([n],None))) in
+		let e = try
+			type_expr ctx e Value
+		with Error (Unknown_ident n,_) when not iscall ->
+			raise (Parser.TypePath ([n],None))
+		| Error (Unknown_ident "trace",_) ->
+			raise (DisplayTypes [tfun [t_dynamic] ctx.com.basic.tvoid])
+		in
 		let e = match e.eexpr with
 			| TField (e1,fa) ->
 				if field_name fa = "bind" then (match follow e1.etype with
@@ -3307,6 +3314,8 @@ and type_call ctx e el (with_type:with_type) p =
 			display_error ctx "callback syntax has changed to func.bind(args)" p;
 			let e = type_expr ctx e Value in
 			type_bind ctx e args p)
+	| (EField ((EConst (Ident "super"),_),_),_), _ ->
+		def()
 	| (EField (e,"bind"),p), args ->
 		let e = type_expr ctx e Value in
 		(match follow e.etype with
@@ -3983,7 +3992,13 @@ and flush_macro_context mint ctx =
 		mint
 	end else mint in
 	(* we should maybe ensure that all filters in Main are applied. Not urgent atm *)
-	(try Interp.add_types mint types (Filters.post_process mctx [Codegen.Abstract.handle_abstract_casts mctx; Filters.captured_vars mctx.com; Filters.rename_local_vars mctx.com])
+	let expr_filters = [Codegen.Abstract.handle_abstract_casts mctx; Filters.captured_vars mctx.com; Filters.rename_local_vars mctx.com] in
+	let type_filters = [Filters.add_field_inits mctx] in
+	let ready = fun t ->
+		Filters.post_process mctx expr_filters t;
+		List.iter (fun f -> f t) type_filters
+	in
+	(try Interp.add_types mint types ready
 	with Error (e,p) -> raise (Fatal_error(error_msg e,p)));
 	Filters.post_process_end()