-
Notifications
You must be signed in to change notification settings - Fork 162
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cプリプロセッサの判定を強化 #1644
Cプリプロセッサの判定を強化 #1644
Conversation
CCppPreprocessMng::ScanLine において #elif にも対応 この処理はアウトライン解析ウィンドウに表示するC/C++関数リストを作成する処理で使用される
SonarCloud Quality Gate failed. |
このPRの変更を入れても色々と問題点は残ります。 例えば下記のようなテキストでアウトライン解析すると #if 0
/*
#endif
void func0() {}
*/
#endif
|
✅ Build sakura 1.0.3705 completed (commit 088892d98c by @beru) |
アウトライン解析機能はどうしましょうか。 コードの構成的にバグが発生しやすい機能です。
根本対策は、ドキュメント構造からアウトラインを読み取る部分と、読み取ったアウトラインを画面表示する部分を完全に分解し、ドキュメント構造からアウトラインを読み取る部分のコードを「構文規則」から自動生成するコードに置き換えることだと思っています。 issue立てると何年も残りそうな話題なので一旦コメントにします。 どう思います? |
どういう実装をしても広義のバグにカテゴライズされてしまうと「お前はいっつもバグを入れやがってこの〇ータ〇ンが!」というパワハラ罵声が脳内で響いてくるので逃げ腰になってしまいそうですが、まぁ冗談はおいておいて…。 まず「実装漏れ」がバグかどうかというのはケースバイケースだと思います。また意図的に決めて実装していなかったのか、それとも考慮漏れや忘れで実装がされなかったのかという違いもあると思います。とはいえ過去の事はおいておいて…。 どこまで対応して何には対応しないのかの計画を立てて作っていく方法もありますが、とはいえそういう文書化が必須化というとそうでもないとは思います。はい、面倒事の回避です。
自分がいまのとこ把握している範囲だと このPRがコメントなしでapproveでいいかというと、良し悪しの判断はおいておいてapproveを貰えたらすぐにmergeさせてもらいます。 個人的にはレビューアーが色々と動作確認をしてもらえると助かりますが、レビューアーの視点だとそんな事をやるのは面倒だと思うので、やはりPR作成者がテストデータとテストケースを用意して変更した実装に不具合が無さそうだという事の説得力を持たせるべきなんでしょうね、実際にやるのは大変なのでやってませんがまぁ開発プロセスの中で手抜きすると不具合はすり抜けていくものなのできちんとしたテストはどこかで用意したいですね。つまり先延ばしです。
アウトライン読み取りとその結果の画面表示が分離されていないのかというと処理としては分離されていると思います。アウトライン解析処理は 「構文規則」から自動生成に実装を変える事についてですが、手書きと比べて良し悪しはあると思います。なお 今の実装の 画面表示やキー操作の度にドキュメント全体からアウトラインを読み取る処理を実行したくないので構造化データに結果を保持しておきたいとは思います(メモリ使用量は増大してしまいますが)。今の実装だとアウトライン解析ウィンドウを表示する度にアウトライン解析処理を実行するので、前回実行してから何もドキュメントを変更していなくても再度アウトライン解析ウィンドウを表示するとまた同じ処理の実行が行われます。とはいえドキュメントが小規模な場合はアウトライン解析はすぐ終わるので問題には感じません。 あとドキュメントの内容を変更した際にアウトライン解析ウィンドウの表示内容がリアルタイムで変化しませんが、これはまた別の仕様の話ですね。 |
話は変わりますが |
解析と表示の分離は、現状でできているかちゃんと確認できていないです。 |
レビューありがとうございます。マージします。 |
PR の目的
CCppPreprocessMng::ScanLine
の処理を変更して#elif
にも対応するのが目的です。カテゴリ
PR の背景
この処理はアウトライン解析ウィンドウに表示するC/C++関数リストを作成する処理で使用されます。
なおCプリプロセッサの色付け処理は(残念ながら)従来のままで強化されません。このPRで変更した箇所の処理が色付けには関わっていない為です。
PR のメリット
Cプリプロセッサの
#elif
に対応したアウトライン解析が行われるようになります。PR のデメリット (トレードオフとかあれば)
CCppPreprocessMng::ScanLine
の実装が複雑化して読み取りにくくなります。仕様・動作説明
従来実装では
#elif
に対応していなかったので対応するようにしました。実装は色々と変えていますが、
CCppPreprocessMng
クラスにm_activated
というメンバーを追加しています。各レベルでC/C++での走査を行う場所が有ったかどうかの記録用です。この変数を追加せずに色々なケースで正しく処理させる方法が思いつきませんでした。m_enablebuf
というフラグ的な変数の使用と合わせてかなり理解しづらい記述になっていると思います。#if defined(...)
や#if !defined(...)
の記述には相変わらず対応出来ていません。PR の影響範囲
アウトライン解析ウィンドウに表示するC/C++関数リストを作成する処理で使用されるCプリプロセッサ判定処理
テスト内容
テスト1
手順
テスト用に cpp_test.cpp.txt を使用しました。拡張子が cpp だと添付出来ないので偽装して txt にしています。
小さいファイルなのでダウンロードしなくても内容が見れるようにしました。
内容
上記のテキスト中のディレクティブの定数を変更してからF11 キーを押してアウトライン解析の表示が期待通りかどうかを確認してテストしました。
関連 issue, PR
#1084
参考資料
https://docs.microsoft.com/en-us/cpp/preprocessor/hash-if-hash-elif-hash-else-and-hash-endif-directives-c-cpp
https://en.wikipedia.org/wiki/C_preprocessor