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

git-svn-id: trunk@34327 -
This commit is contained in:
yury 2016-08-17 19:09:54 +00:00
parent 6a3466e81a
commit c4347e28b9

View File

@ -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;