diff options
author | mattias <mattias@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2019-10-27 20:51:31 +0000 |
---|---|---|
committer | mattias <mattias@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2019-10-27 20:51:31 +0000 |
commit | fd58325075fdd5ca9d76ac119b0175111e8dd00b (patch) | |
tree | a7ded0e2498b806c199696acc2d8f0b9f74784a7 | |
parent | a06599e48602a899d68550a4072881af3f31b96d (diff) | |
download | fpc-fd58325075fdd5ca9d76ac119b0175111e8dd00b.tar.gz |
pastojs: typeinfo for external classes
git-svn-id: https://svn.freepascal.org/svn/fpc/trunk@43323 3ad0048d-3df7-0310-abae-a5850022a9f2
-rw-r--r-- | packages/pastojs/src/fppas2js.pp | 119 | ||||
-rw-r--r-- | packages/pastojs/tests/tcgenerics.pas | 65 | ||||
-rw-r--r-- | packages/pastojs/tests/tcmodules.pas | 109 | ||||
-rw-r--r-- | utils/pas2js/dist/rtl.js | 21 |
4 files changed, 238 insertions, 76 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; diff --git a/utils/pas2js/dist/rtl.js b/utils/pas2js/dist/rtl.js index e09509313d..848d95174f 100644 --- a/utils/pas2js/dist/rtl.js +++ b/utils/pas2js/dist/rtl.js @@ -7,7 +7,7 @@ var rtl = { quiet: false, debug_load_units: false, debug_rtti: false, - + $res : {}, debug: function(){ @@ -1316,6 +1316,7 @@ var rtl = { newBaseTI("tTypeInfoClassRef",14 /* tkClassRef */); newBaseTI("tTypeInfoInterface",18 /* tkInterface */,rtl.tTypeInfoStruct); newBaseTI("tTypeInfoHelper",19 /* tkHelper */,rtl.tTypeInfoStruct); + newBaseTI("tTypeInfoExtClass",20 /* tkExtClass */,rtl.tTypeInfoClass); }, tSectionRTTI: { @@ -1366,7 +1367,8 @@ var rtl = { $ClassRef: function(name,o){ return this.$inherited(name,rtl.tTypeInfoClassRef,o); }, $Pointer: function(name,o){ return this.$inherited(name,rtl.tTypeInfoPointer,o); }, $Interface: function(name,o){ return this.$Scope(name,rtl.tTypeInfoInterface,o); }, - $Helper: function(name,o){ return this.$Scope(name,rtl.tTypeInfoHelper,o); } + $Helper: function(name,o){ return this.$Scope(name,rtl.tTypeInfoHelper,o); }, + $ExtClass: function(name,o){ return this.$Scope(name,rtl.tTypeInfoExtClass,o); } }, newTIParam: function(param){ @@ -1396,21 +1398,22 @@ var rtl = { }; return s; }, - - addResource : function (aRes) { + + addResource: function(aRes){ rtl.$res[aRes.name]=aRes; }, - getResource : function (aName) { + getResource: function(aName){ var res = rtl.$res[aName]; if (res !== undefined) { return res; - } else { + } else { return null; - } + } }, - - getResourceList : function () { + + getResourceList: function(){ return Object.keys(rtl.$res); } } + |