Skip to content
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

履歴管理クラスに関するインクルード文を整理する #1697

Merged
3 commits merged into from Jun 29, 2021
Merged

履歴管理クラスに関するインクルード文を整理する #1697

3 commits merged into from Jun 29, 2021

Conversation

ghost
Copy link

@ghost ghost commented Jun 23, 2021

PR の目的

履歴管理クラス(CRecentインターフェースを実装した各派生クラス)に関するインクルード文を整理します。

カテゴリ

  • リファクタリング

PR の背景

SonarQubeによる解析結果で、ヘッダファイルのインクルード文に対してCode Smellが検出されていました。

インクルード文の整理を実施して当該指摘の解消を試みます。

PR のメリット

  • Code Smellが解消されます。
  • (CRecentインターフェースを利用する側で、)インクルード文からどの履歴管理クラスを利用しているか判断できるようになります。

PR のデメリット (トレードオフとかあれば)

特にありません。

仕様・動作説明

  • CRecent.h及びCRecentImp.hのファイル末尾にある、派生クラスのインクルード文を削除し、CRecent.hをインクルードしていた各ソースファイルでは代わりに各派生クラスのヘッダファイルをインクルードするようにしました。
  • 作業過程でCRecentの各派生クラスに不必要なインクルード文があったため、併せて削除しました。

PR の影響範囲

履歴データにアクセスする各クラス

テスト内容

ビルドの確認のみです。
なお、MinGWビルドは確認できていませんので、Azure Pipelinesの当該ジョブの成否を確認できるまでDraftとします。

関連 issue, PR

参考資料

Kohki Akikaze added 2 commits June 22, 2021 14:52
CRecent.hに代えて各派生クラスのヘッダファイルをインクルードするようにした。

Signed-off-by: Kohki Akikaze <[email protected]>
@ghost ghost marked this pull request as draft June 23, 2021 05:33
Comment on lines 573 to 574
template class CRecentImp<CExcludeFileString, LPCWSTR>; // CRecentExcludeFile
template class CRecentImp<CExcludeFolderString, LPCWSTR>; // CRecentExcludeFolder
Copy link
Author

@ghost ghost Jun 23, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CRecentExcludeFile(Grep除外ファイル)・CRecentExcludeFolder(Grep除外フォルダ)のインスタンス化宣言が無かったので追記しました。

Copy link
Member

@kengoide kengoide Jun 25, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

テンプレートの明示的インスタンス化はプログラム中で1回までと規定されているため、これらの定義のうち typedef する前の型が重複しているものは実は規格違反だったりします。MinGWでコンパイルを外しているのは GCC の方がこの点を厳密に検査するからかなと推察しました(検証してない)。

重複してしまう定義は削除したほうがいいと思います。下記のような形になりますね。

template class CRecentImp<StaticString<WCHAR, 260>, LPCWSTR>;
template class CRecentImp<StaticString<WCHAR, 512>, LPCWSTR>;

可読性・保守性が下がりそうで残念ですけども…。

Copy link
Author

@ghost ghost Jun 26, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ちょっと考えましたが、今回は戻しておきます。

可読性・保守性が下がりそうで残念ですけども…。

実はこんな共通定義があります。

//共通型
typedef StaticString<WCHAR,_MAX_PATH> SFilePath;
typedef StaticString<WCHAR, MAX_GREP_PATH> SFilePathLong;

CPathString・CMetaPath・CCurDirString・CSearchString・CReplaceString・CTagjumpKeywordStringはSFilePathと、CGrepFileString・CGrepFolderStringはSFilePathLongと定義内容が同じです。
CExcludeFileString・CExcludeFolderStringの定義で使われる定数MAX_EXCLUDE_PATHはMAX_GREP_PATHと同じ値なので、この二つも現時点ではSFilePathLongと同じと言えます。

この定義を活用して、こう書くこともできますね。

template class CRecentImp<SFilePath, LPCWSTR>;
template class CRecentImp<SFilePathLong, LPCWSTR>;

ただ、そうするなら各クラスでもSFilePath/SFilePathLongを利用するようにしたほうがいいのかな、とも思いました。
(typedefは履歴データ構造体側に移せば、長い型名の短縮に使えそうです。)

最も、履歴関係でSFilePath/SFilePathLongを使ってもよいのかはわかりません。

Copy link
Author

@ghost ghost Jun 26, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

履歴関係でSFilePath/SFilePathLongを使ってもよいのかはわかりません

CSearchStringCReplaceStringCTagjumpKeywordStringは定義こそSFilePathと同じですが、パス文字列ではないので不適切でした😓

@AppVeyorBot
Copy link

Build sakura 1.0.3846 completed (commit e33fa04894 by @kazasaku)

@ghost ghost marked this pull request as ready for review June 23, 2021 06:11
@ghost
Copy link
Author

ghost commented Jun 23, 2021

Azure PipelinesのMinGWビルドが正常終了したのでDraftは外しておきます。

@beru beru added the refactoring リファクタリング 【ChangeLog除外】 label Jun 23, 2021
@ghost ghost changed the title 履歴データ管理クラスに関するヘッダーファイルのインクルード文を整理する 履歴管理クラスに関するインクルード文を整理する Jun 25, 2021
Comment on lines 573 to 574
template class CRecentImp<CExcludeFileString, LPCWSTR>; // CRecentExcludeFile
template class CRecentImp<CExcludeFolderString, LPCWSTR>; // CRecentExcludeFolder
Copy link
Member

@kengoide kengoide Jun 25, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

テンプレートの明示的インスタンス化はプログラム中で1回までと規定されているため、これらの定義のうち typedef する前の型が重複しているものは実は規格違反だったりします。MinGWでコンパイルを外しているのは GCC の方がこの点を厳密に検査するからかなと推察しました(検証してない)。

重複してしまう定義は削除したほうがいいと思います。下記のような形になりますね。

template class CRecentImp<StaticString<WCHAR, 260>, LPCWSTR>;
template class CRecentImp<StaticString<WCHAR, 512>, LPCWSTR>;

可読性・保守性が下がりそうで残念ですけども…。

@AppVeyorBot
Copy link

Build sakura 1.0.3849 completed (commit dc2366f31d by @kazasaku)

@sonarcloud
Copy link

sonarcloud bot commented Jun 26, 2021

Kudos, SonarCloud Quality Gate passed!

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 0 Code Smells

No Coverage information No Coverage information
0.0% 0.0% Duplication

@AppVeyorBot
Copy link

Build sakura 1.0.3850 completed (commit 9445b1e552 by @kazasaku)

Copy link
Member

@kengoide kengoide left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

妥当だと思います。

Copy link
Contributor

@berryzplus berryzplus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ビルドが通れば問題ないと思います。

細かい指摘入れましたが対応は任意っす。

#include "recent/CRecentGrepFile.h"
#include "recent/CRecentGrepFolder.h"
#include "recent/CRecentCmd.h"
#include "recent/CRecentCurDir.h"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

レビュー指摘じゃないんですけど、これらのインクルードがここに必要になるクラス設計がマズいように思います。

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CRecentの各実装クラスをクラスメンバとして保持しない方が良いということでしょうか。
現状では、以下のクラスがCRecentをメンバに持っています。

  • CDlgExec
  • CDlgFavorite
  • CDlgFind
  • CDlgGrep
  • CDlgGrepReplace
  • CDlgFileData
  • CDlgReplace
  • CDlgTagJumpList
  • CMRUFile
  • CMRUFolder
  • CMainToolBar

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

「CRecentの各実装クラス」の役割が謎なんですよね。

実装から推測されるCRecentクラスの役割

  • 履歴配列へのアクセスを容易にする
  • 履歴配列に格納されるデータ型と文字列ポインタの交換を容易にする
  • 共有メモリへのアクセスを局所化する

たぶん、真面目にクラス設計すると共有メモリへの書き込みアクセスがマルチスレッドを考慮してない件に手を入れる必要があるはずで、その役割を持つのはどのクラスか?と考えるとCRecentが最適な気がするわけです。
 👇
もしコレ(=CRecentに排他機能を付ける)に踏み切ろうとすると、例示されたウインドウ系クラスが修正対象になります。クラスのメンバにインスタンスを持つということは、ウインドウを表示している間は他スレッドから書き込みできないということで、容易にデッドlロックするアフォな設計になってしまうからです。

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

メンバにCRecent派生クラスのインスタンスを持たない設計には以下のものがあります。

  • 読み取りアクセスは現状のまま、ロックして書き込む処理を新設する。
  • ロックが必要なときだけ生成するRAIIクラスを新設する。

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

排他制御をCRecent側で行い、利用側が意識しないようにした方が使いやすくなりそうですね。
今のところCAppNodeManagerのメンバ関数だけが、CRecentEditNodeの呼び出し直前にロックを掛けていました。

検討してみます。

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CDlgOpenFileDataクラスは #1481 のマージ以後CRecentのインスタンスを利用していませんでした。
当該コードの除去をCRecent利用側のリファクタリング案件としてPRを提出しようと思います。

#include "recent/CRecentGrepFile.h"
#include "recent/CRecentGrepFolder.h"
#include "recent/CRecentExcludeFile.h"
#include "recent/CRecentExcludeFolder.h"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ここも。

@@ -21,6 +21,7 @@ class CDlgGrep;

#include "dlg/CDialog.h"
#include "dlg/CDlgGrep.h"
#include "recent/CRecentReplace.h"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

これも。

#include "util/window.h"
#include "recent/CRecentReplace.h"
#include "recent/CRecentSearch.h"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

これも。

@@ -26,8 +26,7 @@

#include "StdAfx.h"
#include "recent/CRecentFile.h"
#include <string.h>
#include "env/DLLSHAREDATA.h"
#include "config/maxdata.h"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

指摘です。ここだけmaxdata.hの参照が実装側になってる気がします。ヘッダ側で参照すべきでは?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ヘッダ側で使われていればヘッダ側に、そうでなければソース側に配置する方針で記述しました。

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

方針は了解です。

ただ、maxdata.hに定義されているものは定数なので、「インターフェース or 具象クラス」に当てはめた場合のインターフェース側に当たると思います。

インターフェースの参照は、ヘッダで行うべきな気がします。
ま、言ってみてるだけ(≒このコメントは指摘じゃない)ですが。

@@ -26,8 +26,7 @@

#include "StdAfx.h"
#include "CRecentFolder.h"
#include <string.h>
#include "env/DLLSHAREDATA.h"
#include "config/maxdata.h"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

あ、ここもやw

sakura_core/recent/CRecentFolder.h Show resolved Hide resolved
@@ -26,8 +26,7 @@

#include "StdAfx.h"
#include "CRecentReplace.h"
#include <string.h>
#include "env/DLLSHAREDATA.h"
#include "config/maxdata.h"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ここもやw (実装側じゃなくヘッダ側に書くべきじゃ・・・

@@ -26,8 +26,7 @@

#include "StdAfx.h"
#include "CRecentTagjumpKeyword.h"
#include "env/DLLSHAREDATA.h"
#include <string.h>
#include "config/maxdata.h"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ここもやw (同上

@ghost
Copy link
Author

ghost commented Jun 29, 2021

レビューありがとうございました。マージしてしまいます。

CRecentの各派生クラスは今後変更すると思うので、その時にmaxdata.hのインクルード位置を再考します。

@ghost ghost merged commit 9768d7f into sakura-editor:master Jun 29, 2021
@ghost
Copy link
Author

ghost commented Jun 29, 2021

本文に記載した3件のSonarQubeによる指摘が消えたことを確認しました。

@ghost ghost deleted the feature/fix_crecent_header_including branch June 29, 2021 14:12
This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
refactoring リファクタリング 【ChangeLog除外】
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants