Class: BitClust::IncludeGraph::Scope

Inherits:
Object
  • Object
show all
Defined in:
lib/bitclust/include_graph.rb

Overview

対象版範囲 [lo, hi)。範囲はパラメータであり、[3.0, 4.2) 以外 (旧版サルベージ等)でも同じ解析結果に対して再利用できる。

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(lo, hi) ⇒ Scope

Returns a new instance of Scope.



78
79
80
81
# File 'lib/bitclust/include_graph.rb', line 78

def initialize(lo, hi)
  @lo = Gem::Version.new(lo)
  @hi = Gem::Version.new(hi)
end

Instance Attribute Details

#hiObject (readonly)

Returns the value of attribute hi.



76
77
78
# File 'lib/bitclust/include_graph.rb', line 76

def hi
  @hi
end

#loObject (readonly)

Returns the value of attribute lo.



76
77
78
# File 'lib/bitclust/include_graph.rb', line 76

def lo
  @lo
end

Instance Method Details

#always?(cond) ⇒ Boolean

条件がスコープ内の全バージョンで真か(:if・不正な版文字列は判定不能なので false)

Returns:

  • (Boolean)


93
94
95
96
97
98
99
100
101
# File 'lib/bitclust/include_graph.rb', line 93

def always?(cond)
  case cond.kind
  when :since then Gem::Version.new(cond.version) <= @lo
  when :until then Gem::Version.new(cond.version) >= @hi
  else false
  end
rescue ArgumentError
  false
end

#cover?(conditions) ⇒ Boolean

conditions の版区間がスコープと交差するか。 恒偽と証明できる :if 条件が含まれる場合も交差しない

Returns:

  • (Boolean)


85
86
87
88
89
90
# File 'lib/bitclust/include_graph.rb', line 85

def cover?(conditions)
  return false if conditions.any? { |c| c.kind == :if && never?(c) }
  lo, hi = IncludeGraph.interval(conditions)
  return false if lo && hi && lo >= hi   # 空区間
  (lo.nil? || lo < @hi) && (hi.nil? || hi > @lo)
end

#gate(conditions) ⇒ Object

front matter に書く構造ゲート。スコープ内で効く境界のみ残す (下限以下の since・上限以上の until は省略)。スコープ外なら nil。 バージョン文字列は原文の表記を保持する。



142
143
144
145
146
147
148
149
# File 'lib/bitclust/include_graph.rb', line 142

def gate(conditions)
  return nil unless cover?(conditions)
  lo, hi = IncludeGraph.bounds(conditions)
  gate = {} #: IncludeGraph::gate
  gate[:since] = lo[1] if lo && lo[0] > @lo
  gate[:until] = hi[1] if hi && hi[0] < @hi
  gate
end

#never?(cond) ⇒ Boolean

条件がスコープ内の全バージョンで偽か(不正な版文字列は判定不能なので false)。 :if は連言子(and 区切り)のいずれかが恒偽と証明できる場合のみ true (LIBRARIES の #@if("1.9.1" <= version and version < "2.5.0") 等)

Returns:

  • (Boolean)


106
107
108
109
110
111
112
113
114
115
116
# File 'lib/bitclust/include_graph.rb', line 106

def never?(cond)
  case cond.kind
  when :since then Gem::Version.new(cond.version) >= @hi
  when :until then Gem::Version.new(cond.version) <= @lo
  when :if
    cond.version.split(/\band\b/).any? { |c| never_conjunct?(c) }
  else false
  end
rescue ArgumentError
  false
end

#never_conjunct?(conjunct) ⇒ Boolean

#@if の連言子が恒偽と証明できるか。 対応形: version < "X" / version <= "X" / version >= "X" / "X" <= version / version == "X"(判定できない形は false)

Returns:

  • (Boolean)


121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/bitclust/include_graph.rb', line 121

def never_conjunct?(conjunct)
  case conjunct
  when /version\s*<=?\s*"([\d.]+)"/
    op_lt = !conjunct.include?('<=')
    v = Gem::Version.new($1)
    op_lt ? v <= @lo : v < @lo
  when /version\s*>=\s*"([\d.]+)"/, /"([\d.]+)"\s*<=\s*version/
    Gem::Version.new($1) >= @hi
  when /version\s*==\s*"([\d.]+)"/
    v = Gem::Version.new($1)
    v < @lo || v >= @hi
  else
    false
  end
rescue ArgumentError
  false
end