summaryrefslogtreecommitdiff
path: root/packages/pastojs
diff options
context:
space:
mode:
authormattias <mattias@3ad0048d-3df7-0310-abae-a5850022a9f2>2019-10-27 20:51:31 +0000
committermattias <mattias@3ad0048d-3df7-0310-abae-a5850022a9f2>2019-10-27 20:51:31 +0000
commitfd58325075fdd5ca9d76ac119b0175111e8dd00b (patch)
treea7ded0e2498b806c199696acc2d8f0b9f74784a7 /packages/pastojs
parenta06599e48602a899d68550a4072881af3f31b96d (diff)
downloadfpc-fd58325075fdd5ca9d76ac119b0175111e8dd00b.tar.gz
pastojs: typeinfo for external classes
git-svn-id: https://svn.freepascal.org/svn/fpc/trunk@43323 3ad0048d-3df7-0310-abae-a5850022a9f2
Diffstat (limited to 'packages/pastojs')
-rw-r--r--packages/pastojs/src/fppas2js.pp119
-rw-r--r--packages/pastojs/tests/tcgenerics.pas65
-rw-r--r--packages/pastojs/tests/tcmodules.pas109
3 files changed, 226 insertions, 67 deletions
diff --git a/packages/pastojs/src/fppas2js.pp b/packages/pastojs/src/fppas2js.pp
index 32b78a12d5..e619f41f3d 100644
--- a/packages/pastojs/src/fppas2js.pp
+++ b/packages/pastojs/src/fppas2js.pp
@@ -620,6 +620,7 @@ type
pbifnRTTINewClassRef,// typeinfo of tkClassRef $ClassRef
pbifnRTTINewDynArray,// typeinfo of tkDynArray $DynArray
pbifnRTTINewEnum,// typeinfo of tkEnumeration $Enum
+ pbifnRTTINewExtClass,// typeinfo creator of tkExtClass $ExtClass
pbifnRTTINewInt,// typeinfo of tkInt $Int
pbifnRTTINewInterface,// typeinfo creator of tkInterface $Interface
pbifnRTTINewMethodVar,// typeinfo of tkMethod $MethodVar
@@ -676,16 +677,18 @@ type
pbivnRTTIInt_MinValue,
pbivnRTTIInt_OrdType,
pbivnRTTILocal, // $r
- pbivnRTTIMemberAttributes,
+ pbivnRTTIMemberAttributes, // attr
pbivnRTTIMethodKind, // tTypeInfoMethodVar has methodkind
- pbivnRTTIPointer_RefType,
- pbivnRTTIProcFlags,
- pbivnRTTIProcVar_ProcSig,
- pbivnRTTIPropDefault,
- pbivnRTTIPropIndex,
- pbivnRTTIPropStored,
- pbivnRTTISet_CompType,
- pbivnRTTITypeAttributes,
+ pbivnRTTIPointer_RefType, // reftype
+ pbivnRTTIProcFlags, // flags
+ pbivnRTTIProcVar_ProcSig, // procsig
+ pbivnRTTIPropDefault, // Default
+ pbivnRTTIPropIndex, // index
+ pbivnRTTIPropStored, // stored
+ pbivnRTTISet_CompType, // comptype
+ pbivnRTTITypeAttributes, // attr
+ pbivnRTTIExtClass_Ancestor, // ancestor
+ pbivnRTTIExtClass_JSClass, // jsclass
pbivnSelf,
pbivnTObjectDestroy,
pbivnWith,
@@ -697,6 +700,7 @@ type
pbitnTIClassRef,
pbitnTIDynArray,
pbitnTIEnum,
+ pbitnTIExtClass,
pbitnTIHelper,
pbitnTIInteger,
pbitnTIInterface,
@@ -791,6 +795,7 @@ const
'$ClassRef',
'$DynArray',
'$Enum',
+ '$ExtClass',
'$Int',
'$Interface',
'$MethodVar',
@@ -856,6 +861,8 @@ const
'stored', // pbivnRTTIPropStored
'comptype', // pbivnRTTISet_CompType
'attr', // pbivnRTTITypeAttributes
+ 'ancestor', // pbivnRTTIExtClass_Ancestor
+ 'jsclass', // pbivnRTTIExtClass_JSClass
'$Self', // pbivnSelf
'tObjectDestroy', // rtl.tObjectDestroy pbivnTObjectDestroy
'$with', // pbivnWith
@@ -866,6 +873,7 @@ const
'tTypeInfoClassRef', // pbitnTIClassRef
'tTypeInfoDynArray', // pbitnTIDynArray
'tTypeInfoEnum', // pbitnTIEnum
+ 'tTypeInfoExtClass', // pbitnTIExtClass
'tTypeInfoHelper', // pbitnTIHelper
'tTypeInfoInteger', // pbitnTIInteger
'tTypeInfoInterface', // pbitnTIInterface
@@ -2013,6 +2021,7 @@ type
Function ConvertClassType(El: TPasClassType; AContext: TConvertContext): TJSElement; virtual;
Function ConvertClassForwardType(El: TPasClassType; AContext: TConvertContext): TJSElement; virtual;
Function ConvertClassOfType(El: TPasClassOfType; AContext: TConvertContext): TJSElement; virtual;
+ Function ConvertExtClassType(El: TPasClassType; AContext: TConvertContext): TJSElement; virtual;
Function ConvertEnumType(El: TPasEnumType; AContext: TConvertContext): TJSElement; virtual;
Function ConvertSetType(El: TPasSetType; AContext: TConvertContext): TJSElement; virtual;
Function ConvertRangeType(El: TPasRangeType; AContext: TConvertContext): TJSElement; virtual;
@@ -2288,7 +2297,7 @@ begin
end;
{$ENDIF}
{$IFDEF VerbosePasResolver}
- if FindElevatedLocal(Item.Identifier)<>Item then
+ if Find(Item.Identifier)<>Item then
raise Exception.Create('20160925183849');
{$ENDIF}
end;
@@ -4914,7 +4923,11 @@ begin
TIName:=Pas2JSBuiltInNames[pbitnTIRecord]
else if C=TPasClassType then
case TPasClassType(TypeEl).ObjKind of
- okClass: TIName:=Pas2JSBuiltInNames[pbitnTIClass];
+ okClass:
+ if TPasClassType(TypeEl).IsExternal then
+ TIName:=Pas2JSBuiltInNames[pbitnTIExtClass]
+ else
+ TIName:=Pas2JSBuiltInNames[pbitnTIClass];
okInterface: TIName:=Pas2JSBuiltInNames[pbitnTIInterface];
okClassHelper,okRecordHelper,okTypeHelper: TIName:=Pas2JSBuiltInNames[pbitnTIHelper];
else
@@ -4950,7 +4963,12 @@ begin
if not (ConEl is TPasType) then
RaiseNotYetImplemented(20191018180031,ConEl,GetObjPath(Param));
if ConEl is TPasClassType then
- TIName:=Pas2JSBuiltInNames[pbitnTIClass]
+ begin
+ if TPasClassType(ConEl).IsExternal then
+ TIName:=Pas2JSBuiltInNames[pbitnTIExtClass]
+ else
+ TIName:=Pas2JSBuiltInNames[pbitnTIClass];
+ end
else
RaiseNotYetImplemented(20191018180131,ConEl,GetObjPath(Param));
end;
@@ -5859,8 +5877,6 @@ function TPas2JSResolver.HasTypeInfo(El: TPasType): boolean;
begin
Result:=inherited HasTypeInfo(El);
if not Result then exit;
- if (El.ClassType=TPasClassType) and TPasClassType(El).IsExternal then
- exit(false);
if El.Parent is TProcedureBody then
Result:=false;
end;
@@ -13592,14 +13608,14 @@ begin
RaiseNotSupported(El,AContext,20170927183645);
if El.Parent is TProcedureBody then
RaiseNotSupported(El,AContext,20181231004355);
+ if El.IsExternal then
+ exit(ConvertExtClassType(El,AContext));
if El.IsForward then
begin
Result:=ConvertClassForwardType(El,AContext);
exit;
end;
- if El.IsExternal then exit;
-
if El.CustomData is TPas2JSClassScope then
begin
Scope:=TPas2JSClassScope(El.CustomData);
@@ -13906,6 +13922,59 @@ begin
end;
end;
+function TPasToJSConverter.ConvertExtClassType(El: TPasClassType;
+ AContext: TConvertContext): TJSElement;
+// module.$rtti.$ExtClass("TJSObject",{
+// ancestor: ancestortypeinfo,
+// jsclass: "Object"
+// });
+var
+ TIObj: TJSObjectLiteral;
+ Call: TJSCallExpression;
+ TIProp: TJSObjectLiteralElement;
+ ClassScope: TPas2JSClassScope;
+ AncestorType: TPasClassType;
+begin
+ Result:=nil;
+ if not El.IsExternal then
+ RaiseNotSupported(El,AContext,20191027183236);
+
+ if not HasTypeInfo(El,AContext) then
+ exit;
+ // create typeinfo
+ if not (AContext is TFunctionContext) then
+ RaiseNotSupported(El,AContext,20191027182023,'typeinfo');
+ if El.Parent is TProcedureBody then
+ RaiseNotSupported(El,AContext,20191027182019);
+
+ ClassScope:=El.CustomData as TPas2JSClassScope;
+ if ClassScope.AncestorScope<>nil then
+ AncestorType:=ClassScope.AncestorScope.Element as TPasClassType
+ else
+ AncestorType:=nil;
+
+ Call:=nil;
+ try
+ // module.$rtti.$ExtClass("TMyClass",{...});
+ Call:=CreateRTTINewType(El,GetBIName(pbifnRTTINewExtClass),false,AContext,TIObj);
+ if AncestorType<>nil then
+ begin
+ // add ancestor: ancestortypeinfo
+ TIProp:=TIObj.Elements.AddElement;
+ TIProp.Name:=TJSString(GetBIName(pbivnRTTIExtClass_Ancestor));
+ TIProp.Expr:=CreateTypeInfoRef(AncestorType,AContext,El);
+ end;
+ // add jsclass: "extname"
+ TIProp:=TIObj.Elements.AddElement;
+ TIProp.Name:=TJSString(GetBIName(pbivnRTTIExtClass_JSClass));
+ TIProp.Expr:=CreateLiteralString(El,TPasClassType(El).ExternalName);
+ Result:=Call;
+ finally
+ if Result=nil then
+ Call.Free;
+ end;
+end;
+
function TPasToJSConverter.ConvertEnumType(El: TPasEnumType;
AContext: TConvertContext): TJSElement;
// TMyEnum = (red, green)
@@ -13916,7 +13985,7 @@ function TPasToJSConverter.ConvertEnumType(El: TPasEnumType;
// "0":"green",
// "green":0,
// };
-// module.$rtti.$TIEnum("TMyEnum",{
+// module.$rtti.$Enum("TMyEnum",{
// enumtype: this.TMyEnum,
// minvalue: 0,
// maxvalue: 1
@@ -21866,15 +21935,25 @@ var
end;
function IsA(SrcType, DstType: TPasType): boolean;
+ var
+ C: TClass;
begin
while SrcType<>nil do
begin
if SrcType=DstType then exit(true);
- if SrcType.ClassType=TPasClassType then
+ C:=SrcType.ClassType;
+ if C=TPasClassType then
SrcType:=TPas2JSClassScope(SrcType.CustomData).DirectAncestor
- else if (SrcType.ClassType=TPasAliasType)
- or (SrcType.ClassType=TPasTypeAliasType) then
+ else if (C=TPasAliasType)
+ or (C=TPasTypeAliasType) then
SrcType:=TPasAliasType(SrcType).DestType
+ else if C=TPasSpecializeType then
+ begin
+ if SrcType.CustomData is TPasSpecializeTypeData then
+ SrcType:=TPasSpecializeTypeData(SrcType.CustomData).SpecializedType
+ else
+ RaiseInconsistency(20191027172642,SrcType);
+ end
else
exit(false);
end;
diff --git a/packages/pastojs/tests/tcgenerics.pas b/packages/pastojs/tests/tcgenerics.pas
index c48388f1a4..1f94a604bc 100644
--- a/packages/pastojs/tests/tcgenerics.pas
+++ b/packages/pastojs/tests/tcgenerics.pas
@@ -24,6 +24,7 @@ type
Procedure TestGen_ClassEmpty;
Procedure TestGen_Class_EmptyMethod;
Procedure TestGen_Class_TList;
+ Procedure TestGen_Class_TCustomList;
Procedure TestGen_ClassAncestor;
Procedure TestGen_Class_TypeInfo;
Procedure TestGen_Class_TypeOverload; // ToDo TBird, TBird<T>, TBird<S,T>
@@ -289,6 +290,62 @@ begin
'']));
end;
+procedure TTestGenerics.TestGen_Class_TCustomList;
+begin
+ StartProgram(false);
+ Add([
+ '{$mode delphi}',
+ 'type',
+ ' TObject = class end;',
+ ' TCustomList<T> = class',
+ ' public',
+ ' function PrepareAddingItem: word; virtual;',
+ ' end;',
+ ' TList<T> = class(TCustomList<T>)',
+ ' public',
+ ' function Add: word;',
+ ' end;',
+ ' TWordList = TList<word>;',
+ 'function TCustomList<T>.PrepareAddingItem: word;',
+ 'begin',
+ 'end;',
+ 'function TList<T>.Add: word;',
+ 'begin',
+ ' Result:=PrepareAddingItem;',
+ //' Result:=Self.PrepareAddingItem;',
+ //' with Self do Result:=PrepareAddingItem;',
+ 'end;',
+ 'var l: TWordList;',
+ 'begin',
+ '']);
+ ConvertProgram;
+ CheckSource('TestGen_Class_TCustomList',
+ LinesToStr([ // statements
+ 'rtl.createClass($mod, "TObject", null, function () {',
+ ' this.$init = function () {',
+ ' };',
+ ' this.$final = function () {',
+ ' };',
+ '});',
+ 'rtl.createClass($mod, "TCustomList$G2", $mod.TObject, function () {',
+ ' this.PrepareAddingItem = function () {',
+ ' var Result = 0;',
+ ' return Result;',
+ ' };',
+ '});',
+ 'rtl.createClass($mod, "TList$G1", $mod.TCustomList$G2, function () {',
+ ' this.Add = function () {',
+ ' var Result = 0;',
+ ' Result = this.PrepareAddingItem();',
+ ' return Result;',
+ ' };',
+ '});',
+ 'this.l = null;',
+ '']),
+ LinesToStr([ // $mod.$main
+ '']));
+end;
+
procedure TTestGenerics.TestGen_ClassAncestor;
begin
StartProgram(false);
@@ -1030,15 +1087,9 @@ end;
procedure TTestGenerics.TestGenProc_TypeInfo;
begin
Converter.Options:=Converter.Options-[coNoTypeInfo];
- StartProgram(false);
+ StartProgram(true,[supTypeInfo]);
Add([
- '{$modeswitch externalclass}',
'{$modeswitch implicitfunctionspecialization}',
- 'type',
- ' TTypeInfo = class external name ''rtl.tTypeInfo''',
- ' end;',
- ' TTypeInfoInteger = class external name ''rtl.tTypeInfoInteger''(TTypeInfo)',
- ' end;',
'generic procedure Run<S>(a: S);',
'var',
' p: TTypeInfo;',
diff --git a/packages/pastojs/tests/tcmodules.pas b/packages/pastojs/tests/tcmodules.pas
index a8c1104d4c..67f2e903da 100644
--- a/packages/pastojs/tests/tcmodules.pas
+++ b/packages/pastojs/tests/tcmodules.pas
@@ -51,7 +51,8 @@ type
TSystemUnitPart = (
supTObject,
- supTVarRec
+ supTVarRec,
+ supTypeInfo
);
TSystemUnitParts = set of TSystemUnitPart;
@@ -816,6 +817,7 @@ type
Procedure TestRTTI_Interface_Corba;
Procedure TestRTTI_Interface_COM;
Procedure TestRTTI_ClassHelper;
+ Procedure TestRTTI_ExternalClass;
// Resourcestring
Procedure TestResourcestringProgram;
@@ -1557,7 +1559,7 @@ var
begin
Intf:=TStringList.Create;
// interface
- if supTVarRec in Parts then
+ if [supTVarRec,supTypeInfo]*Parts<>[] then
Intf.Add('{$modeswitch externalclass}');
Intf.Add('type');
Intf.Add(' integer=longint;');
@@ -1603,6 +1605,28 @@ begin
' TVarRecArray = array of TVarRec;',
'function VarRecs: TVarRecArray; varargs;',
'']);
+ if supTypeInfo in Parts then
+ begin
+ Intf.AddStrings([
+ 'type',
+ ' TTypeInfo = class external name ''rtl.tTypeInfo'' end;',
+ ' TTypeInfoInteger = class external name ''rtl.tTypeInfoInteger''(TTypeInfo)',
+ ' end;',
+ ' TTypeInfoEnum = class external name ''rtl.tTypeInfoEnum''(TTypeInfoInteger) end;',
+ ' TTypeInfoSet = class external name ''rtl.tTypeInfoSet''(TTypeInfo) end;',
+ ' TTypeInfoStaticArray = class external name ''rtl.tTypeInfoStaticArray''(TTypeInfo) end;',
+ ' TTypeInfoDynArray = class external name ''rtl.tTypeInfoDynArray''(TTypeInfo) end;',
+ ' TTypeInfoProcVar = class external name ''rtl.tTypeInfoProcVar''(TTypeInfo) end;',
+ ' TTypeInfoMethodVar = class external name ''rtl.tTypeInfoMethodVar''(TTypeInfoProcVar) end;',
+ ' TTypeInfoClass = class external name ''rtl.tTypeInfoClass''(TTypeInfo) end;',
+ ' TTypeInfoClassRef = class external name ''rtl.tTypeInfoClassRef''(TTypeInfo) end;',
+ ' TTypeInfoExtClass = class external name ''rtl.tTypeInfoExtClass''(TTypeInfo) end;',
+ ' TTypeInfoRecord = class external name ''rtl.tTypeInfoRecord''(TTypeInfo) end;',
+ ' TTypeInfoPointer = class external name ''rtl.tTypeInfoPointer''(TTypeInfo) end;',
+ ' TTypeInfoHelper = class external name ''rtl.tTypeInfoHelper''(TTypeInfo) end;',
+ ' TTypeInfoInterface = class external name ''rtl.tTypeInfoInterface''(TTypeInfo) end;',
+ '']);
+ end;
Intf.Add('var');
Intf.Add(' ExitCode: Longint = 0;');
@@ -27286,14 +27310,10 @@ end;
procedure TTestModule.TestRTTI_IntRange;
begin
Converter.Options:=Converter.Options-[coNoTypeInfo];
- StartProgram(false);
+ StartProgram(true,[supTypeInfo]);
Add([
'{$modeswitch externalclass}',
'type',
- ' TTypeInfo = class external name ''rtl.tTypeInfo''',
- ' end;',
- ' TTypeInfoInteger = class external name ''rtl.tTypeInfoInteger''(TTypeInfo)',
- ' end;',
' TGraphicsColor = -$7FFFFFFF-1..$7FFFFFFF;',
' TColor = type TGraphicsColor;',
'var',
@@ -27322,12 +27342,10 @@ end;
procedure TTestModule.TestRTTI_Double;
begin
Converter.Options:=Converter.Options-[coNoTypeInfo];
- StartProgram(false);
+ StartProgram(true,[supTypeInfo]);
Add([
'{$modeswitch externalclass}',
'type',
- ' TTypeInfo = class external name ''rtl.tTypeInfo''',
- ' end;',
' TFloat = type double;',
'var',
' p: TTypeInfo;',
@@ -29032,16 +29050,12 @@ end;
procedure TTestModule.TestRTTI_TypeInfo_ExtTypeInfoClasses1;
begin
Converter.Options:=Converter.Options-[coNoTypeInfo];
- StartProgram(false);
+ StartProgram(true,[supTypeInfo]);
Add([
'{$modeswitch externalclass}',
'type',
- ' TTypeInfo = class external name ''rtl.tTypeInfo'' end;',
- ' TTypeInfoInteger = class external name ''rtl.tTypeInfoInteger''(TTypeInfo) end;',
' TFlag = (up,down);',
- ' TTypeInfoEnum = class external name ''rtl.tTypeInfoEnum''(TTypeInfoInteger) end;',
' TFlags = set of TFlag;',
- ' TTypeInfoSet = class external name ''rtl.tTypeInfoSet''(TTypeInfo) end;',
'var',
' ti: TTypeInfo;',
' tiInt: TTypeInfoInteger;',
@@ -29104,18 +29118,13 @@ end;
procedure TTestModule.TestRTTI_TypeInfo_ExtTypeInfoClasses2;
begin
Converter.Options:=Converter.Options-[coNoTypeInfo];
- StartProgram(false);
+ StartProgram(true,[supTypeInfo]);
Add('{$modeswitch externalclass}');
Add('type');
- Add(' TTypeInfo = class external name ''rtl.tTypeInfo'' end;');
Add(' TStaticArr = array[boolean] of string;');
- Add(' TTypeInfoStaticArray = class external name ''rtl.tTypeInfoStaticArray''(TTypeInfo) end;');
Add(' TDynArr = array of string;');
- Add(' TTypeInfoDynArray = class external name ''rtl.tTypeInfoDynArray''(TTypeInfo) end;');
Add(' TProc = procedure;');
- Add(' TTypeInfoProcVar = class external name ''rtl.tTypeInfoProcVar''(TTypeInfo) end;');
Add(' TMethod = procedure of object;');
- Add(' TTypeInfoMethodVar = class external name ''rtl.tTypeInfoMethodVar''(TTypeInfoProcVar) end;');
Add('var');
Add(' StaticArray: TStaticArr;');
Add(' tiStaticArray: TTypeInfoStaticArray;');
@@ -29175,18 +29184,13 @@ end;
procedure TTestModule.TestRTTI_TypeInfo_ExtTypeInfoClasses3;
begin
Converter.Options:=Converter.Options-[coNoTypeInfo];
- StartProgram(false);
+ StartProgram(true,[supTypeInfo]);
Add('{$modeswitch externalclass}');
Add('type');
- Add(' TTypeInfo = class external name ''rtl.tTypeInfo'' end;');
Add(' TRec = record end;');
- Add(' TTypeInfoRecord = class external name ''rtl.tTypeInfoRecord''(TTypeInfo) end;');
// ToDo: ^PRec
Add(' TObject = class end;');
- Add(' TTypeInfoClass = class external name ''rtl.tTypeInfoClass''(TTypeInfo) end;');
Add(' TClass = class of tobject;');
- Add(' TTypeInfoClassRef = class external name ''rtl.tTypeInfoClassRef''(TTypeInfo) end;');
- Add(' TTypeInfoPointer = class external name ''rtl.tTypeInfoPointer''(TTypeInfo) end;');
Add('var');
Add(' Rec: trec;');
Add(' tiRecord: ttypeinforecord;');
@@ -29245,7 +29249,7 @@ end;
procedure TTestModule.TestRTTI_TypeInfo_FunctionClassType;
begin
Converter.Options:=Converter.Options-[coNoTypeInfo];
- StartProgram(false);
+ StartProgram(true,[supTypeInfo]);
Add([
'{$modeswitch externalclass}',
'type',
@@ -29254,8 +29258,6 @@ begin
' function MyClass: TClass;',
' class function ClassType: TClass;',
' end;',
- ' TTypeInfo = class external name ''rtl.tTypeInfo'' end;',
- ' TTypeInfoClass = class external name ''rtl.tTypeInfoClass''(TTypeInfo) end;',
'function TObject.MyClass: TClass;',
'var t: TTypeInfoClass;',
'begin',
@@ -29398,7 +29400,7 @@ end;
procedure TTestModule.TestRTTI_Interface_Corba;
begin
Converter.Options:=Converter.Options-[coNoTypeInfo];
- StartProgram(false);
+ StartProgram(true,[supTypeInfo]);
Add([
'{$interfaces corba}',
'{$modeswitch externalclass}',
@@ -29410,8 +29412,6 @@ begin
' procedure SetItem(Value: longint);',
' property Item: longint read GetItem write SetItem;',
' end;',
- ' TTypeInfo = class external name ''rtl.tTypeInfo'' end;',
- ' TTypeInfoInterface = class external name ''rtl.tTypeInfoInterface''(TTypeInfo) end;',
'procedure DoIt(t: TTypeInfoInterface); begin end;',
'var',
' i: IBird;',
@@ -29463,7 +29463,7 @@ end;
procedure TTestModule.TestRTTI_Interface_COM;
begin
Converter.Options:=Converter.Options-[coNoTypeInfo];
- StartProgram(false);
+ StartProgram(true,[supTypeInfo]);
Add([
'{$interfaces com}',
'{$modeswitch externalclass}',
@@ -29480,8 +29480,6 @@ begin
' procedure SetItem(Value: longint);',
' property Item: longint read GetItem write SetItem;',
' end;',
- ' TTypeInfo = class external name ''rtl.tTypeInfo'' end;',
- ' TTypeInfoInterface = class external name ''rtl.tTypeInfoInterface''(TTypeInfo) end;',
'var',
' i: IBird;',
' t: TTypeInfoInterface;',
@@ -29540,7 +29538,7 @@ end;
procedure TTestModule.TestRTTI_ClassHelper;
begin
Converter.Options:=Converter.Options-[coNoTypeInfo];
- StartProgram(false);
+ StartProgram(true,[supTypeInfo]);
Add([
'{$interfaces com}',
'{$modeswitch externalclass}',
@@ -29552,8 +29550,6 @@ begin
' function GetItem: longint;',
' property Item: longint read GetItem;',
' end;',
- ' TTypeInfo = class external name ''rtl.tTypeInfo'' end;',
- ' TTypeInfoHelper = class external name ''rtl.tTypeInfoHelper''(TTypeInfo) end;',
'function THelper.GetItem: longint;',
'begin',
'end;',
@@ -29587,6 +29583,40 @@ begin
'']));
end;
+procedure TTestModule.TestRTTI_ExternalClass;
+begin
+ Converter.Options:=Converter.Options-[coNoTypeInfo];
+ StartProgram(true,[supTypeInfo]);
+ Add([
+ '{$modeswitch externalclass}',
+ 'type',
+ ' TJSObject = class external name ''Object''',
+ ' end;',
+ ' TJSArray = class external name ''Array'' (TJSObject)',
+ ' end;',
+ 'var',
+ ' p: Pointer;',
+ ' tc: TTypeInfoExtClass;',
+ 'begin',
+ ' p:=typeinfo(TJSArray);']);
+ ConvertProgram;
+ CheckSource('TestRTTI_ExternalClass',
+ LinesToStr([ // statements
+ '$mod.$rtti.$ExtClass("TJSObject", {',
+ ' jsclass: "Object"',
+ '});',
+ '$mod.$rtti.$ExtClass("TJSArray", {',
+ ' ancestor: $mod.$rtti["TJSObject"],',
+ ' jsclass: "Array"',
+ '});',
+ 'this.p = null;',
+ 'this.tc = null;',
+ '']),
+ LinesToStr([ // $mod.$main
+ '$mod.p = $mod.$rtti["TJSArray"];',
+ '']));
+end;
+
procedure TTestModule.TestResourcestringProgram;
begin
StartProgram(false);
@@ -29880,7 +29910,6 @@ begin
'constructor THelper.Create(Id: word); begin end;',
'begin',
' if typeinfo(TMyInt)=nil then ;']);
- //SetExpectedConverterError('aaa',123);
ConvertProgram;
end;