@@ -97,7 +97,16 @@ func (x *exporter) mergeValues(label adt.Feature, src *adt.Vertex, a []conjunct,
97
97
for _ , c := range a {
98
98
e .top ().upCount = c .up
99
99
x := c .c .Expr ()
100
- e .addExpr (c .c .Env , x , false )
100
+ e .addExpr (c .c .Env , src , x , false )
101
+ }
102
+
103
+ if src != nil {
104
+ for _ , a := range src .Arcs {
105
+ if x , ok := e .fields [a .Label ]; ok {
106
+ x .arc = a
107
+ e .fields [a .Label ] = x
108
+ }
109
+ }
101
110
}
102
111
103
112
s := x .top ().scope
@@ -107,9 +116,9 @@ func (x *exporter) mergeValues(label adt.Feature, src *adt.Vertex, a []conjunct,
107
116
}
108
117
109
118
// Unify values only for one level.
110
- if len ( e .values .Conjuncts ) > 0 {
119
+ if a := e .values .Conjuncts ; len ( a ) > 0 {
111
120
e .values .Finalize (e .ctx )
112
- e .embed = append (e .embed , e .value (e .values , e . values . Conjuncts ... ))
121
+ e .embed = append (e .embed , e .value (e .values , a ... ))
113
122
}
114
123
115
124
// Collect and order set of fields.
@@ -196,7 +205,7 @@ func (x *exporter) mergeValues(label adt.Feature, src *adt.Vertex, a []conjunct,
196
205
top .fields [f ] = fr
197
206
}
198
207
199
- d .Value = e .mergeValues (f , nil , c , a ... )
208
+ d .Value = e .mergeValues (f , field . arc , c , a ... )
200
209
201
210
if f .IsDef () {
202
211
x .inDefinition --
@@ -218,10 +227,13 @@ func (x *exporter) mergeValues(label adt.Feature, src *adt.Vertex, a []conjunct,
218
227
}
219
228
if e .hasEllipsis {
220
229
s .Elts = append (s .Elts , & ast.Ellipsis {})
221
- } else if src != nil && src .IsClosedStruct () && e .inDefinition == 0 {
222
- return ast .NewCall (ast .NewIdent ("close" ), s )
223
230
}
224
231
232
+ // TODO: why was this necessary?
233
+ // else if src != nil && src.IsClosedStruct() && e.inDefinition == 0 {
234
+ // return ast.NewCall(ast.NewIdent("close"), s)
235
+ // }
236
+
225
237
e .conjuncts = append (e .conjuncts , s )
226
238
227
239
return ast .NewBinExpr (token .AND , e .conjuncts ... )
@@ -240,8 +252,16 @@ type conjuncts struct {
240
252
hasEllipsis bool
241
253
}
242
254
243
- func (c * conjuncts ) addConjunct (f adt.Feature , env * adt.Environment , n adt.Node ) {
255
+ func (c * conjuncts ) addValueConjunct (src * adt.Vertex , env * adt.Environment , x adt.Expr ) {
256
+ switch b , ok := x .(adt.BaseValue ); {
257
+ case ok && src != nil && isTop (b ) && ! isTop (src .BaseValue ):
258
+ // drop top
259
+ default :
260
+ c .values .AddConjunct (adt .MakeRootConjunct (env , x ))
261
+ }
262
+ }
244
263
264
+ func (c * conjuncts ) addConjunct (f adt.Feature , env * adt.Environment , n adt.Node ) {
245
265
x := c .fields [f ]
246
266
v := adt .MakeRootConjunct (env , n )
247
267
x .conjuncts = append (x .conjuncts , conjunct {
@@ -254,6 +274,7 @@ func (c *conjuncts) addConjunct(f adt.Feature, env *adt.Environment, n adt.Node)
254
274
255
275
type field struct {
256
276
docs []* ast.CommentGroup
277
+ arc * adt.Vertex
257
278
conjuncts []conjunct
258
279
}
259
280
@@ -262,7 +283,7 @@ type conjunct struct {
262
283
up int32
263
284
}
264
285
265
- func (e * conjuncts ) addExpr (env * adt.Environment , x adt.Expr , isEmbed bool ) {
286
+ func (e * conjuncts ) addExpr (env * adt.Environment , src * adt. Vertex , x adt.Expr , isEmbed bool ) {
266
287
switch x := x .(type ) {
267
288
case * adt.StructLit :
268
289
e .top ().upCount ++
@@ -294,7 +315,7 @@ func (e *conjuncts) addExpr(env *adt.Environment, x adt.Expr, isEmbed bool) {
294
315
e .hasEllipsis = true
295
316
continue
296
317
case adt.Expr :
297
- e .addExpr (env , f , true )
318
+ e .addExpr (env , nil , f , true )
298
319
continue
299
320
300
321
// TODO: also handle dynamic fields
@@ -309,54 +330,44 @@ func (e *conjuncts) addExpr(env *adt.Environment, x adt.Expr, isEmbed bool) {
309
330
switch v := x .(type ) {
310
331
case nil :
311
332
default :
312
- e .values . AddConjunct ( adt . MakeRootConjunct ( env , x )) // GOBBLE TOP
333
+ e .addValueConjunct ( src , env , x )
313
334
314
335
case * adt.Vertex :
315
- e .structs = append (e .structs , v .Structs ... )
316
-
317
- switch y := v .BaseValue .(type ) {
318
- case * adt.ListMarker :
319
- a := []ast.Expr {}
320
- for _ , x := range v .Elems () {
321
- a = append (a , e .expr (x ))
336
+ if b , ok := v .BaseValue .(* adt.Bottom ); ok {
337
+ if ! b .IsIncomplete () || e .cfg .Final {
338
+ e .addExpr (env , v , b , false )
339
+ return
322
340
}
323
- if ! v .IsClosedList () {
324
- v := & adt.Vertex {}
325
- v .MatchAndInsert (e .ctx , v )
326
- a = append (a , & ast.Ellipsis {Type : e .expr (v )})
341
+ }
342
+
343
+ switch {
344
+ default :
345
+ for _ , c := range v .Conjuncts {
346
+ e .addExpr (c .Env , v , c .Expr (), false )
327
347
}
328
- e .embed = append (e .embed , ast .NewList (a ... ))
329
- return
330
348
331
- case * adt. StructMarker :
332
- x = nil
349
+ case v . IsData () :
350
+ e . structs = append ( e . structs , v . Structs ... )
333
351
334
- case adt.Value :
335
- if v .IsData () {
336
- e .values .AddConjunct (adt .MakeRootConjunct (env , y ))
337
- break
338
- }
339
- for _ , c := range v .Conjuncts {
340
- e .values .AddConjunct (c )
352
+ if y , ok := v .BaseValue .(adt.Value ); ok {
353
+ e .addValueConjunct (src , env , y )
341
354
}
342
- }
343
355
344
- // generated, only consider arcs.
345
- for _ , a := range v .Arcs {
346
- a .Finalize (e .ctx ) // TODO: should we do this?
356
+ for _ , a := range v .Arcs {
357
+ a .Finalize (e .ctx ) // TODO: should we do this?
347
358
348
- e .addConjunct (a .Label , env , a )
359
+ e .addConjunct (a .Label , env , a )
360
+ }
349
361
}
350
- // e.exprs = append(e.exprs, e.value(v, v.Conjuncts...))
351
362
}
352
363
353
364
case * adt.BinaryExpr :
354
365
switch {
355
366
case x .Op == adt .AndOp && ! isEmbed :
356
- e .addExpr (env , x .X , false )
357
- e .addExpr (env , x .Y , false )
367
+ e .addExpr (env , src , x .X , false )
368
+ e .addExpr (env , src , x .Y , false )
358
369
case isSelfContained (x ):
359
- e .values . AddConjunct ( adt . MakeRootConjunct ( env , x ) )
370
+ e .addValueConjunct ( src , env , x )
360
371
default :
361
372
if isEmbed {
362
373
e .embed = append (e .embed , e .expr (x ))
@@ -368,7 +379,7 @@ func (e *conjuncts) addExpr(env *adt.Environment, x adt.Expr, isEmbed bool) {
368
379
default :
369
380
switch {
370
381
case isSelfContained (x ):
371
- e .values . AddConjunct ( adt . MakeRootConjunct ( env , x ) )
382
+ e .addValueConjunct ( src , env , x )
372
383
case isEmbed :
373
384
e .embed = append (e .embed , e .expr (x ))
374
385
default :
@@ -377,6 +388,17 @@ func (e *conjuncts) addExpr(env *adt.Environment, x adt.Expr, isEmbed bool) {
377
388
}
378
389
}
379
390
391
+ func isTop (x adt.BaseValue ) bool {
392
+ switch v := x .(type ) {
393
+ case * adt.Top :
394
+ return true
395
+ case * adt.BasicType :
396
+ return v .K == adt .TopKind
397
+ default :
398
+ return false
399
+ }
400
+ }
401
+
380
402
// TODO: find a better way to annotate optionality. Maybe a special conjunct
381
403
// or store it in the field information?
382
404
func isOptional (a []adt.Conjunct ) bool {
0 commit comments