Class: BitClust::RRDParser::Context
Defined Under Namespace
Classes: MethodAttributes
Constant Summary
collapse
- METHOD_ATTRIBUTES =
現在サポートするメソッド属性(... 属性行のトークン)。
- nomethod/undef: 裸語。kind はエントリ単位でしか持てないので、
別名(複数シグネチャ)のエントリでは全シグネチャに同じ属性が
付いていることを要求する
- since="X"/until="X"(bitclust#132 P4): シグネチャ単位で束縛され、
そのシグネチャの名前だけに適用される。nomethod/undef と違い、
別名ごとに異なる値を持てる(全シグネチャ一致は要求しない)のが
本来の用途。X は "3.2" のように数字とドットのみ。
空値(since="")は「明示的に不明」= バッジ非表示の指定で、メソッド
自体は昔からあるのにドキュメント追加が遅れ、バージョンラダーからの
自動算出が誤った版を出す場合の抑止に使う(空文字が記録されるため
算出値で上書きされず、表示側も空はバッジを出さない)
%w[nomethod undef]
- KV_METHOD_ATTRIBUTES =
%w[since until]
- KV_METHOD_ATTRIBUTE_VALUE_RE =
/\A(?:\d+(?:\.\d+)*)?\z/
- MD_METHOD_SIG_PREFIX_RE =
md の ### def name .../### module_function def name .../
### const name/### gvar $name シグネチャ行を rd 形式
(--- name ...)へ正規化するための接頭辞(MDParser::SIG_RE と
同じパターン)。属性の紐付け先となるメソッド名を
MethodSignature.parse で取り出すために使う
/\A### (?:module_function def |def |const |gvar )/
Constants included
from NameUtils
NameUtils::CHAR_TO_MARK, NameUtils::CHAR_TO_NAME, NameUtils::CLASS_NAME_RE, NameUtils::CLASS_PATH_RE, NameUtils::CONST_PATH_RE, NameUtils::CONST_RE, NameUtils::GVAR_RE, NameUtils::LIBNAME_RE, NameUtils::MARK_TO_CHAR, NameUtils::MARK_TO_NAME, NameUtils::METHOD_NAME_RE, NameUtils::METHOD_SPEC_RE, NameUtils::MID, NameUtils::NAME_TO_CHAR, NameUtils::NAME_TO_MARK, NameUtils::TYPEMARK_RE
Instance Attribute Summary collapse
Instance Method Summary
collapse
Methods included from NameUtils
build_method_id, classid2name, classname2id, classname?, decodeid, decodename_fs, decodename_url, display_typemark, encodeid, encodename_fs, encodename_rdocurl, encodename_url, functionname?, gvarname?, html_filename, libid2name, libname2id, libname?, method_spec?, methodid2classid, methodid2libid, methodid2mname, methodid2specparts, methodid2specstring, methodid2typechar, methodid2typemark, methodid2typename, methodname?, split_method_id, split_method_spec, typechar2mark, typechar2name, typechar?, typemark2char, typemark2name, typemark?, typename2char, typename2mark, typename?
Constructor Details
#initialize(db, libname) ⇒ Context
Returns a new instance of Context.
353
354
355
356
357
358
359
360
|
# File 'lib/bitclust/rrdparser.rb', line 353
def initialize(db, libname)
@db = db
@library = @db.open_library(libname, true) @klass = nil
@type = nil
@visibility = nil
end
|
Instance Attribute Details
Returns the value of attribute klass.
363
364
365
|
# File 'lib/bitclust/rrdparser.rb', line 363
def klass
@klass
end
|
Returns the value of attribute library.
362
363
364
|
# File 'lib/bitclust/rrdparser.rb', line 362
def library
@library
end
|
Returns the value of attribute type.
364
365
366
|
# File 'lib/bitclust/rrdparser.rb', line 364
def type
@type
end
|
#visibility ⇒ Object
Returns the value of attribute visibility.
365
366
367
|
# File 'lib/bitclust/rrdparser.rb', line 365
def visibility
@visibility
end
|
Instance Method Details
#alias(name) ⇒ Object
Add a alias name to the alias list.
449
450
451
452
453
454
455
456
457
458
459
|
# File 'lib/bitclust/rrdparser.rb', line 449
def alias(name)
klass = @klass || raise
@db.open_class(name) do |c|
c.type = klass.type
c.library = @library
c.aliasof = klass
c.source = "Alias of [[c:#{klass.name}]]\n"
@library.add_class c
klass.alias c
end
end
|
#categorize(category) ⇒ Object
367
368
369
|
# File 'lib/bitclust/rrdparser.rb', line 367
def categorize(category)
@library.category = category
end
|
465
466
467
|
# File 'lib/bitclust/rrdparser.rb', line 465
def constant
@type = :constant
end
|
#define_class(name, supername, location: nil) ⇒ Object
379
380
381
382
383
384
385
386
387
|
# File 'lib/bitclust/rrdparser.rb', line 379
def define_class(name, supername, location: nil)
if @db.properties['version'] >= "1.9.0"
top = 'BasicObject'
else
top = 'Object'
end
superclass = (name == top ? nil : @db.get_class(supername))
register_class :class, name, superclass, location: location
end
|
#define_method(chunk) ⇒ Object
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
|
# File 'lib/bitclust/rrdparser.rb', line 481
def define_method(chunk)
id = method_id(chunk)
attrs = method_attributes(chunk)
@db.open_method(id) {|m|
m.names = chunk.names.sort
m.kind = if attrs.flags.include?('undef')
:undefined
elsif attrs.flags.include?('nomethod')
:nomethod
else
@kind
end
m.visibility = @visibility || :public
m.source = chunk.source
m.source_location = chunk.source.location
attrs.since_until.each do |name, kv|
m.fill_since(name, kv['since'] || raise) if kv['since']
m.fill_until(name, kv['until'] || raise) if kv['until']
end
case @kind
when :added, :redefined
@library.add_method m
end
}
end
|
#define_module(name, location: nil) ⇒ Object
389
390
391
|
# File 'lib/bitclust/rrdparser.rb', line 389
def define_module(name, location: nil)
register_class :module, name, nil, location: location
end
|
#define_object(name, singleton_object_class, location: nil) ⇒ Object
393
394
395
396
397
398
|
# File 'lib/bitclust/rrdparser.rb', line 393
def define_object(name, singleton_object_class, location: nil)
singleton_object_class = @db.get_class(singleton_object_class) if singleton_object_class
register_class :object, name, singleton_object_class, location: location
end
|
#dynamic_extend(name) ⇒ Object
444
445
446
|
# File 'lib/bitclust/rrdparser.rb', line 444
def dynamic_extend(name)
@klass&.dynamic_extend(@db.get_class(name), @library)
end
|
#dynamic_include(name) ⇒ Object
440
441
442
|
# File 'lib/bitclust/rrdparser.rb', line 440
def dynamic_include(name)
@klass&.dynamic_include(@db.get_class(name), @library)
end
|
#extend(name) ⇒ Object
436
437
438
|
# File 'lib/bitclust/rrdparser.rb', line 436
def extend(name)
@klass&.extend @db.get_class(name)
end
|
#include(name) ⇒ Object
432
433
434
|
# File 'lib/bitclust/rrdparser.rb', line 432
def include(name)
@klass&.include @db.get_class(name)
end
|
#method_attributes(chunk) ⇒ Object
kramdown Block IAL 風の ... 属性行からメタデータを集める。
属性行は「直前のシグネチャ行のみ」に束縛される(kramdown と同じ解釈)。
裸語トークン(nomethod/undef)は kind がエントリ単位でしか持てないため
全シグネチャで同じであることを要求するが、since=/until= はシグネチャ
単位でそのままの名前に適用するため、この一致要求からは除外する。
本文に入ったら探索を打ち切る(コード例中の ... を誤検出しないため)
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
|
# File 'lib/bitclust/rrdparser.rb', line 545
def method_attributes(chunk)
per_sig = [] since_until = {} current_name = nil current_keys = nil chunk.source.each_line do |line_|
line = line_.chomp
case line
when /\A---\s/, /\A\#\#\#\s/
per_sig.push []
current_name = method_attribute_target_name(line)
current_keys = {}
when /\A\{:(.*)\}[ \t]*\z/
break if per_sig.empty?
($1 || raise).strip.split(/\s+/).each do |token|
if METHOD_ATTRIBUTES.include?(token)
per_sig.last&.push token
else
key, value = parse_kv_method_attribute(token, chunk)
keys = current_keys or raise
if keys.key?(key)
raise ParseError,
"#{chunk.source.location}: duplicate method attribute #{key.inspect} on the same signature"
end
keys[key] = true
name = current_name or
raise ParseError,
"#{chunk.source.location}: cannot determine the signature name to bind method attribute #{token.inspect} to"
(since_until[name] ||= {})[key] = value
end
end
else
break
end
end
return MethodAttributes.new([], {}) if per_sig.empty?
sets = per_sig.map {|a| a.uniq.sort }
unless sets.uniq.size == 1
raise ParseError,
"#{chunk.source.location}: method attributes must be the same on every signature of an entry: #{sets.inspect}"
end
since_until.each_key do |name|
unless chunk.names.include?(name)
raise ParseError,
"#{chunk.source.location}: since/until attribute bound to unknown signature name #{name.inspect} (entry names: #{chunk.names.join(', ')})"
end
end
MethodAttributes.new(sets.first || raise, since_until)
end
|
#method_id(chunk) ⇒ Object
632
633
634
635
636
637
638
639
|
# File 'lib/bitclust/rrdparser.rb', line 632
def method_id(chunk)
id = MethodID.new
id.library = @library
id.klass = chunk.signature.klass ? @db.get_class(chunk.signature.klass) : (@klass || raise)
id.type = chunk.signature.typename || @type
id.name = chunk.names.sort.first
id
end
|
#module_function ⇒ Object
461
462
463
|
# File 'lib/bitclust/rrdparser.rb', line 461
def module_function
@type = :module_function
end
|
#redefine_class(name) ⇒ Object
426
427
428
429
430
|
# File 'lib/bitclust/rrdparser.rb', line 426
def redefine_class(name)
@kind = :redefined
@klass = name ? @db.get_class(name) : nil
clear_scope
end
|
#reopen_class(name) ⇒ Object
420
421
422
423
424
|
# File 'lib/bitclust/rrdparser.rb', line 420
def reopen_class(name)
@kind = :added
@klass = name ? @db.get_class(name) : nil
clear_scope
end
|
#require(libname) ⇒ Object
371
372
373
|
# File 'lib/bitclust/rrdparser.rb', line 371
def require(libname)
@library.require @db.get_library(libname)
end
|
#signature ⇒ Object
476
477
478
479
|
# File 'lib/bitclust/rrdparser.rb', line 476
def signature
return nil unless @klass
Signature.new(@klass&.name, @type ? typename2mark(@type || raise) : nil, nil)
end
|
#special_variable ⇒ Object
469
470
471
472
473
474
|
# File 'lib/bitclust/rrdparser.rb', line 469
def special_variable
unless @klass and @klass&.name == 'Kernel'
raise "must not happen: type=special_variable but class!=Kernel"
end
@type = :special_variable
end
|
#sublibrary(libname) ⇒ Object
375
376
377
|
# File 'lib/bitclust/rrdparser.rb', line 375
def sublibrary(libname)
@library.sublibrary @db.get_library(libname)
end
|