Jump to content
Uwe Raabe

On The Design Of Uses Clauses

Recommended Posts

4 minutes ago, Bill Meyer said:

I can attest that the Peganza Pascal Analyzer Lite Uses Report has been very helpful. Note, however, that it is by no means perfect.

If you can provide reproducible test cases, you should send them to Peganza. They are always interested in cleaning out those glitches.

Share this post


Link to post
34 minutes ago, Uwe Raabe said:

If you can provide reproducible test cases, you should send them to Peganza. They are always interested in cleaning out those glitches.

I have had some correspondence with them. At present, the problem is that the project is huge, and some of these issues depend on third-party components, as well. One example I have already communicated to them is with respect to DevExpress components, where there are numerous units involved in various features, such as look and feel, which they identify as removable, but which are required. It is not a huge issue, and CnPack is similarly confused by DevExpress, so I generally remove them, and the file save puts some back in.

Share this post


Link to post

AFAIU, the only truly reliable way of detecting excess uses is removing each used unit one by one and try compiling. But even then there are possible false positives when something useful happens in unit's init section.

Anyway I doubt this task is required frequently so slow process or some part of false positives is quite acceptable

Share this post


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

AFAIU, the only truly reliable way of detecting excess uses is removing each used unit one by one and try compiling. But even then there are possible false positives when something useful happens in unit's init section.

Anyway I doubt this task is required frequently so slow process or some part of false positives is quite acceptable

CnPack does a quite job of finding those which are not needed. Pascal Analyzer Lite does a good job identifying those which can be moved down to implementation.

 

As the the frequency or magnitude of the process, it depends on what you are doing. In my case, a large legacy code base needs cleaning. That becomes tedious, and false positives are not "quite acceptable." After a hundred or so modules, however, it's easier to overlook them.

Share this post


Link to post

I-Pascal reports unused units on the fly and the ones which can be moved to implementation as well. And can apply the changes automatically as well as mark some unit in uses useful to not report it anymore.

As of class helper case - interesting case, need to think about it.

9 hours ago, Fr0sT.Brutal said:

AFAIU, the only truly reliable way of detecting excess uses is removing each used unit one by one and try compiling.

Even this is not absolutely reliable as you mentioned. But working with AST can give acceptable result.

Share this post


Link to post
On 8/27/2019 at 8:08 AM, Fr0sT.Brutal said:

AFAIU, the only truly reliable way of detecting excess uses is removing each used unit one by one and try compiling.

Impractical in large legacy projects.

Share this post


Link to post
1 hour ago, Bill Meyer said:

Impractical in large legacy projects.

This 1) only should be done once 2) could be done by a not so genius utility

Share this post


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

This 1) only should be done once 2) could be done by a not so genius utility

Given that the legacy code contains things badly done, it may well need to be done more than once. Also, it is not merely a question of removing those not needed, but of demoting to implementation those which are not needed in the interface section.

And in the presence of 2000+ modules, and a couple of million lines of code, few things are trivial.

Share this post


Link to post
15 hours ago, Bill Meyer said:

Given that the legacy code contains things badly done, it may well need to be done more than once. Also, it is not merely a question of removing those not needed, but of demoting to implementation those which are not needed in the interface section.

And in the presence of 2000+ modules, and a couple of million lines of code, few things are trivial.

So why bother this at all? Uses manipulations are no more than a cosmetic change. Of course the intention could be to remove some 3rd party deps, but that anyway requires much more brain than a mechanical purging/grouping.

Share this post


Link to post
6 hours ago, Fr0sT.Brutal said:

So why bother this at all? Uses manipulations are no more than a cosmetic change. Of course the intention could be to remove some 3rd party deps, but that anyway requires much more brain than a mechanical purging/grouping.

Multiple reasons. Legacy code collects detritus, in this case, some unneeded uses references. Moreover, in this project, there are a large number of unit dependency cycles, and those need reduction. A step on the path is moving to the implementation section those references which need not be in the interface. It would be nice if there were some tool which assisted in determining which units are the bad actors in the dependency cycles, but there are none, to my knowledge. 

Another aspect is that Delphi's libraries have grown over time, and now contain functions which in earlier days were written in house. Nice to reduce the home-grown little routines, where possible.

And yes, another part of the process is the transition from old components which may now be orphans to others which are well supported. It seems common, in legacy code, to find many more component vendors represented than is needful.

 

Finally, yes, much work requires more than mechanical grouping and purging. But code rot must be fought, else it continues, in the dark.

Share this post


Link to post
2 hours ago, Bill Meyer said:

Finally, yes, much work requires more than mechanical grouping and purging. But code rot must be fought, else it continues, in the dark.

I'm always voting for code cleanup. And still insist that pretty much of what could be done automatically for this issue could be done via "comment a unit - try to build - OK: remove unit / Fail: revert unit - repeat" cycle. You don't even have to build the whole project as command line compiler, IIRC, allows building separate units. Though, any other cases still require developer's brain. When tools become so smart they could decide that SomeOldLib.i2s is the same as RTL IntToStr we all human devs will become obsolete.

Btw, (I'm sure you know that perfectly) any unit removal could potentially lead to subtle bugs even if it seems excess: unit init sections or overridden identifiers. Of course, a tool could check for these cases and leave decision to a user... maybe Pascal analyzer can do it?

Edited by Fr0sT.Brutal

Share this post


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

I'm always voting for code cleanup. And still insist that all that could be done automatically for this issue could be done via "comment a unit - try to build - OK: remove unit / Fail: revert unit - repeat" cycle. You don't even have to build the whole project as command line compiler, IIRC, allows building separate units. Though, any other cases still require developer's brain. When tools become so smart they could decide that SomeOldLib.i2s is the same as RTL IntToStr we all human devs will become obsolete.

Btw, (I'm sure you know that perfectly) any unit removal could potentially lead to subtle bugs even if it seems excess: unit init sections or overridden identifiers.

It gets to be a considerable challenge when a uses clause references >200 modules. And when the cycles reported by MMX include some in which there are 100+ modules named. Then the question is how to tell which are causing cycles, and which are simply along for the ride?

And then there is the problem of initialization. I replaced all initialization/finalization clauses with explicit calls and a module to make those calls, so that I had a deterministic solution. Prior to that, changes to a uses clause could result in a different sequence of initialization, and some of the init clauses assumed other modules had already been initialized. 

Share this post


Link to post
16 hours ago, Bill Meyer said:

It gets to be a considerable challenge when a uses clause references >200 modules. And when the cycles reported by MMX include some in which there are 100+ modules named

OUCH!

That's really a heavy monstrous piece of petrified sh- ehm, code.

Share this post


Link to post
3 hours ago, Fr0sT.Brutal said:

OUCH!

That's really a heavy monstrous piece of petrified sh- ehm, code.

It's a... challenge.

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

×