Jump to content
Ian Branch

UsesCleaner Issue...

Recommended Posts

Hi Team, Uwe,

I had the following code..

  {$IFDEF VER140}Variants,{$ENDIF}{Delphi 6}
  {$IFDEF VER150}Variants,{$ENDIF}{Delphi 7}
  {$IFDEF VER170}Variants,{$ENDIF}{Delphi 2005}
  {$IFDEF VER180}Variants,{$ENDIF}{Delphi 2006/7}
  {$IFDEF VER200}Variants,{$ENDIF}{Delphi 2009}
  {$IFDEF VER210}Variants,{$ENDIF}{Delphi 2010}
  {$IFDEF VER220}Variants,{$ENDIF}{Delphi XE}
  {$IFDEF VER230}Variants,{$ENDIF}{Delphi XE2}
  {$IFDEF VER240}Variants,{$ENDIF}{Delphi XE3}
  {$IFDEF VER250}Variants,{$ENDIF}{Delphi XE4}
  {$IFDEF VER260}Variants,{$ENDIF}{Delphi XE5}
  {$IFDEF VER270}Variants,{$ENDIF}{Delphi XE6}
  {$IFDEF VER280}Variants,{$ENDIF}{Delphi XE7}
  {$IFDEF VER290}Variants,{$ENDIF}{Delphi XE8}
  {$IFDEF VER300}Variants,{$ENDIF}{Delphi 10 Seattle}
  {$IFDEF VER310}Variants,{$ENDIF}{Delphi 10.1 Berlin}
  {$IFDEF VER320}Variants,{$ENDIF}{Delphi 10.2 Tokyo}
  {$IFDEF VER330}Variants,{$ENDIF}{Delphi 10.3 Rio}
  {$IFDEF VER340}Variants, System.UITypes, VCL.FileCtrl,{$ENDIF}{Delphi 10.4 Sydney}
  {$IFDEF VER350}Variants, System.UITypes, VCL.FileCtrl,{$ENDIF}{Delphi 11}

I applied UsesCleaner.exe and got the following..

  Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Menus, Vcl.Buttons, Vcl.ExtCtrls, Vcl.StdCtrls, Vcl.DBCtrls, Vcl.DBLogDlg, Vcl.Printers,
  * {Delphi 6}, * {Delphi 7}, * {Delphi 2005}, * {Delphi 2006/7}, * {Delphi 2009}, * {Delphi 2010}, * {Delphi XE}, * {Delphi XE2}, * {Delphi XE3},
  * {Delphi XE4}, * {Delphi XE5}, * {Delphi XE6}, * {Delphi XE7}, * {Delphi XE8}, * {Delphi 10 Seattle}, * {Delphi 10.1 Berlin},
  * {Delphi 10.2 Tokyo}, * {Delphi 10.3 Rio}, * {Delphi 10.4 Sydney}, * {Delphi 11}

Is there any chance of this being addressed??

 

Regards & TIA,

Ian

Share this post


Link to post
5 hours ago, Ian Branch said:

  {$IFDEF VER140}Variants,{$ENDIF}{Delphi 6}
  {$IFDEF VER150}Variants,{$ENDIF}{Delphi 7}
  {$IFDEF VER170}Variants,{$ENDIF}{Delphi 2005}
  {$IFDEF VER180}Variants,{$ENDIF}{Delphi 2006/7}
  {$IFDEF VER200}Variants,{$ENDIF}{Delphi 2009}
  {$IFDEF VER210}Variants,{$ENDIF}{Delphi 2010}
  {$IFDEF VER220}Variants,{$ENDIF}{Delphi XE}
  {$IFDEF VER230}Variants,{$ENDIF}{Delphi XE2}
  {$IFDEF VER240}Variants,{$ENDIF}{Delphi XE3}
  {$IFDEF VER250}Variants,{$ENDIF}{Delphi XE4}
  {$IFDEF VER260}Variants,{$ENDIF}{Delphi XE5}
  {$IFDEF VER270}Variants,{$ENDIF}{Delphi XE6}
  {$IFDEF VER280}Variants,{$ENDIF}{Delphi XE7}
  {$IFDEF VER290}Variants,{$ENDIF}{Delphi XE8}
  {$IFDEF VER300}Variants,{$ENDIF}{Delphi 10 Seattle}
  {$IFDEF VER310}Variants,{$ENDIF}{Delphi 10.1 Berlin}
  {$IFDEF VER320}Variants,{$ENDIF}{Delphi 10.2 Tokyo}
  {$IFDEF VER330}Variants,{$ENDIF}{Delphi 10.3 Rio}
 {$IF CompilerVersion >= 14}Variants,{$ENDIF}

 

  • Like 2

Share this post


Link to post
47 minutes ago, Fr0sT.Brutal said:

 {$IF CompilerVersion >= 14}Variants,{$ENDIF}

 

Or if earlier versions are to be supported:

$IFDEF CONDITIONALEXPRESSIONS}
  {$IF CompilerVersion >= 14.0}
    Variants,
  {$IFEND}
{$ENDIF}

If not, then Variants might just as well be moved outside the conditional.

Share this post


Link to post

Hi Team,

So, playing with the CompilerVersion I get some strange results.

Starting with this..

  {$IFDEF VER130}TeeProcs, TeEngine, Chart, Series;{$ENDIF}{Delphi 5}
  {$IFDEF VER140}TeeProcs, TeEngine, Chart, Series;{$ENDIF}{Delphi 6}
  {$IFDEF VER150}TeeProcs, TeEngine, Chart, Series;{$ENDIF}{Delphi 7}
  {$IFDEF VER170}TeeProcs, TeEngine, Chart, Series;{$ENDIF}{Delphi 2005}
  {$IFDEF VER180}TeeProcs, TeEngine, Chart, Series;{$ENDIF}{Delphi 2006/7}
  {$IFDEF VER200}TeeProcs, TeEngine, Chart, Series;{$ENDIF}{Delphi 2009}
  {$IFDEF VER210}TeeProcs, TeEngine, Chart, Series;{$ENDIF}{Delphi 2010}
  {$IFDEF VER220}TeeProcs, TeEngine, Chart, Series;{$ENDIF}{Delphi XE}
  {$IFDEF VER230}TeeProcs, TeEngine, Chart, Series;{$ENDIF}{Delphi XE2}
  {$IFDEF VER240}VCLTee.TeeProcs, VCLTee.TeEngine, VCLTee.Chart, VCLTee.Series;{$ENDIF}{Delphi XE3}
  {$IFDEF VER250}VCLTee.TeeProcs, VCLTee.TeEngine, VCLTee.Chart, VCLTee.Series;{$ENDIF}{Delphi XE4}
  {$IFDEF VER260}VCLTee.TeeProcs, VCLTee.TeEngine, VCLTee.Chart, VCLTee.Series;{$ENDIF}{Delphi XE5}
  {$IFDEF VER270}VCLTee.TeeProcs, VCLTee.TeEngine, VCLTee.Chart, VCLTee.Series;{$ENDIF}{Delphi XE6}
  {$IFDEF VER280}VCLTee.TeeProcs, VCLTee.TeEngine, VCLTee.Chart, VCLTee.Series;{$ENDIF}{Delphi XE7}
  {$IFDEF VER290}VCLTee.TeeProcs, VCLTee.TeEngine, VCLTee.Chart, VCLTee.Series;{$ENDIF}{Delphi XE8}
  {$IFDEF VER300}VCLTee.TeeProcs, VCLTee.TeEngine, VCLTee.Chart, VCLTee.Series;{$ENDIF}{Delphi 10 Seattle}
  {$IFDEF VER310}VCLTee.TeeProcs, VCLTee.TeEngine, VCLTee.Chart, VCLTee.Series;{$ENDIF}{Delphi 10.1 Berlin}
  {$IFDEF VER320}VCLTee.TeeProcs, VCLTee.TeEngine, VCLTee.Chart, VCLTee.Series;{$ENDIF}{Delphi 10.2 Tokyo}
  {$IFDEF VER330}VCLTee.TeeProcs, VCLTee.TeEngine, VCLTee.Chart, VCLTee.Series, VclTee.TeeGDIPlus;{$ENDIF}{Delphi 10.3 Rio}
  {$IFDEF VER340}VCLTee.TeeProcs, VCLTee.TeEngine, VCLTee.Chart, VCLTee.Series;{$ENDIF}{Delphi 10.4 Sydney}
  {$IFDEF VER350}VCLTee.TeeProcs, VCLTee.TeEngine, VCLTee.Chart, VCLTee.Series;{$ENDIF}{Delphi 11}

This works fine in D10.4.2 & D11.

 

Implementing the CompilerVersion idea..

In D11 - At design time this is quite happy..

{code}

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ExtCtrls, Menus, printers,
{$IF (CompilerVersion >= 13.0) and (CompilerVersion <= 23.0)}TeeProcs, TeEngine, Chart, Series;{$ENDIF}
{$IF CompilerVersion >= 24.0}VCLTee.TeEngine, VCLTee.Series, VCLTee.TeeProcs, VCLTee.Chart, VclTee.TeeGDIPlus;{$ENDIF}

{code}

When I build the app it does this and of course errors..

{code}

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ExtCtrls, Menus, printers, VclTee.TeeGDIPlus, VCLTee.TeEngine, VCLTee.Series, VCLTee.TeeProcs, VCLTee.Chart,
{$IF (CompilerVersion >= 13.0) and (CompilerVersion <= 23.0)}TeeProcs, TeEngine, Chart, Series;{$ENDIF}
{$IF CompilerVersion >= 24.0}VCLTee.TeEngine, VCLTee.Series, VCLTee.TeeProcs, VCLTee.Chart, VclTee.TeeGDIPlus;{$ENDIF}

{code}

It is obviously happy at build time with the "{$IF (CompilerVersion >= 13.0) and (CompilerVersion <= 23.0)}TeeProcs, TeEngine, Chart, Series;{$ENDIF}" line.

I don't understand what its problem is with the second line..

I get similar but not the same results in D10.4.2.

Is this a bug??

 

Ian

Share this post


Link to post

Adding these additional units is something the IDE does by itself during Save when related components are placed on the form. Unfortunately the IDE is not able to resolve the conditionals. That is one of the reasons why I rate Conditional Uses Clause Considered Harmful, AFAIK, there is no working solution to prohibit this behavior of the IDE. All approaches I am aware of have glitches in some scenarios.

Share this post


Link to post

Tks Uwe,

In my case it also seems to be related to the presence/need for VclTee.TeeGDIPlus because there is an actual graph on the form.

In other units there is no graph and the CompilerVersion conditionals are quite happy.

 

Ian

Share this post


Link to post
1 hour ago, Uwe Raabe said:

Adding these additional units is something the IDE does by itself during Save when related components are placed on the form.

It would be stellar if we had a switch that could disable this behavior completely. I'm sick and tired of cleaning up the uses clause before commit, every time I have had a form open in the IDE during debug. Particularly since DevExpress keeps adding stupid dependencies between their units which causes the uses list to grow and grow for no good reason.

Share this post


Link to post
5 minutes ago, Ian Branch said:

In my case it also seems to be related to the presence/need for VclTee.TeeGDIPlus because there is an actual graph on the form.

If you create the graph in code instead of placing it on the form then the IDE will not try to add those units to the uses list.

Share this post


Link to post

Alas, auto-using units is a real pain. There's no any good solution that I'm aware of. The most simple is to use traditional IFDEF approach which IDE could understand at design-time but with COMPILER_XXX_UP defines (borrow them from JEDI or anything else). Definition of these flags look VERY sracy but at least they live in separate .inc file that's hidden from coder's eyes. So instead of the same lines for every version you'll have

{$IFDEF DELPHI_XE_UP} Namespace.SomeUnit, {$ELSE}
{$IFDEF DELPHI_7_UP} SomeUnit, {$ENDIF}
{$ENDIF}

note the descending order. But every new compiler version must be added to defines list or build would fail (many libs and components suffer from this flaw - all these "added support for Delphi %NewVer%" updates mainly add the corresponding define).

There's also option to set aliases for namespaces in project options and use old-style short names though it could only solve a part of these issues.

 

8 hours ago, Anders Melander said:

It would be stellar if we had a switch that could disable this behavior completely. I'm sick and tired of cleaning up the uses clause before commit

Pre-commit hooks? Also it's a very useful idea for an IDE expert, something like cnPack's property cleaner

Edited by Fr0sT.Brutal

Share this post


Link to post

There are two project option settings that might help here:

Unit aliases and namespaces

It's not easy either though.

Share this post


Link to post
1 hour ago, Fr0sT.Brutal said:

Pre-commit hooks? Also it's a very useful idea for an IDE expert, something like cnPack's property cleaner

How would the pre-commit hook distinguish my manual changes from the automatic changes made by the IDE?

  • Like 1

Share this post


Link to post
On 12/10/2021 at 2:54 PM, Anders Melander said:

How would the pre-commit hook distinguish my manual changes from the automatic changes made by the IDE?

IDE seems to always add units to the end. So you can check the tail of uses list for VCL-related stuff (by namespace prefix, f.ex. - not a universal solution though as there could be 3rd party components/controls). Or you can add a dummy unit that should always be the last one in uses list so anything that goes after is auto-added. Control over it could be bound to the same pre-commit hook. Or you can add a never-enabled dummy ifdef to the very end of uses list that will function like a signature:

uses .... SomeUnit {$ifdef foo} USES_END {$endif}

Of course, these solutions require somewhat ordering in uses clause.

Alternatively, a tool could store uses lists for any unit and reject any changes so a dev using a new unit should additionally allow it.

Edited by Fr0sT.Brutal

Share this post


Link to post
13 minutes ago, Fr0sT.Brutal said:

Of course, these solutions require somewhat ordering in uses clause.

Which is the main purpose of Uses Cleaner btw. 

 

I have to admit that I hesitated a lot before adding the handling of conditionals in Uses Cleaner, simply because I still think it is a bad approach for so many reasons - the IDE being one of them. My goal was to pressure people to get rid of these when they want to use Uses Cleaner efficiently. In a weak moment I implemented it to handle constructs like

{$IFDEF USE_CODESITE}CodeSiteLogging{$ENDIF} properly. Probably a big mistake...

Share this post


Link to post
1 hour ago, Uwe Raabe said:

My goal was to pressure people to get rid of these when they want to use Uses Cleaner efficiently

I think people wouldn't use them if they could avoid them. Alas, sometimes there's no other way

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×