chelper: c-blocks declarations are skipped if declared as variable or parameter of objc method

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@1377 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
skalogryz
2010-11-20 04:24:38 +00:00
parent 07d1f556a6
commit ef7c96d2da
5 changed files with 72 additions and 10 deletions

View File

@ -34,7 +34,7 @@
<LaunchingApplication PathPlusParams="/usr/X11/bin/xterm -T 'Lazarus Run Output' -e $(LazarusDir)/tools/runwait.sh $(TargetCmdLine)"/>
</local>
</RunParams>
<Units Count="2">
<Units Count="3">
<Unit0>
<Filename Value="cconvert.lpr"/>
<IsPartOfProject Value="True"/>
@ -45,6 +45,10 @@
<IsPartOfProject Value="True"/>
<UnitName Value="objctopasconvert"/>
</Unit1>
<Unit2>
<Filename Value="../../testUIKit/UIViewTest.h"/>
<IsPartOfProject Value="True"/>
</Unit2>
</Units>
</ProjectOptions>
<CompilerOptions>

View File

@ -29,6 +29,7 @@ var
OutputFile : AnsiString = '';
ConfigFileRO : Boolean = false;
ParseAll : Boolean = false;
ShowCodeSize : Boolean = False; // show the size of code processed
function StringFromFile(const FileName: AnsiString): AnsiString;
var
@ -85,6 +86,8 @@ begin
writeln(' -ro - prevent the configuration file from modifications (adding new types, etc)');
writeln(' -cfg filename - specifies the configuration file');
writeln(' -defines filename - macros definition file. should be in C-preprocessor format');
writeln(' -showunparsed - writes out unprased entities by their classname (for debugging only)');
writeln(' -codesize - show two numbers of the code processed (used by Chelper)');
end;
procedure ReadParams(var InputFileName: String);
@ -97,7 +100,8 @@ begin
if (s='-h') or (s='-help') or (s='-?') then begin
PrintHelp;
Halt;
end;
end else if s='-showunparsed' then
DoDebugEntities:=True;
end;
InputFileName:=ParamStr(ParamCount);
end;
@ -127,7 +131,8 @@ begin
inps.LoadFromFile(ParamStr(ParamCount));
outs.Text:=ConvertCode(inps.Text, p, ParseAll, err, cfg);;
outs.Insert(0, Format('%d %d', [p.Y,p.X]));
if ShowCodeSize then outs.Insert(0, Format('%d %d', [p.Y,p.X]));
if err.isError then outs.Insert(0, Format('error %d %d %s',[err.ErrorPos.Y, err.ErrorPos. X, err.ErrorMsg]) );
if OutputFile<>'' then

View File

@ -252,6 +252,7 @@ const
nk_Ref = 1;
nk_Array = 2;
nk_Func = 3;
nk_Block = 4;
type
TNameKind = Integer;
@ -1676,14 +1677,19 @@ begin
Parser.NextToken;
if Parser.Token='const' then Parser.NextToken; // skip const qualifier
end;
end else if (Parser.Token='^') then begin
prefix:=TNamePart.Create(nk_Block);
Parser.NextToken;
end else
prefix:=nil;
if Parser.Token='(' then begin
Parser.NextToken;
id:=ParseNamePart(Parser);
ConsumeToken(Parser, ')');
end else if (Parser.TokenType=tt_Ident) or (Parser.Token='^') then begin
end else if (Parser.TokenType=tt_Ident) then begin
id:=TNamePart.Create(nk_Ident);
id.id:=Parser.Token;
Parser.NextToken;

View File

@ -64,9 +64,10 @@ function GetIdPart(name: TNamePart): TNamePart;
function isNamePartPtrToFunc(part: TNamePart): Boolean; inline;
function isAnyBlock(part: TNamePart): Boolean;
type
{ TLineBreaker }
TLineInfo = record
@ -91,6 +92,11 @@ begin
Result:=Assigned(part) and (part.Kind=nk_Ref) and Assigned(part.owner) and (part.owner.kind=nk_Func);
end;
function isAnyBlock(part: TNamePart): Boolean;
begin
Result:=Assigned(part) and ((part.Kind=nk_Block) or isAnyBlock(part.child));
end;
function isPtrToFunc(name: TNamePart): Boolean;
begin
Result := Assigned(name) and (name.Kind=nk_Func) and Assigned(name.child) and

View File

@ -27,6 +27,9 @@ uses
cparsertypes, TextParsingUtils, codewriter, cparserutils,
objcparsing;
var
DoDebugEntities : Boolean = False; // write parsed entities names if no converter found!?
type
{ TConvertSettings }
@ -106,6 +109,9 @@ type
procedure Clear;
end;
type
TConvertCheck = function (ent: TEntity): Boolean;
implementation
type
@ -176,6 +182,8 @@ type
procedure WriteObjCProtocol(cent: TObjCProtocol);
procedure WriteObjCClasses(cent: TObjCClasses);
function CanConvert(ent: TEntity): Boolean;
procedure PushWriter;
procedure PopWriter;
public
@ -548,7 +556,7 @@ begin
cfg:=ASettings;
wr:=TCodeWriter.Create;
WriteFunc:=@DefFuncWrite;
DebugEntities := True;
DebugEntities := DoDebugEntities;
end;
destructor TCodeConvertor.Destroy;
@ -648,6 +656,9 @@ var
PNames : array of AnsiString;
PTypes : array of AnsiString;
begin
if not CanConvert(m) then Exit;
if m.RetType=nil then ret:='id' else ret:=GetPasTypeName(m.RetType, m.RetName);
SetLength(PNames, length(m.Args));
SetLength(PTypes, length(m.Args));
@ -811,6 +822,34 @@ begin
wr.WLn(cent.ClassList[i] +' = objcclass; external;');
end;
function CanConvertObjCMethod(ent: TObjCMethod): Boolean;
var
i : Integer;
begin
Result:=True;
if not Assigned(ent) then Exit;
for i:=0 to length(ent.Args)-1 do
if Assigned(ent.Args[i].TypeName) and isAnyBlock(ent.Args[i].TypeName) then begin
Result:=False;
Exit;
end;
end;
function TCodeConvertor.CanConvert(ent: TEntity): Boolean;
begin
Result:=Assigned(ent);
if not Result then Exit;
if ent is TVarFuncEntity then
begin
Result:=(not isAnyBlock(TVarFuncEntity(ent).FirstName)) and CanConvert(TVarFuncEntity(ent).RetType)
end else if ent is TObjCMethod then
Result:=CanConvertObjCMethod(TObjCMethod(ent));
end;
procedure TCodeConvertor.PushWriter;
begin
if not Assigned(fWriters) then fWriters:=TList.Create;
@ -1131,6 +1170,8 @@ procedure TCodeConvertor.WriteCtoPas(cent: TEntity; comments: TList; const Parse
var
tp : AnsiString;
begin
if not CanConvert(cent) then Exit;
CmtList:=comments;
Breaker:=TLineBreaker.Create;
Breaker.SetText(ParsedText);