mirror of
https://github.com/ruby/ruby.git
synced 2025-08-15 13:39:04 +02:00
Page:
Node Position Memo JA
Pages
Assumptions JA
Assumptions
C99 Usage Guidelines
CI Servers
CI用Savings Planの購入
Committer How To JA
Committer How To
Developer How To JA
Developer How To
Developers Meeting
Donation
General Maintenance Policy
Git Migration FAQ JA
Home
How To Backport
How To Contribute
How To Maintain RubyCI Servers
How To Manage Redmine
How To Release JA
How To Report JA
How To Report
How To Request Backport
How To Request Features
Machine Instructions Trace with GDB
Node Position Memo JA
Refinements Spec
Release Engineering 2.1
Release Engineering 2.2
Release Engineering 2.3
Release Engineering 2.4
Release Engineering 2.5
Release Engineering 2.6
Release Engineering 2.7
Release Engineering 3.0
Release Engineering 3.1
Release Engineering 3.2
Release Engineering
Ruby 1.8 Branch Policy JA
Ruby 1.8 Branch Policy
Ruby 1.8 Release Plan JA
Ruby 1.8 Release Plan
Security
Server Resources
Versioning Policy
No results
This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
構文木に詳細な位置情報をもたせる計画
雑な lineno 以上に詳しい情報をもたせたい。
ユースケース
- エラー位置の正確な表示 (
x + y + z
でNoMethodError
が起きたとき、どっちで起きたのか示せる) - カバレッジの出力
- TracePoint#column(どんなカラム番号を返すべきなのか?は、TracePoint のユースケースに依存しそう)
power_assert
(TracePoint#column だけでできそう?現状の ripper で十分?)- 構文木を扱う API の構想(組み込み ripper 的なもの、遠い将来の話)
構文木ノードの位置とは
- ノードが広がる範囲の先頭位置
- ノードが広がる範囲の終端位置
- ノードをもっとも特徴的に表す文字列の先頭位置
- ノードをもっとも特徴的に表す文字列の終端位置
obj.foo(1, 2, 3)
^ ^ ^ ^
| | | +-終端位置
| | +----------代表終端位置
| +------------代表先頭位置
+----------------先頭位置
- 例外の可視化やカバレッジの可視化のためには、ノード代表位置が望ましい。
obj.foo.bar.baz
のノード先頭位置は全部重複してしまう- 文字列の範囲で可視化するためには当然、先頭と終端の両方が必要。
- power_assert の可視化ではノード先頭〜終端位置が必要?(本当?)
その他
終端位置を示す方法が inclusive か exclusive か((n..m)
か (n...m)
か)はどっちでもいいと思う。
ヒアドキュメントは要注意。「先頭位置〜終端位置」で扱うと他のノードの文字列が含まれる。例えば、
<<A + <<B
...
A
...
B
だと、<<A のノードの先頭位置〜終端位置と、<<B のノードの先頭位置〜終端位置、は重複してしまう。(しょうがないと思うけど)
位置の表現方法
ファイル先頭からのオフセットか、(行番号, カラム番号) の組にするか。TAB 文字をどう扱うか。0-based or 1-based ?
候補1: ファイル先頭からのオフセット
- [+] 行とカラムとの一貫性が崩れることがない
- [?] エラー表示で位置を示すのは処理が必要
- ファイル全体の文字列を保持または読み込みする必要あり
- 行内の TAB 文字処理が必要(面倒なだけ)
- [?] カバレッジの可視化はおそらく容易
候補2: 行番号+行頭からのオフセット(バイト数)
- [-] 行とカラムとの一貫性を気にする必要がある
- [?] エラー表示で位置を示すのは処理が必要
- ファイル全体の文字列を保持または読み込みする必要あり
- ファイル全体の文字列から指定行目先頭を特定する必要あり
- 行内の TAB 文字処理が必要(面倒なだけ)
- [?] カバレッジの可視化はおそらく容易
候補3: 行番号+行頭からのオフセット(TAB 文字解決済みの見た目のカラム番号)
- [-] 行とカラムとの一貫性を気にする必要がある
- [-] TAB 文字幅を決める必要がある(TAB 文字幅指定 API とか考えたくない)
- [-] カバレッジの可視化は少し面倒
<pre>
などで可視化するのでない限り、バイト数に逆変換する必要あり(面倒なだけ)
- [+] エラー表示で位置を示すのは処理が楽かも
- エラーメッセージだけなら、
undefined local variable or method 'foo' at (1, 1) for ...
とカラムの数字だけで示せる - ターミナルで位置を図示するのは、行の文字列を取得する処理が必要(他の候補と同じ)に加え、
- エラーメッセージだけなら、
候補 3 だと↓は容易
obj.foo()
# ^ NoMethodError
候補 3 だと↓は面倒(見た目のカラム番号からバイト数に逆変換する必要がある)
obj.foo()
# ^^^ ここだけ色を変える
0-based or 1-based
世の中の多くのカラム番号は 1-based だと思ったが、Emacs は 0-based らしい。Ripper は 0-based を採用している。
- 全部 0-based
- データは 0-based として保持し、エラー出力など必要なら 1 を足す
- 全部 1-based
実装方法
NODE には nd_reserved
の 1 ワードしか空きがないので工夫する必要がある。2.5 で実現する方法、2.6 以降で実現する方法を分けて決めたい。
実装 1. nd_reserved
に位置情報を数字でもたせる
- ファイルオフセットならそのまま
- (行番号, カラム番号) なら適当にエンコードする
- 現状の lineno とは別に行番号を保持したほうが良い
- オーバーヘッドは小さそう
- 先頭位置開始点 or 代表位置開始点をもたせるのが限界
実装 2. nd_reserved
に T_IMEMO
オブジェクトをもたせる
- 4 ワード分の空きが確保できるので、いろんな位置を持たせられる
- 実装は容易
- オーバーヘッドはそれなり
- NODE 1 つにつきオブジェクト 2 つ生成になる
- パース時間が 1.4 倍くらい
実装 3. NODE を GC 対象オブジェクトとは別に管理する
- ワード数の縛りがなくなるので、いろんな位置を持たせられる
- 可変長ノードが作れたり、オブジェクト生成が減ったり、他にもメリットあるかも(無視できる程度かも)
- 実装はわりと面倒
- オーバーヘッドは小さそう(たぶん)
Policies
Development
For developers
- Developer How To, Developer How To JA
- How To Contribute
- How To Report, How To Report JA
- How To Request Backport
- How To Request Features
- Developers Meeting
For committers
- Committer How To, Committer How To JA
- Git Migration FAQ JA
- How To Backport
- How To Manage Redmine
- How To Release JA
- How To Maintain RubyCI Servers