Class: Toml::Merge::SourcePreservingProvider

Inherits:
Object
  • Object
show all
Defined in:
lib/toml/merge/source_preserving_provider.rb,
sig/toml/merge.rbs

Overview

rubocop:disable Metrics/AbcSize, Metrics/ClassLength, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/ParameterLists, Metrics/PerceivedComplexity -- provider validation, planning, rendering, and verification form one safety boundary Backend-parameterized conservative source-preserving provider for top-level TOML mappings.

Direct Known Subclasses

Provider

Defined Under Namespace

Classes: Decision, Document, Entry

Constant Summary collapse

DEFAULT_PROFILE =
:source_preserving
DIALECTS =
%i[toml].freeze

Instance Method Summary collapse

Instance Method Details

#analyze(request) ⇒ Hash[Symbol, untyped]

Parameters:

  • request (Hash[Symbol, untyped])

Returns:

  • (Hash[Symbol, untyped])


61
62
63
64
65
66
67
68
69
70
71
# File 'lib/toml/merge/source_preserving_provider.rb', line 61

def analyze(request)
  document = analyze_role(:source, request.fetch(:source))
  return invalid_document_failure(:analyze, request, [document]) unless document.issues.empty?

  result(
    :analyze,
    request,
    analysis: analysis_payload(document),
    verification: { source_parsed: true, structurally_unambiguous: true }
  )
end

#backend_idString

Returns:

  • (String)


37
# File 'lib/toml/merge/source_preserving_provider.rb', line 37

def backend_id = backend_reference.id

#backend_referenceObject

Returns:

  • (Object)


36
# File 'lib/toml/merge/source_preserving_provider.rb', line 36

def backend_reference = self.class::BACKEND

#capabilitiesHash[Symbol, untyped]

Returns:

  • (Hash[Symbol, untyped])


42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/toml/merge/source_preserving_provider.rb', line 42

def capabilities
  {
    operations: Ast::Merge::ProviderContract::OPERATIONS,
    dialects: DIALECTS,
    backends: [backend_id.to_sym],
    profiles: [DEFAULT_PROFILE],
    role: role,
    source_preservation: %i[
      exact_source
      mapping_entry_fragments
      comment_ownership
      line_provenance
      reparse
      semantic_verification
      ast_attribute_verification
    ]
  }.freeze
end

#diff2(request) ⇒ Hash[Symbol, untyped]

Parameters:

  • request (Hash[Symbol, untyped])

Returns:

  • (Hash[Symbol, untyped])


73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/toml/merge/source_preserving_provider.rb', line 73

def diff2(request)
  before = analyze_role(:before, request.fetch(:before_source))
  after = analyze_role(:after, request.fetch(:after_source))
  unsafe = [before, after].reject { |document| document.issues.empty? }
  return invalid_document_failure(:diff2, request, unsafe) unless unsafe.empty?

  changes = mapping_changes(before, after)
  result(
    :diff2,
    request,
    diff: { before: analysis_payload(before), after: analysis_payload(after), changes: changes },
    changes: changes,
    verification: { before_parsed: true, after_parsed: true }
  )
end

#familyString

Returns:

  • (String)


35
# File 'lib/toml/merge/source_preserving_provider.rb', line 35

def family = 'toml'

#merge2(request) ⇒ Hash[Symbol, untyped]

Parameters:

  • request (Hash[Symbol, untyped])

Returns:

  • (Hash[Symbol, untyped])


89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/toml/merge/source_preserving_provider.rb', line 89

def merge2(request)
  documents = {
    incoming: analyze_role(:incoming, request.fetch(:incoming_source)),
    current: analyze_role(:current, request.fetch(:current_source))
  }
  unsafe = documents.values.reject { |document| document.issues.empty? }
  return invalid_document_failure(:merge2, request, unsafe) unless unsafe.empty?

  additions = documents[:incoming].entries.reject { |entry| documents[:current].by_key.key?(entry.key) }
  render_documents = { ours: documents[:current], theirs: documents[:incoming] }
  fragments = [whole_source_fragment(:ours, documents[:current].source)]
  fragments.concat(additions.map { |entry| entry_fragment(:theirs, entry) })
  rendered = render_plan(request, separated_fragments(fragments, render_documents))
  expected = [
    *documents[:current].entries.map { |entry| selected_entry(entry, :current) },
    *additions.map { |entry| selected_entry(entry, :incoming) }
  ]
  verification = verify_composite(rendered.content, expected)
  return verification_failure(:merge2, request, rendered, [], verification) unless verification[:semantic_match]

  result(
    :merge2,
    request,
    output: rendered.content,
    changes: mapping_changes(documents[:current], analyze_role(:output, rendered.content)),
    render_report: render_report(rendered, :exact_mapping_entry_composite),
    verification: verification
  )
end

#merge3(request) ⇒ Hash[Symbol, untyped]

Parameters:

  • request (Hash[Symbol, untyped])

Returns:

  • (Hash[Symbol, untyped])


119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/toml/merge/source_preserving_provider.rb', line 119

def merge3(request)
  documents = %i[base ours theirs].to_h do |role|
    [role, analyze_role(role, request.fetch(:"#{role}_source"))]
  end
  exact_role = exact_revision_role(documents)
  return render_exact(request, documents, exact_role) if exact_role

  unsafe = documents.values.reject { |document| document.issues.empty? }
  return structural_conflict(request, documents, unsafe) unless unsafe.empty?
  return unmanaged_conflict(request, documents) unless unmanaged_unchanged?(documents)

  decisions = three_way_decisions(documents)
  conflicts = decisions.select(&:conflict)
  return render_conflicts(request, documents, decisions, conflicts) unless conflicts.empty?

  render_composite(request, documents, decisions)
end

#package_nameString

Returns:

  • (String)


38
# File 'lib/toml/merge/source_preserving_provider.rb', line 38

def package_name = self.class::PACKAGE_NAME

#package_versionString

Returns:

  • (String)


39
# File 'lib/toml/merge/source_preserving_provider.rb', line 39

def package_version = self.class::PACKAGE_VERSION

#provider_idString

Returns:

  • (String)


34
# File 'lib/toml/merge/source_preserving_provider.rb', line 34

def provider_id = self.class::PROVIDER_ID

#roleSymbol

Returns:

  • (Symbol)


40
# File 'lib/toml/merge/source_preserving_provider.rb', line 40

def role = self.class.const_defined?(:ROLE, false) ? self.class::ROLE : :backend