Skip to content
Open
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
13 changes: 7 additions & 6 deletions src/typing/fields.ml
Original file line number Diff line number Diff line change
Expand Up @@ -655,25 +655,25 @@ let get_struct_init_anon_fields c tl =
| TFun (args,_) ->
Some (match cf.cf_expr with
| Some { eexpr = TFunction fn } ->
List.map (fun (name,_,t) ->
List.map (fun (name,opt,t) ->
let t = apply_params c.cl_params tl t in
let p = try
let v,_ = List.find (fun (v,_) -> v.v_name = name) fn.tf_args in
v.v_pos
with Not_found ->
cf.cf_name_pos
in
name,t,p,extract_param_info name
name,opt,t,p,extract_param_info name
) args
| _ ->
List.map
(fun (name,_,t) ->
(fun (name,opt,t) ->
let t = apply_params c.cl_params tl t in
try
let cf = PMap.find name c.cl_fields in
name,t,cf.cf_name_pos,gen_doc_text_opt cf.cf_doc
name,opt,t,cf.cf_name_pos,gen_doc_text_opt cf.cf_doc
with Not_found ->
name,t,cf.cf_name_pos,extract_param_info name
name,opt,t,cf.cf_name_pos,extract_param_info name
) args
)
| _ -> None
Expand All @@ -682,8 +682,9 @@ let get_struct_init_anon_fields c tl =
in
match args with
| Some args ->
List.fold_left (fun fields (name,t,p,doc) ->
List.fold_left (fun fields (name,opt,t,p,doc) ->
let cf = mk_field name t p p in
if opt then cf.cf_meta <- [(Meta.Optional,[],null_pos)];
cf.cf_doc <- (doc_from_string_opt doc);
PMap.add cf.cf_name cf fields
) PMap.empty args
Expand Down
4 changes: 4 additions & 0 deletions src/typing/typer.ml
Original file line number Diff line number Diff line change
Expand Up @@ -786,6 +786,10 @@ and type_object_decl ctx fl with_type p =
let fields = List.fold_left (fun acc ((n,opt,t),parg) ->
let f = mk_field n t parg parg in
if opt then f.cf_meta <- [(Meta.Optional,[],null_pos)];
(try
let cf = PMap.find n c.cl_fields in
f.cf_doc <- cf.cf_doc
with Not_found -> ());
PMap.add n f acc
) PMap.empty args in
let t,fl = type_fields fields in
Expand Down
133 changes: 133 additions & 0 deletions tests/server/src/cases/display/StructInit.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
package cases.display;

class StructInit extends DisplayTestCase {
/**
@:structInit
class Foo {
var a:Int = null;
var b:Int;
}
class Main {
static function main() {
var foo:Foo = {{-1-}
}
}
**/
function testRequiredAndOptionalFields(_) {
final fields = fields(1);
eq(true, hasField(fields, "a", "Null<Int>"));
eq(true, hasField(fields, "b", "Int"));
}

/**
@:structInit
class Foo {
var a:Int = null;
var b:Int;
}
typedef Foo2 = {
?a:Int,
b:Int,
}
class Main {
static function main() {
var foo:Foo = {{-1-}}
var foo2:Foo2 = {{-2-}
}
}
**/
function testStructInitVsTypedef() {
// structInit: optional (a) and required (b) both present
final classFields = fields(1);
eq(true, hasField(classFields, "a", "Null<Int>"));
eq(true, hasField(classFields, "b", "Int"));
// typedef: same fields also present
final typedefFields = fields(2);
eq(true, hasField(typedefFields, "a", "Null<Int>"));
eq(true, hasField(typedefFields, "b", "Int"));
}

/**
@:structInit
class Doc {
/** doctor doc **\/
public var doctor:Int;
}
class Main {
static function main() {
final v:Doc = {
doc{-1-}tor: 1
};
}
}
**/
function testFieldHoverDoc() {
eq("doctor doc", doc(1));
}

/**
@:structInit
class MultiDoc {
/** field a **\/
public var a:Int;
/** field b **\/
public var b:String;
}
class Main {
static function main() {
var v:MultiDoc = {
a{-1-}: 1,
b{-2-}: "x"
};
}
}
**/
function testMultiFieldHoverDoc() {
eq("field a", doc(1));
eq("field b", doc(2));
}

/**
@:structInit
class Foo {
var b:Int;
var a:Int;
var z:Int;
var d:Int;
}
class Main {
static function main() {
var foo:Foo = {{-1-}};
}
}
**/
function testFieldDeclarationOrder() {
final fields = fields(1);
eq(4, fields.length);
eq(true, isField(fields[0], "b", "Int"));
eq(true, isField(fields[1], "a", "Int"));
eq(true, isField(fields[2], "z", "Int"));
eq(true, isField(fields[3], "d", "Int"));
}

/**
@:structInit
class Ordered {
var first:Int;
var second:String;
var third:Bool;
}
class Main {
static function main() {
var v:Ordered = {{-1-}};
}
}
**/
function testFieldDeclarationOrderMoreTypes() {
final fields = fields(1);
eq(3, fields.length);
eq(true, isField(fields[0], "first", "Int"));
eq(true, isField(fields[1], "second", "String"));
eq(true, isField(fields[2], "third", "Bool"));
}
}
Loading