{
name: 'TestA',
doc: '',
meta: [],
params: [],
flags: [],
data: {
_hx_index: 2,
fields: [
{
name: 'foo',
meta: [],
access: [],
doc: null,
kind: {
_hx_index: 0,
t: {
_hx_index: 0,
p: { pack: [], name: 'String', params: [], sub: null },
__enum__: 'haxe.macro.ComplexType',
toString: [Function: $estr]
},
e: null,
__enum__: 'haxe.macro.FieldType',
toString: [Function: $estr]
},
pos: { file: '<null>', min: 34, max: 45 }
},
{
name: 'bar',
meta: [
{
name: ':optional',
params: [],
pos: { file: '<null>', min: 48, max: 51 }
}
],
access: [],
doc: null,
kind: {
_hx_index: 0,
t: {
_hx_index: 0,
p: {
pack: [],
name: 'Null',
sub: null,
params: [
{
_hx_index: 0,
t: {
_hx_index: 0,
p: { pack: [], name: 'Int', params: [], sub: null },
__enum__: 'haxe.macro.ComplexType',
toString: [Function: $estr]
},
__enum__: 'haxe.macro.TypeParam',
toString: [Function: $estr]
}
]
},
__enum__: 'haxe.macro.ComplexType',
toString: [Function: $estr]
},
e: null,
__enum__: 'haxe.macro.FieldType',
toString: [Function: $estr]
},
pos: { file: '<null>', min: 48, max: 56 }
},
{
name: 'baz',
meta: [
{
name: ':optional',
params: [],
pos: { file: '<null>', min: 59, max: 62 }
}
],
access: [],
doc: null,
kind: {
_hx_index: 0,
t: {
_hx_index: 0,
p: {
pack: [],
name: 'Null',
sub: null,
params: [
{
_hx_index: 0,
t: {
_hx_index: 0,
p: { pack: [], name: 'Bool', params: [], sub: null },
__enum__: 'haxe.macro.ComplexType',
toString: [Function: $estr]
},
__enum__: 'haxe.macro.TypeParam',
toString: [Function: $estr]
}
]
},
__enum__: 'haxe.macro.ComplexType',
toString: [Function: $estr]
},
e: null,
__enum__: 'haxe.macro.FieldType',
toString: [Function: $estr]
},
pos: { file: '<null>', min: 59, max: 69 }
}
],
__enum__: 'haxe.macro.ComplexType',
toString: [Function: $estr]
}
}
Description
I have a test file with two typedefs, one using object notation and one using class notation. When parsing that file the resulting data is inconsistent in retaining information about optional fields depending on which notation was used. Object notation works fine, class notation is misbehaving.
Current result
TestA gets parsed as (code snippet under fold)
{ name: 'TestA', doc: '', meta: [], params: [], flags: [], data: { _hx_index: 2, fields: [ { name: 'foo', meta: [], access: [], doc: null, kind: { _hx_index: 0, t: { _hx_index: 0, p: { pack: [], name: 'String', params: [], sub: null }, __enum__: 'haxe.macro.ComplexType', toString: [Function: $estr] }, e: null, __enum__: 'haxe.macro.FieldType', toString: [Function: $estr] }, pos: { file: '<null>', min: 34, max: 45 } }, { name: 'bar', meta: [ { name: ':optional', params: [], pos: { file: '<null>', min: 48, max: 51 } } ], access: [], doc: null, kind: { _hx_index: 0, t: { _hx_index: 0, p: { pack: [], name: 'Null', sub: null, params: [ { _hx_index: 0, t: { _hx_index: 0, p: { pack: [], name: 'Int', params: [], sub: null }, __enum__: 'haxe.macro.ComplexType', toString: [Function: $estr] }, __enum__: 'haxe.macro.TypeParam', toString: [Function: $estr] } ] }, __enum__: 'haxe.macro.ComplexType', toString: [Function: $estr] }, e: null, __enum__: 'haxe.macro.FieldType', toString: [Function: $estr] }, pos: { file: '<null>', min: 48, max: 56 } }, { name: 'baz', meta: [ { name: ':optional', params: [], pos: { file: '<null>', min: 59, max: 62 } } ], access: [], doc: null, kind: { _hx_index: 0, t: { _hx_index: 0, p: { pack: [], name: 'Null', sub: null, params: [ { _hx_index: 0, t: { _hx_index: 0, p: { pack: [], name: 'Bool', params: [], sub: null }, __enum__: 'haxe.macro.ComplexType', toString: [Function: $estr] }, __enum__: 'haxe.macro.TypeParam', toString: [Function: $estr] } ] }, __enum__: 'haxe.macro.ComplexType', toString: [Function: $estr] }, e: null, __enum__: 'haxe.macro.FieldType', toString: [Function: $estr] }, pos: { file: '<null>', min: 59, max: 69 } } ], __enum__: 'haxe.macro.ComplexType', toString: [Function: $estr] } }TestB gets parsed as (code snippet under fold)
{ name: 'TestB', doc: '', meta: [], params: [], flags: [], data: { _hx_index: 2, fields: [ { name: 'foo', doc: '', meta: [], access: [], pos: { file: '<null>', min: 90, max: 105 }, kind: { _hx_index: 0, t: { _hx_index: 0, p: { pack: [], name: 'String', params: [], sub: null }, __enum__: 'haxe.macro.ComplexType', toString: [Function: $estr] }, e: null, __enum__: 'haxe.macro.FieldType', toString: [Function: $estr] } }, { name: 'bar', doc: '', meta: [], access: [], pos: { file: '<null>', min: 107, max: 120 }, kind: { _hx_index: 0, t: { _hx_index: 0, p: { pack: [], name: 'Int', params: [], sub: null }, __enum__: 'haxe.macro.ComplexType', toString: [Function: $estr] }, e: null, __enum__: 'haxe.macro.FieldType', toString: [Function: $estr] } }, { name: 'baz', doc: '', meta: [ { name: ':optional', params: [], pos: { file: '<null>', min: 123, max: 132 } } ], access: [], pos: { file: '<null>', min: 133, max: 146 }, kind: { _hx_index: 0, t: { _hx_index: 0, p: { pack: [], name: 'Bool', params: [], sub: null }, __enum__: 'haxe.macro.ComplexType', toString: [Function: $estr] }, e: null, __enum__: 'haxe.macro.FieldType', toString: [Function: $estr] } } ], __enum__: 'haxe.macro.ComplexType', toString: [Function: $estr] } }The parse data for
TestAcontains the expected:optionalmetadata for the optional fields, and their respective types come down toNull<X>which was a bit surprising for me at that moment but is still fine.However, the parse data for
TestB::bardoes not contain any information about it being optional (no typing asNull<Int>, no:optionalentry inmeta), which afaics makes it impossible to know whether that field was optional or not. Additionally,TestB::bazis not the same type asTestA::baz(BoolvsNull<Bool>) despite carrying the:optionalmetadata.Using the
?to indicate optional fields should be valid in class notation according to the documentation.Expected result
Information about fields being optional should be retained regardless of notation used. Also, the data should follow a consistent pattern: if optional fields are typed as
Null<X>in one notation then they should also be typed as such when using the other notation.