From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-0.9 required=5.0 tests=BAYES_00,FUZZY_VPILL autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,4c459ff0adb576bc X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2002-02-02 12:29:33 PST Path: archiver1.google.com!news1.google.com!newsfeed.stanford.edu!news-spur1.maxwell.syr.edu!news.maxwell.syr.edu!fu-berlin.de!uni-berlin.de!ppp-1-102.5800-9.telinco.NET!not-for-mail From: "Nick Roberts" Newsgroups: comp.lang.ada Subject: Re: Refactoring and Ada Date: Sat, 2 Feb 2002 17:48:49 -0000 Message-ID: References: <3C5AB0B7.9D75D49A@grammatech.com> NNTP-Posting-Host: ppp-1-102.5800-9.telinco.net (212.1.136.102) X-Trace: fu-berlin.de 1012681770 42477580 212.1.136.102 (16 [25716]) X-Priority: 3 X-MSMail-Priority: Normal X-Newsreader: Microsoft Outlook Express 5.50.4133.2400 X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4133.2400 Xref: archiver1.google.com comp.lang.ada:19535 Date: 2002-02-02T17:48:49+00:00 List-Id: Paul, Ada has a co-standard called ASIS, which provides a standardised way for (Ada) programs to access Ada source code broken down (by a compiler front-end) into its structural form. Thus, Ada refactoring tools will typically use ASIS as the mechanism to do their work. (If not, they will either have to use a standalone lexical parser, e.g. OpenToken, or a compiler's front-end directly). So, if you were to do a Internet search on keywords such as "ASIS" and "OpenToken", you are liekly to get some good leads. The http://www.adapower.com web site could also be a good source of information. I suspect most of the classic refactorings, like global rename, will apply to Ada just as to Java and Smalltalk. I suspect that, in the case of Ada, refactoring in support of legacy code is unlikely in practice. This is largely because Ada 95 contains virtually no incompatibilties with Ada 83, and added no features so valuable that it would make it desirable to refactor Ada 83 code to use those features. [ *** WARNING: mind-numbing esoterica follows; no liability for brain damage can be accepted. *** ] If you would like me to throw in my own ideas, one fairly elaborate one occurs to me, to do with providing support for Aspect-Oriented Programming in Ada. It would work something like as follows. First, the user specifies a list A of aspects, each having a name N (which is a valid Ada name). One of these aspects is designated the default Nd. Each name would either be simple (an identifier) or compound (having a prefix). The operation is applied to a library package P, and does the following: (1) for each (N) of all the aspects in A, write a new private package specification named P.N, containing an inlined declaration for each subprogram S declared in the specification of P, each such declaration being a copy of the declaration of S but excluding out-mode parameters in the case of the default aspect, and a procedure in all other cases with the same parameters but excluding the out-mode (and return) parameters; (2) rewrite the existing body of P with the name P.Nd (but otherwise unchanged); (3) for each (N) of the other aspects in A, write a new body named P.N, which contains a null completion for each subprogram in the specification of P; (4) write a new body of P, with a completion for each subprogram in the specification of P, each such completion containing (only) a call to each member (N) of A (in the order given) in the form "P.N(parameters)" where the parameters are a repetition of the formal parameters of the subprogram, and the result of a function is held in a temporary and returned at the end, if necessary. In addition, for each member of the set formed by the closure of the ancestors of the (compound) names of A, write out an empty private package specification. An example might illuminate the idea. Suppose we have a package: with Customers; package Ice_Cream is type Cone is private; function Make return Cone; procedure Eat (Item: in out Cone; Person: in out Customers.Human); private ... private stuff end Ice_Cream; package body Ice_Cream is function Make return Cone is begin ... make a cone end; procedure Eat (Item: in out Cone; Person: in out Customers.Human) is begin ... eat a cone end; end Ice_Cream; Now, suppose we wished to divide this into the aspects: Debug.Before; Main; Debug.After. The refactoring would generate the following compilation units: private package Ice_Cream.Debug is end; private package Ice_Cream.Debug.Before is procedure Make; procedure Eat (Item: in out Cone; Person: in out Customers.Human); pragma Inline(Make,Eat); end Ice_Cream.Debug.Before; private package Ice_Cream.Main is function Make return Cone; procedure Eat (Item: in out Cone; Person: in out Customers.Human); pragma Inline(Make,Eat); end Ice_Cream.Main; private package body Ice_Cream.Debug.After is procedure Make; procedure Eat (Item: in out Cone; Person: in out Customers.Human); pragma Inline(Make,Eat); end Ice_Cream.Debug.After; package body Ice_Cream.Debug.Before is procedure Make is begin null; end; procedure Eat (Item: in out Cone; Person: in out Customers.Human) is begin null; end; end Ice_Cream.Debug.Before; package body Ice_Cream.Main is function Make return Cone is begin ... make a cone end; procedure Eat (Item: in out Cone; Person: in out Customers.Human) is begin ... eat a cone end; end Ice_Cream.Main; package body Ice_Cream.Debug.After is procedure Make is begin null; end; procedure Eat (Item: in out Cone; Person: in out Customers.Human) is begin null; end; end Ice_Cream.Debug.After; The following replacement compilation unit would be generated: package body Ice_Cream is function Make return Cone is Temp: Cone; begin Ice_Cream.Debug.Before.Make; Temp := Ice_Cream.Main.Make; Ice_Cream.Debug.After.Make; return Temp; end; procedure Eat (Item: in out Cone; Person: in out Customers.Human) is begin Ice_Cream.Debug.Before.Eat(Item,Person); Ice_Cream.Main.Eat(Item,Person); Ice_Cream.Debug.After.Eat(Item,Person); end; end Ice_Cream.Main; For any other compilation unit written, if the unit already exists, it is not replaced. Obviously, the idea is to automatically generate a skeleton that provides for the separation of the implementation of a library package into a set of different aspects. It also would be good to have operations that: added aspects to an implementation already divided; coalesced several aspects back into one; coalesced all the aspects back into one body. I'm sure that any number of similarly specialised and elaborate refactorings could be useful to some people. I'm also sure that useful manipulations would not be limited to those which preserve (external) semantics. -- Nick Roberts "Paul Anderson" wrote in message news:3C5AB0B7.9D75D49A@grammatech.com... > > Hi! > > As part of a government research contract, we are developing a > Refactoring editor for Ada. I am interested in soliciting opinions > from the group about Refactoring and Ada. > > For those that don't know, Refactoring is defined as "a technique to > restructure code in a disciplined way." It has been associated with > Extreme Programming, but stands on its own as a highly useful > technique. General information about Refactoring can be found at > http://www.refactoring.com. > > I am interested in finding out if there are any Ada projects out there > that actively use refactoring. If so, what refactorings do you use? > Are they just like the Java ones, or are there features of Ada that > mandate special-purpose refactorings? What features would you like to > see in a refactoring editor for Ada? > > I am especially interested in any use of refactoring in support of > legacy code, either to clean up code that has been automatically > translated to Ada, or to prepare Ada code so that it can be translated > more easily into something else. > > Best regards, and thanks in advance for your input. > > Paul. > > ______ > Paul Anderson. GrammaTech, Inc. Tel: +1 607 273-7340 x18 > mailto:paul@grammatech.com http://www.grammatech.com