Book a Demo

Author Topic: Delphi Support - Close, but no Kewpie Doll  (Read 7449 times)

greygor

  • EA Novice
  • *
  • Posts: 18
  • Karma: +0/-0
  • I love YaBB 1 Gold!
    • View Profile
Delphi Support - Close, but no Kewpie Doll
« on: March 19, 2002, 03:57:52 am »
Ok, you're nearly there with the Delphi Import/Export, but there are some major problems.

Let's deal with Interfaces first.


INTERFACE SOURCE

 ICommunicate = interface
   procedure Speak(Message: string);
   function Agree(Message: string): Boolean;
 end;

When imported the procedure and function is protected scope rather than public scope.  There is no scoping for interfaces.

When we forward engineer this from EA then the following is generated


GENERATED INTERFACE SOURCE

unit InterfaceTestGen;

interface

uses
     system, graphics;;

type
 ICommunicate = interface (TObject)

protected
     procedure   Speak(Message: string);
     function    Agree(Message: string): Boolean;

 end;

implementation

procedure   ICommunicate.Speak(Message: string);
begin

end;

function    ICommunicate.Agree(Message: string): Boolean;
begin

end;



end.

1. There should only be one semi-colon after the Uses Clause.
2. The ultimate ancestor of Interface is IInterface, not TObject.
3. Interfaces are implemented in classes and so have no implementation.
4. There is no scoping allowed as Public is the default.

what should be generated is

unit InterfaceTestGen;

interface

uses System;

Type

 ICommunicate = interface
   procedure Speak(Message: string);
   function Agree(Message: string): Boolean;
 end;

implementation

end.





Now for Classes


CLASS SOURCE


unit ClassTest;

interface

uses system, graphics;

Type

 TMammal = class(TObject, ICommunicate)
 private
   FEyeColour: TColor;
   procedure SetEyeColour(const Value: TColor);
 protected
   function Agree(Message: string): Boolean;
 published
   property EyeColour: TColor read FEyeColour write SetEyeColour;
   procedure Testing;
 public
   procedure Speak(Message: string);
 end;

 THuman = class(TMammal)
 automated
   procedure Test2(MyOtherTest: TFont);
 end;

 TAlmostHuman = class(TMammal)
   procedure Test3(MyLastTest: Boolean);
 end;

implementation

function Test1(MyTest: integer): string;
begin
 //code
end;

{ TMammal }

function TMammal.Agree(Message: string): Boolean;
begin
 //code
end;

procedure TMammal.SetEyeColour(const Value: TColor);
begin
 FEyeColour := Value;
end;

procedure TMammal.Speak(Message: string);
begin
 //code
end;

procedure TMammal.Testing;
begin
 //code
end;

{ THuman }

procedure THuman.Test2(MyOtherTest: TFont);
begin
 //code
end;

{ TAlmostHuman }

procedure TAlmostHuman.Test3(MyLastTest: Boolean);
begin
 //code
end;

end.



As we can See TMammal is descended from TObject and Implements the Interface ICommunicate.  It uses the 4 main scoping directives of Delphi; Private, Protected, Published and Public.

when we reverse engineer the TMammal class we get the following.

unit classTestGen;

interface

type
 TMammal = class (TObject)

public
     procedure   Speak(Message: string);

protected
     function    Agree(Message: string): Boolean;

private
     FEyeColour: TColor;
     procedure   SetEyeColour(Value: TColor);

 end;

implementation

procedure   TMammal.Speak(Message: string);
begin

end;

function    TMammal.Agree(Message: string): Boolean;
begin

end;

procedure   TMammal.SetEyeColour(Value: TColor);
begin

end;



end.


As you can see neither the published method Testing nor the published property has been generated. Thinking that this was a problem with recognising Published scoping I put a property in the public section and resynchronised and then forward engineered the class.  This resulted in the following.

type
 TMammal = class (TObject)

public
     procedure   Speak(Message: string);

protected
     function    Agree(Message: string): Boolean;

private
     FEyeColour: TColor;
     FEyeColour2: TColor;
     procedure   SetEyeColour(Value: TColor);
     procedure   SetEyeColour2(Value: TColor);

public
     property +EyeColour2:TColor read FEyeColour2 write SetEyeColour2;


 end;

As you can see we now have the property generated but in a separate public section from the other public procedure and we have a '+' concatenated on the fromt of the property name.  So apart from that it is right.



Next, Delphi default scoping.

If in a Delphi unit 'Forms' is in the Interface uses clause then the default scoping is Published, else it is Public.  Thus


 TAlmostHuman = class(TMammal)
   procedure Test3(MyLastTest: Boolean);
 protected
   procedure Test4;
 end;

If 'Forms' in the uses clause then Test3 is Published, otherwise it is Public.


Finally, Automated.  This is legacy so you may not want to bother but

 THuman = class(TMammal)
 automated
   procedure Test2(MyOtherTest: TFont);
 end;

is a perfectly valid piece of Delphi code.  Not sure how you would identify this in UML or EA.


I hope this has been some help, if you have any questions please don't hesitate to contact me.


Mark Stansfield
Senior Developer/Trainer
Runtime Technology
www.runtime.co.uk
[email protected]

mh

  • EA Novice
  • *
  • Posts: 7
  • Karma: +0/-0
    • View Profile
Re: Delphi Support - Close, but no Kewpie Doll
« Reply #1 on: March 19, 2002, 12:13:41 pm »
> If 'Forms' in the uses clause then Test3 is Published,
> otherwise it is Public

actually, the default visibility is ALWAYS published. it's just that for classes declared inside an {$M+} (and not derrived from a class that was, such as TPersistent) published and public are in fact identical.

it has nothing to do with what's in the uses clause and what's not (god forbid this was the case...)

for the sake of a CASE tool, publsihed should always be treated as published.
marc hoffman ([email protected])
elitedevelopments software
http://www.elitedevelopments.com

gsparks

  • EA User
  • **
  • Posts: 325
  • Karma: +0/-0
  • I love YaBB 1 Gold!
    • View Profile
Re: Delphi Support - Close, but no Kewpie Doll
« Reply #2 on: March 19, 2002, 09:06:51 pm »
Hi,

Thanks for the feedback - I have implemented most of the required changes as per the above notes. I will get some testing happening on the new code and hopefully a patch will be available in the next week or less.

Just a note on the Published scope - as this does not have a UML equivalent, Published is only in the drop down lists for Dephi attributes, procedures and properties. When exported to XMI the 'published' scope will be 'public', with a tagged value of scope=published, indicating the Delphi preferred scope.

Geoff Sparks



greygor

  • EA Novice
  • *
  • Posts: 18
  • Karma: +0/-0
  • I love YaBB 1 Gold!
    • View Profile
Re: Delphi Support - Close, but no Kewpie Doll
« Reply #3 on: March 20, 2002, 02:20:46 am »
That's what I get for oversimplyfying the situation to try and make things easier.  However mh is quite right, so lets do this properly.

The default scoping is controlled by the {$M} directive.

{$M+} default Published
{$M-} default Public

However in many cases this is not found in a unit so how can EA tell what it should be.

These are some guidelines.

1. Anything derived directly from TObject, i.e. TMyObject = class or TMyObject = class(TObject) will have a default scoping of Public unless {$M+} is used.

2. Anything derived from TPersistant or its descendents will have a default scoping of Published (Because TPersistant is compiled with {$M+}) unless the {$M-} is used.

3. As TForm is derived from TComponent, which is derived from TPersistant, it has a default scoping of Published. Thus as I was trying to say, albeit badly, you would be right the majority of the time to assume a default scoping of published for Units with Forms in the Uses clause.  However this would not cater for the times when other classes may be declared in the same unit and derived from TObject (Case 1 above).

Mind you, this is according to Borland.  However in experimentation I have found that if I derive a class from TObject and declare a field then it automatically becomes Published - There's probably something I'm missing here and I will come back to it.

Is this any clearer  ???

Mark Stansfield
Senior Developer/Trainer
Runtime Technology

mh

  • EA Novice
  • *
  • Posts: 7
  • Karma: +0/-0
    • View Profile
Re: Delphi Support - Close, but no Kewpie Doll
« Reply #4 on: March 20, 2002, 04:07:51 am »
Sorry, that's of course

> it's just that for classes **NOT** declared inside an {$M+}
> (and not derrived from a class that was, such as
> TPersistent) published and public are in fact identical.
marc hoffman ([email protected])
elitedevelopments software
http://www.elitedevelopments.com

mh

  • EA Novice
  • *
  • Posts: 7
  • Karma: +0/-0
    • View Profile
Re: Delphi Support - Close, but no Kewpie Doll
« Reply #5 on: March 20, 2002, 04:11:22 am »
> The default scoping is controlled by the {$M} directive.

> {$M+} default Published
> {$M-} default Public

still not quite right. the default is ALWAYS published. it's just that when a class (or one of it's ancestors) is declared {$M+}, all published sections do generate RTTI, and if it's not, they don't (i.e. instead _behave_ just like the public sections). that doesn't change the fact that they _are_ published sections, still. even though "published" makes no sematical different from "public" in this case.

sorry to be picky <g>
marc hoffman ([email protected])
elitedevelopments software
http://www.elitedevelopments.com

greygor

  • EA Novice
  • *
  • Posts: 18
  • Karma: +0/-0
  • I love YaBB 1 Gold!
    • View Profile
Re: Delphi Support - Close, but no Kewpie Doll
« Reply #6 on: March 20, 2002, 04:43:04 am »
I was just going off the following

Delphi in a Nutshell pg 45

"Unless you use the $M+ directive (See Chapter 8, Compiler Directives, for details), the default access level is public."

followed by this from Borland's Component Creation Course pg 12 which is talking about default visibility,

"The default depends upon how the class was compiled and which class it inherits from. Classes which are compiled with the {$M-} compiler setting which excludes runtime type information (RTTI) have a default visibility of Public. Classes which are compiled with the {$M+} compiler setting which includes runtime type information have a default visibility of Published. In addition to this any class which inherits either directly or indirectly from a class which includes runtime type information automatically includes runtime type information regardless of the {$M} compiler setting and so these classes also have a default visibility of Published"

I don't think EA are bothered about RTTI and whether it is included or not they just need to know the rules of default visibility.

However something quirky is going on which I'll have to address when I have more time  :-/

Mark Stansfield
Senior Developer/Trainer
Runtime Technology




mh

  • EA Novice
  • *
  • Posts: 7
  • Karma: +0/-0
    • View Profile
Re: Delphi Support - Close, but no Kewpie Doll
« Reply #7 on: March 20, 2002, 07:13:34 am »
You might be right ;).

but anyway, since

- there's no keyword in front
- public and publish DO behave identically

this is somewhat like discussing "if a tree falls over in the forest, and noone's there to hear it, does it make a sound?"

since geoff can't (easily) know about the $M+, he should just always treat the first section as the first section (i.e. stuff in the first section should not end up in a published section after a two-way cycle, but back in the first, unnamed section) and be happy with it <g>

marc hoffman ([email protected])
elitedevelopments software
http://www.elitedevelopments.com

greygor

  • EA Novice
  • *
  • Posts: 18
  • Karma: +0/-0
  • I love YaBB 1 Gold!
    • View Profile
Re: Delphi Support - Close, but no Kewpie Doll
« Reply #8 on: March 20, 2002, 07:37:06 am »
Fair Enough;

How about this;

Include an option on the Delphi Option screen that allows you to set default visibility which will apply to all Reverse Engineered pas units with classes that have an un-named first section.

KISS  ;D