소스 검색

pastojs: implemented string:=interface

git-svn-id: trunk@38727 -
Mattias Gaertner 7 년 전
부모
커밋
288afbe3b4
3개의 변경된 파일110개의 추가작업 그리고 13개의 파일을 삭제
  1. 56 13
      packages/pastojs/src/fppas2js.pp
  2. 8 0
      packages/pastojs/src/pas2jsfiler.pp
  3. 46 0
      packages/pastojs/tests/tcmodules.pas

+ 56 - 13
packages/pastojs/src/fppas2js.pp

@@ -303,6 +303,10 @@ Works:
   - COM: for interface in ... do
   - COM: for interface in ... do
 
 
 ToDos:
 ToDos:
+- interfaces:
+  - GUID
+  - for i in jsvalue do
+  - for i in tjsobject do
 - 'new', 'Function' -> class var use .prototype
 - 'new', 'Function' -> class var use .prototype
 - btArrayLit
 - btArrayLit
   a: array of jsvalue;
   a: array of jsvalue;
@@ -533,6 +537,7 @@ type
     pbifnUnitInit,
     pbifnUnitInit,
     pbivnExceptObject,
     pbivnExceptObject,
     pbivnIntfExprRefs,
     pbivnIntfExprRefs,
+    pbivnIntfGUID,
     pbivnIntfKind,
     pbivnIntfKind,
     pbivnIntfMaps,
     pbivnIntfMaps,
     pbivnImplementation,
     pbivnImplementation,
@@ -665,6 +670,7 @@ const
     '$init',
     '$init',
     '$e',
     '$e',
     '$ir',
     '$ir',
+    '$guid',
     '$kind',
     '$kind',
     '$intfmaps',
     '$intfmaps',
     '$impl',
     '$impl',
@@ -3014,8 +3020,10 @@ var
   LeftBaseType: TPas2jsBaseType;
   LeftBaseType: TPas2jsBaseType;
   LArray: TPasArrayType;
   LArray: TPasArrayType;
   ElTypeResolved: TPasResolverResult;
   ElTypeResolved: TPasResolverResult;
+  LTypeEl, RTypeEl: TPasType;
 begin
 begin
   Result:=cIncompatible;
   Result:=cIncompatible;
+  //writeln('TPas2JSResolver.CheckAssignCompatibilityCustom ',GetResolverResultDbg(LHS));
   if LHS.BaseType=btCustom then
   if LHS.BaseType=btCustom then
     begin
     begin
     if not (LHS.TypeEl is TPasUnresolvedSymbolRef) then
     if not (LHS.TypeEl is TPasUnresolvedSymbolRef) then
@@ -3056,20 +3064,36 @@ begin
         end;
         end;
       end;
       end;
     end
     end
-  else if (LHS.BaseType=btContext) and (LHS.TypeEl.ClassType=TPasArrayType)
-      and (rrfReadable in RHS.Flags) then
+  else if (LHS.BaseType=btContext) then
     begin
     begin
-    LArray:=TPasArrayType(LHS.TypeEl);
-    if length(LArray.Ranges)>0 then
-      exit;
-    if (RHS.BaseType<>btContext) or (RHS.TypeEl.ClassType<>TPasArrayType) then
-      exit;
-    ComputeElement(LArray.ElType,ElTypeResolved,[rcType]);
-    if IsJSBaseType(ElTypeResolved,pbtJSValue) then
+    LTypeEl:=ResolveAliasType(LHS.TypeEl);
+    RTypeEl:=ResolveAliasType(RHS.TypeEl);
+    if (LTypeEl.ClassType=TPasArrayType)
+        and (rrfReadable in RHS.Flags) then
+      begin
+      LArray:=TPasArrayType(LTypeEl);
+      if length(LArray.Ranges)>0 then
+        exit;
+      if (RHS.BaseType<>btContext) or (RTypeEl.ClassType<>TPasArrayType) then
+        exit;
+      ComputeElement(LArray.ElType,ElTypeResolved,[rcType]);
+      if IsJSBaseType(ElTypeResolved,pbtJSValue) then
+        begin
+        // array of jsvalue := array
+        Handled:=true;
+        Result:=cJSValueConversion;
+        end;
+      end;
+    end
+  else if LHS.BaseType=btString then
+    begin
+    RTypeEl:=ResolveAliasType(RHS.TypeEl);
+    if (RTypeEl is TPasClassType)
+        and (TPasClassType(RTypeEl).ObjKind=okInterface) then
       begin
       begin
-      // array of jsvalue := array
+      // string:=interface
       Handled:=true;
       Handled:=true;
-      Result:=cJSValueConversion;
+      Result:=cLossyConversion;
       end;
       end;
     end;
     end;
 
 
@@ -12657,7 +12681,16 @@ begin
       else if RightTypeEl.ClassType=TPasClassType then
       else if RightTypeEl.ClassType=TPasClassType then
         begin
         begin
         LeftTypeEl:=aResolver.ResolveAliasType(AssignContext.LeftResolved.TypeEl);
         LeftTypeEl:=aResolver.ResolveAliasType(AssignContext.LeftResolved.TypeEl);
-        if LeftTypeEl is TPasClassType then
+        if AssignContext.LeftResolved.BaseType=btString then
+          begin
+          if TPasClassType(RightTypeEl).ObjKind=okInterface then
+            begin
+            // string:=interface  ->  string = interface.$guid
+            AssignContext.RightSide:=CreateDotExpression(El,AssignContext.RightSide,
+              CreatePrimitiveDotExpr(FBuiltInNames[pbivnIntfGUID],El));
+            end;
+          end
+        else if LeftTypeEl is TPasClassType then
           case TPasClassType(LeftTypeEl).ObjKind of
           case TPasClassType(LeftTypeEl).ObjKind of
           okClass:
           okClass:
             case TPasClassType(RightTypeEl).ObjKind of
             case TPasClassType(RightTypeEl).ObjKind of
@@ -14920,7 +14953,17 @@ begin
         end
         end
       else if ExprTypeEl.ClassType=TPasClassType then
       else if ExprTypeEl.ClassType=TPasClassType then
         begin
         begin
-        if ArgTypeEl is TPasClassType then
+        if ArgResolved.BaseType=btString then
+          begin
+          if TPasClassType(ExprTypeEl).ObjKind=okInterface then
+            begin
+            // interface to string  ->  intf.$guid
+            Result:=CreateDotExpression(El,Result,CreatePrimitiveDotExpr(FBuiltInNames[pbivnIntfGUID],El));
+            end
+          else
+            RaiseNotSupported(El,AContext,20180410160008);
+          end
+        else if ArgTypeEl is TPasClassType then
           case TPasClassType(ExprTypeEl).ObjKind of
           case TPasClassType(ExprTypeEl).ObjKind of
           okClass:
           okClass:
             case TPasClassType(ArgTypeEl).ObjKind of
             case TPasClassType(ArgTypeEl).ObjKind of

+ 8 - 0
packages/pastojs/src/pas2jsfiler.pp

@@ -7502,6 +7502,14 @@ begin
     else
     else
       Src:=aStream;
       Src:=aStream;
 
 
+    {$IFDEF VerbosePCUUncompressed}
+    writeln('TPCUReader.ReadPCU SRC START====================================');
+    SetLength(FirstBytes,Src.Size);
+    Src.read(FirstBytes[1],length(FirstBytes));
+    writeln(FirstBytes);
+    Src.Position:=0;
+    writeln('TPCUReader.ReadPCU SRC END======================================');
+    {$ENDIF}
     JParser:=TJSONParser.Create(Src,[joUTF8,joStrict]);
     JParser:=TJSONParser.Create(Src,[joUTF8,joStrict]);
     Data:=JParser.Parse;
     Data:=JParser.Parse;
     if not (Data is TJSONObject) then
     if not (Data is TJSONObject) then

+ 46 - 0
packages/pastojs/tests/tcmodules.pas

@@ -505,6 +505,7 @@ type
     Procedure TestClassInterface_COM_ArrayOfIntfFail;
     Procedure TestClassInterface_COM_ArrayOfIntfFail;
     Procedure TestClassInterface_COM_RecordIntfFail;
     Procedure TestClassInterface_COM_RecordIntfFail;
     Procedure TestClassInterface_COM_UnitInitialization;
     Procedure TestClassInterface_COM_UnitInitialization;
+    Procedure TestClassInterface_GUID;
 
 
     // proc types
     // proc types
     Procedure TestProcType;
     Procedure TestProcType;
@@ -14139,6 +14140,51 @@ begin
     );
     );
 end;
 end;
 
 
+procedure TTestModule.TestClassInterface_GUID;
+begin
+  StartProgram(false);
+  Add([
+  '{$interfaces corba}',
+  'type',
+  '  IUnknown = interface',
+  '    [''{F31DB68F-3010-D355-4EBA-CDD4EF4A737C}'']',
+  '  end;',
+  '  TObject = class end;',
+  '  TGUID = string;',
+  '  TAliasGUID = TGUID;',
+  'procedure DoIt(g: TAliasGUID);',
+  'begin end;',
+  'var i: IUnknown;',
+  '  g: TAliasGUID;',
+  'begin',
+  '  DoIt(IUnknown);',
+  '  DoIt(i);',
+  '  g:=i;',
+  '  g:=IUnknown;',
+  '']);
+  ConvertProgram;
+  CheckSource('TestClassInterface_GUID',
+    LinesToStr([ // statements
+    'rtl.createInterface($mod, "IUnknown", "{F31DB68F-3010-D355-4EBA-CDD4EF4A737C}", [], null);',
+    'rtl.createClass($mod, "TObject", null, function () {',
+    '  this.$init = function () {',
+    '  };',
+    '  this.$final = function () {',
+    '  };',
+    '});',
+    'this.DoIt = function (g) {',
+    '};',
+    'this.i = null;',
+    'this.g = "";',
+    '']),
+    LinesToStr([ // $mod.$main
+    '$mod.DoIt($mod.IUnknown.$guid);',
+    '$mod.DoIt($mod.i.$guid);',
+    '$mod.g = $mod.i.$guid;',
+    '$mod.g = $mod.IUnknown.$guid;',
+    '']));
+end;
+
 procedure TTestModule.TestProcType;
 procedure TTestModule.TestProcType;
 begin
 begin
   StartProgram(false);
   StartProgram(false);