Browse Source

pastojs: filer: started read/write uses section

git-svn-id: trunk@38448 -
Mattias Gaertner 7 years ago
parent
commit
4f45325ebd
2 changed files with 159 additions and 60 deletions
  1. 158 60
      packages/pastojs/src/pas2jsfiler.pp
  2. 1 0
      packages/pastojs/tests/tcfiler.pas

+ 158 - 60
packages/pastojs/src/pas2jsfiler.pp

@@ -593,6 +593,7 @@ type
   private
   private
     FConverter: TPasToJSConverter;
     FConverter: TPasToJSConverter;
     FElementIdCounter: integer;
     FElementIdCounter: integer;
+    FOnIsElementUsed: TPas2JSIsElementUsedEvent;
     FSourceFilesSorted: TPJUSourceFileArray;
     FSourceFilesSorted: TPJUSourceFileArray;
     FInImplementation: boolean;
     FInImplementation: boolean;
   protected
   protected
@@ -695,6 +696,7 @@ type
       InitFlags: TPJUInitialFlags): TJSONObject; virtual;
       InitFlags: TPJUInitialFlags): TJSONObject; virtual;
     function IndexOfSourceFile(const Filename: string): integer;
     function IndexOfSourceFile(const Filename: string): integer;
     property SourceFilesSorted: TPJUSourceFileArray read FSourceFilesSorted;
     property SourceFilesSorted: TPJUSourceFileArray read FSourceFilesSorted;
+    property OnIsElementUsed: TPas2JSIsElementUsedEvent read FOnIsElementUsed write FOnIsElementUsed;
   end;
   end;
 
 
   { TPJUReaderContext }
   { TPJUReaderContext }
@@ -734,6 +736,7 @@ type
   private
   private
     FElementRefsArray: TPJUFilerElementRefArray; // TPJUFilerElementRef by Id
     FElementRefsArray: TPJUFilerElementRefArray; // TPJUFilerElementRef by Id
     FFileVersion: longint;
     FFileVersion: longint;
+    FJSON: TJSONObject;
     FPendingIdentifierScopes: TObjectList; // list of TPJUReaderPendingIdentifierScope
     FPendingIdentifierScopes: TObjectList; // list of TPJUReaderPendingIdentifierScope
     procedure Set_Variable_VarType(RefEl: TPasElement; Data: TObject);
     procedure Set_Variable_VarType(RefEl: TPasElement; Data: TObject);
     procedure Set_AliasType_DestType(RefEl: TPasElement; Data: TObject);
     procedure Set_AliasType_DestType(RefEl: TPasElement; Data: TObject);
@@ -787,6 +790,7 @@ type
     procedure ReadSrcFiles(Data: TJSONData); virtual;
     procedure ReadSrcFiles(Data: TJSONData); virtual;
     function ReadMemberHints(Obj: TJSONObject; El: TPasElement; const DefaultValue: TPasMemberHints): TPasMemberHints; virtual;
     function ReadMemberHints(Obj: TJSONObject; El: TPasElement; const DefaultValue: TPasMemberHints): TPasMemberHints; virtual;
     procedure ReadPasElement(Obj: TJSONObject; El: TPasElement; aContext: TPJUReaderContext); virtual;
     procedure ReadPasElement(Obj: TJSONObject; El: TPasElement; aContext: TPJUReaderContext); virtual;
+    procedure ReadUsedUnits(Obj: TJSONObject; Section: TPasSection; aContext: TPJUReaderContext); virtual;
     procedure ReadSectionScope(Obj: TJSONObject; Scope: TPasSectionScope; aContext: TPJUReaderContext); virtual;
     procedure ReadSectionScope(Obj: TJSONObject; Scope: TPasSectionScope; aContext: TPJUReaderContext); virtual;
     procedure ReadSection(Obj: TJSONObject; Section: TPasSection; aContext: TPJUReaderContext); virtual;
     procedure ReadSection(Obj: TJSONObject; Section: TPasSection; aContext: TPJUReaderContext); virtual;
     procedure ReadDeclarations(Obj: TJSONObject; Section: TPasSection; aContext: TPJUReaderContext); virtual;
     procedure ReadDeclarations(Obj: TJSONObject; Section: TPasSection; aContext: TPJUReaderContext); virtual;
@@ -814,7 +818,7 @@ type
     procedure ReadIdentifierScope(Obj: TJSONObject; Scope: TPasIdentifierScope; aContext: TPJUReaderContext); virtual;
     procedure ReadIdentifierScope(Obj: TJSONObject; Scope: TPasIdentifierScope; aContext: TPJUReaderContext); virtual;
     function ReadModuleScopeFlags(Obj: TJSONObject; El: TPasElement; const DefaultValue: TPasModuleScopeFlags): TPasModuleScopeFlags; virtual;
     function ReadModuleScopeFlags(Obj: TJSONObject; El: TPasElement; const DefaultValue: TPasModuleScopeFlags): TPasModuleScopeFlags; virtual;
     procedure ReadModuleScope(Obj: TJSONObject; Scope: TPas2JSModuleScope; aContext: TPJUReaderContext); virtual;
     procedure ReadModuleScope(Obj: TJSONObject; Scope: TPas2JSModuleScope; aContext: TPJUReaderContext); virtual;
-    procedure ReadModule(Data: TJSONData; aContext: TPJUReaderContext); virtual;
+    procedure ReadModule(Obj: TJSONObject; aContext: TPJUReaderContext); virtual;
     procedure ReadUnaryExpr(Obj: TJSONObject; Expr: TUnaryExpr; aContext: TPJUReaderContext); virtual;
     procedure ReadUnaryExpr(Obj: TJSONObject; Expr: TUnaryExpr; aContext: TPJUReaderContext); virtual;
     procedure ReadBinaryExpr(Obj: TJSONObject; Expr: TBinaryExpr; aContext: TPJUReaderContext); virtual;
     procedure ReadBinaryExpr(Obj: TJSONObject; Expr: TBinaryExpr; aContext: TPJUReaderContext); virtual;
     procedure ReadBoolConstExpr(Obj: TJSONObject; Expr: TBoolConstExpr; aContext: TPJUReaderContext); virtual;
     procedure ReadBoolConstExpr(Obj: TJSONObject; Expr: TBoolConstExpr; aContext: TPJUReaderContext); virtual;
@@ -873,9 +877,11 @@ type
     constructor Create; override;
     constructor Create; override;
     destructor Destroy; override;
     destructor Destroy; override;
     procedure Clear; override;
     procedure Clear; override;
-    procedure ReadPJU(aResolver: TPas2JSResolver; aStream: TStream); virtual;
-    procedure ReadJSON(aResolver: TPas2JSResolver; Obj: TJSONObject); virtual;
+    procedure ReadPJU(aResolver: TPas2JSResolver; aStream: TStream); virtual; // sets property JSON, reads header and returns
+    procedure ReadJSONHeader(aResolver: TPas2JSResolver; Obj: TJSONObject); virtual;
+    procedure ReadJSONContinue; virtual;
     property FileVersion: longint read FFileVersion;
     property FileVersion: longint read FFileVersion;
+    property JSON: TJSONObject read FJSON;
   end;
   end;
 
 
 function ComparePointer(Data1, Data2: Pointer): integer;
 function ComparePointer(Data1, Data2: Pointer): integer;
@@ -1943,11 +1949,13 @@ end;
 procedure TPJUWriter.WriteSection(ParentJSON: TJSONObject;
 procedure TPJUWriter.WriteSection(ParentJSON: TJSONObject;
   Section: TPasSection; const PropName: string; aContext: TPJUWriterContext);
   Section: TPasSection; const PropName: string; aContext: TPJUWriterContext);
 var
 var
-  Obj: TJSONObject;
+  Obj, SubObj: TJSONObject;
   Scope, UsesScope: TPasSectionScope;
   Scope, UsesScope: TPasSectionScope;
   i: Integer;
   i: Integer;
   Arr: TJSONArray;
   Arr: TJSONArray;
   UsesUnit: TPasUsesUnit;
   UsesUnit: TPasUsesUnit;
+  Name, InFilename: String;
+  Ref: TPJUFilerElementRef;
 begin
 begin
   if Section=nil then exit;
   if Section=nil then exit;
   Obj:=TJSONObject.Create;
   Obj:=TJSONObject.Create;
@@ -1959,18 +1967,45 @@ begin
     RaiseMsg(20180206130333,Section);
     RaiseMsg(20180206130333,Section);
   if Scope.UsesScopes.Count<>length(Section.UsesClause) then
   if Scope.UsesScopes.Count<>length(Section.UsesClause) then
     RaiseMsg(20180206122222,Section);
     RaiseMsg(20180206122222,Section);
-  if length(Section.UsesClause)>0 then
+  Arr:=nil;
+  for i:=0 to Scope.UsesScopes.Count-1 do
     begin
     begin
-    Arr:=TJSONArray.Create;
-    ParentJSON.Add('Uses',Arr);
-    for i:=0 to Scope.UsesScopes.Count-1 do
+    UsesUnit:=Section.UsesClause[i];
+    UsesScope:=TPasSectionScope(Scope.UsesScopes[i]);
+    if UsesScope.Element<>UsesUnit.Module then
+      RaiseMsg(20180206122459,Section,'usesscope '+IntToStr(i)+' UsesScope.Element='+GetObjName(UsesScope.Element)+' Module='+GetObjName(Section.UsesClause[i].Module));
+    if Arr=nil then
       begin
       begin
-      UsesUnit:=Section.UsesClause[i];
-      UsesScope:=TPasSectionScope(Scope.UsesScopes[i]);
-      if UsesScope.Element<>UsesUnit.Module then
-        RaiseMsg(20180206122459,Section,'usesscope '+IntToStr(i)+' UsesScope.Element='+GetObjName(UsesScope.Element)+' Module='+GetObjName(Section.UsesClause[i].Module));
-      // ToDo
-      RaiseMsg(20180206124005,'ToDo');
+      Arr:=TJSONArray.Create;
+      ParentJSON.Add('Uses',Arr);
+      end;
+    SubObj:=TJSONObject.Create;
+    Arr.Add(SubObj);
+    Name:=DotExprToName(UsesUnit.Expr);
+    if Name='' then
+      RaiseMsg(20180307091654,UsesUnit.Expr);
+    SubObj.Add('Name',Name);
+    if UsesUnit.InFilename<>nil then
+      begin
+      InFilename:=Resolver.GetUsesUnitInFilename(UsesUnit.InFilename);
+      if InFilename='' then
+        RaiseMsg(20180307094723,UsesUnit.InFilename);
+      SubObj.Add('In',InFilename);
+      end;
+    if CompareText(UsesUnit.Module.Name,Name)<>0 then
+      SubObj.Add('UnitName',UsesUnit.Module.Name);
+    // ref object for uses
+    Ref:=GetElementReference(UsesUnit);
+    Ref.Obj:=SubObj;
+    if OnIsElementUsed(Self,UsesUnit.Module) then
+      begin
+      // ref object for module
+      Ref:=GetElementReference(UsesUnit.Module);
+      if Ref.Obj=nil then
+        begin
+        Ref.Obj:=TJSONObject.Create;
+        SubObj.Add('Refs',Ref.Obj);
+        end;
       end;
       end;
     end;
     end;
   WriteIdentifierScope(Obj,Scope,aContext);
   WriteIdentifierScope(Obj,Scope,aContext);
@@ -3901,7 +3936,7 @@ begin
         break;
         break;
         end;
         end;
     if not Found then
     if not Found then
-      RaiseMsg(20180202144009,'unknown ParserOption "'+s+'"');
+      RaiseMsg(20180202144009,El,'unknown ParserOption "'+s+'"');
     end;
     end;
 end;
 end;
 
 
@@ -3935,7 +3970,7 @@ begin
         break;
         break;
         end;
         end;
     if not Found then
     if not Found then
-      RaiseMsg(20180202144054,'unknown ModeSwitch "'+s+'"');
+      RaiseMsg(20180202144054,El,'unknown ModeSwitch "'+s+'"');
     end;
     end;
 end;
 end;
 
 
@@ -4226,25 +4261,74 @@ begin
   if aContext<>nil then ;
   if aContext<>nil then ;
 end;
 end;
 
 
-procedure TPJUReader.ReadSectionScope(Obj: TJSONObject;
-  Scope: TPasSectionScope; aContext: TPJUReaderContext);
+procedure TPJUReader.ReadUsedUnits(Obj: TJSONObject; Section: TPasSection;
+  aContext: TPJUReaderContext);
 var
 var
+  Arr: TJSONArray;
+  i, p: Integer;
   Data: TJSONData;
   Data: TJSONData;
-  UsesArr: TJSONArray;
-  Section: TPasSection;
-  i: Integer;
+  SubObj: TJSONObject;
+  Name, CurName, InFilename, ModuleName: string;
+  Use: TPasUsesUnit;
+  Prim: TPrimitiveExpr;
+  Module: TPasModule;
+begin
+  if not ReadArray(Obj,'Uses',Arr,Section) then exit;
+  SetLength(Section.UsesClause,Arr.Count);
+  for i:=0 to length(Section.UsesClause)-1 do
+    Section.UsesClause[i]:=nil;
+  for i:=0 to Arr.Count-1 do
+    begin
+    Data:=Arr[i];
+    if not (Data is TJSONObject) then
+      RaiseMsg(20180307103518,Section,GetObjName(Data));
+    SubObj:=TJSONObject(Data);
+    if not ReadString(SubObj,'Name',Name,Section) then
+      RaiseMsg(20180307103629,Section);
+    if not IsValidIdent(Name,true,true) then
+      RaiseMsg(20180307103937,Section,Name);
+    ReadString(SubObj,'In',InFilename,Section);
+    ReadString(SubObj,'UnitName',ModuleName,Section);
+    Use:=TPasUsesUnit.Create(Name,Section);
+    Section.UsesClause[i]:=Use;
+    while Name<>'' do
+      begin
+      p:=Pos('.',Name);
+      if p>0 then
+        begin
+        CurName:=LeftStr(Name,p-1);
+        Delete(Name,1,p)
+        end
+      else
+        begin
+        CurName:=Name;
+        Name:='';
+        end;
+      Prim:=TPrimitiveExpr.Create(Use,pekString,CurName);
+      if Use.Expr=nil then
+        Use.Expr:=Prim
+      else
+        Use.Expr:=TBinaryExpr.Create(Use,Use.Expr,Prim,eopSubIdent);
+      end;
+    if InFilename<>'' then
+      Use.InFilename:=TPrimitiveExpr.Create(Use,pekString,InFilename);
+    if ModuleName='' then ModuleName:=Name;
+    Module:=Resolver.FindModule(Name,Use.Expr,Use.InFilename);
+    if Module=nil then
+      RaiseMsg(20180307231247,Use);
+
+    // Refs
+    end;
+  Resolver.CheckPendingUsedInterface(Section);
+  if aContext=nil then ;
+end;
+
+procedure TPJUReader.ReadSectionScope(Obj: TJSONObject;
+  Scope: TPasSectionScope; aContext: TPJUReaderContext);
 begin
 begin
-  Section:=Scope.Element as TPasSection;
+  //Section:=Scope.Element as TPasSection;
   Scope.UsesFinished:=true;
   Scope.UsesFinished:=true;
   Scope.Finished:=true;
   Scope.Finished:=true;
-  Data:=Obj.Find('Uses');
-  if Data<>nil then
-    begin
-    UsesArr:=CheckJSONArray(Data,Section,'Uses');
-    // ToDo UsesClause
-    RaiseMsg(20180206124604,'ToDo');
-    for i:=0 to UsesArr.Count-1 do ;
-    end;
   ReadIdentifierScope(Obj,Scope,aContext);
   ReadIdentifierScope(Obj,Scope,aContext);
 end;
 end;
 
 
@@ -4259,6 +4343,8 @@ begin
   ReadPasElement(Obj,Section,aContext);
   ReadPasElement(Obj,Section,aContext);
 
 
   Scope:=TPasSectionScope(Resolver.CreateScope(Section,TPasSectionScope));
   Scope:=TPasSectionScope(Resolver.CreateScope(Section,TPasSectionScope));
+  ReadUsedUnits(Obj,Section,aContext);
+
   ReadSectionScope(Obj,Scope,aContext);
   ReadSectionScope(Obj,Scope,aContext);
 
 
   ReadDeclarations(Obj,Section,aContext);
   ReadDeclarations(Obj,Section,aContext);
@@ -5042,7 +5128,7 @@ begin
   ReadPasScope(Obj,Scope,aContext);
   ReadPasScope(Obj,Scope,aContext);
 end;
 end;
 
 
-procedure TPJUReader.ReadModule(Data: TJSONData; aContext: TPJUReaderContext);
+procedure TPJUReader.ReadModule(Obj: TJSONObject; aContext: TPJUReaderContext);
 var
 var
   aModule: TPasModule;
   aModule: TPasModule;
 
 
@@ -5069,7 +5155,7 @@ var
   end;
   end;
 
 
 var
 var
-  Obj, SubObj: TJSONObject;
+  SubObj: TJSONObject;
   aType, aName: String;
   aType, aName: String;
   ModScope: TPas2JSModuleScope;
   ModScope: TPas2JSModuleScope;
   OldBoolSwitches: TBoolSwitches;
   OldBoolSwitches: TBoolSwitches;
@@ -5077,7 +5163,6 @@ begin
   {$IFDEF VerbosePJUFiler}
   {$IFDEF VerbosePJUFiler}
   writeln('TPJUReader.ReadModule START ');
   writeln('TPJUReader.ReadModule START ');
   {$ENDIF}
   {$ENDIF}
-  Obj:=CheckJSONObject(Data,20180203100422);
   aName:=String(Obj.Get('Name',''));
   aName:=String(Obj.Get('Name',''));
   aType:=String(Obj.Get('Type',''));
   aType:=String(Obj.Get('Type',''));
   case aType of
   case aType of
@@ -5109,6 +5194,8 @@ begin
       begin
       begin
       aModule.InterfaceSection:=TInterfaceSection.Create('',aModule);
       aModule.InterfaceSection:=TInterfaceSection.Create('',aModule);
       ReadSection(SubObj,aModule.InterfaceSection,aContext);
       ReadSection(SubObj,aModule.InterfaceSection,aContext);
+      if aModule.InterfaceSection.PendingUsedIntf<>nil then
+        exit;
       end;
       end;
     SubObj:=PreReadSection(Obj,'Implementation');
     SubObj:=PreReadSection(Obj,'Implementation');
     if SubObj<>nil then
     if SubObj<>nil then
@@ -6130,64 +6217,75 @@ begin
   finally
   finally
     JParser.Free;
     JParser.Free;
   end;
   end;
-  ReadJSON(aResolver,TJSONObject(Data));
+  ReadJSONHeader(aResolver,TJSONObject(Data));
 end;
 end;
 
 
-procedure TPJUReader.ReadJSON(aResolver: TPas2JSResolver;
+procedure TPJUReader.ReadJSONHeader(aResolver: TPas2JSResolver;
   Obj: TJSONObject);
   Obj: TJSONObject);
 var
 var
   aName: String;
   aName: String;
   Data: TJSONData;
   Data: TJSONData;
   i: Integer;
   i: Integer;
-  aContext: TPJUReaderContext;
-  aModule: TPasModule;
 begin
 begin
   {$IFDEF VerbosePJUFiler}
   {$IFDEF VerbosePJUFiler}
-  writeln('TPJUReader.ReadModuleAsJSON START ');
+  writeln('TPJUReader.ReadJSONHeader START ');
   {$ENDIF}
   {$ENDIF}
   FResolver:=aResolver;
   FResolver:=aResolver;
   FParser:=Resolver.CurrentParser;
   FParser:=Resolver.CurrentParser;
   FScanner:=FParser.Scanner;
   FScanner:=FParser.Scanner;
+  FJSON:=Obj;
 
 
   ReadHeaderMagic(Obj);
   ReadHeaderMagic(Obj);
   ReadHeaderVersion(Obj);
   ReadHeaderVersion(Obj);
 
 
-  aModule:=nil;
   for i:=0 to Obj.Count-1 do
   for i:=0 to Obj.Count-1 do
     begin
     begin
     aName:=Obj.Names[i];
     aName:=Obj.Names[i];
     {$IFDEF VerbosePJUFiler}
     {$IFDEF VerbosePJUFiler}
-    writeln('TPJUReader.ReadModuleAsJSON ',aName);
+    writeln('TPJUReader.ReadJSONHeader ',aName);
     {$ENDIF}
     {$ENDIF}
     Data:=Obj.Elements[aName];
     Data:=Obj.Elements[aName];
-    case Obj.Names[i] of
-    'FileType': ;
-    'Version': ;
-    'ParserOptions': InitialFlags.ParserOptions:=ReadParserOptions(Data,aModule,PJUDefaultParserOptions);
-    'ModeSwitches': InitialFlags.ModeSwitches:=ReadModeSwitches(Data,aModule,PJUDefaultModeSwitches);
-    'BoolSwitches': InitialFlags.BoolSwitches:=ReadBoolSwitches(Obj,aModule,aName,PJUDefaultBoolSwitches);
-    'ConverterOptions': InitialFlags.ConverterOptions:=ReadConverterOptions(Data,aModule,PJUDefaultConvertOptions);
+    case aName of
+    'FileType': ; // done in ReadHeaderMagic
+    'Version': ; // done in ReadHeaderVersion
     'TargetPlatform': ReadTargetPlatform(Data);
     'TargetPlatform': ReadTargetPlatform(Data);
     'TargetProcessor': ReadTargetProcessor(Data);
     'TargetProcessor': ReadTargetProcessor(Data);
     'Sources': ReadSrcFiles(Data);
     'Sources': ReadSrcFiles(Data);
-    'Module':
-      begin
-      aContext:=TPJUReaderContext.Create;
-      try
-        aContext.ModeSwitches:=InitialFlags.ModeSwitches;
-        aContext.BoolSwitches:=InitialFlags.BoolSwitches;
-        ReadModule(Data,aContext);
-        aModule:=aResolver.RootElement;
-      finally
-        aContext.Free;
-      end;
-      end
+    'ParserOptions': InitialFlags.ParserOptions:=ReadParserOptions(Data,nil,PJUDefaultParserOptions);
+    'ModeSwitches': InitialFlags.ModeSwitches:=ReadModeSwitches(Data,nil,PJUDefaultModeSwitches);
+    'BoolSwitches': InitialFlags.BoolSwitches:=ReadBoolSwitches(Obj,nil,aName,PJUDefaultBoolSwitches);
+    'ConverterOptions': InitialFlags.ConverterOptions:=ReadConverterOptions(Data,nil,PJUDefaultConvertOptions);
+    'Module': ReadJSONContinue;
     else
     else
       RaiseMsg(20180202151706,'unknown property "'+aName+'"');
       RaiseMsg(20180202151706,'unknown property "'+aName+'"');
     end;
     end;
     end;
     end;
   {$IFDEF VerbosePJUFiler}
   {$IFDEF VerbosePJUFiler}
-  writeln('TPJUReader.ReadModuleAsJSON END');
+  writeln('TPJUReader.ReadJSONHeader END');
+  {$ENDIF}
+end;
+
+procedure TPJUReader.ReadJSONContinue;
+var
+  Obj, SubObj: TJSONObject;
+  aContext: TPJUReaderContext;
+begin
+  {$IFDEF VerbosePJUFiler}
+  writeln('TPJUReader.ReadJSONContinue START');
+  {$ENDIF}
+  Obj:=JSON;
+  if not ReadObject(Obj,'Module',SubObj,nil) then
+    RaiseMsg(20180307114005,'missing Module');
+  aContext:=TPJUReaderContext.Create;
+  try
+    aContext.ModeSwitches:=InitialFlags.ModeSwitches;
+    aContext.BoolSwitches:=InitialFlags.BoolSwitches;
+    ReadModule(SubObj,aContext);
+  finally
+    aContext.Free;
+  end;
+  {$IFDEF VerbosePJUFiler}
+  writeln('TPJUReader.ReadJSONContinue END');
   {$ENDIF}
   {$ENDIF}
 end;
 end;
 
 

+ 1 - 0
packages/pastojs/tests/tcfiler.pas

@@ -261,6 +261,7 @@ begin
   try
   try
     try
     try
       PJUWriter.OnGetSrc:=@OnFilerGetSrc;
       PJUWriter.OnGetSrc:=@OnFilerGetSrc;
+      PJUWriter.OnIsElementUsed:=@OnConverterIsElementUsed;
       PJUWriter.WritePJU(Engine,Converter,InitialFlags,ms,false);
       PJUWriter.WritePJU(Engine,Converter,InitialFlags,ms,false);
     except
     except
       on E: Exception do
       on E: Exception do