pastojs: typecast array to/from tjsobject

git-svn-id: trunk@39034 -
This commit is contained in:
Mattias Gaertner 2018-05-20 10:40:07 +00:00
parent 8364b1f4ca
commit 763fd783e0
3 changed files with 43 additions and 26 deletions

View File

@ -3984,8 +3984,9 @@ begin
FromTypeEl:=FromResolved.LoTypeEl;
if FromTypeEl.ClassType=TPasArrayType then
begin
if IsExternalClassName(ToClass,'Array') then
// TJSArray(AnArray)
if IsExternalClassName(ToClass,'Array')
or IsExternalClassName(ToClass,'Object') then
// TJSArray(AnArray) or TJSObject(AnArray)
exit(cExact);
end
else if FromTypeEl.ClassType=TPasRecordType then
@ -4010,9 +4011,10 @@ begin
FromTypeEl:=FromResolved.LoTypeEl;
if (FromTypeEl.ClassType=TPasClassType)
and TPasClassType(FromTypeEl).IsExternal
and IsExternalClassName(TPasClassType(FromTypeEl),'Array') then
and (IsExternalClassName(TPasClassType(FromTypeEl),'Array')
or IsExternalClassName(TPasClassType(FromTypeEl),'Object')) then
begin
// type cast external Array to an array
// type cast external Array/Object to an array
exit(cCompatible);
end;
end;

View File

@ -394,8 +394,8 @@ type
Procedure TestArray_InsertDelete;
Procedure TestArray_DynArrayConst;
Procedure TestArray_ForInArrOfString;
Procedure TestExternalClass_TypeCastArrayToExternalArray;
Procedure TestExternalClass_TypeCastArrayFromExternalArray;
Procedure TestExternalClass_TypeCastArrayToExternalClass;
Procedure TestExternalClass_TypeCastArrayFromExternalClass;
// record
Procedure TestRecord_Empty;
@ -7649,12 +7649,14 @@ begin
'']));
end;
procedure TTestModule.TestExternalClass_TypeCastArrayToExternalArray;
procedure TTestModule.TestExternalClass_TypeCastArrayToExternalClass;
begin
StartProgram(false);
Add([
'{$modeswitch externalclass}',
'type',
' TJSObject = class external name ''Object''',
' end;',
' TJSArray = class external name ''Array''',
' class function isArray(Value: JSValue) : boolean;',
' function concat() : TJSArray; varargs;',
@ -7662,44 +7664,56 @@ begin
'var',
' aObj: TJSArray;',
' a: array of longint;',
' o: TJSObject;',
'begin',
' if TJSArray.isArray(65) then ;',
' aObj:=TJSArray(a).concat(a);']);
' aObj:=TJSArray(a).concat(a);',
' o:=TJSObject(a);']);
ConvertProgram;
CheckSource('TestExternalClass_TypeCastArrayToExternalArray',
CheckSource('TestExternalClass_TypeCastArrayToExternalClass',
LinesToStr([ // statements
'this.aObj = null;',
'this.a = [];',
'this.o = null;',
'']),
LinesToStr([ // $mod.$main
'if (Array.isArray(65)) ;',
'$mod.aObj = $mod.a.concat($mod.a);',
'$mod.o = $mod.a;',
'']));
end;
procedure TTestModule.TestExternalClass_TypeCastArrayFromExternalArray;
procedure TTestModule.TestExternalClass_TypeCastArrayFromExternalClass;
begin
StartProgram(false);
Add('{$modeswitch externalclass}');
Add('type');
Add(' TArrStr = array of string;');
Add(' TJSArray = class external name ''Array''');
Add(' end;');
Add('var');
Add(' aObj: TJSArray;');
Add(' a: TArrStr;');
Add('begin');
Add(' a:=TArrStr(aObj);');
Add(' TArrStr(aObj)[1]:=TArrStr(aObj)[2];');
Add([
'{$modeswitch externalclass}',
'type',
' TArrStr = array of string;',
' TJSArray = class external name ''Array''',
' end;',
' TJSObject = class external name ''Object''',
' end;',
'var',
' aObj: TJSArray;',
' a: TArrStr;',
' jo: TJSObject;',
'begin',
' a:=TArrStr(aObj);',
' TArrStr(aObj)[1]:=TArrStr(aObj)[2];',
' a:=TarrStr(jo);',
'']);
ConvertProgram;
CheckSource('TestExternalClass_TypeCastArrayFromExternalArray',
CheckSource('TestExternalClass_TypeCastArrayFromExternalClass',
LinesToStr([ // statements
'this.aObj = null;',
'this.a = [];',
'this.jo = null;',
'']),
LinesToStr([ // $mod.$main
'$mod.a = $mod.aObj;',
'$mod.aObj[1] = $mod.aObj[2];',
'$mod.a = $mod.jo;',
'']));
end;

View File

@ -1865,10 +1865,11 @@ function(){
<li><i>for key in jsvalue do</i> translates to <i>for (key in jsvalue){}</i></li>
<li><i>for key in ExternalClass do</i><br>
<ul>
<li>if the externalclass has a ''length'' and a default property e.g.
<i>for value in TJSArray do</i> translates same as for-in PascalArray,
i.e. it enumerates the values of the array, not the index.</li>
<li>otherwise translates to <i>for (key in externalclass){}</i>,
<li>If the externalclass has a ''length'' and a matching default property
it uses the enumeration of an array. For example
<i>for value in TJSArray do</i> enumerates the values of the array, not the index.
It checks if the array is nil.</li>
<li>Otherwise it translates to <i>for (key in externalclass){}</i>,
which enumerates the keys (property names) of the JS object.</li>
</ul>
</ul>