(spec Spec)
| 1384 | } |
| 1385 | |
| 1386 | func findLabelSpecs(spec Spec) []string { |
| 1387 | maxIdx := -1 |
| 1388 | var names map[int]string |
| 1389 | |
| 1390 | var visit visitFunc |
| 1391 | visit = func(s Spec) { |
| 1392 | if ls, ok := s.(*BlockLabelSpec); ok { |
| 1393 | if maxIdx < ls.Index { |
| 1394 | maxIdx = ls.Index |
| 1395 | } |
| 1396 | if names == nil { |
| 1397 | names = make(map[int]string) |
| 1398 | } |
| 1399 | names[ls.Index] = ls.Name |
| 1400 | } |
| 1401 | s.visitSameBodyChildren(visit) |
| 1402 | } |
| 1403 | |
| 1404 | visit(spec) |
| 1405 | |
| 1406 | if maxIdx < 0 { |
| 1407 | return nil // no labels at all |
| 1408 | } |
| 1409 | |
| 1410 | ret := make([]string, maxIdx+1) |
| 1411 | for i := range ret { |
| 1412 | name := names[i] |
| 1413 | if name == "" { |
| 1414 | // Should never happen if the spec is conformant, since we require |
| 1415 | // consecutive indices starting at zero. |
| 1416 | name = fmt.Sprintf("missing%02d", i) |
| 1417 | } |
| 1418 | ret[i] = name |
| 1419 | } |
| 1420 | |
| 1421 | return ret |
| 1422 | } |
| 1423 | |
| 1424 | // DefaultSpec is a spec that wraps two specs, evaluating the primary first |
| 1425 | // and then evaluating the default if the primary returns a null value. |
no test coverage detected