pas2jsuseanalyzer.pp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. {
  2. This file is part of the Free Component Library (FCL)
  3. Copyright (c) 2019 Mattias Gaertner [email protected]
  4. Pascal to Javascript converter class.
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************
  11. Abstract:
  12. Extends the FCL Pascal use analyzer for the language subset of pas2js.
  13. Works:
  14. - Array of Const marks function System.VarRecs()
  15. - TPascalDescendantOfExt.Create marks class method NewInstance
  16. }
  17. unit Pas2jsUseAnalyzer;
  18. {$mode objfpc}{$H+}
  19. {$inline on}
  20. interface
  21. uses
  22. Classes,
  23. PasUseAnalyzer, PasTree, PasResolver,
  24. FPPas2Js;
  25. type
  26. { TPas2JSAnalyzer }
  27. TPas2JSAnalyzer = class(TPasAnalyzer)
  28. public
  29. procedure UseExpr(El: TPasExpr); override;
  30. procedure UseConstructor(Proc: TPasConstructor; PosEl: TPasElement); virtual;
  31. end;
  32. implementation
  33. { TPas2JSAnalyzer }
  34. procedure TPas2JSAnalyzer.UseExpr(El: TPasExpr);
  35. procedure CheckArgs(Args: TFPList);
  36. var
  37. i: Integer;
  38. ArgType: TPasType;
  39. ModScope: TPas2JSModuleScope;
  40. aMod: TPasModule;
  41. SystemVarRecs: TPasFunction;
  42. begin
  43. if Args=nil then exit;
  44. for i:=0 to Args.Count-1 do
  45. begin
  46. ArgType:=TPasArgument(Args[i]).ArgType;
  47. if ArgType=nil then continue;
  48. if (ArgType.ClassType=TPasArrayType)
  49. and (TPasArrayType(ArgType).ElType=nil) then
  50. begin
  51. // array of const
  52. aMod:=El.GetModule;
  53. ModScope:=NoNil(aMod.CustomData) as TPas2JSModuleScope;
  54. SystemVarRecs:=ModScope.SystemVarRecs;
  55. if SystemVarRecs=nil then
  56. RaiseNotSupported(20190216104347,El);
  57. MarkImplScopeRef(El,SystemVarRecs,psraRead);
  58. UseProcedure(SystemVarRecs);
  59. break;
  60. end;
  61. end;
  62. end;
  63. var
  64. Ref: TResolvedReference;
  65. Decl: TPasElement;
  66. begin
  67. if El=nil then exit;
  68. inherited UseExpr(El);
  69. Ref:=nil;
  70. if El.CustomData is TResolvedReference then
  71. begin
  72. // this is a reference -> mark target
  73. Ref:=TResolvedReference(El.CustomData);
  74. Decl:=Ref.Declaration;
  75. if Decl is TPasProcedure then
  76. begin
  77. CheckArgs(TPasProcedure(Decl).ProcType.Args);
  78. if Decl.ClassType=TPasConstructor then
  79. UseConstructor(TPasConstructor(Decl),El);
  80. end
  81. else if Decl.ClassType=TPasProperty then
  82. CheckArgs(Resolver.GetPasPropertyArgs(TPasProperty(Decl)));
  83. end;
  84. end;
  85. procedure TPas2JSAnalyzer.UseConstructor(Proc: TPasConstructor;
  86. PosEl: TPasElement);
  87. var
  88. ClassScope: TPas2JSClassScope;
  89. begin
  90. if Proc.Parent.ClassType=TPasClassType then
  91. begin
  92. ClassScope:=TPasClassType(Proc.Parent).CustomData as TPas2JSClassScope;
  93. repeat
  94. if ClassScope.NewInstanceFunction<>nil then
  95. begin
  96. UseProcedure(ClassScope.NewInstanceFunction);
  97. break;
  98. end;
  99. ClassScope:=ClassScope.AncestorScope as TPas2JSClassScope;
  100. until ClassScope=nil;
  101. end;
  102. if PosEl=nil then ;
  103. end;
  104. end.