Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[hl] Fix interface override function resolution #11723

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions src/generators/genhl.ml
Original file line number Diff line number Diff line change
Expand Up @@ -570,10 +570,17 @@ and class_type ?(tref=None) ctx c pl statics =
let t = HVirtual vp in
ctx.cached_types <- PMap.add key_path t ctx.cached_types;
let rec loop c =
let fields = List.fold_left (fun acc (i,_) -> loop i @ acc) [] c.cl_implements in
PMap.fold (fun cf acc -> cfield_type ctx cf :: acc) c.cl_fields fields
let rec concat_uniq fields pfields =
match pfields with
| (n,_,_) as pf::pfl -> if List.exists (fun (n1,_,_) -> n1 = n) fields then concat_uniq fields pfl else concat_uniq (pf::fields) pfl
| [] -> fields
in
let pfields = List.fold_left (fun acc (i,_) -> loop i @ acc) [] c.cl_implements in
let fields = PMap.fold (fun cf acc -> cfield_type ctx cf :: acc) c.cl_fields [] in
concat_uniq fields pfields
in
let fields = loop c in
let fields = List.sort (fun (n1,_,_) (n2,_,_) -> compare n1 n2) fields in
vp.vfields <- Array.of_list fields;
Array.iteri (fun i (n,_,_) -> vp.vindex <- PMap.add n i vp.vindex) vp.vfields;
t
Expand Down
115 changes: 115 additions & 0 deletions tests/unit/src/unit/issues/Issue11723.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
package unit.issues;

@:keep
private interface IEntity {
var id:Int;
function getVariable(varName:String):IVariable;
function containsVariable(varName:String):Bool;
}

@:keep
private interface IUser extends IEntity {
var id:Int;
var name:String;
function getVariable(name:String):IUserVariable;
function setVariable(userVariable:IUserVariable):Void;
}

private class BasicUser implements IUser {
public var id:Int;
public var name:String;

private var _variables:haxe.ds.StringMap<IUserVariable>;

public function new(id:Int, name:String) {
this.id = id;
this.name = name;
_variables = new haxe.ds.StringMap();
}

public function getVariable(name:String):IUserVariable {
var get = _variables.get(name);
return cast(get, IUserVariable);
}

public function containsVariable(name:String):Bool {
var get = _variables.get(name);
return get != null;
}

public function setVariable(userVariable:IUserVariable):Void {
if (userVariable != null) {
_variables.set(userVariable.name, userVariable);
}
}
}

@:keep
private interface IVariable {
var name:String;
var type:String;
function getValue():Dynamic;
function getIntValue():Int;
function getStringValue():String;
}

@:keep
private interface IUserVariable extends IVariable {
var isPrivate:Bool;
}

private class BaseVariable implements IVariable {
public var name:String;
public var type:String;

private var _value:Any;

public function new(name:String, value:Any, type:String) {
this.name = name;
this.type = type;
_value = value;
}

public function getValue():Dynamic {
return _value;
}

public function getIntValue():Int {
return cast(_value, Int);
}

public function getStringValue():String {
return cast(_value, String);
}
}

private class BasicUserVariable extends BaseVariable implements IUserVariable {
public var isPrivate:Bool;

public function new(name:String, value:Any, type:String) {
super(name, value, type);
}
}

class Issue11723 extends Test {
public function test() {
var varname = "TestVar";
var myVariable = new BasicUserVariable(varname, "Testvalue", "String");
eq("Testvalue", myVariable.getStringValue());

var myUser = new BasicUser(1, "myUser");
myUser.setVariable(myVariable);
var formUser = myUser.getVariable(varname);
eq("Testvalue", formUser.getStringValue());

var bareEntity:IEntity = myUser;
var fromBareEntity = bareEntity.getVariable(varname);
eq("Testvalue", fromBareEntity.getStringValue());
t(bareEntity.containsVariable(varname));

var bareUser:IUser = myUser;
var fromBareUser = bareUser.getVariable(varname);
eq("Testvalue", fromBareUser.getStringValue());
t(bareUser.containsVariable(varname));
}
}
Loading