Class: RBS::Namespace

Inherits:
Object
  • Object
show all
Defined in:
lib/rbs/namespace.rb

Constant Summary collapse

INTERN_LEAF =
Module.new

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(path:, absolute:) ⇒ Namespace

Returns a new instance of Namespace.



7
8
9
10
# File 'lib/rbs/namespace.rb', line 7

def initialize(path:, absolute:)
  @path = path
  @absolute = absolute ? true : false
end

Instance Attribute Details

#pathObject (readonly)

Returns the value of attribute path.



5
6
7
# File 'lib/rbs/namespace.rb', line 5

def path
  @path
end

Class Method Details

.[](path, absolute) ⇒ Object

Returns a canonical ‘Namespace` instance for the given `path` / `absolute` pair. Repeated calls with structurally equal arguments return the same object, so callers can rely on `equal?` for fast equality. The path Array is duplicated and frozen on insert.



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/rbs/namespace.rb', line 24

def self.[](path, absolute)
  absolute = absolute ? true : false

  # Lock-free fast path.
  node = absolute ? @intern_trie_absolute : @intern_trie_relative
  path.each do |sym|
    node = node[sym]
    break unless node
  end
  if node && (cached = node[INTERN_LEAF])
    return cached
  end

  @intern_mutex.synchronize do
    node = absolute ? @intern_trie_absolute : @intern_trie_relative
    path.each { |sym| node = (node[sym] ||= {}) }
    node[INTERN_LEAF] ||= begin
      frozen_path = path.frozen? ? path : path.dup.freeze
      new(path: frozen_path, absolute: absolute)
    end
  end
end

.emptyObject



47
48
49
# File 'lib/rbs/namespace.rb', line 47

def self.empty
  @empty ||= self[[], false]
end

.parse(string) ⇒ Object



129
130
131
132
133
134
135
# File 'lib/rbs/namespace.rb', line 129

def self.parse(string)
  if string.start_with?("::")
    self[string.split("::").drop(1).map(&:to_sym), true]
  else
    self[string.split("::").map(&:to_sym), false]
  end
end

.rootObject



51
52
53
# File 'lib/rbs/namespace.rb', line 51

def self.root
  @root ||= self[[], true]
end

Instance Method Details

#+(other) ⇒ Object



55
56
57
58
59
60
61
# File 'lib/rbs/namespace.rb', line 55

def +(other)
  if other.absolute?
    other
  else
    Namespace[path + other.path, absolute?]
  end
end

#==(other) ⇒ Object Also known as: eql?



94
95
96
97
# File 'lib/rbs/namespace.rb', line 94

def ==(other)
  return true if equal?(other)
  other.is_a?(Namespace) && other.path == path && other.absolute? == absolute?
end

#absolute!Object



82
83
84
# File 'lib/rbs/namespace.rb', line 82

def absolute!
  Namespace[path, true]
end

#absolute?Boolean

Returns:

  • (Boolean)


74
75
76
# File 'lib/rbs/namespace.rb', line 74

def absolute?
  @absolute
end

#append(component) ⇒ Object



63
64
65
# File 'lib/rbs/namespace.rb', line 63

def append(component)
  Namespace[path + [component], absolute?]
end

#ascendObject



137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/rbs/namespace.rb', line 137

def ascend
  if block_given?
    current = self

    until current.empty?
      yield current
      current = _ = current.parent
    end

    yield current

    self
  else
    enum_for(:ascend)
  end
end

#empty?Boolean

Returns:

  • (Boolean)


90
91
92
# File 'lib/rbs/namespace.rb', line 90

def empty?
  path.empty?
end

#hashObject



101
102
103
# File 'lib/rbs/namespace.rb', line 101

def hash
  @hash ||= path.hash ^ absolute?.hash
end

#parentObject



67
68
69
70
71
72
# File 'lib/rbs/namespace.rb', line 67

def parent
  @parent ||= begin
    raise "Parent with empty namespace" if empty?
    Namespace[path.take(path.size - 1), absolute?]
  end
end

#relative!Object



86
87
88
# File 'lib/rbs/namespace.rb', line 86

def relative!
  Namespace[path, false]
end

#relative?Boolean

Returns:

  • (Boolean)


78
79
80
# File 'lib/rbs/namespace.rb', line 78

def relative?
  !absolute?
end

#splitObject



105
106
107
108
109
# File 'lib/rbs/namespace.rb', line 105

def split
  last = path.last or return
  parent = self.parent
  [parent, last]
end

#to_sObject



111
112
113
114
115
116
117
118
# File 'lib/rbs/namespace.rb', line 111

def to_s
  if empty?
    absolute? ? "::" : ""
  else
    s = path.join("::")
    absolute? ? "::#{s}::" : "#{s}::"
  end
end

#to_type_nameObject



120
121
122
123
124
125
126
127
# File 'lib/rbs/namespace.rb', line 120

def to_type_name
  parent, name = split

  raise unless name
  raise unless parent

  TypeName[parent, name]
end