-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathTObject.pas
More file actions
221 lines (180 loc) · 5.72 KB
/
TObject.pas
File metadata and controls
221 lines (180 loc) · 5.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
namespace RemObjects.Elements.RTL.Delphi;
uses
RemObjects.Elements.RTL;
type
TObject = public Object;
IInterface = public interface
end;
Object__Delphi = public extension class(Object)
public
method Destroy;
begin
{$IF ECHOES OR ISLAND}
IDisposable(self):Dispose;
{$ENDIF}
{$IF COOPER}
AutoCloseable(self):close;
{$ENDIF}
end;
method Free;
begin
Destroy;
end;
class method InitInstance(Instance: Pointer): TObject; empty;
method CleanupInstance; empty;
method ClassType: TClass;
begin
result := new RemObjects.Elements.RTL.Reflection.Type withPlatformType(typeOf(self));
end;
class method ClassName: ShortString;
begin
result := typeOf(self).Name;
end;
method InstanceClassName: String;
begin
result := ClassType.Name;
end;
class method ClassNameIs(const Name: String): Boolean;
begin
result := RemObjects.Elements.RTL.String.EqualsIgnoringCase(ClassName, Name);
end;
class method ClassParent: TClass;
begin
result := (new RemObjects.Elements.RTL.Reflection.Type withPlatformType(typeOf(self))).BaseType;
end;
class method ClassInfo: Pointer; empty;
class method InstanceSize: LongInt; empty;
class method InheritsFrom(AClass: TClass): Boolean;
begin
{$IF COOPER}
result := false;
(*var SelfType := new RemObjects.Elements.RTL.Reflection.Type withPlatformType(typeOf(self));
var altSelfType := typeOf(Self);
result := (AClass = typeOf(self)) or altSelfType.IsSubClassOf(AClass);
result := RemObjects.Elements.RTL.String.Equals(SelfType.Name, AClass.Name) or (SelfType.IsSubclassOf(AClass));*)
{$ELSEIF TOFFEE}
var SelfType := new RemObjects.Elements.RTL.Reflection.Type withPlatformType(typeOf(self));
result := RemObjects.Elements.RTL.String.Equals(SelfType.Name, AClass.Name) or (SelfType.IsSubclassOf(AClass));
{$ELSE}
result := (AClass = typeOf(self)) or (typeOf(self).IsSubclassOf(AClass));
{$ENDIF}
end;
class method MethodAddress(const Name: ShortString): Pointer;
begin
raise new NotSupportedException("TObject.MethodAddress");
end;
class method MethodName(Address: Pointer): ShortString;
begin
raise new NotSupportedException("TObject.MethodName");
end;
method FieldAddress(const Name: ShortString): Pointer;
begin
raise new NotSupportedException("TObject.FieldAddress");
end;
method GetInterface(const IID: TGUID; out Obj): Boolean;
begin
raise new NotSupportedException("TObject.GetInterface");
end;
class method GetInterfaceEntry(const IID: TGUID): PInterfaceEntry;
begin
raise new NotSupportedException("TObject.GetInterfaceEntry");
end;
class method GetInterfaceTable: PInterfaceTable;
begin
raise new NotSupportedException("TObject.GetInterfaceTable");
end;
method SafeCallException(ExceptObject: TObject; ExceptAddr: Pointer): HResult;
begin
raise new NotSupportedException("TObject.SafeCallException");
end;
procedure AfterConstruction; {virtual;} empty;
procedure BeforeDestruction; {virtual;} empty;
procedure Dispatch(var Message); {virtual;}
begin
raise new NotSupportedException("TObject.Dispatch");
end;
procedure DefaultHandler(var Message); {virtual;}
begin
raise new NotSupportedException("TObject.DefaultHandler");
end;
class method NewInstance: TObject; {virtual;}
begin
result := new self;
end;
procedure FreeInstance; {virtual;}
begin
{$IF ECHOES}
IDisposable(self).Dispose();
{$ELSEIF TOFFEE}
{$ELSEIF COOPER}
{$ELSEIF ISLAND}
{$ENDIF}
end;
end;
TDelphiObject = public partial class(TObject)
public
procedure AfterConstruction; virtual; empty; // will be called by the compiler after a any "new", at thew call site.
procedure BeforeDestruction; virtual; empty;
constructor Create; virtual; empty;
method Destroy; virtual; empty; // can't use "destructor" because this project isn't built using Delphi Compatibility. same diff though.
method Free; inline; // this allows writing SomeObject.Free without getting an NRE in Echoes
begin
self:InternalFree;
end;
method InternalFree;
begin
if assigned(self) and not fDestroyed then begin
fDestroyed := true;
BeforeDestruction;
Destroy;
{$IF ECHOES}
GC.SuppressFinalize(self);
{$ENDIF}
{$IF ISLAND AND NOT WEBASSEMBLY}
DefaultGC.SuppressFinalize(self);
{$ENDIF}
end;
end;
private
fDestroyed: Boolean;
end;
{$IF ECHOES OR ISLAND}
TDelphiObject = public partial class(IDisposable)
protected
finalizer;
begin
if not fDestroyed then begin
fDestroyed := true;
BeforeDestruction;
Destroy;
end;
end;
method Dispose; private;
begin
if not fDestroyed then begin
fDestroyed := true;
BeforeDestruction;
Destroy;
{$IF ECHOES}
GC.SuppressFinalize(self);
{$ELSEIF ISLAND AND NOT WEBASSEMBLY}
DefaultGC.SuppressFinalize(self);
{$ENDIF}
end;
end;
end;
{$ENDIF}
{$IF COOPER}
TDelphiObject = public partial class(AutoCloseable)
private
method close; //raises Exception;
begin
if not fDestroyed then begin
fDestroyed := true;
BeforeDestruction;
Destroy;
end;
end;
end;
{$ENDIF}
end.