Integrate history prefixes into load handoffs
This commit is contained in:
@@ -10,6 +10,7 @@ type postDecodeOverrideContext struct {
|
||||
preCLIOrigins map[string]Origin
|
||||
decoded decodedConfiguration
|
||||
metadata Metadata
|
||||
historyBuilder *historyBuilder
|
||||
resolution resolutionInput
|
||||
applications []historyApplication
|
||||
postDecodeApps []historyApplication
|
||||
@@ -60,6 +61,7 @@ func preparePostDecodeOverrideContext(input assembledInput, before decodedConfig
|
||||
appendPostDecodeCLIHistory(&metadata, cliRecords, postDecodeApps, before.final)
|
||||
}
|
||||
metadata.historyBuilder.observePostCLICheckpoint(after.final, after.origins)
|
||||
metadata.historyBuilder.prefixReady = true
|
||||
|
||||
sources := cloneSourceInfos(input.sources)
|
||||
knownSources := make(map[string]bool, len(sources)+len(assigned.overrides))
|
||||
@@ -85,6 +87,7 @@ func preparePostDecodeOverrideContext(input assembledInput, before decodedConfig
|
||||
preCLIOrigins: cloneOrigins(before.origins),
|
||||
decoded: after,
|
||||
metadata: metadata,
|
||||
historyBuilder: metadata.historyBuilder,
|
||||
resolution: resolution,
|
||||
applications: applications,
|
||||
postDecodeApps: postDecodeApps,
|
||||
@@ -197,13 +200,12 @@ func documentWithMetadataLocations(root *document.Node, metadata Metadata, fallb
|
||||
if lookup == nil {
|
||||
lookup = buildDocumentLookup(fallbackRoot)
|
||||
}
|
||||
return nearestDocumentLocationWithLookup(fallbackRoot, path, lookup)
|
||||
return nearestConcreteDocumentLocationWithLookup(fallbackRoot, path, lookup)
|
||||
}
|
||||
var visit func(*document.Node, Path)
|
||||
visit = func(node *document.Node, path Path) {
|
||||
pointer := path.String()
|
||||
if info, exists := metadata.fields[pointer]; exists {
|
||||
if location, ok := metadataFieldLocation(metadata, pointer, info.Origin); ok {
|
||||
if info, exists := metadata.effectiveField(path); exists {
|
||||
if location, ok := metadataFieldLocation(metadata, path, info.Origin); ok {
|
||||
node.Location = location
|
||||
} else if location, ok := fallbackLocation(path); ok {
|
||||
node.Location = location
|
||||
@@ -216,8 +218,8 @@ func documentWithMetadataLocations(root *document.Node, metadata Metadata, fallb
|
||||
for index := range node.Mapping {
|
||||
entry := &node.Mapping[index]
|
||||
childPath := path.Key(entry.Key)
|
||||
if info, exists := metadata.fields[childPath.String()]; exists {
|
||||
if location, ok := metadataFieldLocation(metadata, childPath.String(), info.Origin); ok {
|
||||
if info, exists := metadata.effectiveField(childPath); exists {
|
||||
if location, ok := metadataFieldLocation(metadata, childPath, info.Origin); ok {
|
||||
entry.KeyLocation = location
|
||||
entry.ValueLocation = location
|
||||
} else if location, ok := fallbackLocation(childPath); ok {
|
||||
@@ -240,19 +242,57 @@ func documentWithMetadataLocations(root *document.Node, metadata Metadata, fallb
|
||||
return located
|
||||
}
|
||||
|
||||
func metadataFieldLocation(metadata Metadata, pointer string, origin Origin) (document.Location, bool) {
|
||||
func nearestConcreteDocumentLocationWithLookup(root *document.Node, path Path, lookup *documentLookup) (document.Location, bool) {
|
||||
if root == nil || !path.valid() {
|
||||
return document.Location{}, false
|
||||
}
|
||||
current := root
|
||||
nearest := current.Location
|
||||
for _, segment := range path.segments {
|
||||
switch current.Kind {
|
||||
case document.Mapping:
|
||||
if segment.kind != pathSegmentKey {
|
||||
return nearest, locationKnown(nearest)
|
||||
}
|
||||
position := -1
|
||||
if lookup != nil {
|
||||
position = lookup.find(current, segment.key)
|
||||
} else {
|
||||
for index, entry := range current.Mapping {
|
||||
if entry.Key == segment.key {
|
||||
position = index
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if position < 0 || position >= len(current.Mapping) {
|
||||
return nearest, locationKnown(nearest)
|
||||
}
|
||||
current = current.Mapping[position].Value
|
||||
case document.Sequence:
|
||||
if segment.kind != pathSegmentIndex || segment.index < 0 || segment.index >= len(current.Sequence) {
|
||||
return nearest, locationKnown(nearest)
|
||||
}
|
||||
current = current.Sequence[segment.index]
|
||||
default:
|
||||
return nearest, locationKnown(nearest)
|
||||
}
|
||||
if current == nil {
|
||||
return nearest, locationKnown(nearest)
|
||||
}
|
||||
nearest = current.Location
|
||||
}
|
||||
return nearest, locationKnown(nearest)
|
||||
}
|
||||
|
||||
func metadataFieldLocation(metadata Metadata, path Path, origin Origin) (document.Location, bool) {
|
||||
if location, ok := latestOriginDocumentLocation(origin); ok {
|
||||
return location, true
|
||||
}
|
||||
for index := len(metadata.history[pointer]) - 1; index >= 0; index-- {
|
||||
change := metadata.history[pointer][index]
|
||||
if location, ok := latestOriginDocumentLocation(change.Origin); ok {
|
||||
return location, true
|
||||
}
|
||||
for prior := len(change.Previous) - 1; prior >= 0; prior-- {
|
||||
if location, ok := latestOriginDocumentLocation(change.Previous[prior]); ok {
|
||||
return location, true
|
||||
}
|
||||
if model := metadata.currentHistoryModel(); model != nil {
|
||||
location, ok := model.latestHistoricalLocation(path)
|
||||
if ok {
|
||||
return document.Location{SourceID: location.SourceID, Line: location.Line, Column: location.Column}, true
|
||||
}
|
||||
}
|
||||
return document.Location{}, false
|
||||
|
||||
Reference in New Issue
Block a user