diff --git a/doc/markdown-samples/MARKUP_SPEC.md b/doc/markdown-samples/MARKUP_SPEC.md index ceb210b..cbd8dce 100644 --- a/doc/markdown-samples/MARKUP_SPEC.md +++ b/doc/markdown-samples/MARKUP_SPEC.md @@ -463,6 +463,15 @@ nth 番目の要素を返します。 存在し、X 以降には存在しない)ことを明示する。X は `"3.2"` のように数字と ドットのみをダブルクォートで囲んで書く。シグネチャ見出しの横に since/until バッジとして表示される +- `since=""`(空値)— 「初出バージョンは不明(少なくとも記録が残る最古の + バージョンより前から存在する)」ことを明示し、**バッジを表示しない**。 + メソッド自体は昔からあるのにリファレンスへの記載が後から追加されたために、 + 自動算出(`bitclust methodsince`)が記載時期を初出として誤った版を + 表示してしまう場合の抑止に使う(例: `Array#collect` は Ruby 1.8 以前から + 存在するが、記載は 2.4.0 のドキュメント凍結後に追加されたため + 「Ruby 2.5.0 から」と誤って算出される)。 + 別名(複数シグネチャ)のエントリで抑止する場合は、抑止したいすべての + シグネチャ見出しの直後にそれぞれ付けること。`until=""` も同様 規則: diff --git a/lib/bitclust/rrdparser.rb b/lib/bitclust/rrdparser.rb index 6407ee6..c2494af 100644 --- a/lib/bitclust/rrdparser.rb +++ b/lib/bitclust/rrdparser.rb @@ -513,10 +513,14 @@ def define_method(chunk) # - since="X"/until="X"(bitclust#132 P4): シグネチャ単位で束縛され、 # そのシグネチャの名前だけに適用される。nomethod/undef と違い、 # 別名ごとに異なる値を持てる(全シグネチャ一致は要求しない)のが - # 本来の用途。X は "3.2" のように数字とドットのみ + # 本来の用途。X は "3.2" のように数字とドットのみ。 + # 空値(since="")は「明示的に不明」= バッジ非表示の指定で、メソッド + # 自体は昔からあるのにドキュメント追加が遅れ、バージョンラダーからの + # 自動算出が誤った版を出す場合の抑止に使う(空文字が記録されるため + # 算出値で上書きされず、表示側も空はバッジを出さない) METHOD_ATTRIBUTES = %w[nomethod undef] KV_METHOD_ATTRIBUTES = %w[since until] - KV_METHOD_ATTRIBUTE_VALUE_RE = /\A\d+(?:\.\d+)*\z/ + KV_METHOD_ATTRIBUTE_VALUE_RE = /\A(?:\d+(?:\.\d+)*)?\z/ # md の `### def name ...`/`### module_function def name ...`/ # `### const name`/`### gvar $name` シグネチャ行を rd 形式 @@ -606,7 +610,8 @@ def parse_kv_method_attribute(token, chunk) raise ParseError, "#{chunk.source.location}: invalid method attribute #{token.inspect} " \ "(supported: #{METHOD_ATTRIBUTES.join(', ')}, " \ - "#{KV_METHOD_ATTRIBUTES.map {|k| %Q(#{k}="X") }.join('/')} where X is digits and dots, e.g. since=\"3.2\")" + "#{KV_METHOD_ATTRIBUTES.map {|k| %Q(#{k}="X") }.join('/')} where X is digits and dots, e.g. since=\"3.2\", " \ + "or empty for explicitly-unknown, e.g. since=\"\")" end private :parse_kv_method_attribute diff --git a/lib/bitclust/version_badges.rb b/lib/bitclust/version_badges.rb index 2c1f0fc..23c38fe 100644 --- a/lib/bitclust/version_badges.rb +++ b/lib/bitclust/version_badges.rb @@ -78,7 +78,8 @@ def uniform_map?(entry, map) end def badge_span(version, css_class, catalog_key) - return nil unless version + # 空文字は「明示的に不明」({: since=""})= バッジ非表示(bitclust#132) + return nil if version.nil? || version.empty? %Q(#{escape_html(_(catalog_key, version))}) end diff --git a/test/test_method_since_calculator.rb b/test/test_method_since_calculator.rb index 05c7946..0ef0d31 100644 --- a/test/test_method_since_calculator.rb +++ b/test/test_method_since_calculator.rb @@ -51,6 +51,13 @@ class TestMethodSinceCalculator < Test::Unit::TestCase 説明 #@end + #@since 2.0.0 + --- suppressed + {: since=""} + + 説明 + #@end + #@since 2.0.0 --- -@ #@since 3.0 @@ -224,6 +231,15 @@ def test_author_since_attribute_parsed_from_source_survives_apply assert_equal '2.5', find_entry('3.0', 'i', 'overridden').since_of('overridden') end + def test_explicit_empty_since_suppresses_computed_value + # suppressed は #@since 2.0.0 ゲートによりラダー上は 2.0.0 と算出されるが、 + # {: since=""}(明示的に不明=バッジ非表示)がパース時に記録されているため + # apply は上書きしない(bitclust#132: ドキュメント追加がメソッド追加より + # 遅れて算出が誤る場合の抑止) + run_calculator('3.0') + assert_equal '', find_entry('3.0', 'i', 'suppressed').since_of('suppressed') + end + def test_apply_rejects_target_whose_version_is_not_in_ladder build_db('4.0') calc = BitClust::MethodSinceCalculator.new(ladder_dbs) diff --git a/test/test_rdcompiler.rb b/test/test_rdcompiler.rb index 6baf369..362c66e 100644 --- a/test/test_rdcompiler.rb +++ b/test/test_rdcompiler.rb @@ -621,6 +621,46 @@ def test_method_signature_since_badge_special_variable_alias names: ['0', 'PROGRAM_NAME'], since_map: {'PROGRAM_NAME' => '1.9.1'}) end + # since_map の空文字値は「明示的に不明」(著者が {: since=""} で指定)。 + # バッジは表示しない(bitclust#132: ドキュメント追加が遅れて算出が誤る場合の抑止) + def test_method_signature_empty_since_suppresses_badge + @c = ja_catalog_compiler + src = <<'HERE' +--- hoge +foo +HERE + expected = <<'HERE' +
hoge[permalink][rdoc]+foo +
+hoge1[permalink][rdoc]hoge2Ruby 2.0.0 から+bar +
+