Class: RubyBindgen::SymbolCandidates

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/ruby-bindgen/symbol_candidates.rb

Overview

Generates the ordered list of name strings a cursor could plausibly be referenced as in a YAML symbols entry. Pure name enumeration — owns no tables and makes no policy decisions. Consumers (Symbols, Namer) feed the result through their own lookup tables.

The list spans:

* libclang's qualified_name (with anonymous scopes stripped)
* parent.type.spelling-based qualified name (collapses inline namespaces)
* display_name forms with template arguments
* a "specialized" display rebuilt from libclang template-arg APIs (so
  Outer::takeValue<7>() matches even when display_name is takeValue<>())
* parameter-list forms (clang preferred / fully-qualified / canonical)
  for callable cursors, against every qualified-name form above
* cursor.spelling as the bare-name fallback (last so it does not
  shadow a more-specific user rule)

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(cursor) ⇒ SymbolCandidates

Returns a new instance of SymbolCandidates.



32
33
34
# File 'lib/ruby-bindgen/symbol_candidates.rb', line 32

def initialize(cursor)
  @cursor = cursor
end

Class Method Details

.normalize_signature(str) ⇒ Object

Canonicalize whitespace in a signature so user-supplied spellings match libclang’s. Used by table consumers to keep keys and lookups aligned.



24
25
26
27
28
29
30
# File 'lib/ruby-bindgen/symbol_candidates.rb', line 24

def self.normalize_signature(str)
  str
    .gsub(/\s+/, ' ')
    .gsub(/\s*\*/, '*')
    .gsub(/\s*&/, '&')
    .strip
end

Instance Method Details

#each {|@cursor.spelling| ... } ⇒ Object

Yield each candidate string in priority order (most-specific first). Consumers stop on the first match, so qualified user rules win over bare-name fallbacks like the built-in operator mappings.

Yields:

  • (@cursor.spelling)


39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/ruby-bindgen/symbol_candidates.rb', line 39

def each
  return enum_for(:each) unless block_given?

  seen = Set.new
  qualified_names = qualified_name_forms

  qualified_names.each do |name|
    yield name if seen.add?(name)
  end

  # Template display candidates: display_name carries template args, e.g.
  # "DataType<hfloat>" or "saturate_cast<hfloat>(uchar)". Also rebuild a
  # specialized display from libclang template-arg APIs to recover names
  # that display_name leaves abbreviated, e.g. takeValue<>() -> takeValue<7>().
  display = @cursor.display_name
  if display != @cursor.spelling
    qualified_names.each do |qn|
      yield display if seen.add?(display)
      qualified_display = sub_last(qn, @cursor.spelling, display)
      yield qualified_display if seen.add?(qualified_display)
    end

    specialized_display = specialized_template_display_name(display)
    if specialized_display && specialized_display != display
      qualified_names.each do |qn|
        yield specialized_display if seen.add?(specialized_display)
        fq_qualified_display = sub_last(qn, @cursor.spelling, specialized_display)
        yield fq_qualified_display if seen.add?(fq_qualified_display)
      end
    end
  end

  # Parameter-list forms for callable cursors. Each list is built three
  # ways because libclang spells the same parameter type differently in
  # different contexts:
  #   - arg_type.spelling: clang's preferred form, often the typedef
  #   - fully_qualified_name: fully namespace-qualified
  #   - canonical.spelling: post-typedef canonical type
  # Users may write any of these forms in their YAML; emit them all.
  if @cursor.type.is_a?(FFI::Clang::Types::Function)
    parameter_lists = []
    parameter_lists << (0...@cursor.type.args_size).map { |i| @cursor.type.arg_type(i).spelling }.join(", ")
    parameter_lists << (0...@cursor.type.args_size).map { |i| @cursor.type.arg_type(i).fully_qualified_name(@cursor.printing_policy) }.join(", ")
    parameter_lists << (0...@cursor.type.args_size).map { |i| @cursor.type.arg_type(i).canonical.spelling }.join(", ")

    parameter_lists.uniq.each do |param_types|
      bare = "#{@cursor.spelling}(#{param_types})"
      yield bare if seen.add?(bare)
      qualified_names.each do |qn|
        candidate = "#{qn}(#{param_types})"
        yield candidate if seen.add?(candidate)
      end
    end
  end

  yield @cursor.spelling if seen.add?(@cursor.spelling)

  $stderr.puts "Candidates for #{@cursor.spelling}: #{seen.to_a.inspect}" if ENV['BINDGEN_DEBUG_SYMBOLS']
end