Module: Rbs::Merge::NodeTypeNormalizer

Extended by:
Ast::Merge::NodeTyping::Normalizer
Defined in:
lib/rbs/merge/node_type_normalizer.rb

Overview

Normalizes backend-specific node types to canonical RBS types.

Uses Ast::Merge::NodeTyping::Wrapper to wrap nodes with canonical
merge_type, allowing portable merge rules across backends.

Thread Safety

All backend registration and lookup operations are thread-safe via
the shared Ast::Merge::NodeTyping::Normalizer module.

Backends

Currently supports:

  • :rbs - Official RBS gem parser (MRI only, full-featured)
  • :tree_sitter - tree-sitter-rbs grammar (cross-platform)

Extensibility

New backends can be registered at runtime:

Canonical Types

The following canonical types are used for portable merge rules:

Declaration Types

  • :class - Class declaration
  • :module - Module declaration
  • :interface - Interface declaration
  • :type_alias - Type alias declaration
  • :constant - Constant declaration
  • :global - Global variable declaration

Member Types

  • :method - Method definition
  • :alias - Method alias
  • :attr_reader - Attribute reader
  • :attr_writer - Attribute writer
  • :attr_accessor - Attribute accessor
  • :include - Module include
  • :extend - Module extend
  • :prepend - Module prepend
  • :ivar - Instance variable
  • :civar - Class instance variable
  • :cvar - Class variable

Other

  • :comment - Comment lines
  • :document - Root document node

Examples:

Registering a new backend

NodeTypeNormalizer.register_backend(:my_rbs_parser, {
  class_decl: :class,
  module_decl: :module,
})

See Also:

  • Ast::Merge::NodeTyping::Wrapper
  • Ast::Merge::NodeTyping::Normalizer

Constant Summary collapse

DEFAULT_BACKEND =

Default backend for RBS normalization

:rbs

Class Method Summary collapse

Class Method Details

.canonical_type(backend_type, backend = DEFAULT_BACKEND) ⇒ Symbol?

Get the canonical type for a backend-specific type.
Overrides the shared Normalizer to default to :rbs backend.

Parameters:

  • backend_type (Symbol, String, nil)

    The backend’s node type

  • backend (Symbol) (defaults to: DEFAULT_BACKEND)

    The backend identifier (defaults to :rbs)

Returns:

  • (Symbol, nil)

    Canonical type (or original if no mapping)



240
241
242
# File 'lib/rbs/merge/node_type_normalizer.rb', line 240

def canonical_type(backend_type, backend = DEFAULT_BACKEND)
  super(backend_type, backend)
end

.canonical_type_for_node(node, backend = DEFAULT_BACKEND) ⇒ Symbol?

Get the canonical type for a specific node, allowing node-shape-aware
refinement when a backend uses generic wrapper/member node types.

Parameters:

  • node (Object, nil)

    Backend node responding to #type and optionally #each

  • backend (Symbol) (defaults to: DEFAULT_BACKEND)

    Backend identifier

Returns:

  • (Symbol, nil)


250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
# File 'lib/rbs/merge/node_type_normalizer.rb', line 250

def canonical_type_for_node(node, backend = DEFAULT_BACKEND)
  return if node.nil?

  backend_type = if backend == :tree_sitter && node.respond_to?(:type)
    node.type
  else
    node.class.name
  end

  canonical = canonical_type(backend_type, backend)
  return canonical unless backend == :tree_sitter

  case canonical
  when :attribute
    refine_tree_sitter_attribute_type(node) || canonical
  when :ivar
    refine_tree_sitter_variable_type(node) || canonical
  else
    canonical
  end
end

.container_type?(type) ⇒ Boolean

Check if a type is a container type (can have children/members)

Parameters:

  • type (Symbol, String)

    The type to check

Returns:

  • (Boolean)


305
306
307
308
# File 'lib/rbs/merge/node_type_normalizer.rb', line 305

def container_type?(type)
  canonical = type.to_sym
  %i[document class module interface].include?(canonical)
end

.declaration_type?(type) ⇒ Boolean

Check if a type is a declaration type (class, module, interface, etc.)
Also includes :declaration_wrapper which wraps declarations in tree-sitter-rbs

Parameters:

  • type (Symbol, String)

    The type to check

Returns:

  • (Boolean)


287
288
289
290
# File 'lib/rbs/merge/node_type_normalizer.rb', line 287

def declaration_type?(type)
  canonical = type.to_sym
  %i[class module interface type_alias constant global class_alias module_alias declaration_wrapper].include?(canonical)
end

.member_type?(type) ⇒ Boolean

Check if a type is a member type (method, attr, include, etc.)

Parameters:

  • type (Symbol, String)

    The type to check

Returns:

  • (Boolean)


296
297
298
299
# File 'lib/rbs/merge/node_type_normalizer.rb', line 296

def member_type?(type)
  canonical = type.to_sym
  %i[method alias attr_reader attr_writer attr_accessor include extend prepend ivar civar cvar visibility].include?(canonical)
end

.type_definition?(type) ⇒ Boolean

Check if a type is a type definition (type_alias, etc.)

Parameters:

  • type (Symbol, String)

    The type to check

Returns:

  • (Boolean)


314
315
316
317
# File 'lib/rbs/merge/node_type_normalizer.rb', line 314

def type_definition?(type)
  canonical = type.to_sym
  %i[type_alias].include?(canonical)
end

.wrap(node, backend = DEFAULT_BACKEND) ⇒ Ast::Merge::NodeTyping::Wrapper

Wrap a node with its canonical type as merge_type.
Overrides the shared Normalizer to default to :rbs backend.

Parameters:

  • node (Object)

    The backend node to wrap (must respond to #type)

  • backend (Symbol) (defaults to: DEFAULT_BACKEND)

    The backend identifier (defaults to :rbs)

Returns:

  • (Ast::Merge::NodeTyping::Wrapper)

    Wrapped node with canonical merge_type



278
279
280
# File 'lib/rbs/merge/node_type_normalizer.rb', line 278

def wrap(node, backend = DEFAULT_BACKEND)
  super(node, backend)
end