+ objc 2.0 properties parsing (no pascal code generated yet)

+ objc protocol parsing
* cleaning the code



git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@661 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
skalogryz
2009-01-17 22:24:04 +00:00
parent 26a1d72de5
commit d650978c91
4 changed files with 1000 additions and 123 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,14 +1,20 @@
{ { * This file is part of ObjCParser tool
ObjCParserUtils.pas * Copyright (C) 2008-2009 by Dmitry Boyarintsev under the GNU LGPL
Copyright (C) 2008 Dmitry 'Skalogryz' Boyarintsev * license version 2.0 or 2.1. You should have received a copy of the
converting obj-c header to pascal (delphi compatible) unit * LGPL license along with at http://www.gnu.org/
} }
unit ObjCParserUtils; unit ObjCParserUtils;
interface interface
{$ifdef fpc}{$mode delphi}{$H+}{$endif} {$ifdef fpc}
{$mode delphi}{$H+}
{$else}
{$warn unsafe_code off}
{$warn unsafe_type off}
{$warn unsafe_cast off}
{$endif}
uses uses
Classes, SysUtils, ObjCParserTypes; Classes, SysUtils, ObjCParserTypes;
@ -93,7 +99,7 @@ function GetObjCVarType(const TypeName: AnsiString):TObjcConvertVarType; //): Bo
implementation implementation
procedure WriteOutRecordField(AField: TStructField; const Prefix: AnsiString; subs: TStrings); forward; procedure WriteOutRecordField(AField: TStructField; const Prefix: AnsiString; subs: TStrings); forward;
procedure WriteOutRecord(struct: TStructTypeDef; const Prefix, RecPrefix : AnsiString; subs: TStrings); forward; procedure WriteOutRecord(struct: TEntityStruct; const Prefix, RecPrefix : AnsiString; subs: TStrings); forward;
function GetObjCVarType(const TypeName: AnsiString):TObjcConvertVarType; function GetObjCVarType(const TypeName: AnsiString):TObjcConvertVarType;
begin begin
@ -965,9 +971,9 @@ begin
if Assigned(AField._Type) then begin if Assigned(AField._Type) then begin
if (AField._Type is TUnionTypeDef) then if (AField._Type is TUnionTypeDef) then
WriteOutUnion(TUnionTypeDef(AField._Type), Prefix, subs) WriteOutUnion(TUnionTypeDef(AField._Type), Prefix, subs)
else if AField._Type is TStructTypeDef then begin else if AField._Type is TEntityStruct then begin
i := subs.Count; i := subs.Count;
WriteOutRecord(TStructTypeDef(AField._Type), Prefix, 'packed', subs); WriteOutRecord(TEntityStruct(AField._Type), Prefix, 'packed', subs);
if i < subs.Count then begin if i < subs.Count then begin
nm := subs[i]; nm := subs[i];
Delete(nm, 1, length(Prefix)); Delete(nm, 1, length(Prefix));
@ -1011,7 +1017,7 @@ begin
end; end;
end; end;
procedure WriteOutRecord(struct: TStructTypeDef; const Prefix, RecPrefix : AnsiString; subs: TStrings); procedure WriteOutRecord(struct: TEntityStruct; const Prefix, RecPrefix : AnsiString; subs: TStrings);
var var
i : integer; i : integer;
bits : Integer; bits : Integer;
@ -1042,7 +1048,7 @@ begin
subs.Add(Prefix + 'end;'); subs.Add(Prefix + 'end;');
end; end;
procedure WriteOutTypeDefRecord(struct: TStructTypeDef; const Prefix, RecPrefix : AnsiString; subs: TStrings); procedure WriteOutTypeDefRecord(struct: TEntityStruct; const Prefix, RecPrefix : AnsiString; subs: TStrings);
var var
i : integer; i : integer;
s : AnsiString; s : AnsiString;
@ -1090,15 +1096,15 @@ begin
TEnumTypeDef(typedef._Type)._Name := typedef._TypeName; TEnumTypeDef(typedef._Type)._Name := typedef._TypeName;
WriteOutEnumToHeader(TEnumTypeDef(typedef._Type), subs); WriteOutEnumToHeader(TEnumTypeDef(typedef._Type), subs);
TEnumTypeDef(typedef._Type)._Name := tmp; TEnumTypeDef(typedef._Type)._Name := tmp;
end else if typedef._Type is TStructTypeDef then begin end else if typedef._Type is TEntityStruct then begin
subs.Add('type'); subs.Add('type');
if TStructTypeDef(typedef._Type)._Name <> '' then begin if TEntityStruct(typedef._Type)._Name <> '' then begin
WriteOutTypeDefRecord(typedef._Type as TStructTypeDef, ' ', 'packed ', subs); WriteOutTypeDefRecord(typedef._Type as TEntityStruct, ' ', 'packed ', subs);
subs.Add(Prefix + WriteOutTypeDefName(typedef._TypeName, TStructTypeDef(typedef._Type)._Name, IsTypePointer(typedef._Type, false))); subs.Add(Prefix + WriteOutTypeDefName(typedef._TypeName, TEntityStruct(typedef._Type)._Name, IsTypePointer(typedef._Type, false)));
ConvertSettings.StructTypes.Add(TStructTypeDef(typedef._Type)._Name); ConvertSettings.StructTypes.Add(TEntityStruct(typedef._Type)._Name);
end else begin end else begin
TStructTypeDef(typedef._Type)._Name := typedef._TypeName; TEntityStruct(typedef._Type)._Name := typedef._TypeName;
WriteOutTypeDefRecord(typedef._Type as TStructTypeDef, ' ', 'packed ', subs); WriteOutTypeDefRecord(typedef._Type as TEntityStruct, ' ', 'packed ', subs);
ConvertSettings.StructTypes.Add(typedef._TypeName); ConvertSettings.StructTypes.Add(typedef._TypeName);
end; end;
end; end;
@ -1173,8 +1179,9 @@ var
cmt : AnsiString; cmt : AnsiString;
j : Integer; j : Integer;
obj : TObject; // or TEntity obj : TObject; // or TEntity
mtds : TStringList; // name of methods mtds : TStringList; // name of methods
restype: TObjCResultTypeDef;
// over : TStringList; // overloaded names // over : TStringList; // overloaded names
const const
SpacePrefix = ' '; SpacePrefix = ' ';
@ -1214,8 +1221,10 @@ begin
nm := TClassMethodDef(cl.Items[j])._Name; nm := TClassMethodDef(cl.Items[j])._Name;
i := mtds.IndexOf(nm); i := mtds.IndexOf(nm);
if Integer(mtds.Objects[i]) > 0 then s := s + ' overload;'; if Integer(mtds.Objects[i]) > 0 then s := s + ' overload;';
if Assigned(TClassMethodDef(cl.Items[j]).GetResultType) then begin
restype := TClassMethodDef(cl.Items[j]).GetResultType;
if Assigned(restype) then begin
cmt := TClassMethodDef(cl.Items[j]).GetResultType.TagComment; cmt := TClassMethodDef(cl.Items[j]).GetResultType.TagComment;
if cmt <> '' then if cmt <> '' then
s := s + '{'+cmt+'}'; s := s + '{'+cmt+'}';
@ -1742,7 +1751,7 @@ begin
// packing list, removing nil references. // packing list, removing nil references.
FastPack(ent.Items); FastPack(ent.Items);
for i := 0 to ent.Items.Count - 1 do for i := 0 to ent.Items.Count - 1 do
AppleHeaderFix( TEntity(ent.Items[i])); AppleHeaderFix( TEntity(ent.Items[i]));

View File

@ -1,13 +1,14 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<CONFIG> <CONFIG>
<ProjectOptions> <ProjectOptions>
<PathDelim Value="/"/> <PathDelim Value="\"/>
<Version Value="6"/> <Version Value="7"/>
<General> <General>
<Flags> <Flags>
<MainUnitHasUsesSectionForAllUnits Value="False"/> <MainUnitHasUsesSectionForAllUnits Value="False"/>
<MainUnitHasCreateFormStatements Value="False"/> <MainUnitHasCreateFormStatements Value="False"/>
<MainUnitHasTitleStatement Value="False"/> <MainUnitHasTitleStatement Value="False"/>
<LRSInOutputDirectory Value="False"/>
</Flags> </Flags>
<MainUnit Value="0"/> <MainUnit Value="0"/>
<TargetFileExt Value=""/> <TargetFileExt Value=""/>
@ -35,7 +36,7 @@
<Filename Value="objcparser.pas"/> <Filename Value="objcparser.pas"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<UnitName Value="objcparser"/> <UnitName Value="objcparser"/>
<CursorPos X="18" Y="17"/> <CursorPos X="1" Y="3"/>
<TopLine Value="1"/> <TopLine Value="1"/>
<EditorIndex Value="0"/> <EditorIndex Value="0"/>
<UsageCount Value="26"/> <UsageCount Value="26"/>
@ -44,8 +45,8 @@
<Unit1> <Unit1>
<Filename Value="ObjCParserUtils.pas"/> <Filename Value="ObjCParserUtils.pas"/>
<UnitName Value="ObjCParserUtils"/> <UnitName Value="ObjCParserUtils"/>
<CursorPos X="47" Y="1774"/> <CursorPos X="1" Y="6"/>
<TopLine Value="1751"/> <TopLine Value="1"/>
<EditorIndex Value="1"/> <EditorIndex Value="1"/>
<UsageCount Value="13"/> <UsageCount Value="13"/>
<Loaded Value="True"/> <Loaded Value="True"/>
@ -53,14 +54,14 @@
<Unit2> <Unit2>
<Filename Value="ObjCParserTypes.pas"/> <Filename Value="ObjCParserTypes.pas"/>
<UnitName Value="ObjCParserTypes"/> <UnitName Value="ObjCParserTypes"/>
<CursorPos X="18" Y="1966"/> <CursorPos X="1" Y="6"/>
<TopLine Value="1950"/> <TopLine Value="1"/>
<EditorIndex Value="2"/> <EditorIndex Value="2"/>
<UsageCount Value="13"/> <UsageCount Value="13"/>
<Loaded Value="True"/> <Loaded Value="True"/>
</Unit2> </Unit2>
</Units> </Units>
<JumpHistory Count="6" HistoryIndex="5"> <JumpHistory Count="16" HistoryIndex="15">
<Position1> <Position1>
<Filename Value="objcparser.pas"/> <Filename Value="objcparser.pas"/>
<Caret Line="342" Column="61" TopLine="325"/> <Caret Line="342" Column="61" TopLine="325"/>
@ -85,6 +86,46 @@
<Filename Value="ObjCParserUtils.pas"/> <Filename Value="ObjCParserUtils.pas"/>
<Caret Line="144" Column="138" TopLine="128"/> <Caret Line="144" Column="138" TopLine="128"/>
</Position6> </Position6>
<Position7>
<Filename Value="ObjCParserTypes.pas"/>
<Caret Line="293" Column="14" TopLine="283"/>
</Position7>
<Position8>
<Filename Value="ObjCParserTypes.pas"/>
<Caret Line="1" Column="1" TopLine="1"/>
</Position8>
<Position9>
<Filename Value="ObjCParserTypes.pas"/>
<Caret Line="284" Column="9" TopLine="274"/>
</Position9>
<Position10>
<Filename Value="ObjCParserTypes.pas"/>
<Caret Line="1" Column="1" TopLine="1"/>
</Position10>
<Position11>
<Filename Value="ObjCParserTypes.pas"/>
<Caret Line="284" Column="9" TopLine="274"/>
</Position11>
<Position12>
<Filename Value="ObjCParserTypes.pas"/>
<Caret Line="285" Column="9" TopLine="274"/>
</Position12>
<Position13>
<Filename Value="objcparser.pas"/>
<Caret Line="17" Column="18" TopLine="1"/>
</Position13>
<Position14>
<Filename Value="ObjCParserUtils.pas"/>
<Caret Line="1754" Column="3" TopLine="1751"/>
</Position14>
<Position15>
<Filename Value="ObjCParserTypes.pas"/>
<Caret Line="422" Column="12" TopLine="412"/>
</Position15>
<Position16>
<Filename Value="ObjCParserTypes.pas"/>
<Caret Line="5" Column="18" TopLine="1"/>
</Position16>
</JumpHistory> </JumpHistory>
</ProjectOptions> </ProjectOptions>
<CompilerOptions> <CompilerOptions>

View File

@ -1,23 +1,27 @@
{ { * This file is part of ObjCParser tool
Project1.pas * Copyright (C) 2008-2009 by Dmitry Boyarintsev under the GNU LGPL
* license version 2.0 or 2.1. You should have received a copy of the
Copyright (C) 2008 Dmitry 'Skalogryz' Boyarintsev * LGPL license along with at http://www.gnu.org/
main parser unit
} }
program objcparser; program objcparser;
{$ifdef fpc} {$ifdef fpc}
{$mode delphi}{$H+} {$mode delphi}{$H+}
{$else} {$else}
{$APPTYPE CONSOLE} {$APPTYPE CONSOLE}
{$warn unsafe_code off}
{$warn unsafe_type off}
{$warn unsafe_cast off}
{$endif} {$endif}
uses uses
Classes, IniFiles, Classes,
IniFiles,
SysUtils, SysUtils,
ObjCParserUtils, ObjCParserUtils,
ObjCParserTypes; ObjCParserTypes,
CToPasWriter;
type type
// this object is used only for precomile directives handling // this object is used only for precomile directives handling
@ -26,7 +30,7 @@ type
TPrecompileHandler = class(TObject) TPrecompileHandler = class(TObject)
public public
hdr : TObjCHeader; hdr : TObjCHeader;
procedure OnPrecompile(Sender: TObject); procedure OnPrecompile(Sender: TObject; Precomp: TObject);
procedure OnComment(Sender: TObject; const Comment: AnsiString); procedure OnComment(Sender: TObject; const Comment: AnsiString);
constructor Create(AHeader: TObjCHeader); constructor Create(AHeader: TObjCHeader);
end; end;
@ -58,12 +62,12 @@ begin
Result := mn; Result := mn;
end; end;
procedure TPrecompileHandler.OnPrecompile(Sender: TObject); procedure TPrecompileHandler.OnPrecompile(Sender: TObject; Precomp: TObject);
var var
parser : TTextParser; parser : TTextParser;
preEntity : TPrecompiler; preEntity : TPrecompiler;
lst : TEntity; lst : TEntity;
prc : TNotifyEvent; prc : TPrecompilerEvent;
begin begin
parser := Sender as TTextParser; parser := Sender as TTextParser;
//todo: change for something nicier =) //todo: change for something nicier =)
@ -119,8 +123,8 @@ var
begin begin
if Entity is TClassDef then begin if Entity is TClassDef then begin
Ini.WriteString(TypeDefsSec, TClassDef(Entity)._ClassName, 'objcclass'); Ini.WriteString(TypeDefsSec, TClassDef(Entity)._ClassName, 'objcclass');
end else if Entity is TStructTypeDef then begin end else if Entity is TEntityStruct then begin
Ini.WriteString(TypeDefsSec, TStructTypeDef(Entity)._Name, 'struct'); Ini.WriteString(TypeDefsSec, TEntityStruct(Entity)._Name, 'struct');
end else if Entity is TTypeNameDef then begin end else if Entity is TTypeNameDef then begin
if Assigned(Sets) then begin if Assigned(Sets) then begin
cnv := AnsiLowerCase(ObjCToDelphiType(TTypeNameDef(Entity)._Inherited, false )); cnv := AnsiLowerCase(ObjCToDelphiType(TTypeNameDef(Entity)._Inherited, false ));
@ -153,13 +157,10 @@ begin
s := StrFromFile(FileName); s := StrFromFile(FileName);
hdr := TObjCHeader.Create; hdr := TObjCHeader.Create;
prec := TPrecompileHandler.Create(hdr); prec := TPrecompileHandler.Create(hdr);
parser := TTextParser.Create; parser := CreateCParser(s);
parser.TokenTable := CreateObjCTokenTable;
try try
parser.Buf := s; parser.Buf := s;
try try
parser.TokenTable.Precompile := '#';
parser.OnPrecompile := prec.OnPrecompile; parser.OnPrecompile := prec.OnPrecompile;
parser.OnComment := prec.OnComment; parser.OnComment := prec.OnComment;
parser.IgnoreTokens.AddStrings(ConvertSettings.IgnoreTokens); parser.IgnoreTokens.AddStrings(ConvertSettings.IgnoreTokens);
@ -202,7 +203,7 @@ end;
procedure ParseAll; procedure ParseAll;
var var
ch : char; // ch : char;
srch : TSearchRec; srch : TSearchRec;
res : Integer; res : Integer;
i : Integer; i : Integer;
@ -221,7 +222,6 @@ begin
end;} end;}
pth := IncludeTrailingPathDelimiter( GetCurrentDir); pth := IncludeTrailingPathDelimiter( GetCurrentDir);
writeln('looking for .h files in ', pth);
res := FindFirst(pth + '*.h', -1, srch); res := FindFirst(pth + '*.h', -1, srch);
if res = 0 then begin if res = 0 then begin
st := TStringList.Create; st := TStringList.Create;
@ -246,9 +246,7 @@ begin
end; end;
st.Clear; st.Clear;
writeln(' converted!');
end else begin end else begin
writeln('Error: ', err);
end; end;
until FindNext(srch) <> 0; until FindNext(srch) <> 0;
@ -308,7 +306,6 @@ var
begin begin
// uikit.ini // uikit.ini
if not FileExists(FileName) then begin if not FileExists(FileName) then begin
writeln('//ini file is not found');
Exit; Exit;
end; end;
{$ifndef fpc} {$ifndef fpc}
@ -456,6 +453,56 @@ var
i : integer; i : integer;
function FileToString(const FileName: WideString): AnsiString;
var
fs : TFileStream;
begin
Result := '';
try
fs := TfileStream.Create(FileName, fmOpenRead or fmShareDenyNone);
try
SetLength(Result, fs.Size);
fs.Read(Result[1], fs.Size)
finally
fs.Free;
end;
except
end;
end;
procedure DoTest(const InputFile: AnsiString);
var
hdr : TObjCHeader;
wrt : TStringsWriter;
cnv : TDefaultConverter;
i : Integer;
names : TPascalNames;
begin
hdr := TObjCHeader.Create;
wrt := TStringsWriter.Create;
wrt.Strings := TStringList.Create;
try
if not ParserCHeader( FileToString(InputFile), hdr) then Exit;
cnv := TDefaultConverter.Create;
names := CreateDefaultPascalNames;
try
cnv.WriteCHeader(hdr, wrt, names);
finally
cnv.Free;
end;
for i := 0 to wrt.Strings.Count - 1 do
writeln(wrt.Strings[i]);
finally
wrt.Strings.Free;
wrt.Free;
hdr.Free;
end;
end;
begin begin
doOutput := true; doOutput := true;
try try
@ -467,6 +514,9 @@ begin
TypeHelp; TypeHelp;
Exit; Exit;
end; end;
DoTest(inpf);
Exit;
st := TStringList.Create; st := TStringList.Create;
try try