Class: TreeHaver::Backends::MRI::Language

Inherits:
Object
  • Object
show all
Includes:
Comparable
Defined in:
lib/tree_haver/backends/mri.rb

Overview

Wrapper for ruby_tree_sitter Language

Wraps ::TreeSitter::Language from ruby_tree_sitter to provide a consistent API across all backends.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(lang, path: nil, symbol: nil) ⇒ Language

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a new instance of Language.

Parameters:

  • lang (::TreeSitter::Language)

    the language object from ruby_tree_sitter

  • path (String, nil) (defaults to: nil)

    path language was loaded from

  • symbol (String, nil) (defaults to: nil)

    symbol name



93
94
95
96
97
98
# File 'lib/tree_haver/backends/mri.rb', line 93

def initialize(lang, path: nil, symbol: nil)
  @inner_language = lang
  @backend = :mri
  @path = path
  @symbol = symbol
end

Instance Attribute Details

#backendSymbol (readonly)

The backend this language is for

Returns:

  • (Symbol)


79
80
81
# File 'lib/tree_haver/backends/mri.rb', line 79

def backend
  @backend
end

#inner_language::TreeSitter::Language (readonly)

The wrapped TreeSitter::Language object



75
76
77
# File 'lib/tree_haver/backends/mri.rb', line 75

def inner_language
  @inner_language
end

#pathString? (readonly)

The path this language was loaded from (if known)

Returns:

  • (String, nil)


83
84
85
# File 'lib/tree_haver/backends/mri.rb', line 83

def path
  @path
end

#symbolString? (readonly)

The symbol name (if known)

Returns:

  • (String, nil)


87
88
89
# File 'lib/tree_haver/backends/mri.rb', line 87

def symbol
  @symbol
end

Class Method Details

.from_library(path, symbol: nil, name: nil) ⇒ Object



145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# File 'lib/tree_haver/backends/mri.rb', line 145

def from_library(path, symbol: nil, name: nil)
  raise TreeHaver::NotAvailable, "ruby_tree_sitter not available" unless MRI.available?

  # ruby_tree_sitter's TreeSitter::Language.load takes (language_name, path_to_so)
  # where language_name is the language identifier (e.g., "toml", "json")
  # NOT the full symbol name (e.g., NOT "tree_sitter_toml")
  # and path_to_so is the full path to the .so file
  #
  # If name is not provided, derive it from symbol by stripping "tree_sitter_" prefix
  language_name = name || symbol&.sub(/\Atree_sitter_/, "")
  ts_lang = ::TreeSitter::Language.load(language_name, path)
  new(ts_lang, path: path, symbol: symbol)
rescue NameError => e
  # TreeSitter constant doesn't exist - backend not loaded
  raise TreeHaver::NotAvailable, "ruby_tree_sitter not available: #{e.message}"
rescue Exception => e # rubocop:disable Lint/RescueException
  # TreeSitter errors inherit from Exception (not StandardError) in ruby_tree_sitter v2+
  # We rescue Exception and check the class name dynamically to avoid NameError
  # at parse time when TreeSitter constant isn't loaded yet
  if defined?(TreeSitter::TreeSitterError) && e.is_a?(TreeSitter::TreeSitterError)
    raise TreeHaver::NotAvailable, "Could not load language: #{e.message}"
  else
    raise # Re-raise if it's not a TreeSitter error
  end
end

.from_path(path, symbol: nil) ⇒ Language

Deprecated.

Use from_library instead

Load a language from a shared library path (legacy method)

Parameters:

  • path (String)

    absolute path to the language shared library

  • symbol (String) (defaults to: nil)

    the exported symbol name (e.g., “tree_sitter_json”)

Returns:

  • (Language)

    wrapped language handle



177
178
179
# File 'lib/tree_haver/backends/mri.rb', line 177

def from_path(path, symbol: nil)
  from_library(path, symbol: symbol)
end

Instance Method Details

#<=>(other) ⇒ Integer?

Compare languages for equality

MRI languages are equal if they have the same backend, path, and symbol. Path and symbol uniquely identify a loaded language.

Parameters:

  • other (Object)

    object to compare with

Returns:

  • (Integer, nil)

    -1, 0, 1, or nil if not comparable



107
108
109
110
111
112
113
114
115
116
# File 'lib/tree_haver/backends/mri.rb', line 107

def <=>(other)
  return unless other.is_a?(Language)
  return unless other.backend == @backend

  # Compare by path first, then symbol
  cmp = (@path || "") <=> (other.path || "")
  return cmp if cmp.nonzero?

  (@symbol || "") <=> (other.symbol || "")
end

#hashInteger

Hash value for this language (for use in Sets/Hashes)

Returns:

  • (Integer)


120
121
122
# File 'lib/tree_haver/backends/mri.rb', line 120

def hash
  [@backend, @path, @symbol].hash
end

#to_language::TreeSitter::Language Also known as: to_ts_language

Convert to the underlying TreeSitter::Language for passing to parser



130
131
132
# File 'lib/tree_haver/backends/mri.rb', line 130

def to_language
  @inner_language
end