mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-24 02:00:34 +02:00
Merged revision(s) 33859, 34275, 34309, 34327, 34367, 34369, 34634 from trunk:
* pas2jni: Explicitly release JNI local refs while executing method pointers. ........ * pas2jni: Fixed string constant handling after recent changes in FPC. ........ * pas2jni: Fixed invoking of Java event handlers from non-main threads. ........ * pas2jni: Fixed handling of identical names of classes, proctypes when they are defined in different units. ........ * pas2jni: Removed option to create event handler by passing Java method method name as a string. It is not safe, since the target method is treated as unused by Java and the method may be removed from the resulting application. ........ * pas2jni: Reverted r34367 and mark undesired event handler creation "deprecated". ........ git-svn-id: branches/fixes_3_0@34774 -
This commit is contained in:
parent
93d5be005e
commit
80e88fdc34
@ -33,11 +33,12 @@ The following Pascal features are supported by pas2jni:
|
|||||||
- pointer type;
|
- pointer type;
|
||||||
- string types;
|
- string types;
|
||||||
- all numeric types;
|
- all numeric types;
|
||||||
- method pointer.
|
- method pointer;
|
||||||
|
- setters/getters for array elements.
|
||||||
|
|
||||||
USUPPORTED features:
|
USUPPORTED features:
|
||||||
- array;
|
- Full support for arrays;
|
||||||
- procedure pointer.
|
- procedure pointer (Not possible to implement. To workaround this limitation create a procedure handler in your Pascal code and call a method pointer declared in some global Pascal class. Then you can assign this method pointer from a Java code).
|
||||||
|
|
||||||
Shared libraries, generated by pas2jni were tested with Java on Windows and Android. It should work on other systems as well.
|
Shared libraries, generated by pas2jni were tested with Java on Windows and Android. It should work on other systems as well.
|
||||||
|
|
||||||
@ -84,9 +85,7 @@ In a Java code you get the following TMyClass instance:
|
|||||||
|
|
||||||
TMyClass myclass = TMyClass.Create();
|
TMyClass myclass = TMyClass.Create();
|
||||||
|
|
||||||
It is possible set a Java handler in 2 ways:
|
Then you add the event handler in a usual Java way:
|
||||||
|
|
||||||
1) Place the handler inline.
|
|
||||||
|
|
||||||
...
|
...
|
||||||
myclass.setOnChange(
|
myclass.setOnChange(
|
||||||
@ -98,21 +97,6 @@ It is possible set a Java handler in 2 ways:
|
|||||||
);
|
);
|
||||||
...
|
...
|
||||||
|
|
||||||
2) Define the handler as a method in a class.
|
|
||||||
|
|
||||||
public class MyJavaClass {
|
|
||||||
private void DoOnChange(TObject Sender) {
|
|
||||||
// The handler code
|
|
||||||
}
|
|
||||||
|
|
||||||
public void main() {
|
|
||||||
...
|
|
||||||
// Set the handler to the method with the "DoOnChange" name in the current class (this).
|
|
||||||
myclass.setOnChange( new TNotifyEvent(this, "DoOnChange") );
|
|
||||||
...
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
COMMAND LINE OPTIONS
|
COMMAND LINE OPTIONS
|
||||||
|
|
||||||
Usage: pas2jni [options] <unit> [<unit2> <unit3> ...]
|
Usage: pas2jni [options] <unit> [<unit2> <unit3> ...]
|
||||||
|
@ -54,12 +54,45 @@ type
|
|||||||
property SIndent: string read FIndStr;
|
property SIndent: string read FIndStr;
|
||||||
end;
|
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 }
|
||||||
|
|
||||||
TWriter = class
|
TWriter = class
|
||||||
private
|
private
|
||||||
Fjs, Fps: TTextOutStream;
|
Fjs, Fps: TTextOutStream;
|
||||||
FClasses: TStringList;
|
FClasses: TClassList;
|
||||||
FPkgDir: string;
|
FPkgDir: string;
|
||||||
FUniqueCnt: integer;
|
FUniqueCnt: integer;
|
||||||
FThisUnit: TUnitDef;
|
FThisUnit: TUnitDef;
|
||||||
@ -169,6 +202,50 @@ begin
|
|||||||
Result:='{$ifdef windows} stdcall {$else} cdecl {$endif};';
|
Result:='{$ifdef windows} stdcall {$else} cdecl {$endif};';
|
||||||
end;
|
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 }
|
{ TTextOutStream }
|
||||||
|
|
||||||
procedure TTextOutStream.SetIndednt(const AValue: integer);
|
procedure TTextOutStream.SetIndednt(const AValue: integer);
|
||||||
@ -210,24 +287,6 @@ begin
|
|||||||
Indent:=Indent - 1;
|
Indent:=Indent - 1;
|
||||||
end;
|
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 }
|
{ TClassInfo }
|
||||||
|
|
||||||
constructor TClassInfo.Create;
|
constructor TClassInfo.Create;
|
||||||
@ -705,9 +764,9 @@ begin
|
|||||||
pi.JniSignature:=GetProcSignature(d);
|
pi.JniSignature:=GetProcSignature(d);
|
||||||
if AParent = nil then begin
|
if AParent = nil then begin
|
||||||
// Checking duplicate proc name and duplicate param types
|
// 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
|
if ClassIdx >= 0 then begin
|
||||||
ci:=TClassInfo(FClasses.Objects[ClassIdx]);
|
ci:=FClasses.GetClassInfo(ClassIdx);
|
||||||
j:=1;
|
j:=1;
|
||||||
ss:=Copy(pi.JniSignature, 1, Pos(')', pi.JniSignature));
|
ss:=Copy(pi.JniSignature, 1, Pos(')', pi.JniSignature));
|
||||||
repeat
|
repeat
|
||||||
@ -973,16 +1032,16 @@ begin
|
|||||||
AParent:=d.Parent;
|
AParent:=d.Parent;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
ClassIdx:=FClasses.IndexOf(GetJavaClassName(AParent, ItemDef));
|
ClassIdx:=FClasses.IndexOf(GetJavaClassName(AParent, ItemDef), AParent);
|
||||||
|
|
||||||
if ClassIdx < 0 then begin
|
if ClassIdx < 0 then begin
|
||||||
ci:=TClassInfo.Create;
|
ci:=TClassInfo.Create;
|
||||||
ci.Def:=AParent;
|
ci.Def:=AParent;
|
||||||
s:=GetJavaClassName(AParent, ItemDef);
|
s:=GetJavaClassName(AParent, ItemDef);
|
||||||
ci.IsCommonClass:=s <> AParent.Name;
|
ci.IsCommonClass:=s <> AParent.Name;
|
||||||
ClassIdx:=FClasses.AddObject(s, ci);
|
ClassIdx:=FClasses.Add(s, AParent, ci);
|
||||||
end;
|
end;
|
||||||
TClassInfo(FClasses.Objects[ClassIdx]).Funcs.Add(pi);
|
FClasses.GetClassInfo(ClassIdx).Funcs.Add(pi);
|
||||||
pi:=nil;
|
pi:=nil;
|
||||||
|
|
||||||
// Java part
|
// Java part
|
||||||
@ -1170,19 +1229,30 @@ begin
|
|||||||
s:='double';
|
s:='double';
|
||||||
end
|
end
|
||||||
else begin
|
else begin
|
||||||
s:=DefToJavaType(d.VarType);
|
s:='';
|
||||||
if d.VarType.DefType = dtType then
|
case d.VarType.DefType of
|
||||||
case TTypeDef(d.VarType).BasicType of
|
dtType:
|
||||||
btLongWord, btInt64:
|
case TTypeDef(d.VarType).BasicType of
|
||||||
v:=v + 'L';
|
btLongWord, btInt64:
|
||||||
btBoolean:
|
v:=v + 'L';
|
||||||
if v = '1' then
|
btBoolean:
|
||||||
v:='true'
|
if v = '1' then
|
||||||
else
|
v:='true'
|
||||||
v:='false';
|
else
|
||||||
end;
|
v:='false';
|
||||||
|
end;
|
||||||
|
dtArray:
|
||||||
|
with TArrayDef(d.VarType) do
|
||||||
|
if (ElType.DefType = dtType) and (TTypeDef(ElType).BasicType in [btChar, btWideChar]) then
|
||||||
|
s:='String';
|
||||||
|
end;
|
||||||
|
if s = '' then
|
||||||
|
s:=DefToJavaType(d.VarType);
|
||||||
end;
|
end;
|
||||||
Fjs.WriteLn(Format('public static final %s %s = %s;', [s, d.Name, v]));
|
v:=Format('public static final %s %s = %s;', [s, d.Name, v]);
|
||||||
|
if s = SUnsupportedType then
|
||||||
|
v:='// ' + v;
|
||||||
|
Fjs.WriteLn(v);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TWriter.WriteEnum(d: TDef);
|
procedure TWriter.WriteEnum(d: TDef);
|
||||||
@ -1254,6 +1324,7 @@ begin
|
|||||||
Fps.WriteLn('var');
|
Fps.WriteLn('var');
|
||||||
Fps.IncI;
|
Fps.IncI;
|
||||||
Fps.WriteLn('_env: PJNIEnv;');
|
Fps.WriteLn('_env: PJNIEnv;');
|
||||||
|
Fps.WriteLn('_new_env: boolean;');
|
||||||
Fps.WriteLn('_mpi: _TMethodPtrInfo;');
|
Fps.WriteLn('_mpi: _TMethodPtrInfo;');
|
||||||
if d.Count > 0 then begin
|
if d.Count > 0 then begin
|
||||||
Fps.WriteLn(Format('_args: array[0..%d] of jvalue;', [d.Count - 1]));
|
Fps.WriteLn(Format('_args: array[0..%d] of jvalue;', [d.Count - 1]));
|
||||||
@ -1270,6 +1341,11 @@ begin
|
|||||||
Fps.WriteLn('begin');
|
Fps.WriteLn('begin');
|
||||||
Fps.IncI;
|
Fps.IncI;
|
||||||
Fps.WriteLn('CurJavaVM^^.GetEnv(CurJavaVM, @_env, JNI_VERSION_1_6);');
|
Fps.WriteLn('CurJavaVM^^.GetEnv(CurJavaVM, @_env, JNI_VERSION_1_6);');
|
||||||
|
Fps.WriteLn('_new_env:=_env = nil;');
|
||||||
|
Fps.WriteLn('if _new_env then CurJavaVM^^.AttachCurrentThread(CurJavaVM, @_env, nil);');
|
||||||
|
Fps.WriteLn('_env^^.PushLocalFrame(_env, 100);');
|
||||||
|
Fps.WriteLn('try');
|
||||||
|
Fps.IncI;
|
||||||
Fps.WriteLn('_MethodPointersCS.Enter;');
|
Fps.WriteLn('_MethodPointersCS.Enter;');
|
||||||
Fps.WriteLn('try');
|
Fps.WriteLn('try');
|
||||||
Fps.WriteLn('_mpi:=_TMethodPtrInfo(_MethodPointers[-integer(ptruint(Self)) - 1]);', 1);
|
Fps.WriteLn('_mpi:=_TMethodPtrInfo(_MethodPointers[-integer(ptruint(Self)) - 1]);', 1);
|
||||||
@ -1330,6 +1406,11 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
Fps.DecI;
|
||||||
|
Fps.WriteLn('finally');
|
||||||
|
Fps.WriteLn('_env^^.PopLocalFrame(_env, nil);', 1);
|
||||||
|
Fps.WriteLn('if _new_env then CurJavaVM^^.DetachCurrentThread(CurJavaVM);', 1);
|
||||||
|
Fps.WriteLn('end;');
|
||||||
Fps.DecI;
|
Fps.DecI;
|
||||||
Fps.WriteLn('end;');
|
Fps.WriteLn('end;');
|
||||||
|
|
||||||
@ -1356,7 +1437,7 @@ begin
|
|||||||
Fjs.IncI;
|
Fjs.IncI;
|
||||||
Fjs.WriteLn(Format('{ mSignature = "%s"; }', [GetProcSignature(d)]));
|
Fjs.WriteLn(Format('{ mSignature = "%s"; }', [GetProcSignature(d)]));
|
||||||
Fjs.WriteLn(Format('protected %s(long objptr, boolean cleanup) { _pasobj=objptr; }', [d.Name]));
|
Fjs.WriteLn(Format('protected %s(long objptr, boolean cleanup) { _pasobj=objptr; }', [d.Name]));
|
||||||
Fjs.WriteLn(Format('public %s(Object Obj, String MethodName) { mObject=Obj; mName=MethodName; }', [d.Name]));
|
Fjs.WriteLn(Format('@Deprecated public %s(Object Obj, String MethodName) { mObject=Obj; mName=MethodName; }', [d.Name]));
|
||||||
Fjs.WriteLn(Format('public %s() { mObject=this; mName="Execute"; }', [d.Name]));
|
Fjs.WriteLn(Format('public %s() { mObject=this; mName="Execute"; }', [d.Name]));
|
||||||
Fjs.WriteLn(Format('protected %s throws NoSuchMethodException { throw new NoSuchMethodException(); }', [GetJavaProcDeclaration(d, 'Execute')]));
|
Fjs.WriteLn(Format('protected %s throws NoSuchMethodException { throw new NoSuchMethodException(); }', [GetJavaProcDeclaration(d, 'Execute')]));
|
||||||
Fjs.DecI;
|
Fjs.DecI;
|
||||||
@ -1770,6 +1851,7 @@ begin
|
|||||||
Fjs.WriteLn('public int Value;');
|
Fjs.WriteLn('public int Value;');
|
||||||
Fjs.WriteLn('public int Ord() { return Value; }');
|
Fjs.WriteLn('public int Ord() { return Value; }');
|
||||||
Fjs.WriteLn('@Override public boolean equals(Object o) { return (o instanceof Integer) && Value == (Integer)o; }');
|
Fjs.WriteLn('@Override public boolean equals(Object o) { return (o instanceof Integer) && Value == (Integer)o; }');
|
||||||
|
Fjs.WriteLn('public boolean equals(int v) { return Value == v; }');
|
||||||
Fjs.WriteLn('@Override public int hashCode() { return Value; }');
|
Fjs.WriteLn('@Override public int hashCode() { return Value; }');
|
||||||
Fjs.DecI;
|
Fjs.DecI;
|
||||||
Fjs.WriteLn('}');
|
Fjs.WriteLn('}');
|
||||||
@ -1891,10 +1973,10 @@ begin
|
|||||||
|
|
||||||
Fps.WriteLn('const');
|
Fps.WriteLn('const');
|
||||||
for i:=0 to FClasses.Count - 1 do begin
|
for i:=0 to FClasses.Count - 1 do begin
|
||||||
ci:=TClassInfo(FClasses.Objects[i]);
|
ci:=FClasses.GetClassInfo(i);
|
||||||
if ci.Funcs.Count = 0 then
|
if ci.Funcs.Count = 0 then
|
||||||
continue;
|
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
|
for j:=0 to ci.Funcs.Count - 1 do begin
|
||||||
with TProcInfo(ci.Funcs[j]) do
|
with TProcInfo(ci.Funcs[j]) do
|
||||||
Fps.Write(Format(' (name: ''%s''; signature: ''%s''; fnPtr: @%s)', [Name, JniSignature, JniName]));
|
Fps.Write(Format(' (name: ''%s''; signature: ''%s''; fnPtr: @%s)', [Name, JniSignature, JniName]));
|
||||||
@ -1953,7 +2035,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
for i:=0 to FClasses.Count - 1 do begin
|
for i:=0 to FClasses.Count - 1 do begin
|
||||||
ci:=TClassInfo(FClasses.Objects[i]);
|
ci:=FClasses.GetClassInfo(i);
|
||||||
s:=GetTypeInfoVar(ci.Def);
|
s:=GetTypeInfoVar(ci.Def);
|
||||||
if (s = '') or (ci.IsCommonClass) then
|
if (s = '') or (ci.IsCommonClass) then
|
||||||
s:='nil'
|
s:='nil'
|
||||||
@ -1962,13 +2044,13 @@ begin
|
|||||||
if ci.Funcs.Count = 0 then
|
if ci.Funcs.Count = 0 then
|
||||||
ss:='nil'
|
ss:='nil'
|
||||||
else
|
else
|
||||||
ss:=Format('@_%sNativeMethods', [GetClassPrefix(ci.Def, FClasses[i])]);
|
ss:=Format('@_%sNativeMethods', [GetClassPrefix(ci.Def, FClasses.GetClassName(i))]);
|
||||||
fn:='';
|
fn:='';
|
||||||
if ci.Def <> nil then
|
if ci.Def <> nil then
|
||||||
if ci.Def.DefType in [dtSet, dtEnum] then
|
if ci.Def.DefType in [dtSet, dtEnum] then
|
||||||
fn:=', ''Value'', ''I''';
|
fn:=', ''Value'', ''I''';
|
||||||
Fps.WriteLn(Format('if not _Reg(''%s'', %s, %d, %s%s) then exit;',
|
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;
|
end;
|
||||||
|
|
||||||
Fps.WriteLn('Result:=JNI_VERSION_1_6;');
|
Fps.WriteLn('Result:=JNI_VERSION_1_6;');
|
||||||
@ -2249,10 +2331,10 @@ procedure TWriter.RegisterPseudoClass(d: TDef);
|
|||||||
var
|
var
|
||||||
ci: TClassInfo;
|
ci: TClassInfo;
|
||||||
begin
|
begin
|
||||||
if FClasses.IndexOf(d.Name) < 0 then begin
|
if FClasses.IndexOf(d.Name, d) < 0 then begin
|
||||||
ci:=TClassInfo.Create;
|
ci:=TClassInfo.Create;
|
||||||
ci.Def:=d;
|
ci.Def:=d;
|
||||||
FClasses.AddObject(d.Name, ci);
|
FClasses.Add(d.Name, d, ci);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -2305,13 +2387,13 @@ begin
|
|||||||
pi.Name:=Name;
|
pi.Name:=Name;
|
||||||
pi.JniName:=JniName;
|
pi.JniName:=JniName;
|
||||||
pi.JniSignature:=Signature;
|
pi.JniSignature:=Signature;
|
||||||
i:=FClasses.IndexOf(ParentDef.AliasName);
|
i:=FClasses.IndexOf(ParentDef.AliasName, ParentDef);
|
||||||
if i < 0 then begin
|
if i < 0 then begin
|
||||||
ci:=TClassInfo.Create;
|
ci:=TClassInfo.Create;
|
||||||
ci.Def:=ParentDef;
|
ci.Def:=ParentDef;
|
||||||
i:=FClasses.AddObject(ParentDef.AliasName, ci);
|
i:=FClasses.Add(ParentDef.AliasName, ParentDef, ci);
|
||||||
end;
|
end;
|
||||||
TClassInfo(FClasses.Objects[i]).Funcs.Add(pi);
|
FClasses.GetClassInfo(i).Funcs.Add(pi);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TWriter.GetProcSignature(d: TProcDef): string;
|
function TWriter.GetProcSignature(d: TProcDef): string;
|
||||||
@ -2398,8 +2480,7 @@ var
|
|||||||
i: integer;
|
i: integer;
|
||||||
begin
|
begin
|
||||||
Units:=TStringList.Create;
|
Units:=TStringList.Create;
|
||||||
FClasses:=TStringList.Create;
|
FClasses:=TClassList.Create;
|
||||||
FClasses.Sorted:=True;
|
|
||||||
JavaPackage:='pas';
|
JavaPackage:='pas';
|
||||||
IncludeList:=TStringList.Create;
|
IncludeList:=TStringList.Create;
|
||||||
IncludeList.Duplicates:=dupIgnore;
|
IncludeList.Duplicates:=dupIgnore;
|
||||||
|
Loading…
Reference in New Issue
Block a user