sonar-delphi
sonar-delphi copied to clipboard
Catch redundant member access casts in RedundantCast
Prerequisites
- [X] This improvement has not already been suggested.
- [X] This improvement should not be implemented as a separate rule.
Rule to improve
RedundantCast
Improvement description
The RedundantCast rule could be updated to catch cast expressions followed by a member access, in cases where the cast is not required to access the member.
For example:
type
TMyClass = class(TObject)
public
procedure Foo;
end;
// ...
procedure DoFoo(MyObj: TMyClass);
begin
TMyClass(MyObj).Foo;
end;
Rationale
This improvement would catch a number of sneaky code smells that commonly occur when refactoring.
For example. consider a protected field on a class that is accessed from another unit by declaring a descendant class in the same unit, e.g.
// Unit1.pas
type
TMyActualClass = class(TObject)
protected
procedure SecretProc;
end;
// Unit2.pas
type
TMyFriendClass = class(TMyActualClass);
procedure DoSecretProc(MyObj: TMyActualClass);
begin
TMyFriendClass(MyObj).SecretProc;
end;
If a refactor changed TMyActualClass.SecretProc to public, the cast is no longer required to access SecretProc. This is easy to miss when refactoring and results in unnecessary complexity sticking around in the codebase.