Module: Go::Merge

Extended by:
Merge
Included in:
Merge
Defined in:
lib/go/merge.rb,
lib/go/merge/version.rb

Defined Under Namespace

Modules: Version

Constant Summary collapse

PACKAGE_NAME =
"go-merge"
TREE_SITTER_BACKEND =
TreeHaver::KREUZBERG_LANGUAGE_PACK_BACKEND
DESTINATION_WINS_ARRAY_POLICY =
{ surface: "array", name: "destination_wins_array" }.freeze
VERSION =
Version::VERSION

Instance Method Summary collapse

Instance Method Details

#available_go_backendsObject



18
19
20
# File 'lib/go/merge.rb', line 18

def available_go_backends
  [TREE_SITTER_BACKEND]
end

#go_backend_feature_profile(backend: nil) ⇒ Object



22
23
24
25
26
27
28
29
30
31
# File 'lib/go/merge.rb', line 22

def go_backend_feature_profile(backend: nil)
  requested = backend.to_s.empty? ? TREE_SITTER_BACKEND.id : backend.to_s
  return unsupported_feature_result("Unsupported Go backend #{requested}.") unless requested == TREE_SITTER_BACKEND.id

  go_feature_profile.merge(
    backend: requested,
    backend_ref: TREE_SITTER_BACKEND.to_h,
    supports_dialects: true
  )
end

#go_feature_profileObject



14
15
16
# File 'lib/go/merge.rb', line 14

def go_feature_profile
  { family: "go", supported_dialects: ["go"], supported_policies: [DESTINATION_WINS_ARRAY_POLICY] }
end

#go_plan_context(backend: nil) ⇒ Object



33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/go/merge.rb', line 33

def go_plan_context(backend: nil)
  profile = go_backend_feature_profile(backend: backend)
  return profile if profile[:ok] == false

  {
    family_profile: go_feature_profile,
    feature_profile: {
      backend: profile[:backend],
      supports_dialects: true,
      supported_policies: profile[:supported_policies]
    }
  }
end

#match_go_owners(template, destination) ⇒ Object



55
56
57
58
59
60
61
62
63
# File 'lib/go/merge.rb', line 55

def match_go_owners(template, destination)
  destination_paths = destination[:owners].to_h { |owner| [owner[:path], true] }
  template_paths = template[:owners].to_h { |owner| [owner[:path], true] }
  {
    matched: template[:owners].filter { |owner| destination_paths[owner[:path]] }.map { |owner| { template_path: owner[:path], destination_path: owner[:path] } },
    unmatched_template: template[:owners].map { |owner| owner[:path] }.reject { |path| destination_paths[path] },
    unmatched_destination: destination[:owners].map { |owner| owner[:path] }.reject { |path| template_paths[path] }
  }
end

#merge_go(template_source, destination_source, dialect) ⇒ Object



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/go/merge.rb', line 65

def merge_go(template_source, destination_source, dialect)
  template = parse_go(template_source, dialect)
  return { ok: false, diagnostics: template[:diagnostics], policies: [] } unless template[:ok]
  destination = parse_go(destination_source, dialect)
  unless destination[:ok]
    return {
      ok: false,
      diagnostics: destination[:diagnostics].map { |diagnostic| diagnostic[:category] == "parse_error" ? diagnostic.merge(category: "destination_parse_error") : diagnostic },
      policies: []
    }
  end

  destination_declarations = destination.dig(:analysis, :declarations).to_h { |item| [item[:path], item] }
  merged_declaration_texts = destination.dig(:analysis, :declarations).map { |item| item[:text] } +
    template.dig(:analysis, :declarations).reject { |item| destination_declarations[item[:path]] }.map { |item| item[:text] }
  import_block = destination.dig(:analysis, :imports).map { |item| item[:text] }.join
  declaration_block = merged_declaration_texts.join("\n").rstrip
  sections = [import_block.rstrip, declaration_block].reject(&:empty?)
  { ok: true, diagnostics: [], output: "#{sections.join("\n\n").rstrip}\n", policies: [DESTINATION_WINS_ARRAY_POLICY] }
end

#parse_go(source, dialect) ⇒ Object



47
48
49
50
51
52
53
# File 'lib/go/merge.rb', line 47

def parse_go(source, dialect)
  requested = TREE_SITTER_BACKEND.id
  return unsupported_feature_result("Unsupported Go backend #{requested}.") unless requested == TREE_SITTER_BACKEND.id
  return analyze_go_module(source) if dialect == "go"

  { ok: false, diagnostics: [{ severity: "error", category: "unsupported_feature", message: "Unsupported Go dialect #{dialect}." }], policies: [] }
end