Browse Source

* pas2jni: Fixed handling of identical names of classes, proctypes when they are defined in different units.

git-svn-id: trunk@34327 -
yury 9 years ago
parent
commit
c4347e28b9
1 changed files with 94 additions and 36 deletions
  1. 94 36
      utils/pas2jni/writer.pas

+ 94 - 36
utils/pas2jni/writer.pas

@@ -54,12 +54,45 @@ type
     property SIndent: string read FIndStr;
   end;
 
+  { TClassInfo }
+
+  TClassInfo = class
+  public
+    Def: TDef;
+    Funcs: TObjectList;
+    IsCommonClass: boolean;
+    constructor Create;
+    destructor Destroy; override;
+  end;
+
+  { TProcInfo }
+
+  TProcInfo = class
+  public
+    Name: string;
+    JniName: string;
+    JniSignature: string;
+  end;
+
+  { TClassList }
+
+  TClassList = class(TStringList)
+  private
+    function GetFullName(const AName: string; Def: TDef): string;
+  public
+    constructor Create;
+    function Add(const AName: string; Def: TDef; Info: TClassInfo): integer;
+    function IndexOf(const AName: string; Def: TDef): integer; reintroduce;
+    function GetClassName(Index: integer): string;
+    function GetClassInfo(Index: integer): TClassInfo;
+  end;
+
   { TWriter }
 
   TWriter = class
   private
     Fjs, Fps: TTextOutStream;
-    FClasses: TStringList;
+    FClasses: TClassList;
     FPkgDir: string;
     FUniqueCnt: integer;
     FThisUnit: TUnitDef;
@@ -169,6 +202,50 @@ begin
   Result:='{$ifdef windows} stdcall {$else} cdecl {$endif};';
 end;
 
+{ TClassList }
+
+function TClassList.IndexOf(const AName: string; Def: TDef): integer;
+begin
+  Result:=inherited IndexOf(GetFullName(AName, Def));
+end;
+
+function TClassList.GetClassName(Index: integer): string;
+var
+  i: integer;
+begin
+  Result:=Strings[Index];
+  i:=Pos('.', Result);
+  if i > 0 then
+    System.Delete(Result, 1, i);
+end;
+
+function TClassList.GetClassInfo(Index: integer): TClassInfo;
+begin
+  Result:=TClassInfo(Objects[Index]);
+end;
+
+function TClassList.GetFullName(const AName: string; Def: TDef): string;
+begin
+  if (Def = nil) or (Def.DefType = dtUnit) then
+    Result:=AName
+  else begin
+    while (Def.Parent <> nil) and (Def.DefType <> dtUnit) do
+      Def:=Def.Parent;
+    Result:=Def.Name + '.' + AName;
+  end;
+end;
+
+constructor TClassList.Create;
+begin
+  inherited Create;
+  Sorted:=True;
+end;
+
+function TClassList.Add(const AName: string; Def: TDef; Info: TClassInfo): integer;
+begin
+  Result:=AddObject(GetFullName(AName, Def), Info);
+end;
+
 { TTextOutStream }
 
 procedure TTextOutStream.SetIndednt(const AValue: integer);
@@ -210,24 +287,6 @@ begin
     Indent:=Indent - 1;
 end;
 
-type
-  { TClassInfo }
-  TClassInfo = class
-  public
-    Def: TDef;
-    Funcs: TObjectList;
-    IsCommonClass: boolean;
-    constructor Create;
-    destructor Destroy; override;
-  end;
-
-  TProcInfo = class
-  public
-    Name: string;
-    JniName: string;
-    JniSignature: string;
-  end;
-
 { TClassInfo }
 
 constructor TClassInfo.Create;
@@ -705,9 +764,9 @@ begin
     pi.JniSignature:=GetProcSignature(d);
     if AParent = nil then begin
       // Checking duplicate proc name and duplicate param types
-      ClassIdx:=FClasses.IndexOf(GetJavaClassName(d.Parent, ItemDef));
+      ClassIdx:=FClasses.IndexOf(GetJavaClassName(d.Parent, ItemDef), d.Parent);
       if ClassIdx >= 0 then begin
-        ci:=TClassInfo(FClasses.Objects[ClassIdx]);
+        ci:=FClasses.GetClassInfo(ClassIdx);
         j:=1;
         ss:=Copy(pi.JniSignature, 1, Pos(')', pi.JniSignature));
         repeat
@@ -973,16 +1032,16 @@ begin
       AParent:=d.Parent;
     end
     else
-      ClassIdx:=FClasses.IndexOf(GetJavaClassName(AParent, ItemDef));
+      ClassIdx:=FClasses.IndexOf(GetJavaClassName(AParent, ItemDef), AParent);
 
     if ClassIdx < 0 then begin
       ci:=TClassInfo.Create;
       ci.Def:=AParent;
       s:=GetJavaClassName(AParent, ItemDef);
       ci.IsCommonClass:=s <> AParent.Name;
-      ClassIdx:=FClasses.AddObject(s, ci);
+      ClassIdx:=FClasses.Add(s, AParent, ci);
     end;
-    TClassInfo(FClasses.Objects[ClassIdx]).Funcs.Add(pi);
+    FClasses.GetClassInfo(ClassIdx).Funcs.Add(pi);
     pi:=nil;
 
     // Java part
@@ -1913,10 +1972,10 @@ begin
 
   Fps.WriteLn('const');
   for i:=0 to FClasses.Count - 1 do begin
-    ci:=TClassInfo(FClasses.Objects[i]);
+    ci:=FClasses.GetClassInfo(i);
     if ci.Funcs.Count = 0 then
       continue;
-    Fps.WriteLn(Format('  _%sNativeMethods: array[0..%d] of JNINativeMethod = (', [GetClassPrefix(ci.Def, FClasses[i]), ci.Funcs.Count - 1]));
+    Fps.WriteLn(Format('  _%sNativeMethods: array[0..%d] of JNINativeMethod = (', [GetClassPrefix(ci.Def, FClasses.GetClassName(i)), ci.Funcs.Count - 1]));
     for j:=0 to ci.Funcs.Count - 1 do begin
       with TProcInfo(ci.Funcs[j]) do
         Fps.Write(Format('    (name: ''%s''; signature: ''%s''; fnPtr: @%s)', [Name, JniSignature, JniName]));
@@ -1975,7 +2034,7 @@ begin
   end;
 
   for i:=0 to FClasses.Count - 1 do begin
-    ci:=TClassInfo(FClasses.Objects[i]);
+    ci:=FClasses.GetClassInfo(i);
     s:=GetTypeInfoVar(ci.Def);
     if (s = '') or (ci.IsCommonClass) then
       s:='nil'
@@ -1984,13 +2043,13 @@ begin
     if ci.Funcs.Count = 0 then
       ss:='nil'
     else
-      ss:=Format('@_%sNativeMethods', [GetClassPrefix(ci.Def, FClasses[i])]);
+      ss:=Format('@_%sNativeMethods', [GetClassPrefix(ci.Def, FClasses.GetClassName(i))]);
     fn:='';
     if ci.Def <> nil then
       if ci.Def.DefType in [dtSet, dtEnum] then
         fn:=', ''Value'', ''I''';
     Fps.WriteLn(Format('if not _Reg(''%s'', %s, %d, %s%s) then exit;',
-                       [GetJavaClassPath(ci.Def, FClasses[i]), ss, ci.Funcs.Count, s, fn]));
+                       [GetJavaClassPath(ci.Def, FClasses.GetClassName(i)), ss, ci.Funcs.Count, s, fn]));
   end;
 
   Fps.WriteLn('Result:=JNI_VERSION_1_6;');
@@ -2271,10 +2330,10 @@ procedure TWriter.RegisterPseudoClass(d: TDef);
 var
   ci: TClassInfo;
 begin
-  if FClasses.IndexOf(d.Name) < 0 then begin
+  if FClasses.IndexOf(d.Name, d) < 0 then begin
     ci:=TClassInfo.Create;
     ci.Def:=d;
-    FClasses.AddObject(d.Name, ci);
+    FClasses.Add(d.Name, d, ci);
   end;
 end;
 
@@ -2327,13 +2386,13 @@ begin
   pi.Name:=Name;
   pi.JniName:=JniName;
   pi.JniSignature:=Signature;
-  i:=FClasses.IndexOf(ParentDef.AliasName);
+  i:=FClasses.IndexOf(ParentDef.AliasName, ParentDef);
   if i < 0 then begin
     ci:=TClassInfo.Create;
     ci.Def:=ParentDef;
-    i:=FClasses.AddObject(ParentDef.AliasName, ci);
+    i:=FClasses.Add(ParentDef.AliasName, ParentDef, ci);
   end;
-  TClassInfo(FClasses.Objects[i]).Funcs.Add(pi);
+  FClasses.GetClassInfo(i).Funcs.Add(pi);
 end;
 
 function TWriter.GetProcSignature(d: TProcDef): string;
@@ -2420,8 +2479,7 @@ var
   i: integer;
 begin
   Units:=TStringList.Create;
-  FClasses:=TStringList.Create;
-  FClasses.Sorted:=True;
+  FClasses:=TClassList.Create;
   JavaPackage:='pas';
   IncludeList:=TStringList.Create;
   IncludeList.Duplicates:=dupIgnore;